{ "version": 3, "sources": ["../../node_modules/@stimulus/core/src/event_listener.ts", "../../node_modules/@stimulus/core/src/dispatcher.ts", "../../node_modules/@stimulus/core/src/action_descriptor.ts", "../../node_modules/@stimulus/core/src/action.ts", "../../node_modules/@stimulus/core/src/binding.ts", "../../node_modules/@stimulus/mutation-observers/src/element_observer.ts", "../../node_modules/@stimulus/mutation-observers/src/attribute_observer.ts", "../../node_modules/@stimulus/mutation-observers/src/string_map_observer.ts", "../../node_modules/@stimulus/multimap/src/set_operations.ts", "../../node_modules/@stimulus/multimap/src/multimap.ts", "../../node_modules/@stimulus/multimap/src/indexed_multimap.ts", "../../node_modules/@stimulus/multimap/src/index.ts", "../../node_modules/@stimulus/mutation-observers/src/token_list_observer.ts", "../../node_modules/@stimulus/mutation-observers/src/value_list_observer.ts", "../../node_modules/@stimulus/mutation-observers/src/index.ts", "../../node_modules/@stimulus/core/src/binding_observer.ts", "../../node_modules/@stimulus/core/src/value_observer.ts", "../../node_modules/@stimulus/core/src/context.ts", "../../node_modules/@stimulus/core/src/inheritable_statics.ts", "../../node_modules/@stimulus/core/src/blessing.ts", "../../node_modules/@stimulus/core/src/definition.ts", "../../node_modules/@stimulus/core/src/module.ts", "../../node_modules/@stimulus/core/src/class_map.ts", "../../node_modules/@stimulus/core/src/string_helpers.ts", "../../node_modules/@stimulus/core/src/data_map.ts", "../../node_modules/@stimulus/core/src/guide.ts", "../../node_modules/@stimulus/core/src/selectors.ts", "../../node_modules/@stimulus/core/src/target_set.ts", "../../node_modules/@stimulus/core/src/scope.ts", "../../node_modules/@stimulus/core/src/scope_observer.ts", "../../node_modules/@stimulus/core/src/router.ts", "../../node_modules/@stimulus/core/src/schema.ts", "../../node_modules/@stimulus/core/src/application.ts", "../../node_modules/@stimulus/core/src/class_properties.ts", "../../node_modules/@stimulus/core/src/target_properties.ts", "../../node_modules/@stimulus/core/src/value_properties.ts", "../../node_modules/@stimulus/core/src/controller.ts", "../../node_modules/@stimulus/core/src/index.ts", "../../node_modules/stimulus/index.js", "../../app/javascript/controllers/form_controller.js", "../../app/javascript/controllers/form_reset_controller.js", "../../node_modules/lodash.debounce/index.js", "../../app/javascript/controllers/form_throttle_controller.js", "../../app/javascript/controllers/search.js", "../../app/javascript/controllers/replace_controller.js", "../../node_modules/el-transition/index.js", "../../app/javascript/controllers/toggle_controller.js", "../../app/javascript/controllers/overlay_controller.js", "../../app/javascript/controllers/context_menu_controller.js", "../../app/javascript/controllers/floating-cart.js", "../../app/javascript/controllers/remove_controller.js", "../../app/javascript/controllers/location-href.js", "../../app/javascript/controllers/focus_controller.js", "../../app/javascript/controllers/scroll-fixer.js", "../../app/javascript/controllers/form-auto-submit.js", "../../app/javascript/controllers/charcount.js", "../../app/javascript/controllers/theme-color.js", "../../app/javascript/controllers/image-zoom.js", "../../app/javascript/controllers/voucher-picker.js", "../../app/javascript/controllers/flash_controller.js", "../../app/javascript/controllers/catalogue-filter.js", "../../node_modules/ibantools/jsnext/ibantools.js", "../../app/javascript/controllers/iban.js", "../../app/javascript/controllers/scroll.js", "../../app/javascript/controllers/tasting-card.js", "../../node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js", "../../node_modules/form-request-submit-polyfill/form-request-submit-polyfill.js", "../../node_modules/swiper/shared/ssr-window.esm.mjs", "../../node_modules/swiper/shared/utils.mjs", "../../node_modules/swiper/shared/swiper-core.mjs", "../../node_modules/swiper/modules/virtual.mjs", "../../node_modules/swiper/modules/keyboard.mjs", "../../node_modules/swiper/modules/mousewheel.mjs", "../../node_modules/swiper/shared/create-element-if-not-defined.mjs", "../../node_modules/swiper/modules/navigation.mjs", "../../node_modules/swiper/shared/classes-to-selector.mjs", "../../node_modules/swiper/modules/pagination.mjs", "../../node_modules/swiper/modules/scrollbar.mjs", "../../node_modules/swiper/modules/parallax.mjs", "../../node_modules/swiper/modules/zoom.mjs", "../../node_modules/swiper/modules/controller.mjs", "../../node_modules/swiper/modules/a11y.mjs", "../../node_modules/swiper/modules/history.mjs", "../../node_modules/swiper/modules/hash-navigation.mjs", "../../node_modules/swiper/modules/autoplay.mjs", "../../node_modules/swiper/modules/thumbs.mjs", "../../node_modules/swiper/modules/free-mode.mjs", "../../node_modules/swiper/modules/grid.mjs", "../../node_modules/swiper/modules/manipulation.mjs", "../../node_modules/swiper/shared/effect-init.mjs", "../../node_modules/swiper/shared/effect-target.mjs", "../../node_modules/swiper/shared/effect-virtual-transition-end.mjs", "../../node_modules/swiper/modules/effect-fade.mjs", "../../node_modules/swiper/modules/effect-cube.mjs", "../../node_modules/swiper/shared/create-shadow.mjs", "../../node_modules/swiper/modules/effect-flip.mjs", "../../node_modules/swiper/modules/effect-coverflow.mjs", "../../node_modules/swiper/modules/effect-creative.mjs", "../../node_modules/swiper/modules/effect-cards.mjs", "../../node_modules/swiper/swiper-bundle.mjs", "../../node_modules/swiper/shared/update-swiper.mjs", "../../node_modules/swiper/shared/get-element-params.mjs", "../../node_modules/swiper/swiper-element-bundle.mjs", "../../app/javascript/entrypoints/store.js"], "sourcesContent": [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, "export * from \"@stimulus/core\"\n", "import { Controller } from 'stimulus';\n\nexport default class extends Controller {\n onSubmit () {\n // disable submit button to prevent duplicate submits\n this.element.querySelectorAll('button[type=submit]').forEach (submit => submit.disabled = true)\n }\n\n onSubmitEnd () {\n this.element.querySelectorAll('button[type=submit]').forEach(submit => submit.disabled = false)\n }\n\n submit () {\n this.element.requestSubmit()\n }\n\n disableValidation () {\n this.element.noValidate = true\n }\n}\n", "import { Controller } from 'stimulus';\n\nexport default class extends Controller {\n connect () {\n this.element.querySelectorAll('input').forEach(input => {\n if (input.dataset.originalValue === undefined) {\n input.dataset.originalValue = input.value\n }\n })\n }\n\n reset () {\n this.element.querySelectorAll('input').forEach(input => {\n console.log(input.dataset.originalValue)\n // if (input.dataset.originalValue.length > 0) {\n input.value = input.dataset.originalValue\n // }\n })\n }\n}\n", "/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = debounce;\n", "import { Controller } from \"stimulus\";\nimport _debounce from \"lodash.debounce\";\n\n// needs to be connected to a
\nexport default class extends Controller {\n connect() {\n this.submit = _debounce(this.submitNow, 500, { trailing: true }).bind(this);\n }\n\n submitNow() {\n this.element.requestSubmit();\n }\n}\n", "import { Controller } from \"stimulus\";\n\nexport default class extends Controller {\n static targets = [\"input\", \"result\", \"loading\", \"submit\"];\n\n connect() {\n this._selectedIdx = undefined;\n }\n\n get selectedIdx() {\n return this._selectedIdx;\n }\n\n set selectedIdx(idx) {\n this._selectedIdx = idx;\n this.resultTargets.forEach((result) => {\n result.classList.remove(\"bg-slate-50\");\n });\n\n return idx;\n }\n\n submitStart(e) {\n this.submitTarget.classList.add(\"hidden\");\n this.loadingTarget.classList.remove(\"hidden\");\n }\n\n submitEnd(e) {\n this.loadingTarget.classList.add(\"hidden\");\n this.submitTarget.classList.remove(\"hidden\");\n }\n\n keyDown(e) {\n switch (e.key) {\n case \"ArrowUp\":\n e.preventDefault();\n if (this.selectedIdx === undefined) {\n this.selectedIdx = 0;\n }\n\n if (this.selectedIdx - 1 < 0) {\n this.selectedIdx = this.resultTargets.length - 1;\n } else {\n this.selectedIdx--;\n }\n\n this.resultTargets[this.selectedIdx]?.classList.add(\"bg-slate-50\");\n break;\n\n case \"ArrowDown\":\n e.preventDefault();\n\n if (this.selectedIdx === undefined) {\n this.selectedIdx = 0;\n } else {\n if (this.selectedIdx + 1 >= this.resultTargets.length) {\n this.selectedIdx = 0;\n } else {\n this.selectedIdx++;\n }\n }\n\n this.resultTargets[this.selectedIdx]?.classList.add(\"bg-slate-50\");\n break;\n\n case \"Enter\":\n if (this.selectedIdx === undefined) break;\n\n const url = this.resultTargets[this.selectedIdx]?.getAttribute(\"href\");\n window.Turbo.visit(url);\n break;\n\n default:\n this.selectedIdx = undefined;\n break;\n }\n }\n\n mouseOver(e) {\n this.selectedIdx = this.resultTargets.indexOf(e.target);\n this.resultTargets[this.selectedIdx]?.classList.add(\"bg-slate-50\");\n }\n}\n", "import { Controller } from 'stimulus';\n\nexport default class extends Controller {\n static targets = [ \"replaceable\" ]\n\n replaceFromSelect ({ target }) {\n const $opt = target.options[target.selectedIndex]\n this.replace($opt.dataset.value)\n }\n\n replace (value) {\n this.replaceableTargets.forEach( t => t.innerHTML = value)\n }\n}\n", "export async function enter(element, transitionName = null) {\n element.classList.remove('hidden')\n await transition('enter', element, transitionName)\n}\n\nexport async function leave(element, transitionName = null) {\n await transition('leave', element, transitionName)\n element.classList.add('hidden')\n}\n\nexport async function toggle(element, transitionName = null) {\n if (element.classList.contains('hidden')) {\n await enter(element, transitionName)\n } else {\n await leave(element, transitionName)\n }\n}\n\nasync function transition(direction, element, animation) {\n const dataset = element.dataset\n const animationClass = animation ? `${animation}-${direction}` : direction\n let transition = `transition${direction.charAt(0).toUpperCase() + direction.slice(1)}`\n const genesis = dataset[transition] ? dataset[transition].split(\" \") : [animationClass]\n const start = dataset[`${transition}Start`] ? dataset[`${transition}Start`].split(\" \") : [`${animationClass}-start`]\n const end = dataset[`${transition}End`] ? dataset[`${transition}End`].split(\" \") : [`${animationClass}-end`]\n\n addClasses(element, genesis)\n addClasses(element, start)\n await nextFrame()\n removeClasses(element, start)\n addClasses(element, end);\n await afterTransition(element)\n removeClasses(element, end)\n removeClasses(element, genesis)\n}\n\nfunction addClasses(element, classes) {\n element.classList.add(...classes)\n}\n\nfunction removeClasses(element, classes) {\n element.classList.remove(...classes)\n}\n\nfunction nextFrame() {\n return new Promise(resolve => {\n requestAnimationFrame(() => {\n requestAnimationFrame(resolve)\n });\n });\n}\n\nfunction afterTransition(element) {\n return new Promise(resolve => {\n // safari return string with comma separate values\n const computedDuration = getComputedStyle(element).transitionDuration.split(\",\")[0]\n const duration = Number(computedDuration.replace('s', '')) * 1000;\n setTimeout(() => {\n resolve()\n }, duration)\n });\n}", "import { Controller } from \"stimulus\";\nimport { toggle } from \"el-transition\";\n\nexport default class extends Controller {\n static targets = [\"toggleable\"];\n\n hideNow() {\n this.toggleableTargets.forEach((t) => t.classList.add(\"hidden\"));\n }\n\n toggle() {\n this.toggleableTargets.forEach((t) => {\n // don\u2019t toggle if already toggled (eg. if behaviour is set to once)\n if (t.dataset.toggled) {\n return;\n }\n\n if (t.dataset.toggleClass) {\n t.dataset.toggleClass.split(\" \").forEach((c) => t.classList.toggle(c));\n } else {\n if (t.dataset.transitionEnter !== undefined) {\n toggle(t);\n } else {\n t.classList.toggle(\"hidden\");\n }\n }\n\n // if the toggle should only happen once, save that we have toggled\n // successfully so we can return early on the next toggle\n if (t.dataset.toggleBehaviour === \"once\") {\n t.dataset.toggled = true;\n }\n });\n }\n}\n", "import { Controller } from \"stimulus\";\nimport { toggle } from \"el-transition\";\n\nexport default class extends Controller {\n static targets = [\"overlay\", \"backdrop\", \"content\"];\n\n open() {\n this.overlayTarget.classList.remove(\"hidden\");\n toggle(this.backdropTarget);\n toggle(this.contentTarget);\n\n const e = new CustomEvent(\"overlay:open\");\n this.element.dispatchEvent(e);\n }\n\n close() {\n toggle(this.backdropTarget);\n toggle(this.contentTarget);\n setTimeout(() => this.overlayTarget.classList.add(\"hidden\"), 110);\n }\n\n keydown({ key }) {\n if (key === \"Escape\") {\n this.close();\n }\n }\n}\n", "import { Controller } from \"stimulus\"\nimport { leave, toggle } from \"el-transition\"\n\nexport default class extends Controller {\n static targets = [\"trigger\", \"menu\"]\n\n connect () {\n this.isOpen = false\n }\n\n toggle (e) {\n e.preventDefault()\n this.isOpen = !this.isOpen\n toggle(this.menuTarget)\n this.dispatchEvents()\n }\n\n // clickOutside is bound to document using stimulus global binding\n // and closes the context menu when a click outside of it is detected\n clickOutside (e) {\n if (this.element.contains(e.target)) {\n return\n }\n\n this.close()\n }\n\n keyDown ({ key, target }) {\n if (key === \"Escape\" && target === this.triggerTarget) {\n this.close()\n }\n }\n\n close () {\n if (this.isOpen === false) {\n return\n }\n\n this.isOpen = false\n leave(this.menuTarget)\n this.dispatchEvents()\n }\n\n closeNow () {\n if (this.isOpen === false) {\n return\n }\n\n this.isOpen = false\n this.menuTarget.classList.add(\"hidden\")\n this.dispatchEvents()\n }\n\n dispatchEvents () {\n if (this.isOpen === true) {\n this.element.dispatchEvent(new CustomEvent(\"context-menu:open\"))\n } else {\n this.element.dispatchEvent(new CustomEvent(\"context-menu:close\"))\n }\n }\n}\n", "import { Controller } from \"stimulus\"\nimport { enter, leave } from \"el-transition\"\n\nexport default class extends Controller {\n static targets = [ \"trigger\", \"cart\" ]\n\n connect () {\n this.observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.intersectionRatio > 0) {\n leave(this.cartTarget)\n } else {\n enter(this.cartTarget)\n }\n })\n })\n\n this.observer.observe(this.triggerTarget)\n }\n}\n", "import { Controller } from \"stimulus\";\n\nexport default class extends Controller {\n // could add more methods: removeSelf, removeAll (use removable targets)\n\n static values = {\n delay: Number\n }\n\n connect () {\n if (this.hasDelayValue) {\n setTimeout(() => this.removeRoot(), this.delayValue)\n }\n }\n\n removeRoot () {\n this.element.remove()\n }\n}\n", "import { Controller } from \"stimulus\"\n\nexport default class extends Controller {\n static values = {\n url: String\n }\n\n connect() {\n if (this.hasUrlValue) {\n if (this.urlValue.slice(0, 1) === \"/\") {\n window.Turbo.visit(this.urlValue)\n } else {\n window.location = this.urlValue\n }\n } else {\n console.error(\"location-href: no urlValue provided\")\n }\n }\n}\n", "import { Controller } from \"stimulus\";\n\nexport default class extends Controller {\n static targets = [\"focusable\"];\n\n focus() {\n // either focus an explicit element or the first input\n const $focusable = this.hasFocusableTarget ? this.focusableTarget : this.element.querySelector('input:not([type=\"hidden\"]), textarea');\n\n // select contents or focus as appropriate\n if ($focusable?.select) {\n $focusable.select();\n } else {\n $focusable?.focus();\n }\n }\n\n // bind key down events as an action to this method\n // and it will focus the input when pressing /, except\n // if the user is typing in an input field\n onKey({ key, target }) {\n if (target.tagName !== \"INPUT\" && key === \"/\") {\n this.focus();\n }\n }\n}\n", "import { Controller } from \"stimulus\"\n\nexport default class extends Controller {\n static values = {\n scroll: Number\n }\n\n connect () {\n this.element.scrollLeft = this.scrollValue\n }\n\n scroll () {\n this.scrollLeft = this.element.scrollLeft\n }\n\n cache () {\n this.scrollValue = this.scrollLeft\n }\n}\n", "import { Controller } from 'stimulus';\n\nexport default class extends Controller {\n connect () {\n setTimeout(() => this.element.requestSubmit(), 1000)\n }\n\n // onSubmit () {\n // // disable submit button to prevent duplicate submits\n // this.element.querySelectorAll('button[type=submit]').forEach (submit => submit.disabled = true)\n // }\n\n // onSubmitEnd () {\n // this.element.querySelectorAll('button[type=submit]').forEach(submit => submit.disabled = false)\n // }\n\n // submit () {\n // this.element.requestSubmit()\n // }\n\n // disableValidation () {\n // this.element.noValidate = true\n // }\n}\n", "import { Controller } from \"stimulus\"\n\nexport default class extends Controller {\n static targets = [\"input\", \"count\"]\n\n connect () {\n this.update()\n }\n\n update () {\n let count = this.inputTarget.value.trim().length\n if (count <= 0) {\n this.clear()\n return\n }\n\n if (this.inputTarget.getAttribute(\"maxlength\") !== null) {\n count += `/${this.inputTarget.getAttribute(\"maxlength\")}`\n }\n\n this.countTarget.innerText = count\n }\n\n clear () {\n this.countTarget.innerText = \"\"\n }\n}\n", "import { Controller } from \"stimulus\"\n\nexport default class extends Controller {\n connect () {\n this.metaTag = document.querySelector(\"meta[name=theme-color]\")\n }\n\n darken () {\n this.metaTag.setAttribute(\"content\", this.metaTag.dataset.dark)\n }\n\n lighten () {\n this.metaTag.setAttribute(\"content\", this.metaTag.dataset.light)\n }\n\n // // static values = {\n // // scroll: Number\n // // }\n\n // connect () {\n // this.element.scrollLeft = this.scrollValue\n // }\n\n // scroll () {\n // this.scrollLeft = this.element.scrollLeft\n // }\n\n // cache () {\n // this.scrollValue = this.scrollLeft\n // }\n}\n", "import { Controller } from \"stimulus\";\nimport { enter, leave } from \"el-transition\";\n\nexport default class extends Controller {\n connect() {\n this.overlays = {};\n }\n\n open({ currentTarget }) {\n if (this.overlays[currentTarget] !== undefined) {\n enter(this.overlays[currentTarget]);\n } else {\n const o = document.createElement(\"div\");\n o.dataset.turboCache = false;\n o.classList.add(\n \"js-image-zoom\",\n \"fixed\",\n \"inset-0\",\n \"p-4\",\n \"lg:p-8\",\n \"bg-white/90\",\n \"z-50\",\n \"flex\",\n \"justify-center\",\n \"items-center\",\n \"cursor-zoom-out\",\n \"hidden\",\n );\n\n // Transition.fadeIn\n const transition = {\n transitionEnter: \"transition ease-out duration-150\",\n transitionEnterStart: \"opacity-0\",\n transitionEnterEnd: \"opacity-100\",\n transitionLeave: \"transition ease-in duration-100\",\n transitionLeaveStart: \"opacity-100\",\n transitionLeaveEnd: \"opacity-0\",\n };\n\n Object.entries(transition).map(([k, v]) => {\n o.dataset[k] = v;\n });\n\n o.addEventListener(\"click\", ({ currentTarget }) => leave(currentTarget));\n\n const img = document.createElement(\"img\");\n img.classList.add(\n \"object-center\",\n \"object-contain\",\n \"w-full\",\n \"h-full\",\n \"max-h-[1800px]\",\n \"z-40\",\n );\n img.setAttribute(\n \"src\",\n currentTarget.dataset?.src || currentTarget.getAttribute(\"src\"),\n );\n\n // const spinner = document.createElement(\"div\");\n // spinner.classList.add(\n // \"absolute\",\n // \"top-1/2\",\n // \"left-1/2\",\n // \"-translate-x-1/2\",\n // \"-translate-y-1/2\",\n // \"w-8\",\n // \"h-8\",\n // \"bg-red-500\",\n // \"z-30\",\n // \"animate-spin\",\n // );\n\n o.appendChild(img);\n // o.appendChild(spinner);\n document.body.appendChild(o);\n\n enter(o);\n this.overlays[currentTarget] = o;\n }\n }\n\n keydown({ key }) {\n if (key === \"Escape\") {\n document\n .querySelectorAll(\".js-image-zoom:not(.hidden)\")\n .forEach((z) => leave(z));\n }\n }\n}\n", "import { Controller } from \"stimulus\";\n// import { toggle } from \"el-transition\";\n\nexport default class extends Controller {\n static targets = [\"amount\", \"customAmount\", \"design\", \"preview\"];\n static classes = [\"unchecked\", \"checked\"];\n\n connect() {\n this.amountTargets[0].parentElement.classList.add(\n ...this.checkedClass.split(\" \")\n );\n\n this.designTargets[0].parentElement.classList.add(\n ...this.checkedClass.split(\" \")\n );\n }\n\n toggleAmount(e) {\n this.amountTargets.forEach((amount) => {\n amount.parentElement.classList.remove(...this.checkedClass.split(\" \"));\n amount.parentElement.classList.add(...this.uncheckedClass.split(\" \"));\n });\n\n e.target.parentElement.classList.remove(...this.uncheckedClass.split(\" \"));\n e.target.parentElement.classList.add(...this.checkedClass.split(\" \"));\n\n this.customAmountTarget.classList.remove(...this.checkedClass.split(\" \"));\n this.customAmountTarget.classList.add(...this.uncheckedClass.split(\" \"));\n this.customAmountTarget.value = \"\";\n }\n\n toggleDesign(e) {\n this.designTargets.forEach((amount) => {\n amount.parentElement.classList.remove(...this.checkedClass.split(\" \"));\n amount.parentElement.classList.add(...this.uncheckedClass.split(\" \"));\n });\n\n e.target.parentElement.classList.remove(...this.uncheckedClass.split(\" \"));\n e.target.parentElement.classList.add(...this.checkedClass.split(\" \"));\n\n this.previewTarget.src = e.target.dataset.previewImage;\n }\n\n focusCustomAmount(e) {\n this.amountTargets.forEach((amount) => {\n amount.parentElement.classList.remove(...this.checkedClass.split(\" \"));\n amount.parentElement.classList.add(...this.uncheckedClass.split(\" \"));\n });\n }\n\n blurCustomAmount(e) {\n if (e.target.value !== \"\") {\n e.target.classList.remove(...this.uncheckedClass.split(\" \"));\n e.target.classList.add(...this.checkedClass.split(\" \"));\n }\n }\n}\n", "import { Controller } from \"stimulus\";\nimport { leave } from \"el-transition\";\n\nexport default class extends Controller {\n connect() {\n setTimeout(() => this.remove(), 3000);\n }\n\n remove() {\n leave(this.element).then(() => this.element.remove());\n }\n}\n", "import { Controller } from \"stimulus\";\nimport { enter, leave } from \"el-transition\";\n\nexport default class extends Controller {\n static targets = [\"category\", \"tag\", \"scroll-trigger\"];\n\n connect() {\n this.activeClasses = this.element.dataset.activeClass.split(\" \");\n\n this.observer = new IntersectionObserver((entries) => {\n entries.forEach((entry) => {\n // don\u2019t run this on lg and up\n if (window.innerWidth >= 1024) {\n return;\n }\n\n if (entry.isIntersecting) {\n enter(this.element);\n console.log(\"enter\");\n } else {\n leave(this.element);\n console.log(\"leave\");\n }\n });\n });\n\n this.observer.observe(document.querySelector(\"#nav-scroll-trigger\"));\n }\n\n scrollIntoView() {\n if (this.element.dataset.scrollIntoView === \"true\") {\n document.querySelector(\"turbo-frame#catalogue_products\").scrollIntoView({\n behavior: \"smooth\",\n });\n }\n }\n\n clickCategory({ currentTarget }) {\n this.categoryTargets.forEach((el) => {\n el.classList.remove(...this.activeClasses);\n });\n\n currentTarget.classList.add(...this.activeClasses);\n\n const url = new URL(location);\n const target = new URL(currentTarget.href);\n url.search = target.searchParams.toString();\n history.replaceState({}, \"\", url);\n\n this.scrollIntoView();\n }\n\n clickTag({ currentTarget }) {\n if (currentTarget.classList.contains(...this.activeClasses)) {\n currentTarget.classList.remove(...this.activeClasses);\n } else {\n currentTarget.classList.add(...this.activeClasses);\n }\n\n const url = new URL(location);\n const target = new URL(currentTarget.href);\n url.search = target.searchParams.toString();\n history.replaceState({}, \"\", url);\n\n this.scrollIntoView();\n }\n}\n", "/*!\n * @license\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n/**\n * Validation, extraction and creation of IBAN, BBAN, BIC/SWIFT numbers plus some other helpful stuff\n * @package Documentation\n * @author Sa\u0161a Jovani\u0107\n * @module ibantools\n * @version 4.3.9\n * @license MPL-2.0\n * @preferred\n */\n'use strict';\n/**\n * Validate IBAN\n * ```\n * // returns true\n * ibantools.isValidIBAN(\"NL91ABNA0417164300\");\n * ```\n * ```\n * // returns false\n * ibantools.isValidIBAN(\"NL92ABNA0517164300\");\n * ```\n * ```\n * // returns true\n * ibantools.isValidIBAN('CH4431999123000889012');\n * ```\n * ```\n * // returns false\n * ibantools.isValidIBAN('CH4431999123000889012', { allowQRIBAN: false });\n * ```\n */\nexport function isValidIBAN(iban, validationOptions) {\n if (validationOptions === void 0) { validationOptions = { allowQRIBAN: true }; }\n if (iban === undefined || iban === null)\n return false;\n var reg = new RegExp('^[0-9]{2}$', '');\n var countryCode = iban.slice(0, 2);\n var spec = countrySpecs[countryCode];\n if (spec === undefined || spec.bban_regexp === undefined || spec.bban_regexp === null || spec.chars === undefined)\n return false;\n return (spec.chars === iban.length &&\n reg.test(iban.slice(2, 4)) &&\n isValidBBAN(iban.slice(4), countryCode) &&\n isValidIBANChecksum(iban) &&\n (validationOptions.allowQRIBAN || !isQRIBAN(iban)));\n}\n/**\n * IBAM validation errors\n */\nexport var ValidationErrorsIBAN;\n(function (ValidationErrorsIBAN) {\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"NoIBANProvided\"] = 0] = \"NoIBANProvided\";\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"NoIBANCountry\"] = 1] = \"NoIBANCountry\";\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"WrongBBANLength\"] = 2] = \"WrongBBANLength\";\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"WrongBBANFormat\"] = 3] = \"WrongBBANFormat\";\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"ChecksumNotNumber\"] = 4] = \"ChecksumNotNumber\";\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"WrongIBANChecksum\"] = 5] = \"WrongIBANChecksum\";\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"WrongAccountBankBranchChecksum\"] = 6] = \"WrongAccountBankBranchChecksum\";\n ValidationErrorsIBAN[ValidationErrorsIBAN[\"QRIBANNotAllowed\"] = 7] = \"QRIBANNotAllowed\";\n})(ValidationErrorsIBAN || (ValidationErrorsIBAN = {}));\n/**\n * validateIBAN\n * ```\n * // returns {errorCodes: [], valid: true}\n * ibantools.validateIBAN(\"NL91ABNA0417164300\");\n * ```\n * ```\n * ```\n * // returns {errorCodes: [], valid: true}\n * ibantools.validateIBAN('CH4431999123000889012');\n * ```\n * ```\n * // returns {errorCodes: [7], valid: false}\n * ibantools.validateIBAN('CH4431999123000889012', { allowQRIBAN: false });\n * ```\n */\nexport function validateIBAN(iban, validationOptions) {\n if (validationOptions === void 0) { validationOptions = { allowQRIBAN: true }; }\n var result = { errorCodes: [], valid: true };\n if (iban !== undefined && iban !== null && iban !== '') {\n var spec = countrySpecs[iban.slice(0, 2)];\n if (!spec || !(spec.bban_regexp || spec.chars)) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.NoIBANCountry);\n return result;\n }\n if (spec && spec.chars && spec.chars !== iban.length) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.WrongBBANLength);\n }\n if (spec && spec.bban_regexp && !checkFormatBBAN(iban.slice(4), spec.bban_regexp)) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.WrongBBANFormat);\n }\n if (spec && spec.bban_validation_func && !spec.bban_validation_func(iban.slice(4))) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.WrongAccountBankBranchChecksum);\n }\n var reg = new RegExp('^[0-9]{2}$', '');\n if (!reg.test(iban.slice(2, 4))) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.ChecksumNotNumber);\n }\n if (result.errorCodes.indexOf(ValidationErrorsIBAN.WrongBBANFormat) !== -1 || !isValidIBANChecksum(iban)) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.WrongIBANChecksum);\n }\n if (!validationOptions.allowQRIBAN && isQRIBAN(iban)) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.QRIBANNotAllowed);\n }\n }\n else {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsIBAN.NoIBANProvided);\n }\n return result;\n}\n/**\n * Validate BBAN\n *\n * ```\n * // returns true\n * ibantools.isValidBBAN(\"ABNA0417164300\", \"NL\");\n * ```\n * ```\n * // returns false\n * ibantools.isValidBBAN(\"A7NA0517164300\", \"NL\");\n * ```\n */\nexport function isValidBBAN(bban, countryCode) {\n if (bban === undefined || bban === null || countryCode === undefined || countryCode === null)\n return false;\n var spec = countrySpecs[countryCode];\n if (spec === undefined ||\n spec === null ||\n spec.bban_regexp === undefined ||\n spec.bban_regexp === null ||\n spec.chars === undefined ||\n spec.chars === null)\n return false;\n if (spec.chars - 4 === bban.length && checkFormatBBAN(bban, spec.bban_regexp)) {\n if (spec.bban_validation_func) {\n return spec.bban_validation_func(bban.replace(/[\\s.]+/g, ''));\n }\n return true;\n }\n return false;\n}\n/**\n * Validate if country code is from a SEPA country\n * ```\n * // returns true\n * ibantools.isSEPACountry(\"NL\");\n * ```\n * ```\n * // returns false\n * ibantools.isSEPACountry(\"PK\");\n * ```\n */\nexport function isSEPACountry(countryCode) {\n if (countryCode !== undefined && countryCode !== null) {\n var spec = countrySpecs[countryCode];\n if (spec !== undefined) {\n return spec.SEPA ? spec.SEPA : false;\n }\n }\n return false;\n}\n/**\n * Check if IBAN is QR-IBAN\n * ```\n * // returns true\n * ibantools.isQRIBAN(\"CH4431999123000889012\");\n * ```\n * ```\n * // returns false\n * ibantools.isQRIBAN(\"NL92ABNA0517164300\");\n * ```\n */\nexport function isQRIBAN(iban) {\n if (iban === undefined || iban === null)\n return false;\n var countryCode = iban.slice(0, 2);\n var QRIBANCountries = ['LI', 'CH'];\n if (!QRIBANCountries.includes(countryCode))\n return false;\n var reg = new RegExp('^3[0-1]{1}[0-9]{3}$', '');\n return reg.test(iban.slice(4, 9));\n}\n/**\n * composeIBAN\n *\n * ```\n * // returns NL91ABNA0417164300\n * ibantools.composeIBAN({ countryCode: \"NL\", bban: \"ABNA0417164300\" });\n * ```\n */\nexport function composeIBAN(params) {\n var formated_bban = electronicFormatIBAN(params.bban) || '';\n if (params.countryCode === null || params.countryCode === undefined) {\n return null;\n }\n var spec = countrySpecs[params.countryCode];\n if (formated_bban !== '' &&\n spec !== undefined &&\n spec.chars &&\n spec.chars !== null &&\n spec.chars === formated_bban.length + 4 &&\n spec.bban_regexp &&\n spec.bban_regexp !== null &&\n checkFormatBBAN(formated_bban, spec.bban_regexp)) {\n var checksom = mod9710Iban(params.countryCode + '00' + formated_bban);\n return params.countryCode + ('0' + (98 - checksom)).slice(-2) + formated_bban;\n }\n return null;\n}\n/**\n * extractIBAN\n * ```\n * // returns {iban: \"NL91ABNA0417164300\", bban: \"ABNA0417164300\", countryCode: \"NL\", valid: true, accountNumber: '0417164300', bankIdentifier: 'ABNA'}\n * ibantools.extractIBAN(\"NL91 ABNA 0417 1643 00\");\n * ```\n */\nexport function extractIBAN(iban) {\n var result = {};\n var eFormatIBAN = electronicFormatIBAN(iban);\n result.iban = eFormatIBAN || iban;\n if (!!eFormatIBAN && isValidIBAN(eFormatIBAN)) {\n result.bban = eFormatIBAN.slice(4);\n result.countryCode = eFormatIBAN.slice(0, 2);\n result.valid = true;\n var spec = countrySpecs[result.countryCode];\n if (spec.account_indentifier) {\n var ac = spec.account_indentifier.split('-');\n var starting = parseInt(ac[0]);\n var ending = parseInt(ac[1]);\n result.accountNumber = result.iban.slice(starting, ending + 1);\n }\n if (spec.bank_identifier) {\n var ac = spec.bank_identifier.split('-');\n var starting = parseInt(ac[0]);\n var ending = parseInt(ac[1]);\n result.bankIdentifier = result.bban.slice(starting, ending + 1);\n }\n if (spec.branch_indentifier) {\n var ac = spec.branch_indentifier.split('-');\n var starting = parseInt(ac[0]);\n var ending = parseInt(ac[1]);\n result.branchIdentifier = result.bban.slice(starting, ending + 1);\n }\n }\n else {\n result.valid = false;\n }\n return result;\n}\n/**\n * Check BBAN format\n *\n * @ignore\n */\nfunction checkFormatBBAN(bban, bformat) {\n var reg = new RegExp(bformat, '');\n return reg.test(bban);\n}\n/**\n * Get IBAN in electronic format (no spaces)\n * IBAN validation is not performed.\n * When non-string value for IBAN is provided, returns null.\n * ```\n * // returns \"NL91ABNA0417164300\"\n * ibantools.electronicFormatIBAN(\"NL91 ABNA 0417 1643 00\");\n * ```\n */\nexport function electronicFormatIBAN(iban) {\n if (typeof iban !== 'string') {\n return null;\n }\n return iban.replace(/[-\\ ]/g, '').toUpperCase();\n}\n/**\n * Get IBAN in friendly format (separated after every 4 characters)\n * IBAN validation is not performed.\n * When non-string value for IBAN is provided, returns null.\n * ```\n * // returns \"NL91 ABNA 0417 1643 00\"\n * ibantools.friendlyFormatIBAN(\"NL91ABNA0417164300\");\n * ```\n * ```\n * // returns \"NL91-ABNA-0417-1643-00\"\n * ibantools.friendlyFormatIBAN(\"NL91ABNA0417164300\",\"-\");\n * ```\n */\nexport function friendlyFormatIBAN(iban, separator) {\n if (typeof iban !== 'string') {\n return null;\n }\n if (separator === undefined || separator === null) {\n separator = ' ';\n }\n var electronic_iban = electronicFormatIBAN(iban);\n /* istanbul ignore if */\n if (electronic_iban === null) {\n return null;\n }\n return electronic_iban.replace(/(.{4})(?!$)/g, '$1' + separator);\n}\n/**\n * Calculate checksum of IBAN and compares it with checksum provided in IBAN Registry\n *\n * @ignore\n */\nfunction isValidIBANChecksum(iban) {\n var countryCode = iban.slice(0, 2);\n var providedChecksum = parseInt(iban.slice(2, 4), 10);\n var bban = iban.slice(4);\n // Wikipedia[validating_iban] says there are a specif way to check if a IBAN is valid but\n // it. It says 'If the remainder is 1, the check digit test is passed and the\n // IBAN might be valid.'. might, MIGHT!\n // We don't want might but want yes or no. Since every BBAN is IBAN from the fifth\n // (slice(4)) we can generate the IBAN from BBAN and country code(two first characters)\n // from in the IBAN.\n // To generate the (generate the iban check digits)[generating-iban-check]\n // Move the country code to the end\n // remove the checksum from the begging\n // Add \"00\" to the end\n // modulo 97 on the amount\n // subtract remainder from 98, (98 - remainder)\n // Add a leading 0 if the remainder is less then 10 (padStart(2, \"0\")) (we skip this\n // since we compare int, not string)\n //\n // [validating_iban][https://en.wikipedia.org/wiki/International_Bank_Account_Number#Validating_the_IBAN]\n // [generating-iban-check][https://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits]\n var validationString = replaceCharaterWithCode(\"\".concat(bban).concat(countryCode, \"00\"));\n var rest = mod9710(validationString);\n return 98 - rest === providedChecksum;\n}\n/**\n * Iban contain characters and should be converted to intereger by 55 substracted\n * from there ascii value\n *\n * @ignore\n */\nfunction replaceCharaterWithCode(str) {\n // It is slower but alot more readable\n // https://jsbench.me/ttkzgsekae/1\n return str\n .split('')\n .map(function (c) {\n var code = c.charCodeAt(0);\n return code >= 65 ? (code - 55).toString() : c;\n })\n .join('');\n}\n/**\n * MOD-97-10\n *\n * @ignore\n */\nfunction mod9710Iban(iban) {\n return mod9710(replaceCharaterWithCode(iban.slice(4) + iban.slice(0, 4)));\n}\n/**\n * Returns specifications for all countries, even those who are not\n * members of IBAN registry. `IBANRegistry` field indicates if country\n * is member of not.\n *\n * ```\n * // Validating IBAN form field after user selects his country\n * // \n * $(\"#countries\").select(function() {\n * // Find country\n * let country = ibantools.getCountrySpecifications()[$(this).val()];\n * // Add country code letters to IBAN form field\n * $(\"input#iban\").value($(this).val());\n * // Add New value to \"pattern\" attribute to #iban input text field\n * $(\"input#iban\").attr(\"pattern\", $(this).val() + \"[0-9]{2}\" + country.bban_regexp.slice(1).replace(\"$\",\"\"));\n * });\n * ```\n */\nexport function getCountrySpecifications() {\n var countyMap = {};\n for (var countyCode in countrySpecs) {\n var county = countrySpecs[countyCode];\n countyMap[countyCode] = {\n chars: county.chars || null,\n bban_regexp: county.bban_regexp || null,\n IBANRegistry: county.IBANRegistry || false,\n SEPA: county.SEPA || false,\n };\n }\n return countyMap;\n}\n/**\n * Validate BIC/SWIFT\n *\n * ```\n * // returns true\n * ibantools.isValidBIC(\"ABNANL2A\");\n *\n * // returns true\n * ibantools.isValidBIC(\"NEDSZAJJXXX\");\n *\n * // returns false\n * ibantools.isValidBIC(\"ABN4NL2A\");\n *\n * // returns false\n * ibantools.isValidBIC(\"ABNA NL 2A\");\n * ```\n */\nexport function isValidBIC(bic) {\n if (!bic) {\n return false;\n }\n var reg = new RegExp('^[a-zA-Z]{6}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?$', '');\n var spec = countrySpecs[bic.toUpperCase().slice(4, 6)];\n return reg.test(bic) && spec !== undefined;\n}\n/**\n * BIC validation errors\n */\nexport var ValidationErrorsBIC;\n(function (ValidationErrorsBIC) {\n ValidationErrorsBIC[ValidationErrorsBIC[\"NoBICProvided\"] = 0] = \"NoBICProvided\";\n ValidationErrorsBIC[ValidationErrorsBIC[\"NoBICCountry\"] = 1] = \"NoBICCountry\";\n ValidationErrorsBIC[ValidationErrorsBIC[\"WrongBICFormat\"] = 2] = \"WrongBICFormat\";\n})(ValidationErrorsBIC || (ValidationErrorsBIC = {}));\n/**\n * validateBIC\n * ```\n * // returns {errorCodes: [], valid: true}\n * ibantools.validateBIC(\"NEDSZAJJXXX\");\n * ```\n */\nexport function validateBIC(bic) {\n var result = { errorCodes: [], valid: true };\n if (bic !== undefined && bic !== null && bic !== '') {\n var spec = countrySpecs[bic.toUpperCase().slice(4, 6)];\n if (spec === undefined) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsBIC.NoBICCountry);\n }\n else {\n var reg = new RegExp('^[a-zA-Z]{6}[a-zA-Z0-9]{2}([a-zA-Z0-9]{3})?$', '');\n if (!reg.test(bic)) {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsBIC.WrongBICFormat);\n }\n }\n }\n else {\n result.valid = false;\n result.errorCodes.push(ValidationErrorsBIC.NoBICProvided);\n }\n return result;\n}\n/**\n * extractBIC\n * ```\n * // returns {bankCode: \"ABNA\", countryCode: \"NL\", locationCode: \"2A\", branchCode: null, testBIC: false, valid: true}\n * ibantools.extractBIC(\"ABNANL2A\");\n * ```\n */\nexport function extractBIC(inputBic) {\n var result = {};\n var bic = inputBic.toUpperCase();\n if (isValidBIC(bic)) {\n result.bankCode = bic.slice(0, 4);\n result.countryCode = bic.slice(4, 6);\n result.locationCode = bic.slice(6, 8);\n result.testBIC = result.locationCode[1] === '0' ? true : false;\n result.branchCode = bic.length > 8 ? bic.slice(8) : null;\n result.valid = true;\n }\n else {\n result.valid = false;\n }\n return result;\n}\n/**\n * Used for Norway BBAN check\n *\n * @ignore\n */\nvar checkNorwayBBAN = function (bban) {\n var weights = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2];\n var bbanWithoutSpacesAndPeriods = bban.replace(/[\\s.]+/g, '');\n var controlDigit = parseInt(bbanWithoutSpacesAndPeriods.charAt(10), 10);\n var bbanWithoutControlDigit = bbanWithoutSpacesAndPeriods.substring(0, 10);\n var sum = 0;\n for (var index = 0; index < 10; index++) {\n sum += parseInt(bbanWithoutControlDigit.charAt(index), 10) * weights[index];\n }\n var remainder = sum % 11;\n return controlDigit === (remainder === 0 ? 0 : 11 - remainder);\n};\n/**\n * Used for Belgian BBAN check\n *\n * @ignore\n */\nvar checkBelgianBBAN = function (bban) {\n var stripped = bban.replace(/[\\s.]+/g, '');\n var checkingPart = parseInt(stripped.substring(0, stripped.length - 2), 10);\n var checksum = parseInt(stripped.substring(stripped.length - 2, stripped.length), 10);\n var remainder = checkingPart % 97 === 0 ? 97 : checkingPart % 97;\n return remainder === checksum;\n};\n/**\n * Mod 97/10 calculation\n *\n * @ignore\n */\nvar mod9710 = function (validationString) {\n while (validationString.length > 2) {\n // > Any computer programming language or software package that is used to compute D\n // > mod 97 directly must have the ability to handle integers of more than 30 digits.\n // > In practice, this can only be done by software that either supports\n // > arbitrary-precision arithmetic or that can handle 219-bit (unsigned) integers\n // https://en.wikipedia.org/wiki/International_Bank_Account_Number#Modulo_operation_on_IBAN\n var part = validationString.slice(0, 6);\n var partInt = parseInt(part, 10);\n if (isNaN(partInt)) {\n return NaN;\n }\n validationString = (partInt % 97) + validationString.slice(part.length);\n }\n return parseInt(validationString, 10) % 97;\n};\n/**\n * Check BBAN based on Mod97/10 calculation for countries that support it:\n * BA, ME, MK, PT, RS, SI\n *\n * @ignore\n */\nvar checkMod9710BBAN = function (bban) {\n var stripped = bban.replace(/[\\s.]+/g, '');\n var reminder = mod9710(stripped);\n return reminder === 1;\n};\n/**\n * Used for Poland BBAN check\n *\n * @ignore\n */\nvar checkPolandBBAN = function (bban) {\n var weights = [3, 9, 7, 1, 3, 9, 7];\n var controlDigit = parseInt(bban.charAt(7), 10);\n var toCheck = bban.substring(0, 7);\n var sum = 0;\n for (var index = 0; index < 7; index++) {\n sum += parseInt(toCheck.charAt(index), 10) * weights[index];\n }\n var remainder = sum % 10;\n return controlDigit === (remainder === 0 ? 0 : 10 - remainder);\n};\n/**\n * Spain (ES) BBAN check\n *\n * @ignore\n */\nvar checkSpainBBAN = function (bban) {\n var weightsBankBranch = [4, 8, 5, 10, 9, 7, 3, 6];\n var weightsAccount = [1, 2, 4, 8, 5, 10, 9, 7, 3, 6];\n var controlBankBranch = parseInt(bban.charAt(8), 10);\n var controlAccount = parseInt(bban.charAt(9), 10);\n var bankBranch = bban.substring(0, 8);\n var account = bban.substring(10, 20);\n var sum = 0;\n for (var index = 0; index < 8; index++) {\n sum += parseInt(bankBranch.charAt(index), 10) * weightsBankBranch[index];\n }\n var remainder = sum % 11;\n if (controlBankBranch !== (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder)) {\n return false;\n }\n sum = 0;\n for (var index = 0; index < 10; index++) {\n sum += parseInt(account.charAt(index), 10) * weightsAccount[index];\n }\n remainder = sum % 11;\n return controlAccount === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);\n};\n/**\n * Mod 11/10 check\n *\n * @ignore\n */\nvar checkMod1110 = function (toCheck, control) {\n var nr = 10;\n for (var index = 0; index < toCheck.length; index++) {\n nr += parseInt(toCheck.charAt(index), 10);\n if (nr % 10 !== 0) {\n nr = nr % 10;\n }\n nr = nr * 2;\n nr = nr % 11;\n }\n return control === (11 - nr === 10 ? 0 : 11 - nr);\n};\n/**\n * Croatian (HR) BBAN check\n *\n * @ignore\n */\nvar checkCroatianBBAN = function (bban) {\n var controlBankBranch = parseInt(bban.charAt(6), 10);\n var controlAccount = parseInt(bban.charAt(16), 10);\n var bankBranch = bban.substring(0, 6);\n var account = bban.substring(7, 16);\n return checkMod1110(bankBranch, controlBankBranch) && checkMod1110(account, controlAccount);\n};\n/**\n * Czech (CZ) and Slowak (SK) BBAN check\n *\n * @ignore\n */\nvar checkCzechAndSlovakBBAN = function (bban) {\n var weightsPrefix = [10, 5, 8, 4, 2, 1];\n var weightsSuffix = [6, 3, 7, 9, 10, 5, 8, 4, 2, 1];\n var controlPrefix = parseInt(bban.charAt(9), 10);\n var controlSuffix = parseInt(bban.charAt(19), 10);\n var prefix = bban.substring(4, 9);\n var suffix = bban.substring(10, 19);\n var sum = 0;\n for (var index = 0; index < prefix.length; index++) {\n sum += parseInt(prefix.charAt(index), 10) * weightsPrefix[index];\n }\n var remainder = sum % 11;\n if (controlPrefix !== (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder)) {\n return false;\n }\n sum = 0;\n for (var index = 0; index < suffix.length; index++) {\n sum += parseInt(suffix.charAt(index), 10) * weightsSuffix[index];\n }\n remainder = sum % 11;\n return controlSuffix === (remainder === 0 ? 0 : remainder === 1 ? 1 : 11 - remainder);\n};\n/**\n * Estonian (EE) BBAN check\n *\n * @ignore\n */\nvar checkEstonianBBAN = function (bban) {\n var weights = [7, 1, 3, 7, 1, 3, 7, 1, 3, 7, 1, 3, 7];\n var controlDigit = parseInt(bban.charAt(15), 10);\n var toCheck = bban.substring(2, 15);\n var sum = 0;\n for (var index = 0; index < toCheck.length; index++) {\n sum += parseInt(toCheck.charAt(index), 10) * weights[index];\n }\n var remainder = sum % 10;\n return controlDigit === (remainder === 0 ? 0 : 10 - remainder);\n};\n/**\n * Check French (FR) BBAN\n * Also for Monaco (MC)\n *\n * @ignore\n */\nvar checkFrenchBBAN = function (bban) {\n var stripped = bban.replace(/[\\s.]+/g, '');\n var normalized = Array.from(stripped);\n for (var index = 0; index < stripped.length; index++) {\n var c = normalized[index].charCodeAt(0);\n if (c >= 65) {\n switch (c) {\n case 65:\n case 74:\n normalized[index] = '1';\n break;\n case 66:\n case 75:\n case 83:\n normalized[index] = '2';\n break;\n case 67:\n case 76:\n case 84:\n normalized[index] = '3';\n break;\n case 68:\n case 77:\n case 85:\n normalized[index] = '4';\n break;\n case 69:\n case 78:\n case 86:\n normalized[index] = '5';\n break;\n case 70:\n case 79:\n case 87:\n normalized[index] = '6';\n break;\n case 71:\n case 80:\n case 88:\n normalized[index] = '7';\n break;\n case 72:\n case 81:\n case 89:\n normalized[index] = '8';\n break;\n case 73:\n case 82:\n case 90:\n normalized[index] = '9';\n break;\n }\n }\n }\n var remainder = mod9710(normalized.join(''));\n return remainder === 0;\n};\n/**\n * Hungarian (HU) BBAN check\n *\n * @ignore\n */\nvar checkHungarianBBAN = function (bban) {\n var weights = [9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3, 1, 9, 7, 3];\n var controlDigitBankBranch = parseInt(bban.charAt(7), 10);\n var toCheckBankBranch = bban.substring(0, 7);\n var sum = 0;\n for (var index = 0; index < toCheckBankBranch.length; index++) {\n sum += parseInt(toCheckBankBranch.charAt(index), 10) * weights[index];\n }\n var remainder = sum % 10;\n if (controlDigitBankBranch !== (remainder === 0 ? 0 : 10 - remainder)) {\n return false;\n }\n sum = 0;\n if (bban.endsWith('00000000')) {\n var toCheckAccount = bban.substring(8, 15);\n var controlDigitAccount = parseInt(bban.charAt(15), 10);\n for (var index = 0; index < toCheckAccount.length; index++) {\n sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];\n }\n var remainder_1 = sum % 10;\n return controlDigitAccount === (remainder_1 === 0 ? 0 : 10 - remainder_1);\n }\n else {\n var toCheckAccount = bban.substring(8, 23);\n var controlDigitAccount = parseInt(bban.charAt(23), 10);\n for (var index = 0; index < toCheckAccount.length; index++) {\n sum += parseInt(toCheckAccount.charAt(index), 10) * weights[index];\n }\n var remainder_2 = sum % 10;\n return controlDigitAccount === (remainder_2 === 0 ? 0 : 10 - remainder_2);\n }\n};\n/**\n * Set custom BBAN validation function for country.\n *\n * If `bban_validation_func` already exists for the corresponding country,\n * it will be overwritten.\n */\nexport var setCountryBBANValidation = function (country, func) {\n if (typeof countrySpecs[country] === 'undefined') {\n return false;\n }\n countrySpecs[country].bban_validation_func = func;\n return true;\n};\n/**\n * Country specifications\n */\nexport var countrySpecs = {\n AD: {\n chars: 24,\n bban_regexp: '^[0-9]{8}[A-Z0-9]{12}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '4-7',\n bank_identifier: '0-3',\n account_indentifier: '8-24',\n },\n AE: {\n chars: 23,\n bban_regexp: '^[0-9]{3}[0-9]{16}$',\n IBANRegistry: true,\n bank_identifier: '0-2',\n account_indentifier: '7-23',\n },\n AF: {},\n AG: {},\n AI: {},\n AL: {\n chars: 28,\n bban_regexp: '^[0-9]{8}[A-Z0-9]{16}$',\n IBANRegistry: true,\n branch_indentifier: '3-7',\n bank_identifier: '0-2',\n account_indentifier: '12-28',\n },\n AM: {},\n AO: {\n chars: 25,\n bban_regexp: '^[0-9]{21}$',\n },\n AQ: {},\n AR: {},\n AS: {},\n AT: { chars: 20, bban_regexp: '^[0-9]{16}$', IBANRegistry: true, SEPA: true, bank_identifier: '0-4' },\n AU: {},\n AW: {},\n AX: {\n chars: 18,\n bban_regexp: '^[0-9]{14}$',\n IBANRegistry: true,\n },\n AZ: {\n chars: 28,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{20}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '4-28',\n },\n BA: {\n chars: 20,\n bban_regexp: '^[0-9]{16}$',\n bban_validation_func: checkMod9710BBAN,\n IBANRegistry: true,\n branch_indentifier: '3-5',\n bank_identifier: '0-2',\n },\n BB: {},\n BD: {},\n BE: {\n chars: 16,\n bban_regexp: '^[0-9]{12}$',\n bban_validation_func: checkBelgianBBAN,\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-2',\n account_indentifier: '0-16',\n },\n BF: {\n chars: 28,\n bban_regexp: '^[A-Z0-9]{2}[0-9]{22}$',\n },\n BG: {\n chars: 22,\n bban_regexp: '^[A-Z]{4}[0-9]{6}[A-Z0-9]{8}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '4-7',\n bank_identifier: '0-3',\n },\n BH: {\n chars: 22,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{14}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '8-22',\n },\n BI: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n branch_indentifier: '5-9',\n bank_identifier: '0-4',\n account_indentifier: '14-27',\n },\n BJ: {\n chars: 28,\n bban_regexp: '^[A-Z0-9]{2}[0-9]{22}$',\n },\n BL: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n },\n BM: {},\n BN: {},\n BO: {},\n BQ: {},\n BR: {\n chars: 29,\n bban_regexp: '^[0-9]{23}[A-Z]{1}[A-Z0-9]{1}$',\n IBANRegistry: true,\n branch_indentifier: '8-12',\n bank_identifier: '0-7',\n account_indentifier: '17-29',\n },\n BS: {},\n BT: {},\n BV: {},\n BW: {},\n BY: {\n chars: 28,\n bban_regexp: '^[A-Z]{4}[0-9]{4}[A-Z0-9]{16}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n },\n BZ: {},\n CA: {},\n CC: {},\n CD: {},\n CF: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n CG: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n CH: {\n chars: 21,\n bban_regexp: '^[0-9]{5}[A-Z0-9]{12}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-4',\n },\n CI: {\n chars: 28,\n bban_regexp: '^[A-Z]{1}[0-9]{23}$',\n },\n CK: {},\n CL: {},\n CM: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n CN: {},\n CO: {},\n CR: {\n chars: 22,\n bban_regexp: '^[0-9]{18}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '8-22',\n },\n CU: {},\n CV: { chars: 25, bban_regexp: '^[0-9]{21}$' },\n CW: {},\n CX: {},\n CY: {\n chars: 28,\n bban_regexp: '^[0-9]{8}[A-Z0-9]{16}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '3-7',\n bank_identifier: '0-2',\n account_indentifier: '12-28',\n },\n CZ: {\n chars: 24,\n bban_regexp: '^[0-9]{20}$',\n bban_validation_func: checkCzechAndSlovakBBAN,\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n },\n DE: {\n chars: 22,\n bban_regexp: '^[0-9]{18}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-7',\n account_indentifier: '13-22',\n },\n DJ: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n branch_indentifier: '5-9',\n bank_identifier: '0-4',\n account_indentifier: '14-27',\n },\n DK: {\n chars: 18,\n bban_regexp: '^[0-9]{14}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n account_indentifier: '4-18',\n },\n DM: {},\n DO: {\n chars: 28,\n bban_regexp: '^[A-Z]{4}[0-9]{20}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '8-28',\n },\n DZ: {\n chars: 26,\n bban_regexp: '^[0-9]{22}$',\n },\n EC: {},\n EE: {\n chars: 20,\n bban_regexp: '^[0-9]{16}$',\n bban_validation_func: checkEstonianBBAN,\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-1',\n account_indentifier: '8-20',\n },\n EG: {\n chars: 29,\n bban_regexp: '^[0-9]{25}',\n IBANRegistry: true,\n branch_indentifier: '4-7',\n bank_identifier: '0-3',\n account_indentifier: '17-29',\n },\n EH: {},\n ER: {},\n ES: {\n chars: 24,\n bban_validation_func: checkSpainBBAN,\n bban_regexp: '^[0-9]{20}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '4-7',\n bank_identifier: '0-3',\n account_indentifier: '4-24',\n },\n ET: {},\n FI: {\n chars: 18,\n bban_regexp: '^[0-9]{14}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-2',\n account_indentifier: '0-0',\n },\n FJ: {},\n FK: {\n chars: 18,\n bban_regexp: '^[A-Z]{2}[0-9]{12}$',\n bank_identifier: '0-1',\n account_indentifier: '6-18',\n },\n FM: {},\n FO: {\n chars: 18,\n bban_regexp: '^[0-9]{14}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '4-18',\n },\n FR: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n bban_validation_func: checkFrenchBBAN,\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-4',\n account_indentifier: '4-27',\n },\n GA: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n GB: {\n chars: 22,\n bban_regexp: '^[A-Z]{4}[0-9]{14}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '4-9',\n bank_identifier: '0-3',\n },\n GD: {},\n GE: {\n chars: 22,\n bban_regexp: '^[A-Z0-9]{2}[0-9]{16}$',\n IBANRegistry: true,\n bank_identifier: '0-1',\n account_indentifier: '6-22',\n },\n GF: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n GG: {},\n GH: {},\n GI: {\n chars: 23,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{15}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n account_indentifier: '8-23',\n },\n GL: {\n chars: 18,\n bban_regexp: '^[0-9]{14}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '4-18',\n },\n GM: {},\n GN: {},\n GP: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n GQ: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n GR: {\n chars: 27,\n bban_regexp: '^[0-9]{7}[A-Z0-9]{16}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '3-6',\n bank_identifier: '0-2',\n account_indentifier: '7-27',\n },\n GS: {},\n GT: {\n chars: 28,\n bban_regexp: '^[A-Z0-9]{24}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '8-28',\n },\n GU: {},\n GW: {\n chars: 25,\n bban_regexp: '^[A-Z]{2}[0-9]{19}$',\n },\n GY: {},\n HK: {},\n HM: {},\n HN: {\n chars: 28,\n bban_regexp: '^[A-Z]{4}[0-9]{20}$',\n },\n HR: {\n chars: 21,\n bban_regexp: '^[0-9]{17}$',\n bban_validation_func: checkCroatianBBAN,\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-6',\n },\n HT: {},\n HU: {\n chars: 28,\n bban_regexp: '^[0-9]{24}$',\n bban_validation_func: checkHungarianBBAN,\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '3-6',\n bank_identifier: '0-2',\n },\n ID: {},\n IE: {\n chars: 22,\n bban_regexp: '^[A-Z0-9]{4}[0-9]{14}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '4-9',\n bank_identifier: '0-3',\n },\n IL: {\n chars: 23,\n bban_regexp: '^[0-9]{19}$',\n IBANRegistry: true,\n branch_indentifier: '3-5',\n bank_identifier: '0-2',\n },\n IM: {},\n IN: {},\n IO: {},\n IQ: {\n chars: 23,\n bban_regexp: '^[A-Z]{4}[0-9]{15}$',\n IBANRegistry: true,\n branch_indentifier: '4-6',\n bank_identifier: '0-3',\n account_indentifier: '11-23',\n },\n IR: {\n chars: 26,\n bban_regexp: '^[0-9]{22}$',\n },\n IS: {\n chars: 26,\n bban_regexp: '^[0-9]{22}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '2-3',\n bank_identifier: '0-1',\n },\n IT: {\n chars: 27,\n bban_regexp: '^[A-Z]{1}[0-9]{10}[A-Z0-9]{12}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '6-10',\n bank_identifier: '1-5',\n account_indentifier: '4-27',\n },\n JE: {},\n JM: {},\n JO: {\n chars: 30,\n bban_regexp: '^[A-Z]{4}[0-9]{4}[A-Z0-9]{18}$',\n IBANRegistry: true,\n branch_indentifier: '4-7',\n bank_identifier: '4-7',\n },\n JP: {},\n KE: {},\n KG: {},\n KH: {},\n KI: {},\n KM: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n KN: {},\n KP: {},\n KR: {},\n KW: {\n chars: 30,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{22}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '20-30',\n },\n KY: {},\n KZ: {\n chars: 20,\n bban_regexp: '^[0-9]{3}[A-Z0-9]{13}$',\n IBANRegistry: true,\n bank_identifier: '0-2',\n account_indentifier: '0-20',\n },\n LA: {},\n LB: {\n chars: 28,\n bban_regexp: '^[0-9]{4}[A-Z0-9]{20}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '14-28',\n },\n LC: {\n chars: 32,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{24}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '8-32',\n },\n LI: {\n chars: 21,\n bban_regexp: '^[0-9]{5}[A-Z0-9]{12}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-4',\n },\n LK: {},\n LR: {},\n LS: {},\n LT: { chars: 20, bban_regexp: '^[0-9]{16}$', IBANRegistry: true, SEPA: true, bank_identifier: '0-4' },\n LU: {\n chars: 20,\n bban_regexp: '^[0-9]{3}[A-Z0-9]{13}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-2',\n },\n LV: {\n chars: 21,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{13}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n account_indentifier: '0-21',\n },\n LY: {\n chars: 25,\n bban_regexp: '^[0-9]{21}$',\n IBANRegistry: true,\n branch_indentifier: '3-5',\n bank_identifier: '0-2',\n account_indentifier: '10-25',\n },\n MA: {\n chars: 28,\n bban_regexp: '^[0-9]{24}$',\n },\n MC: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n bban_validation_func: checkFrenchBBAN,\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '5-9',\n bank_identifier: '0-4',\n },\n MD: {\n chars: 24,\n bban_regexp: '^[A-Z0-9]{2}[A-Z0-9]{18}$',\n IBANRegistry: true,\n bank_identifier: '0-1',\n account_indentifier: '6-24',\n },\n ME: {\n chars: 22,\n bban_regexp: '^[0-9]{18}$',\n bban_validation_func: checkMod9710BBAN,\n IBANRegistry: true,\n bank_identifier: '0-2',\n account_indentifier: '4-22',\n },\n MF: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n MG: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n MH: {},\n MK: {\n chars: 19,\n bban_regexp: '^[0-9]{3}[A-Z0-9]{10}[0-9]{2}$',\n bban_validation_func: checkMod9710BBAN,\n IBANRegistry: true,\n bank_identifier: '0-2',\n },\n ML: {\n chars: 28,\n bban_regexp: '^[A-Z0-9]{2}[0-9]{22}$',\n },\n MM: {},\n MN: {\n chars: 20,\n bban_regexp: '^[0-9]{16}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '8-20',\n },\n MO: {},\n MP: {},\n MQ: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n MR: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n IBANRegistry: true,\n branch_indentifier: '5-9',\n bank_identifier: '0-4',\n account_indentifier: '4-27',\n },\n MS: {},\n MT: {\n chars: 31,\n bban_regexp: '^[A-Z]{4}[0-9]{5}[A-Z0-9]{18}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '4-8',\n bank_identifier: '0-3',\n account_indentifier: '15-31',\n },\n MU: {\n chars: 30,\n bban_regexp: '^[A-Z]{4}[0-9]{19}[A-Z]{3}$',\n IBANRegistry: true,\n branch_indentifier: '6-7',\n bank_identifier: '0-5',\n account_indentifier: '0-30',\n },\n MV: {},\n MW: {},\n MX: {},\n MY: {},\n MZ: {\n chars: 25,\n bban_regexp: '^[0-9]{21}$',\n },\n NA: {},\n NC: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n NE: {\n chars: 28,\n bban_regexp: '^[A-Z]{2}[0-9]{22}$',\n },\n NF: {},\n NG: {},\n NI: {\n chars: 28,\n bban_regexp: '^[A-Z]{4}[0-9]{20}$',\n bank_identifier: '0-3',\n IBANRegistry: true,\n account_indentifier: '8-28',\n },\n NL: {\n chars: 18,\n bban_regexp: '^[A-Z]{4}[0-9]{10}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n account_indentifier: '8-18',\n },\n NO: {\n chars: 15,\n bban_regexp: '^[0-9]{11}$',\n bban_validation_func: checkNorwayBBAN,\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n account_indentifier: '4-15',\n },\n NP: {},\n NR: {},\n NU: {},\n NZ: {},\n OM: {},\n PA: {},\n PE: {},\n PF: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n PG: {},\n PH: {},\n PK: {\n chars: 24,\n bban_regexp: '^[A-Z0-9]{4}[0-9]{16}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n },\n PL: {\n chars: 28,\n bban_validation_func: checkPolandBBAN,\n bban_regexp: '^[0-9]{24}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '0-7',\n account_indentifier: '2-28',\n },\n PM: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n PN: {},\n PR: {},\n PS: {\n chars: 29,\n bban_regexp: '^[A-Z0-9]{4}[0-9]{21}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '17-29',\n },\n PT: {\n chars: 25,\n bban_regexp: '^[0-9]{21}$',\n bban_validation_func: checkMod9710BBAN,\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n },\n PW: {},\n PY: {},\n QA: {\n chars: 29,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{21}$',\n IBANRegistry: true,\n bank_identifier: '0-3',\n account_indentifier: '8-29',\n },\n RE: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n RO: {\n chars: 24,\n bban_regexp: '^[A-Z]{4}[A-Z0-9]{16}$',\n IBANRegistry: true,\n SEPA: true,\n bank_identifier: '0-3',\n account_indentifier: '0-24',\n },\n RS: {\n chars: 22,\n bban_regexp: '^[0-9]{18}$',\n bban_validation_func: checkMod9710BBAN,\n IBANRegistry: true,\n bank_identifier: '0-2',\n },\n RU: {\n chars: 33,\n bban_regexp: '^[0-9]{14}[A-Z0-9]{15}$',\n IBANRegistry: true,\n branch_indentifier: '9-13',\n bank_identifier: '0-8',\n account_indentifier: '13-33',\n },\n RW: {},\n SA: {\n chars: 24,\n bban_regexp: '^[0-9]{2}[A-Z0-9]{18}$',\n IBANRegistry: true,\n bank_identifier: '0-1',\n account_indentifier: '12-24',\n },\n SB: {},\n SC: {\n chars: 31,\n bban_regexp: '^[A-Z]{4}[0-9]{20}[A-Z]{3}$',\n IBANRegistry: true,\n branch_indentifier: '6-7',\n bank_identifier: '0-5',\n account_indentifier: '12-28',\n },\n SD: {\n chars: 18,\n bban_regexp: '^[0-9]{14}$',\n IBANRegistry: true,\n bank_identifier: '0-1',\n account_indentifier: '6-18',\n },\n SE: { chars: 24, bban_regexp: '^[0-9]{20}$', IBANRegistry: true, SEPA: true, bank_identifier: '0-2' },\n SG: {},\n SH: {},\n SI: {\n chars: 19,\n bban_regexp: '^[0-9]{15}$',\n bban_validation_func: checkMod9710BBAN,\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '2-4',\n bank_identifier: '0-1',\n account_indentifier: '9-16',\n },\n SJ: {},\n SK: {\n chars: 24,\n bban_regexp: '^[0-9]{20}$',\n bban_validation_func: checkCzechAndSlovakBBAN,\n IBANRegistry: true,\n SEPA: true,\n },\n SL: {},\n SM: {\n chars: 27,\n bban_regexp: '^[A-Z]{1}[0-9]{10}[A-Z0-9]{12}$',\n IBANRegistry: true,\n SEPA: true,\n branch_indentifier: '6-10',\n },\n SN: {\n chars: 28,\n bban_regexp: '^[A-Z]{2}[0-9]{22}$',\n },\n SO: {\n chars: 23,\n bban_regexp: '^[0-9]{19}$',\n IBANRegistry: true,\n branch_indentifier: '4-6',\n account_indentifier: '11-23',\n },\n SR: {},\n SS: {},\n ST: {\n chars: 25,\n bban_regexp: '^[0-9]{21}$',\n IBANRegistry: true,\n branch_indentifier: '4-7',\n },\n SV: {\n chars: 28,\n bban_regexp: '^[A-Z]{4}[0-9]{20}$',\n IBANRegistry: true,\n account_indentifier: '8-28',\n },\n SX: {},\n SY: {},\n SZ: {},\n TC: {},\n TD: {\n chars: 27,\n bban_regexp: '^[0-9]{23}$',\n },\n TF: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n TG: {\n chars: 28,\n bban_regexp: '^[A-Z]{2}[0-9]{22}$',\n },\n TH: {},\n TJ: {},\n TK: {},\n TL: {\n chars: 23,\n bban_regexp: '^[0-9]{19}$',\n IBANRegistry: true,\n account_indentifier: '4-23',\n },\n TM: {},\n TN: {\n chars: 24,\n bban_regexp: '^[0-9]{20}$',\n IBANRegistry: true,\n branch_indentifier: '2-4',\n account_indentifier: '4-24',\n },\n TO: {},\n TR: {\n chars: 26,\n bban_regexp: '^[0-9]{5}[A-Z0-9]{17}$',\n IBANRegistry: true,\n },\n TT: {},\n TV: {},\n TW: {},\n TZ: {},\n UA: {\n chars: 29,\n bban_regexp: '^[0-9]{6}[A-Z0-9]{19}$',\n IBANRegistry: true,\n account_indentifier: '15-29',\n },\n UG: {},\n UM: {},\n US: {},\n UY: {},\n UZ: {},\n VA: {\n chars: 22,\n bban_regexp: '^[0-9]{18}',\n IBANRegistry: true,\n SEPA: true,\n account_indentifier: '7-22',\n },\n VC: {},\n VE: {},\n VG: {\n chars: 24,\n bban_regexp: '^[A-Z0-9]{4}[0-9]{16}$',\n IBANRegistry: true,\n account_indentifier: '8-24',\n },\n VI: {},\n VN: {},\n VU: {},\n WF: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n WS: {},\n XK: {\n chars: 20,\n bban_regexp: '^[0-9]{16}$',\n IBANRegistry: true,\n branch_indentifier: '2-3',\n account_indentifier: '4-20',\n },\n YE: {},\n YT: {\n chars: 27,\n bban_regexp: '^[0-9]{10}[A-Z0-9]{11}[0-9]{2}$',\n IBANRegistry: true,\n },\n ZA: {},\n ZM: {},\n ZW: {},\n};\n", "import { Controller } from \"stimulus\";\nimport { isValidIBAN, friendlyFormatIBAN } from \"ibantools\";\n\nexport default class extends Controller {\n static targets = [\"iban\"];\n\n connect() {\n if (this.hasIbanTarget) {\n this.ibanTarget.innerText = friendlyFormatIBAN(this.ibanTarget.innerText);\n }\n }\n\n blur({ currentTarget }) {\n if (isValidIBAN(currentTarget.value.trim())) {\n currentTarget.value = friendlyFormatIBAN(currentTarget.value);\n }\n }\n\n // validate(iban)\n\n // append() {\n // const el = document.importNode(this.templateTarget.content, true);\n // this.containerTarget.appendChild(el);\n // }\n\n // appendBeforeLast() {\n // const el = document.importNode(this.templateTarget.content, true);\n // this.containerTarget.insertBefore(\n // el,\n // this.containerTarget.lastElementChild\n // );\n // }\n}\n", "import { Controller } from \"stimulus\";\n\nexport default class extends Controller {\n scroll() {\n this.element.scrollIntoView({\n behavior: \"smooth\",\n });\n }\n}\n", "import { Controller } from \"stimulus\";\n\nexport default class extends Controller {\n static targets = [\"toggleable\", \"widget\"];\n\n toggle() {\n this.toggleableTargets.forEach((t) => {\n t.classList.toggle(\"hidden\");\n });\n\n if (this.widgetTarget.innerHTML === \"\") {\n this.widgetTarget.innerHTML = ``;\n }\n }\n}\n", "/*\nTurbo 7.0.0\nCopyright \u00A9 2021 Basecamp, LLC\n */\n(function () {\n if (window.Reflect === undefined || window.customElements === undefined ||\n window.customElements.polyfillWrapFlushCallback) {\n return;\n }\n const BuiltInHTMLElement = HTMLElement;\n const wrapperForTheName = {\n 'HTMLElement': function HTMLElement() {\n return Reflect.construct(BuiltInHTMLElement, [], this.constructor);\n }\n };\n window.HTMLElement =\n wrapperForTheName['HTMLElement'];\n HTMLElement.prototype = BuiltInHTMLElement.prototype;\n HTMLElement.prototype.constructor = HTMLElement;\n Object.setPrototypeOf(HTMLElement, BuiltInHTMLElement);\n})();\n\nconst submittersByForm = new WeakMap;\nfunction findSubmitterFromClickTarget(target) {\n const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n const candidate = element ? element.closest(\"input, button\") : null;\n return (candidate === null || candidate === void 0 ? void 0 : candidate.type) == \"submit\" ? candidate : null;\n}\nfunction clickCaptured(event) {\n const submitter = findSubmitterFromClickTarget(event.target);\n if (submitter && submitter.form) {\n submittersByForm.set(submitter.form, submitter);\n }\n}\n(function () {\n if (\"submitter\" in Event.prototype)\n return;\n let prototype;\n if (\"SubmitEvent\" in window && /Apple Computer/.test(navigator.vendor)) {\n prototype = window.SubmitEvent.prototype;\n }\n else if (\"SubmitEvent\" in window) {\n return;\n }\n else {\n prototype = window.Event.prototype;\n }\n addEventListener(\"click\", clickCaptured, true);\n Object.defineProperty(prototype, \"submitter\", {\n get() {\n if (this.type == \"submit\" && this.target instanceof HTMLFormElement) {\n return submittersByForm.get(this.target);\n }\n }\n });\n})();\n\nvar FrameLoadingStyle;\n(function (FrameLoadingStyle) {\n FrameLoadingStyle[\"eager\"] = \"eager\";\n FrameLoadingStyle[\"lazy\"] = \"lazy\";\n})(FrameLoadingStyle || (FrameLoadingStyle = {}));\nclass FrameElement extends HTMLElement {\n constructor() {\n super();\n this.loaded = Promise.resolve();\n this.delegate = new FrameElement.delegateConstructor(this);\n }\n static get observedAttributes() {\n return [\"disabled\", \"loading\", \"src\"];\n }\n connectedCallback() {\n this.delegate.connect();\n }\n disconnectedCallback() {\n this.delegate.disconnect();\n }\n reload() {\n const { src } = this;\n this.src = null;\n this.src = src;\n }\n attributeChangedCallback(name) {\n if (name == \"loading\") {\n this.delegate.loadingStyleChanged();\n }\n else if (name == \"src\") {\n this.delegate.sourceURLChanged();\n }\n else {\n this.delegate.disabledChanged();\n }\n }\n get src() {\n return this.getAttribute(\"src\");\n }\n set src(value) {\n if (value) {\n this.setAttribute(\"src\", value);\n }\n else {\n this.removeAttribute(\"src\");\n }\n }\n get loading() {\n return frameLoadingStyleFromString(this.getAttribute(\"loading\") || \"\");\n }\n set loading(value) {\n if (value) {\n this.setAttribute(\"loading\", value);\n }\n else {\n this.removeAttribute(\"loading\");\n }\n }\n get disabled() {\n return this.hasAttribute(\"disabled\");\n }\n set disabled(value) {\n if (value) {\n this.setAttribute(\"disabled\", \"\");\n }\n else {\n this.removeAttribute(\"disabled\");\n }\n }\n get autoscroll() {\n return this.hasAttribute(\"autoscroll\");\n }\n set autoscroll(value) {\n if (value) {\n this.setAttribute(\"autoscroll\", \"\");\n }\n else {\n this.removeAttribute(\"autoscroll\");\n }\n }\n get complete() {\n return !this.delegate.isLoading;\n }\n get isActive() {\n return this.ownerDocument === document && !this.isPreview;\n }\n get isPreview() {\n var _a, _b;\n return (_b = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.documentElement) === null || _b === void 0 ? void 0 : _b.hasAttribute(\"data-turbo-preview\");\n }\n}\nfunction frameLoadingStyleFromString(style) {\n switch (style.toLowerCase()) {\n case \"lazy\": return FrameLoadingStyle.lazy;\n default: return FrameLoadingStyle.eager;\n }\n}\n\nfunction expandURL(locatable) {\n return new URL(locatable.toString(), document.baseURI);\n}\nfunction getAnchor(url) {\n let anchorMatch;\n if (url.hash) {\n return url.hash.slice(1);\n }\n else if (anchorMatch = url.href.match(/#(.*)$/)) {\n return anchorMatch[1];\n }\n}\nfunction getExtension(url) {\n return (getLastPathComponent(url).match(/\\.[^.]*$/) || [])[0] || \"\";\n}\nfunction isHTML(url) {\n return !!getExtension(url).match(/^(?:|\\.(?:htm|html|xhtml))$/);\n}\nfunction isPrefixedBy(baseURL, url) {\n const prefix = getPrefix(url);\n return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix);\n}\nfunction getRequestURL(url) {\n const anchor = getAnchor(url);\n return anchor != null\n ? url.href.slice(0, -(anchor.length + 1))\n : url.href;\n}\nfunction toCacheKey(url) {\n return getRequestURL(url);\n}\nfunction urlsAreEqual(left, right) {\n return expandURL(left).href == expandURL(right).href;\n}\nfunction getPathComponents(url) {\n return url.pathname.split(\"/\").slice(1);\n}\nfunction getLastPathComponent(url) {\n return getPathComponents(url).slice(-1)[0];\n}\nfunction getPrefix(url) {\n return addTrailingSlash(url.origin + url.pathname);\n}\nfunction addTrailingSlash(value) {\n return value.endsWith(\"/\") ? value : value + \"/\";\n}\n\nclass FetchResponse {\n constructor(response) {\n this.response = response;\n }\n get succeeded() {\n return this.response.ok;\n }\n get failed() {\n return !this.succeeded;\n }\n get clientError() {\n return this.statusCode >= 400 && this.statusCode <= 499;\n }\n get serverError() {\n return this.statusCode >= 500 && this.statusCode <= 599;\n }\n get redirected() {\n return this.response.redirected;\n }\n get location() {\n return expandURL(this.response.url);\n }\n get isHTML() {\n return this.contentType && this.contentType.match(/^(?:text\\/([^\\s;,]+\\b)?html|application\\/xhtml\\+xml)\\b/);\n }\n get statusCode() {\n return this.response.status;\n }\n get contentType() {\n return this.header(\"Content-Type\");\n }\n get responseText() {\n return this.response.clone().text();\n }\n get responseHTML() {\n if (this.isHTML) {\n return this.response.clone().text();\n }\n else {\n return Promise.resolve(undefined);\n }\n }\n header(name) {\n return this.response.headers.get(name);\n }\n}\n\nfunction dispatch(eventName, { target, cancelable, detail } = {}) {\n const event = new CustomEvent(eventName, { cancelable, bubbles: true, detail });\n if (target && target.isConnected) {\n target.dispatchEvent(event);\n }\n else {\n document.documentElement.dispatchEvent(event);\n }\n return event;\n}\nfunction nextAnimationFrame() {\n return new Promise(resolve => requestAnimationFrame(() => resolve()));\n}\nfunction nextEventLoopTick() {\n return new Promise(resolve => setTimeout(() => resolve(), 0));\n}\nfunction nextMicrotask() {\n return Promise.resolve();\n}\nfunction parseHTMLDocument(html = \"\") {\n return new DOMParser().parseFromString(html, \"text/html\");\n}\nfunction unindent(strings, ...values) {\n const lines = interpolate(strings, values).replace(/^\\n/, \"\").split(\"\\n\");\n const match = lines[0].match(/^\\s+/);\n const indent = match ? match[0].length : 0;\n return lines.map(line => line.slice(indent)).join(\"\\n\");\n}\nfunction interpolate(strings, values) {\n return strings.reduce((result, string, i) => {\n const value = values[i] == undefined ? \"\" : values[i];\n return result + string + value;\n }, \"\");\n}\nfunction uuid() {\n return Array.apply(null, { length: 36 }).map((_, i) => {\n if (i == 8 || i == 13 || i == 18 || i == 23) {\n return \"-\";\n }\n else if (i == 14) {\n return \"4\";\n }\n else if (i == 19) {\n return (Math.floor(Math.random() * 4) + 8).toString(16);\n }\n else {\n return Math.floor(Math.random() * 15).toString(16);\n }\n }).join(\"\");\n}\n\nvar FetchMethod;\n(function (FetchMethod) {\n FetchMethod[FetchMethod[\"get\"] = 0] = \"get\";\n FetchMethod[FetchMethod[\"post\"] = 1] = \"post\";\n FetchMethod[FetchMethod[\"put\"] = 2] = \"put\";\n FetchMethod[FetchMethod[\"patch\"] = 3] = \"patch\";\n FetchMethod[FetchMethod[\"delete\"] = 4] = \"delete\";\n})(FetchMethod || (FetchMethod = {}));\nfunction fetchMethodFromString(method) {\n switch (method.toLowerCase()) {\n case \"get\": return FetchMethod.get;\n case \"post\": return FetchMethod.post;\n case \"put\": return FetchMethod.put;\n case \"patch\": return FetchMethod.patch;\n case \"delete\": return FetchMethod.delete;\n }\n}\nclass FetchRequest {\n constructor(delegate, method, location, body = new URLSearchParams, target = null) {\n this.abortController = new AbortController;\n this.resolveRequestPromise = (value) => { };\n this.delegate = delegate;\n this.method = method;\n this.headers = this.defaultHeaders;\n if (this.isIdempotent) {\n this.url = mergeFormDataEntries(location, [...body.entries()]);\n }\n else {\n this.body = body;\n this.url = location;\n }\n this.target = target;\n }\n get location() {\n return this.url;\n }\n get params() {\n return this.url.searchParams;\n }\n get entries() {\n return this.body ? Array.from(this.body.entries()) : [];\n }\n cancel() {\n this.abortController.abort();\n }\n async perform() {\n var _a, _b;\n const { fetchOptions } = this;\n (_b = (_a = this.delegate).prepareHeadersForRequest) === null || _b === void 0 ? void 0 : _b.call(_a, this.headers, this);\n await this.allowRequestToBeIntercepted(fetchOptions);\n try {\n this.delegate.requestStarted(this);\n const response = await fetch(this.url.href, fetchOptions);\n return await this.receive(response);\n }\n catch (error) {\n if (error.name !== 'AbortError') {\n this.delegate.requestErrored(this, error);\n throw error;\n }\n }\n finally {\n this.delegate.requestFinished(this);\n }\n }\n async receive(response) {\n const fetchResponse = new FetchResponse(response);\n const event = dispatch(\"turbo:before-fetch-response\", { cancelable: true, detail: { fetchResponse }, target: this.target });\n if (event.defaultPrevented) {\n this.delegate.requestPreventedHandlingResponse(this, fetchResponse);\n }\n else if (fetchResponse.succeeded) {\n this.delegate.requestSucceededWithResponse(this, fetchResponse);\n }\n else {\n this.delegate.requestFailedWithResponse(this, fetchResponse);\n }\n return fetchResponse;\n }\n get fetchOptions() {\n var _a;\n return {\n method: FetchMethod[this.method].toUpperCase(),\n credentials: \"same-origin\",\n headers: this.headers,\n redirect: \"follow\",\n body: this.body,\n signal: this.abortSignal,\n referrer: (_a = this.delegate.referrer) === null || _a === void 0 ? void 0 : _a.href\n };\n }\n get defaultHeaders() {\n return {\n \"Accept\": \"text/html, application/xhtml+xml\"\n };\n }\n get isIdempotent() {\n return this.method == FetchMethod.get;\n }\n get abortSignal() {\n return this.abortController.signal;\n }\n async allowRequestToBeIntercepted(fetchOptions) {\n const requestInterception = new Promise(resolve => this.resolveRequestPromise = resolve);\n const event = dispatch(\"turbo:before-fetch-request\", {\n cancelable: true,\n detail: {\n fetchOptions,\n url: this.url.href,\n resume: this.resolveRequestPromise\n },\n target: this.target\n });\n if (event.defaultPrevented)\n await requestInterception;\n }\n}\nfunction mergeFormDataEntries(url, entries) {\n const currentSearchParams = new URLSearchParams(url.search);\n for (const [name, value] of entries) {\n if (value instanceof File)\n continue;\n if (currentSearchParams.has(name)) {\n currentSearchParams.delete(name);\n url.searchParams.set(name, value);\n }\n else {\n url.searchParams.append(name, value);\n }\n }\n return url;\n}\n\nclass AppearanceObserver {\n constructor(delegate, element) {\n this.started = false;\n this.intersect = entries => {\n const lastEntry = entries.slice(-1)[0];\n if (lastEntry === null || lastEntry === void 0 ? void 0 : lastEntry.isIntersecting) {\n this.delegate.elementAppearedInViewport(this.element);\n }\n };\n this.delegate = delegate;\n this.element = element;\n this.intersectionObserver = new IntersectionObserver(this.intersect);\n }\n start() {\n if (!this.started) {\n this.started = true;\n this.intersectionObserver.observe(this.element);\n }\n }\n stop() {\n if (this.started) {\n this.started = false;\n this.intersectionObserver.unobserve(this.element);\n }\n }\n}\n\nclass StreamMessage {\n constructor(html) {\n this.templateElement = document.createElement(\"template\");\n this.templateElement.innerHTML = html;\n }\n static wrap(message) {\n if (typeof message == \"string\") {\n return new this(message);\n }\n else {\n return message;\n }\n }\n get fragment() {\n const fragment = document.createDocumentFragment();\n for (const element of this.foreignElements) {\n fragment.appendChild(document.importNode(element, true));\n }\n return fragment;\n }\n get foreignElements() {\n return this.templateChildren.reduce((streamElements, child) => {\n if (child.tagName.toLowerCase() == \"turbo-stream\") {\n return [...streamElements, child];\n }\n else {\n return streamElements;\n }\n }, []);\n }\n get templateChildren() {\n return Array.from(this.templateElement.content.children);\n }\n}\nStreamMessage.contentType = \"text/vnd.turbo-stream.html\";\n\nvar FormSubmissionState;\n(function (FormSubmissionState) {\n FormSubmissionState[FormSubmissionState[\"initialized\"] = 0] = \"initialized\";\n FormSubmissionState[FormSubmissionState[\"requesting\"] = 1] = \"requesting\";\n FormSubmissionState[FormSubmissionState[\"waiting\"] = 2] = \"waiting\";\n FormSubmissionState[FormSubmissionState[\"receiving\"] = 3] = \"receiving\";\n FormSubmissionState[FormSubmissionState[\"stopping\"] = 4] = \"stopping\";\n FormSubmissionState[FormSubmissionState[\"stopped\"] = 5] = \"stopped\";\n})(FormSubmissionState || (FormSubmissionState = {}));\nvar FormEnctype;\n(function (FormEnctype) {\n FormEnctype[\"urlEncoded\"] = \"application/x-www-form-urlencoded\";\n FormEnctype[\"multipart\"] = \"multipart/form-data\";\n FormEnctype[\"plain\"] = \"text/plain\";\n})(FormEnctype || (FormEnctype = {}));\nfunction formEnctypeFromString(encoding) {\n switch (encoding.toLowerCase()) {\n case FormEnctype.multipart: return FormEnctype.multipart;\n case FormEnctype.plain: return FormEnctype.plain;\n default: return FormEnctype.urlEncoded;\n }\n}\nclass FormSubmission {\n constructor(delegate, formElement, submitter, mustRedirect = false) {\n this.state = FormSubmissionState.initialized;\n this.delegate = delegate;\n this.formElement = formElement;\n this.submitter = submitter;\n this.formData = buildFormData(formElement, submitter);\n this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement);\n this.mustRedirect = mustRedirect;\n }\n get method() {\n var _a;\n const method = ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute(\"formmethod\")) || this.formElement.getAttribute(\"method\") || \"\";\n return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get;\n }\n get action() {\n var _a;\n const formElementAction = typeof this.formElement.action === 'string' ? this.formElement.action : null;\n return ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute(\"formaction\")) || this.formElement.getAttribute(\"action\") || formElementAction || \"\";\n }\n get location() {\n return expandURL(this.action);\n }\n get body() {\n if (this.enctype == FormEnctype.urlEncoded || this.method == FetchMethod.get) {\n return new URLSearchParams(this.stringFormData);\n }\n else {\n return this.formData;\n }\n }\n get enctype() {\n var _a;\n return formEnctypeFromString(((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute(\"formenctype\")) || this.formElement.enctype);\n }\n get isIdempotent() {\n return this.fetchRequest.isIdempotent;\n }\n get stringFormData() {\n return [...this.formData].reduce((entries, [name, value]) => {\n return entries.concat(typeof value == \"string\" ? [[name, value]] : []);\n }, []);\n }\n async start() {\n const { initialized, requesting } = FormSubmissionState;\n if (this.state == initialized) {\n this.state = requesting;\n return this.fetchRequest.perform();\n }\n }\n stop() {\n const { stopping, stopped } = FormSubmissionState;\n if (this.state != stopping && this.state != stopped) {\n this.state = stopping;\n this.fetchRequest.cancel();\n return true;\n }\n }\n prepareHeadersForRequest(headers, request) {\n if (!request.isIdempotent) {\n const token = getCookieValue(getMetaContent(\"csrf-param\")) || getMetaContent(\"csrf-token\");\n if (token) {\n headers[\"X-CSRF-Token\"] = token;\n }\n headers[\"Accept\"] = [StreamMessage.contentType, headers[\"Accept\"]].join(\", \");\n }\n }\n requestStarted(request) {\n this.state = FormSubmissionState.waiting;\n dispatch(\"turbo:submit-start\", { target: this.formElement, detail: { formSubmission: this } });\n this.delegate.formSubmissionStarted(this);\n }\n requestPreventedHandlingResponse(request, response) {\n this.result = { success: response.succeeded, fetchResponse: response };\n }\n requestSucceededWithResponse(request, response) {\n if (response.clientError || response.serverError) {\n this.delegate.formSubmissionFailedWithResponse(this, response);\n }\n else if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) {\n const error = new Error(\"Form responses must redirect to another location\");\n this.delegate.formSubmissionErrored(this, error);\n }\n else {\n this.state = FormSubmissionState.receiving;\n this.result = { success: true, fetchResponse: response };\n this.delegate.formSubmissionSucceededWithResponse(this, response);\n }\n }\n requestFailedWithResponse(request, response) {\n this.result = { success: false, fetchResponse: response };\n this.delegate.formSubmissionFailedWithResponse(this, response);\n }\n requestErrored(request, error) {\n this.result = { success: false, error };\n this.delegate.formSubmissionErrored(this, error);\n }\n requestFinished(request) {\n this.state = FormSubmissionState.stopped;\n dispatch(\"turbo:submit-end\", { target: this.formElement, detail: Object.assign({ formSubmission: this }, this.result) });\n this.delegate.formSubmissionFinished(this);\n }\n requestMustRedirect(request) {\n return !request.isIdempotent && this.mustRedirect;\n }\n}\nfunction buildFormData(formElement, submitter) {\n const formData = new FormData(formElement);\n const name = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute(\"name\");\n const value = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute(\"value\");\n if (name && value != null && formData.get(name) != value) {\n formData.append(name, value);\n }\n return formData;\n}\nfunction getCookieValue(cookieName) {\n if (cookieName != null) {\n const cookies = document.cookie ? document.cookie.split(\"; \") : [];\n const cookie = cookies.find((cookie) => cookie.startsWith(cookieName));\n if (cookie) {\n const value = cookie.split(\"=\").slice(1).join(\"=\");\n return value ? decodeURIComponent(value) : undefined;\n }\n }\n}\nfunction getMetaContent(name) {\n const element = document.querySelector(`meta[name=\"${name}\"]`);\n return element && element.content;\n}\nfunction responseSucceededWithoutRedirect(response) {\n return response.statusCode == 200 && !response.redirected;\n}\n\nclass Snapshot {\n constructor(element) {\n this.element = element;\n }\n get children() {\n return [...this.element.children];\n }\n hasAnchor(anchor) {\n return this.getElementForAnchor(anchor) != null;\n }\n getElementForAnchor(anchor) {\n return anchor ? this.element.querySelector(`[id='${anchor}'], a[name='${anchor}']`) : null;\n }\n get isConnected() {\n return this.element.isConnected;\n }\n get firstAutofocusableElement() {\n return this.element.querySelector(\"[autofocus]\");\n }\n get permanentElements() {\n return [...this.element.querySelectorAll(\"[id][data-turbo-permanent]\")];\n }\n getPermanentElementById(id) {\n return this.element.querySelector(`#${id}[data-turbo-permanent]`);\n }\n getPermanentElementMapForSnapshot(snapshot) {\n const permanentElementMap = {};\n for (const currentPermanentElement of this.permanentElements) {\n const { id } = currentPermanentElement;\n const newPermanentElement = snapshot.getPermanentElementById(id);\n if (newPermanentElement) {\n permanentElementMap[id] = [currentPermanentElement, newPermanentElement];\n }\n }\n return permanentElementMap;\n }\n}\n\nclass FormInterceptor {\n constructor(delegate, element) {\n this.submitBubbled = ((event) => {\n const form = event.target;\n if (form instanceof HTMLFormElement && form.closest(\"turbo-frame, html\") == this.element) {\n const submitter = event.submitter || undefined;\n if (this.delegate.shouldInterceptFormSubmission(form, submitter)) {\n event.preventDefault();\n event.stopImmediatePropagation();\n this.delegate.formSubmissionIntercepted(form, submitter);\n }\n }\n });\n this.delegate = delegate;\n this.element = element;\n }\n start() {\n this.element.addEventListener(\"submit\", this.submitBubbled);\n }\n stop() {\n this.element.removeEventListener(\"submit\", this.submitBubbled);\n }\n}\n\nclass View {\n constructor(delegate, element) {\n this.resolveRenderPromise = (value) => { };\n this.resolveInterceptionPromise = (value) => { };\n this.delegate = delegate;\n this.element = element;\n }\n scrollToAnchor(anchor) {\n const element = this.snapshot.getElementForAnchor(anchor);\n if (element) {\n this.scrollToElement(element);\n this.focusElement(element);\n }\n else {\n this.scrollToPosition({ x: 0, y: 0 });\n }\n }\n scrollToAnchorFromLocation(location) {\n this.scrollToAnchor(getAnchor(location));\n }\n scrollToElement(element) {\n element.scrollIntoView();\n }\n focusElement(element) {\n if (element instanceof HTMLElement) {\n if (element.hasAttribute(\"tabindex\")) {\n element.focus();\n }\n else {\n element.setAttribute(\"tabindex\", \"-1\");\n element.focus();\n element.removeAttribute(\"tabindex\");\n }\n }\n }\n scrollToPosition({ x, y }) {\n this.scrollRoot.scrollTo(x, y);\n }\n scrollToTop() {\n this.scrollToPosition({ x: 0, y: 0 });\n }\n get scrollRoot() {\n return window;\n }\n async render(renderer) {\n const { isPreview, shouldRender, newSnapshot: snapshot } = renderer;\n if (shouldRender) {\n try {\n this.renderPromise = new Promise(resolve => this.resolveRenderPromise = resolve);\n this.renderer = renderer;\n this.prepareToRenderSnapshot(renderer);\n const renderInterception = new Promise(resolve => this.resolveInterceptionPromise = resolve);\n const immediateRender = this.delegate.allowsImmediateRender(snapshot, this.resolveInterceptionPromise);\n if (!immediateRender)\n await renderInterception;\n await this.renderSnapshot(renderer);\n this.delegate.viewRenderedSnapshot(snapshot, isPreview);\n this.finishRenderingSnapshot(renderer);\n }\n finally {\n delete this.renderer;\n this.resolveRenderPromise(undefined);\n delete this.renderPromise;\n }\n }\n else {\n this.invalidate();\n }\n }\n invalidate() {\n this.delegate.viewInvalidated();\n }\n prepareToRenderSnapshot(renderer) {\n this.markAsPreview(renderer.isPreview);\n renderer.prepareToRender();\n }\n markAsPreview(isPreview) {\n if (isPreview) {\n this.element.setAttribute(\"data-turbo-preview\", \"\");\n }\n else {\n this.element.removeAttribute(\"data-turbo-preview\");\n }\n }\n async renderSnapshot(renderer) {\n await renderer.render();\n }\n finishRenderingSnapshot(renderer) {\n renderer.finishRendering();\n }\n}\n\nclass FrameView extends View {\n invalidate() {\n this.element.innerHTML = \"\";\n }\n get snapshot() {\n return new Snapshot(this.element);\n }\n}\n\nclass LinkInterceptor {\n constructor(delegate, element) {\n this.clickBubbled = (event) => {\n if (this.respondsToEventTarget(event.target)) {\n this.clickEvent = event;\n }\n else {\n delete this.clickEvent;\n }\n };\n this.linkClicked = ((event) => {\n if (this.clickEvent && this.respondsToEventTarget(event.target) && event.target instanceof Element) {\n if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url)) {\n this.clickEvent.preventDefault();\n event.preventDefault();\n this.delegate.linkClickIntercepted(event.target, event.detail.url);\n }\n }\n delete this.clickEvent;\n });\n this.willVisit = () => {\n delete this.clickEvent;\n };\n this.delegate = delegate;\n this.element = element;\n }\n start() {\n this.element.addEventListener(\"click\", this.clickBubbled);\n document.addEventListener(\"turbo:click\", this.linkClicked);\n document.addEventListener(\"turbo:before-visit\", this.willVisit);\n }\n stop() {\n this.element.removeEventListener(\"click\", this.clickBubbled);\n document.removeEventListener(\"turbo:click\", this.linkClicked);\n document.removeEventListener(\"turbo:before-visit\", this.willVisit);\n }\n respondsToEventTarget(target) {\n const element = target instanceof Element\n ? target\n : target instanceof Node\n ? target.parentElement\n : null;\n return element && element.closest(\"turbo-frame, html\") == this.element;\n }\n}\n\nclass Bardo {\n constructor(permanentElementMap) {\n this.permanentElementMap = permanentElementMap;\n }\n static preservingPermanentElements(permanentElementMap, callback) {\n const bardo = new this(permanentElementMap);\n bardo.enter();\n callback();\n bardo.leave();\n }\n enter() {\n for (const id in this.permanentElementMap) {\n const [, newPermanentElement] = this.permanentElementMap[id];\n this.replaceNewPermanentElementWithPlaceholder(newPermanentElement);\n }\n }\n leave() {\n for (const id in this.permanentElementMap) {\n const [currentPermanentElement] = this.permanentElementMap[id];\n this.replaceCurrentPermanentElementWithClone(currentPermanentElement);\n this.replacePlaceholderWithPermanentElement(currentPermanentElement);\n }\n }\n replaceNewPermanentElementWithPlaceholder(permanentElement) {\n const placeholder = createPlaceholderForPermanentElement(permanentElement);\n permanentElement.replaceWith(placeholder);\n }\n replaceCurrentPermanentElementWithClone(permanentElement) {\n const clone = permanentElement.cloneNode(true);\n permanentElement.replaceWith(clone);\n }\n replacePlaceholderWithPermanentElement(permanentElement) {\n const placeholder = this.getPlaceholderById(permanentElement.id);\n placeholder === null || placeholder === void 0 ? void 0 : placeholder.replaceWith(permanentElement);\n }\n getPlaceholderById(id) {\n return this.placeholders.find(element => element.content == id);\n }\n get placeholders() {\n return [...document.querySelectorAll(\"meta[name=turbo-permanent-placeholder][content]\")];\n }\n}\nfunction createPlaceholderForPermanentElement(permanentElement) {\n const element = document.createElement(\"meta\");\n element.setAttribute(\"name\", \"turbo-permanent-placeholder\");\n element.setAttribute(\"content\", permanentElement.id);\n return element;\n}\n\nclass Renderer {\n constructor(currentSnapshot, newSnapshot, isPreview) {\n this.currentSnapshot = currentSnapshot;\n this.newSnapshot = newSnapshot;\n this.isPreview = isPreview;\n this.promise = new Promise((resolve, reject) => this.resolvingFunctions = { resolve, reject });\n }\n get shouldRender() {\n return true;\n }\n prepareToRender() {\n return;\n }\n finishRendering() {\n if (this.resolvingFunctions) {\n this.resolvingFunctions.resolve();\n delete this.resolvingFunctions;\n }\n }\n createScriptElement(element) {\n if (element.getAttribute(\"data-turbo-eval\") == \"false\") {\n return element;\n }\n else {\n const createdScriptElement = document.createElement(\"script\");\n if (this.cspNonce) {\n createdScriptElement.nonce = this.cspNonce;\n }\n createdScriptElement.textContent = element.textContent;\n createdScriptElement.async = false;\n copyElementAttributes(createdScriptElement, element);\n return createdScriptElement;\n }\n }\n preservingPermanentElements(callback) {\n Bardo.preservingPermanentElements(this.permanentElementMap, callback);\n }\n focusFirstAutofocusableElement() {\n const element = this.connectedSnapshot.firstAutofocusableElement;\n if (elementIsFocusable(element)) {\n element.focus();\n }\n }\n get connectedSnapshot() {\n return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot;\n }\n get currentElement() {\n return this.currentSnapshot.element;\n }\n get newElement() {\n return this.newSnapshot.element;\n }\n get permanentElementMap() {\n return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot);\n }\n get cspNonce() {\n var _a;\n return (_a = document.head.querySelector('meta[name=\"csp-nonce\"]')) === null || _a === void 0 ? void 0 : _a.getAttribute(\"content\");\n }\n}\nfunction copyElementAttributes(destinationElement, sourceElement) {\n for (const { name, value } of [...sourceElement.attributes]) {\n destinationElement.setAttribute(name, value);\n }\n}\nfunction elementIsFocusable(element) {\n return element && typeof element.focus == \"function\";\n}\n\nclass FrameRenderer extends Renderer {\n get shouldRender() {\n return true;\n }\n async render() {\n await nextAnimationFrame();\n this.preservingPermanentElements(() => {\n this.loadFrameElement();\n });\n this.scrollFrameIntoView();\n await nextAnimationFrame();\n this.focusFirstAutofocusableElement();\n await nextAnimationFrame();\n this.activateScriptElements();\n }\n loadFrameElement() {\n var _a;\n const destinationRange = document.createRange();\n destinationRange.selectNodeContents(this.currentElement);\n destinationRange.deleteContents();\n const frameElement = this.newElement;\n const sourceRange = (_a = frameElement.ownerDocument) === null || _a === void 0 ? void 0 : _a.createRange();\n if (sourceRange) {\n sourceRange.selectNodeContents(frameElement);\n this.currentElement.appendChild(sourceRange.extractContents());\n }\n }\n scrollFrameIntoView() {\n if (this.currentElement.autoscroll || this.newElement.autoscroll) {\n const element = this.currentElement.firstElementChild;\n const block = readScrollLogicalPosition(this.currentElement.getAttribute(\"data-autoscroll-block\"), \"end\");\n if (element) {\n element.scrollIntoView({ block });\n return true;\n }\n }\n return false;\n }\n activateScriptElements() {\n for (const inertScriptElement of this.newScriptElements) {\n const activatedScriptElement = this.createScriptElement(inertScriptElement);\n inertScriptElement.replaceWith(activatedScriptElement);\n }\n }\n get newScriptElements() {\n return this.currentElement.querySelectorAll(\"script\");\n }\n}\nfunction readScrollLogicalPosition(value, defaultValue) {\n if (value == \"end\" || value == \"start\" || value == \"center\" || value == \"nearest\") {\n return value;\n }\n else {\n return defaultValue;\n }\n}\n\nclass ProgressBar {\n constructor() {\n this.hiding = false;\n this.value = 0;\n this.visible = false;\n this.trickle = () => {\n this.setValue(this.value + Math.random() / 100);\n };\n this.stylesheetElement = this.createStylesheetElement();\n this.progressElement = this.createProgressElement();\n this.installStylesheetElement();\n this.setValue(0);\n }\n static get defaultCSS() {\n return unindent `\n .turbo-progress-bar {\n position: fixed;\n display: block;\n top: 0;\n left: 0;\n height: 3px;\n background: #0076ff;\n z-index: 9999;\n transition:\n width ${ProgressBar.animationDuration}ms ease-out,\n opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in;\n transform: translate3d(0, 0, 0);\n }\n `;\n }\n show() {\n if (!this.visible) {\n this.visible = true;\n this.installProgressElement();\n this.startTrickling();\n }\n }\n hide() {\n if (this.visible && !this.hiding) {\n this.hiding = true;\n this.fadeProgressElement(() => {\n this.uninstallProgressElement();\n this.stopTrickling();\n this.visible = false;\n this.hiding = false;\n });\n }\n }\n setValue(value) {\n this.value = value;\n this.refresh();\n }\n installStylesheetElement() {\n document.head.insertBefore(this.stylesheetElement, document.head.firstChild);\n }\n installProgressElement() {\n this.progressElement.style.width = \"0\";\n this.progressElement.style.opacity = \"1\";\n document.documentElement.insertBefore(this.progressElement, document.body);\n this.refresh();\n }\n fadeProgressElement(callback) {\n this.progressElement.style.opacity = \"0\";\n setTimeout(callback, ProgressBar.animationDuration * 1.5);\n }\n uninstallProgressElement() {\n if (this.progressElement.parentNode) {\n document.documentElement.removeChild(this.progressElement);\n }\n }\n startTrickling() {\n if (!this.trickleInterval) {\n this.trickleInterval = window.setInterval(this.trickle, ProgressBar.animationDuration);\n }\n }\n stopTrickling() {\n window.clearInterval(this.trickleInterval);\n delete this.trickleInterval;\n }\n refresh() {\n requestAnimationFrame(() => {\n this.progressElement.style.width = `${10 + (this.value * 90)}%`;\n });\n }\n createStylesheetElement() {\n const element = document.createElement(\"style\");\n element.type = \"text/css\";\n element.textContent = ProgressBar.defaultCSS;\n return element;\n }\n createProgressElement() {\n const element = document.createElement(\"div\");\n element.className = \"turbo-progress-bar\";\n return element;\n }\n}\nProgressBar.animationDuration = 300;\n\nclass HeadSnapshot extends Snapshot {\n constructor() {\n super(...arguments);\n this.detailsByOuterHTML = this.children\n .filter((element) => !elementIsNoscript(element))\n .map((element) => elementWithoutNonce(element))\n .reduce((result, element) => {\n const { outerHTML } = element;\n const details = outerHTML in result\n ? result[outerHTML]\n : {\n type: elementType(element),\n tracked: elementIsTracked(element),\n elements: []\n };\n return Object.assign(Object.assign({}, result), { [outerHTML]: Object.assign(Object.assign({}, details), { elements: [...details.elements, element] }) });\n }, {});\n }\n get trackedElementSignature() {\n return Object.keys(this.detailsByOuterHTML)\n .filter(outerHTML => this.detailsByOuterHTML[outerHTML].tracked)\n .join(\"\");\n }\n getScriptElementsNotInSnapshot(snapshot) {\n return this.getElementsMatchingTypeNotInSnapshot(\"script\", snapshot);\n }\n getStylesheetElementsNotInSnapshot(snapshot) {\n return this.getElementsMatchingTypeNotInSnapshot(\"stylesheet\", snapshot);\n }\n getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) {\n return Object.keys(this.detailsByOuterHTML)\n .filter(outerHTML => !(outerHTML in snapshot.detailsByOuterHTML))\n .map(outerHTML => this.detailsByOuterHTML[outerHTML])\n .filter(({ type }) => type == matchedType)\n .map(({ elements: [element] }) => element);\n }\n get provisionalElements() {\n return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {\n const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML];\n if (type == null && !tracked) {\n return [...result, ...elements];\n }\n else if (elements.length > 1) {\n return [...result, ...elements.slice(1)];\n }\n else {\n return result;\n }\n }, []);\n }\n getMetaValue(name) {\n const element = this.findMetaElementByName(name);\n return element\n ? element.getAttribute(\"content\")\n : null;\n }\n findMetaElementByName(name) {\n return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {\n const { elements: [element] } = this.detailsByOuterHTML[outerHTML];\n return elementIsMetaElementWithName(element, name) ? element : result;\n }, undefined);\n }\n}\nfunction elementType(element) {\n if (elementIsScript(element)) {\n return \"script\";\n }\n else if (elementIsStylesheet(element)) {\n return \"stylesheet\";\n }\n}\nfunction elementIsTracked(element) {\n return element.getAttribute(\"data-turbo-track\") == \"reload\";\n}\nfunction elementIsScript(element) {\n const tagName = element.tagName.toLowerCase();\n return tagName == \"script\";\n}\nfunction elementIsNoscript(element) {\n const tagName = element.tagName.toLowerCase();\n return tagName == \"noscript\";\n}\nfunction elementIsStylesheet(element) {\n const tagName = element.tagName.toLowerCase();\n return tagName == \"style\" || (tagName == \"link\" && element.getAttribute(\"rel\") == \"stylesheet\");\n}\nfunction elementIsMetaElementWithName(element, name) {\n const tagName = element.tagName.toLowerCase();\n return tagName == \"meta\" && element.getAttribute(\"name\") == name;\n}\nfunction elementWithoutNonce(element) {\n if (element.hasAttribute(\"nonce\")) {\n element.setAttribute(\"nonce\", \"\");\n }\n return element;\n}\n\nclass PageSnapshot extends Snapshot {\n constructor(element, headSnapshot) {\n super(element);\n this.headSnapshot = headSnapshot;\n }\n static fromHTMLString(html = \"\") {\n return this.fromDocument(parseHTMLDocument(html));\n }\n static fromElement(element) {\n return this.fromDocument(element.ownerDocument);\n }\n static fromDocument({ head, body }) {\n return new this(body, new HeadSnapshot(head));\n }\n clone() {\n return new PageSnapshot(this.element.cloneNode(true), this.headSnapshot);\n }\n get headElement() {\n return this.headSnapshot.element;\n }\n get rootLocation() {\n var _a;\n const root = (_a = this.getSetting(\"root\")) !== null && _a !== void 0 ? _a : \"/\";\n return expandURL(root);\n }\n get cacheControlValue() {\n return this.getSetting(\"cache-control\");\n }\n get isPreviewable() {\n return this.cacheControlValue != \"no-preview\";\n }\n get isCacheable() {\n return this.cacheControlValue != \"no-cache\";\n }\n get isVisitable() {\n return this.getSetting(\"visit-control\") != \"reload\";\n }\n getSetting(name) {\n return this.headSnapshot.getMetaValue(`turbo-${name}`);\n }\n}\n\nvar TimingMetric;\n(function (TimingMetric) {\n TimingMetric[\"visitStart\"] = \"visitStart\";\n TimingMetric[\"requestStart\"] = \"requestStart\";\n TimingMetric[\"requestEnd\"] = \"requestEnd\";\n TimingMetric[\"visitEnd\"] = \"visitEnd\";\n})(TimingMetric || (TimingMetric = {}));\nvar VisitState;\n(function (VisitState) {\n VisitState[\"initialized\"] = \"initialized\";\n VisitState[\"started\"] = \"started\";\n VisitState[\"canceled\"] = \"canceled\";\n VisitState[\"failed\"] = \"failed\";\n VisitState[\"completed\"] = \"completed\";\n})(VisitState || (VisitState = {}));\nconst defaultOptions = {\n action: \"advance\",\n historyChanged: false\n};\nvar SystemStatusCode;\n(function (SystemStatusCode) {\n SystemStatusCode[SystemStatusCode[\"networkFailure\"] = 0] = \"networkFailure\";\n SystemStatusCode[SystemStatusCode[\"timeoutFailure\"] = -1] = \"timeoutFailure\";\n SystemStatusCode[SystemStatusCode[\"contentTypeMismatch\"] = -2] = \"contentTypeMismatch\";\n})(SystemStatusCode || (SystemStatusCode = {}));\nclass Visit {\n constructor(delegate, location, restorationIdentifier, options = {}) {\n this.identifier = uuid();\n this.timingMetrics = {};\n this.followedRedirect = false;\n this.historyChanged = false;\n this.scrolled = false;\n this.snapshotCached = false;\n this.state = VisitState.initialized;\n this.delegate = delegate;\n this.location = location;\n this.restorationIdentifier = restorationIdentifier || uuid();\n const { action, historyChanged, referrer, snapshotHTML, response } = Object.assign(Object.assign({}, defaultOptions), options);\n this.action = action;\n this.historyChanged = historyChanged;\n this.referrer = referrer;\n this.snapshotHTML = snapshotHTML;\n this.response = response;\n this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);\n }\n get adapter() {\n return this.delegate.adapter;\n }\n get view() {\n return this.delegate.view;\n }\n get history() {\n return this.delegate.history;\n }\n get restorationData() {\n return this.history.getRestorationDataForIdentifier(this.restorationIdentifier);\n }\n get silent() {\n return this.isSamePage;\n }\n start() {\n if (this.state == VisitState.initialized) {\n this.recordTimingMetric(TimingMetric.visitStart);\n this.state = VisitState.started;\n this.adapter.visitStarted(this);\n this.delegate.visitStarted(this);\n }\n }\n cancel() {\n if (this.state == VisitState.started) {\n if (this.request) {\n this.request.cancel();\n }\n this.cancelRender();\n this.state = VisitState.canceled;\n }\n }\n complete() {\n if (this.state == VisitState.started) {\n this.recordTimingMetric(TimingMetric.visitEnd);\n this.state = VisitState.completed;\n this.adapter.visitCompleted(this);\n this.delegate.visitCompleted(this);\n this.followRedirect();\n }\n }\n fail() {\n if (this.state == VisitState.started) {\n this.state = VisitState.failed;\n this.adapter.visitFailed(this);\n }\n }\n changeHistory() {\n var _a;\n if (!this.historyChanged) {\n const actionForHistory = this.location.href === ((_a = this.referrer) === null || _a === void 0 ? void 0 : _a.href) ? \"replace\" : this.action;\n const method = this.getHistoryMethodForAction(actionForHistory);\n this.history.update(method, this.location, this.restorationIdentifier);\n this.historyChanged = true;\n }\n }\n issueRequest() {\n if (this.hasPreloadedResponse()) {\n this.simulateRequest();\n }\n else if (this.shouldIssueRequest() && !this.request) {\n this.request = new FetchRequest(this, FetchMethod.get, this.location);\n this.request.perform();\n }\n }\n simulateRequest() {\n if (this.response) {\n this.startRequest();\n this.recordResponse();\n this.finishRequest();\n }\n }\n startRequest() {\n this.recordTimingMetric(TimingMetric.requestStart);\n this.adapter.visitRequestStarted(this);\n }\n recordResponse(response = this.response) {\n this.response = response;\n if (response) {\n const { statusCode } = response;\n if (isSuccessful(statusCode)) {\n this.adapter.visitRequestCompleted(this);\n }\n else {\n this.adapter.visitRequestFailedWithStatusCode(this, statusCode);\n }\n }\n }\n finishRequest() {\n this.recordTimingMetric(TimingMetric.requestEnd);\n this.adapter.visitRequestFinished(this);\n }\n loadResponse() {\n if (this.response) {\n const { statusCode, responseHTML } = this.response;\n this.render(async () => {\n this.cacheSnapshot();\n if (this.view.renderPromise)\n await this.view.renderPromise;\n if (isSuccessful(statusCode) && responseHTML != null) {\n await this.view.renderPage(PageSnapshot.fromHTMLString(responseHTML));\n this.adapter.visitRendered(this);\n this.complete();\n }\n else {\n await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML));\n this.adapter.visitRendered(this);\n this.fail();\n }\n });\n }\n }\n getCachedSnapshot() {\n const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot();\n if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) {\n if (this.action == \"restore\" || snapshot.isPreviewable) {\n return snapshot;\n }\n }\n }\n getPreloadedSnapshot() {\n if (this.snapshotHTML) {\n return PageSnapshot.fromHTMLString(this.snapshotHTML);\n }\n }\n hasCachedSnapshot() {\n return this.getCachedSnapshot() != null;\n }\n loadCachedSnapshot() {\n const snapshot = this.getCachedSnapshot();\n if (snapshot) {\n const isPreview = this.shouldIssueRequest();\n this.render(async () => {\n this.cacheSnapshot();\n if (this.isSamePage) {\n this.adapter.visitRendered(this);\n }\n else {\n if (this.view.renderPromise)\n await this.view.renderPromise;\n await this.view.renderPage(snapshot, isPreview);\n this.adapter.visitRendered(this);\n if (!isPreview) {\n this.complete();\n }\n }\n });\n }\n }\n followRedirect() {\n if (this.redirectedToLocation && !this.followedRedirect) {\n this.adapter.visitProposedToLocation(this.redirectedToLocation, {\n action: 'replace',\n response: this.response\n });\n this.followedRedirect = true;\n }\n }\n goToSamePageAnchor() {\n if (this.isSamePage) {\n this.render(async () => {\n this.cacheSnapshot();\n this.adapter.visitRendered(this);\n });\n }\n }\n requestStarted() {\n this.startRequest();\n }\n requestPreventedHandlingResponse(request, response) {\n }\n async requestSucceededWithResponse(request, response) {\n const responseHTML = await response.responseHTML;\n if (responseHTML == undefined) {\n this.recordResponse({ statusCode: SystemStatusCode.contentTypeMismatch });\n }\n else {\n this.redirectedToLocation = response.redirected ? response.location : undefined;\n this.recordResponse({ statusCode: response.statusCode, responseHTML });\n }\n }\n async requestFailedWithResponse(request, response) {\n const responseHTML = await response.responseHTML;\n if (responseHTML == undefined) {\n this.recordResponse({ statusCode: SystemStatusCode.contentTypeMismatch });\n }\n else {\n this.recordResponse({ statusCode: response.statusCode, responseHTML });\n }\n }\n requestErrored(request, error) {\n this.recordResponse({ statusCode: SystemStatusCode.networkFailure });\n }\n requestFinished() {\n this.finishRequest();\n }\n performScroll() {\n if (!this.scrolled) {\n if (this.action == \"restore\") {\n this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop();\n }\n else {\n this.scrollToAnchor() || this.view.scrollToTop();\n }\n if (this.isSamePage) {\n this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation, this.location);\n }\n this.scrolled = true;\n }\n }\n scrollToRestoredPosition() {\n const { scrollPosition } = this.restorationData;\n if (scrollPosition) {\n this.view.scrollToPosition(scrollPosition);\n return true;\n }\n }\n scrollToAnchor() {\n const anchor = getAnchor(this.location);\n if (anchor != null) {\n this.view.scrollToAnchor(anchor);\n return true;\n }\n }\n recordTimingMetric(metric) {\n this.timingMetrics[metric] = new Date().getTime();\n }\n getTimingMetrics() {\n return Object.assign({}, this.timingMetrics);\n }\n getHistoryMethodForAction(action) {\n switch (action) {\n case \"replace\": return history.replaceState;\n case \"advance\":\n case \"restore\": return history.pushState;\n }\n }\n hasPreloadedResponse() {\n return typeof this.response == \"object\";\n }\n shouldIssueRequest() {\n if (this.isSamePage) {\n return false;\n }\n else if (this.action == \"restore\") {\n return !this.hasCachedSnapshot();\n }\n else {\n return true;\n }\n }\n cacheSnapshot() {\n if (!this.snapshotCached) {\n this.view.cacheSnapshot();\n this.snapshotCached = true;\n }\n }\n async render(callback) {\n this.cancelRender();\n await new Promise(resolve => {\n this.frame = requestAnimationFrame(() => resolve());\n });\n await callback();\n delete this.frame;\n this.performScroll();\n }\n cancelRender() {\n if (this.frame) {\n cancelAnimationFrame(this.frame);\n delete this.frame;\n }\n }\n}\nfunction isSuccessful(statusCode) {\n return statusCode >= 200 && statusCode < 300;\n}\n\nclass BrowserAdapter {\n constructor(session) {\n this.progressBar = new ProgressBar;\n this.showProgressBar = () => {\n this.progressBar.show();\n };\n this.session = session;\n }\n visitProposedToLocation(location, options) {\n this.navigator.startVisit(location, uuid(), options);\n }\n visitStarted(visit) {\n visit.issueRequest();\n visit.changeHistory();\n visit.goToSamePageAnchor();\n visit.loadCachedSnapshot();\n }\n visitRequestStarted(visit) {\n this.progressBar.setValue(0);\n if (visit.hasCachedSnapshot() || visit.action != \"restore\") {\n this.showVisitProgressBarAfterDelay();\n }\n else {\n this.showProgressBar();\n }\n }\n visitRequestCompleted(visit) {\n visit.loadResponse();\n }\n visitRequestFailedWithStatusCode(visit, statusCode) {\n switch (statusCode) {\n case SystemStatusCode.networkFailure:\n case SystemStatusCode.timeoutFailure:\n case SystemStatusCode.contentTypeMismatch:\n return this.reload();\n default:\n return visit.loadResponse();\n }\n }\n visitRequestFinished(visit) {\n this.progressBar.setValue(1);\n this.hideVisitProgressBar();\n }\n visitCompleted(visit) {\n }\n pageInvalidated() {\n this.reload();\n }\n visitFailed(visit) {\n }\n visitRendered(visit) {\n }\n formSubmissionStarted(formSubmission) {\n this.progressBar.setValue(0);\n this.showFormProgressBarAfterDelay();\n }\n formSubmissionFinished(formSubmission) {\n this.progressBar.setValue(1);\n this.hideFormProgressBar();\n }\n showVisitProgressBarAfterDelay() {\n this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);\n }\n hideVisitProgressBar() {\n this.progressBar.hide();\n if (this.visitProgressBarTimeout != null) {\n window.clearTimeout(this.visitProgressBarTimeout);\n delete this.visitProgressBarTimeout;\n }\n }\n showFormProgressBarAfterDelay() {\n if (this.formProgressBarTimeout == null) {\n this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);\n }\n }\n hideFormProgressBar() {\n this.progressBar.hide();\n if (this.formProgressBarTimeout != null) {\n window.clearTimeout(this.formProgressBarTimeout);\n delete this.formProgressBarTimeout;\n }\n }\n reload() {\n window.location.reload();\n }\n get navigator() {\n return this.session.navigator;\n }\n}\n\nclass CacheObserver {\n constructor() {\n this.started = false;\n }\n start() {\n if (!this.started) {\n this.started = true;\n addEventListener(\"turbo:before-cache\", this.removeStaleElements, false);\n }\n }\n stop() {\n if (this.started) {\n this.started = false;\n removeEventListener(\"turbo:before-cache\", this.removeStaleElements, false);\n }\n }\n removeStaleElements() {\n const staleElements = [...document.querySelectorAll('[data-turbo-cache=\"false\"]')];\n for (const element of staleElements) {\n element.remove();\n }\n }\n}\n\nclass FormSubmitObserver {\n constructor(delegate) {\n this.started = false;\n this.submitCaptured = () => {\n removeEventListener(\"submit\", this.submitBubbled, false);\n addEventListener(\"submit\", this.submitBubbled, false);\n };\n this.submitBubbled = ((event) => {\n if (!event.defaultPrevented) {\n const form = event.target instanceof HTMLFormElement ? event.target : undefined;\n const submitter = event.submitter || undefined;\n if (form) {\n const method = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute(\"formmethod\")) || form.method;\n if (method != \"dialog\" && this.delegate.willSubmitForm(form, submitter)) {\n event.preventDefault();\n this.delegate.formSubmitted(form, submitter);\n }\n }\n }\n });\n this.delegate = delegate;\n }\n start() {\n if (!this.started) {\n addEventListener(\"submit\", this.submitCaptured, true);\n this.started = true;\n }\n }\n stop() {\n if (this.started) {\n removeEventListener(\"submit\", this.submitCaptured, true);\n this.started = false;\n }\n }\n}\n\nclass FrameRedirector {\n constructor(element) {\n this.element = element;\n this.linkInterceptor = new LinkInterceptor(this, element);\n this.formInterceptor = new FormInterceptor(this, element);\n }\n start() {\n this.linkInterceptor.start();\n this.formInterceptor.start();\n }\n stop() {\n this.linkInterceptor.stop();\n this.formInterceptor.stop();\n }\n shouldInterceptLinkClick(element, url) {\n return this.shouldRedirect(element);\n }\n linkClickIntercepted(element, url) {\n const frame = this.findFrameElement(element);\n if (frame) {\n frame.setAttribute(\"reloadable\", \"\");\n frame.src = url;\n }\n }\n shouldInterceptFormSubmission(element, submitter) {\n return this.shouldRedirect(element, submitter);\n }\n formSubmissionIntercepted(element, submitter) {\n const frame = this.findFrameElement(element, submitter);\n if (frame) {\n frame.removeAttribute(\"reloadable\");\n frame.delegate.formSubmissionIntercepted(element, submitter);\n }\n }\n shouldRedirect(element, submitter) {\n const frame = this.findFrameElement(element, submitter);\n return frame ? frame != element.closest(\"turbo-frame\") : false;\n }\n findFrameElement(element, submitter) {\n const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute(\"data-turbo-frame\")) || element.getAttribute(\"data-turbo-frame\");\n if (id && id != \"_top\") {\n const frame = this.element.querySelector(`#${id}:not([disabled])`);\n if (frame instanceof FrameElement) {\n return frame;\n }\n }\n }\n}\n\nclass History {\n constructor(delegate) {\n this.restorationIdentifier = uuid();\n this.restorationData = {};\n this.started = false;\n this.pageLoaded = false;\n this.onPopState = (event) => {\n if (this.shouldHandlePopState()) {\n const { turbo } = event.state || {};\n if (turbo) {\n this.location = new URL(window.location.href);\n const { restorationIdentifier } = turbo;\n this.restorationIdentifier = restorationIdentifier;\n this.delegate.historyPoppedToLocationWithRestorationIdentifier(this.location, restorationIdentifier);\n }\n }\n };\n this.onPageLoad = async (event) => {\n await nextMicrotask();\n this.pageLoaded = true;\n };\n this.delegate = delegate;\n }\n start() {\n if (!this.started) {\n addEventListener(\"popstate\", this.onPopState, false);\n addEventListener(\"load\", this.onPageLoad, false);\n this.started = true;\n this.replace(new URL(window.location.href));\n }\n }\n stop() {\n if (this.started) {\n removeEventListener(\"popstate\", this.onPopState, false);\n removeEventListener(\"load\", this.onPageLoad, false);\n this.started = false;\n }\n }\n push(location, restorationIdentifier) {\n this.update(history.pushState, location, restorationIdentifier);\n }\n replace(location, restorationIdentifier) {\n this.update(history.replaceState, location, restorationIdentifier);\n }\n update(method, location, restorationIdentifier = uuid()) {\n const state = { turbo: { restorationIdentifier } };\n method.call(history, state, \"\", location.href);\n this.location = location;\n this.restorationIdentifier = restorationIdentifier;\n }\n getRestorationDataForIdentifier(restorationIdentifier) {\n return this.restorationData[restorationIdentifier] || {};\n }\n updateRestorationData(additionalData) {\n const { restorationIdentifier } = this;\n const restorationData = this.restorationData[restorationIdentifier];\n this.restorationData[restorationIdentifier] = Object.assign(Object.assign({}, restorationData), additionalData);\n }\n assumeControlOfScrollRestoration() {\n var _a;\n if (!this.previousScrollRestoration) {\n this.previousScrollRestoration = (_a = history.scrollRestoration) !== null && _a !== void 0 ? _a : \"auto\";\n history.scrollRestoration = \"manual\";\n }\n }\n relinquishControlOfScrollRestoration() {\n if (this.previousScrollRestoration) {\n history.scrollRestoration = this.previousScrollRestoration;\n delete this.previousScrollRestoration;\n }\n }\n shouldHandlePopState() {\n return this.pageIsLoaded();\n }\n pageIsLoaded() {\n return this.pageLoaded || document.readyState == \"complete\";\n }\n}\n\nclass LinkClickObserver {\n constructor(delegate) {\n this.started = false;\n this.clickCaptured = () => {\n removeEventListener(\"click\", this.clickBubbled, false);\n addEventListener(\"click\", this.clickBubbled, false);\n };\n this.clickBubbled = (event) => {\n if (this.clickEventIsSignificant(event)) {\n const target = (event.composedPath && event.composedPath()[0]) || event.target;\n const link = this.findLinkFromClickTarget(target);\n if (link) {\n const location = this.getLocationForLink(link);\n if (this.delegate.willFollowLinkToLocation(link, location)) {\n event.preventDefault();\n this.delegate.followedLinkToLocation(link, location);\n }\n }\n }\n };\n this.delegate = delegate;\n }\n start() {\n if (!this.started) {\n addEventListener(\"click\", this.clickCaptured, true);\n this.started = true;\n }\n }\n stop() {\n if (this.started) {\n removeEventListener(\"click\", this.clickCaptured, true);\n this.started = false;\n }\n }\n clickEventIsSignificant(event) {\n return !((event.target && event.target.isContentEditable)\n || event.defaultPrevented\n || event.which > 1\n || event.altKey\n || event.ctrlKey\n || event.metaKey\n || event.shiftKey);\n }\n findLinkFromClickTarget(target) {\n if (target instanceof Element) {\n return target.closest(\"a[href]:not([target^=_]):not([download])\");\n }\n }\n getLocationForLink(link) {\n return expandURL(link.getAttribute(\"href\") || \"\");\n }\n}\n\nfunction isAction(action) {\n return action == \"advance\" || action == \"replace\" || action == \"restore\";\n}\n\nclass Navigator {\n constructor(delegate) {\n this.delegate = delegate;\n }\n proposeVisit(location, options = {}) {\n if (this.delegate.allowsVisitingLocationWithAction(location, options.action)) {\n this.delegate.visitProposedToLocation(location, options);\n }\n }\n startVisit(locatable, restorationIdentifier, options = {}) {\n this.stop();\n this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, Object.assign({ referrer: this.location }, options));\n this.currentVisit.start();\n }\n submitForm(form, submitter) {\n this.stop();\n this.formSubmission = new FormSubmission(this, form, submitter, true);\n if (this.formSubmission.isIdempotent) {\n this.proposeVisit(this.formSubmission.fetchRequest.url, { action: this.getActionForFormSubmission(this.formSubmission) });\n }\n else {\n this.formSubmission.start();\n }\n }\n stop() {\n if (this.formSubmission) {\n this.formSubmission.stop();\n delete this.formSubmission;\n }\n if (this.currentVisit) {\n this.currentVisit.cancel();\n delete this.currentVisit;\n }\n }\n get adapter() {\n return this.delegate.adapter;\n }\n get view() {\n return this.delegate.view;\n }\n get history() {\n return this.delegate.history;\n }\n formSubmissionStarted(formSubmission) {\n if (typeof this.adapter.formSubmissionStarted === 'function') {\n this.adapter.formSubmissionStarted(formSubmission);\n }\n }\n async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) {\n if (formSubmission == this.formSubmission) {\n const responseHTML = await fetchResponse.responseHTML;\n if (responseHTML) {\n if (formSubmission.method != FetchMethod.get) {\n this.view.clearSnapshotCache();\n }\n const { statusCode } = fetchResponse;\n const visitOptions = { response: { statusCode, responseHTML } };\n this.proposeVisit(fetchResponse.location, visitOptions);\n }\n }\n }\n async formSubmissionFailedWithResponse(formSubmission, fetchResponse) {\n const responseHTML = await fetchResponse.responseHTML;\n if (responseHTML) {\n const snapshot = PageSnapshot.fromHTMLString(responseHTML);\n if (fetchResponse.serverError) {\n await this.view.renderError(snapshot);\n }\n else {\n await this.view.renderPage(snapshot);\n }\n this.view.scrollToTop();\n this.view.clearSnapshotCache();\n }\n }\n formSubmissionErrored(formSubmission, error) {\n console.error(error);\n }\n formSubmissionFinished(formSubmission) {\n if (typeof this.adapter.formSubmissionFinished === 'function') {\n this.adapter.formSubmissionFinished(formSubmission);\n }\n }\n visitStarted(visit) {\n this.delegate.visitStarted(visit);\n }\n visitCompleted(visit) {\n this.delegate.visitCompleted(visit);\n }\n locationWithActionIsSamePage(location, action) {\n const anchor = getAnchor(location);\n const currentAnchor = getAnchor(this.view.lastRenderedLocation);\n const isRestorationToTop = action === 'restore' && typeof anchor === 'undefined';\n return action !== \"replace\" &&\n getRequestURL(location) === getRequestURL(this.view.lastRenderedLocation) &&\n (isRestorationToTop || (anchor != null && anchor !== currentAnchor));\n }\n visitScrolledToSamePageLocation(oldURL, newURL) {\n this.delegate.visitScrolledToSamePageLocation(oldURL, newURL);\n }\n get location() {\n return this.history.location;\n }\n get restorationIdentifier() {\n return this.history.restorationIdentifier;\n }\n getActionForFormSubmission(formSubmission) {\n const { formElement, submitter } = formSubmission;\n const action = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute(\"data-turbo-action\")) || formElement.getAttribute(\"data-turbo-action\");\n return isAction(action) ? action : \"advance\";\n }\n}\n\nvar PageStage;\n(function (PageStage) {\n PageStage[PageStage[\"initial\"] = 0] = \"initial\";\n PageStage[PageStage[\"loading\"] = 1] = \"loading\";\n PageStage[PageStage[\"interactive\"] = 2] = \"interactive\";\n PageStage[PageStage[\"complete\"] = 3] = \"complete\";\n})(PageStage || (PageStage = {}));\nclass PageObserver {\n constructor(delegate) {\n this.stage = PageStage.initial;\n this.started = false;\n this.interpretReadyState = () => {\n const { readyState } = this;\n if (readyState == \"interactive\") {\n this.pageIsInteractive();\n }\n else if (readyState == \"complete\") {\n this.pageIsComplete();\n }\n };\n this.pageWillUnload = () => {\n this.delegate.pageWillUnload();\n };\n this.delegate = delegate;\n }\n start() {\n if (!this.started) {\n if (this.stage == PageStage.initial) {\n this.stage = PageStage.loading;\n }\n document.addEventListener(\"readystatechange\", this.interpretReadyState, false);\n addEventListener(\"pagehide\", this.pageWillUnload, false);\n this.started = true;\n }\n }\n stop() {\n if (this.started) {\n document.removeEventListener(\"readystatechange\", this.interpretReadyState, false);\n removeEventListener(\"pagehide\", this.pageWillUnload, false);\n this.started = false;\n }\n }\n pageIsInteractive() {\n if (this.stage == PageStage.loading) {\n this.stage = PageStage.interactive;\n this.delegate.pageBecameInteractive();\n }\n }\n pageIsComplete() {\n this.pageIsInteractive();\n if (this.stage == PageStage.interactive) {\n this.stage = PageStage.complete;\n this.delegate.pageLoaded();\n }\n }\n get readyState() {\n return document.readyState;\n }\n}\n\nclass ScrollObserver {\n constructor(delegate) {\n this.started = false;\n this.onScroll = () => {\n this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset });\n };\n this.delegate = delegate;\n }\n start() {\n if (!this.started) {\n addEventListener(\"scroll\", this.onScroll, false);\n this.onScroll();\n this.started = true;\n }\n }\n stop() {\n if (this.started) {\n removeEventListener(\"scroll\", this.onScroll, false);\n this.started = false;\n }\n }\n updatePosition(position) {\n this.delegate.scrollPositionChanged(position);\n }\n}\n\nclass StreamObserver {\n constructor(delegate) {\n this.sources = new Set;\n this.started = false;\n this.inspectFetchResponse = ((event) => {\n const response = fetchResponseFromEvent(event);\n if (response && fetchResponseIsStream(response)) {\n event.preventDefault();\n this.receiveMessageResponse(response);\n }\n });\n this.receiveMessageEvent = (event) => {\n if (this.started && typeof event.data == \"string\") {\n this.receiveMessageHTML(event.data);\n }\n };\n this.delegate = delegate;\n }\n start() {\n if (!this.started) {\n this.started = true;\n addEventListener(\"turbo:before-fetch-response\", this.inspectFetchResponse, false);\n }\n }\n stop() {\n if (this.started) {\n this.started = false;\n removeEventListener(\"turbo:before-fetch-response\", this.inspectFetchResponse, false);\n }\n }\n connectStreamSource(source) {\n if (!this.streamSourceIsConnected(source)) {\n this.sources.add(source);\n source.addEventListener(\"message\", this.receiveMessageEvent, false);\n }\n }\n disconnectStreamSource(source) {\n if (this.streamSourceIsConnected(source)) {\n this.sources.delete(source);\n source.removeEventListener(\"message\", this.receiveMessageEvent, false);\n }\n }\n streamSourceIsConnected(source) {\n return this.sources.has(source);\n }\n async receiveMessageResponse(response) {\n const html = await response.responseHTML;\n if (html) {\n this.receiveMessageHTML(html);\n }\n }\n receiveMessageHTML(html) {\n this.delegate.receivedMessageFromStream(new StreamMessage(html));\n }\n}\nfunction fetchResponseFromEvent(event) {\n var _a;\n const fetchResponse = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.fetchResponse;\n if (fetchResponse instanceof FetchResponse) {\n return fetchResponse;\n }\n}\nfunction fetchResponseIsStream(response) {\n var _a;\n const contentType = (_a = response.contentType) !== null && _a !== void 0 ? _a : \"\";\n return contentType.startsWith(StreamMessage.contentType);\n}\n\nclass ErrorRenderer extends Renderer {\n async render() {\n this.replaceHeadAndBody();\n this.activateScriptElements();\n }\n replaceHeadAndBody() {\n const { documentElement, head, body } = document;\n documentElement.replaceChild(this.newHead, head);\n documentElement.replaceChild(this.newElement, body);\n }\n activateScriptElements() {\n for (const replaceableElement of this.scriptElements) {\n const parentNode = replaceableElement.parentNode;\n if (parentNode) {\n const element = this.createScriptElement(replaceableElement);\n parentNode.replaceChild(element, replaceableElement);\n }\n }\n }\n get newHead() {\n return this.newSnapshot.headSnapshot.element;\n }\n get scriptElements() {\n return [...document.documentElement.querySelectorAll(\"script\")];\n }\n}\n\nclass PageRenderer extends Renderer {\n get shouldRender() {\n return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical;\n }\n prepareToRender() {\n this.mergeHead();\n }\n async render() {\n this.replaceBody();\n }\n finishRendering() {\n super.finishRendering();\n if (!this.isPreview) {\n this.focusFirstAutofocusableElement();\n }\n }\n get currentHeadSnapshot() {\n return this.currentSnapshot.headSnapshot;\n }\n get newHeadSnapshot() {\n return this.newSnapshot.headSnapshot;\n }\n get newElement() {\n return this.newSnapshot.element;\n }\n mergeHead() {\n this.copyNewHeadStylesheetElements();\n this.copyNewHeadScriptElements();\n this.removeCurrentHeadProvisionalElements();\n this.copyNewHeadProvisionalElements();\n }\n replaceBody() {\n this.preservingPermanentElements(() => {\n this.activateNewBody();\n this.assignNewBody();\n });\n }\n get trackedElementsAreIdentical() {\n return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature;\n }\n copyNewHeadStylesheetElements() {\n for (const element of this.newHeadStylesheetElements) {\n document.head.appendChild(element);\n }\n }\n copyNewHeadScriptElements() {\n for (const element of this.newHeadScriptElements) {\n document.head.appendChild(this.createScriptElement(element));\n }\n }\n removeCurrentHeadProvisionalElements() {\n for (const element of this.currentHeadProvisionalElements) {\n document.head.removeChild(element);\n }\n }\n copyNewHeadProvisionalElements() {\n for (const element of this.newHeadProvisionalElements) {\n document.head.appendChild(element);\n }\n }\n activateNewBody() {\n document.adoptNode(this.newElement);\n this.activateNewBodyScriptElements();\n }\n activateNewBodyScriptElements() {\n for (const inertScriptElement of this.newBodyScriptElements) {\n const activatedScriptElement = this.createScriptElement(inertScriptElement);\n inertScriptElement.replaceWith(activatedScriptElement);\n }\n }\n assignNewBody() {\n if (document.body && this.newElement instanceof HTMLBodyElement) {\n document.body.replaceWith(this.newElement);\n }\n else {\n document.documentElement.appendChild(this.newElement);\n }\n }\n get newHeadStylesheetElements() {\n return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot);\n }\n get newHeadScriptElements() {\n return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot);\n }\n get currentHeadProvisionalElements() {\n return this.currentHeadSnapshot.provisionalElements;\n }\n get newHeadProvisionalElements() {\n return this.newHeadSnapshot.provisionalElements;\n }\n get newBodyScriptElements() {\n return this.newElement.querySelectorAll(\"script\");\n }\n}\n\nclass SnapshotCache {\n constructor(size) {\n this.keys = [];\n this.snapshots = {};\n this.size = size;\n }\n has(location) {\n return toCacheKey(location) in this.snapshots;\n }\n get(location) {\n if (this.has(location)) {\n const snapshot = this.read(location);\n this.touch(location);\n return snapshot;\n }\n }\n put(location, snapshot) {\n this.write(location, snapshot);\n this.touch(location);\n return snapshot;\n }\n clear() {\n this.snapshots = {};\n }\n read(location) {\n return this.snapshots[toCacheKey(location)];\n }\n write(location, snapshot) {\n this.snapshots[toCacheKey(location)] = snapshot;\n }\n touch(location) {\n const key = toCacheKey(location);\n const index = this.keys.indexOf(key);\n if (index > -1)\n this.keys.splice(index, 1);\n this.keys.unshift(key);\n this.trim();\n }\n trim() {\n for (const key of this.keys.splice(this.size)) {\n delete this.snapshots[key];\n }\n }\n}\n\nclass PageView extends View {\n constructor() {\n super(...arguments);\n this.snapshotCache = new SnapshotCache(10);\n this.lastRenderedLocation = new URL(location.href);\n }\n renderPage(snapshot, isPreview = false) {\n const renderer = new PageRenderer(this.snapshot, snapshot, isPreview);\n return this.render(renderer);\n }\n renderError(snapshot) {\n const renderer = new ErrorRenderer(this.snapshot, snapshot, false);\n return this.render(renderer);\n }\n clearSnapshotCache() {\n this.snapshotCache.clear();\n }\n async cacheSnapshot() {\n if (this.shouldCacheSnapshot) {\n this.delegate.viewWillCacheSnapshot();\n const { snapshot, lastRenderedLocation: location } = this;\n await nextEventLoopTick();\n this.snapshotCache.put(location, snapshot.clone());\n }\n }\n getCachedSnapshotForLocation(location) {\n return this.snapshotCache.get(location);\n }\n get snapshot() {\n return PageSnapshot.fromElement(this.element);\n }\n get shouldCacheSnapshot() {\n return this.snapshot.isCacheable;\n }\n}\n\nclass Session {\n constructor() {\n this.navigator = new Navigator(this);\n this.history = new History(this);\n this.view = new PageView(this, document.documentElement);\n this.adapter = new BrowserAdapter(this);\n this.pageObserver = new PageObserver(this);\n this.cacheObserver = new CacheObserver();\n this.linkClickObserver = new LinkClickObserver(this);\n this.formSubmitObserver = new FormSubmitObserver(this);\n this.scrollObserver = new ScrollObserver(this);\n this.streamObserver = new StreamObserver(this);\n this.frameRedirector = new FrameRedirector(document.documentElement);\n this.drive = true;\n this.enabled = true;\n this.progressBarDelay = 500;\n this.started = false;\n }\n start() {\n if (!this.started) {\n this.pageObserver.start();\n this.cacheObserver.start();\n this.linkClickObserver.start();\n this.formSubmitObserver.start();\n this.scrollObserver.start();\n this.streamObserver.start();\n this.frameRedirector.start();\n this.history.start();\n this.started = true;\n this.enabled = true;\n }\n }\n disable() {\n this.enabled = false;\n }\n stop() {\n if (this.started) {\n this.pageObserver.stop();\n this.cacheObserver.stop();\n this.linkClickObserver.stop();\n this.formSubmitObserver.stop();\n this.scrollObserver.stop();\n this.streamObserver.stop();\n this.frameRedirector.stop();\n this.history.stop();\n this.started = false;\n }\n }\n registerAdapter(adapter) {\n this.adapter = adapter;\n }\n visit(location, options = {}) {\n this.navigator.proposeVisit(expandURL(location), options);\n }\n connectStreamSource(source) {\n this.streamObserver.connectStreamSource(source);\n }\n disconnectStreamSource(source) {\n this.streamObserver.disconnectStreamSource(source);\n }\n renderStreamMessage(message) {\n document.documentElement.appendChild(StreamMessage.wrap(message).fragment);\n }\n clearCache() {\n this.view.clearSnapshotCache();\n }\n setProgressBarDelay(delay) {\n this.progressBarDelay = delay;\n }\n get location() {\n return this.history.location;\n }\n get restorationIdentifier() {\n return this.history.restorationIdentifier;\n }\n historyPoppedToLocationWithRestorationIdentifier(location, restorationIdentifier) {\n if (this.enabled) {\n this.navigator.startVisit(location, restorationIdentifier, { action: \"restore\", historyChanged: true });\n }\n else {\n this.adapter.pageInvalidated();\n }\n }\n scrollPositionChanged(position) {\n this.history.updateRestorationData({ scrollPosition: position });\n }\n willFollowLinkToLocation(link, location) {\n return this.elementDriveEnabled(link)\n && this.locationIsVisitable(location)\n && this.applicationAllowsFollowingLinkToLocation(link, location);\n }\n followedLinkToLocation(link, location) {\n const action = this.getActionForLink(link);\n this.convertLinkWithMethodClickToFormSubmission(link) || this.visit(location.href, { action });\n }\n convertLinkWithMethodClickToFormSubmission(link) {\n var _a;\n const linkMethod = link.getAttribute(\"data-turbo-method\");\n if (linkMethod) {\n const form = document.createElement(\"form\");\n form.method = linkMethod;\n form.action = link.getAttribute(\"href\") || \"undefined\";\n form.hidden = true;\n (_a = link.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(form, link);\n return dispatch(\"submit\", { cancelable: true, target: form });\n }\n else {\n return false;\n }\n }\n allowsVisitingLocationWithAction(location, action) {\n return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location);\n }\n visitProposedToLocation(location, options) {\n extendURLWithDeprecatedProperties(location);\n this.adapter.visitProposedToLocation(location, options);\n }\n visitStarted(visit) {\n extendURLWithDeprecatedProperties(visit.location);\n if (!visit.silent) {\n this.notifyApplicationAfterVisitingLocation(visit.location, visit.action);\n }\n }\n visitCompleted(visit) {\n this.notifyApplicationAfterPageLoad(visit.getTimingMetrics());\n }\n locationWithActionIsSamePage(location, action) {\n return this.navigator.locationWithActionIsSamePage(location, action);\n }\n visitScrolledToSamePageLocation(oldURL, newURL) {\n this.notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL);\n }\n willSubmitForm(form, submitter) {\n return this.elementDriveEnabled(form) && (!submitter || this.elementDriveEnabled(submitter));\n }\n formSubmitted(form, submitter) {\n this.navigator.submitForm(form, submitter);\n }\n pageBecameInteractive() {\n this.view.lastRenderedLocation = this.location;\n this.notifyApplicationAfterPageLoad();\n }\n pageLoaded() {\n this.history.assumeControlOfScrollRestoration();\n }\n pageWillUnload() {\n this.history.relinquishControlOfScrollRestoration();\n }\n receivedMessageFromStream(message) {\n this.renderStreamMessage(message);\n }\n viewWillCacheSnapshot() {\n var _a;\n if (!((_a = this.navigator.currentVisit) === null || _a === void 0 ? void 0 : _a.silent)) {\n this.notifyApplicationBeforeCachingSnapshot();\n }\n }\n allowsImmediateRender({ element }, resume) {\n const event = this.notifyApplicationBeforeRender(element, resume);\n return !event.defaultPrevented;\n }\n viewRenderedSnapshot(snapshot, isPreview) {\n this.view.lastRenderedLocation = this.history.location;\n this.notifyApplicationAfterRender();\n }\n viewInvalidated() {\n this.adapter.pageInvalidated();\n }\n frameLoaded(frame) {\n this.notifyApplicationAfterFrameLoad(frame);\n }\n frameRendered(fetchResponse, frame) {\n this.notifyApplicationAfterFrameRender(fetchResponse, frame);\n }\n applicationAllowsFollowingLinkToLocation(link, location) {\n const event = this.notifyApplicationAfterClickingLinkToLocation(link, location);\n return !event.defaultPrevented;\n }\n applicationAllowsVisitingLocation(location) {\n const event = this.notifyApplicationBeforeVisitingLocation(location);\n return !event.defaultPrevented;\n }\n notifyApplicationAfterClickingLinkToLocation(link, location) {\n return dispatch(\"turbo:click\", { target: link, detail: { url: location.href }, cancelable: true });\n }\n notifyApplicationBeforeVisitingLocation(location) {\n return dispatch(\"turbo:before-visit\", { detail: { url: location.href }, cancelable: true });\n }\n notifyApplicationAfterVisitingLocation(location, action) {\n return dispatch(\"turbo:visit\", { detail: { url: location.href, action } });\n }\n notifyApplicationBeforeCachingSnapshot() {\n return dispatch(\"turbo:before-cache\");\n }\n notifyApplicationBeforeRender(newBody, resume) {\n return dispatch(\"turbo:before-render\", { detail: { newBody, resume }, cancelable: true });\n }\n notifyApplicationAfterRender() {\n return dispatch(\"turbo:render\");\n }\n notifyApplicationAfterPageLoad(timing = {}) {\n return dispatch(\"turbo:load\", { detail: { url: this.location.href, timing } });\n }\n notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) {\n dispatchEvent(new HashChangeEvent(\"hashchange\", { oldURL: oldURL.toString(), newURL: newURL.toString() }));\n }\n notifyApplicationAfterFrameLoad(frame) {\n return dispatch(\"turbo:frame-load\", { target: frame });\n }\n notifyApplicationAfterFrameRender(fetchResponse, frame) {\n return dispatch(\"turbo:frame-render\", { detail: { fetchResponse }, target: frame, cancelable: true });\n }\n elementDriveEnabled(element) {\n const container = element === null || element === void 0 ? void 0 : element.closest(\"[data-turbo]\");\n if (this.drive) {\n if (container) {\n return container.getAttribute(\"data-turbo\") != \"false\";\n }\n else {\n return true;\n }\n }\n else {\n if (container) {\n return container.getAttribute(\"data-turbo\") == \"true\";\n }\n else {\n return false;\n }\n }\n }\n getActionForLink(link) {\n const action = link.getAttribute(\"data-turbo-action\");\n return isAction(action) ? action : \"advance\";\n }\n locationIsVisitable(location) {\n return isPrefixedBy(location, this.snapshot.rootLocation) && isHTML(location);\n }\n get snapshot() {\n return this.view.snapshot;\n }\n}\nfunction extendURLWithDeprecatedProperties(url) {\n Object.defineProperties(url, deprecatedLocationPropertyDescriptors);\n}\nconst deprecatedLocationPropertyDescriptors = {\n absoluteURL: {\n get() {\n return this.toString();\n }\n }\n};\n\nconst session = new Session;\nconst { navigator: navigator$1 } = session;\nfunction start() {\n session.start();\n}\nfunction registerAdapter(adapter) {\n session.registerAdapter(adapter);\n}\nfunction visit(location, options) {\n session.visit(location, options);\n}\nfunction connectStreamSource(source) {\n session.connectStreamSource(source);\n}\nfunction disconnectStreamSource(source) {\n session.disconnectStreamSource(source);\n}\nfunction renderStreamMessage(message) {\n session.renderStreamMessage(message);\n}\nfunction clearCache() {\n session.clearCache();\n}\nfunction setProgressBarDelay(delay) {\n session.setProgressBarDelay(delay);\n}\n\nvar Turbo = /*#__PURE__*/Object.freeze({\n __proto__: null,\n navigator: navigator$1,\n session: session,\n PageRenderer: PageRenderer,\n PageSnapshot: PageSnapshot,\n start: start,\n registerAdapter: registerAdapter,\n visit: visit,\n connectStreamSource: connectStreamSource,\n disconnectStreamSource: disconnectStreamSource,\n renderStreamMessage: renderStreamMessage,\n clearCache: clearCache,\n setProgressBarDelay: setProgressBarDelay\n});\n\nclass FrameController {\n constructor(element) {\n this.resolveVisitPromise = () => { };\n this.connected = false;\n this.hasBeenLoaded = false;\n this.settingSourceURL = false;\n this.element = element;\n this.view = new FrameView(this, this.element);\n this.appearanceObserver = new AppearanceObserver(this, this.element);\n this.linkInterceptor = new LinkInterceptor(this, this.element);\n this.formInterceptor = new FormInterceptor(this, this.element);\n }\n connect() {\n if (!this.connected) {\n this.connected = true;\n this.reloadable = false;\n if (this.loadingStyle == FrameLoadingStyle.lazy) {\n this.appearanceObserver.start();\n }\n this.linkInterceptor.start();\n this.formInterceptor.start();\n this.sourceURLChanged();\n }\n }\n disconnect() {\n if (this.connected) {\n this.connected = false;\n this.appearanceObserver.stop();\n this.linkInterceptor.stop();\n this.formInterceptor.stop();\n }\n }\n disabledChanged() {\n if (this.loadingStyle == FrameLoadingStyle.eager) {\n this.loadSourceURL();\n }\n }\n sourceURLChanged() {\n if (this.loadingStyle == FrameLoadingStyle.eager || this.hasBeenLoaded) {\n this.loadSourceURL();\n }\n }\n loadingStyleChanged() {\n if (this.loadingStyle == FrameLoadingStyle.lazy) {\n this.appearanceObserver.start();\n }\n else {\n this.appearanceObserver.stop();\n this.loadSourceURL();\n }\n }\n async loadSourceURL() {\n if (!this.settingSourceURL && this.enabled && this.isActive && (this.reloadable || this.sourceURL != this.currentURL)) {\n const previousURL = this.currentURL;\n this.currentURL = this.sourceURL;\n if (this.sourceURL) {\n try {\n this.element.loaded = this.visit(this.sourceURL);\n this.appearanceObserver.stop();\n await this.element.loaded;\n this.hasBeenLoaded = true;\n session.frameLoaded(this.element);\n }\n catch (error) {\n this.currentURL = previousURL;\n throw error;\n }\n }\n }\n }\n async loadResponse(fetchResponse) {\n if (fetchResponse.redirected) {\n this.sourceURL = fetchResponse.response.url;\n }\n try {\n const html = await fetchResponse.responseHTML;\n if (html) {\n const { body } = parseHTMLDocument(html);\n const snapshot = new Snapshot(await this.extractForeignFrameElement(body));\n const renderer = new FrameRenderer(this.view.snapshot, snapshot, false);\n if (this.view.renderPromise)\n await this.view.renderPromise;\n await this.view.render(renderer);\n session.frameRendered(fetchResponse, this.element);\n }\n }\n catch (error) {\n console.error(error);\n this.view.invalidate();\n }\n }\n elementAppearedInViewport(element) {\n this.loadSourceURL();\n }\n shouldInterceptLinkClick(element, url) {\n if (element.hasAttribute(\"data-turbo-method\")) {\n return false;\n }\n else {\n return this.shouldInterceptNavigation(element);\n }\n }\n linkClickIntercepted(element, url) {\n this.reloadable = true;\n this.navigateFrame(element, url);\n }\n shouldInterceptFormSubmission(element, submitter) {\n return this.shouldInterceptNavigation(element, submitter);\n }\n formSubmissionIntercepted(element, submitter) {\n if (this.formSubmission) {\n this.formSubmission.stop();\n }\n this.reloadable = false;\n this.formSubmission = new FormSubmission(this, element, submitter);\n if (this.formSubmission.fetchRequest.isIdempotent) {\n this.navigateFrame(element, this.formSubmission.fetchRequest.url.href, submitter);\n }\n else {\n const { fetchRequest } = this.formSubmission;\n this.prepareHeadersForRequest(fetchRequest.headers, fetchRequest);\n this.formSubmission.start();\n }\n }\n prepareHeadersForRequest(headers, request) {\n headers[\"Turbo-Frame\"] = this.id;\n }\n requestStarted(request) {\n this.element.setAttribute(\"busy\", \"\");\n }\n requestPreventedHandlingResponse(request, response) {\n this.resolveVisitPromise();\n }\n async requestSucceededWithResponse(request, response) {\n await this.loadResponse(response);\n this.resolveVisitPromise();\n }\n requestFailedWithResponse(request, response) {\n console.error(response);\n this.resolveVisitPromise();\n }\n requestErrored(request, error) {\n console.error(error);\n this.resolveVisitPromise();\n }\n requestFinished(request) {\n this.element.removeAttribute(\"busy\");\n }\n formSubmissionStarted(formSubmission) {\n const frame = this.findFrameElement(formSubmission.formElement);\n frame.setAttribute(\"busy\", \"\");\n }\n formSubmissionSucceededWithResponse(formSubmission, response) {\n const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter);\n frame.delegate.loadResponse(response);\n }\n formSubmissionFailedWithResponse(formSubmission, fetchResponse) {\n this.element.delegate.loadResponse(fetchResponse);\n }\n formSubmissionErrored(formSubmission, error) {\n console.error(error);\n }\n formSubmissionFinished(formSubmission) {\n const frame = this.findFrameElement(formSubmission.formElement);\n frame.removeAttribute(\"busy\");\n }\n allowsImmediateRender(snapshot, resume) {\n return true;\n }\n viewRenderedSnapshot(snapshot, isPreview) {\n }\n viewInvalidated() {\n }\n async visit(url) {\n const request = new FetchRequest(this, FetchMethod.get, expandURL(url), undefined, this.element);\n return new Promise(resolve => {\n this.resolveVisitPromise = () => {\n this.resolveVisitPromise = () => { };\n resolve();\n };\n request.perform();\n });\n }\n navigateFrame(element, url, submitter) {\n const frame = this.findFrameElement(element, submitter);\n frame.setAttribute(\"reloadable\", \"\");\n frame.src = url;\n }\n findFrameElement(element, submitter) {\n var _a;\n const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute(\"data-turbo-frame\")) || element.getAttribute(\"data-turbo-frame\") || this.element.getAttribute(\"target\");\n return (_a = getFrameElementById(id)) !== null && _a !== void 0 ? _a : this.element;\n }\n async extractForeignFrameElement(container) {\n let element;\n const id = CSS.escape(this.id);\n try {\n if (element = activateElement(container.querySelector(`turbo-frame#${id}`), this.currentURL)) {\n return element;\n }\n if (element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.currentURL)) {\n await element.loaded;\n return await this.extractForeignFrameElement(element);\n }\n console.error(`Response has no matching element`);\n }\n catch (error) {\n console.error(error);\n }\n return new FrameElement();\n }\n shouldInterceptNavigation(element, submitter) {\n const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute(\"data-turbo-frame\")) || element.getAttribute(\"data-turbo-frame\") || this.element.getAttribute(\"target\");\n if (!this.enabled || id == \"_top\") {\n return false;\n }\n if (id) {\n const frameElement = getFrameElementById(id);\n if (frameElement) {\n return !frameElement.disabled;\n }\n }\n if (!session.elementDriveEnabled(element)) {\n return false;\n }\n if (submitter && !session.elementDriveEnabled(submitter)) {\n return false;\n }\n return true;\n }\n get id() {\n return this.element.id;\n }\n get enabled() {\n return !this.element.disabled;\n }\n get sourceURL() {\n if (this.element.src) {\n return this.element.src;\n }\n }\n get reloadable() {\n const frame = this.findFrameElement(this.element);\n return frame.hasAttribute(\"reloadable\");\n }\n set reloadable(value) {\n const frame = this.findFrameElement(this.element);\n if (value) {\n frame.setAttribute(\"reloadable\", \"\");\n }\n else {\n frame.removeAttribute(\"reloadable\");\n }\n }\n set sourceURL(sourceURL) {\n this.settingSourceURL = true;\n this.element.src = sourceURL !== null && sourceURL !== void 0 ? sourceURL : null;\n this.currentURL = this.element.src;\n this.settingSourceURL = false;\n }\n get loadingStyle() {\n return this.element.loading;\n }\n get isLoading() {\n return this.formSubmission !== undefined || this.resolveVisitPromise() !== undefined;\n }\n get isActive() {\n return this.element.isActive && this.connected;\n }\n}\nfunction getFrameElementById(id) {\n if (id != null) {\n const element = document.getElementById(id);\n if (element instanceof FrameElement) {\n return element;\n }\n }\n}\nfunction activateElement(element, currentURL) {\n if (element) {\n const src = element.getAttribute(\"src\");\n if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) {\n throw new Error(`Matching element has a source URL which references itself`);\n }\n if (element.ownerDocument !== document) {\n element = document.importNode(element, true);\n }\n if (element instanceof FrameElement) {\n element.connectedCallback();\n return element;\n }\n }\n}\n\nconst StreamActions = {\n after() {\n this.targetElements.forEach(e => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e.nextSibling); });\n },\n append() {\n this.removeDuplicateTargetChildren();\n this.targetElements.forEach(e => e.append(this.templateContent));\n },\n before() {\n this.targetElements.forEach(e => { var _a; return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e); });\n },\n prepend() {\n this.removeDuplicateTargetChildren();\n this.targetElements.forEach(e => e.prepend(this.templateContent));\n },\n remove() {\n this.targetElements.forEach(e => e.remove());\n },\n replace() {\n this.targetElements.forEach(e => e.replaceWith(this.templateContent));\n },\n update() {\n this.targetElements.forEach(e => {\n e.innerHTML = \"\";\n e.append(this.templateContent);\n });\n }\n};\n\nclass StreamElement extends HTMLElement {\n async connectedCallback() {\n try {\n await this.render();\n }\n catch (error) {\n console.error(error);\n }\n finally {\n this.disconnect();\n }\n }\n async render() {\n var _a;\n return (_a = this.renderPromise) !== null && _a !== void 0 ? _a : (this.renderPromise = (async () => {\n if (this.dispatchEvent(this.beforeRenderEvent)) {\n await nextAnimationFrame();\n this.performAction();\n }\n })());\n }\n disconnect() {\n try {\n this.remove();\n }\n catch (_a) { }\n }\n removeDuplicateTargetChildren() {\n this.duplicateChildren.forEach(c => c.remove());\n }\n get duplicateChildren() {\n var _a;\n const existingChildren = this.targetElements.flatMap(e => [...e.children]).filter(c => !!c.id);\n const newChildrenIds = [...(_a = this.templateContent) === null || _a === void 0 ? void 0 : _a.children].filter(c => !!c.id).map(c => c.id);\n return existingChildren.filter(c => newChildrenIds.includes(c.id));\n }\n get performAction() {\n if (this.action) {\n const actionFunction = StreamActions[this.action];\n if (actionFunction) {\n return actionFunction;\n }\n this.raise(\"unknown action\");\n }\n this.raise(\"action attribute is missing\");\n }\n get targetElements() {\n if (this.target) {\n return this.targetElementsById;\n }\n else if (this.targets) {\n return this.targetElementsByQuery;\n }\n else {\n this.raise(\"target or targets attribute is missing\");\n }\n }\n get templateContent() {\n return this.templateElement.content.cloneNode(true);\n }\n get templateElement() {\n if (this.firstElementChild instanceof HTMLTemplateElement) {\n return this.firstElementChild;\n }\n this.raise(\"first child element must be a