home to your local SPACEGIRL 💫 arimelody.space
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

moving to custom swap engine

Signed-off-by: ari melody <ari@arimelody.me>

+4361 -225
+1 -1
.air.toml
··· 13 13 exclude_unchanged = false 14 14 follow_symlink = false 15 15 full_bin = "" 16 - include_dir = [] 16 + include_dir = [".", "views", "api"] 17 17 include_ext = ["go", "tpl", "tmpl", "html"] 18 18 include_file = [] 19 19 kill_delay = "0s"
+13 -13
docker-compose-db.yml
··· 1 1 version: '3.9' 2 2 3 3 services: 4 - db: 5 - image: postgres:16.1-alpine3.18 6 - container_name: arimelody.me-db 7 - ports: 8 - - 5432:5432 9 - volumes: 10 - - arimelody-db:/var/lib/postgresql/data 11 - environment: 12 - POSTGRES_DB: arimelody 13 - POSTGRES_USER: arimelody 14 - POSTGRES_PASSWORD: fuckingpassword 4 + db: 5 + image: postgres:16.1-alpine3.18 6 + container_name: arimelody.me-db 7 + ports: 8 + - 5432:5432 9 + volumes: 10 + - arimelody-db:/var/lib/postgresql/data 11 + environment: 12 + POSTGRES_DB: arimelody 13 + POSTGRES_USER: arimelody 14 + POSTGRES_PASSWORD: fuckingpassword 15 15 16 16 volumes: 17 - arimelody-db: 18 - external: true 17 + arimelody-db: 18 + external: true
+39 -25
main.go
··· 6 6 "log" 7 7 "net/http" 8 8 "os" 9 - "regexp" 10 9 "strconv" 11 10 "strings" 12 11 "time" ··· 37 36 "views/footer.html", 38 37 "views/prideflag.html", 39 38 )) 40 - var htmx_template = template.Must(template.New("root").Parse(`<head>{{block "head" .}}{{end}}</head>{{block "content" .}}{{end}}`)) 39 + // var htmx_template = template.Must(template.New("root").Parse(`<head>{{block "head" .}}{{end}}</head>{{block "content" .}}{{end}}`)) 41 40 42 41 func log_request(req *http.Request, code int, start_time time.Time) { 43 42 now := time.Now() ··· 61 60 uri := req.URL.Path 62 61 start_time := time.Now() 63 62 64 - hx_request := len(req.Header["Hx-Request"]) > 0 && req.Header["Hx-Request"][0] == "true" 65 - 66 - // don't bother fulfilling requests to a page that's already loaded on the client! 67 - if hx_request && len(req.Header["Referer"]) > 0 && len(req.Header["Hx-Current-Url"]) > 0 { 68 - regex := regexp.MustCompile(`https?:\/\/[^\/]+`) 69 - current_location := regex.ReplaceAllString(req.Header["Hx-Current-Url"][0], "") 70 - if current_location == req.URL.Path { 71 - writer.WriteHeader(204); 72 - return 73 - } 74 - } 63 + // hx_request := len(req.Header["Hx-Request"]) > 0 && req.Header["Hx-Request"][0] == "true" 64 + // 65 + // // don't bother fulfilling requests to a page that's already loaded on the client! 66 + // if hx_request && len(req.Header["Referer"]) > 0 && len(req.Header["Hx-Current-Url"]) > 0 { 67 + // regex := regexp.MustCompile(`https?:\/\/[^\/]+`) 68 + // current_location := regex.ReplaceAllString(req.Header["Hx-Current-Url"][0], "") 69 + // if current_location == req.URL.Path { 70 + // writer.WriteHeader(204); 71 + // return 72 + // } 73 + // } 75 74 76 75 code := func(writer http.ResponseWriter, req *http.Request) int { 77 - var root *template.Template 78 - if hx_request { 79 - root = template.Must(htmx_template.Clone()) 80 - } else { 81 - root = template.Must(base_template.Clone()) 82 - } 76 + // var root *template.Template 77 + // if hx_request { 78 + // root = template.Must(htmx_template.Clone()) 79 + // } else { 80 + // root = template.Must(base_template.Clone()) 81 + // } 82 + 83 + var root = template.Must(base_template.Clone()) 83 84 84 85 if req.URL.Path == "/" { 85 86 return index_handler(writer, root) ··· 93 94 return music_gateway_handler(writer, req, root) 94 95 } 95 96 96 - return static_handler(writer, req) 97 + return static_handler(writer, req, root) 97 98 }(writer, req) 98 99 99 100 log_request(req, code, start_time) ··· 126 127 // return 127 128 release, ok := music.GetRelease(id) 128 129 if !ok { 129 - http.Error(writer, "404 not found", http.StatusNotFound) 130 - return 404 130 + return handle_not_found(writer, req, root) 131 131 } 132 132 gateway_template := template.Must(root.ParseFiles("views/music-gateway.html")) 133 133 err := gateway_template.Execute(writer, release) ··· 138 138 return 200 139 139 } 140 140 141 - func static_handler(writer http.ResponseWriter, req *http.Request) int { 141 + func static_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int { 142 142 filename := "public/" + req.URL.Path[1:] 143 143 144 144 // check the file's metadata 145 145 info, err := os.Stat(filename) 146 146 if err != nil { 147 - http.Error(writer, "404 not found", http.StatusNotFound) 148 - return 404 147 + return handle_not_found(writer, req, root) 149 148 } 150 149 151 150 if len(req.Header["If-Modified-Since"]) > 0 && req.Header["If-Modified-Since"][0] != "" { ··· 183 182 184 183 writer.Write([]byte(body)) 185 184 return 200 185 + } 186 + 187 + func handle_not_found(writer http.ResponseWriter, req *http.Request, root *template.Template) int { 188 + type ErrorData struct { 189 + Target string 190 + } 191 + error_data := ErrorData{ Target: req.URL.Path } 192 + writer.WriteHeader(404); 193 + error_template := template.Must(root.ParseFiles("views/404.html")) 194 + err := error_template.Execute(writer, error_data) 195 + if err != nil { 196 + http.Error(writer, err.Error(), http.StatusInternalServerError) 197 + return 500 198 + } 199 + return 404 186 200 } 187 201 188 202 func parse_markdown(md []byte) []byte {
public/img/buttons/zvava.png

This is a binary file and will not be displayed.

-44
public/script/accessibility.js
··· 1 - const accessibility = JSON.parse(localStorage.getItem("accessibility")) || {}; 2 - 3 - function toggle_accessibility_setting(name) { 4 - if (accessibility[name]) { 5 - delete accessibility[name]; 6 - update_accessibility(); 7 - return true; 8 - } 9 - accessibility[name] = true; 10 - update_accessibility(); 11 - return true; 12 - } 13 - 14 - function set_accessibility_setting(name, value) { 15 - accessibility[name] = value; 16 - update_accessibility(); 17 - return true; 18 - } 19 - 20 - function clear_accessibility_setting(name) { 21 - if (!accessibility[name]) return false; 22 - delete accessibility[name]; 23 - update_accessibility(); 24 - return true; 25 - } 26 - 27 - function update_accessibility() { 28 - localStorage.setItem("accessibility", JSON.stringify(accessibility)); 29 - } 30 - 31 - if (accessibility) { 32 - if (accessibility.disable_crt) { 33 - document.querySelector('div#overlay').setAttribute("hidden", true); 34 - document.body.style.textShadow = "none"; 35 - document.getElementById('toggle-crt').classList.add("disabled"); 36 - } 37 - } 38 - 39 - document.getElementById("toggle-crt").addEventListener("click", () => { 40 - toggle_accessibility_setting("disable_crt"); 41 - document.querySelector('div#overlay').toggleAttribute("hidden"); 42 - document.getElementById('toggle-crt').className = accessibility.disable_crt ? "disabled" : ""; 43 - }); 44 -
+42
public/script/config.js
··· 1 + function toggle_config_setting(config, name) { 2 + if (config[name]) { 3 + delete config[name]; 4 + update_config(config); 5 + return true; 6 + } 7 + config[name] = true; 8 + update_config(config); 9 + return true; 10 + } 11 + 12 + function set_config_setting(config, name, value) { 13 + config[name] = value; 14 + update_config(config); 15 + return true; 16 + } 17 + 18 + function clear_config_setting(config, name) { 19 + if (!config[name]) return false; 20 + delete config[name]; 21 + update_config(config); 22 + return true; 23 + } 24 + 25 + function update_config(config) { 26 + localStorage.setItem("config", JSON.stringify(config)); 27 + } 28 + 29 + const config = JSON.parse(localStorage.getItem("config")) || {}; 30 + if (config) { 31 + if (config.disable_crt) { 32 + document.querySelector('div#overlay').setAttribute("hidden", true); 33 + document.body.style.textShadow = "none"; 34 + document.getElementById('toggle-crt').classList.add("disabled"); 35 + } 36 + } 37 + 38 + document.getElementById("toggle-crt").addEventListener("click", () => { 39 + toggle_config_setting(config, "disable_crt"); 40 + document.querySelector('div#overlay').toggleAttribute("hidden"); 41 + document.getElementById('toggle-crt').className = config.disable_crt ? "disabled" : ""; 42 + });
+3 -5
public/script/header.js
··· 1 1 const header_links = document.getElementById("header-links"); 2 2 const hamburger = document.getElementById("header-links-toggle"); 3 3 4 - function toggle_header_links() { 5 - header_links.classList.toggle("open"); 6 - } 7 - 8 4 document.addEventListener("click", event => { 9 5 if (!header_links.contains(event.target) && !hamburger.contains(event.target) && !header_links.href) { 10 6 header_links.classList.remove("open"); 11 7 } 12 8 }); 13 9 14 - hamburger.addEventListener("click", event => { toggle_header_links(); }); 10 + hamburger.addEventListener("click", event => { 11 + header_links.classList.toggle("open"); 12 + });
+147
public/script/lib/htmx-preload.js
··· 1 + // This adds the "preload" extension to htmx. By default, this will 2 + // preload the targets of any tags with `href` or `hx-get` attributes 3 + // if they also have a `preload` attribute as well. See documentation 4 + // for more details 5 + htmx.defineExtension("preload", { 6 + 7 + onEvent: function(name, event) { 8 + 9 + // Only take actions on "htmx:afterProcessNode" 10 + if (name !== "htmx:afterProcessNode") { 11 + return; 12 + } 13 + 14 + // SOME HELPER FUNCTIONS WE'LL NEED ALONG THE WAY 15 + 16 + // attr gets the closest non-empty value from the attribute. 17 + var attr = function(node, property) { 18 + if (node == undefined) {return undefined;} 19 + return node.getAttribute(property) || node.getAttribute("data-" + property) || attr(node.parentElement, property) 20 + } 21 + 22 + // load handles the actual HTTP fetch, and uses htmx.ajax in cases where we're 23 + // preloading an htmx resource (this sends the same HTTP headers as a regular htmx request) 24 + var load = function(node) { 25 + 26 + // Called after a successful AJAX request, to mark the 27 + // content as loaded (and prevent additional AJAX calls.) 28 + var done = function(html) { 29 + if (!node.preloadAlways) { 30 + node.preloadState = "DONE" 31 + } 32 + 33 + if (attr(node, "preload-images") == "true") { 34 + document.createElement("div").innerHTML = html // create and populate a node to load linked resources, too. 35 + } 36 + } 37 + 38 + return function() { 39 + 40 + // If this value has already been loaded, then do not try again. 41 + if (node.preloadState !== "READY") { 42 + return; 43 + } 44 + 45 + // Special handling for HX-GET - use built-in htmx.ajax function 46 + // so that headers match other htmx requests, then set 47 + // node.preloadState = TRUE so that requests are not duplicated 48 + // in the future 49 + var hxGet = node.getAttribute("hx-get") || node.getAttribute("data-hx-get") 50 + if (hxGet) { 51 + htmx.ajax("GET", hxGet, { 52 + source: node, 53 + handler:function(elt, info) { 54 + done(info.xhr.responseText); 55 + } 56 + }); 57 + return; 58 + } 59 + 60 + // Otherwise, perform a standard xhr request, then set 61 + // node.preloadState = TRUE so that requests are not duplicated 62 + // in the future. 63 + if (node.getAttribute("href")) { 64 + var r = new XMLHttpRequest(); 65 + r.open("GET", node.getAttribute("href")); 66 + r.onload = function() {done(r.responseText);}; 67 + r.send(); 68 + return; 69 + } 70 + } 71 + } 72 + 73 + // This function processes a specific node and sets up event handlers. 74 + // We'll search for nodes and use it below. 75 + var init = function(node) { 76 + 77 + // If this node DOES NOT include a "GET" transaction, then there's nothing to do here. 78 + if (node.getAttribute("href") + node.getAttribute("hx-get") + node.getAttribute("data-hx-get") == "") { 79 + return; 80 + } 81 + 82 + // Guarantee that we only initialize each node once. 83 + if (node.preloadState !== undefined) { 84 + return; 85 + } 86 + 87 + // Get event name from config. 88 + var on = attr(node, "preload") || "mousedown" 89 + const always = on.indexOf("always") !== -1 90 + if (always) { 91 + on = on.replace('always', '').trim() 92 + } 93 + 94 + // FALL THROUGH to here means we need to add an EventListener 95 + 96 + // Apply the listener to the node 97 + node.addEventListener(on, function(evt) { 98 + if (node.preloadState === "PAUSE") { // Only add one event listener 99 + node.preloadState = "READY"; // Required for the `load` function to trigger 100 + 101 + // Special handling for "mouseover" events. Wait 100ms before triggering load. 102 + if (on === "mouseover") { 103 + window.setTimeout(load(node), 100); 104 + } else { 105 + load(node)() // all other events trigger immediately. 106 + } 107 + } 108 + }) 109 + 110 + // Special handling for certain built-in event handlers 111 + switch (on) { 112 + 113 + case "mouseover": 114 + // Mirror `touchstart` events (fires immediately) 115 + node.addEventListener("touchstart", load(node)); 116 + 117 + // WHhen the mouse leaves, immediately disable the preload 118 + node.addEventListener("mouseout", function(evt) { 119 + if ((evt.target === node) && (node.preloadState === "READY")) { 120 + node.preloadState = "PAUSE"; 121 + } 122 + }) 123 + break; 124 + 125 + case "mousedown": 126 + // Mirror `touchstart` events (fires immediately) 127 + node.addEventListener("touchstart", load(node)); 128 + break; 129 + } 130 + 131 + // Mark the node as ready to run. 132 + node.preloadState = "PAUSE"; 133 + node.preloadAlways = always; 134 + htmx.trigger(node, "preload:init") // This event can be used to load content immediately. 135 + } 136 + 137 + // Search for all child nodes that have a "preload" attribute 138 + event.target.querySelectorAll("[preload]").forEach(function(node) { 139 + 140 + // Initialize the node with the "preload" attribute 141 + init(node) 142 + 143 + // Initialize all child elements that are anchors or have `hx-get` (use with care) 144 + node.querySelectorAll("a,[hx-get],[data-hx-get]").forEach(init) 145 + }) 146 + } 147 + })
+3922
public/script/lib/htmx.js
··· 1 + // UMD insanity 2 + // This code sets up support for (in order) AMD, ES6 modules, and globals. 3 + (function (root, factory) { 4 + //@ts-ignore 5 + if (typeof define === 'function' && define.amd) { 6 + // AMD. Register as an anonymous module. 7 + //@ts-ignore 8 + define([], factory); 9 + } else if (typeof module === 'object' && module.exports) { 10 + // Node. Does not work with strict CommonJS, but 11 + // only CommonJS-like environments that support module.exports, 12 + // like Node. 13 + module.exports = factory(); 14 + } else { 15 + // Browser globals 16 + root.htmx = root.htmx || factory(); 17 + } 18 + }(typeof self !== 'undefined' ? self : this, function () { 19 + return (function () { 20 + 'use strict'; 21 + 22 + // Public API 23 + //** @type {import("./htmx").HtmxApi} */ 24 + // TODO: list all methods in public API 25 + var htmx = { 26 + onLoad: onLoadHelper, 27 + process: processNode, 28 + on: addEventListenerImpl, 29 + off: removeEventListenerImpl, 30 + trigger : triggerEvent, 31 + ajax : ajaxHelper, 32 + find : find, 33 + findAll : findAll, 34 + closest : closest, 35 + values : function(elt, type){ 36 + var inputValues = getInputValues(elt, type || "post"); 37 + return inputValues.values; 38 + }, 39 + remove : removeElement, 40 + addClass : addClassToElement, 41 + removeClass : removeClassFromElement, 42 + toggleClass : toggleClassOnElement, 43 + takeClass : takeClassForElement, 44 + defineExtension : defineExtension, 45 + removeExtension : removeExtension, 46 + logAll : logAll, 47 + logNone : logNone, 48 + logger : null, 49 + config : { 50 + historyEnabled:true, 51 + historyCacheSize:10, 52 + refreshOnHistoryMiss:false, 53 + defaultSwapStyle:'innerHTML', 54 + defaultSwapDelay:0, 55 + defaultSettleDelay:20, 56 + includeIndicatorStyles:true, 57 + indicatorClass:'htmx-indicator', 58 + requestClass:'htmx-request', 59 + addedClass:'htmx-added', 60 + settlingClass:'htmx-settling', 61 + swappingClass:'htmx-swapping', 62 + allowEval:true, 63 + allowScriptTags:true, 64 + inlineScriptNonce:'', 65 + attributesToSettle:["class", "style", "width", "height"], 66 + withCredentials:false, 67 + timeout:0, 68 + wsReconnectDelay: 'full-jitter', 69 + wsBinaryType: 'blob', 70 + disableSelector: "[hx-disable], [data-hx-disable]", 71 + useTemplateFragments: false, 72 + scrollBehavior: 'smooth', 73 + defaultFocusScroll: false, 74 + getCacheBusterParam: false, 75 + globalViewTransitions: false, 76 + methodsThatUseUrlParams: ["get"], 77 + selfRequestsOnly: false, 78 + ignoreTitle: false, 79 + scrollIntoViewOnBoost: true, 80 + triggerSpecsCache: null, 81 + }, 82 + parseInterval:parseInterval, 83 + _:internalEval, 84 + createEventSource: function(url){ 85 + return new EventSource(url, {withCredentials:true}) 86 + }, 87 + createWebSocket: function(url){ 88 + var sock = new WebSocket(url, []); 89 + sock.binaryType = htmx.config.wsBinaryType; 90 + return sock; 91 + }, 92 + version: "1.9.11" 93 + }; 94 + 95 + /** @type {import("./htmx").HtmxInternalApi} */ 96 + var internalAPI = { 97 + addTriggerHandler: addTriggerHandler, 98 + bodyContains: bodyContains, 99 + canAccessLocalStorage: canAccessLocalStorage, 100 + findThisElement: findThisElement, 101 + filterValues: filterValues, 102 + hasAttribute: hasAttribute, 103 + getAttributeValue: getAttributeValue, 104 + getClosestAttributeValue: getClosestAttributeValue, 105 + getClosestMatch: getClosestMatch, 106 + getExpressionVars: getExpressionVars, 107 + getHeaders: getHeaders, 108 + getInputValues: getInputValues, 109 + getInternalData: getInternalData, 110 + getSwapSpecification: getSwapSpecification, 111 + getTriggerSpecs: getTriggerSpecs, 112 + getTarget: getTarget, 113 + makeFragment: makeFragment, 114 + mergeObjects: mergeObjects, 115 + makeSettleInfo: makeSettleInfo, 116 + oobSwap: oobSwap, 117 + querySelectorExt: querySelectorExt, 118 + selectAndSwap: selectAndSwap, 119 + settleImmediately: settleImmediately, 120 + shouldCancel: shouldCancel, 121 + triggerEvent: triggerEvent, 122 + triggerErrorEvent: triggerErrorEvent, 123 + withExtensions: withExtensions, 124 + } 125 + 126 + var VERBS = ['get', 'post', 'put', 'delete', 'patch']; 127 + var VERB_SELECTOR = VERBS.map(function(verb){ 128 + return "[hx-" + verb + "], [data-hx-" + verb + "]" 129 + }).join(", "); 130 + 131 + var HEAD_TAG_REGEX = makeTagRegEx('head'), 132 + TITLE_TAG_REGEX = makeTagRegEx('title'), 133 + SVG_TAGS_REGEX = makeTagRegEx('svg', true); 134 + 135 + //==================================================================== 136 + // Utilities 137 + //==================================================================== 138 + 139 + /** 140 + * @param {string} tag 141 + * @param {boolean} global 142 + * @returns {RegExp} 143 + */ 144 + function makeTagRegEx(tag, global = false) { 145 + return new RegExp(`<${tag}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${tag}>`, 146 + global ? 'gim' : 'im'); 147 + } 148 + 149 + function parseInterval(str) { 150 + if (str == undefined) { 151 + return undefined; 152 + } 153 + 154 + let interval = NaN; 155 + if (str.slice(-2) == "ms") { 156 + interval = parseFloat(str.slice(0, -2)); 157 + } else if (str.slice(-1) == "s") { 158 + interval = parseFloat(str.slice(0, -1)) * 1000; 159 + } else if (str.slice(-1) == "m") { 160 + interval = parseFloat(str.slice(0, -1)) * 1000 * 60; 161 + } else { 162 + interval = parseFloat(str); 163 + } 164 + return isNaN(interval) ? undefined : interval; 165 + } 166 + 167 + /** 168 + * @param {HTMLElement} elt 169 + * @param {string} name 170 + * @returns {(string | null)} 171 + */ 172 + function getRawAttribute(elt, name) { 173 + return elt.getAttribute && elt.getAttribute(name); 174 + } 175 + 176 + // resolve with both hx and data-hx prefixes 177 + function hasAttribute(elt, qualifiedName) { 178 + return elt.hasAttribute && (elt.hasAttribute(qualifiedName) || 179 + elt.hasAttribute("data-" + qualifiedName)); 180 + } 181 + 182 + /** 183 + * 184 + * @param {HTMLElement} elt 185 + * @param {string} qualifiedName 186 + * @returns {(string | null)} 187 + */ 188 + function getAttributeValue(elt, qualifiedName) { 189 + return getRawAttribute(elt, qualifiedName) || getRawAttribute(elt, "data-" + qualifiedName); 190 + } 191 + 192 + /** 193 + * @param {HTMLElement} elt 194 + * @returns {HTMLElement | null} 195 + */ 196 + function parentElt(elt) { 197 + return elt.parentElement; 198 + } 199 + 200 + /** 201 + * @returns {Document} 202 + */ 203 + function getDocument() { 204 + return document; 205 + } 206 + 207 + /** 208 + * @param {HTMLElement} elt 209 + * @param {(e:HTMLElement) => boolean} condition 210 + * @returns {HTMLElement | null} 211 + */ 212 + function getClosestMatch(elt, condition) { 213 + while (elt && !condition(elt)) { 214 + elt = parentElt(elt); 215 + } 216 + 217 + return elt ? elt : null; 218 + } 219 + 220 + function getAttributeValueWithDisinheritance(initialElement, ancestor, attributeName){ 221 + var attributeValue = getAttributeValue(ancestor, attributeName); 222 + var disinherit = getAttributeValue(ancestor, "hx-disinherit"); 223 + if (initialElement !== ancestor && disinherit && (disinherit === "*" || disinherit.split(" ").indexOf(attributeName) >= 0)) { 224 + return "unset"; 225 + } else { 226 + return attributeValue 227 + } 228 + } 229 + 230 + /** 231 + * @param {HTMLElement} elt 232 + * @param {string} attributeName 233 + * @returns {string | null} 234 + */ 235 + function getClosestAttributeValue(elt, attributeName) { 236 + var closestAttr = null; 237 + getClosestMatch(elt, function (e) { 238 + return closestAttr = getAttributeValueWithDisinheritance(elt, e, attributeName); 239 + }); 240 + if (closestAttr !== "unset") { 241 + return closestAttr; 242 + } 243 + } 244 + 245 + /** 246 + * @param {HTMLElement} elt 247 + * @param {string} selector 248 + * @returns {boolean} 249 + */ 250 + function matches(elt, selector) { 251 + // @ts-ignore: non-standard properties for browser compatibility 252 + // noinspection JSUnresolvedVariable 253 + var matchesFunction = elt.matches || elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector || elt.webkitMatchesSelector || elt.oMatchesSelector; 254 + return matchesFunction && matchesFunction.call(elt, selector); 255 + } 256 + 257 + /** 258 + * @param {string} str 259 + * @returns {string} 260 + */ 261 + function getStartTag(str) { 262 + var tagMatcher = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i 263 + var match = tagMatcher.exec( str ); 264 + if (match) { 265 + return match[1].toLowerCase(); 266 + } else { 267 + return ""; 268 + } 269 + } 270 + 271 + /** 272 + * 273 + * @param {string} resp 274 + * @param {number} depth 275 + * @returns {Element} 276 + */ 277 + function parseHTML(resp, depth) { 278 + var parser = new DOMParser(); 279 + var responseDoc = parser.parseFromString(resp, "text/html"); 280 + 281 + /** @type {Element} */ 282 + var responseNode = responseDoc.body; 283 + while (depth > 0) { 284 + depth--; 285 + // @ts-ignore 286 + responseNode = responseNode.firstChild; 287 + } 288 + if (responseNode == null) { 289 + // @ts-ignore 290 + responseNode = getDocument().createDocumentFragment(); 291 + } 292 + return responseNode; 293 + } 294 + 295 + function aFullPageResponse(resp) { 296 + return /<body/.test(resp) 297 + } 298 + 299 + /** 300 + * 301 + * @param {string} response 302 + * @returns {Element} 303 + */ 304 + function makeFragment(response) { 305 + var partialResponse = !aFullPageResponse(response); 306 + var startTag = getStartTag(response); 307 + var content = response; 308 + if (startTag === 'head') { 309 + content = content.replace(HEAD_TAG_REGEX, ''); 310 + } 311 + if (htmx.config.useTemplateFragments && partialResponse) { 312 + var fragment = parseHTML("<body><template>" + content + "</template></body>", 0); 313 + // @ts-ignore type mismatch between DocumentFragment and Element. 314 + // TODO: Are these close enough for htmx to use interchangeably? 315 + var fragmentContent = fragment.querySelector('template').content; 316 + if (htmx.config.allowScriptTags) { 317 + // if there is a nonce set up, set it on the new script tags 318 + forEach(fragmentContent.querySelectorAll("script"), function (script) { 319 + if (htmx.config.inlineScriptNonce) { 320 + script.nonce = htmx.config.inlineScriptNonce; 321 + } 322 + // mark as executed due to template insertion semantics on all browsers except firefox fml 323 + script.htmxExecuted = navigator.userAgent.indexOf("Firefox") === -1; 324 + }) 325 + } else { 326 + forEach(fragmentContent.querySelectorAll("script"), function (script) { 327 + // remove all script tags if scripts are disabled 328 + removeElement(script); 329 + }) 330 + } 331 + return fragmentContent; 332 + } 333 + switch (startTag) { 334 + case "thead": 335 + case "tbody": 336 + case "tfoot": 337 + case "colgroup": 338 + case "caption": 339 + return parseHTML("<table>" + content + "</table>", 1); 340 + case "col": 341 + return parseHTML("<table><colgroup>" + content + "</colgroup></table>", 2); 342 + case "tr": 343 + return parseHTML("<table><tbody>" + content + "</tbody></table>", 2); 344 + case "td": 345 + case "th": 346 + return parseHTML("<table><tbody><tr>" + content + "</tr></tbody></table>", 3); 347 + case "script": 348 + case "style": 349 + return parseHTML("<div>" + content + "</div>", 1); 350 + default: 351 + return parseHTML(content, 0); 352 + } 353 + } 354 + 355 + /** 356 + * @param {Function} func 357 + */ 358 + function maybeCall(func){ 359 + if(func) { 360 + func(); 361 + } 362 + } 363 + 364 + /** 365 + * @param {any} o 366 + * @param {string} type 367 + * @returns 368 + */ 369 + function isType(o, type) { 370 + return Object.prototype.toString.call(o) === "[object " + type + "]"; 371 + } 372 + 373 + /** 374 + * @param {*} o 375 + * @returns {o is Function} 376 + */ 377 + function isFunction(o) { 378 + return isType(o, "Function"); 379 + } 380 + 381 + /** 382 + * @param {*} o 383 + * @returns {o is Object} 384 + */ 385 + function isRawObject(o) { 386 + return isType(o, "Object"); 387 + } 388 + 389 + /** 390 + * getInternalData retrieves "private" data stored by htmx within an element 391 + * @param {HTMLElement} elt 392 + * @returns {*} 393 + */ 394 + function getInternalData(elt) { 395 + var dataProp = 'htmx-internal-data'; 396 + var data = elt[dataProp]; 397 + if (!data) { 398 + data = elt[dataProp] = {}; 399 + } 400 + return data; 401 + } 402 + 403 + /** 404 + * toArray converts an ArrayLike object into a real array. 405 + * @param {ArrayLike} arr 406 + * @returns {any[]} 407 + */ 408 + function toArray(arr) { 409 + var returnArr = []; 410 + if (arr) { 411 + for (var i = 0; i < arr.length; i++) { 412 + returnArr.push(arr[i]); 413 + } 414 + } 415 + return returnArr 416 + } 417 + 418 + function forEach(arr, func) { 419 + if (arr) { 420 + for (var i = 0; i < arr.length; i++) { 421 + func(arr[i]); 422 + } 423 + } 424 + } 425 + 426 + function isScrolledIntoView(el) { 427 + var rect = el.getBoundingClientRect(); 428 + var elemTop = rect.top; 429 + var elemBottom = rect.bottom; 430 + return elemTop < window.innerHeight && elemBottom >= 0; 431 + } 432 + 433 + function bodyContains(elt) { 434 + // IE Fix 435 + if (elt.getRootNode && elt.getRootNode() instanceof window.ShadowRoot) { 436 + return getDocument().body.contains(elt.getRootNode().host); 437 + } else { 438 + return getDocument().body.contains(elt); 439 + } 440 + } 441 + 442 + function splitOnWhitespace(trigger) { 443 + return trigger.trim().split(/\s+/); 444 + } 445 + 446 + /** 447 + * mergeObjects takes all of the keys from 448 + * obj2 and duplicates them into obj1 449 + * @param {Object} obj1 450 + * @param {Object} obj2 451 + * @returns {Object} 452 + */ 453 + function mergeObjects(obj1, obj2) { 454 + for (var key in obj2) { 455 + if (obj2.hasOwnProperty(key)) { 456 + obj1[key] = obj2[key]; 457 + } 458 + } 459 + return obj1; 460 + } 461 + 462 + function parseJSON(jString) { 463 + try { 464 + return JSON.parse(jString); 465 + } catch(error) { 466 + logError(error); 467 + return null; 468 + } 469 + } 470 + 471 + function canAccessLocalStorage() { 472 + var test = 'htmx:localStorageTest'; 473 + try { 474 + localStorage.setItem(test, test); 475 + localStorage.removeItem(test); 476 + return true; 477 + } catch(e) { 478 + return false; 479 + } 480 + } 481 + 482 + function normalizePath(path) { 483 + try { 484 + var url = new URL(path); 485 + if (url) { 486 + path = url.pathname + url.search; 487 + } 488 + // remove trailing slash, unless index page 489 + if (!(/^\/$/.test(path))) { 490 + path = path.replace(/\/+$/, ''); 491 + } 492 + return path; 493 + } catch (e) { 494 + // be kind to IE11, which doesn't support URL() 495 + return path; 496 + } 497 + } 498 + 499 + //========================================================================================== 500 + // public API 501 + //========================================================================================== 502 + 503 + function internalEval(str){ 504 + return maybeEval(getDocument().body, function () { 505 + return eval(str); 506 + }); 507 + } 508 + 509 + function onLoadHelper(callback) { 510 + var value = htmx.on("htmx:load", function(evt) { 511 + callback(evt.detail.elt); 512 + }); 513 + return value; 514 + } 515 + 516 + function logAll(){ 517 + htmx.logger = function(elt, event, data) { 518 + if(console) { 519 + console.log(event, elt, data); 520 + } 521 + } 522 + } 523 + 524 + function logNone() { 525 + htmx.logger = null 526 + } 527 + 528 + function find(eltOrSelector, selector) { 529 + if (selector) { 530 + return eltOrSelector.querySelector(selector); 531 + } else { 532 + return find(getDocument(), eltOrSelector); 533 + } 534 + } 535 + 536 + function findAll(eltOrSelector, selector) { 537 + if (selector) { 538 + return eltOrSelector.querySelectorAll(selector); 539 + } else { 540 + return findAll(getDocument(), eltOrSelector); 541 + } 542 + } 543 + 544 + function removeElement(elt, delay) { 545 + elt = resolveTarget(elt); 546 + if (delay) { 547 + setTimeout(function(){ 548 + removeElement(elt); 549 + elt = null; 550 + }, delay); 551 + } else { 552 + elt.parentElement.removeChild(elt); 553 + } 554 + } 555 + 556 + function addClassToElement(elt, clazz, delay) { 557 + elt = resolveTarget(elt); 558 + if (delay) { 559 + setTimeout(function(){ 560 + addClassToElement(elt, clazz); 561 + elt = null; 562 + }, delay); 563 + } else { 564 + elt.classList && elt.classList.add(clazz); 565 + } 566 + } 567 + 568 + function removeClassFromElement(elt, clazz, delay) { 569 + elt = resolveTarget(elt); 570 + if (delay) { 571 + setTimeout(function(){ 572 + removeClassFromElement(elt, clazz); 573 + elt = null; 574 + }, delay); 575 + } else { 576 + if (elt.classList) { 577 + elt.classList.remove(clazz); 578 + // if there are no classes left, remove the class attribute 579 + if (elt.classList.length === 0) { 580 + elt.removeAttribute("class"); 581 + } 582 + } 583 + } 584 + } 585 + 586 + function toggleClassOnElement(elt, clazz) { 587 + elt = resolveTarget(elt); 588 + elt.classList.toggle(clazz); 589 + } 590 + 591 + function takeClassForElement(elt, clazz) { 592 + elt = resolveTarget(elt); 593 + forEach(elt.parentElement.children, function(child){ 594 + removeClassFromElement(child, clazz); 595 + }) 596 + addClassToElement(elt, clazz); 597 + } 598 + 599 + function closest(elt, selector) { 600 + elt = resolveTarget(elt); 601 + if (elt.closest) { 602 + return elt.closest(selector); 603 + } else { 604 + // TODO remove when IE goes away 605 + do{ 606 + if (elt == null || matches(elt, selector)){ 607 + return elt; 608 + } 609 + } 610 + while (elt = elt && parentElt(elt)); 611 + return null; 612 + } 613 + } 614 + 615 + function startsWith(str, prefix) { 616 + return str.substring(0, prefix.length) === prefix 617 + } 618 + 619 + function endsWith(str, suffix) { 620 + return str.substring(str.length - suffix.length) === suffix 621 + } 622 + 623 + function normalizeSelector(selector) { 624 + var trimmedSelector = selector.trim(); 625 + if (startsWith(trimmedSelector, "<") && endsWith(trimmedSelector, "/>")) { 626 + return trimmedSelector.substring(1, trimmedSelector.length - 2); 627 + } else { 628 + return trimmedSelector; 629 + } 630 + } 631 + 632 + function querySelectorAllExt(elt, selector) { 633 + if (selector.indexOf("closest ") === 0) { 634 + return [closest(elt, normalizeSelector(selector.substr(8)))]; 635 + } else if (selector.indexOf("find ") === 0) { 636 + return [find(elt, normalizeSelector(selector.substr(5)))]; 637 + } else if (selector === "next") { 638 + return [elt.nextElementSibling] 639 + } else if (selector.indexOf("next ") === 0) { 640 + return [scanForwardQuery(elt, normalizeSelector(selector.substr(5)))]; 641 + } else if (selector === "previous") { 642 + return [elt.previousElementSibling] 643 + } else if (selector.indexOf("previous ") === 0) { 644 + return [scanBackwardsQuery(elt, normalizeSelector(selector.substr(9)))]; 645 + } else if (selector === 'document') { 646 + return [document]; 647 + } else if (selector === 'window') { 648 + return [window]; 649 + } else if (selector === 'body') { 650 + return [document.body]; 651 + } else { 652 + return getDocument().querySelectorAll(normalizeSelector(selector)); 653 + } 654 + } 655 + 656 + var scanForwardQuery = function(start, match) { 657 + var results = getDocument().querySelectorAll(match); 658 + for (var i = 0; i < results.length; i++) { 659 + var elt = results[i]; 660 + if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_PRECEDING) { 661 + return elt; 662 + } 663 + } 664 + } 665 + 666 + var scanBackwardsQuery = function(start, match) { 667 + var results = getDocument().querySelectorAll(match); 668 + for (var i = results.length - 1; i >= 0; i--) { 669 + var elt = results[i]; 670 + if (elt.compareDocumentPosition(start) === Node.DOCUMENT_POSITION_FOLLOWING) { 671 + return elt; 672 + } 673 + } 674 + } 675 + 676 + function querySelectorExt(eltOrSelector, selector) { 677 + if (selector) { 678 + return querySelectorAllExt(eltOrSelector, selector)[0]; 679 + } else { 680 + return querySelectorAllExt(getDocument().body, eltOrSelector)[0]; 681 + } 682 + } 683 + 684 + function resolveTarget(arg2) { 685 + if (isType(arg2, 'String')) { 686 + return find(arg2); 687 + } else { 688 + return arg2; 689 + } 690 + } 691 + 692 + function processEventArgs(arg1, arg2, arg3) { 693 + if (isFunction(arg2)) { 694 + return { 695 + target: getDocument().body, 696 + event: arg1, 697 + listener: arg2 698 + } 699 + } else { 700 + return { 701 + target: resolveTarget(arg1), 702 + event: arg2, 703 + listener: arg3 704 + } 705 + } 706 + 707 + } 708 + 709 + function addEventListenerImpl(arg1, arg2, arg3) { 710 + ready(function(){ 711 + var eventArgs = processEventArgs(arg1, arg2, arg3); 712 + eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); 713 + }) 714 + var b = isFunction(arg2); 715 + return b ? arg2 : arg3; 716 + } 717 + 718 + function removeEventListenerImpl(arg1, arg2, arg3) { 719 + ready(function(){ 720 + var eventArgs = processEventArgs(arg1, arg2, arg3); 721 + eventArgs.target.removeEventListener(eventArgs.event, eventArgs.listener); 722 + }) 723 + return isFunction(arg2) ? arg2 : arg3; 724 + } 725 + 726 + //==================================================================== 727 + // Node processing 728 + //==================================================================== 729 + 730 + var DUMMY_ELT = getDocument().createElement("output"); // dummy element for bad selectors 731 + function findAttributeTargets(elt, attrName) { 732 + var attrTarget = getClosestAttributeValue(elt, attrName); 733 + if (attrTarget) { 734 + if (attrTarget === "this") { 735 + return [findThisElement(elt, attrName)]; 736 + } else { 737 + var result = querySelectorAllExt(elt, attrTarget); 738 + if (result.length === 0) { 739 + logError('The selector "' + attrTarget + '" on ' + attrName + " returned no matches!"); 740 + return [DUMMY_ELT] 741 + } else { 742 + return result; 743 + } 744 + } 745 + } 746 + } 747 + 748 + function findThisElement(elt, attribute){ 749 + return getClosestMatch(elt, function (elt) { 750 + return getAttributeValue(elt, attribute) != null; 751 + }) 752 + } 753 + 754 + function getTarget(elt) { 755 + var targetStr = getClosestAttributeValue(elt, "hx-target"); 756 + if (targetStr) { 757 + if (targetStr === "this") { 758 + return findThisElement(elt,'hx-target'); 759 + } else { 760 + return querySelectorExt(elt, targetStr) 761 + } 762 + } else { 763 + var data = getInternalData(elt); 764 + if (data.boosted) { 765 + return getDocument().body; 766 + } else { 767 + return elt; 768 + } 769 + } 770 + } 771 + 772 + function shouldSettleAttribute(name) { 773 + var attributesToSettle = htmx.config.attributesToSettle; 774 + for (var i = 0; i < attributesToSettle.length; i++) { 775 + if (name === attributesToSettle[i]) { 776 + return true; 777 + } 778 + } 779 + return false; 780 + } 781 + 782 + function cloneAttributes(mergeTo, mergeFrom) { 783 + forEach(mergeTo.attributes, function (attr) { 784 + if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) { 785 + mergeTo.removeAttribute(attr.name) 786 + } 787 + }); 788 + forEach(mergeFrom.attributes, function (attr) { 789 + if (shouldSettleAttribute(attr.name)) { 790 + mergeTo.setAttribute(attr.name, attr.value); 791 + } 792 + }); 793 + } 794 + 795 + function isInlineSwap(swapStyle, target) { 796 + var extensions = getExtensions(target); 797 + for (var i = 0; i < extensions.length; i++) { 798 + var extension = extensions[i]; 799 + try { 800 + if (extension.isInlineSwap(swapStyle)) { 801 + return true; 802 + } 803 + } catch(e) { 804 + logError(e); 805 + } 806 + } 807 + return swapStyle === "outerHTML"; 808 + } 809 + 810 + /** 811 + * 812 + * @param {string} oobValue 813 + * @param {HTMLElement} oobElement 814 + * @param {*} settleInfo 815 + * @returns 816 + */ 817 + function oobSwap(oobValue, oobElement, settleInfo) { 818 + var selector = "#" + getRawAttribute(oobElement, "id"); 819 + var swapStyle = "outerHTML"; 820 + if (oobValue === "true") { 821 + // do nothing 822 + } else if (oobValue.indexOf(":") > 0) { 823 + swapStyle = oobValue.substr(0, oobValue.indexOf(":")); 824 + selector = oobValue.substr(oobValue.indexOf(":") + 1, oobValue.length); 825 + } else { 826 + swapStyle = oobValue; 827 + } 828 + 829 + var targets = getDocument().querySelectorAll(selector); 830 + if (targets) { 831 + forEach( 832 + targets, 833 + function (target) { 834 + var fragment; 835 + var oobElementClone = oobElement.cloneNode(true); 836 + fragment = getDocument().createDocumentFragment(); 837 + fragment.appendChild(oobElementClone); 838 + if (!isInlineSwap(swapStyle, target)) { 839 + fragment = oobElementClone; // if this is not an inline swap, we use the content of the node, not the node itself 840 + } 841 + 842 + var beforeSwapDetails = {shouldSwap: true, target: target, fragment:fragment }; 843 + if (!triggerEvent(target, 'htmx:oobBeforeSwap', beforeSwapDetails)) return; 844 + 845 + target = beforeSwapDetails.target; // allow re-targeting 846 + if (beforeSwapDetails['shouldSwap']){ 847 + swap(swapStyle, target, target, fragment, settleInfo); 848 + } 849 + forEach(settleInfo.elts, function (elt) { 850 + triggerEvent(elt, 'htmx:oobAfterSwap', beforeSwapDetails); 851 + }); 852 + } 853 + ); 854 + oobElement.parentNode.removeChild(oobElement); 855 + } else { 856 + oobElement.parentNode.removeChild(oobElement); 857 + triggerErrorEvent(getDocument().body, "htmx:oobErrorNoTarget", {content: oobElement}); 858 + } 859 + return oobValue; 860 + } 861 + 862 + function handleOutOfBandSwaps(elt, fragment, settleInfo) { 863 + var oobSelects = getClosestAttributeValue(elt, "hx-select-oob"); 864 + if (oobSelects) { 865 + var oobSelectValues = oobSelects.split(","); 866 + for (var i = 0; i < oobSelectValues.length; i++) { 867 + var oobSelectValue = oobSelectValues[i].split(":", 2); 868 + var id = oobSelectValue[0].trim(); 869 + if (id.indexOf("#") === 0) { 870 + id = id.substring(1); 871 + } 872 + var oobValue = oobSelectValue[1] || "true"; 873 + var oobElement = fragment.querySelector("#" + id); 874 + if (oobElement) { 875 + oobSwap(oobValue, oobElement, settleInfo); 876 + } 877 + } 878 + } 879 + forEach(findAll(fragment, '[hx-swap-oob], [data-hx-swap-oob]'), function (oobElement) { 880 + var oobValue = getAttributeValue(oobElement, "hx-swap-oob"); 881 + if (oobValue != null) { 882 + oobSwap(oobValue, oobElement, settleInfo); 883 + } 884 + }); 885 + } 886 + 887 + function handlePreservedElements(fragment) { 888 + forEach(findAll(fragment, '[hx-preserve], [data-hx-preserve]'), function (preservedElt) { 889 + var id = getAttributeValue(preservedElt, "id"); 890 + var oldElt = getDocument().getElementById(id); 891 + if (oldElt != null) { 892 + preservedElt.parentNode.replaceChild(oldElt, preservedElt); 893 + } 894 + }); 895 + } 896 + 897 + function handleAttributes(parentNode, fragment, settleInfo) { 898 + forEach(fragment.querySelectorAll("[id]"), function (newNode) { 899 + var id = getRawAttribute(newNode, "id") 900 + if (id && id.length > 0) { 901 + var normalizedId = id.replace("'", "\\'"); 902 + var normalizedTag = newNode.tagName.replace(':', '\\:'); 903 + var oldNode = parentNode.querySelector(normalizedTag + "[id='" + normalizedId + "']"); 904 + if (oldNode && oldNode !== parentNode) { 905 + var newAttributes = newNode.cloneNode(); 906 + cloneAttributes(newNode, oldNode); 907 + settleInfo.tasks.push(function () { 908 + cloneAttributes(newNode, newAttributes); 909 + }); 910 + } 911 + } 912 + }); 913 + } 914 + 915 + function makeAjaxLoadTask(child) { 916 + return function () { 917 + removeClassFromElement(child, htmx.config.addedClass); 918 + processNode(child); 919 + processScripts(child); 920 + processFocus(child) 921 + triggerEvent(child, 'htmx:load'); 922 + }; 923 + } 924 + 925 + function processFocus(child) { 926 + var autofocus = "[autofocus]"; 927 + var autoFocusedElt = matches(child, autofocus) ? child : child.querySelector(autofocus) 928 + if (autoFocusedElt != null) { 929 + autoFocusedElt.focus(); 930 + } 931 + } 932 + 933 + function insertNodesBefore(parentNode, insertBefore, fragment, settleInfo) { 934 + handleAttributes(parentNode, fragment, settleInfo); 935 + while(fragment.childNodes.length > 0){ 936 + var child = fragment.firstChild; 937 + addClassToElement(child, htmx.config.addedClass); 938 + parentNode.insertBefore(child, insertBefore); 939 + if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { 940 + settleInfo.tasks.push(makeAjaxLoadTask(child)); 941 + } 942 + } 943 + } 944 + 945 + // based on https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0, 946 + // derived from Java's string hashcode implementation 947 + function stringHash(string, hash) { 948 + var char = 0; 949 + while (char < string.length){ 950 + hash = (hash << 5) - hash + string.charCodeAt(char++) | 0; // bitwise or ensures we have a 32-bit int 951 + } 952 + return hash; 953 + } 954 + 955 + function attributeHash(elt) { 956 + var hash = 0; 957 + // IE fix 958 + if (elt.attributes) { 959 + for (var i = 0; i < elt.attributes.length; i++) { 960 + var attribute = elt.attributes[i]; 961 + if(attribute.value){ // only include attributes w/ actual values (empty is same as non-existent) 962 + hash = stringHash(attribute.name, hash); 963 + hash = stringHash(attribute.value, hash); 964 + } 965 + } 966 + } 967 + return hash; 968 + } 969 + 970 + function deInitOnHandlers(elt) { 971 + var internalData = getInternalData(elt); 972 + if (internalData.onHandlers) { 973 + for (var i = 0; i < internalData.onHandlers.length; i++) { 974 + const handlerInfo = internalData.onHandlers[i]; 975 + elt.removeEventListener(handlerInfo.event, handlerInfo.listener); 976 + } 977 + delete internalData.onHandlers 978 + } 979 + } 980 + 981 + function deInitNode(element) { 982 + var internalData = getInternalData(element); 983 + if (internalData.timeout) { 984 + clearTimeout(internalData.timeout); 985 + } 986 + if (internalData.webSocket) { 987 + internalData.webSocket.close(); 988 + } 989 + if (internalData.sseEventSource) { 990 + internalData.sseEventSource.close(); 991 + } 992 + if (internalData.listenerInfos) { 993 + forEach(internalData.listenerInfos, function (info) { 994 + if (info.on) { 995 + info.on.removeEventListener(info.trigger, info.listener); 996 + } 997 + }); 998 + } 999 + deInitOnHandlers(element); 1000 + forEach(Object.keys(internalData), function(key) { delete internalData[key] }); 1001 + } 1002 + 1003 + function cleanUpElement(element) { 1004 + triggerEvent(element, "htmx:beforeCleanupElement") 1005 + deInitNode(element); 1006 + if (element.children) { // IE 1007 + forEach(element.children, function(child) { cleanUpElement(child) }); 1008 + } 1009 + } 1010 + 1011 + function swapOuterHTML(target, fragment, settleInfo) { 1012 + if (target.tagName === "BODY") { 1013 + return swapInnerHTML(target, fragment, settleInfo); 1014 + } else { 1015 + // @type {HTMLElement} 1016 + var newElt 1017 + var eltBeforeNewContent = target.previousSibling; 1018 + insertNodesBefore(parentElt(target), target, fragment, settleInfo); 1019 + if (eltBeforeNewContent == null) { 1020 + newElt = parentElt(target).firstChild; 1021 + } else { 1022 + newElt = eltBeforeNewContent.nextSibling; 1023 + } 1024 + settleInfo.elts = settleInfo.elts.filter(function(e) { return e != target }); 1025 + while(newElt && newElt !== target) { 1026 + if (newElt.nodeType === Node.ELEMENT_NODE) { 1027 + settleInfo.elts.push(newElt); 1028 + } 1029 + newElt = newElt.nextElementSibling; 1030 + } 1031 + cleanUpElement(target); 1032 + parentElt(target).removeChild(target); 1033 + } 1034 + } 1035 + 1036 + function swapAfterBegin(target, fragment, settleInfo) { 1037 + return insertNodesBefore(target, target.firstChild, fragment, settleInfo); 1038 + } 1039 + 1040 + function swapBeforeBegin(target, fragment, settleInfo) { 1041 + return insertNodesBefore(parentElt(target), target, fragment, settleInfo); 1042 + } 1043 + 1044 + function swapBeforeEnd(target, fragment, settleInfo) { 1045 + return insertNodesBefore(target, null, fragment, settleInfo); 1046 + } 1047 + 1048 + function swapAfterEnd(target, fragment, settleInfo) { 1049 + return insertNodesBefore(parentElt(target), target.nextSibling, fragment, settleInfo); 1050 + } 1051 + function swapDelete(target, fragment, settleInfo) { 1052 + cleanUpElement(target); 1053 + return parentElt(target).removeChild(target); 1054 + } 1055 + 1056 + function swapInnerHTML(target, fragment, settleInfo) { 1057 + var firstChild = target.firstChild; 1058 + insertNodesBefore(target, firstChild, fragment, settleInfo); 1059 + if (firstChild) { 1060 + while (firstChild.nextSibling) { 1061 + cleanUpElement(firstChild.nextSibling) 1062 + target.removeChild(firstChild.nextSibling); 1063 + } 1064 + cleanUpElement(firstChild) 1065 + target.removeChild(firstChild); 1066 + } 1067 + } 1068 + 1069 + function maybeSelectFromResponse(elt, fragment, selectOverride) { 1070 + var selector = selectOverride || getClosestAttributeValue(elt, "hx-select"); 1071 + if (selector) { 1072 + var newFragment = getDocument().createDocumentFragment(); 1073 + forEach(fragment.querySelectorAll(selector), function (node) { 1074 + newFragment.appendChild(node); 1075 + }); 1076 + fragment = newFragment; 1077 + } 1078 + return fragment; 1079 + } 1080 + 1081 + function swap(swapStyle, elt, target, fragment, settleInfo) { 1082 + switch (swapStyle) { 1083 + case "none": 1084 + return; 1085 + case "outerHTML": 1086 + swapOuterHTML(target, fragment, settleInfo); 1087 + return; 1088 + case "afterbegin": 1089 + swapAfterBegin(target, fragment, settleInfo); 1090 + return; 1091 + case "beforebegin": 1092 + swapBeforeBegin(target, fragment, settleInfo); 1093 + return; 1094 + case "beforeend": 1095 + swapBeforeEnd(target, fragment, settleInfo); 1096 + return; 1097 + case "afterend": 1098 + swapAfterEnd(target, fragment, settleInfo); 1099 + return; 1100 + case "delete": 1101 + swapDelete(target, fragment, settleInfo); 1102 + return; 1103 + default: 1104 + var extensions = getExtensions(elt); 1105 + for (var i = 0; i < extensions.length; i++) { 1106 + var ext = extensions[i]; 1107 + try { 1108 + var newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo); 1109 + if (newElements) { 1110 + if (typeof newElements.length !== 'undefined') { 1111 + // if handleSwap returns an array (like) of elements, we handle them 1112 + for (var j = 0; j < newElements.length; j++) { 1113 + var child = newElements[j]; 1114 + if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { 1115 + settleInfo.tasks.push(makeAjaxLoadTask(child)); 1116 + } 1117 + } 1118 + } 1119 + return; 1120 + } 1121 + } catch (e) { 1122 + logError(e); 1123 + } 1124 + } 1125 + if (swapStyle === "innerHTML") { 1126 + swapInnerHTML(target, fragment, settleInfo); 1127 + } else { 1128 + swap(htmx.config.defaultSwapStyle, elt, target, fragment, settleInfo); 1129 + } 1130 + } 1131 + } 1132 + 1133 + function findTitle(content) { 1134 + if (content.indexOf('<title') > -1) { 1135 + var contentWithSvgsRemoved = content.replace(SVG_TAGS_REGEX, ''); 1136 + var result = contentWithSvgsRemoved.match(TITLE_TAG_REGEX); 1137 + if (result) { 1138 + return result[2]; 1139 + } 1140 + } 1141 + } 1142 + 1143 + function selectAndSwap(swapStyle, target, elt, responseText, settleInfo, selectOverride) { 1144 + settleInfo.title = findTitle(responseText); 1145 + var fragment = makeFragment(responseText); 1146 + if (fragment) { 1147 + handleOutOfBandSwaps(elt, fragment, settleInfo); 1148 + fragment = maybeSelectFromResponse(elt, fragment, selectOverride); 1149 + handlePreservedElements(fragment); 1150 + return swap(swapStyle, elt, target, fragment, settleInfo); 1151 + } 1152 + } 1153 + 1154 + function handleTrigger(xhr, header, elt) { 1155 + var triggerBody = xhr.getResponseHeader(header); 1156 + if (triggerBody.indexOf("{") === 0) { 1157 + var triggers = parseJSON(triggerBody); 1158 + for (var eventName in triggers) { 1159 + if (triggers.hasOwnProperty(eventName)) { 1160 + var detail = triggers[eventName]; 1161 + if (!isRawObject(detail)) { 1162 + detail = {"value": detail} 1163 + } 1164 + triggerEvent(elt, eventName, detail); 1165 + } 1166 + } 1167 + } else { 1168 + var eventNames = triggerBody.split(",") 1169 + for (var i = 0; i < eventNames.length; i++) { 1170 + triggerEvent(elt, eventNames[i].trim(), []); 1171 + } 1172 + } 1173 + } 1174 + 1175 + var WHITESPACE = /\s/; 1176 + var WHITESPACE_OR_COMMA = /[\s,]/; 1177 + var SYMBOL_START = /[_$a-zA-Z]/; 1178 + var SYMBOL_CONT = /[_$a-zA-Z0-9]/; 1179 + var STRINGISH_START = ['"', "'", "/"]; 1180 + var NOT_WHITESPACE = /[^\s]/; 1181 + var COMBINED_SELECTOR_START = /[{(]/; 1182 + var COMBINED_SELECTOR_END = /[})]/; 1183 + function tokenizeString(str) { 1184 + var tokens = []; 1185 + var position = 0; 1186 + while (position < str.length) { 1187 + if(SYMBOL_START.exec(str.charAt(position))) { 1188 + var startPosition = position; 1189 + while (SYMBOL_CONT.exec(str.charAt(position + 1))) { 1190 + position++; 1191 + } 1192 + tokens.push(str.substr(startPosition, position - startPosition + 1)); 1193 + } else if (STRINGISH_START.indexOf(str.charAt(position)) !== -1) { 1194 + var startChar = str.charAt(position); 1195 + var startPosition = position; 1196 + position++; 1197 + while (position < str.length && str.charAt(position) !== startChar ) { 1198 + if (str.charAt(position) === "\\") { 1199 + position++; 1200 + } 1201 + position++; 1202 + } 1203 + tokens.push(str.substr(startPosition, position - startPosition + 1)); 1204 + } else { 1205 + var symbol = str.charAt(position); 1206 + tokens.push(symbol); 1207 + } 1208 + position++; 1209 + } 1210 + return tokens; 1211 + } 1212 + 1213 + function isPossibleRelativeReference(token, last, paramName) { 1214 + return SYMBOL_START.exec(token.charAt(0)) && 1215 + token !== "true" && 1216 + token !== "false" && 1217 + token !== "this" && 1218 + token !== paramName && 1219 + last !== "."; 1220 + } 1221 + 1222 + function maybeGenerateConditional(elt, tokens, paramName) { 1223 + if (tokens[0] === '[') { 1224 + tokens.shift(); 1225 + var bracketCount = 1; 1226 + var conditionalSource = " return (function(" + paramName + "){ return ("; 1227 + var last = null; 1228 + while (tokens.length > 0) { 1229 + var token = tokens[0]; 1230 + if (token === "]") { 1231 + bracketCount--; 1232 + if (bracketCount === 0) { 1233 + if (last === null) { 1234 + conditionalSource = conditionalSource + "true"; 1235 + } 1236 + tokens.shift(); 1237 + conditionalSource += ")})"; 1238 + try { 1239 + var conditionFunction = maybeEval(elt,function () { 1240 + return Function(conditionalSource)(); 1241 + }, 1242 + function(){return true}) 1243 + conditionFunction.source = conditionalSource; 1244 + return conditionFunction; 1245 + } catch (e) { 1246 + triggerErrorEvent(getDocument().body, "htmx:syntax:error", {error:e, source:conditionalSource}) 1247 + return null; 1248 + } 1249 + } 1250 + } else if (token === "[") { 1251 + bracketCount++; 1252 + } 1253 + if (isPossibleRelativeReference(token, last, paramName)) { 1254 + conditionalSource += "((" + paramName + "." + token + ") ? (" + paramName + "." + token + ") : (window." + token + "))"; 1255 + } else { 1256 + conditionalSource = conditionalSource + token; 1257 + } 1258 + last = tokens.shift(); 1259 + } 1260 + } 1261 + } 1262 + 1263 + function consumeUntil(tokens, match) { 1264 + var result = ""; 1265 + while (tokens.length > 0 && !match.test(tokens[0])) { 1266 + result += tokens.shift(); 1267 + } 1268 + return result; 1269 + } 1270 + 1271 + function consumeCSSSelector(tokens) { 1272 + var result; 1273 + if (tokens.length > 0 && COMBINED_SELECTOR_START.test(tokens[0])) { 1274 + tokens.shift(); 1275 + result = consumeUntil(tokens, COMBINED_SELECTOR_END).trim(); 1276 + tokens.shift(); 1277 + } else { 1278 + result = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1279 + } 1280 + return result; 1281 + } 1282 + 1283 + var INPUT_SELECTOR = 'input, textarea, select'; 1284 + 1285 + /** 1286 + * @param {HTMLElement} elt 1287 + * @param {string} explicitTrigger 1288 + * @param {cache} cache for trigger specs 1289 + * @returns {import("./htmx").HtmxTriggerSpecification[]} 1290 + */ 1291 + function parseAndCacheTrigger(elt, explicitTrigger, cache) { 1292 + var triggerSpecs = []; 1293 + var tokens = tokenizeString(explicitTrigger); 1294 + do { 1295 + consumeUntil(tokens, NOT_WHITESPACE); 1296 + var initialLength = tokens.length; 1297 + var trigger = consumeUntil(tokens, /[,\[\s]/); 1298 + if (trigger !== "") { 1299 + if (trigger === "every") { 1300 + var every = {trigger: 'every'}; 1301 + consumeUntil(tokens, NOT_WHITESPACE); 1302 + every.pollInterval = parseInterval(consumeUntil(tokens, /[,\[\s]/)); 1303 + consumeUntil(tokens, NOT_WHITESPACE); 1304 + var eventFilter = maybeGenerateConditional(elt, tokens, "event"); 1305 + if (eventFilter) { 1306 + every.eventFilter = eventFilter; 1307 + } 1308 + triggerSpecs.push(every); 1309 + } else if (trigger.indexOf("sse:") === 0) { 1310 + triggerSpecs.push({trigger: 'sse', sseEvent: trigger.substr(4)}); 1311 + } else { 1312 + var triggerSpec = {trigger: trigger}; 1313 + var eventFilter = maybeGenerateConditional(elt, tokens, "event"); 1314 + if (eventFilter) { 1315 + triggerSpec.eventFilter = eventFilter; 1316 + } 1317 + while (tokens.length > 0 && tokens[0] !== ",") { 1318 + consumeUntil(tokens, NOT_WHITESPACE) 1319 + var token = tokens.shift(); 1320 + if (token === "changed") { 1321 + triggerSpec.changed = true; 1322 + } else if (token === "once") { 1323 + triggerSpec.once = true; 1324 + } else if (token === "consume") { 1325 + triggerSpec.consume = true; 1326 + } else if (token === "delay" && tokens[0] === ":") { 1327 + tokens.shift(); 1328 + triggerSpec.delay = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); 1329 + } else if (token === "from" && tokens[0] === ":") { 1330 + tokens.shift(); 1331 + if (COMBINED_SELECTOR_START.test(tokens[0])) { 1332 + var from_arg = consumeCSSSelector(tokens); 1333 + } else { 1334 + var from_arg = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1335 + if (from_arg === "closest" || from_arg === "find" || from_arg === "next" || from_arg === "previous") { 1336 + tokens.shift(); 1337 + var selector = consumeCSSSelector(tokens); 1338 + // `next` and `previous` allow a selector-less syntax 1339 + if (selector.length > 0) { 1340 + from_arg += " " + selector; 1341 + } 1342 + } 1343 + } 1344 + triggerSpec.from = from_arg; 1345 + } else if (token === "target" && tokens[0] === ":") { 1346 + tokens.shift(); 1347 + triggerSpec.target = consumeCSSSelector(tokens); 1348 + } else if (token === "throttle" && tokens[0] === ":") { 1349 + tokens.shift(); 1350 + triggerSpec.throttle = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); 1351 + } else if (token === "queue" && tokens[0] === ":") { 1352 + tokens.shift(); 1353 + triggerSpec.queue = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1354 + } else if (token === "root" && tokens[0] === ":") { 1355 + tokens.shift(); 1356 + triggerSpec[token] = consumeCSSSelector(tokens); 1357 + } else if (token === "threshold" && tokens[0] === ":") { 1358 + tokens.shift(); 1359 + triggerSpec[token] = consumeUntil(tokens, WHITESPACE_OR_COMMA); 1360 + } else { 1361 + triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()}); 1362 + } 1363 + } 1364 + triggerSpecs.push(triggerSpec); 1365 + } 1366 + } 1367 + if (tokens.length === initialLength) { 1368 + triggerErrorEvent(elt, "htmx:syntax:error", {token:tokens.shift()}); 1369 + } 1370 + consumeUntil(tokens, NOT_WHITESPACE); 1371 + } while (tokens[0] === "," && tokens.shift()) 1372 + if (cache) { 1373 + cache[explicitTrigger] = triggerSpecs 1374 + } 1375 + return triggerSpecs 1376 + } 1377 + 1378 + /** 1379 + * @param {HTMLElement} elt 1380 + * @returns {import("./htmx").HtmxTriggerSpecification[]} 1381 + */ 1382 + function getTriggerSpecs(elt) { 1383 + var explicitTrigger = getAttributeValue(elt, 'hx-trigger'); 1384 + var triggerSpecs = []; 1385 + if (explicitTrigger) { 1386 + var cache = htmx.config.triggerSpecsCache 1387 + triggerSpecs = (cache && cache[explicitTrigger]) || parseAndCacheTrigger(elt, explicitTrigger, cache) 1388 + } 1389 + 1390 + if (triggerSpecs.length > 0) { 1391 + return triggerSpecs; 1392 + } else if (matches(elt, 'form')) { 1393 + return [{trigger: 'submit'}]; 1394 + } else if (matches(elt, 'input[type="button"], input[type="submit"]')){ 1395 + return [{trigger: 'click'}]; 1396 + } else if (matches(elt, INPUT_SELECTOR)) { 1397 + return [{trigger: 'change'}]; 1398 + } else { 1399 + return [{trigger: 'click'}]; 1400 + } 1401 + } 1402 + 1403 + function cancelPolling(elt) { 1404 + getInternalData(elt).cancelled = true; 1405 + } 1406 + 1407 + function processPolling(elt, handler, spec) { 1408 + var nodeData = getInternalData(elt); 1409 + nodeData.timeout = setTimeout(function () { 1410 + if (bodyContains(elt) && nodeData.cancelled !== true) { 1411 + if (!maybeFilterEvent(spec, elt, makeEvent('hx:poll:trigger', { 1412 + triggerSpec: spec, 1413 + target: elt 1414 + }))) { 1415 + handler(elt); 1416 + } 1417 + processPolling(elt, handler, spec); 1418 + } 1419 + }, spec.pollInterval); 1420 + } 1421 + 1422 + function isLocalLink(elt) { 1423 + return location.hostname === elt.hostname && 1424 + getRawAttribute(elt,'href') && 1425 + getRawAttribute(elt,'href').indexOf("#") !== 0; 1426 + } 1427 + 1428 + function boostElement(elt, nodeData, triggerSpecs) { 1429 + if ((elt.tagName === "A" && isLocalLink(elt) && (elt.target === "" || elt.target === "_self")) || elt.tagName === "FORM") { 1430 + nodeData.boosted = true; 1431 + var verb, path; 1432 + if (elt.tagName === "A") { 1433 + verb = "get"; 1434 + path = getRawAttribute(elt, 'href') 1435 + } else { 1436 + var rawAttribute = getRawAttribute(elt, "method"); 1437 + verb = rawAttribute ? rawAttribute.toLowerCase() : "get"; 1438 + if (verb === "get") { 1439 + } 1440 + path = getRawAttribute(elt, 'action'); 1441 + } 1442 + triggerSpecs.forEach(function(triggerSpec) { 1443 + addEventListener(elt, function(elt, evt) { 1444 + if (closest(elt, htmx.config.disableSelector)) { 1445 + cleanUpElement(elt) 1446 + return 1447 + } 1448 + issueAjaxRequest(verb, path, elt, evt) 1449 + }, nodeData, triggerSpec, true); 1450 + }); 1451 + } 1452 + } 1453 + 1454 + /** 1455 + * 1456 + * @param {Event} evt 1457 + * @param {HTMLElement} elt 1458 + * @returns 1459 + */ 1460 + function shouldCancel(evt, elt) { 1461 + if (evt.type === "submit" || evt.type === "click") { 1462 + if (elt.tagName === "FORM") { 1463 + return true; 1464 + } 1465 + if (matches(elt, 'input[type="submit"], button') && closest(elt, 'form') !== null) { 1466 + return true; 1467 + } 1468 + if (elt.tagName === "A" && elt.href && 1469 + (elt.getAttribute('href') === '#' || elt.getAttribute('href').indexOf("#") !== 0)) { 1470 + return true; 1471 + } 1472 + } 1473 + return false; 1474 + } 1475 + 1476 + function ignoreBoostedAnchorCtrlClick(elt, evt) { 1477 + return getInternalData(elt).boosted && elt.tagName === "A" && evt.type === "click" && (evt.ctrlKey || evt.metaKey); 1478 + } 1479 + 1480 + function maybeFilterEvent(triggerSpec, elt, evt) { 1481 + var eventFilter = triggerSpec.eventFilter; 1482 + if(eventFilter){ 1483 + try { 1484 + return eventFilter.call(elt, evt) !== true; 1485 + } catch(e) { 1486 + triggerErrorEvent(getDocument().body, "htmx:eventFilter:error", {error: e, source:eventFilter.source}); 1487 + return true; 1488 + } 1489 + } 1490 + return false; 1491 + } 1492 + 1493 + function addEventListener(elt, handler, nodeData, triggerSpec, explicitCancel) { 1494 + var elementData = getInternalData(elt); 1495 + var eltsToListenOn; 1496 + if (triggerSpec.from) { 1497 + eltsToListenOn = querySelectorAllExt(elt, triggerSpec.from); 1498 + } else { 1499 + eltsToListenOn = [elt]; 1500 + } 1501 + // store the initial values of the elements, so we can tell if they change 1502 + if (triggerSpec.changed) { 1503 + eltsToListenOn.forEach(function (eltToListenOn) { 1504 + var eltToListenOnData = getInternalData(eltToListenOn); 1505 + eltToListenOnData.lastValue = eltToListenOn.value; 1506 + }) 1507 + } 1508 + forEach(eltsToListenOn, function (eltToListenOn) { 1509 + var eventListener = function (evt) { 1510 + if (!bodyContains(elt)) { 1511 + eltToListenOn.removeEventListener(triggerSpec.trigger, eventListener); 1512 + return; 1513 + } 1514 + if (ignoreBoostedAnchorCtrlClick(elt, evt)) { 1515 + return; 1516 + } 1517 + if (explicitCancel || shouldCancel(evt, elt)) { 1518 + evt.preventDefault(); 1519 + } 1520 + if (maybeFilterEvent(triggerSpec, elt, evt)) { 1521 + return; 1522 + } 1523 + var eventData = getInternalData(evt); 1524 + eventData.triggerSpec = triggerSpec; 1525 + if (eventData.handledFor == null) { 1526 + eventData.handledFor = []; 1527 + } 1528 + if (eventData.handledFor.indexOf(elt) < 0) { 1529 + eventData.handledFor.push(elt); 1530 + if (triggerSpec.consume) { 1531 + evt.stopPropagation(); 1532 + } 1533 + if (triggerSpec.target && evt.target) { 1534 + if (!matches(evt.target, triggerSpec.target)) { 1535 + return; 1536 + } 1537 + } 1538 + if (triggerSpec.once) { 1539 + if (elementData.triggeredOnce) { 1540 + return; 1541 + } else { 1542 + elementData.triggeredOnce = true; 1543 + } 1544 + } 1545 + if (triggerSpec.changed) { 1546 + var eltToListenOnData = getInternalData(eltToListenOn) 1547 + if (eltToListenOnData.lastValue === eltToListenOn.value) { 1548 + return; 1549 + } 1550 + eltToListenOnData.lastValue = eltToListenOn.value 1551 + } 1552 + if (elementData.delayed) { 1553 + clearTimeout(elementData.delayed); 1554 + } 1555 + if (elementData.throttle) { 1556 + return; 1557 + } 1558 + 1559 + if (triggerSpec.throttle > 0) { 1560 + if (!elementData.throttle) { 1561 + handler(elt, evt); 1562 + elementData.throttle = setTimeout(function () { 1563 + elementData.throttle = null; 1564 + }, triggerSpec.throttle); 1565 + } 1566 + } else if (triggerSpec.delay > 0) { 1567 + elementData.delayed = setTimeout(function() { handler(elt, evt) }, triggerSpec.delay); 1568 + } else { 1569 + triggerEvent(elt, 'htmx:trigger') 1570 + handler(elt, evt); 1571 + } 1572 + } 1573 + }; 1574 + if (nodeData.listenerInfos == null) { 1575 + nodeData.listenerInfos = []; 1576 + } 1577 + nodeData.listenerInfos.push({ 1578 + trigger: triggerSpec.trigger, 1579 + listener: eventListener, 1580 + on: eltToListenOn 1581 + }) 1582 + eltToListenOn.addEventListener(triggerSpec.trigger, eventListener); 1583 + }); 1584 + } 1585 + 1586 + var windowIsScrolling = false // used by initScrollHandler 1587 + var scrollHandler = null; 1588 + function initScrollHandler() { 1589 + if (!scrollHandler) { 1590 + scrollHandler = function() { 1591 + windowIsScrolling = true 1592 + }; 1593 + window.addEventListener("scroll", scrollHandler) 1594 + setInterval(function() { 1595 + if (windowIsScrolling) { 1596 + windowIsScrolling = false; 1597 + forEach(getDocument().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"), function (elt) { 1598 + maybeReveal(elt); 1599 + }) 1600 + } 1601 + }, 200); 1602 + } 1603 + } 1604 + 1605 + function maybeReveal(elt) { 1606 + if (!hasAttribute(elt,'data-hx-revealed') && isScrolledIntoView(elt)) { 1607 + elt.setAttribute('data-hx-revealed', 'true'); 1608 + var nodeData = getInternalData(elt); 1609 + if (nodeData.initHash) { 1610 + triggerEvent(elt, 'revealed'); 1611 + } else { 1612 + // if the node isn't initialized, wait for it before triggering the request 1613 + elt.addEventListener("htmx:afterProcessNode", function(evt) { triggerEvent(elt, 'revealed') }, {once: true}); 1614 + } 1615 + } 1616 + } 1617 + 1618 + //==================================================================== 1619 + // Web Sockets 1620 + //==================================================================== 1621 + 1622 + function processWebSocketInfo(elt, nodeData, info) { 1623 + var values = splitOnWhitespace(info); 1624 + for (var i = 0; i < values.length; i++) { 1625 + var value = values[i].split(/:(.+)/); 1626 + if (value[0] === "connect") { 1627 + ensureWebSocket(elt, value[1], 0); 1628 + } 1629 + if (value[0] === "send") { 1630 + processWebSocketSend(elt); 1631 + } 1632 + } 1633 + } 1634 + 1635 + function ensureWebSocket(elt, wssSource, retryCount) { 1636 + if (!bodyContains(elt)) { 1637 + return; // stop ensuring websocket connection when socket bearing element ceases to exist 1638 + } 1639 + 1640 + if (wssSource.indexOf("/") == 0) { // complete absolute paths only 1641 + var base_part = location.hostname + (location.port ? ':'+location.port: ''); 1642 + if (location.protocol == 'https:') { 1643 + wssSource = "wss://" + base_part + wssSource; 1644 + } else if (location.protocol == 'http:') { 1645 + wssSource = "ws://" + base_part + wssSource; 1646 + } 1647 + } 1648 + var socket = htmx.createWebSocket(wssSource); 1649 + socket.onerror = function (e) { 1650 + triggerErrorEvent(elt, "htmx:wsError", {error:e, socket:socket}); 1651 + maybeCloseWebSocketSource(elt); 1652 + }; 1653 + 1654 + socket.onclose = function (e) { 1655 + if ([1006, 1012, 1013].indexOf(e.code) >= 0) { // Abnormal Closure/Service Restart/Try Again Later 1656 + var delay = getWebSocketReconnectDelay(retryCount); 1657 + setTimeout(function() { 1658 + ensureWebSocket(elt, wssSource, retryCount+1); // creates a websocket with a new timeout 1659 + }, delay); 1660 + } 1661 + }; 1662 + socket.onopen = function (e) { 1663 + retryCount = 0; 1664 + } 1665 + 1666 + getInternalData(elt).webSocket = socket; 1667 + socket.addEventListener('message', function (event) { 1668 + if (maybeCloseWebSocketSource(elt)) { 1669 + return; 1670 + } 1671 + 1672 + var response = event.data; 1673 + withExtensions(elt, function(extension){ 1674 + response = extension.transformResponse(response, null, elt); 1675 + }); 1676 + 1677 + var settleInfo = makeSettleInfo(elt); 1678 + var fragment = makeFragment(response); 1679 + var children = toArray(fragment.children); 1680 + for (var i = 0; i < children.length; i++) { 1681 + var child = children[i]; 1682 + oobSwap(getAttributeValue(child, "hx-swap-oob") || "true", child, settleInfo); 1683 + } 1684 + 1685 + settleImmediately(settleInfo.tasks); 1686 + }); 1687 + } 1688 + 1689 + function maybeCloseWebSocketSource(elt) { 1690 + if (!bodyContains(elt)) { 1691 + getInternalData(elt).webSocket.close(); 1692 + return true; 1693 + } 1694 + } 1695 + 1696 + function processWebSocketSend(elt) { 1697 + var webSocketSourceElt = getClosestMatch(elt, function (parent) { 1698 + return getInternalData(parent).webSocket != null; 1699 + }); 1700 + if (webSocketSourceElt) { 1701 + elt.addEventListener(getTriggerSpecs(elt)[0].trigger, function (evt) { 1702 + var webSocket = getInternalData(webSocketSourceElt).webSocket; 1703 + var headers = getHeaders(elt, webSocketSourceElt); 1704 + var results = getInputValues(elt, 'post'); 1705 + var errors = results.errors; 1706 + var rawParameters = results.values; 1707 + var expressionVars = getExpressionVars(elt); 1708 + var allParameters = mergeObjects(rawParameters, expressionVars); 1709 + var filteredParameters = filterValues(allParameters, elt); 1710 + filteredParameters['HEADERS'] = headers; 1711 + if (errors && errors.length > 0) { 1712 + triggerEvent(elt, 'htmx:validation:halted', errors); 1713 + return; 1714 + } 1715 + webSocket.send(JSON.stringify(filteredParameters)); 1716 + if(shouldCancel(evt, elt)){ 1717 + evt.preventDefault(); 1718 + } 1719 + }); 1720 + } else { 1721 + triggerErrorEvent(elt, "htmx:noWebSocketSourceError"); 1722 + } 1723 + } 1724 + 1725 + function getWebSocketReconnectDelay(retryCount) { 1726 + var delay = htmx.config.wsReconnectDelay; 1727 + if (typeof delay === 'function') { 1728 + // @ts-ignore 1729 + return delay(retryCount); 1730 + } 1731 + if (delay === 'full-jitter') { 1732 + var exp = Math.min(retryCount, 6); 1733 + var maxDelay = 1000 * Math.pow(2, exp); 1734 + return maxDelay * Math.random(); 1735 + } 1736 + logError('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"'); 1737 + } 1738 + 1739 + //==================================================================== 1740 + // Server Sent Events 1741 + //==================================================================== 1742 + 1743 + function processSSEInfo(elt, nodeData, info) { 1744 + var values = splitOnWhitespace(info); 1745 + for (var i = 0; i < values.length; i++) { 1746 + var value = values[i].split(/:(.+)/); 1747 + if (value[0] === "connect") { 1748 + processSSESource(elt, value[1]); 1749 + } 1750 + 1751 + if ((value[0] === "swap")) { 1752 + processSSESwap(elt, value[1]) 1753 + } 1754 + } 1755 + } 1756 + 1757 + function processSSESource(elt, sseSrc) { 1758 + var source = htmx.createEventSource(sseSrc); 1759 + source.onerror = function (e) { 1760 + triggerErrorEvent(elt, "htmx:sseError", {error:e, source:source}); 1761 + maybeCloseSSESource(elt); 1762 + }; 1763 + getInternalData(elt).sseEventSource = source; 1764 + } 1765 + 1766 + function processSSESwap(elt, sseEventName) { 1767 + var sseSourceElt = getClosestMatch(elt, hasEventSource); 1768 + if (sseSourceElt) { 1769 + var sseEventSource = getInternalData(sseSourceElt).sseEventSource; 1770 + var sseListener = function (event) { 1771 + if (maybeCloseSSESource(sseSourceElt)) { 1772 + return; 1773 + } 1774 + if (!bodyContains(elt)) { 1775 + sseEventSource.removeEventListener(sseEventName, sseListener); 1776 + return; 1777 + } 1778 + 1779 + /////////////////////////// 1780 + // TODO: merge this code with AJAX and WebSockets code in the future. 1781 + 1782 + var response = event.data; 1783 + withExtensions(elt, function(extension){ 1784 + response = extension.transformResponse(response, null, elt); 1785 + }); 1786 + 1787 + var swapSpec = getSwapSpecification(elt) 1788 + var target = getTarget(elt) 1789 + var settleInfo = makeSettleInfo(elt); 1790 + 1791 + selectAndSwap(swapSpec.swapStyle, target, elt, response, settleInfo) 1792 + settleImmediately(settleInfo.tasks) 1793 + triggerEvent(elt, "htmx:sseMessage", event) 1794 + }; 1795 + 1796 + getInternalData(elt).sseListener = sseListener; 1797 + sseEventSource.addEventListener(sseEventName, sseListener); 1798 + } else { 1799 + triggerErrorEvent(elt, "htmx:noSSESourceError"); 1800 + } 1801 + } 1802 + 1803 + function processSSETrigger(elt, handler, sseEventName) { 1804 + var sseSourceElt = getClosestMatch(elt, hasEventSource); 1805 + if (sseSourceElt) { 1806 + var sseEventSource = getInternalData(sseSourceElt).sseEventSource; 1807 + var sseListener = function () { 1808 + if (!maybeCloseSSESource(sseSourceElt)) { 1809 + if (bodyContains(elt)) { 1810 + handler(elt); 1811 + } else { 1812 + sseEventSource.removeEventListener(sseEventName, sseListener); 1813 + } 1814 + } 1815 + }; 1816 + getInternalData(elt).sseListener = sseListener; 1817 + sseEventSource.addEventListener(sseEventName, sseListener); 1818 + } else { 1819 + triggerErrorEvent(elt, "htmx:noSSESourceError"); 1820 + } 1821 + } 1822 + 1823 + function maybeCloseSSESource(elt) { 1824 + if (!bodyContains(elt)) { 1825 + getInternalData(elt).sseEventSource.close(); 1826 + return true; 1827 + } 1828 + } 1829 + 1830 + function hasEventSource(node) { 1831 + return getInternalData(node).sseEventSource != null; 1832 + } 1833 + 1834 + //==================================================================== 1835 + 1836 + function loadImmediately(elt, handler, nodeData, delay) { 1837 + var load = function(){ 1838 + if (!nodeData.loaded) { 1839 + nodeData.loaded = true; 1840 + handler(elt); 1841 + } 1842 + } 1843 + if (delay > 0) { 1844 + setTimeout(load, delay); 1845 + } else { 1846 + load(); 1847 + } 1848 + } 1849 + 1850 + function processVerbs(elt, nodeData, triggerSpecs) { 1851 + var explicitAction = false; 1852 + forEach(VERBS, function (verb) { 1853 + if (hasAttribute(elt,'hx-' + verb)) { 1854 + var path = getAttributeValue(elt, 'hx-' + verb); 1855 + explicitAction = true; 1856 + nodeData.path = path; 1857 + nodeData.verb = verb; 1858 + triggerSpecs.forEach(function(triggerSpec) { 1859 + addTriggerHandler(elt, triggerSpec, nodeData, function (elt, evt) { 1860 + if (closest(elt, htmx.config.disableSelector)) { 1861 + cleanUpElement(elt) 1862 + return 1863 + } 1864 + issueAjaxRequest(verb, path, elt, evt) 1865 + }) 1866 + }); 1867 + } 1868 + }); 1869 + return explicitAction; 1870 + } 1871 + 1872 + function addTriggerHandler(elt, triggerSpec, nodeData, handler) { 1873 + if (triggerSpec.sseEvent) { 1874 + processSSETrigger(elt, handler, triggerSpec.sseEvent); 1875 + } else if (triggerSpec.trigger === "revealed") { 1876 + initScrollHandler(); 1877 + addEventListener(elt, handler, nodeData, triggerSpec); 1878 + maybeReveal(elt); 1879 + } else if (triggerSpec.trigger === "intersect") { 1880 + var observerOptions = {}; 1881 + if (triggerSpec.root) { 1882 + observerOptions.root = querySelectorExt(elt, triggerSpec.root) 1883 + } 1884 + if (triggerSpec.threshold) { 1885 + observerOptions.threshold = parseFloat(triggerSpec.threshold); 1886 + } 1887 + var observer = new IntersectionObserver(function (entries) { 1888 + for (var i = 0; i < entries.length; i++) { 1889 + var entry = entries[i]; 1890 + if (entry.isIntersecting) { 1891 + triggerEvent(elt, "intersect"); 1892 + break; 1893 + } 1894 + } 1895 + }, observerOptions); 1896 + observer.observe(elt); 1897 + addEventListener(elt, handler, nodeData, triggerSpec); 1898 + } else if (triggerSpec.trigger === "load") { 1899 + if (!maybeFilterEvent(triggerSpec, elt, makeEvent("load", {elt: elt}))) { 1900 + loadImmediately(elt, handler, nodeData, triggerSpec.delay); 1901 + } 1902 + } else if (triggerSpec.pollInterval > 0) { 1903 + nodeData.polling = true; 1904 + processPolling(elt, handler, triggerSpec); 1905 + } else { 1906 + addEventListener(elt, handler, nodeData, triggerSpec); 1907 + } 1908 + } 1909 + 1910 + function evalScript(script) { 1911 + if (!script.htmxExecuted && htmx.config.allowScriptTags && 1912 + (script.type === "text/javascript" || script.type === "module" || script.type === "") ) { 1913 + var newScript = getDocument().createElement("script"); 1914 + forEach(script.attributes, function (attr) { 1915 + newScript.setAttribute(attr.name, attr.value); 1916 + }); 1917 + newScript.textContent = script.textContent; 1918 + newScript.async = false; 1919 + if (htmx.config.inlineScriptNonce) { 1920 + newScript.nonce = htmx.config.inlineScriptNonce; 1921 + } 1922 + var parent = script.parentElement; 1923 + 1924 + try { 1925 + parent.insertBefore(newScript, script); 1926 + } catch (e) { 1927 + logError(e); 1928 + } finally { 1929 + // remove old script element, but only if it is still in DOM 1930 + if (script.parentElement) { 1931 + script.parentElement.removeChild(script); 1932 + } 1933 + } 1934 + } 1935 + } 1936 + 1937 + function processScripts(elt) { 1938 + if (matches(elt, "script")) { 1939 + evalScript(elt); 1940 + } 1941 + forEach(findAll(elt, "script"), function (script) { 1942 + evalScript(script); 1943 + }); 1944 + } 1945 + 1946 + function shouldProcessHxOn(elt) { 1947 + var attributes = elt.attributes 1948 + for (var j = 0; j < attributes.length; j++) { 1949 + var attrName = attributes[j].name 1950 + if (startsWith(attrName, "hx-on:") || startsWith(attrName, "data-hx-on:") || 1951 + startsWith(attrName, "hx-on-") || startsWith(attrName, "data-hx-on-")) { 1952 + return true 1953 + } 1954 + } 1955 + return false 1956 + } 1957 + 1958 + function findHxOnWildcardElements(elt) { 1959 + var node = null 1960 + var elements = [] 1961 + 1962 + if (shouldProcessHxOn(elt)) { 1963 + elements.push(elt) 1964 + } 1965 + 1966 + if (document.evaluate) { 1967 + var iter = document.evaluate('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or' + 1968 + ' starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]', elt) 1969 + while (node = iter.iterateNext()) elements.push(node) 1970 + } else { 1971 + var allElements = elt.getElementsByTagName("*") 1972 + for (var i = 0; i < allElements.length; i++) { 1973 + if (shouldProcessHxOn(allElements[i])) { 1974 + elements.push(allElements[i]) 1975 + } 1976 + } 1977 + } 1978 + 1979 + return elements 1980 + } 1981 + 1982 + function findElementsToProcess(elt) { 1983 + if (elt.querySelectorAll) { 1984 + var boostedSelector = ", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]"; 1985 + var results = elt.querySelectorAll(VERB_SELECTOR + boostedSelector + ", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws]," + 1986 + " [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]"); 1987 + return results; 1988 + } else { 1989 + return []; 1990 + } 1991 + } 1992 + 1993 + // Handle submit buttons/inputs that have the form attribute set 1994 + // see https://developer.mozilla.org/docs/Web/HTML/Element/button 1995 + function maybeSetLastButtonClicked(evt) { 1996 + var elt = closest(evt.target, "button, input[type='submit']"); 1997 + var internalData = getRelatedFormData(evt) 1998 + if (internalData) { 1999 + internalData.lastButtonClicked = elt; 2000 + } 2001 + }; 2002 + function maybeUnsetLastButtonClicked(evt){ 2003 + var internalData = getRelatedFormData(evt) 2004 + if (internalData) { 2005 + internalData.lastButtonClicked = null; 2006 + } 2007 + } 2008 + function getRelatedFormData(evt) { 2009 + var elt = closest(evt.target, "button, input[type='submit']"); 2010 + if (!elt) { 2011 + return; 2012 + } 2013 + var form = resolveTarget('#' + getRawAttribute(elt, 'form')) || closest(elt, 'form'); 2014 + if (!form) { 2015 + return; 2016 + } 2017 + return getInternalData(form); 2018 + } 2019 + function initButtonTracking(elt) { 2020 + // need to handle both click and focus in: 2021 + // focusin - in case someone tabs in to a button and hits the space bar 2022 + // click - on OSX buttons do not focus on click see https://bugs.webkit.org/show_bug.cgi?id=13724 2023 + elt.addEventListener('click', maybeSetLastButtonClicked) 2024 + elt.addEventListener('focusin', maybeSetLastButtonClicked) 2025 + elt.addEventListener('focusout', maybeUnsetLastButtonClicked) 2026 + } 2027 + 2028 + function countCurlies(line) { 2029 + var tokens = tokenizeString(line); 2030 + var netCurlies = 0; 2031 + for (var i = 0; i < tokens.length; i++) { 2032 + const token = tokens[i]; 2033 + if (token === "{") { 2034 + netCurlies++; 2035 + } else if (token === "}") { 2036 + netCurlies--; 2037 + } 2038 + } 2039 + return netCurlies; 2040 + } 2041 + 2042 + function addHxOnEventHandler(elt, eventName, code) { 2043 + var nodeData = getInternalData(elt); 2044 + if (!Array.isArray(nodeData.onHandlers)) { 2045 + nodeData.onHandlers = []; 2046 + } 2047 + var func; 2048 + var listener = function (e) { 2049 + return maybeEval(elt, function() { 2050 + if (!func) { 2051 + func = new Function("event", code); 2052 + } 2053 + func.call(elt, e); 2054 + }); 2055 + }; 2056 + elt.addEventListener(eventName, listener); 2057 + nodeData.onHandlers.push({event:eventName, listener:listener}); 2058 + } 2059 + 2060 + function processHxOn(elt) { 2061 + var hxOnValue = getAttributeValue(elt, 'hx-on'); 2062 + if (hxOnValue) { 2063 + var handlers = {} 2064 + var lines = hxOnValue.split("\n"); 2065 + var currentEvent = null; 2066 + var curlyCount = 0; 2067 + while (lines.length > 0) { 2068 + var line = lines.shift(); 2069 + var match = line.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/); 2070 + if (curlyCount === 0 && match) { 2071 + line.split(":") 2072 + currentEvent = match[1].slice(0, -1); // strip last colon 2073 + handlers[currentEvent] = match[2]; 2074 + } else { 2075 + handlers[currentEvent] += line; 2076 + } 2077 + curlyCount += countCurlies(line); 2078 + } 2079 + 2080 + for (var eventName in handlers) { 2081 + addHxOnEventHandler(elt, eventName, handlers[eventName]); 2082 + } 2083 + } 2084 + } 2085 + 2086 + function processHxOnWildcard(elt) { 2087 + // wipe any previous on handlers so that this function takes precedence 2088 + deInitOnHandlers(elt) 2089 + 2090 + for (var i = 0; i < elt.attributes.length; i++) { 2091 + var name = elt.attributes[i].name 2092 + var value = elt.attributes[i].value 2093 + if (startsWith(name, "hx-on") || startsWith(name, "data-hx-on")) { 2094 + var afterOnPosition = name.indexOf("-on") + 3; 2095 + var nextChar = name.slice(afterOnPosition, afterOnPosition + 1); 2096 + if (nextChar === "-" || nextChar === ":") { 2097 + var eventName = name.slice(afterOnPosition + 1); 2098 + // if the eventName starts with a colon or dash, prepend "htmx" for shorthand support 2099 + if (startsWith(eventName, ":")) { 2100 + eventName = "htmx" + eventName 2101 + } else if (startsWith(eventName, "-")) { 2102 + eventName = "htmx:" + eventName.slice(1); 2103 + } else if (startsWith(eventName, "htmx-")) { 2104 + eventName = "htmx:" + eventName.slice(5); 2105 + } 2106 + 2107 + addHxOnEventHandler(elt, eventName, value) 2108 + } 2109 + } 2110 + } 2111 + } 2112 + 2113 + function initNode(elt) { 2114 + if (closest(elt, htmx.config.disableSelector)) { 2115 + cleanUpElement(elt) 2116 + return; 2117 + } 2118 + var nodeData = getInternalData(elt); 2119 + if (nodeData.initHash !== attributeHash(elt)) { 2120 + // clean up any previously processed info 2121 + deInitNode(elt); 2122 + 2123 + nodeData.initHash = attributeHash(elt); 2124 + 2125 + processHxOn(elt); 2126 + 2127 + triggerEvent(elt, "htmx:beforeProcessNode") 2128 + 2129 + if (elt.value) { 2130 + nodeData.lastValue = elt.value; 2131 + } 2132 + 2133 + var triggerSpecs = getTriggerSpecs(elt); 2134 + var hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs); 2135 + 2136 + if (!hasExplicitHttpAction) { 2137 + if (getClosestAttributeValue(elt, "hx-boost") === "true") { 2138 + boostElement(elt, nodeData, triggerSpecs); 2139 + } else if (hasAttribute(elt, 'hx-trigger')) { 2140 + triggerSpecs.forEach(function (triggerSpec) { 2141 + // For "naked" triggers, don't do anything at all 2142 + addTriggerHandler(elt, triggerSpec, nodeData, function () { 2143 + }) 2144 + }) 2145 + } 2146 + } 2147 + 2148 + // Handle submit buttons/inputs that have the form attribute set 2149 + // see https://developer.mozilla.org/docs/Web/HTML/Element/button 2150 + if (elt.tagName === "FORM" || (getRawAttribute(elt, "type") === "submit" && hasAttribute(elt, "form"))) { 2151 + initButtonTracking(elt) 2152 + } 2153 + 2154 + var sseInfo = getAttributeValue(elt, 'hx-sse'); 2155 + if (sseInfo) { 2156 + processSSEInfo(elt, nodeData, sseInfo); 2157 + } 2158 + 2159 + var wsInfo = getAttributeValue(elt, 'hx-ws'); 2160 + if (wsInfo) { 2161 + processWebSocketInfo(elt, nodeData, wsInfo); 2162 + } 2163 + triggerEvent(elt, "htmx:afterProcessNode"); 2164 + } 2165 + } 2166 + 2167 + function processNode(elt) { 2168 + elt = resolveTarget(elt); 2169 + if (closest(elt, htmx.config.disableSelector)) { 2170 + cleanUpElement(elt) 2171 + return; 2172 + } 2173 + initNode(elt); 2174 + forEach(findElementsToProcess(elt), function(child) { initNode(child) }); 2175 + // Because it happens second, the new way of adding onHandlers superseeds the old one 2176 + // i.e. if there are any hx-on:eventName attributes, the hx-on attribute will be ignored 2177 + forEach(findHxOnWildcardElements(elt), processHxOnWildcard); 2178 + } 2179 + 2180 + //==================================================================== 2181 + // Event/Log Support 2182 + //==================================================================== 2183 + 2184 + function kebabEventName(str) { 2185 + return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase(); 2186 + } 2187 + 2188 + function makeEvent(eventName, detail) { 2189 + var evt; 2190 + if (window.CustomEvent && typeof window.CustomEvent === 'function') { 2191 + evt = new CustomEvent(eventName, {bubbles: true, cancelable: true, detail: detail}); 2192 + } else { 2193 + evt = getDocument().createEvent('CustomEvent'); 2194 + evt.initCustomEvent(eventName, true, true, detail); 2195 + } 2196 + return evt; 2197 + } 2198 + 2199 + function triggerErrorEvent(elt, eventName, detail) { 2200 + triggerEvent(elt, eventName, mergeObjects({error:eventName}, detail)); 2201 + } 2202 + 2203 + function ignoreEventForLogging(eventName) { 2204 + return eventName === "htmx:afterProcessNode" 2205 + } 2206 + 2207 + /** 2208 + * `withExtensions` locates all active extensions for a provided element, then 2209 + * executes the provided function using each of the active extensions. It should 2210 + * be called internally at every extendable execution point in htmx. 2211 + * 2212 + * @param {HTMLElement} elt 2213 + * @param {(extension:import("./htmx").HtmxExtension) => void} toDo 2214 + * @returns void 2215 + */ 2216 + function withExtensions(elt, toDo) { 2217 + forEach(getExtensions(elt), function(extension){ 2218 + try { 2219 + toDo(extension); 2220 + } catch (e) { 2221 + logError(e); 2222 + } 2223 + }); 2224 + } 2225 + 2226 + function logError(msg) { 2227 + if(console.error) { 2228 + console.error(msg); 2229 + } else if (console.log) { 2230 + console.log("ERROR: ", msg); 2231 + } 2232 + } 2233 + 2234 + function triggerEvent(elt, eventName, detail) { 2235 + elt = resolveTarget(elt); 2236 + if (detail == null) { 2237 + detail = {}; 2238 + } 2239 + detail["elt"] = elt; 2240 + var event = makeEvent(eventName, detail); 2241 + if (htmx.logger && !ignoreEventForLogging(eventName)) { 2242 + htmx.logger(elt, eventName, detail); 2243 + } 2244 + if (detail.error) { 2245 + logError(detail.error); 2246 + triggerEvent(elt, "htmx:error", {errorInfo:detail}) 2247 + } 2248 + var eventResult = elt.dispatchEvent(event); 2249 + var kebabName = kebabEventName(eventName); 2250 + if (eventResult && kebabName !== eventName) { 2251 + var kebabedEvent = makeEvent(kebabName, event.detail); 2252 + eventResult = eventResult && elt.dispatchEvent(kebabedEvent) 2253 + } 2254 + withExtensions(elt, function (extension) { 2255 + eventResult = eventResult && (extension.onEvent(eventName, event) !== false && !event.defaultPrevented) 2256 + }); 2257 + return eventResult; 2258 + } 2259 + 2260 + //==================================================================== 2261 + // History Support 2262 + //==================================================================== 2263 + var currentPathForHistory = location.pathname+location.search; 2264 + 2265 + function getHistoryElement() { 2266 + var historyElt = getDocument().querySelector('[hx-history-elt],[data-hx-history-elt]'); 2267 + return historyElt || getDocument().body; 2268 + } 2269 + 2270 + function saveToHistoryCache(url, content, title, scroll) { 2271 + if (!canAccessLocalStorage()) { 2272 + return; 2273 + } 2274 + 2275 + if (htmx.config.historyCacheSize <= 0) { 2276 + // make sure that an eventually already existing cache is purged 2277 + localStorage.removeItem("htmx-history-cache"); 2278 + return; 2279 + } 2280 + 2281 + url = normalizePath(url); 2282 + 2283 + var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; 2284 + for (var i = 0; i < historyCache.length; i++) { 2285 + if (historyCache[i].url === url) { 2286 + historyCache.splice(i, 1); 2287 + break; 2288 + } 2289 + } 2290 + var newHistoryItem = {url:url, content: content, title:title, scroll:scroll}; 2291 + triggerEvent(getDocument().body, "htmx:historyItemCreated", {item:newHistoryItem, cache: historyCache}) 2292 + historyCache.push(newHistoryItem) 2293 + while (historyCache.length > htmx.config.historyCacheSize) { 2294 + historyCache.shift(); 2295 + } 2296 + while(historyCache.length > 0){ 2297 + try { 2298 + localStorage.setItem("htmx-history-cache", JSON.stringify(historyCache)); 2299 + break; 2300 + } catch (e) { 2301 + triggerErrorEvent(getDocument().body, "htmx:historyCacheError", {cause:e, cache: historyCache}) 2302 + historyCache.shift(); // shrink the cache and retry 2303 + } 2304 + } 2305 + } 2306 + 2307 + function getCachedHistory(url) { 2308 + if (!canAccessLocalStorage()) { 2309 + return null; 2310 + } 2311 + 2312 + url = normalizePath(url); 2313 + 2314 + var historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; 2315 + for (var i = 0; i < historyCache.length; i++) { 2316 + if (historyCache[i].url === url) { 2317 + return historyCache[i]; 2318 + } 2319 + } 2320 + return null; 2321 + } 2322 + 2323 + function cleanInnerHtmlForHistory(elt) { 2324 + var className = htmx.config.requestClass; 2325 + var clone = elt.cloneNode(true); 2326 + forEach(findAll(clone, "." + className), function(child){ 2327 + removeClassFromElement(child, className); 2328 + }); 2329 + return clone.innerHTML; 2330 + } 2331 + 2332 + function saveCurrentPageToHistory() { 2333 + var elt = getHistoryElement(); 2334 + var path = currentPathForHistory || location.pathname+location.search; 2335 + 2336 + // Allow history snapshot feature to be disabled where hx-history="false" 2337 + // is present *anywhere* in the current document we're about to save, 2338 + // so we can prevent privileged data entering the cache. 2339 + // The page will still be reachable as a history entry, but htmx will fetch it 2340 + // live from the server onpopstate rather than look in the localStorage cache 2341 + var disableHistoryCache 2342 + try { 2343 + disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]') 2344 + } catch (e) { 2345 + // IE11: insensitive modifier not supported so fallback to case sensitive selector 2346 + disableHistoryCache = getDocument().querySelector('[hx-history="false"],[data-hx-history="false"]') 2347 + } 2348 + if (!disableHistoryCache) { 2349 + triggerEvent(getDocument().body, "htmx:beforeHistorySave", {path: path, historyElt: elt}); 2350 + saveToHistoryCache(path, cleanInnerHtmlForHistory(elt), getDocument().title, window.scrollY); 2351 + } 2352 + 2353 + if (htmx.config.historyEnabled) history.replaceState({htmx: true}, getDocument().title, window.location.href); 2354 + } 2355 + 2356 + function pushUrlIntoHistory(path) { 2357 + // remove the cache buster parameter, if any 2358 + if (htmx.config.getCacheBusterParam) { 2359 + path = path.replace(/org\.htmx\.cache-buster=[^&]*&?/, '') 2360 + if (endsWith(path, '&') || endsWith(path, "?")) { 2361 + path = path.slice(0, -1); 2362 + } 2363 + } 2364 + if(htmx.config.historyEnabled) { 2365 + history.pushState({htmx:true}, "", path); 2366 + } 2367 + currentPathForHistory = path; 2368 + } 2369 + 2370 + function replaceUrlInHistory(path) { 2371 + if(htmx.config.historyEnabled) history.replaceState({htmx:true}, "", path); 2372 + currentPathForHistory = path; 2373 + } 2374 + 2375 + function settleImmediately(tasks) { 2376 + forEach(tasks, function (task) { 2377 + task.call(); 2378 + }); 2379 + } 2380 + 2381 + function loadHistoryFromServer(path) { 2382 + var request = new XMLHttpRequest(); 2383 + var details = {path: path, xhr:request}; 2384 + triggerEvent(getDocument().body, "htmx:historyCacheMiss", details); 2385 + request.open('GET', path, true); 2386 + request.setRequestHeader("HX-Request", "true"); 2387 + request.setRequestHeader("HX-History-Restore-Request", "true"); 2388 + request.setRequestHeader("HX-Current-URL", getDocument().location.href); 2389 + request.onload = function () { 2390 + if (this.status >= 200 && this.status < 400) { 2391 + triggerEvent(getDocument().body, "htmx:historyCacheMissLoad", details); 2392 + var fragment = makeFragment(this.response); 2393 + // @ts-ignore 2394 + fragment = fragment.querySelector('[hx-history-elt],[data-hx-history-elt]') || fragment; 2395 + var historyElement = getHistoryElement(); 2396 + var settleInfo = makeSettleInfo(historyElement); 2397 + var title = findTitle(this.response); 2398 + if (title) { 2399 + var titleElt = find("title"); 2400 + if (titleElt) { 2401 + titleElt.innerHTML = title; 2402 + } else { 2403 + window.document.title = title; 2404 + } 2405 + } 2406 + // @ts-ignore 2407 + swapInnerHTML(historyElement, fragment, settleInfo) 2408 + settleImmediately(settleInfo.tasks); 2409 + currentPathForHistory = path; 2410 + triggerEvent(getDocument().body, "htmx:historyRestore", {path: path, cacheMiss:true, serverResponse:this.response}); 2411 + } else { 2412 + triggerErrorEvent(getDocument().body, "htmx:historyCacheMissLoadError", details); 2413 + } 2414 + }; 2415 + request.send(); 2416 + } 2417 + 2418 + function restoreHistory(path) { 2419 + saveCurrentPageToHistory(); 2420 + path = path || location.pathname+location.search; 2421 + var cached = getCachedHistory(path); 2422 + if (cached) { 2423 + var fragment = makeFragment(cached.content); 2424 + var historyElement = getHistoryElement(); 2425 + var settleInfo = makeSettleInfo(historyElement); 2426 + swapInnerHTML(historyElement, fragment, settleInfo) 2427 + settleImmediately(settleInfo.tasks); 2428 + document.title = cached.title; 2429 + setTimeout(function () { 2430 + window.scrollTo(0, cached.scroll); 2431 + }, 0); // next 'tick', so browser has time to render layout 2432 + currentPathForHistory = path; 2433 + triggerEvent(getDocument().body, "htmx:historyRestore", {path:path, item:cached}); 2434 + } else { 2435 + if (htmx.config.refreshOnHistoryMiss) { 2436 + 2437 + // @ts-ignore: optional parameter in reload() function throws error 2438 + window.location.reload(true); 2439 + } else { 2440 + loadHistoryFromServer(path); 2441 + } 2442 + } 2443 + } 2444 + 2445 + function addRequestIndicatorClasses(elt) { 2446 + var indicators = findAttributeTargets(elt, 'hx-indicator'); 2447 + if (indicators == null) { 2448 + indicators = [elt]; 2449 + } 2450 + forEach(indicators, function (ic) { 2451 + var internalData = getInternalData(ic); 2452 + internalData.requestCount = (internalData.requestCount || 0) + 1; 2453 + ic.classList["add"].call(ic.classList, htmx.config.requestClass); 2454 + }); 2455 + return indicators; 2456 + } 2457 + 2458 + function disableElements(elt) { 2459 + var disabledElts = findAttributeTargets(elt, 'hx-disabled-elt'); 2460 + if (disabledElts == null) { 2461 + disabledElts = []; 2462 + } 2463 + forEach(disabledElts, function (disabledElement) { 2464 + var internalData = getInternalData(disabledElement); 2465 + internalData.requestCount = (internalData.requestCount || 0) + 1; 2466 + disabledElement.setAttribute("disabled", ""); 2467 + }); 2468 + return disabledElts; 2469 + } 2470 + 2471 + function removeRequestIndicators(indicators, disabled) { 2472 + forEach(indicators, function (ic) { 2473 + var internalData = getInternalData(ic); 2474 + internalData.requestCount = (internalData.requestCount || 0) - 1; 2475 + if (internalData.requestCount === 0) { 2476 + ic.classList["remove"].call(ic.classList, htmx.config.requestClass); 2477 + } 2478 + }); 2479 + forEach(disabled, function (disabledElement) { 2480 + var internalData = getInternalData(disabledElement); 2481 + internalData.requestCount = (internalData.requestCount || 0) - 1; 2482 + if (internalData.requestCount === 0) { 2483 + disabledElement.removeAttribute('disabled'); 2484 + } 2485 + }); 2486 + } 2487 + 2488 + //==================================================================== 2489 + // Input Value Processing 2490 + //==================================================================== 2491 + 2492 + function haveSeenNode(processed, elt) { 2493 + for (var i = 0; i < processed.length; i++) { 2494 + var node = processed[i]; 2495 + if (node.isSameNode(elt)) { 2496 + return true; 2497 + } 2498 + } 2499 + return false; 2500 + } 2501 + 2502 + function shouldInclude(elt) { 2503 + if(elt.name === "" || elt.name == null || elt.disabled || closest(elt, "fieldset[disabled]")) { 2504 + return false; 2505 + } 2506 + // ignore "submitter" types (see jQuery src/serialize.js) 2507 + if (elt.type === "button" || elt.type === "submit" || elt.tagName === "image" || elt.tagName === "reset" || elt.tagName === "file" ) { 2508 + return false; 2509 + } 2510 + if (elt.type === "checkbox" || elt.type === "radio" ) { 2511 + return elt.checked; 2512 + } 2513 + return true; 2514 + } 2515 + 2516 + function addValueToValues(name, value, values) { 2517 + // This is a little ugly because both the current value of the named value in the form 2518 + // and the new value could be arrays, so we have to handle all four cases :/ 2519 + if (name != null && value != null) { 2520 + var current = values[name]; 2521 + if (current === undefined) { 2522 + values[name] = value; 2523 + } else if (Array.isArray(current)) { 2524 + if (Array.isArray(value)) { 2525 + values[name] = current.concat(value); 2526 + } else { 2527 + current.push(value); 2528 + } 2529 + } else { 2530 + if (Array.isArray(value)) { 2531 + values[name] = [current].concat(value); 2532 + } else { 2533 + values[name] = [current, value]; 2534 + } 2535 + } 2536 + } 2537 + } 2538 + 2539 + function processInputValue(processed, values, errors, elt, validate) { 2540 + if (elt == null || haveSeenNode(processed, elt)) { 2541 + return; 2542 + } else { 2543 + processed.push(elt); 2544 + } 2545 + if (shouldInclude(elt)) { 2546 + var name = getRawAttribute(elt,"name"); 2547 + var value = elt.value; 2548 + if (elt.multiple && elt.tagName === "SELECT") { 2549 + value = toArray(elt.querySelectorAll("option:checked")).map(function (e) { return e.value }); 2550 + } 2551 + // include file inputs 2552 + if (elt.files) { 2553 + value = toArray(elt.files); 2554 + } 2555 + addValueToValues(name, value, values); 2556 + if (validate) { 2557 + validateElement(elt, errors); 2558 + } 2559 + } 2560 + if (matches(elt, 'form')) { 2561 + var inputs = elt.elements; 2562 + forEach(inputs, function(input) { 2563 + processInputValue(processed, values, errors, input, validate); 2564 + }); 2565 + } 2566 + } 2567 + 2568 + function validateElement(element, errors) { 2569 + if (element.willValidate) { 2570 + triggerEvent(element, "htmx:validation:validate") 2571 + if (!element.checkValidity()) { 2572 + errors.push({elt: element, message:element.validationMessage, validity:element.validity}); 2573 + triggerEvent(element, "htmx:validation:failed", {message:element.validationMessage, validity:element.validity}) 2574 + } 2575 + } 2576 + } 2577 + 2578 + /** 2579 + * @param {HTMLElement} elt 2580 + * @param {string} verb 2581 + */ 2582 + function getInputValues(elt, verb) { 2583 + var processed = []; 2584 + var values = {}; 2585 + var formValues = {}; 2586 + var errors = []; 2587 + var internalData = getInternalData(elt); 2588 + if (internalData.lastButtonClicked && !bodyContains(internalData.lastButtonClicked)) { 2589 + internalData.lastButtonClicked = null 2590 + } 2591 + 2592 + // only validate when form is directly submitted and novalidate or formnovalidate are not set 2593 + // or if the element has an explicit hx-validate="true" on it 2594 + var validate = (matches(elt, 'form') && elt.noValidate !== true) || getAttributeValue(elt, "hx-validate") === "true"; 2595 + if (internalData.lastButtonClicked) { 2596 + validate = validate && internalData.lastButtonClicked.formNoValidate !== true; 2597 + } 2598 + 2599 + // for a non-GET include the closest form 2600 + if (verb !== 'get') { 2601 + processInputValue(processed, formValues, errors, closest(elt, 'form'), validate); 2602 + } 2603 + 2604 + // include the element itself 2605 + processInputValue(processed, values, errors, elt, validate); 2606 + 2607 + // if a button or submit was clicked last, include its value 2608 + if (internalData.lastButtonClicked || elt.tagName === "BUTTON" || 2609 + (elt.tagName === "INPUT" && getRawAttribute(elt, "type") === "submit")) { 2610 + var button = internalData.lastButtonClicked || elt 2611 + var name = getRawAttribute(button, "name") 2612 + addValueToValues(name, button.value, formValues) 2613 + } 2614 + 2615 + // include any explicit includes 2616 + var includes = findAttributeTargets(elt, "hx-include"); 2617 + forEach(includes, function(node) { 2618 + processInputValue(processed, values, errors, node, validate); 2619 + // if a non-form is included, include any input values within it 2620 + if (!matches(node, 'form')) { 2621 + forEach(node.querySelectorAll(INPUT_SELECTOR), function (descendant) { 2622 + processInputValue(processed, values, errors, descendant, validate); 2623 + }) 2624 + } 2625 + }); 2626 + 2627 + // form values take precedence, overriding the regular values 2628 + values = mergeObjects(values, formValues); 2629 + 2630 + return {errors:errors, values:values}; 2631 + } 2632 + 2633 + function appendParam(returnStr, name, realValue) { 2634 + if (returnStr !== "") { 2635 + returnStr += "&"; 2636 + } 2637 + if (String(realValue) === "[object Object]") { 2638 + realValue = JSON.stringify(realValue); 2639 + } 2640 + var s = encodeURIComponent(realValue); 2641 + returnStr += encodeURIComponent(name) + "=" + s; 2642 + return returnStr; 2643 + } 2644 + 2645 + function urlEncode(values) { 2646 + var returnStr = ""; 2647 + for (var name in values) { 2648 + if (values.hasOwnProperty(name)) { 2649 + var value = values[name]; 2650 + if (Array.isArray(value)) { 2651 + forEach(value, function(v) { 2652 + returnStr = appendParam(returnStr, name, v); 2653 + }); 2654 + } else { 2655 + returnStr = appendParam(returnStr, name, value); 2656 + } 2657 + } 2658 + } 2659 + return returnStr; 2660 + } 2661 + 2662 + function makeFormData(values) { 2663 + var formData = new FormData(); 2664 + for (var name in values) { 2665 + if (values.hasOwnProperty(name)) { 2666 + var value = values[name]; 2667 + if (Array.isArray(value)) { 2668 + forEach(value, function(v) { 2669 + formData.append(name, v); 2670 + }); 2671 + } else { 2672 + formData.append(name, value); 2673 + } 2674 + } 2675 + } 2676 + return formData; 2677 + } 2678 + 2679 + //==================================================================== 2680 + // Ajax 2681 + //==================================================================== 2682 + 2683 + /** 2684 + * @param {HTMLElement} elt 2685 + * @param {HTMLElement} target 2686 + * @param {string} prompt 2687 + * @returns {Object} // TODO: Define/Improve HtmxHeaderSpecification 2688 + */ 2689 + function getHeaders(elt, target, prompt) { 2690 + var headers = { 2691 + "HX-Request" : "true", 2692 + "HX-Trigger" : getRawAttribute(elt, "id"), 2693 + "HX-Trigger-Name" : getRawAttribute(elt, "name"), 2694 + "HX-Target" : getAttributeValue(target, "id"), 2695 + "HX-Current-URL" : getDocument().location.href, 2696 + } 2697 + getValuesForElement(elt, "hx-headers", false, headers) 2698 + if (prompt !== undefined) { 2699 + headers["HX-Prompt"] = prompt; 2700 + } 2701 + if (getInternalData(elt).boosted) { 2702 + headers["HX-Boosted"] = "true"; 2703 + } 2704 + return headers; 2705 + } 2706 + 2707 + /** 2708 + * filterValues takes an object containing form input values 2709 + * and returns a new object that only contains keys that are 2710 + * specified by the closest "hx-params" attribute 2711 + * @param {Object} inputValues 2712 + * @param {HTMLElement} elt 2713 + * @returns {Object} 2714 + */ 2715 + function filterValues(inputValues, elt) { 2716 + var paramsValue = getClosestAttributeValue(elt, "hx-params"); 2717 + if (paramsValue) { 2718 + if (paramsValue === "none") { 2719 + return {}; 2720 + } else if (paramsValue === "*") { 2721 + return inputValues; 2722 + } else if(paramsValue.indexOf("not ") === 0) { 2723 + forEach(paramsValue.substr(4).split(","), function (name) { 2724 + name = name.trim(); 2725 + delete inputValues[name]; 2726 + }); 2727 + return inputValues; 2728 + } else { 2729 + var newValues = {} 2730 + forEach(paramsValue.split(","), function (name) { 2731 + name = name.trim(); 2732 + newValues[name] = inputValues[name]; 2733 + }); 2734 + return newValues; 2735 + } 2736 + } else { 2737 + return inputValues; 2738 + } 2739 + } 2740 + 2741 + function isAnchorLink(elt) { 2742 + return getRawAttribute(elt, 'href') && getRawAttribute(elt, 'href').indexOf("#") >=0 2743 + } 2744 + 2745 + /** 2746 + * 2747 + * @param {HTMLElement} elt 2748 + * @param {string} swapInfoOverride 2749 + * @returns {import("./htmx").HtmxSwapSpecification} 2750 + */ 2751 + function getSwapSpecification(elt, swapInfoOverride) { 2752 + var swapInfo = swapInfoOverride ? swapInfoOverride : getClosestAttributeValue(elt, "hx-swap"); 2753 + var swapSpec = { 2754 + "swapStyle" : getInternalData(elt).boosted ? 'innerHTML' : htmx.config.defaultSwapStyle, 2755 + "swapDelay" : htmx.config.defaultSwapDelay, 2756 + "settleDelay" : htmx.config.defaultSettleDelay 2757 + } 2758 + if (htmx.config.scrollIntoViewOnBoost && getInternalData(elt).boosted && !isAnchorLink(elt)) { 2759 + swapSpec["show"] = "top" 2760 + } 2761 + if (swapInfo) { 2762 + var split = splitOnWhitespace(swapInfo); 2763 + if (split.length > 0) { 2764 + for (var i = 0; i < split.length; i++) { 2765 + var value = split[i]; 2766 + if (value.indexOf("swap:") === 0) { 2767 + swapSpec["swapDelay"] = parseInterval(value.substr(5)); 2768 + } else if (value.indexOf("settle:") === 0) { 2769 + swapSpec["settleDelay"] = parseInterval(value.substr(7)); 2770 + } else if (value.indexOf("transition:") === 0) { 2771 + swapSpec["transition"] = value.substr(11) === "true"; 2772 + } else if (value.indexOf("ignoreTitle:") === 0) { 2773 + swapSpec["ignoreTitle"] = value.substr(12) === "true"; 2774 + } else if (value.indexOf("scroll:") === 0) { 2775 + var scrollSpec = value.substr(7); 2776 + var splitSpec = scrollSpec.split(":"); 2777 + var scrollVal = splitSpec.pop(); 2778 + var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; 2779 + swapSpec["scroll"] = scrollVal; 2780 + swapSpec["scrollTarget"] = selectorVal; 2781 + } else if (value.indexOf("show:") === 0) { 2782 + var showSpec = value.substr(5); 2783 + var splitSpec = showSpec.split(":"); 2784 + var showVal = splitSpec.pop(); 2785 + var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; 2786 + swapSpec["show"] = showVal; 2787 + swapSpec["showTarget"] = selectorVal; 2788 + } else if (value.indexOf("focus-scroll:") === 0) { 2789 + var focusScrollVal = value.substr("focus-scroll:".length); 2790 + swapSpec["focusScroll"] = focusScrollVal == "true"; 2791 + } else if (i == 0) { 2792 + swapSpec["swapStyle"] = value; 2793 + } else { 2794 + logError('Unknown modifier in hx-swap: ' + value); 2795 + } 2796 + } 2797 + } 2798 + } 2799 + return swapSpec; 2800 + } 2801 + 2802 + function usesFormData(elt) { 2803 + return getClosestAttributeValue(elt, "hx-encoding") === "multipart/form-data" || 2804 + (matches(elt, "form") && getRawAttribute(elt, 'enctype') === "multipart/form-data"); 2805 + } 2806 + 2807 + function encodeParamsForBody(xhr, elt, filteredParameters) { 2808 + var encodedParameters = null; 2809 + withExtensions(elt, function (extension) { 2810 + if (encodedParameters == null) { 2811 + encodedParameters = extension.encodeParameters(xhr, filteredParameters, elt); 2812 + } 2813 + }); 2814 + if (encodedParameters != null) { 2815 + return encodedParameters; 2816 + } else { 2817 + if (usesFormData(elt)) { 2818 + return makeFormData(filteredParameters); 2819 + } else { 2820 + return urlEncode(filteredParameters); 2821 + } 2822 + } 2823 + } 2824 + 2825 + /** 2826 + * 2827 + * @param {Element} target 2828 + * @returns {import("./htmx").HtmxSettleInfo} 2829 + */ 2830 + function makeSettleInfo(target) { 2831 + return {tasks: [], elts: [target]}; 2832 + } 2833 + 2834 + function updateScrollState(content, swapSpec) { 2835 + var first = content[0]; 2836 + var last = content[content.length - 1]; 2837 + if (swapSpec.scroll) { 2838 + var target = null; 2839 + if (swapSpec.scrollTarget) { 2840 + target = querySelectorExt(first, swapSpec.scrollTarget); 2841 + } 2842 + if (swapSpec.scroll === "top" && (first || target)) { 2843 + target = target || first; 2844 + target.scrollTop = 0; 2845 + } 2846 + if (swapSpec.scroll === "bottom" && (last || target)) { 2847 + target = target || last; 2848 + target.scrollTop = target.scrollHeight; 2849 + } 2850 + } 2851 + if (swapSpec.show) { 2852 + var target = null; 2853 + if (swapSpec.showTarget) { 2854 + var targetStr = swapSpec.showTarget; 2855 + if (swapSpec.showTarget === "window") { 2856 + targetStr = "body"; 2857 + } 2858 + target = querySelectorExt(first, targetStr); 2859 + } 2860 + if (swapSpec.show === "top" && (first || target)) { 2861 + target = target || first; 2862 + target.scrollIntoView({block:'start', behavior: htmx.config.scrollBehavior}); 2863 + } 2864 + if (swapSpec.show === "bottom" && (last || target)) { 2865 + target = target || last; 2866 + target.scrollIntoView({block:'end', behavior: htmx.config.scrollBehavior}); 2867 + } 2868 + } 2869 + } 2870 + 2871 + /** 2872 + * @param {HTMLElement} elt 2873 + * @param {string} attr 2874 + * @param {boolean=} evalAsDefault 2875 + * @param {Object=} values 2876 + * @returns {Object} 2877 + */ 2878 + function getValuesForElement(elt, attr, evalAsDefault, values) { 2879 + if (values == null) { 2880 + values = {}; 2881 + } 2882 + if (elt == null) { 2883 + return values; 2884 + } 2885 + var attributeValue = getAttributeValue(elt, attr); 2886 + if (attributeValue) { 2887 + var str = attributeValue.trim(); 2888 + var evaluateValue = evalAsDefault; 2889 + if (str === "unset") { 2890 + return null; 2891 + } 2892 + if (str.indexOf("javascript:") === 0) { 2893 + str = str.substr(11); 2894 + evaluateValue = true; 2895 + } else if (str.indexOf("js:") === 0) { 2896 + str = str.substr(3); 2897 + evaluateValue = true; 2898 + } 2899 + if (str.indexOf('{') !== 0) { 2900 + str = "{" + str + "}"; 2901 + } 2902 + var varsValues; 2903 + if (evaluateValue) { 2904 + varsValues = maybeEval(elt,function () {return Function("return (" + str + ")")();}, {}); 2905 + } else { 2906 + varsValues = parseJSON(str); 2907 + } 2908 + for (var key in varsValues) { 2909 + if (varsValues.hasOwnProperty(key)) { 2910 + if (values[key] == null) { 2911 + values[key] = varsValues[key]; 2912 + } 2913 + } 2914 + } 2915 + } 2916 + return getValuesForElement(parentElt(elt), attr, evalAsDefault, values); 2917 + } 2918 + 2919 + function maybeEval(elt, toEval, defaultVal) { 2920 + if (htmx.config.allowEval) { 2921 + return toEval(); 2922 + } else { 2923 + triggerErrorEvent(elt, 'htmx:evalDisallowedError'); 2924 + return defaultVal; 2925 + } 2926 + } 2927 + 2928 + /** 2929 + * @param {HTMLElement} elt 2930 + * @param {*} expressionVars 2931 + * @returns 2932 + */ 2933 + function getHXVarsForElement(elt, expressionVars) { 2934 + return getValuesForElement(elt, "hx-vars", true, expressionVars); 2935 + } 2936 + 2937 + /** 2938 + * @param {HTMLElement} elt 2939 + * @param {*} expressionVars 2940 + * @returns 2941 + */ 2942 + function getHXValsForElement(elt, expressionVars) { 2943 + return getValuesForElement(elt, "hx-vals", false, expressionVars); 2944 + } 2945 + 2946 + /** 2947 + * @param {HTMLElement} elt 2948 + * @returns {Object} 2949 + */ 2950 + function getExpressionVars(elt) { 2951 + return mergeObjects(getHXVarsForElement(elt), getHXValsForElement(elt)); 2952 + } 2953 + 2954 + function safelySetHeaderValue(xhr, header, headerValue) { 2955 + if (headerValue !== null) { 2956 + try { 2957 + xhr.setRequestHeader(header, headerValue); 2958 + } catch (e) { 2959 + // On an exception, try to set the header URI encoded instead 2960 + xhr.setRequestHeader(header, encodeURIComponent(headerValue)); 2961 + xhr.setRequestHeader(header + "-URI-AutoEncoded", "true"); 2962 + } 2963 + } 2964 + } 2965 + 2966 + function getPathFromResponse(xhr) { 2967 + // NB: IE11 does not support this stuff 2968 + if (xhr.responseURL && typeof(URL) !== "undefined") { 2969 + try { 2970 + var url = new URL(xhr.responseURL); 2971 + return url.pathname + url.search; 2972 + } catch (e) { 2973 + triggerErrorEvent(getDocument().body, "htmx:badResponseUrl", {url: xhr.responseURL}); 2974 + } 2975 + } 2976 + } 2977 + 2978 + function hasHeader(xhr, regexp) { 2979 + return regexp.test(xhr.getAllResponseHeaders()) 2980 + } 2981 + 2982 + function ajaxHelper(verb, path, context) { 2983 + verb = verb.toLowerCase(); 2984 + if (context) { 2985 + if (context instanceof Element || isType(context, 'String')) { 2986 + return issueAjaxRequest(verb, path, null, null, { 2987 + targetOverride: resolveTarget(context), 2988 + returnPromise: true 2989 + }); 2990 + } else { 2991 + return issueAjaxRequest(verb, path, resolveTarget(context.source), context.event, 2992 + { 2993 + handler : context.handler, 2994 + headers : context.headers, 2995 + values : context.values, 2996 + targetOverride: resolveTarget(context.target), 2997 + swapOverride: context.swap, 2998 + select: context.select, 2999 + returnPromise: true 3000 + }); 3001 + } 3002 + } else { 3003 + return issueAjaxRequest(verb, path, null, null, { 3004 + returnPromise: true 3005 + }); 3006 + } 3007 + } 3008 + 3009 + function hierarchyForElt(elt) { 3010 + var arr = []; 3011 + while (elt) { 3012 + arr.push(elt); 3013 + elt = elt.parentElement; 3014 + } 3015 + return arr; 3016 + } 3017 + 3018 + function verifyPath(elt, path, requestConfig) { 3019 + var sameHost 3020 + var url 3021 + if (typeof URL === "function") { 3022 + url = new URL(path, document.location.href); 3023 + var origin = document.location.origin; 3024 + sameHost = origin === url.origin; 3025 + } else { 3026 + // IE11 doesn't support URL 3027 + url = path 3028 + sameHost = startsWith(path, document.location.origin) 3029 + } 3030 + 3031 + if (htmx.config.selfRequestsOnly) { 3032 + if (!sameHost) { 3033 + return false; 3034 + } 3035 + } 3036 + return triggerEvent(elt, "htmx:validateUrl", mergeObjects({url: url, sameHost: sameHost}, requestConfig)); 3037 + } 3038 + 3039 + function issueAjaxRequest(verb, path, elt, event, etc, confirmed) { 3040 + var resolve = null; 3041 + var reject = null; 3042 + etc = etc != null ? etc : {}; 3043 + if(etc.returnPromise && typeof Promise !== "undefined"){ 3044 + var promise = new Promise(function (_resolve, _reject) { 3045 + resolve = _resolve; 3046 + reject = _reject; 3047 + }); 3048 + } 3049 + if(elt == null) { 3050 + elt = getDocument().body; 3051 + } 3052 + var responseHandler = etc.handler || handleAjaxResponse; 3053 + var select = etc.select || null; 3054 + 3055 + if (!bodyContains(elt)) { 3056 + // do not issue requests for elements removed from the DOM 3057 + maybeCall(resolve); 3058 + return promise; 3059 + } 3060 + var target = etc.targetOverride || getTarget(elt); 3061 + if (target == null || target == DUMMY_ELT) { 3062 + triggerErrorEvent(elt, 'htmx:targetError', {target: getAttributeValue(elt, "hx-target")}); 3063 + maybeCall(reject); 3064 + return promise; 3065 + } 3066 + 3067 + var eltData = getInternalData(elt); 3068 + var submitter = eltData.lastButtonClicked; 3069 + 3070 + if (submitter) { 3071 + var buttonPath = getRawAttribute(submitter, "formaction"); 3072 + if (buttonPath != null) { 3073 + path = buttonPath; 3074 + } 3075 + 3076 + var buttonVerb = getRawAttribute(submitter, "formmethod") 3077 + if (buttonVerb != null) { 3078 + // ignore buttons with formmethod="dialog" 3079 + if (buttonVerb.toLowerCase() !== "dialog") { 3080 + verb = buttonVerb; 3081 + } 3082 + } 3083 + } 3084 + 3085 + var confirmQuestion = getClosestAttributeValue(elt, "hx-confirm"); 3086 + // allow event-based confirmation w/ a callback 3087 + if (confirmed === undefined) { 3088 + var issueRequest = function(skipConfirmation) { 3089 + return issueAjaxRequest(verb, path, elt, event, etc, !!skipConfirmation); 3090 + } 3091 + var confirmDetails = {target: target, elt: elt, path: path, verb: verb, triggeringEvent: event, etc: etc, issueRequest: issueRequest, question: confirmQuestion}; 3092 + if (triggerEvent(elt, 'htmx:confirm', confirmDetails) === false) { 3093 + maybeCall(resolve); 3094 + return promise; 3095 + } 3096 + } 3097 + 3098 + var syncElt = elt; 3099 + var syncStrategy = getClosestAttributeValue(elt, "hx-sync"); 3100 + var queueStrategy = null; 3101 + var abortable = false; 3102 + if (syncStrategy) { 3103 + var syncStrings = syncStrategy.split(":"); 3104 + var selector = syncStrings[0].trim(); 3105 + if (selector === "this") { 3106 + syncElt = findThisElement(elt, 'hx-sync'); 3107 + } else { 3108 + syncElt = querySelectorExt(elt, selector); 3109 + } 3110 + // default to the drop strategy 3111 + syncStrategy = (syncStrings[1] || 'drop').trim(); 3112 + eltData = getInternalData(syncElt); 3113 + if (syncStrategy === "drop" && eltData.xhr && eltData.abortable !== true) { 3114 + maybeCall(resolve); 3115 + return promise; 3116 + } else if (syncStrategy === "abort") { 3117 + if (eltData.xhr) { 3118 + maybeCall(resolve); 3119 + return promise; 3120 + } else { 3121 + abortable = true; 3122 + } 3123 + } else if (syncStrategy === "replace") { 3124 + triggerEvent(syncElt, 'htmx:abort'); // abort the current request and continue 3125 + } else if (syncStrategy.indexOf("queue") === 0) { 3126 + var queueStrArray = syncStrategy.split(" "); 3127 + queueStrategy = (queueStrArray[1] || "last").trim(); 3128 + } 3129 + } 3130 + 3131 + if (eltData.xhr) { 3132 + if (eltData.abortable) { 3133 + triggerEvent(syncElt, 'htmx:abort'); // abort the current request and continue 3134 + } else { 3135 + if(queueStrategy == null){ 3136 + if (event) { 3137 + var eventData = getInternalData(event); 3138 + if (eventData && eventData.triggerSpec && eventData.triggerSpec.queue) { 3139 + queueStrategy = eventData.triggerSpec.queue; 3140 + } 3141 + } 3142 + if (queueStrategy == null) { 3143 + queueStrategy = "last"; 3144 + } 3145 + } 3146 + if (eltData.queuedRequests == null) { 3147 + eltData.queuedRequests = []; 3148 + } 3149 + if (queueStrategy === "first" && eltData.queuedRequests.length === 0) { 3150 + eltData.queuedRequests.push(function () { 3151 + issueAjaxRequest(verb, path, elt, event, etc) 3152 + }); 3153 + } else if (queueStrategy === "all") { 3154 + eltData.queuedRequests.push(function () { 3155 + issueAjaxRequest(verb, path, elt, event, etc) 3156 + }); 3157 + } else if (queueStrategy === "last") { 3158 + eltData.queuedRequests = []; // dump existing queue 3159 + eltData.queuedRequests.push(function () { 3160 + issueAjaxRequest(verb, path, elt, event, etc) 3161 + }); 3162 + } 3163 + maybeCall(resolve); 3164 + return promise; 3165 + } 3166 + } 3167 + 3168 + var xhr = new XMLHttpRequest(); 3169 + eltData.xhr = xhr; 3170 + eltData.abortable = abortable; 3171 + var endRequestLock = function(){ 3172 + eltData.xhr = null; 3173 + eltData.abortable = false; 3174 + if (eltData.queuedRequests != null && 3175 + eltData.queuedRequests.length > 0) { 3176 + var queuedRequest = eltData.queuedRequests.shift(); 3177 + queuedRequest(); 3178 + } 3179 + } 3180 + var promptQuestion = getClosestAttributeValue(elt, "hx-prompt"); 3181 + if (promptQuestion) { 3182 + var promptResponse = prompt(promptQuestion); 3183 + // prompt returns null if cancelled and empty string if accepted with no entry 3184 + if (promptResponse === null || 3185 + !triggerEvent(elt, 'htmx:prompt', {prompt: promptResponse, target:target})) { 3186 + maybeCall(resolve); 3187 + endRequestLock(); 3188 + return promise; 3189 + } 3190 + } 3191 + 3192 + if (confirmQuestion && !confirmed) { 3193 + if(!confirm(confirmQuestion)) { 3194 + maybeCall(resolve); 3195 + endRequestLock() 3196 + return promise; 3197 + } 3198 + } 3199 + 3200 + 3201 + var headers = getHeaders(elt, target, promptResponse); 3202 + 3203 + if (verb !== 'get' && !usesFormData(elt)) { 3204 + headers['Content-Type'] = 'application/x-www-form-urlencoded'; 3205 + } 3206 + 3207 + if (etc.headers) { 3208 + headers = mergeObjects(headers, etc.headers); 3209 + } 3210 + var results = getInputValues(elt, verb); 3211 + var errors = results.errors; 3212 + var rawParameters = results.values; 3213 + if (etc.values) { 3214 + rawParameters = mergeObjects(rawParameters, etc.values); 3215 + } 3216 + var expressionVars = getExpressionVars(elt); 3217 + var allParameters = mergeObjects(rawParameters, expressionVars); 3218 + var filteredParameters = filterValues(allParameters, elt); 3219 + 3220 + if (htmx.config.getCacheBusterParam && verb === 'get') { 3221 + filteredParameters['org.htmx.cache-buster'] = getRawAttribute(target, "id") || "true"; 3222 + } 3223 + 3224 + // behavior of anchors w/ empty href is to use the current URL 3225 + if (path == null || path === "") { 3226 + path = getDocument().location.href; 3227 + } 3228 + 3229 + 3230 + var requestAttrValues = getValuesForElement(elt, 'hx-request'); 3231 + 3232 + var eltIsBoosted = getInternalData(elt).boosted; 3233 + 3234 + var useUrlParams = htmx.config.methodsThatUseUrlParams.indexOf(verb) >= 0 3235 + 3236 + var requestConfig = { 3237 + boosted: eltIsBoosted, 3238 + useUrlParams: useUrlParams, 3239 + parameters: filteredParameters, 3240 + unfilteredParameters: allParameters, 3241 + headers:headers, 3242 + target:target, 3243 + verb:verb, 3244 + errors:errors, 3245 + withCredentials: etc.credentials || requestAttrValues.credentials || htmx.config.withCredentials, 3246 + timeout: etc.timeout || requestAttrValues.timeout || htmx.config.timeout, 3247 + path:path, 3248 + triggeringEvent:event 3249 + }; 3250 + 3251 + if(!triggerEvent(elt, 'htmx:configRequest', requestConfig)){ 3252 + maybeCall(resolve); 3253 + endRequestLock(); 3254 + return promise; 3255 + } 3256 + 3257 + // copy out in case the object was overwritten 3258 + path = requestConfig.path; 3259 + verb = requestConfig.verb; 3260 + headers = requestConfig.headers; 3261 + filteredParameters = requestConfig.parameters; 3262 + errors = requestConfig.errors; 3263 + useUrlParams = requestConfig.useUrlParams; 3264 + 3265 + if(errors && errors.length > 0){ 3266 + triggerEvent(elt, 'htmx:validation:halted', requestConfig) 3267 + maybeCall(resolve); 3268 + endRequestLock(); 3269 + return promise; 3270 + } 3271 + 3272 + var splitPath = path.split("#"); 3273 + var pathNoAnchor = splitPath[0]; 3274 + var anchor = splitPath[1]; 3275 + 3276 + var finalPath = path 3277 + if (useUrlParams) { 3278 + finalPath = pathNoAnchor; 3279 + var values = Object.keys(filteredParameters).length !== 0; 3280 + if (values) { 3281 + if (finalPath.indexOf("?") < 0) { 3282 + finalPath += "?"; 3283 + } else { 3284 + finalPath += "&"; 3285 + } 3286 + finalPath += urlEncode(filteredParameters); 3287 + if (anchor) { 3288 + finalPath += "#" + anchor; 3289 + } 3290 + } 3291 + } 3292 + 3293 + if (!verifyPath(elt, finalPath, requestConfig)) { 3294 + triggerErrorEvent(elt, 'htmx:invalidPath', requestConfig) 3295 + maybeCall(reject); 3296 + return promise; 3297 + }; 3298 + 3299 + xhr.open(verb.toUpperCase(), finalPath, true); 3300 + xhr.overrideMimeType("text/html"); 3301 + xhr.withCredentials = requestConfig.withCredentials; 3302 + xhr.timeout = requestConfig.timeout; 3303 + 3304 + // request headers 3305 + if (requestAttrValues.noHeaders) { 3306 + // ignore all headers 3307 + } else { 3308 + for (var header in headers) { 3309 + if (headers.hasOwnProperty(header)) { 3310 + var headerValue = headers[header]; 3311 + safelySetHeaderValue(xhr, header, headerValue); 3312 + } 3313 + } 3314 + } 3315 + 3316 + var responseInfo = { 3317 + xhr: xhr, target: target, requestConfig: requestConfig, etc: etc, boosted: eltIsBoosted, select: select, 3318 + pathInfo: { 3319 + requestPath: path, 3320 + finalRequestPath: finalPath, 3321 + anchor: anchor 3322 + } 3323 + }; 3324 + 3325 + xhr.onload = function () { 3326 + try { 3327 + var hierarchy = hierarchyForElt(elt); 3328 + responseInfo.pathInfo.responsePath = getPathFromResponse(xhr); 3329 + responseHandler(elt, responseInfo); 3330 + removeRequestIndicators(indicators, disableElts); 3331 + triggerEvent(elt, 'htmx:afterRequest', responseInfo); 3332 + triggerEvent(elt, 'htmx:afterOnLoad', responseInfo); 3333 + // if the body no longer contains the element, trigger the event on the closest parent 3334 + // remaining in the DOM 3335 + if (!bodyContains(elt)) { 3336 + var secondaryTriggerElt = null; 3337 + while (hierarchy.length > 0 && secondaryTriggerElt == null) { 3338 + var parentEltInHierarchy = hierarchy.shift(); 3339 + if (bodyContains(parentEltInHierarchy)) { 3340 + secondaryTriggerElt = parentEltInHierarchy; 3341 + } 3342 + } 3343 + if (secondaryTriggerElt) { 3344 + triggerEvent(secondaryTriggerElt, 'htmx:afterRequest', responseInfo); 3345 + triggerEvent(secondaryTriggerElt, 'htmx:afterOnLoad', responseInfo); 3346 + } 3347 + } 3348 + maybeCall(resolve); 3349 + endRequestLock(); 3350 + } catch (e) { 3351 + triggerErrorEvent(elt, 'htmx:onLoadError', mergeObjects({error:e}, responseInfo)); 3352 + throw e; 3353 + } 3354 + } 3355 + xhr.onerror = function () { 3356 + removeRequestIndicators(indicators, disableElts); 3357 + triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); 3358 + triggerErrorEvent(elt, 'htmx:sendError', responseInfo); 3359 + maybeCall(reject); 3360 + endRequestLock(); 3361 + } 3362 + xhr.onabort = function() { 3363 + removeRequestIndicators(indicators, disableElts); 3364 + triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); 3365 + triggerErrorEvent(elt, 'htmx:sendAbort', responseInfo); 3366 + maybeCall(reject); 3367 + endRequestLock(); 3368 + } 3369 + xhr.ontimeout = function() { 3370 + removeRequestIndicators(indicators, disableElts); 3371 + triggerErrorEvent(elt, 'htmx:afterRequest', responseInfo); 3372 + triggerErrorEvent(elt, 'htmx:timeout', responseInfo); 3373 + maybeCall(reject); 3374 + endRequestLock(); 3375 + } 3376 + if(!triggerEvent(elt, 'htmx:beforeRequest', responseInfo)){ 3377 + maybeCall(resolve); 3378 + endRequestLock() 3379 + return promise 3380 + } 3381 + var indicators = addRequestIndicatorClasses(elt); 3382 + var disableElts = disableElements(elt); 3383 + 3384 + forEach(['loadstart', 'loadend', 'progress', 'abort'], function(eventName) { 3385 + forEach([xhr, xhr.upload], function (target) { 3386 + target.addEventListener(eventName, function(event){ 3387 + triggerEvent(elt, "htmx:xhr:" + eventName, { 3388 + lengthComputable:event.lengthComputable, 3389 + loaded:event.loaded, 3390 + total:event.total 3391 + }); 3392 + }) 3393 + }); 3394 + }); 3395 + triggerEvent(elt, 'htmx:beforeSend', responseInfo); 3396 + var params = useUrlParams ? null : encodeParamsForBody(xhr, elt, filteredParameters) 3397 + xhr.send(params); 3398 + return promise; 3399 + } 3400 + 3401 + function determineHistoryUpdates(elt, responseInfo) { 3402 + 3403 + var xhr = responseInfo.xhr; 3404 + 3405 + //=========================================== 3406 + // First consult response headers 3407 + //=========================================== 3408 + var pathFromHeaders = null; 3409 + var typeFromHeaders = null; 3410 + if (hasHeader(xhr,/HX-Push:/i)) { 3411 + pathFromHeaders = xhr.getResponseHeader("HX-Push"); 3412 + typeFromHeaders = "push"; 3413 + } else if (hasHeader(xhr,/HX-Push-Url:/i)) { 3414 + pathFromHeaders = xhr.getResponseHeader("HX-Push-Url"); 3415 + typeFromHeaders = "push"; 3416 + } else if (hasHeader(xhr,/HX-Replace-Url:/i)) { 3417 + pathFromHeaders = xhr.getResponseHeader("HX-Replace-Url"); 3418 + typeFromHeaders = "replace"; 3419 + } 3420 + 3421 + // if there was a response header, that has priority 3422 + if (pathFromHeaders) { 3423 + if (pathFromHeaders === "false") { 3424 + return {} 3425 + } else { 3426 + return { 3427 + type: typeFromHeaders, 3428 + path : pathFromHeaders 3429 + } 3430 + } 3431 + } 3432 + 3433 + //=========================================== 3434 + // Next resolve via DOM values 3435 + //=========================================== 3436 + var requestPath = responseInfo.pathInfo.finalRequestPath; 3437 + var responsePath = responseInfo.pathInfo.responsePath; 3438 + 3439 + var pushUrl = getClosestAttributeValue(elt, "hx-push-url"); 3440 + var replaceUrl = getClosestAttributeValue(elt, "hx-replace-url"); 3441 + var elementIsBoosted = getInternalData(elt).boosted; 3442 + 3443 + var saveType = null; 3444 + var path = null; 3445 + 3446 + if (pushUrl) { 3447 + saveType = "push"; 3448 + path = pushUrl; 3449 + } else if (replaceUrl) { 3450 + saveType = "replace"; 3451 + path = replaceUrl; 3452 + } else if (elementIsBoosted) { 3453 + saveType = "push"; 3454 + path = responsePath || requestPath; // if there is no response path, go with the original request path 3455 + } 3456 + 3457 + if (path) { 3458 + // false indicates no push, return empty object 3459 + if (path === "false") { 3460 + return {}; 3461 + } 3462 + 3463 + // true indicates we want to follow wherever the server ended up sending us 3464 + if (path === "true") { 3465 + path = responsePath || requestPath; // if there is no response path, go with the original request path 3466 + } 3467 + 3468 + // restore any anchor associated with the request 3469 + if (responseInfo.pathInfo.anchor && 3470 + path.indexOf("#") === -1) { 3471 + path = path + "#" + responseInfo.pathInfo.anchor; 3472 + } 3473 + 3474 + return { 3475 + type:saveType, 3476 + path: path 3477 + } 3478 + } else { 3479 + return {}; 3480 + } 3481 + } 3482 + 3483 + function handleAjaxResponse(elt, responseInfo) { 3484 + var xhr = responseInfo.xhr; 3485 + var target = responseInfo.target; 3486 + var etc = responseInfo.etc; 3487 + var requestConfig = responseInfo.requestConfig; 3488 + var select = responseInfo.select; 3489 + 3490 + if (!triggerEvent(elt, 'htmx:beforeOnLoad', responseInfo)) return; 3491 + 3492 + if (hasHeader(xhr, /HX-Trigger:/i)) { 3493 + handleTrigger(xhr, "HX-Trigger", elt); 3494 + } 3495 + 3496 + if (hasHeader(xhr, /HX-Location:/i)) { 3497 + saveCurrentPageToHistory(); 3498 + var redirectPath = xhr.getResponseHeader("HX-Location"); 3499 + var swapSpec; 3500 + if (redirectPath.indexOf("{") === 0) { 3501 + swapSpec = parseJSON(redirectPath); 3502 + // what's the best way to throw an error if the user didn't include this 3503 + redirectPath = swapSpec['path']; 3504 + delete swapSpec['path']; 3505 + } 3506 + ajaxHelper('GET', redirectPath, swapSpec).then(function(){ 3507 + pushUrlIntoHistory(redirectPath); 3508 + }); 3509 + return; 3510 + } 3511 + 3512 + var shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && "true" === xhr.getResponseHeader("HX-Refresh"); 3513 + 3514 + if (hasHeader(xhr, /HX-Redirect:/i)) { 3515 + location.href = xhr.getResponseHeader("HX-Redirect"); 3516 + shouldRefresh && location.reload(); 3517 + return; 3518 + } 3519 + 3520 + if (shouldRefresh) { 3521 + location.reload(); 3522 + return; 3523 + } 3524 + 3525 + if (hasHeader(xhr,/HX-Retarget:/i)) { 3526 + if (xhr.getResponseHeader("HX-Retarget") === "this") { 3527 + responseInfo.target = elt; 3528 + } else { 3529 + responseInfo.target = querySelectorExt(elt, xhr.getResponseHeader("HX-Retarget")); 3530 + } 3531 + } 3532 + 3533 + var historyUpdate = determineHistoryUpdates(elt, responseInfo); 3534 + 3535 + // by default htmx only swaps on 200 return codes and does not swap 3536 + // on 204 'No Content' 3537 + // this can be ovverriden by responding to the htmx:beforeSwap event and 3538 + // overriding the detail.shouldSwap property 3539 + var shouldSwap = xhr.status >= 200 && xhr.status < 400 && xhr.status !== 204; 3540 + var serverResponse = xhr.response; 3541 + var isError = xhr.status >= 400; 3542 + var ignoreTitle = htmx.config.ignoreTitle 3543 + var beforeSwapDetails = mergeObjects({shouldSwap: shouldSwap, serverResponse:serverResponse, isError:isError, ignoreTitle:ignoreTitle }, responseInfo); 3544 + if (!triggerEvent(target, 'htmx:beforeSwap', beforeSwapDetails)) return; 3545 + 3546 + target = beforeSwapDetails.target; // allow re-targeting 3547 + serverResponse = beforeSwapDetails.serverResponse; // allow updating content 3548 + isError = beforeSwapDetails.isError; // allow updating error 3549 + ignoreTitle = beforeSwapDetails.ignoreTitle; // allow updating ignoring title 3550 + 3551 + responseInfo.target = target; // Make updated target available to response events 3552 + responseInfo.failed = isError; // Make failed property available to response events 3553 + responseInfo.successful = !isError; // Make successful property available to response events 3554 + 3555 + if (beforeSwapDetails.shouldSwap) { 3556 + if (xhr.status === 286) { 3557 + cancelPolling(elt); 3558 + } 3559 + 3560 + withExtensions(elt, function (extension) { 3561 + serverResponse = extension.transformResponse(serverResponse, xhr, elt); 3562 + }); 3563 + 3564 + // Save current page if there will be a history update 3565 + if (historyUpdate.type) { 3566 + saveCurrentPageToHistory(); 3567 + } 3568 + 3569 + var swapOverride = etc.swapOverride; 3570 + if (hasHeader(xhr,/HX-Reswap:/i)) { 3571 + swapOverride = xhr.getResponseHeader("HX-Reswap"); 3572 + } 3573 + var swapSpec = getSwapSpecification(elt, swapOverride); 3574 + 3575 + if (swapSpec.hasOwnProperty('ignoreTitle')) { 3576 + ignoreTitle = swapSpec.ignoreTitle; 3577 + } 3578 + 3579 + target.classList.add(htmx.config.swappingClass); 3580 + 3581 + // optional transition API promise callbacks 3582 + var settleResolve = null; 3583 + var settleReject = null; 3584 + 3585 + var doSwap = function () { 3586 + try { 3587 + var activeElt = document.activeElement; 3588 + var selectionInfo = {}; 3589 + try { 3590 + selectionInfo = { 3591 + elt: activeElt, 3592 + // @ts-ignore 3593 + start: activeElt ? activeElt.selectionStart : null, 3594 + // @ts-ignore 3595 + end: activeElt ? activeElt.selectionEnd : null 3596 + }; 3597 + } catch (e) { 3598 + // safari issue - see https://github.com/microsoft/playwright/issues/5894 3599 + } 3600 + 3601 + var selectOverride; 3602 + if (select) { 3603 + selectOverride = select; 3604 + } 3605 + 3606 + if (hasHeader(xhr, /HX-Reselect:/i)) { 3607 + selectOverride = xhr.getResponseHeader("HX-Reselect"); 3608 + } 3609 + 3610 + // if we need to save history, do so, before swapping so that relative resources have the correct base URL 3611 + if (historyUpdate.type) { 3612 + triggerEvent(getDocument().body, 'htmx:beforeHistoryUpdate', mergeObjects({ history: historyUpdate }, responseInfo)); 3613 + if (historyUpdate.type === "push") { 3614 + pushUrlIntoHistory(historyUpdate.path); 3615 + triggerEvent(getDocument().body, 'htmx:pushedIntoHistory', {path: historyUpdate.path}); 3616 + } else { 3617 + replaceUrlInHistory(historyUpdate.path); 3618 + triggerEvent(getDocument().body, 'htmx:replacedInHistory', {path: historyUpdate.path}); 3619 + } 3620 + } 3621 + 3622 + var settleInfo = makeSettleInfo(target); 3623 + selectAndSwap(swapSpec.swapStyle, target, elt, serverResponse, settleInfo, selectOverride); 3624 + 3625 + if (selectionInfo.elt && 3626 + !bodyContains(selectionInfo.elt) && 3627 + getRawAttribute(selectionInfo.elt, "id")) { 3628 + var newActiveElt = document.getElementById(getRawAttribute(selectionInfo.elt, "id")); 3629 + var focusOptions = { preventScroll: swapSpec.focusScroll !== undefined ? !swapSpec.focusScroll : !htmx.config.defaultFocusScroll }; 3630 + if (newActiveElt) { 3631 + // @ts-ignore 3632 + if (selectionInfo.start && newActiveElt.setSelectionRange) { 3633 + // @ts-ignore 3634 + try { 3635 + newActiveElt.setSelectionRange(selectionInfo.start, selectionInfo.end); 3636 + } catch (e) { 3637 + // the setSelectionRange method is present on fields that don't support it, so just let this fail 3638 + } 3639 + } 3640 + newActiveElt.focus(focusOptions); 3641 + } 3642 + } 3643 + 3644 + target.classList.remove(htmx.config.swappingClass); 3645 + forEach(settleInfo.elts, function (elt) { 3646 + if (elt.classList) { 3647 + elt.classList.add(htmx.config.settlingClass); 3648 + } 3649 + triggerEvent(elt, 'htmx:afterSwap', responseInfo); 3650 + }); 3651 + 3652 + if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) { 3653 + var finalElt = elt; 3654 + if (!bodyContains(elt)) { 3655 + finalElt = getDocument().body; 3656 + } 3657 + handleTrigger(xhr, "HX-Trigger-After-Swap", finalElt); 3658 + } 3659 + 3660 + var doSettle = function () { 3661 + forEach(settleInfo.tasks, function (task) { 3662 + task.call(); 3663 + }); 3664 + forEach(settleInfo.elts, function (elt) { 3665 + if (elt.classList) { 3666 + elt.classList.remove(htmx.config.settlingClass); 3667 + } 3668 + triggerEvent(elt, 'htmx:afterSettle', responseInfo); 3669 + }); 3670 + 3671 + if (responseInfo.pathInfo.anchor) { 3672 + var anchorTarget = getDocument().getElementById(responseInfo.pathInfo.anchor); 3673 + if(anchorTarget) { 3674 + anchorTarget.scrollIntoView({block:'start', behavior: "auto"}); 3675 + } 3676 + } 3677 + 3678 + if(settleInfo.title && !ignoreTitle) { 3679 + var titleElt = find("title"); 3680 + if(titleElt) { 3681 + titleElt.innerHTML = settleInfo.title; 3682 + } else { 3683 + window.document.title = settleInfo.title; 3684 + } 3685 + } 3686 + 3687 + updateScrollState(settleInfo.elts, swapSpec); 3688 + 3689 + if (hasHeader(xhr, /HX-Trigger-After-Settle:/i)) { 3690 + var finalElt = elt; 3691 + if (!bodyContains(elt)) { 3692 + finalElt = getDocument().body; 3693 + } 3694 + handleTrigger(xhr, "HX-Trigger-After-Settle", finalElt); 3695 + } 3696 + maybeCall(settleResolve); 3697 + } 3698 + 3699 + if (swapSpec.settleDelay > 0) { 3700 + setTimeout(doSettle, swapSpec.settleDelay) 3701 + } else { 3702 + doSettle(); 3703 + } 3704 + } catch (e) { 3705 + triggerErrorEvent(elt, 'htmx:swapError', responseInfo); 3706 + maybeCall(settleReject); 3707 + throw e; 3708 + } 3709 + }; 3710 + 3711 + var shouldTransition = htmx.config.globalViewTransitions 3712 + if(swapSpec.hasOwnProperty('transition')){ 3713 + shouldTransition = swapSpec.transition; 3714 + } 3715 + 3716 + if(shouldTransition && 3717 + triggerEvent(elt, 'htmx:beforeTransition', responseInfo) && 3718 + typeof Promise !== "undefined" && document.startViewTransition){ 3719 + var settlePromise = new Promise(function (_resolve, _reject) { 3720 + settleResolve = _resolve; 3721 + settleReject = _reject; 3722 + }); 3723 + // wrap the original doSwap() in a call to startViewTransition() 3724 + var innerDoSwap = doSwap; 3725 + doSwap = function() { 3726 + document.startViewTransition(function () { 3727 + innerDoSwap(); 3728 + return settlePromise; 3729 + }); 3730 + } 3731 + } 3732 + 3733 + 3734 + if (swapSpec.swapDelay > 0) { 3735 + setTimeout(doSwap, swapSpec.swapDelay) 3736 + } else { 3737 + doSwap(); 3738 + } 3739 + } 3740 + if (isError) { 3741 + triggerErrorEvent(elt, 'htmx:responseError', mergeObjects({error: "Response Status Error Code " + xhr.status + " from " + responseInfo.pathInfo.requestPath}, responseInfo)); 3742 + } 3743 + } 3744 + 3745 + //==================================================================== 3746 + // Extensions API 3747 + //==================================================================== 3748 + 3749 + /** @type {Object<string, import("./htmx").HtmxExtension>} */ 3750 + var extensions = {}; 3751 + 3752 + /** 3753 + * extensionBase defines the default functions for all extensions. 3754 + * @returns {import("./htmx").HtmxExtension} 3755 + */ 3756 + function extensionBase() { 3757 + return { 3758 + init: function(api) {return null;}, 3759 + onEvent : function(name, evt) {return true;}, 3760 + transformResponse : function(text, xhr, elt) {return text;}, 3761 + isInlineSwap : function(swapStyle) {return false;}, 3762 + handleSwap : function(swapStyle, target, fragment, settleInfo) {return false;}, 3763 + encodeParameters : function(xhr, parameters, elt) {return null;} 3764 + } 3765 + } 3766 + 3767 + /** 3768 + * defineExtension initializes the extension and adds it to the htmx registry 3769 + * 3770 + * @param {string} name 3771 + * @param {import("./htmx").HtmxExtension} extension 3772 + */ 3773 + function defineExtension(name, extension) { 3774 + if(extension.init) { 3775 + extension.init(internalAPI) 3776 + } 3777 + extensions[name] = mergeObjects(extensionBase(), extension); 3778 + } 3779 + 3780 + /** 3781 + * removeExtension removes an extension from the htmx registry 3782 + * 3783 + * @param {string} name 3784 + */ 3785 + function removeExtension(name) { 3786 + delete extensions[name]; 3787 + } 3788 + 3789 + /** 3790 + * getExtensions searches up the DOM tree to return all extensions that can be applied to a given element 3791 + * 3792 + * @param {HTMLElement} elt 3793 + * @param {import("./htmx").HtmxExtension[]=} extensionsToReturn 3794 + * @param {import("./htmx").HtmxExtension[]=} extensionsToIgnore 3795 + */ 3796 + function getExtensions(elt, extensionsToReturn, extensionsToIgnore) { 3797 + 3798 + if (elt == undefined) { 3799 + return extensionsToReturn; 3800 + } 3801 + if (extensionsToReturn == undefined) { 3802 + extensionsToReturn = []; 3803 + } 3804 + if (extensionsToIgnore == undefined) { 3805 + extensionsToIgnore = []; 3806 + } 3807 + var extensionsForElement = getAttributeValue(elt, "hx-ext"); 3808 + if (extensionsForElement) { 3809 + forEach(extensionsForElement.split(","), function(extensionName){ 3810 + extensionName = extensionName.replace(/ /g, ''); 3811 + if (extensionName.slice(0, 7) == "ignore:") { 3812 + extensionsToIgnore.push(extensionName.slice(7)); 3813 + return; 3814 + } 3815 + if (extensionsToIgnore.indexOf(extensionName) < 0) { 3816 + var extension = extensions[extensionName]; 3817 + if (extension && extensionsToReturn.indexOf(extension) < 0) { 3818 + extensionsToReturn.push(extension); 3819 + } 3820 + } 3821 + }); 3822 + } 3823 + return getExtensions(parentElt(elt), extensionsToReturn, extensionsToIgnore); 3824 + } 3825 + 3826 + //==================================================================== 3827 + // Initialization 3828 + //==================================================================== 3829 + var isReady = false 3830 + getDocument().addEventListener('DOMContentLoaded', function() { 3831 + isReady = true 3832 + }) 3833 + 3834 + /** 3835 + * Execute a function now if DOMContentLoaded has fired, otherwise listen for it. 3836 + * 3837 + * This function uses isReady because there is no realiable way to ask the browswer whether 3838 + * the DOMContentLoaded event has already been fired; there's a gap between DOMContentLoaded 3839 + * firing and readystate=complete. 3840 + */ 3841 + function ready(fn) { 3842 + // Checking readyState here is a failsafe in case the htmx script tag entered the DOM by 3843 + // some means other than the initial page load. 3844 + if (isReady || getDocument().readyState === 'complete') { 3845 + fn(); 3846 + } else { 3847 + getDocument().addEventListener('DOMContentLoaded', fn); 3848 + } 3849 + } 3850 + 3851 + function insertIndicatorStyles() { 3852 + if (htmx.config.includeIndicatorStyles !== false) { 3853 + getDocument().head.insertAdjacentHTML("beforeend", 3854 + "<style>\ 3855 + ." + htmx.config.indicatorClass + "{opacity:0}\ 3856 + ." + htmx.config.requestClass + " ." + htmx.config.indicatorClass + "{opacity:1; transition: opacity 200ms ease-in;}\ 3857 + ." + htmx.config.requestClass + "." + htmx.config.indicatorClass + "{opacity:1; transition: opacity 200ms ease-in;}\ 3858 + </style>"); 3859 + } 3860 + } 3861 + 3862 + function getMetaConfig() { 3863 + var element = getDocument().querySelector('meta[name="htmx-config"]'); 3864 + if (element) { 3865 + // @ts-ignore 3866 + return parseJSON(element.content); 3867 + } else { 3868 + return null; 3869 + } 3870 + } 3871 + 3872 + function mergeMetaConfig() { 3873 + var metaConfig = getMetaConfig(); 3874 + if (metaConfig) { 3875 + htmx.config = mergeObjects(htmx.config , metaConfig) 3876 + } 3877 + } 3878 + 3879 + // initialize the document 3880 + ready(function () { 3881 + mergeMetaConfig(); 3882 + insertIndicatorStyles(); 3883 + var body = getDocument().body; 3884 + processNode(body); 3885 + var restoredElts = getDocument().querySelectorAll( 3886 + "[hx-trigger='restored'],[data-hx-trigger='restored']" 3887 + ); 3888 + body.addEventListener("htmx:abort", function (evt) { 3889 + var target = evt.target; 3890 + var internalData = getInternalData(target); 3891 + if (internalData && internalData.xhr) { 3892 + internalData.xhr.abort(); 3893 + } 3894 + }); 3895 + /** @type {(ev: PopStateEvent) => any} */ 3896 + const originalPopstate = window.onpopstate ? window.onpopstate.bind(window) : null; 3897 + /** @type {(ev: PopStateEvent) => any} */ 3898 + window.onpopstate = function (event) { 3899 + if (event.state && event.state.htmx) { 3900 + restoreHistory(); 3901 + forEach(restoredElts, function(elt){ 3902 + triggerEvent(elt, 'htmx:restored', { 3903 + 'document': getDocument(), 3904 + 'triggerEvent': triggerEvent 3905 + }); 3906 + }); 3907 + } else { 3908 + if (originalPopstate) { 3909 + originalPopstate(event); 3910 + } 3911 + } 3912 + }; 3913 + setTimeout(function () { 3914 + triggerEvent(body, 'htmx:load', {}); // give ready handlers a chance to load up before firing this event 3915 + body = null; // kill reference for gc 3916 + }, 0); 3917 + }) 3918 + 3919 + return htmx; 3920 + } 3921 + )() 3922 + }));
+1 -1
public/script/lib/htmx.min.js
··· 1 - (function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var Q={onLoad:B,process:zt,on:de,off:ge,trigger:ce,ajax:Nr,find:C,findAll:f,closest:v,values:function(e,t){var r=dr(e,t||"post");return r.values},remove:_,addClass:z,removeClass:n,toggleClass:$,takeClass:W,defineExtension:Ur,removeExtension:Fr,logAll:V,logNone:j,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false,ignoreTitle:false,scrollIntoViewOnBoost:true,triggerSpecsCache:null},parseInterval:d,_:t,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=Q.config.wsBinaryType;return t},version:"1.9.11"};var r={addTriggerHandler:Lt,bodyContains:se,canAccessLocalStorage:U,findThisElement:xe,filterValues:yr,hasAttribute:o,getAttributeValue:te,getClosestAttributeValue:ne,getClosestMatch:c,getExpressionVars:Hr,getHeaders:xr,getInputValues:dr,getInternalData:ae,getSwapSpecification:wr,getTriggerSpecs:it,getTarget:ye,makeFragment:l,mergeObjects:le,makeSettleInfo:T,oobSwap:Ee,querySelectorExt:ue,selectAndSwap:je,settleImmediately:nr,shouldCancel:ut,triggerEvent:ce,triggerErrorEvent:fe,withExtensions:R};var w=["get","post","put","delete","patch"];var i=w.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");var S=e("head"),q=e("title"),H=e("svg",true);function e(e,t=false){return new RegExp(`<${e}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${e}>`,t?"gim":"im")}function d(e){if(e==undefined){return undefined}let t=NaN;if(e.slice(-2)=="ms"){t=parseFloat(e.slice(0,-2))}else if(e.slice(-1)=="s"){t=parseFloat(e.slice(0,-1))*1e3}else if(e.slice(-1)=="m"){t=parseFloat(e.slice(0,-1))*1e3*60}else{t=parseFloat(e)}return isNaN(t)?undefined:t}function ee(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function te(e,t){return ee(e,t)||ee(e,"data-"+t)}function u(e){return e.parentElement}function re(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function L(e,t,r){var n=te(t,r);var i=te(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function ne(t,r){var n=null;c(t,function(e){return n=L(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function A(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function s(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=re().createDocumentFragment()}return i}function N(e){return/<body/.test(e)}function l(e){var t=!N(e);var r=A(e);var n=e;if(r==="head"){n=n.replace(S,"")}if(Q.config.useTemplateFragments&&t){var i=s("<body><template>"+n+"</template></body>",0);var a=i.querySelector("template").content;if(Q.config.allowScriptTags){oe(a.querySelectorAll("script"),function(e){if(Q.config.inlineScriptNonce){e.nonce=Q.config.inlineScriptNonce}e.htmxExecuted=navigator.userAgent.indexOf("Firefox")===-1})}else{oe(a.querySelectorAll("script"),function(e){_(e)})}return a}switch(r){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return s("<table>"+n+"</table>",1);case"col":return s("<table><colgroup>"+n+"</colgroup></table>",2);case"tr":return s("<table><tbody>"+n+"</tbody></table>",2);case"td":case"th":return s("<table><tbody><tr>"+n+"</tr></tbody></table>",3);case"script":case"style":return s("<div>"+n+"</div>",1);default:return s(n,0)}}function ie(e){if(e){e()}}function I(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function k(e){return I(e,"Function")}function P(e){return I(e,"Object")}function ae(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function M(e){var t=[];if(e){for(var r=0;r<e.length;r++){t.push(e[r])}}return t}function oe(e,t){if(e){for(var r=0;r<e.length;r++){t(e[r])}}}function X(e){var t=e.getBoundingClientRect();var r=t.top;var n=t.bottom;return r<window.innerHeight&&n>=0}function se(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return re().body.contains(e.getRootNode().host)}else{return re().body.contains(e)}}function D(e){return e.trim().split(/\s+/)}function le(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function E(e){try{return JSON.parse(e)}catch(e){b(e);return null}}function U(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function F(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!/^\/$/.test(t)){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function t(e){return Tr(re().body,function(){return eval(e)})}function B(t){var e=Q.on("htmx:load",function(e){t(e.detail.elt)});return e}function V(){Q.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function j(){Q.logger=null}function C(e,t){if(t){return e.querySelector(t)}else{return C(re(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(re(),e)}}function _(e,t){e=p(e);if(t){setTimeout(function(){_(e);e=null},t)}else{e.parentElement.removeChild(e)}}function z(e,t,r){e=p(e);if(r){setTimeout(function(){z(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=p(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function $(e,t){e=p(e);e.classList.toggle(t)}function W(e,t){e=p(e);oe(e.parentElement.children,function(e){n(e,t)});z(e,t)}function v(e,t){e=p(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function g(e,t){return e.substring(0,t.length)===t}function G(e,t){return e.substring(e.length-t.length)===t}function J(e){var t=e.trim();if(g(t,"<")&&G(t,"/>")){return t.substring(1,t.length-2)}else{return t}}function Z(e,t){if(t.indexOf("closest ")===0){return[v(e,J(t.substr(8)))]}else if(t.indexOf("find ")===0){return[C(e,J(t.substr(5)))]}else if(t==="next"){return[e.nextElementSibling]}else if(t.indexOf("next ")===0){return[K(e,J(t.substr(5)))]}else if(t==="previous"){return[e.previousElementSibling]}else if(t.indexOf("previous ")===0){return[Y(e,J(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return re().querySelectorAll(J(t))}}var K=function(e,t){var r=re().querySelectorAll(t);for(var n=0;n<r.length;n++){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_PRECEDING){return i}}};var Y=function(e,t){var r=re().querySelectorAll(t);for(var n=r.length-1;n>=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ue(e,t){if(t){return Z(e,t)[0]}else{return Z(re().body,e)[0]}}function p(e){if(I(e,"String")){return C(e)}else{return e}}function ve(e,t,r){if(k(t)){return{target:re().body,event:e,listener:t}}else{return{target:p(e),event:t,listener:r}}}function de(t,r,n){jr(function(){var e=ve(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=k(r);return e?r:n}function ge(t,r,n){jr(function(){var e=ve(t,r,n);e.target.removeEventListener(e.event,e.listener)});return k(r)?r:n}var pe=re().createElement("output");function me(e,t){var r=ne(e,t);if(r){if(r==="this"){return[xe(e,t)]}else{var n=Z(e,r);if(n.length===0){b('The selector "'+r+'" on '+t+" returned no matches!");return[pe]}else{return n}}}}function xe(e,t){return c(e,function(e){return te(e,t)!=null})}function ye(e){var t=ne(e,"hx-target");if(t){if(t==="this"){return xe(e,"hx-target")}else{return ue(e,t)}}else{var r=ae(e);if(r.boosted){return re().body}else{return e}}}function be(e){var t=Q.config.attributesToSettle;for(var r=0;r<t.length;r++){if(e===t[r]){return true}}return false}function we(t,r){oe(t.attributes,function(e){if(!r.hasAttribute(e.name)&&be(e.name)){t.removeAttribute(e.name)}});oe(r.attributes,function(e){if(be(e.name)){t.setAttribute(e.name,e.value)}})}function Se(e,t){var r=Br(t);for(var n=0;n<r.length;n++){var i=r[n];try{if(i.isInlineSwap(e)){return true}}catch(e){b(e)}}return e==="outerHTML"}function Ee(e,i,a){var t="#"+ee(i,"id");var o="outerHTML";if(e==="true"){}else if(e.indexOf(":")>0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=re().querySelectorAll(t);if(r){oe(r,function(e){var t;var r=i.cloneNode(true);t=re().createDocumentFragment();t.appendChild(r);if(!Se(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!ce(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){Be(o,e,e,t,a)}oe(a.elts,function(e){ce(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);fe(re().body,"htmx:oobErrorNoTarget",{content:i})}return e}function Ce(e,t,r){var n=ne(e,"hx-select-oob");if(n){var i=n.split(",");for(var a=0;a<i.length;a++){var o=i[a].split(":",2);var s=o[0].trim();if(s.indexOf("#")===0){s=s.substring(1)}var l=o[1]||"true";var u=t.querySelector("#"+s);if(u){Ee(l,u,r)}}}oe(f(t,"[hx-swap-oob], [data-hx-swap-oob]"),function(e){var t=te(e,"hx-swap-oob");if(t!=null){Ee(t,e,r)}})}function Re(e){oe(f(e,"[hx-preserve], [data-hx-preserve]"),function(e){var t=te(e,"id");var r=re().getElementById(t);if(r!=null){e.parentNode.replaceChild(r,e)}})}function Te(o,e,s){oe(e.querySelectorAll("[id]"),function(e){var t=ee(e,"id");if(t&&t.length>0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();we(e,i);s.tasks.push(function(){we(e,a)})}}})}function Oe(e){return function(){n(e,Q.config.addedClass);zt(e);Nt(e);qe(e);ce(e,"htmx:load")}}function qe(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){Te(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;z(i,Q.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Oe(i))}}}function He(e,t){var r=0;while(r<e.length){t=(t<<5)-t+e.charCodeAt(r++)|0}return t}function Le(e){var t=0;if(e.attributes){for(var r=0;r<e.attributes.length;r++){var n=e.attributes[r];if(n.value){t=He(n.name,t);t=He(n.value,t)}}}return t}function Ae(e){var t=ae(e);if(t.onHandlers){for(var r=0;r<t.onHandlers.length;r++){const n=t.onHandlers[r];e.removeEventListener(n.event,n.listener)}delete t.onHandlers}}function Ne(e){var t=ae(e);if(t.timeout){clearTimeout(t.timeout)}if(t.webSocket){t.webSocket.close()}if(t.sseEventSource){t.sseEventSource.close()}if(t.listenerInfos){oe(t.listenerInfos,function(e){if(e.on){e.on.removeEventListener(e.trigger,e.listener)}})}Ae(e);oe(Object.keys(t),function(e){delete t[e]})}function m(e){ce(e,"htmx:beforeCleanupElement");Ne(e);if(e.children){oe(e.children,function(e){m(e)})}}function Ie(t,e,r){if(t.tagName==="BODY"){return Ue(t,e,r)}else{var n;var i=t.previousSibling;a(u(t),t,e,r);if(i==null){n=u(t).firstChild}else{n=i.nextSibling}r.elts=r.elts.filter(function(e){return e!=t});while(n&&n!==t){if(n.nodeType===Node.ELEMENT_NODE){r.elts.push(n)}n=n.nextElementSibling}m(t);u(t).removeChild(t)}}function ke(e,t,r){return a(e,e.firstChild,t,r)}function Pe(e,t,r){return a(u(e),e,t,r)}function Me(e,t,r){return a(e,null,t,r)}function Xe(e,t,r){return a(u(e),e.nextSibling,t,r)}function De(e,t,r){m(e);return u(e).removeChild(e)}function Ue(e,t,r){var n=e.firstChild;a(e,n,t,r);if(n){while(n.nextSibling){m(n.nextSibling);e.removeChild(n.nextSibling)}m(n);e.removeChild(n)}}function Fe(e,t,r){var n=r||ne(e,"hx-select");if(n){var i=re().createDocumentFragment();oe(t.querySelectorAll(n),function(e){i.appendChild(e)});t=i}return t}function Be(e,t,r,n,i){switch(e){case"none":return;case"outerHTML":Ie(r,n,i);return;case"afterbegin":ke(r,n,i);return;case"beforebegin":Pe(r,n,i);return;case"beforeend":Me(r,n,i);return;case"afterend":Xe(r,n,i);return;case"delete":De(r,n,i);return;default:var a=Br(t);for(var o=0;o<a.length;o++){var s=a[o];try{var l=s.handleSwap(e,r,n,i);if(l){if(typeof l.length!=="undefined"){for(var u=0;u<l.length;u++){var f=l[u];if(f.nodeType!==Node.TEXT_NODE&&f.nodeType!==Node.COMMENT_NODE){i.tasks.push(Oe(f))}}}return}}catch(e){b(e)}}if(e==="innerHTML"){Ue(r,n,i)}else{Be(Q.config.defaultSwapStyle,t,r,n,i)}}}function Ve(e){if(e.indexOf("<title")>-1){var t=e.replace(H,"");var r=t.match(q);if(r){return r[2]}}}function je(e,t,r,n,i,a){i.title=Ve(n);var o=l(n);if(o){Ce(r,o,i);o=Fe(r,o,a);Re(o);return Be(e,r,t,o,i)}}function _e(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=E(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!P(o)){o={value:o}}ce(r,a,o)}}}else{var s=n.split(",");for(var l=0;l<s.length;l++){ce(r,s[l].trim(),[])}}}var ze=/\s/;var x=/[\s,]/;var $e=/[_$a-zA-Z]/;var We=/[_$a-zA-Z0-9]/;var Ge=['"',"'","/"];var Je=/[^\s]/;var Ze=/[{(]/;var Ke=/[})]/;function Ye(e){var t=[];var r=0;while(r<e.length){if($e.exec(e.charAt(r))){var n=r;while(We.exec(e.charAt(r+1))){r++}t.push(e.substr(n,r-n+1))}else if(Ge.indexOf(e.charAt(r))!==-1){var i=e.charAt(r);var n=r;r++;while(r<e.length&&e.charAt(r)!==i){if(e.charAt(r)==="\\"){r++}r++}t.push(e.substr(n,r-n+1))}else{var a=e.charAt(r);t.push(a)}r++}return t}function Qe(e,t,r){return $e.exec(e.charAt(0))&&e!=="true"&&e!=="false"&&e!=="this"&&e!==r&&t!=="."}function et(e,t,r){if(t[0]==="["){t.shift();var n=1;var i=" return (function("+r+"){ return (";var a=null;while(t.length>0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=Tr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){fe(re().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(Qe(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function y(e,t){var r="";while(e.length>0&&!t.test(e[0])){r+=e.shift()}return r}function tt(e){var t;if(e.length>0&&Ze.test(e[0])){e.shift();t=y(e,Ke).trim();e.shift()}else{t=y(e,x)}return t}var rt="input, textarea, select";function nt(e,t,r){var n=[];var i=Ye(t);do{y(i,Je);var a=i.length;var o=y(i,/[,\[\s]/);if(o!==""){if(o==="every"){var s={trigger:"every"};y(i,Je);s.pollInterval=d(y(i,/[,\[\s]/));y(i,Je);var l=et(e,i,"event");if(l){s.eventFilter=l}n.push(s)}else if(o.indexOf("sse:")===0){n.push({trigger:"sse",sseEvent:o.substr(4)})}else{var u={trigger:o};var l=et(e,i,"event");if(l){u.eventFilter=l}while(i.length>0&&i[0]!==","){y(i,Je);var f=i.shift();if(f==="changed"){u.changed=true}else if(f==="once"){u.once=true}else if(f==="consume"){u.consume=true}else if(f==="delay"&&i[0]===":"){i.shift();u.delay=d(y(i,x))}else if(f==="from"&&i[0]===":"){i.shift();if(Ze.test(i[0])){var c=tt(i)}else{var c=y(i,x);if(c==="closest"||c==="find"||c==="next"||c==="previous"){i.shift();var h=tt(i);if(h.length>0){c+=" "+h}}}u.from=c}else if(f==="target"&&i[0]===":"){i.shift();u.target=tt(i)}else if(f==="throttle"&&i[0]===":"){i.shift();u.throttle=d(y(i,x))}else if(f==="queue"&&i[0]===":"){i.shift();u.queue=y(i,x)}else if(f==="root"&&i[0]===":"){i.shift();u[f]=tt(i)}else if(f==="threshold"&&i[0]===":"){i.shift();u[f]=y(i,x)}else{fe(e,"htmx:syntax:error",{token:i.shift()})}}n.push(u)}}if(i.length===a){fe(e,"htmx:syntax:error",{token:i.shift()})}y(i,Je)}while(i[0]===","&&i.shift());if(r){r[t]=n}return n}function it(e){var t=te(e,"hx-trigger");var r=[];if(t){var n=Q.config.triggerSpecsCache;r=n&&n[t]||nt(e,t,n)}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,rt)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function at(e){ae(e).cancelled=true}function ot(e,t,r){var n=ae(e);n.timeout=setTimeout(function(){if(se(e)&&n.cancelled!==true){if(!ct(r,e,Wt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}ot(e,t,r)}},r.pollInterval)}function st(e){return location.hostname===e.hostname&&ee(e,"href")&&ee(e,"href").indexOf("#")!==0}function lt(t,r,e){if(t.tagName==="A"&&st(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=ee(t,"href")}else{var a=ee(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=ee(t,"action")}e.forEach(function(e){ht(t,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(n,i,e,t)},r,e,true)})}}function ut(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&v(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function ft(e,t){return ae(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function ct(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){fe(re().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function ht(a,o,e,s,l){var u=ae(a);var t;if(s.from){t=Z(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ae(e);t.lastValue=e.value})}oe(t,function(n){var i=function(e){if(!se(a)){n.removeEventListener(s.trigger,i);return}if(ft(a,e)){return}if(l||ut(e,a)){e.preventDefault()}if(ct(s,a,e)){return}var t=ae(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ae(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle>0){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay>0){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{ce(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var vt=false;var dt=null;function gt(){if(!dt){dt=function(){vt=true};window.addEventListener("scroll",dt);setInterval(function(){if(vt){vt=false;oe(re().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){pt(e)})}},200)}}function pt(t){if(!o(t,"data-hx-revealed")&&X(t)){t.setAttribute("data-hx-revealed","true");var e=ae(t);if(e.initHash){ce(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){ce(t,"revealed")},{once:true})}}}function mt(e,t,r){var n=D(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){xt(e,a[1],0)}if(a[0]==="send"){bt(e)}}}function xt(s,r,n){if(!se(s)){return}if(r.indexOf("/")==0){var e=location.hostname+(location.port?":"+location.port:"");if(location.protocol=="https:"){r="wss://"+e+r}else if(location.protocol=="http:"){r="ws://"+e+r}}var t=Q.createWebSocket(r);t.onerror=function(e){fe(s,"htmx:wsError",{error:e,socket:t});yt(s)};t.onclose=function(e){if([1006,1012,1013].indexOf(e.code)>=0){var t=wt(n);setTimeout(function(){xt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ae(s).webSocket=t;t.addEventListener("message",function(e){if(yt(s)){return}var t=e.data;R(s,function(e){t=e.transformResponse(t,null,s)});var r=T(s);var n=l(t);var i=M(n.children);for(var a=0;a<i.length;a++){var o=i[a];Ee(te(o,"hx-swap-oob")||"true",o,r)}nr(r.tasks)})}function yt(e){if(!se(e)){ae(e).webSocket.close();return true}}function bt(u){var f=c(u,function(e){return ae(e).webSocket!=null});if(f){u.addEventListener(it(u)[0].trigger,function(e){var t=ae(f).webSocket;var r=xr(u,f);var n=dr(u,"post");var i=n.errors;var a=n.values;var o=Hr(u);var s=le(a,o);var l=yr(s,u);l["HEADERS"]=r;if(i&&i.length>0){ce(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(ut(e,u)){e.preventDefault()}})}else{fe(u,"htmx:noWebSocketSourceError")}}function wt(e){var t=Q.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}b('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function St(e,t,r){var n=D(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){Et(e,a[1])}if(a[0]==="swap"){Ct(e,a[1])}}}function Et(t,e){var r=Q.createEventSource(e);r.onerror=function(e){fe(t,"htmx:sseError",{error:e,source:r});Tt(t)};ae(t).sseEventSource=r}function Ct(a,o){var s=c(a,Ot);if(s){var l=ae(s).sseEventSource;var u=function(e){if(Tt(s)){return}if(!se(a)){l.removeEventListener(o,u);return}var t=e.data;R(a,function(e){t=e.transformResponse(t,null,a)});var r=wr(a);var n=ye(a);var i=T(a);je(r.swapStyle,n,a,t,i);nr(i.tasks);ce(a,"htmx:sseMessage",e)};ae(a).sseListener=u;l.addEventListener(o,u)}else{fe(a,"htmx:noSSESourceError")}}function Rt(e,t,r){var n=c(e,Ot);if(n){var i=ae(n).sseEventSource;var a=function(){if(!Tt(n)){if(se(e)){t(e)}else{i.removeEventListener(r,a)}}};ae(e).sseListener=a;i.addEventListener(r,a)}else{fe(e,"htmx:noSSESourceError")}}function Tt(e){if(!se(e)){ae(e).sseEventSource.close();return true}}function Ot(e){return ae(e).sseEventSource!=null}function qt(e,t,r,n){var i=function(){if(!r.loaded){r.loaded=true;t(e)}};if(n>0){setTimeout(i,n)}else{i()}}function Ht(t,i,e){var a=false;oe(w,function(r){if(o(t,"hx-"+r)){var n=te(t,"hx-"+r);a=true;i.path=n;i.verb=r;e.forEach(function(e){Lt(t,e,i,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(r,n,e,t)})})}});return a}function Lt(n,e,t,r){if(e.sseEvent){Rt(n,r,e.sseEvent)}else if(e.trigger==="revealed"){gt();ht(n,r,t,e);pt(n)}else if(e.trigger==="intersect"){var i={};if(e.root){i.root=ue(n,e.root)}if(e.threshold){i.threshold=parseFloat(e.threshold)}var a=new IntersectionObserver(function(e){for(var t=0;t<e.length;t++){var r=e[t];if(r.isIntersecting){ce(n,"intersect");break}}},i);a.observe(n);ht(n,r,t,e)}else if(e.trigger==="load"){if(!ct(e,n,Wt("load",{elt:n}))){qt(n,r,t,e.delay)}}else if(e.pollInterval>0){t.polling=true;ot(n,r,e)}else{ht(n,r,t,e)}}function At(e){if(!e.htmxExecuted&&Q.config.allowScriptTags&&(e.type==="text/javascript"||e.type==="module"||e.type==="")){var t=re().createElement("script");oe(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(Q.config.inlineScriptNonce){t.nonce=Q.config.inlineScriptNonce}var r=e.parentElement;try{r.insertBefore(t,e)}catch(e){b(e)}finally{if(e.parentElement){e.parentElement.removeChild(e)}}}}function Nt(e){if(h(e,"script")){At(e)}oe(f(e,"script"),function(e){At(e)})}function It(e){var t=e.attributes;for(var r=0;r<t.length;r++){var n=t[r].name;if(g(n,"hx-on:")||g(n,"data-hx-on:")||g(n,"hx-on-")||g(n,"data-hx-on-")){return true}}return false}function kt(e){var t=null;var r=[];if(It(e)){r.push(e)}if(document.evaluate){var n=document.evaluate('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or'+' starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]',e);while(t=n.iterateNext())r.push(t)}else{var i=e.getElementsByTagName("*");for(var a=0;a<i.length;a++){if(It(i[a])){r.push(i[a])}}}return r}function Pt(e){if(e.querySelectorAll){var t=", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]";var r=e.querySelectorAll(i+t+", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws],"+" [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]");return r}else{return[]}}function Mt(e){var t=v(e.target,"button, input[type='submit']");var r=Dt(e);if(r){r.lastButtonClicked=t}}function Xt(e){var t=Dt(e);if(t){t.lastButtonClicked=null}}function Dt(e){var t=v(e.target,"button, input[type='submit']");if(!t){return}var r=p("#"+ee(t,"form"))||v(t,"form");if(!r){return}return ae(r)}function Ut(e){e.addEventListener("click",Mt);e.addEventListener("focusin",Mt);e.addEventListener("focusout",Xt)}function Ft(e){var t=Ye(e);var r=0;for(var n=0;n<t.length;n++){const i=t[n];if(i==="{"){r++}else if(i==="}"){r--}}return r}function Bt(t,e,r){var n=ae(t);if(!Array.isArray(n.onHandlers)){n.onHandlers=[]}var i;var a=function(e){return Tr(t,function(){if(!i){i=new Function("event",r)}i.call(t,e)})};t.addEventListener(e,a);n.onHandlers.push({event:e,listener:a})}function Vt(e){var t=te(e,"hx-on");if(t){var r={};var n=t.split("\n");var i=null;var a=0;while(n.length>0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Ft(o)}for(var l in r){Bt(e,l,r[l])}}}function jt(e){Ae(e);for(var t=0;t<e.attributes.length;t++){var r=e.attributes[t].name;var n=e.attributes[t].value;if(g(r,"hx-on")||g(r,"data-hx-on")){var i=r.indexOf("-on")+3;var a=r.slice(i,i+1);if(a==="-"||a===":"){var o=r.slice(i+1);if(g(o,":")){o="htmx"+o}else if(g(o,"-")){o="htmx:"+o.slice(1)}else if(g(o,"htmx-")){o="htmx:"+o.slice(5)}Bt(e,o,n)}}}}function _t(t){if(v(t,Q.config.disableSelector)){m(t);return}var r=ae(t);if(r.initHash!==Le(t)){Ne(t);r.initHash=Le(t);Vt(t);ce(t,"htmx:beforeProcessNode");if(t.value){r.lastValue=t.value}var e=it(t);var n=Ht(t,r,e);if(!n){if(ne(t,"hx-boost")==="true"){lt(t,r,e)}else if(o(t,"hx-trigger")){e.forEach(function(e){Lt(t,e,r,function(){})})}}if(t.tagName==="FORM"||ee(t,"type")==="submit"&&o(t,"form")){Ut(t)}var i=te(t,"hx-sse");if(i){St(t,r,i)}var a=te(t,"hx-ws");if(a){mt(t,r,a)}ce(t,"htmx:afterProcessNode")}}function zt(e){e=p(e);if(v(e,Q.config.disableSelector)){m(e);return}_t(e);oe(Pt(e),function(e){_t(e)});oe(kt(e),jt)}function $t(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function Wt(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=re().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function fe(e,t,r){ce(e,t,le({error:t},r))}function Gt(e){return e==="htmx:afterProcessNode"}function R(e,t){oe(Br(e),function(e){try{t(e)}catch(e){b(e)}})}function b(e){if(console.error){console.error(e)}else if(console.log){console.log("ERROR: ",e)}}function ce(e,t,r){e=p(e);if(r==null){r={}}r["elt"]=e;var n=Wt(t,r);if(Q.logger&&!Gt(t)){Q.logger(e,t,r)}if(r.error){b(r.error);ce(e,"htmx:error",{errorInfo:r})}var i=e.dispatchEvent(n);var a=$t(t);if(i&&a!==t){var o=Wt(a,n.detail);i=i&&e.dispatchEvent(o)}R(e,function(e){i=i&&(e.onEvent(t,n)!==false&&!n.defaultPrevented)});return i}var Jt=location.pathname+location.search;function Zt(){var e=re().querySelector("[hx-history-elt],[data-hx-history-elt]");return e||re().body}function Kt(e,t,r,n){if(!U()){return}if(Q.config.historyCacheSize<=0){localStorage.removeItem("htmx-history-cache");return}e=F(e);var i=E(localStorage.getItem("htmx-history-cache"))||[];for(var a=0;a<i.length;a++){if(i[a].url===e){i.splice(a,1);break}}var o={url:e,content:t,title:r,scroll:n};ce(re().body,"htmx:historyItemCreated",{item:o,cache:i});i.push(o);while(i.length>Q.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){fe(re().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Yt(e){if(!U()){return null}e=F(e);var t=E(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r<t.length;r++){if(t[r].url===e){return t[r]}}return null}function Qt(e){var t=Q.config.requestClass;var r=e.cloneNode(true);oe(f(r,"."+t),function(e){n(e,t)});return r.innerHTML}function er(){var e=Zt();var t=Jt||location.pathname+location.search;var r;try{r=re().querySelector('[hx-history="false" i],[data-hx-history="false" i]')}catch(e){r=re().querySelector('[hx-history="false"],[data-hx-history="false"]')}if(!r){ce(re().body,"htmx:beforeHistorySave",{path:t,historyElt:e});Kt(t,Qt(e),re().title,window.scrollY)}if(Q.config.historyEnabled)history.replaceState({htmx:true},re().title,window.location.href)}function tr(e){if(Q.config.getCacheBusterParam){e=e.replace(/org\.htmx\.cache-buster=[^&]*&?/,"");if(G(e,"&")||G(e,"?")){e=e.slice(0,-1)}}if(Q.config.historyEnabled){history.pushState({htmx:true},"",e)}Jt=e}function rr(e){if(Q.config.historyEnabled)history.replaceState({htmx:true},"",e);Jt=e}function nr(e){oe(e,function(e){e.call()})}function ir(a){var e=new XMLHttpRequest;var o={path:a,xhr:e};ce(re().body,"htmx:historyCacheMiss",o);e.open("GET",a,true);e.setRequestHeader("HX-Request","true");e.setRequestHeader("HX-History-Restore-Request","true");e.setRequestHeader("HX-Current-URL",re().location.href);e.onload=function(){if(this.status>=200&&this.status<400){ce(re().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Zt();var r=T(t);var n=Ve(this.response);if(n){var i=C("title");if(i){i.innerHTML=n}else{window.document.title=n}}Ue(t,e,r);nr(r.tasks);Jt=a;ce(re().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{fe(re().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function ar(e){er();e=e||location.pathname+location.search;var t=Yt(e);if(t){var r=l(t.content);var n=Zt();var i=T(n);Ue(n,r,i);nr(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Jt=e;ce(re().body,"htmx:historyRestore",{path:e,item:t})}else{if(Q.config.refreshOnHistoryMiss){window.location.reload(true)}else{ir(e)}}}function or(e){var t=me(e,"hx-indicator");if(t==null){t=[e]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,Q.config.requestClass)});return t}function sr(e){var t=me(e,"hx-disabled-elt");if(t==null){t=[]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.setAttribute("disabled","")});return t}function lr(e,t){oe(e,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,Q.config.requestClass)}});oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.removeAttribute("disabled")}})}function ur(e,t){for(var r=0;r<e.length;r++){var n=e[r];if(n.isSameNode(t)){return true}}return false}function fr(e){if(e.name===""||e.name==null||e.disabled||v(e,"fieldset[disabled]")){return false}if(e.type==="button"||e.type==="submit"||e.tagName==="image"||e.tagName==="reset"||e.tagName==="file"){return false}if(e.type==="checkbox"||e.type==="radio"){return e.checked}return true}function cr(e,t,r){if(e!=null&&t!=null){var n=r[e];if(n===undefined){r[e]=t}else if(Array.isArray(n)){if(Array.isArray(t)){r[e]=n.concat(t)}else{n.push(t)}}else{if(Array.isArray(t)){r[e]=[n].concat(t)}else{r[e]=[n,t]}}}}function hr(t,r,n,e,i){if(e==null||ur(t,e)){return}else{t.push(e)}if(fr(e)){var a=ee(e,"name");var o=e.value;if(e.multiple&&e.tagName==="SELECT"){o=M(e.querySelectorAll("option:checked")).map(function(e){return e.value})}if(e.files){o=M(e.files)}cr(a,o,r);if(i){vr(e,n)}}if(h(e,"form")){var s=e.elements;oe(s,function(e){hr(t,r,n,e,i)})}}function vr(e,t){if(e.willValidate){ce(e,"htmx:validation:validate");if(!e.checkValidity()){t.push({elt:e,message:e.validationMessage,validity:e.validity});ce(e,"htmx:validation:failed",{message:e.validationMessage,validity:e.validity})}}}function dr(e,t){var r=[];var n={};var i={};var a=[];var o=ae(e);if(o.lastButtonClicked&&!se(o.lastButtonClicked)){o.lastButtonClicked=null}var s=h(e,"form")&&e.noValidate!==true||te(e,"hx-validate")==="true";if(o.lastButtonClicked){s=s&&o.lastButtonClicked.formNoValidate!==true}if(t!=="get"){hr(r,i,a,v(e,"form"),s)}hr(r,n,a,e,s);if(o.lastButtonClicked||e.tagName==="BUTTON"||e.tagName==="INPUT"&&ee(e,"type")==="submit"){var l=o.lastButtonClicked||e;var u=ee(l,"name");cr(u,l.value,i)}var f=me(e,"hx-include");oe(f,function(e){hr(r,n,a,e,s);if(!h(e,"form")){oe(e.querySelectorAll(rt),function(e){hr(r,n,a,e,s)})}});n=le(n,i);return{errors:a,values:n}}function gr(e,t,r){if(e!==""){e+="&"}if(String(r)==="[object Object]"){r=JSON.stringify(r)}var n=encodeURIComponent(r);e+=encodeURIComponent(t)+"="+n;return e}function pr(e){var t="";for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){oe(n,function(e){t=gr(t,r,e)})}else{t=gr(t,r,n)}}}return t}function mr(e){var t=new FormData;for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){oe(n,function(e){t.append(r,e)})}else{t.append(r,n)}}}return t}function xr(e,t,r){var n={"HX-Request":"true","HX-Trigger":ee(e,"id"),"HX-Trigger-Name":ee(e,"name"),"HX-Target":te(t,"id"),"HX-Current-URL":re().location.href};Rr(e,"hx-headers",false,n);if(r!==undefined){n["HX-Prompt"]=r}if(ae(e).boosted){n["HX-Boosted"]="true"}return n}function yr(t,e){var r=ne(e,"hx-params");if(r){if(r==="none"){return{}}else if(r==="*"){return t}else if(r.indexOf("not ")===0){oe(r.substr(4).split(","),function(e){e=e.trim();delete t[e]});return t}else{var n={};oe(r.split(","),function(e){e=e.trim();n[e]=t[e]});return n}}else{return t}}function br(e){return ee(e,"href")&&ee(e,"href").indexOf("#")>=0}function wr(e,t){var r=t?t:ne(e,"hx-swap");var n={swapStyle:ae(e).boosted?"innerHTML":Q.config.defaultSwapStyle,swapDelay:Q.config.defaultSwapDelay,settleDelay:Q.config.defaultSettleDelay};if(Q.config.scrollIntoViewOnBoost&&ae(e).boosted&&!br(e)){n["show"]="top"}if(r){var i=D(r);if(i.length>0){for(var a=0;a<i.length;a++){var o=i[a];if(o.indexOf("swap:")===0){n["swapDelay"]=d(o.substr(5))}else if(o.indexOf("settle:")===0){n["settleDelay"]=d(o.substr(7))}else if(o.indexOf("transition:")===0){n["transition"]=o.substr(11)==="true"}else if(o.indexOf("ignoreTitle:")===0){n["ignoreTitle"]=o.substr(12)==="true"}else if(o.indexOf("scroll:")===0){var s=o.substr(7);var l=s.split(":");var u=l.pop();var f=l.length>0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}else if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}else if(o.indexOf("focus-scroll:")===0){var v=o.substr("focus-scroll:".length);n["focusScroll"]=v=="true"}else if(a==0){n["swapStyle"]=o}else{b("Unknown modifier in hx-swap: "+o)}}}}return n}function Sr(e){return ne(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&ee(e,"enctype")==="multipart/form-data"}function Er(t,r,n){var i=null;R(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(Sr(r)){return mr(n)}else{return pr(n)}}}function T(e){return{tasks:[],elts:[e]}}function Cr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ue(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ue(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:Q.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:Q.config.scrollBehavior})}}}function Rr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=te(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=Tr(e,function(){return Function("return ("+a+")")()},{})}else{s=E(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return Rr(u(e),t,r,n)}function Tr(e,t,r){if(Q.config.allowEval){return t()}else{fe(e,"htmx:evalDisallowedError");return r}}function Or(e,t){return Rr(e,"hx-vars",true,t)}function qr(e,t){return Rr(e,"hx-vals",false,t)}function Hr(e){return le(Or(e),qr(e))}function Lr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function Ar(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){fe(re().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function O(e,t){return t.test(e.getAllResponseHeaders())}function Nr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||I(r,"String")){return he(e,t,null,null,{targetOverride:p(r),returnPromise:true})}else{return he(e,t,p(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:p(r.target),swapOverride:r.swap,select:r.select,returnPromise:true})}}else{return he(e,t,null,null,{returnPromise:true})}}function Ir(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function kr(e,t,r){var n;var i;if(typeof URL==="function"){i=new URL(t,document.location.href);var a=document.location.origin;n=a===i.origin}else{i=t;n=g(t,document.location.origin)}if(Q.config.selfRequestsOnly){if(!n){return false}}return ce(e,"htmx:validateUrl",le({url:i,sameHost:n},r))}function he(t,r,n,i,a,e){var o=null;var s=null;a=a!=null?a:{};if(a.returnPromise&&typeof Promise!=="undefined"){var l=new Promise(function(e,t){o=e;s=t})}if(n==null){n=re().body}var M=a.handler||Mr;var X=a.select||null;if(!se(n)){ie(o);return l}var u=a.targetOverride||ye(n);if(u==null||u==pe){fe(n,"htmx:targetError",{target:te(n,"hx-target")});ie(s);return l}var f=ae(n);var c=f.lastButtonClicked;if(c){var h=ee(c,"formaction");if(h!=null){r=h}var v=ee(c,"formmethod");if(v!=null){if(v.toLowerCase()!=="dialog"){t=v}}}var d=ne(n,"hx-confirm");if(e===undefined){var D=function(e){return he(t,r,n,i,a,!!e)};var U={target:u,elt:n,path:r,verb:t,triggeringEvent:i,etc:a,issueRequest:D,question:d};if(ce(n,"htmx:confirm",U)===false){ie(o);return l}}var g=n;var p=ne(n,"hx-sync");var m=null;var x=false;if(p){var F=p.split(":");var B=F[0].trim();if(B==="this"){g=xe(n,"hx-sync")}else{g=ue(n,B)}p=(F[1]||"drop").trim();f=ae(g);if(p==="drop"&&f.xhr&&f.abortable!==true){ie(o);return l}else if(p==="abort"){if(f.xhr){ie(o);return l}else{x=true}}else if(p==="replace"){ce(g,"htmx:abort")}else if(p.indexOf("queue")===0){var V=p.split(" ");m=(V[1]||"last").trim()}}if(f.xhr){if(f.abortable){ce(g,"htmx:abort")}else{if(m==null){if(i){var y=ae(i);if(y&&y.triggerSpec&&y.triggerSpec.queue){m=y.triggerSpec.queue}}if(m==null){m="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(m==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="all"){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){he(t,r,n,i,a)})}ie(o);return l}}var b=new XMLHttpRequest;f.xhr=b;f.abortable=x;var w=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var j=ne(n,"hx-prompt");if(j){var S=prompt(j);if(S===null||!ce(n,"htmx:prompt",{prompt:S,target:u})){ie(o);w();return l}}if(d&&!e){if(!confirm(d)){ie(o);w();return l}}var E=xr(n,u,S);if(t!=="get"&&!Sr(n)){E["Content-Type"]="application/x-www-form-urlencoded"}if(a.headers){E=le(E,a.headers)}var _=dr(n,t);var C=_.errors;var R=_.values;if(a.values){R=le(R,a.values)}var z=Hr(n);var $=le(R,z);var T=yr($,n);if(Q.config.getCacheBusterParam&&t==="get"){T["org.htmx.cache-buster"]=ee(u,"id")||"true"}if(r==null||r===""){r=re().location.href}var O=Rr(n,"hx-request");var W=ae(n).boosted;var q=Q.config.methodsThatUseUrlParams.indexOf(t)>=0;var H={boosted:W,useUrlParams:q,parameters:T,unfilteredParameters:$,headers:E,target:u,verb:t,errors:C,withCredentials:a.credentials||O.credentials||Q.config.withCredentials,timeout:a.timeout||O.timeout||Q.config.timeout,path:r,triggeringEvent:i};if(!ce(n,"htmx:configRequest",H)){ie(o);w();return l}r=H.path;t=H.verb;E=H.headers;T=H.parameters;C=H.errors;q=H.useUrlParams;if(C&&C.length>0){ce(n,"htmx:validation:halted",H);ie(o);w();return l}var G=r.split("#");var J=G[0];var L=G[1];var A=r;if(q){A=J;var Z=Object.keys(T).length!==0;if(Z){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=pr(T);if(L){A+="#"+L}}}if(!kr(n,A,H)){fe(n,"htmx:invalidPath",H);ie(s);return l}b.open(t.toUpperCase(),A,true);b.overrideMimeType("text/html");b.withCredentials=H.withCredentials;b.timeout=H.timeout;if(O.noHeaders){}else{for(var N in E){if(E.hasOwnProperty(N)){var K=E[N];Lr(b,N,K)}}}var I={xhr:b,target:u,requestConfig:H,etc:a,boosted:W,select:X,pathInfo:{requestPath:r,finalRequestPath:A,anchor:L}};b.onload=function(){try{var e=Ir(n);I.pathInfo.responsePath=Ar(b);M(n,I);lr(k,P);ce(n,"htmx:afterRequest",I);ce(n,"htmx:afterOnLoad",I);if(!se(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(se(r)){t=r}}if(t){ce(t,"htmx:afterRequest",I);ce(t,"htmx:afterOnLoad",I)}}ie(o);w()}catch(e){fe(n,"htmx:onLoadError",le({error:e},I));throw e}};b.onerror=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendError",I);ie(s);w()};b.onabort=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendAbort",I);ie(s);w()};b.ontimeout=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:timeout",I);ie(s);w()};if(!ce(n,"htmx:beforeRequest",I)){ie(o);w();return l}var k=or(n);var P=sr(n);oe(["loadstart","loadend","progress","abort"],function(t){oe([b,b.upload],function(e){e.addEventListener(t,function(e){ce(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});ce(n,"htmx:beforeSend",I);var Y=q?null:Er(b,n,T);b.send(Y);return l}function Pr(e,t){var r=t.xhr;var n=null;var i=null;if(O(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(O(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(O(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=ne(e,"hx-push-url");var l=ne(e,"hx-replace-url");var u=ae(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function Mr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;var t=u.requestConfig;var h=u.select;if(!ce(l,"htmx:beforeOnLoad",u))return;if(O(f,/HX-Trigger:/i)){_e(f,"HX-Trigger",l)}if(O(f,/HX-Location:/i)){er();var r=f.getResponseHeader("HX-Location");var v;if(r.indexOf("{")===0){v=E(r);r=v["path"];delete v["path"]}Nr("GET",r,v).then(function(){tr(r)});return}var n=O(f,/HX-Refresh:/i)&&"true"===f.getResponseHeader("HX-Refresh");if(O(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");n&&location.reload();return}if(n){location.reload();return}if(O(f,/HX-Retarget:/i)){if(f.getResponseHeader("HX-Retarget")==="this"){u.target=l}else{u.target=ue(l,f.getResponseHeader("HX-Retarget"))}}var d=Pr(l,u);var i=f.status>=200&&f.status<400&&f.status!==204;var g=f.response;var a=f.status>=400;var p=Q.config.ignoreTitle;var o=le({shouldSwap:i,serverResponse:g,isError:a,ignoreTitle:p},u);if(!ce(c,"htmx:beforeSwap",o))return;c=o.target;g=o.serverResponse;a=o.isError;p=o.ignoreTitle;u.target=c;u.failed=a;u.successful=!a;if(o.shouldSwap){if(f.status===286){at(l)}R(l,function(e){g=e.transformResponse(g,f,l)});if(d.type){er()}var s=e.swapOverride;if(O(f,/HX-Reswap:/i)){s=f.getResponseHeader("HX-Reswap")}var v=wr(l,s);if(v.hasOwnProperty("ignoreTitle")){p=v.ignoreTitle}c.classList.add(Q.config.swappingClass);var m=null;var x=null;var y=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(h){r=h}if(O(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}if(d.type){ce(re().body,"htmx:beforeHistoryUpdate",le({history:d},u));if(d.type==="push"){tr(d.path);ce(re().body,"htmx:pushedIntoHistory",{path:d.path})}else{rr(d.path);ce(re().body,"htmx:replacedInHistory",{path:d.path})}}var n=T(c);je(v.swapStyle,c,l,g,n,r);if(t.elt&&!se(t.elt)&&ee(t.elt,"id")){var i=document.getElementById(ee(t.elt,"id"));var a={preventScroll:v.focusScroll!==undefined?!v.focusScroll:!Q.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(Q.config.swappingClass);oe(n.elts,function(e){if(e.classList){e.classList.add(Q.config.settlingClass)}ce(e,"htmx:afterSwap",u)});if(O(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!se(l)){o=re().body}_e(f,"HX-Trigger-After-Swap",o)}var s=function(){oe(n.tasks,function(e){e.call()});oe(n.elts,function(e){if(e.classList){e.classList.remove(Q.config.settlingClass)}ce(e,"htmx:afterSettle",u)});if(u.pathInfo.anchor){var e=re().getElementById(u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title&&!p){var t=C("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}Cr(n.elts,v);if(O(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!se(l)){r=re().body}_e(f,"HX-Trigger-After-Settle",r)}ie(m)};if(v.settleDelay>0){setTimeout(s,v.settleDelay)}else{s()}}catch(e){fe(l,"htmx:swapError",u);ie(x);throw e}};var b=Q.config.globalViewTransitions;if(v.hasOwnProperty("transition")){b=v.transition}if(b&&ce(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var w=new Promise(function(e,t){m=e;x=t});var S=y;y=function(){document.startViewTransition(function(){S();return w})}}if(v.swapDelay>0){setTimeout(y,v.swapDelay)}else{y()}}if(a){fe(l,"htmx:responseError",le({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Xr={};function Dr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Ur(e,t){if(t.init){t.init(r)}Xr[e]=le(Dr(),t)}function Fr(e){delete Xr[e]}function Br(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=te(e,"hx-ext");if(t){oe(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Xr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Br(u(e),r,n)}var Vr=false;re().addEventListener("DOMContentLoaded",function(){Vr=true});function jr(e){if(Vr||re().readyState==="complete"){e()}else{re().addEventListener("DOMContentLoaded",e)}}function _r(){if(Q.config.includeIndicatorStyles!==false){re().head.insertAdjacentHTML("beforeend","<style> ."+Q.config.indicatorClass+"{opacity:0} ."+Q.config.requestClass+" ."+Q.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} ."+Q.config.requestClass+"."+Q.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} </style>")}}function zr(){var e=re().querySelector('meta[name="htmx-config"]');if(e){return E(e.content)}else{return null}}function $r(){var e=zr();if(e){Q.config=le(Q.config,e)}}jr(function(){$r();_r();var e=re().body;zt(e);var t=re().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ae(t);if(r&&r.xhr){r.xhr.abort()}});const r=window.onpopstate?window.onpopstate.bind(window):null;window.onpopstate=function(e){if(e.state&&e.state.htmx){ar();oe(t,function(e){ce(e,"htmx:restored",{document:re(),triggerEvent:ce})})}else{if(r){r(e)}}};setTimeout(function(){ce(e,"htmx:load",{});e=null},0)});return Q}()}); 1 + (function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var Q={onLoad:B,process:zt,on:de,off:ge,trigger:ce,ajax:Nr,find:C,findAll:f,closest:v,values:function(e,t){var r=dr(e,t||"post");return r.values},remove:_,addClass:z,removeClass:n,toggleClass:$,takeClass:W,defineExtension:Ur,removeExtension:Fr,logAll:V,logNone:j,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false,ignoreTitle:false,scrollIntoViewOnBoost:true,triggerSpecsCache:null},parseInterval:d,_:t,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=Q.config.wsBinaryType;return t},version:"1.9.11"};var r={addTriggerHandler:Lt,bodyContains:se,canAccessLocalStorage:U,findThisElement:xe,filterValues:yr,hasAttribute:o,getAttributeValue:te,getClosestAttributeValue:ne,getClosestMatch:c,getExpressionVars:Hr,getHeaders:xr,getInputValues:dr,getInternalData:ae,getSwapSpecification:wr,getTriggerSpecs:it,getTarget:ye,makeFragment:l,mergeObjects:le,makeSettleInfo:T,oobSwap:Ee,querySelectorExt:ue,selectAndSwap:je,settleImmediately:nr,shouldCancel:ut,triggerEvent:ce,triggerErrorEvent:fe,withExtensions:R};var w=["get","post","put","delete","patch"];var i=w.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");var S=e("head"),q=e("title"),H=e("svg",true);function e(e,t=false){return new RegExp(`<${e}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${e}>`,t?"gim":"im")}function d(e){if(e==undefined){return undefined}let t=NaN;if(e.slice(-2)=="ms"){t=parseFloat(e.slice(0,-2))}else if(e.slice(-1)=="s"){t=parseFloat(e.slice(0,-1))*1e3}else if(e.slice(-1)=="m"){t=parseFloat(e.slice(0,-1))*1e3*60}else{t=parseFloat(e)}return isNaN(t)?undefined:t}function ee(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function te(e,t){return ee(e,t)||ee(e,"data-"+t)}function u(e){return e.parentElement}function re(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function L(e,t,r){var n=te(t,r);var i=te(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function ne(t,r){var n=null;c(t,function(e){return n=L(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function A(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function s(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=re().createDocumentFragment()}return i}function N(e){return/<body/.test(e)}function l(e){var t=!N(e);var r=A(e);var n=e;if(r==="head"){n=n.replace(S,"")}if(Q.config.useTemplateFragments&&t){var i=s("<body><template>"+n+"</template></body>",0);var a=i.querySelector("template").content;if(Q.config.allowScriptTags){oe(a.querySelectorAll("script"),function(e){if(Q.config.inlineScriptNonce){e.nonce=Q.config.inlineScriptNonce}e.htmxExecuted=navigator.userAgent.indexOf("Firefox")===-1})}else{oe(a.querySelectorAll("script"),function(e){_(e)})}return a}switch(r){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return s("<table>"+n+"</table>",1);case"col":return s("<table><colgroup>"+n+"</colgroup></table>",2);case"tr":return s("<table><tbody>"+n+"</tbody></table>",2);case"td":case"th":return s("<table><tbody><tr>"+n+"</tr></tbody></table>",3);case"script":case"style":return s("<div>"+n+"</div>",1);default:return s(n,0)}}function ie(e){if(e){e()}}function I(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function k(e){return I(e,"Function")}function P(e){return I(e,"Object")}function ae(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function M(e){var t=[];if(e){for(var r=0;r<e.length;r++){t.push(e[r])}}return t}function oe(e,t){if(e){for(var r=0;r<e.length;r++){t(e[r])}}}function X(e){var t=e.getBoundingClientRect();var r=t.top;var n=t.bottom;return r<window.innerHeight&&n>=0}function se(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return re().body.contains(e.getRootNode().host)}else{return re().body.contains(e)}}function D(e){return e.trim().split(/\s+/)}function le(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function E(e){try{return JSON.parse(e)}catch(e){b(e);return null}}function U(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function F(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!/^\/$/.test(t)){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function t(e){return Tr(re().body,function(){return eval(e)})}function B(t){var e=Q.on("htmx:load",function(e){t(e.detail.elt)});return e}function V(){Q.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function j(){Q.logger=null}function C(e,t){if(t){return e.querySelector(t)}else{return C(re(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(re(),e)}}function _(e,t){e=p(e);if(t){setTimeout(function(){_(e);e=null},t)}else{e.parentElement.removeChild(e)}}function z(e,t,r){e=p(e);if(r){setTimeout(function(){z(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=p(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function $(e,t){e=p(e);e.classList.toggle(t)}function W(e,t){e=p(e);oe(e.parentElement.children,function(e){n(e,t)});z(e,t)}function v(e,t){e=p(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function g(e,t){return e.substring(0,t.length)===t}function G(e,t){return e.substring(e.length-t.length)===t}function J(e){var t=e.trim();if(g(t,"<")&&G(t,"/>")){return t.substring(1,t.length-2)}else{return t}}function Z(e,t){if(t.indexOf("closest ")===0){return[v(e,J(t.substr(8)))]}else if(t.indexOf("find ")===0){return[C(e,J(t.substr(5)))]}else if(t==="next"){return[e.nextElementSibling]}else if(t.indexOf("next ")===0){return[K(e,J(t.substr(5)))]}else if(t==="previous"){return[e.previousElementSibling]}else if(t.indexOf("previous ")===0){return[Y(e,J(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return re().querySelectorAll(J(t))}}var K=function(e,t){var r=re().querySelectorAll(t);for(var n=0;n<r.length;n++){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_PRECEDING){return i}}};var Y=function(e,t){var r=re().querySelectorAll(t);for(var n=r.length-1;n>=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ue(e,t){if(t){return Z(e,t)[0]}else{return Z(re().body,e)[0]}}function p(e){if(I(e,"String")){return C(e)}else{return e}}function ve(e,t,r){if(k(t)){return{target:re().body,event:e,listener:t}}else{return{target:p(e),event:t,listener:r}}}function de(t,r,n){jr(function(){var e=ve(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=k(r);return e?r:n}function ge(t,r,n){jr(function(){var e=ve(t,r,n);e.target.removeEventListener(e.event,e.listener)});return k(r)?r:n}var pe=re().createElement("output");function me(e,t){var r=ne(e,t);if(r){if(r==="this"){return[xe(e,t)]}else{var n=Z(e,r);if(n.length===0){b('The selector "'+r+'" on '+t+" returned no matches!");return[pe]}else{return n}}}}function xe(e,t){return c(e,function(e){return te(e,t)!=null})}function ye(e){var t=ne(e,"hx-target");if(t){if(t==="this"){return xe(e,"hx-target")}else{return ue(e,t)}}else{var r=ae(e);if(r.boosted){return re().body}else{return e}}}function be(e){var t=Q.config.attributesToSettle;for(var r=0;r<t.length;r++){if(e===t[r]){return true}}return false}function we(t,r){oe(t.attributes,function(e){if(!r.hasAttribute(e.name)&&be(e.name)){t.removeAttribute(e.name)}});oe(r.attributes,function(e){if(be(e.name)){t.setAttribute(e.name,e.value)}})}function Se(e,t){var r=Br(t);for(var n=0;n<r.length;n++){var i=r[n];try{if(i.isInlineSwap(e)){return true}}catch(e){b(e)}}return e==="outerHTML"}function Ee(e,i,a){var t="#"+ee(i,"id");var o="outerHTML";if(e==="true"){}else if(e.indexOf(":")>0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=re().querySelectorAll(t);if(r){oe(r,function(e){var t;var r=i.cloneNode(true);t=re().createDocumentFragment();t.appendChild(r);if(!Se(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!ce(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){Be(o,e,e,t,a)}oe(a.elts,function(e){ce(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);fe(re().body,"htmx:oobErrorNoTarget",{content:i})}return e}function Ce(e,t,r){var n=ne(e,"hx-select-oob");if(n){var i=n.split(",");for(var a=0;a<i.length;a++){var o=i[a].split(":",2);var s=o[0].trim();if(s.indexOf("#")===0){s=s.substring(1)}var l=o[1]||"true";var u=t.querySelector("#"+s);if(u){Ee(l,u,r)}}}oe(f(t,"[hx-swap-oob], [data-hx-swap-oob]"),function(e){var t=te(e,"hx-swap-oob");if(t!=null){Ee(t,e,r)}})}function Re(e){oe(f(e,"[hx-preserve], [data-hx-preserve]"),function(e){var t=te(e,"id");var r=re().getElementById(t);if(r!=null){e.parentNode.replaceChild(r,e)}})}function Te(o,e,s){oe(e.querySelectorAll("[id]"),function(e){var t=ee(e,"id");if(t&&t.length>0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();we(e,i);s.tasks.push(function(){we(e,a)})}}})}function Oe(e){return function(){n(e,Q.config.addedClass);zt(e);Nt(e);qe(e);ce(e,"htmx:load")}}function qe(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){Te(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;z(i,Q.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(Oe(i))}}}function He(e,t){var r=0;while(r<e.length){t=(t<<5)-t+e.charCodeAt(r++)|0}return t}function Le(e){var t=0;if(e.attributes){for(var r=0;r<e.attributes.length;r++){var n=e.attributes[r];if(n.value){t=He(n.name,t);t=He(n.value,t)}}}return t}function Ae(e){var t=ae(e);if(t.onHandlers){for(var r=0;r<t.onHandlers.length;r++){const n=t.onHandlers[r];e.removeEventListener(n.event,n.listener)}delete t.onHandlers}}function Ne(e){var t=ae(e);if(t.timeout){clearTimeout(t.timeout)}if(t.webSocket){t.webSocket.close()}if(t.sseEventSource){t.sseEventSource.close()}if(t.listenerInfos){oe(t.listenerInfos,function(e){if(e.on){e.on.removeEventListener(e.trigger,e.listener)}})}Ae(e);oe(Object.keys(t),function(e){delete t[e]})}function m(e){ce(e,"htmx:beforeCleanupElement");Ne(e);if(e.children){oe(e.children,function(e){m(e)})}}function Ie(t,e,r){if(t.tagName==="BODY"){return Ue(t,e,r)}else{var n;var i=t.previousSibling;a(u(t),t,e,r);if(i==null){n=u(t).firstChild}else{n=i.nextSibling}r.elts=r.elts.filter(function(e){return e!=t});while(n&&n!==t){if(n.nodeType===Node.ELEMENT_NODE){r.elts.push(n)}n=n.nextElementSibling}m(t);u(t).removeChild(t)}}function ke(e,t,r){return a(e,e.firstChild,t,r)}function Pe(e,t,r){return a(u(e),e,t,r)}function Me(e,t,r){return a(e,null,t,r)}function Xe(e,t,r){return a(u(e),e.nextSibling,t,r)}function De(e,t,r){m(e);return u(e).removeChild(e)}function Ue(e,t,r){var n=e.firstChild;a(e,n,t,r);if(n){while(n.nextSibling){m(n.nextSibling);e.removeChild(n.nextSibling)}m(n);e.removeChild(n)}}function Fe(e,t,r){var n=r||ne(e,"hx-select");if(n){var i=re().createDocumentFragment();oe(t.querySelectorAll(n),function(e){i.appendChild(e)});t=i}return t}function Be(e,t,r,n,i){switch(e){case"none":return;case"outerHTML":Ie(r,n,i);return;case"afterbegin":ke(r,n,i);return;case"beforebegin":Pe(r,n,i);return;case"beforeend":Me(r,n,i);return;case"afterend":Xe(r,n,i);return;case"delete":De(r,n,i);return;default:var a=Br(t);for(var o=0;o<a.length;o++){var s=a[o];try{var l=s.handleSwap(e,r,n,i);if(l){if(typeof l.length!=="undefined"){for(var u=0;u<l.length;u++){var f=l[u];if(f.nodeType!==Node.TEXT_NODE&&f.nodeType!==Node.COMMENT_NODE){i.tasks.push(Oe(f))}}}return}}catch(e){b(e)}}if(e==="innerHTML"){Ue(r,n,i)}else{Be(Q.config.defaultSwapStyle,t,r,n,i)}}}function Ve(e){if(e.indexOf("<title")>-1){var t=e.replace(H,"");var r=t.match(q);if(r){return r[2]}}}function je(e,t,r,n,i,a){i.title=Ve(n);var o=l(n);if(o){Ce(r,o,i);o=Fe(r,o,a);Re(o);return Be(e,r,t,o,i)}}function _e(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=E(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!P(o)){o={value:o}}ce(r,a,o)}}}else{var s=n.split(",");for(var l=0;l<s.length;l++){ce(r,s[l].trim(),[])}}}var ze=/\s/;var x=/[\s,]/;var $e=/[_$a-zA-Z]/;var We=/[_$a-zA-Z0-9]/;var Ge=['"',"'","/"];var Je=/[^\s]/;var Ze=/[{(]/;var Ke=/[})]/;function Ye(e){var t=[];var r=0;while(r<e.length){if($e.exec(e.charAt(r))){var n=r;while(We.exec(e.charAt(r+1))){r++}t.push(e.substr(n,r-n+1))}else if(Ge.indexOf(e.charAt(r))!==-1){var i=e.charAt(r);var n=r;r++;while(r<e.length&&e.charAt(r)!==i){if(e.charAt(r)==="\\"){r++}r++}t.push(e.substr(n,r-n+1))}else{var a=e.charAt(r);t.push(a)}r++}return t}function Qe(e,t,r){return $e.exec(e.charAt(0))&&e!=="true"&&e!=="false"&&e!=="this"&&e!==r&&t!=="."}function et(e,t,r){if(t[0]==="["){t.shift();var n=1;var i=" return (function("+r+"){ return (";var a=null;while(t.length>0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=Tr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){fe(re().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(Qe(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function y(e,t){var r="";while(e.length>0&&!t.test(e[0])){r+=e.shift()}return r}function tt(e){var t;if(e.length>0&&Ze.test(e[0])){e.shift();t=y(e,Ke).trim();e.shift()}else{t=y(e,x)}return t}var rt="input, textarea, select";function nt(e,t,r){var n=[];var i=Ye(t);do{y(i,Je);var a=i.length;var o=y(i,/[,\[\s]/);if(o!==""){if(o==="every"){var s={trigger:"every"};y(i,Je);s.pollInterval=d(y(i,/[,\[\s]/));y(i,Je);var l=et(e,i,"event");if(l){s.eventFilter=l}n.push(s)}else if(o.indexOf("sse:")===0){n.push({trigger:"sse",sseEvent:o.substr(4)})}else{var u={trigger:o};var l=et(e,i,"event");if(l){u.eventFilter=l}while(i.length>0&&i[0]!==","){y(i,Je);var f=i.shift();if(f==="changed"){u.changed=true}else if(f==="once"){u.once=true}else if(f==="consume"){u.consume=true}else if(f==="delay"&&i[0]===":"){i.shift();u.delay=d(y(i,x))}else if(f==="from"&&i[0]===":"){i.shift();if(Ze.test(i[0])){var c=tt(i)}else{var c=y(i,x);if(c==="closest"||c==="find"||c==="next"||c==="previous"){i.shift();var h=tt(i);if(h.length>0){c+=" "+h}}}u.from=c}else if(f==="target"&&i[0]===":"){i.shift();u.target=tt(i)}else if(f==="throttle"&&i[0]===":"){i.shift();u.throttle=d(y(i,x))}else if(f==="queue"&&i[0]===":"){i.shift();u.queue=y(i,x)}else if(f==="root"&&i[0]===":"){i.shift();u[f]=tt(i)}else if(f==="threshold"&&i[0]===":"){i.shift();u[f]=y(i,x)}else{fe(e,"htmx:syntax:error",{token:i.shift()})}}n.push(u)}}if(i.length===a){fe(e,"htmx:syntax:error",{token:i.shift()})}y(i,Je)}while(i[0]===","&&i.shift());if(r){r[t]=n}return n}function it(e){var t=te(e,"hx-trigger");var r=[];if(t){var n=Q.config.triggerSpecsCache;r=n&&n[t]||nt(e,t,n)}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,rt)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function at(e){ae(e).cancelled=true}function ot(e,t,r){var n=ae(e);n.timeout=setTimeout(function(){if(se(e)&&n.cancelled!==true){if(!ct(r,e,Wt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}ot(e,t,r)}},r.pollInterval)}function st(e){return location.hostname===e.hostname&&ee(e,"href")&&ee(e,"href").indexOf("#")!==0}function lt(t,r,e){if(t.tagName==="A"&&st(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=ee(t,"href")}else{var a=ee(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=ee(t,"action")}e.forEach(function(e){ht(t,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(n,i,e,t)},r,e,true)})}}function ut(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&v(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function ft(e,t){return ae(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function ct(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){fe(re().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function ht(a,o,e,s,l){var u=ae(a);var t;if(s.from){t=Z(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ae(e);t.lastValue=e.value})}oe(t,function(n){var i=function(e){if(!se(a)){n.removeEventListener(s.trigger,i);return}if(ft(a,e)){return}if(l||ut(e,a)){e.preventDefault()}if(ct(s,a,e)){return}var t=ae(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ae(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle>0){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay>0){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{ce(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var vt=false;var dt=null;function gt(){if(!dt){dt=function(){vt=true};window.addEventListener("scroll",dt);setInterval(function(){if(vt){vt=false;oe(re().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){pt(e)})}},200)}}function pt(t){if(!o(t,"data-hx-revealed")&&X(t)){t.setAttribute("data-hx-revealed","true");var e=ae(t);if(e.initHash){ce(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){ce(t,"revealed")},{once:true})}}}function mt(e,t,r){var n=D(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){xt(e,a[1],0)}if(a[0]==="send"){bt(e)}}}function xt(s,r,n){if(!se(s)){return}if(r.indexOf("/")==0){var e=location.hostname+(location.port?":"+location.port:"");if(location.protocol=="https:"){r="wss://"+e+r}else if(location.protocol=="http:"){r="ws://"+e+r}}var t=Q.createWebSocket(r);t.onerror=function(e){fe(s,"htmx:wsError",{error:e,socket:t});yt(s)};t.onclose=function(e){if([1006,1012,1013].indexOf(e.code)>=0){var t=wt(n);setTimeout(function(){xt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ae(s).webSocket=t;t.addEventListener("message",function(e){if(yt(s)){return}var t=e.data;R(s,function(e){t=e.transformResponse(t,null,s)});var r=T(s);var n=l(t);var i=M(n.children);for(var a=0;a<i.length;a++){var o=i[a];Ee(te(o,"hx-swap-oob")||"true",o,r)}nr(r.tasks)})}function yt(e){if(!se(e)){ae(e).webSocket.close();return true}}function bt(u){var f=c(u,function(e){return ae(e).webSocket!=null});if(f){u.addEventListener(it(u)[0].trigger,function(e){var t=ae(f).webSocket;var r=xr(u,f);var n=dr(u,"post");var i=n.errors;var a=n.values;var o=Hr(u);var s=le(a,o);var l=yr(s,u);l["HEADERS"]=r;if(i&&i.length>0){ce(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(ut(e,u)){e.preventDefault()}})}else{fe(u,"htmx:noWebSocketSourceError")}}function wt(e){var t=Q.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}b('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function St(e,t,r){var n=D(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){Et(e,a[1])}if(a[0]==="swap"){Ct(e,a[1])}}}function Et(t,e){var r=Q.createEventSource(e);r.onerror=function(e){fe(t,"htmx:sseError",{error:e,source:r});Tt(t)};ae(t).sseEventSource=r}function Ct(a,o){var s=c(a,Ot);if(s){var l=ae(s).sseEventSource;var u=function(e){if(Tt(s)){return}if(!se(a)){l.removeEventListener(o,u);return}var t=e.data;R(a,function(e){t=e.transformResponse(t,null,a)});var r=wr(a);var n=ye(a);var i=T(a);je(r.swapStyle,n,a,t,i);nr(i.tasks);ce(a,"htmx:sseMessage",e)};ae(a).sseListener=u;l.addEventListener(o,u)}else{fe(a,"htmx:noSSESourceError")}}function Rt(e,t,r){var n=c(e,Ot);if(n){var i=ae(n).sseEventSource;var a=function(){if(!Tt(n)){if(se(e)){t(e)}else{i.removeEventListener(r,a)}}};ae(e).sseListener=a;i.addEventListener(r,a)}else{fe(e,"htmx:noSSESourceError")}}function Tt(e){if(!se(e)){ae(e).sseEventSource.close();return true}}function Ot(e){return ae(e).sseEventSource!=null}function qt(e,t,r,n){var i=function(){if(!r.loaded){r.loaded=true;t(e)}};if(n>0){setTimeout(i,n)}else{i()}}function Ht(t,i,e){var a=false;oe(w,function(r){if(o(t,"hx-"+r)){var n=te(t,"hx-"+r);a=true;i.path=n;i.verb=r;e.forEach(function(e){Lt(t,e,i,function(e,t){if(v(e,Q.config.disableSelector)){m(e);return}he(r,n,e,t)})})}});return a}function Lt(n,e,t,r){if(e.sseEvent){Rt(n,r,e.sseEvent)}else if(e.trigger==="revealed"){gt();ht(n,r,t,e);pt(n)}else if(e.trigger==="intersect"){var i={};if(e.root){i.root=ue(n,e.root)}if(e.threshold){i.threshold=parseFloat(e.threshold)}var a=new IntersectionObserver(function(e){for(var t=0;t<e.length;t++){var r=e[t];if(r.isIntersecting){ce(n,"intersect");break}}},i);a.observe(n);ht(n,r,t,e)}else if(e.trigger==="load"){if(!ct(e,n,Wt("load",{elt:n}))){qt(n,r,t,e.delay)}}else if(e.pollInterval>0){t.polling=true;ot(n,r,e)}else{ht(n,r,t,e)}}function At(e){if(!e.htmxExecuted&&Q.config.allowScriptTags&&(e.type==="text/javascript"||e.type==="module"||e.type==="")){var t=re().createElement("script");oe(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(Q.config.inlineScriptNonce){t.nonce=Q.config.inlineScriptNonce}var r=e.parentElement;try{r.insertBefore(t,e)}catch(e){b(e)}finally{if(e.parentElement){e.parentElement.removeChild(e)}}}}function Nt(e){if(h(e,"script")){At(e)}oe(f(e,"script"),function(e){At(e)})}function It(e){var t=e.attributes;for(var r=0;r<t.length;r++){var n=t[r].name;if(g(n,"hx-on:")||g(n,"data-hx-on:")||g(n,"hx-on-")||g(n,"data-hx-on-")){return true}}return false}function kt(e){var t=null;var r=[];if(It(e)){r.push(e)}if(document.evaluate){var n=document.evaluate('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or'+' starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]',e);while(t=n.iterateNext())r.push(t)}else{var i=e.getElementsByTagName("*");for(var a=0;a<i.length;a++){if(It(i[a])){r.push(i[a])}}}return r}function Pt(e){if(e.querySelectorAll){var t=", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]";var r=e.querySelectorAll(i+t+", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws],"+" [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]");return r}else{return[]}}function Mt(e){var t=v(e.target,"button, input[type='submit']");var r=Dt(e);if(r){r.lastButtonClicked=t}}function Xt(e){var t=Dt(e);if(t){t.lastButtonClicked=null}}function Dt(e){var t=v(e.target,"button, input[type='submit']");if(!t){return}var r=p("#"+ee(t,"form"))||v(t,"form");if(!r){return}return ae(r)}function Ut(e){e.addEventListener("click",Mt);e.addEventListener("focusin",Mt);e.addEventListener("focusout",Xt)}function Ft(e){var t=Ye(e);var r=0;for(var n=0;n<t.length;n++){const i=t[n];if(i==="{"){r++}else if(i==="}"){r--}}return r}function Bt(t,e,r){var n=ae(t);if(!Array.isArray(n.onHandlers)){n.onHandlers=[]}var i;var a=function(e){return Tr(t,function(){if(!i){i=new Function("event",r)}i.call(t,e)})};t.addEventListener(e,a);n.onHandlers.push({event:e,listener:a})}function Vt(e){var t=te(e,"hx-on");if(t){var r={};var n=t.split("\n");var i=null;var a=0;while(n.length>0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-\.]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Ft(o)}for(var l in r){Bt(e,l,r[l])}}}function jt(e){Ae(e);for(var t=0;t<e.attributes.length;t++){var r=e.attributes[t].name;var n=e.attributes[t].value;if(g(r,"hx-on")||g(r,"data-hx-on")){var i=r.indexOf("-on")+3;var a=r.slice(i,i+1);if(a==="-"||a===":"){var o=r.slice(i+1);if(g(o,":")){o="htmx"+o}else if(g(o,"-")){o="htmx:"+o.slice(1)}else if(g(o,"htmx-")){o="htmx:"+o.slice(5)}Bt(e,o,n)}}}}function _t(t){if(v(t,Q.config.disableSelector)){m(t);return}var r=ae(t);if(r.initHash!==Le(t)){Ne(t);r.initHash=Le(t);Vt(t);ce(t,"htmx:beforeProcessNode");if(t.value){r.lastValue=t.value}var e=it(t);var n=Ht(t,r,e);if(!n){if(ne(t,"hx-boost")==="true"){lt(t,r,e)}else if(o(t,"hx-trigger")){e.forEach(function(e){Lt(t,e,r,function(){})})}}if(t.tagName==="FORM"||ee(t,"type")==="submit"&&o(t,"form")){Ut(t)}var i=te(t,"hx-sse");if(i){St(t,r,i)}var a=te(t,"hx-ws");if(a){mt(t,r,a)}ce(t,"htmx:afterProcessNode")}}function zt(e){e=p(e);if(v(e,Q.config.disableSelector)){m(e);return}_t(e);oe(Pt(e),function(e){_t(e)});oe(kt(e),jt)}function $t(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function Wt(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=re().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function fe(e,t,r){ce(e,t,le({error:t},r))}function Gt(e){return e==="htmx:afterProcessNode"}function R(e,t){oe(Br(e),function(e){try{t(e)}catch(e){b(e)}})}function b(e){if(console.error){console.error(e)}else if(console.log){console.log("ERROR: ",e)}}function ce(e,t,r){e=p(e);if(r==null){r={}}r["elt"]=e;var n=Wt(t,r);if(Q.logger&&!Gt(t)){Q.logger(e,t,r)}if(r.error){b(r.error);ce(e,"htmx:error",{errorInfo:r})}var i=e.dispatchEvent(n);var a=$t(t);if(i&&a!==t){var o=Wt(a,n.detail);i=i&&e.dispatchEvent(o)}R(e,function(e){i=i&&(e.onEvent(t,n)!==false&&!n.defaultPrevented)});return i}var Jt=location.pathname+location.search;function Zt(){var e=re().querySelector("[hx-history-elt],[data-hx-history-elt]");return e||re().body}function Kt(e,t,r,n){if(!U()){return}if(Q.config.historyCacheSize<=0){localStorage.removeItem("htmx-history-cache");return}e=F(e);var i=E(localStorage.getItem("htmx-history-cache"))||[];for(var a=0;a<i.length;a++){if(i[a].url===e){i.splice(a,1);break}}var o={url:e,content:t,title:r,scroll:n};ce(re().body,"htmx:historyItemCreated",{item:o,cache:i});i.push(o);while(i.length>Q.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){fe(re().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Yt(e){if(!U()){return null}e=F(e);var t=E(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r<t.length;r++){if(t[r].url===e){return t[r]}}return null}function Qt(e){var t=Q.config.requestClass;var r=e.cloneNode(true);oe(f(r,"."+t),function(e){n(e,t)});return r.innerHTML}function er(){var e=Zt();var t=Jt||location.pathname+location.search;var r;try{r=re().querySelector('[hx-history="false" i],[data-hx-history="false" i]')}catch(e){r=re().querySelector('[hx-history="false"],[data-hx-history="false"]')}if(!r){ce(re().body,"htmx:beforeHistorySave",{path:t,historyElt:e});Kt(t,Qt(e),re().title,window.scrollY)}if(Q.config.historyEnabled)history.replaceState({htmx:true},re().title,window.location.href)}function tr(e){if(Q.config.getCacheBusterParam){e=e.replace(/org\.htmx\.cache-buster=[^&]*&?/,"");if(G(e,"&")||G(e,"?")){e=e.slice(0,-1)}}if(Q.config.historyEnabled){history.pushState({htmx:true},"",e)}Jt=e}function rr(e){if(Q.config.historyEnabled)history.replaceState({htmx:true},"",e);Jt=e}function nr(e){oe(e,function(e){e.call()})}function ir(a){var e=new XMLHttpRequest;var o={path:a,xhr:e};ce(re().body,"htmx:historyCacheMiss",o);e.open("GET",a,true);e.setRequestHeader("HX-Request","true");e.setRequestHeader("HX-History-Restore-Request","true");e.setRequestHeader("HX-Current-URL",re().location.href);e.onload=function(){if(this.status>=200&&this.status<400){ce(re().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Zt();var r=T(t);var n=Ve(this.response);if(n){var i=C("title");if(i){i.innerHTML=n}else{window.document.title=n}}Ue(t,e,r);nr(r.tasks);Jt=a;ce(re().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{fe(re().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function ar(e){er();e=e||location.pathname+location.search;var t=Yt(e);if(t){var r=l(t.content);var n=Zt();var i=T(n);Ue(n,r,i);nr(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Jt=e;ce(re().body,"htmx:historyRestore",{path:e,item:t})}else{if(Q.config.refreshOnHistoryMiss){window.location.reload(true)}else{ir(e)}}}function or(e){var t=me(e,"hx-indicator");if(t==null){t=[e]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,Q.config.requestClass)});return t}function sr(e){var t=me(e,"hx-disabled-elt");if(t==null){t=[]}oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)+1;e.setAttribute("disabled","")});return t}function lr(e,t){oe(e,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,Q.config.requestClass)}});oe(t,function(e){var t=ae(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.removeAttribute("disabled")}})}function ur(e,t){for(var r=0;r<e.length;r++){var n=e[r];if(n.isSameNode(t)){return true}}return false}function fr(e){if(e.name===""||e.name==null||e.disabled||v(e,"fieldset[disabled]")){return false}if(e.type==="button"||e.type==="submit"||e.tagName==="image"||e.tagName==="reset"||e.tagName==="file"){return false}if(e.type==="checkbox"||e.type==="radio"){return e.checked}return true}function cr(e,t,r){if(e!=null&&t!=null){var n=r[e];if(n===undefined){r[e]=t}else if(Array.isArray(n)){if(Array.isArray(t)){r[e]=n.concat(t)}else{n.push(t)}}else{if(Array.isArray(t)){r[e]=[n].concat(t)}else{r[e]=[n,t]}}}}function hr(t,r,n,e,i){if(e==null||ur(t,e)){return}else{t.push(e)}if(fr(e)){var a=ee(e,"name");var o=e.value;if(e.multiple&&e.tagName==="SELECT"){o=M(e.querySelectorAll("option:checked")).map(function(e){return e.value})}if(e.files){o=M(e.files)}cr(a,o,r);if(i){vr(e,n)}}if(h(e,"form")){var s=e.elements;oe(s,function(e){hr(t,r,n,e,i)})}}function vr(e,t){if(e.willValidate){ce(e,"htmx:validation:validate");if(!e.checkValidity()){t.push({elt:e,message:e.validationMessage,validity:e.validity});ce(e,"htmx:validation:failed",{message:e.validationMessage,validity:e.validity})}}}function dr(e,t){var r=[];var n={};var i={};var a=[];var o=ae(e);if(o.lastButtonClicked&&!se(o.lastButtonClicked)){o.lastButtonClicked=null}var s=h(e,"form")&&e.noValidate!==true||te(e,"hx-validate")==="true";if(o.lastButtonClicked){s=s&&o.lastButtonClicked.formNoValidate!==true}if(t!=="get"){hr(r,i,a,v(e,"form"),s)}hr(r,n,a,e,s);if(o.lastButtonClicked||e.tagName==="BUTTON"||e.tagName==="INPUT"&&ee(e,"type")==="submit"){var l=o.lastButtonClicked||e;var u=ee(l,"name");cr(u,l.value,i)}var f=me(e,"hx-include");oe(f,function(e){hr(r,n,a,e,s);if(!h(e,"form")){oe(e.querySelectorAll(rt),function(e){hr(r,n,a,e,s)})}});n=le(n,i);return{errors:a,values:n}}function gr(e,t,r){if(e!==""){e+="&"}if(String(r)==="[object Object]"){r=JSON.stringify(r)}var n=encodeURIComponent(r);e+=encodeURIComponent(t)+"="+n;return e}function pr(e){var t="";for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){oe(n,function(e){t=gr(t,r,e)})}else{t=gr(t,r,n)}}}return t}function mr(e){var t=new FormData;for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){oe(n,function(e){t.append(r,e)})}else{t.append(r,n)}}}return t}function xr(e,t,r){var n={"HX-Request":"true","HX-Trigger":ee(e,"id"),"HX-Trigger-Name":ee(e,"name"),"HX-Target":te(t,"id"),"HX-Current-URL":re().location.href};Rr(e,"hx-headers",false,n);if(r!==undefined){n["HX-Prompt"]=r}if(ae(e).boosted){n["HX-Boosted"]="true"}return n}function yr(t,e){var r=ne(e,"hx-params");if(r){if(r==="none"){return{}}else if(r==="*"){return t}else if(r.indexOf("not ")===0){oe(r.substr(4).split(","),function(e){e=e.trim();delete t[e]});return t}else{var n={};oe(r.split(","),function(e){e=e.trim();n[e]=t[e]});return n}}else{return t}}function br(e){return ee(e,"href")&&ee(e,"href").indexOf("#")>=0}function wr(e,t){var r=t?t:ne(e,"hx-swap");var n={swapStyle:ae(e).boosted?"innerHTML":Q.config.defaultSwapStyle,swapDelay:Q.config.defaultSwapDelay,settleDelay:Q.config.defaultSettleDelay};if(Q.config.scrollIntoViewOnBoost&&ae(e).boosted&&!br(e)){n["show"]="top"}if(r){var i=D(r);if(i.length>0){for(var a=0;a<i.length;a++){var o=i[a];if(o.indexOf("swap:")===0){n["swapDelay"]=d(o.substr(5))}else if(o.indexOf("settle:")===0){n["settleDelay"]=d(o.substr(7))}else if(o.indexOf("transition:")===0){n["transition"]=o.substr(11)==="true"}else if(o.indexOf("ignoreTitle:")===0){n["ignoreTitle"]=o.substr(12)==="true"}else if(o.indexOf("scroll:")===0){var s=o.substr(7);var l=s.split(":");var u=l.pop();var f=l.length>0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}else if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}else if(o.indexOf("focus-scroll:")===0){var v=o.substr("focus-scroll:".length);n["focusScroll"]=v=="true"}else if(a==0){n["swapStyle"]=o}else{b("Unknown modifier in hx-swap: "+o)}}}}return n}function Sr(e){return ne(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&ee(e,"enctype")==="multipart/form-data"}function Er(t,r,n){var i=null;R(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(Sr(r)){return mr(n)}else{return pr(n)}}}function T(e){return{tasks:[],elts:[e]}}function Cr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ue(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ue(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:Q.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:Q.config.scrollBehavior})}}}function Rr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=te(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=Tr(e,function(){return Function("return ("+a+")")()},{})}else{s=E(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return Rr(u(e),t,r,n)}function Tr(e,t,r){if(Q.config.allowEval){return t()}else{fe(e,"htmx:evalDisallowedError");return r}}function Or(e,t){return Rr(e,"hx-vars",true,t)}function qr(e,t){return Rr(e,"hx-vals",false,t)}function Hr(e){return le(Or(e),qr(e))}function Lr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function Ar(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){fe(re().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function O(e,t){return t.test(e.getAllResponseHeaders())}function Nr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||I(r,"String")){return he(e,t,null,null,{targetOverride:p(r),returnPromise:true})}else{return he(e,t,p(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:p(r.target),swapOverride:r.swap,select:r.select,returnPromise:true})}}else{return he(e,t,null,null,{returnPromise:true})}}function Ir(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function kr(e,t,r){var n;var i;if(typeof URL==="function"){i=new URL(t,document.location.href);var a=document.location.origin;n=a===i.origin}else{i=t;n=g(t,document.location.origin)}if(Q.config.selfRequestsOnly){if(!n){return false}}return ce(e,"htmx:validateUrl",le({url:i,sameHost:n},r))}function he(t,r,n,i,a,e){var o=null;var s=null;a=a!=null?a:{};if(a.returnPromise&&typeof Promise!=="undefined"){var l=new Promise(function(e,t){o=e;s=t})}if(n==null){n=re().body}var M=a.handler||Mr;var X=a.select||null;if(!se(n)){ie(o);return l}var u=a.targetOverride||ye(n);if(u==null||u==pe){fe(n,"htmx:targetError",{target:te(n,"hx-target")});ie(s);return l}var f=ae(n);var c=f.lastButtonClicked;if(c){var h=ee(c,"formaction");if(h!=null){r=h}var v=ee(c,"formmethod");if(v!=null){if(v.toLowerCase()!=="dialog"){t=v}}}var d=ne(n,"hx-confirm");if(e===undefined){var D=function(e){return he(t,r,n,i,a,!!e)};var U={target:u,elt:n,path:r,verb:t,triggeringEvent:i,etc:a,issueRequest:D,question:d};if(ce(n,"htmx:confirm",U)===false){ie(o);return l}}var g=n;var p=ne(n,"hx-sync");var m=null;var x=false;if(p){var F=p.split(":");var B=F[0].trim();if(B==="this"){g=xe(n,"hx-sync")}else{g=ue(n,B)}p=(F[1]||"drop").trim();f=ae(g);if(p==="drop"&&f.xhr&&f.abortable!==true){ie(o);return l}else if(p==="abort"){if(f.xhr){ie(o);return l}else{x=true}}else if(p==="replace"){ce(g,"htmx:abort")}else if(p.indexOf("queue")===0){var V=p.split(" ");m=(V[1]||"last").trim()}}if(f.xhr){if(f.abortable){ce(g,"htmx:abort")}else{if(m==null){if(i){var y=ae(i);if(y&&y.triggerSpec&&y.triggerSpec.queue){m=y.triggerSpec.queue}}if(m==null){m="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(m==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="all"){f.queuedRequests.push(function(){he(t,r,n,i,a)})}else if(m==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){he(t,r,n,i,a)})}ie(o);return l}}var b=new XMLHttpRequest;f.xhr=b;f.abortable=x;var w=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var j=ne(n,"hx-prompt");if(j){var S=prompt(j);if(S===null||!ce(n,"htmx:prompt",{prompt:S,target:u})){ie(o);w();return l}}if(d&&!e){if(!confirm(d)){ie(o);w();return l}}var E=xr(n,u,S);if(t!=="get"&&!Sr(n)){E["Content-Type"]="application/x-www-form-urlencoded"}if(a.headers){E=le(E,a.headers)}var _=dr(n,t);var C=_.errors;var R=_.values;if(a.values){R=le(R,a.values)}var z=Hr(n);var $=le(R,z);var T=yr($,n);if(Q.config.getCacheBusterParam&&t==="get"){T["org.htmx.cache-buster"]=ee(u,"id")||"true"}if(r==null||r===""){r=re().location.href}var O=Rr(n,"hx-request");var W=ae(n).boosted;var q=Q.config.methodsThatUseUrlParams.indexOf(t)>=0;var H={boosted:W,useUrlParams:q,parameters:T,unfilteredParameters:$,headers:E,target:u,verb:t,errors:C,withCredentials:a.credentials||O.credentials||Q.config.withCredentials,timeout:a.timeout||O.timeout||Q.config.timeout,path:r,triggeringEvent:i};if(!ce(n,"htmx:configRequest",H)){ie(o);w();return l}r=H.path;t=H.verb;E=H.headers;T=H.parameters;C=H.errors;q=H.useUrlParams;if(C&&C.length>0){ce(n,"htmx:validation:halted",H);ie(o);w();return l}var G=r.split("#");var J=G[0];var L=G[1];var A=r;if(q){A=J;var Z=Object.keys(T).length!==0;if(Z){if(A.indexOf("?")<0){A+="?"}else{A+="&"}A+=pr(T);if(L){A+="#"+L}}}if(!kr(n,A,H)){fe(n,"htmx:invalidPath",H);ie(s);return l}b.open(t.toUpperCase(),A,true);b.overrideMimeType("text/html");b.withCredentials=H.withCredentials;b.timeout=H.timeout;if(O.noHeaders){}else{for(var N in E){if(E.hasOwnProperty(N)){var K=E[N];Lr(b,N,K)}}}var I={xhr:b,target:u,requestConfig:H,etc:a,boosted:W,select:X,pathInfo:{requestPath:r,finalRequestPath:A,anchor:L}};b.onload=function(){try{var e=Ir(n);I.pathInfo.responsePath=Ar(b);M(n,I);lr(k,P);ce(n,"htmx:afterRequest",I);ce(n,"htmx:afterOnLoad",I);if(!se(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(se(r)){t=r}}if(t){ce(t,"htmx:afterRequest",I);ce(t,"htmx:afterOnLoad",I)}}ie(o);w()}catch(e){fe(n,"htmx:onLoadError",le({error:e},I));throw e}};b.onerror=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendError",I);ie(s);w()};b.onabort=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:sendAbort",I);ie(s);w()};b.ontimeout=function(){lr(k,P);fe(n,"htmx:afterRequest",I);fe(n,"htmx:timeout",I);ie(s);w()};if(!ce(n,"htmx:beforeRequest",I)){ie(o);w();return l}var k=or(n);var P=sr(n);oe(["loadstart","loadend","progress","abort"],function(t){oe([b,b.upload],function(e){e.addEventListener(t,function(e){ce(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});ce(n,"htmx:beforeSend",I);var Y=q?null:Er(b,n,T);b.send(Y);return l}function Pr(e,t){var r=t.xhr;var n=null;var i=null;if(O(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(O(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(O(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=ne(e,"hx-push-url");var l=ne(e,"hx-replace-url");var u=ae(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function Mr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;var t=u.requestConfig;var h=u.select;if(!ce(l,"htmx:beforeOnLoad",u))return;if(O(f,/HX-Trigger:/i)){_e(f,"HX-Trigger",l)}if(O(f,/HX-Location:/i)){er();var r=f.getResponseHeader("HX-Location");var v;if(r.indexOf("{")===0){v=E(r);r=v["path"];delete v["path"]}Nr("GET",r,v).then(function(){tr(r)});return}var n=O(f,/HX-Refresh:/i)&&"true"===f.getResponseHeader("HX-Refresh");if(O(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");n&&location.reload();return}if(n){location.reload();return}if(O(f,/HX-Retarget:/i)){if(f.getResponseHeader("HX-Retarget")==="this"){u.target=l}else{u.target=ue(l,f.getResponseHeader("HX-Retarget"))}}var d=Pr(l,u);var i=f.status>=200&&f.status<400&&f.status!==204;var g=f.response;var a=f.status>=400;var p=Q.config.ignoreTitle;var o=le({shouldSwap:i,serverResponse:g,isError:a,ignoreTitle:p},u);if(!ce(c,"htmx:beforeSwap",o))return;c=o.target;g=o.serverResponse;a=o.isError;p=o.ignoreTitle;u.target=c;u.failed=a;u.successful=!a;if(o.shouldSwap){if(f.status===286){at(l)}R(l,function(e){g=e.transformResponse(g,f,l)});if(d.type){er()}var s=e.swapOverride;if(O(f,/HX-Reswap:/i)){s=f.getResponseHeader("HX-Reswap")}var v=wr(l,s);if(v.hasOwnProperty("ignoreTitle")){p=v.ignoreTitle}c.classList.add(Q.config.swappingClass);var m=null;var x=null;var y=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(h){r=h}if(O(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}if(d.type){ce(re().body,"htmx:beforeHistoryUpdate",le({history:d},u));if(d.type==="push"){tr(d.path);ce(re().body,"htmx:pushedIntoHistory",{path:d.path})}else{rr(d.path);ce(re().body,"htmx:replacedInHistory",{path:d.path})}}var n=T(c);je(v.swapStyle,c,l,g,n,r);if(t.elt&&!se(t.elt)&&ee(t.elt,"id")){var i=document.getElementById(ee(t.elt,"id"));var a={preventScroll:v.focusScroll!==undefined?!v.focusScroll:!Q.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(Q.config.swappingClass);oe(n.elts,function(e){if(e.classList){e.classList.add(Q.config.settlingClass)}ce(e,"htmx:afterSwap",u)});if(O(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!se(l)){o=re().body}_e(f,"HX-Trigger-After-Swap",o)}var s=function(){oe(n.tasks,function(e){e.call()});oe(n.elts,function(e){if(e.classList){e.classList.remove(Q.config.settlingClass)}ce(e,"htmx:afterSettle",u)});if(u.pathInfo.anchor){var e=re().getElementById(u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title&&!p){var t=C("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}Cr(n.elts,v);if(O(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!se(l)){r=re().body}_e(f,"HX-Trigger-After-Settle",r)}ie(m)};if(v.settleDelay>0){setTimeout(s,v.settleDelay)}else{s()}}catch(e){fe(l,"htmx:swapError",u);ie(x);throw e}};var b=Q.config.globalViewTransitions;if(v.hasOwnProperty("transition")){b=v.transition}if(b&&ce(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var w=new Promise(function(e,t){m=e;x=t});var S=y;y=function(){document.startViewTransition(function(){S();return w})}}if(v.swapDelay>0){setTimeout(y,v.swapDelay)}else{y()}}if(a){fe(l,"htmx:responseError",le({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Xr={};function Dr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Ur(e,t){if(t.init){t.init(r)}Xr[e]=le(Dr(),t)}function Fr(e){delete Xr[e]}function Br(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=te(e,"hx-ext");if(t){oe(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Xr[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Br(u(e),r,n)}var Vr=false;re().addEventListener("DOMContentLoaded",function(){Vr=true});function jr(e){if(Vr||re().readyState==="complete"){e()}else{re().addEventListener("DOMContentLoaded",e)}}function _r(){if(Q.config.includeIndicatorStyles!==false){re().head.insertAdjacentHTML("beforeend","<style> ."+Q.config.indicatorClass+"{opacity:0} ."+Q.config.requestClass+" ."+Q.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} ."+Q.config.requestClass+"."+Q.config.indicatorClass+"{opacity:1; transition: opacity 200ms ease-in;} </style>")}}function zr(){var e=re().querySelector('meta[name="htmx-config"]');if(e){return E(e.content)}else{return null}}function $r(){var e=zr();if(e){Q.config=le(Q.config,e)}}jr(function(){$r();_r();var e=re().body;zt(e);var t=re().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ae(t);if(r&&r.xhr){r.xhr.abort()}});const r=window.onpopstate?window.onpopstate.bind(window):null;window.onpopstate=function(e){if(e.state&&e.state.htmx){ar();oe(t,function(e){ce(e,"htmx:restored",{document:re(),triggerEvent:ce})})}else{if(r){r(e)}}};setTimeout(function(){ce(e,"htmx:load",{});e=null},0)});return Q}()});
+40 -36
public/script/main.js
··· 1 1 import "./header.js"; 2 - import "./accessibility.js"; 2 + import "./config.js"; 3 3 4 4 function type_out(e) { 5 5 const text = e.innerText; ··· 34 34 } 35 35 36 36 function fill_list(list) { 37 - const items = list.querySelectorAll("li a, li span"); 38 - items.innerText = ""; 39 - const delay = 100; 37 + const items = list.querySelectorAll("li a, li span"); 38 + items.innerText = ""; 39 + const delay = 100; 40 40 41 - items.forEach((item, iter) => { 42 - item.style.animationDelay = `${iter * delay}ms`; 43 - item.style.animationPlayState = "playing"; 44 - }); 41 + items.forEach((item, iter) => { 42 + item.style.animationDelay = `${iter * delay}ms`; 43 + item.style.animationPlayState = "playing"; 44 + }); 45 45 } 46 46 47 - [...document.querySelectorAll("h1, h2, h3, h4, h5, h6")] 48 - .filter((e) => e.innerText != "") 49 - .forEach((e) => { 50 - type_out(e); 51 - }); 52 - [...document.querySelectorAll("ol, ul")] 53 - .filter((e) => e.innerText != "") 54 - .forEach((e) => { 55 - fill_list(e); 56 - }); 47 + function start() { 48 + [...document.querySelectorAll("h1, h2, h3, h4, h5, h6")] 49 + .filter((e) => e.innerText != "") 50 + .forEach((e) => { 51 + type_out(e); 52 + }); 53 + [...document.querySelectorAll("ol, ul")] 54 + .filter((e) => e.innerText != "") 55 + .forEach((e) => { 56 + fill_list(e); 57 + }); 57 58 58 - document.addEventListener("htmx:afterSwap", async event => { 59 - const res = await event.detail.xhr.response; 60 - var new_head = res.substring(res.indexOf("<head>")+1, res.indexOf("</head>")); 61 - if (new_head) { 62 - document.head.innerHTML = new_head; 63 - } 64 - window.scrollY = 0; 65 - }); 59 + document.addEventListener("htmx:afterSwap", async event => { 60 + const res = await event.detail.xhr.response; 61 + var new_head = res.substring(res.indexOf("<head>")+1, res.indexOf("</head>")); 62 + if (new_head) { 63 + document.head.innerHTML = new_head; 64 + } 65 + window.scrollY = 0; 66 + }); 66 67 67 - const top_button = document.getElementById("backtotop"); 68 - window.onscroll = () => { 69 - if (!top_button) return; 70 - const btt_threshold = 100; 71 - if ( 72 - document.body.scrollTop > btt_threshold || 68 + const top_button = document.getElementById("backtotop"); 69 + window.onscroll = () => { 70 + if (!top_button) return; 71 + const btt_threshold = 100; 72 + if ( 73 + document.body.scrollTop > btt_threshold || 73 74 document.documentElement.scrollTop > btt_threshold 74 - ) { 75 - top_button.classList.add("active"); 76 - } else { 77 - top_button.classList.remove("active"); 75 + ) { 76 + top_button.classList.add("active"); 77 + } else { 78 + top_button.classList.remove("active"); 79 + } 78 80 } 79 81 } 82 + 83 + start();
+36 -75
public/script/music-gateway.js
··· 1 1 import "./main.js"; 2 2 3 - const bg = document.getElementById("background"); 4 - bg.style.backgroundImage = `url(${bg.dataset.url})`; 5 - bg.removeAttribute("data-url"); 6 - 7 - const share_btn = document.getElementById("share"); 8 - share_btn.onclick = (e) => { 9 - navigator.clipboard.writeText(window.location.href); 10 - share_btn.classList.remove('active'); 11 - void share_btn.offsetWidth; 12 - share_btn.classList.add('active'); 13 - } 14 - 15 - const go_back_btn = document.getElementById("go-back") 16 - go_back_btn.innerText = "<"; 17 - go_back_btn.addEventListener("click", () => { 18 - window.history.back(); 19 - }); 20 - 21 - apply_funny_bob_to_upcoming_tags(); 22 - 23 3 function apply_funny_bob_to_upcoming_tags() { 24 - const upcomingTags = document.querySelectorAll("#type.upcoming"); 25 - for (var i = 0; i < upcomingTags.length; i++) { 26 - const tag = upcomingTags[i]; 4 + const upcoming_tags = document.querySelectorAll("#type.upcoming"); 5 + for (var i = 0; i < upcoming_tags.length; i++) { 6 + const tag = upcoming_tags[i]; 27 7 const chars = tag.innerText.split(""); 28 8 const result = chars.map((c, i) => `<span style="animation-delay: -${i * 100}ms;">${c}</span>`); 29 9 tag.innerHTML = result.join(""); 30 10 } 31 11 } 32 12 33 - const extras_pairs = Array.from(document.querySelectorAll("div#info > div").values()).map(container => { 34 - return { 35 - container, 36 - button: document.getElementById("extras").querySelector(`ul li a[href="#${container.id}"]`) 37 - }; 38 - }); 39 - const info_container = document.getElementById("info") 40 - info_container.addEventListener("scroll", update_extras_buttons); 41 13 function update_extras_buttons() { 14 + const extras_pairs = Array.from(document.querySelectorAll("div#info > div").values()).map(container => { 15 + return { 16 + container, 17 + button: document.getElementById("extras").querySelector(`ul li a[href="#${container.id}"]`) 18 + }; 19 + }); 20 + const info_container = document.getElementById("info") 21 + info_container.addEventListener("scroll", update_extras_buttons); 42 22 const info_rect = info_container.getBoundingClientRect(); 43 23 const info_y = info_rect.y; 44 24 const font_size = parseFloat(getComputedStyle(document.documentElement).fontSize); ··· 52 32 if (scroll_diff <= 0) current = pair; 53 33 }) 54 34 current.button.classList.add("active"); 55 - } 56 - update_extras_buttons(); 57 35 58 - document.querySelectorAll("div#extras ul li a[href]").forEach(link => { 59 - link.addEventListener("click", event => { 60 - event.preventDefault(); 61 - location.replace(link.href); 36 + document.querySelectorAll("div#extras ul li a[href]").forEach(link => { 37 + link.addEventListener("click", event => { 38 + event.preventDefault(); 39 + location.replace(link.href); 40 + }); 62 41 }); 63 - }); 42 + } 64 43 65 - /* 66 - * handling track previews (currently not implemented) 67 - 68 - const previews = document.querySelectorAll("[id^=preview-]"); 69 - for (const preview of previews) { 70 - preview.addEventListener("click", (e) => { 71 - if (e.target.classList.contains('playing')) { 72 - stopPreview(e.target); 73 - } else { 74 - playPreview(e.target); 75 - } 44 + function bind_go_back_btn() { 45 + const go_back_btn = document.getElementById("go-back") 46 + go_back_btn.innerText = "<"; 47 + go_back_btn.addEventListener("click", () => { 48 + window.history.back(); 76 49 }); 77 - preview.querySelector('audio').addEventListener("ended", () => { stopPreview(preview); }); 78 50 } 79 51 80 - var stupidsounds = false; 81 - 82 - function stopPreviews() { 83 - for (const preview of previews) stopPreview(preview); 52 + function bind_share_btn() { 53 + const share_btn = document.getElementById("share"); 54 + share_btn.onclick = (e) => { 55 + navigator.clipboard.writeText(window.location.href); 56 + share_btn.classList.remove('active'); 57 + void share_btn.offsetWidth; 58 + share_btn.classList.add('active'); 59 + } 84 60 } 85 61 86 - function playPreview(preview) { 87 - if (!stupidsounds) stopPreviews(); 88 - const btn = preview.querySelector('i'); 89 - btn.classList.remove("play", "fa-play"); 90 - btn.classList.add("pause", "fa-pause"); 91 - const audio = preview.querySelector('audio'); 92 - audio.play(); 93 - preview.classList.add('playing'); 62 + function start() { 63 + bind_share_btn(); 64 + bind_go_back_btn(); 65 + apply_funny_bob_to_upcoming_tags(); 66 + update_extras_buttons(); 94 67 } 95 68 96 - function stopPreview(preview) { 97 - const btn = preview.querySelector('i'); 98 - btn.classList.remove("pause", "fa-pause"); 99 - btn.classList.add("play", "fa-play"); 100 - const audio = preview.querySelector('audio'); 101 - audio.pause(); 102 - audio.currentTime = 0; 103 - preview.classList.remove('playing'); 104 - } 105 - 106 - stopPreviews(); 107 - 108 - */ 69 + start();
+53
public/script/swap.js
··· 1 + async function swap(url) { 2 + const res = await fetch(url); 3 + 4 + if (res.status !== 200) return; 5 + if (!res.headers.get("content-type").startsWith("text/html")) return; 6 + 7 + const text = await res.text(); 8 + const content = new DOMParser().parseFromString(text, "text/html"); 9 + 10 + const stylesheets = [...content.querySelectorAll("link[rel='stylesheet']")]; 11 + 12 + // swap title 13 + document.title = content.title; 14 + // swap body html 15 + document.body.innerHTML = content.body.innerHTML; 16 + // swap head html 17 + document.head.innerHTML = content.head.innerHTML; 18 + // swap stylesheets 19 + // const old_sheets = document.head.querySelectorAll("link[rel='stylesheet']"); 20 + // stylesheets.forEach(stylesheet => { document.head.appendChild(stylesheet) }); 21 + // old_sheets.forEach(stylesheet => { stylesheet.remove(); }); 22 + // push history 23 + window.history.pushState({}, "", url); 24 + 25 + bind(document.body); 26 + } 27 + 28 + function bind(content) { 29 + if (typeof(content) !== 'object' || content.nodeType !== Node.ELEMENT_NODE) return; 30 + 31 + content.querySelectorAll("a[href]").forEach(element => { 32 + if (element.href.includes("#")) return; 33 + if (!element.href.startsWith(window.location.origin)) return; 34 + const href = element.href.substring(window.location.origin.length); 35 + if (href.includes(".")) return; 36 + 37 + element.addEventListener("click", event => { 38 + event.preventDefault(); 39 + swap(element.href); 40 + }) 41 + }); 42 + 43 + content.querySelectorAll("[swap-url]").forEach(element => { 44 + const href = element.attributes.getNamedItem('swap-url').value; 45 + 46 + element.addEventListener("click", event => { 47 + event.preventDefault(); 48 + swap(href); 49 + }); 50 + }); 51 + } 52 + 53 + bind(document.body);
+18
public/style/error.css
··· 1 + @import url("/style/main.css"); 2 + 3 + main { 4 + width: min(calc(100% - 4rem), 720px); 5 + min-height: calc(100vh - 11.5rem); 6 + margin: 0 auto 2rem auto; 7 + padding-top: 4rem; 8 + } 9 + 10 + main h1 { 11 + line-height: 3rem; 12 + color: #f7215b; 13 + } 14 + 15 + small { 16 + font-size: 1em; 17 + color: #aaa; 18 + }
+21
views/404.html
··· 1 + {{define "head"}} 2 + <title>404 - ari melody 💫</title> 3 + <link rel="shortcut icon" href="/img/favicon.png" type="image/x-icon"> 4 + <link rel="stylesheet" href="/style/error.css"> 5 + {{end}} 6 + 7 + {{define "content"}} 8 + <main> 9 + <h1> 10 + # 404 - not found! 11 + </h1> 12 + 13 + <p> 14 + the page you're looking for does not exist. 15 + <br> 16 + if you like, you can head back <a href="/">home</a> or <a href="{{.Target}}">try again!</a> 17 + </p> 18 + 19 + <p><small>status: ERR_NOT_FOUND</small></p> 20 + </main> 21 + {{end}}
+6 -4
views/base.html
··· 9 9 10 10 {{block "head" .}}{{end}} 11 11 12 - <meta name="htmx-config" content='{"htmx.config.scrollIntoViewOnBoost":false}'> 13 - <script type="application/javascript" src="/script/lib/htmx.min.js"></script> 14 - <script type="application/javascript" src="/script/lib/htmx-head-support.js"></script> 12 + <!-- <meta name="htmx-config" content='{"htmx.config.scrollIntoViewOnBoost":false}'> --> 13 + <!-- <script type="application/javascript" src="/script/lib/htmx.js"></script> --> 14 + <!-- <script type="application/javascript" src="/script/lib/htmx.min.js"></script> --> 15 + <!-- <script type="application/javascript" src="/script/lib/htmx-preload.js"></script> --> 16 + <script type="application/javascript" src="/script/swap.js" defer></script> 15 17 </head> 16 18 17 - <body hx-ext="head-support"> 19 + <body hx-ext="head-support, preload"> 18 20 {{template "header"}} 19 21 20 22 {{block "content" .}}
+4 -4
views/header.html
··· 2 2 3 3 <header> 4 4 <nav> 5 - <div id="header-home" hx-get="/" hx-on="click" hx-target="main" hx-swap="outerHTML show:window:top" hx-push-url="true"> 5 + <div id="header-home" hx-get="/" hx-on="click" hx-target="body" hx-swap="outerHTML show:window:top" preload="mouseover" hx-push-url="true"> 6 6 <img src="/img/favicon.png" id="header-icon" width="100" height="100" alt=""> 7 7 <div id="header-text"> 8 8 <h1>ari melody</h1> ··· 16 16 <rect y="40" width="70" height="10" rx="5" fill="#eee" /> 17 17 </svg> 18 18 </a> 19 - <ul id="header-links" hx-boost="true" hx-target="main" hx-swap="outerHTML show:window:top"> 19 + <ul id="header-links" hx-boost="true" hx-target="body" hx-swap="outerHTML show:window:top"> 20 20 <li> 21 - <a href="/">home</a> 21 + <a href="/" preload="mouseover">home</a> 22 22 </li> 23 23 <li> 24 - <a href="/music">music</a> 24 + <a href="/music" preload="mouseover">music</a> 25 25 </li> 26 26 <li> 27 27 <a href="https://git.arimelody.me/ari/arimelody.me" target="_blank">source</a>
-10
views/htmx-base.html
··· 1 - <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 2 - <meta charset="UTF-8"> 3 - <meta http-equiv="X-UA-Compatible" content="IE=edge"> 4 - <meta name="viewport" content="width=device-width, initial-scale=1.0"> 5 - {{block "head" .}}{{end}} 6 - <meta name="htmx-config" content='{"htmx.config.scrollIntoViewOnBoost":false}'> 7 - <script type="application/javascript" src="/script/lib/htmx.min.js"></script> 8 - <script type="application/javascript" src="/script/lib/htmx-head-support.js"></script> 9 - 10 - {{block "content" .}}{{end}}
+6 -1
views/index.html
··· 12 12 <meta property="og:description" content="home to your local SPACEGIRL 💫"> 13 13 14 14 <link rel="stylesheet" href="/style/index.css"> 15 - <script type="module" src="/script/main.js" defer></script> 15 + <link rel="me" href="https://ice.arimelody.me/@ari"> 16 16 <link rel="me" href="https://wetdry.world/@ari"> 17 17 {{end}} 18 18 ··· 153 153 <a href="https://mae.wtf" target="_blank"> 154 154 <img src="/img/buttons/mae.png" alt="vimae web button"> 155 155 </a> 156 + <a href="https://zvava.org" target="_blank"> 157 + <img src="/img/buttons/zvava.png" alt="zvava web button"> 158 + </a> 156 159 157 160 <hr> 158 161 ··· 177 180 <img src="/img/buttons/misc/epicblazed.png" alt="epic blazed"> 178 181 </a> 179 182 </div> 183 + 184 + <script type="module" src="/script/main.js" defer></script> 180 185 </main> 181 186 {{end}}
+5 -3
views/music-gateway.html
··· 25 25 <meta name="twitter:image:alt" content="Cover art for &quot;{{.Title}}&quot;"> 26 26 27 27 <link rel="stylesheet" href="/style/music-gateway.css"> 28 - <script type="module" src="/script/music-gateway.js" defer></script> 29 28 {{end}} 30 29 31 30 {{define "content"}} 32 31 <main> 33 - <div id="background" data-url="{{.ResolveArtwork}}"></div> 32 + <div id="background" style="background-image: url({{.ResolveArtwork}})"></div> 34 33 35 - <a href="/music" id="go-back" title="back to arimelody.me">back to arimelody.me</a> 34 + <!-- <a href="/music" hx-boost="true" hx-target="body" hx-swap="innerHTML" id="go-back" title="back to arimelody.me">back to arimelody.me</a> --> 35 + <a href="/music" hx-boost="true" hx-target="body" hx-swap="innerHTML" id="go-back" title="back to arimelody.me">&lt;</a> 36 36 <br><br> 37 37 38 38 <div id="music-container"> ··· 161 161 <!-- <% } %> --> 162 162 <!-- </div> --> 163 163 </div> 164 + 165 + <script type="module" src="/script/music-gateway.js" defer></script> 164 166 </main> 165 167 {{end}}
+4 -3
views/music.html
··· 12 12 <meta property="og:description" content="music from your local SPACEGIRL 💫"> 13 13 14 14 <link rel="stylesheet" href="/style/music.css"> 15 - <script type="module" src="/script/music.js" defer></script> 16 15 {{end}} 17 16 18 17 {{define "content"}} ··· 23 22 24 23 <div id="music-container"> 25 24 {{range $Album := .}} 26 - <div class="music" id="{{$Album.Id}}" hx-get="/music/{{$Album.Id}}" hx-trigger="click" hx-target="main" hx-swap="outerHTML" hx-push-url="true"> 25 + <div class="music" id="{{$Album.Id}}" swap-url="/music/{{$Album.Id}}"> 27 26 <div class="music-artwork"> 28 27 <img src="{{$Album.ResolveArtwork}}" alt="{{$Album.Title}} artwork" width="128"> 29 28 </div> 30 - <div class="music-details" hx-boost="true" hx-target="main" hx-swap="outerHTML"> 29 + <div class="music-details"> 31 30 <a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a> 32 31 <h2 class="music-artist">{{$Album.PrintPrimaryArtists false}}</h2> 33 32 <h3 class="music-type-{{.ResolveType}}">{{$Album.ResolveType}}</h3> ··· 85 84 </div> 86 85 87 86 <a href="#" id="backtotop">back to top</a> 87 + 88 + <script type="module" src="/script/music.js" defer></script> 88 89 </main> 89 90 {{end}}