diff --git a/client/simple/src/js/main/results.ts b/client/simple/src/js/main/results.ts index 0f8692345..29cab399a 100644 --- a/client/simple/src/js/main/results.ts +++ b/client/simple/src/js/main/results.ts @@ -35,8 +35,9 @@ const imageLoader = (resultElement: HTMLElement): void => { }, 1000) as unknown as number; }; -const imageThumbnails: NodeListOf = - document.querySelectorAll("#urls img.image_thumbnail"); +const imageThumbnails: NodeListOf = document.querySelectorAll( + "#urls img.image_thumbnail, img.thumbnail" +); for (const thumbnail of imageThumbnails) { if (thumbnail.complete && thumbnail.naturalWidth === 0) { thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`; diff --git a/searx/static/themes/simple/chunk/B8prKeWj.min.js b/searx/static/themes/simple/chunk/B8prKeWj.min.js deleted file mode 100644 index 7fc2ae635..000000000 --- a/searx/static/themes/simple/chunk/B8prKeWj.min.js +++ /dev/null @@ -1,11 +0,0 @@ -import{i as e,n as t,r as n}from"../sxng-core.min.js";import{t as r}from"./DK4yUVpy.min.js"; -/*! -* swiped-events.js - v@version@ -* Pure JavaScript swipe events -* https://github.com/john-doherty/swiped-events -* @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element -* @author John Doherty -* @license MIT -*/ -(function(e,t){typeof e.CustomEvent!=`function`&&(e.CustomEvent=function(e,n){n||={bubbles:!1,cancelable:!1,detail:void 0};var r=t.createEvent(`CustomEvent`);return r.initCustomEvent(e,n.bubbles,n.cancelable,n.detail),r},e.CustomEvent.prototype=e.Event.prototype),t.addEventListener(`touchstart`,u,!1),t.addEventListener(`touchmove`,d,!1),t.addEventListener(`touchend`,l,!1);var n=null,r=null,i=null,a=null,o=null,s=null,c=0;function l(e){if(s===e.target){var l=parseInt(f(s,`data-swipe-threshold`,`20`),10),u=f(s,`data-swipe-unit`,`px`),d=parseInt(f(s,`data-swipe-timeout`,`500`),10),p=Date.now()-o,m=``,h=e.changedTouches||e.touches||[];if(u===`vh`&&(l=Math.round(l/100*t.documentElement.clientHeight)),u===`vw`&&(l=Math.round(l/100*t.documentElement.clientWidth)),Math.abs(i)>Math.abs(a)?Math.abs(i)>l&&p0?`swiped-left`:`swiped-right`):Math.abs(a)>l&&p0?`swiped-up`:`swiped-down`),m!==``){var g={dir:m.replace(/swiped-/,``),touchType:(h[0]||{}).touchType||`direct`,fingers:c,xStart:parseInt(n,10),xEnd:parseInt((h[0]||{}).clientX||-1,10),yStart:parseInt(r,10),yEnd:parseInt((h[0]||{}).clientY||-1,10)};s.dispatchEvent(new CustomEvent(`swiped`,{bubbles:!0,cancelable:!0,detail:g})),s.dispatchEvent(new CustomEvent(m,{bubbles:!0,cancelable:!0,detail:g}))}n=null,r=null,o=null}}function u(e){e.target.getAttribute(`data-swipe-ignore`)!==`true`&&(s=e.target,o=Date.now(),n=e.touches[0].clientX,r=e.touches[0].clientY,i=0,a=0,c=e.touches.length)}function d(e){if(!(!n||!r)){var t=e.touches[0].clientX,o=e.touches[0].clientY;i=n-t,a=r-o}}function f(e,n,r){for(;e&&e!==t.documentElement;){var i=e.getAttribute(n);if(i)return i;e=e.parentNode}return r}})(window,document);var i,a=t=>{i&&clearTimeout(i);let n=t.querySelector(`.result-images-source img`);if(!n)return;let r=t.querySelector(`.image_thumbnail`);if(r){if(r.src===`${e.theme_static_path}/img/img_load_error.svg`)return;n.onerror=()=>{n.src=r.src},n.src=r.src}let a=n.getAttribute(`data-src`);a&&(i=setTimeout(()=>{n.src=a,n.removeAttribute(`data-src`)},1e3))},o=document.querySelectorAll(`#urls img.image_thumbnail`);for(let t of o)t.complete&&t.naturalWidth===0&&(t.src=`${e.theme_static_path}/img/img_load_error.svg`),t.onerror=()=>{t.src=`${e.theme_static_path}/img/img_load_error.svg`};document.querySelector(`#search_url button#copy_url`)?.style.setProperty(`display`,`block`),n.selectImage=e=>{document.getElementById(`results`)?.classList.add(`image-detail-open`),window.location.hash=`#image-viewer`,n.scrollPageToSelected?.(),e&&a(e)},n.closeDetail=()=>{document.getElementById(`results`)?.classList.remove(`image-detail-open`),window.location.hash===`#image-viewer`&&window.history.back(),n.scrollPageToSelected?.()},t(`click`,`.btn-collapse`,function(){let e=this.getAttribute(`data-btn-text-collapsed`),t=this.getAttribute(`data-btn-text-not-collapsed`),n=this.getAttribute(`data-target`);if(!(n&&e&&t))return;let i=document.querySelector(n);r(i);let a=this.classList.contains(`collapsed`),o=a?t:e,s=a?e:t;this.innerHTML=this.innerHTML.replace(s,o),this.classList.toggle(`collapsed`),i.classList.toggle(`invisible`)}),t(`click`,`.media-loader`,function(){let e=this.getAttribute(`data-target`);if(!e)return;let t=document.querySelector(`${e} > iframe`);if(r(t),!t.getAttribute(`src`)){let e=t.getAttribute(`data-src`);e&&t.setAttribute(`src`,e)}}),t(`click`,`#copy_url`,async function(){let e=this.parentElement?.querySelector(`pre`);if(r(e),window.isSecureContext)await navigator.clipboard.writeText(e.innerText);else{let t=window.getSelection();if(t){let n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n),document.execCommand(`copy`)}}this.dataset.copiedText&&(this.innerText=this.dataset.copiedText)}),t(`click`,`.result-detail-close`,e=>{e.preventDefault(),n.closeDetail?.()}),t(`click`,`.result-detail-previous`,e=>{e.preventDefault(),n.selectPrevious?.(!1)}),t(`click`,`.result-detail-next`,e=>{e.preventDefault(),n.selectNext?.(!1)}),window.addEventListener(`hashchange`,()=>{window.location.hash!==`#image-viewer`&&n.closeDetail?.()});var s=document.querySelectorAll(`.swipe-horizontal`);for(let e of s)t(`swiped-left`,e,()=>{n.selectNext?.(!1)}),t(`swiped-right`,e,()=>{n.selectPrevious?.(!1)});window.addEventListener(`scroll`,()=>{let e=document.getElementById(`backToTop`),t=document.getElementById(`results`);if(e&&t){let e=(document.documentElement.scrollTop||document.body.scrollTop)>=100;t.classList.toggle(`scrolling`,e)}},!0); -//# sourceMappingURL=B8prKeWj.min.js.map \ No newline at end of file diff --git a/searx/static/themes/simple/chunk/B8prKeWj.min.js.map b/searx/static/themes/simple/chunk/B8prKeWj.min.js.map deleted file mode 100644 index 8359ac663..000000000 --- a/searx/static/themes/simple/chunk/B8prKeWj.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"B8prKeWj.min.js","names":[],"sources":["../../../../../client/simple/node_modules/swiped-events/src/swiped-events.js","../../../../../client/simple/src/js/main/results.ts"],"sourcesContent":["/*!\n * swiped-events.js - v@version@\n * Pure JavaScript swipe events\n * https://github.com/john-doherty/swiped-events\n * @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element\n * @author John Doherty \n * @license MIT\n */\n(function (window, document) {\n\n 'use strict';\n\n // patch CustomEvent to allow constructor creation (IE/Chrome)\n if (typeof window.CustomEvent !== 'function') {\n\n window.CustomEvent = function (event, params) {\n\n params = params || { bubbles: false, cancelable: false, detail: undefined };\n\n var evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n };\n\n window.CustomEvent.prototype = window.Event.prototype;\n }\n\n document.addEventListener('touchstart', handleTouchStart, false);\n document.addEventListener('touchmove', handleTouchMove, false);\n document.addEventListener('touchend', handleTouchEnd, false);\n\n var xDown = null;\n var yDown = null;\n var xDiff = null;\n var yDiff = null;\n var timeDown = null;\n var startEl = null;\n var touchCount = 0;\n\n /**\n * Fires swiped event if swipe detected on touchend\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchEnd(e) {\n\n // if the user released on a different target, cancel!\n if (startEl !== e.target) return;\n\n var swipeThreshold = parseInt(getNearestAttribute(startEl, 'data-swipe-threshold', '20'), 10); // default 20 units\n var swipeUnit = getNearestAttribute(startEl, 'data-swipe-unit', 'px'); // default px\n var swipeTimeout = parseInt(getNearestAttribute(startEl, 'data-swipe-timeout', '500'), 10); // default 500ms\n var timeDiff = Date.now() - timeDown;\n var eventType = '';\n var changedTouches = e.changedTouches || e.touches || [];\n\n if (swipeUnit === 'vh') {\n swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientHeight); // get percentage of viewport height in pixels\n }\n if (swipeUnit === 'vw') {\n swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientWidth); // get percentage of viewport height in pixels\n }\n\n if (Math.abs(xDiff) > Math.abs(yDiff)) { // most significant\n if (Math.abs(xDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n if (xDiff > 0) {\n eventType = 'swiped-left';\n }\n else {\n eventType = 'swiped-right';\n }\n }\n }\n else if (Math.abs(yDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n if (yDiff > 0) {\n eventType = 'swiped-up';\n }\n else {\n eventType = 'swiped-down';\n }\n }\n\n if (eventType !== '') {\n\n var eventData = {\n dir: eventType.replace(/swiped-/, ''),\n touchType: (changedTouches[0] || {}).touchType || 'direct',\n fingers: touchCount, // Number of fingers used\n xStart: parseInt(xDown, 10),\n xEnd: parseInt((changedTouches[0] || {}).clientX || -1, 10),\n yStart: parseInt(yDown, 10),\n yEnd: parseInt((changedTouches[0] || {}).clientY || -1, 10)\n };\n\n // fire `swiped` event event on the element that started the swipe\n startEl.dispatchEvent(new CustomEvent('swiped', { bubbles: true, cancelable: true, detail: eventData }));\n\n // fire `swiped-dir` event on the element that started the swipe\n startEl.dispatchEvent(new CustomEvent(eventType, { bubbles: true, cancelable: true, detail: eventData }));\n }\n\n // reset values\n xDown = null;\n yDown = null;\n timeDown = null;\n }\n /**\n * Records current location on touchstart event\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchStart(e) {\n\n // if the element has data-swipe-ignore=\"true\" we stop listening for swipe events\n if (e.target.getAttribute('data-swipe-ignore') === 'true') return;\n\n startEl = e.target;\n\n timeDown = Date.now();\n xDown = e.touches[0].clientX;\n yDown = e.touches[0].clientY;\n xDiff = 0;\n yDiff = 0;\n touchCount = e.touches.length;\n }\n\n /**\n * Records location diff in px on touchmove event\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchMove(e) {\n\n if (!xDown || !yDown) return;\n\n var xUp = e.touches[0].clientX;\n var yUp = e.touches[0].clientY;\n\n xDiff = xDown - xUp;\n yDiff = yDown - yUp;\n }\n\n /**\n * Gets attribute off HTML element or nearest parent\n * @param {object} el - HTML element to retrieve attribute from\n * @param {string} attributeName - name of the attribute\n * @param {any} defaultValue - default value to return if no match found\n * @returns {any} attribute value or defaultValue\n */\n function getNearestAttribute(el, attributeName, defaultValue) {\n\n // walk up the dom tree looking for attributeName\n while (el && el !== document.documentElement) {\n\n var attributeValue = el.getAttribute(attributeName);\n\n if (attributeValue) {\n return attributeValue;\n }\n\n el = el.parentNode;\n }\n\n return defaultValue;\n }\n\n}(window, document));\n","// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport \"../../../node_modules/swiped-events/src/swiped-events.js\";\nimport { listen, mutable, settings } from \"../toolkit.ts\";\nimport { assertElement } from \"../util/assertElement.ts\";\n\nlet imgTimeoutID: number;\n\nconst imageLoader = (resultElement: HTMLElement): void => {\n if (imgTimeoutID) clearTimeout(imgTimeoutID);\n\n const imgElement = resultElement.querySelector(\".result-images-source img\");\n if (!imgElement) return;\n\n // use thumbnail until full image loads\n const thumbnail = resultElement.querySelector(\".image_thumbnail\");\n if (thumbnail) {\n if (thumbnail.src === `${settings.theme_static_path}/img/img_load_error.svg`) return;\n\n imgElement.onerror = (): void => {\n imgElement.src = thumbnail.src;\n };\n\n imgElement.src = thumbnail.src;\n }\n\n const imgSource = imgElement.getAttribute(\"data-src\");\n if (!imgSource) return;\n\n // unsafe nodejs specific, cast to https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout#return_value\n // https://github.com/searxng/searxng/pull/5073#discussion_r2265767231\n imgTimeoutID = setTimeout(() => {\n imgElement.src = imgSource;\n imgElement.removeAttribute(\"data-src\");\n }, 1000) as unknown as number;\n};\n\nconst imageThumbnails: NodeListOf =\n document.querySelectorAll(\"#urls img.image_thumbnail\");\nfor (const thumbnail of imageThumbnails) {\n if (thumbnail.complete && thumbnail.naturalWidth === 0) {\n thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;\n }\n\n thumbnail.onerror = (): void => {\n thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;\n };\n}\n\nconst copyUrlButton: HTMLButtonElement | null =\n document.querySelector(\"#search_url button#copy_url\");\ncopyUrlButton?.style.setProperty(\"display\", \"block\");\n\nmutable.selectImage = (resultElement: HTMLElement): void => {\n // add a class that can be evaluated in the CSS and indicates that the\n // detail view is open\n const resultsElement = document.getElementById(\"results\");\n resultsElement?.classList.add(\"image-detail-open\");\n\n // add a hash to the browser history so that pressing back doesn't return\n // to the previous page this allows us to dismiss the image details on\n // pressing the back button on mobile devices\n window.location.hash = \"#image-viewer\";\n\n mutable.scrollPageToSelected?.();\n\n // if there is no element given by the caller, stop here\n if (!resultElement) return;\n\n imageLoader(resultElement);\n};\n\nmutable.closeDetail = (): void => {\n const resultsElement = document.getElementById(\"results\");\n resultsElement?.classList.remove(\"image-detail-open\");\n\n // remove #image-viewer hash from url by navigating back\n if (window.location.hash === \"#image-viewer\") {\n window.history.back();\n }\n\n mutable.scrollPageToSelected?.();\n};\n\nlisten(\"click\", \".btn-collapse\", function (this: HTMLElement) {\n const btnLabelCollapsed = this.getAttribute(\"data-btn-text-collapsed\");\n const btnLabelNotCollapsed = this.getAttribute(\"data-btn-text-not-collapsed\");\n const target = this.getAttribute(\"data-target\");\n\n if (!(target && btnLabelCollapsed && btnLabelNotCollapsed)) return;\n\n const targetElement = document.querySelector(target);\n assertElement(targetElement);\n\n const isCollapsed = this.classList.contains(\"collapsed\");\n const newLabel = isCollapsed ? btnLabelNotCollapsed : btnLabelCollapsed;\n const oldLabel = isCollapsed ? btnLabelCollapsed : btnLabelNotCollapsed;\n\n this.innerHTML = this.innerHTML.replace(oldLabel, newLabel);\n this.classList.toggle(\"collapsed\");\n\n targetElement.classList.toggle(\"invisible\");\n});\n\nlisten(\"click\", \".media-loader\", function (this: HTMLElement) {\n const target = this.getAttribute(\"data-target\");\n if (!target) return;\n\n const iframeLoad = document.querySelector(`${target} > iframe`);\n assertElement(iframeLoad);\n\n const srctest = iframeLoad.getAttribute(\"src\");\n if (!srctest) {\n const dataSrc = iframeLoad.getAttribute(\"data-src\");\n if (dataSrc) {\n iframeLoad.setAttribute(\"src\", dataSrc);\n }\n }\n});\n\nlisten(\"click\", \"#copy_url\", async function (this: HTMLElement) {\n const target = this.parentElement?.querySelector(\"pre\");\n assertElement(target);\n\n if (window.isSecureContext) {\n await navigator.clipboard.writeText(target.innerText);\n } else {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(target);\n selection.removeAllRanges();\n selection.addRange(range);\n document.execCommand(\"copy\");\n }\n }\n\n if (this.dataset.copiedText) {\n this.innerText = this.dataset.copiedText;\n }\n});\n\nlisten(\"click\", \".result-detail-close\", (event: Event) => {\n event.preventDefault();\n mutable.closeDetail?.();\n});\n\nlisten(\"click\", \".result-detail-previous\", (event: Event) => {\n event.preventDefault();\n mutable.selectPrevious?.(false);\n});\n\nlisten(\"click\", \".result-detail-next\", (event: Event) => {\n event.preventDefault();\n mutable.selectNext?.(false);\n});\n\n// listen for the back button to be pressed and dismiss the image details when called\nwindow.addEventListener(\"hashchange\", () => {\n if (window.location.hash !== \"#image-viewer\") {\n mutable.closeDetail?.();\n }\n});\n\nconst swipeHorizontal: NodeListOf = document.querySelectorAll(\".swipe-horizontal\");\nfor (const element of swipeHorizontal) {\n listen(\"swiped-left\", element, () => {\n mutable.selectNext?.(false);\n });\n\n listen(\"swiped-right\", element, () => {\n mutable.selectPrevious?.(false);\n });\n}\n\nwindow.addEventListener(\n \"scroll\",\n () => {\n const backToTopElement = document.getElementById(\"backToTop\");\n const resultsElement = document.getElementById(\"results\");\n\n if (backToTopElement && resultsElement) {\n const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;\n const isScrolling = scrollTop >= 100;\n resultsElement.classList.toggle(\"scrolling\", isScrolling);\n }\n },\n true\n);\n"],"x_google_ignoreList":[0],"mappings":"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"} \ No newline at end of file diff --git a/searx/static/themes/simple/chunk/od7pNHfk.min.js b/searx/static/themes/simple/chunk/od7pNHfk.min.js new file mode 100644 index 000000000..b8d6bb7d2 --- /dev/null +++ b/searx/static/themes/simple/chunk/od7pNHfk.min.js @@ -0,0 +1,11 @@ +import{i as e,n as t,r as n}from"../sxng-core.min.js";import{t as r}from"./DK4yUVpy.min.js"; +/*! +* swiped-events.js - v@version@ +* Pure JavaScript swipe events +* https://github.com/john-doherty/swiped-events +* @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element +* @author John Doherty +* @license MIT +*/ +(function(e,t){typeof e.CustomEvent!=`function`&&(e.CustomEvent=function(e,n){n||={bubbles:!1,cancelable:!1,detail:void 0};var r=t.createEvent(`CustomEvent`);return r.initCustomEvent(e,n.bubbles,n.cancelable,n.detail),r},e.CustomEvent.prototype=e.Event.prototype),t.addEventListener(`touchstart`,u,!1),t.addEventListener(`touchmove`,d,!1),t.addEventListener(`touchend`,l,!1);var n=null,r=null,i=null,a=null,o=null,s=null,c=0;function l(e){if(s===e.target){var l=parseInt(f(s,`data-swipe-threshold`,`20`),10),u=f(s,`data-swipe-unit`,`px`),d=parseInt(f(s,`data-swipe-timeout`,`500`),10),p=Date.now()-o,m=``,h=e.changedTouches||e.touches||[];if(u===`vh`&&(l=Math.round(l/100*t.documentElement.clientHeight)),u===`vw`&&(l=Math.round(l/100*t.documentElement.clientWidth)),Math.abs(i)>Math.abs(a)?Math.abs(i)>l&&p0?`swiped-left`:`swiped-right`):Math.abs(a)>l&&p0?`swiped-up`:`swiped-down`),m!==``){var g={dir:m.replace(/swiped-/,``),touchType:(h[0]||{}).touchType||`direct`,fingers:c,xStart:parseInt(n,10),xEnd:parseInt((h[0]||{}).clientX||-1,10),yStart:parseInt(r,10),yEnd:parseInt((h[0]||{}).clientY||-1,10)};s.dispatchEvent(new CustomEvent(`swiped`,{bubbles:!0,cancelable:!0,detail:g})),s.dispatchEvent(new CustomEvent(m,{bubbles:!0,cancelable:!0,detail:g}))}n=null,r=null,o=null}}function u(e){e.target.getAttribute(`data-swipe-ignore`)!==`true`&&(s=e.target,o=Date.now(),n=e.touches[0].clientX,r=e.touches[0].clientY,i=0,a=0,c=e.touches.length)}function d(e){if(!(!n||!r)){var t=e.touches[0].clientX,o=e.touches[0].clientY;i=n-t,a=r-o}}function f(e,n,r){for(;e&&e!==t.documentElement;){var i=e.getAttribute(n);if(i)return i;e=e.parentNode}return r}})(window,document);var i,a=t=>{i&&clearTimeout(i);let n=t.querySelector(`.result-images-source img`);if(!n)return;let r=t.querySelector(`.image_thumbnail`);if(r){if(r.src===`${e.theme_static_path}/img/img_load_error.svg`)return;n.onerror=()=>{n.src=r.src},n.src=r.src}let a=n.getAttribute(`data-src`);a&&(i=setTimeout(()=>{n.src=a,n.removeAttribute(`data-src`)},1e3))},o=document.querySelectorAll(`#urls img.image_thumbnail, img.thumbnail`);for(let t of o)t.complete&&t.naturalWidth===0&&(t.src=`${e.theme_static_path}/img/img_load_error.svg`),t.onerror=()=>{t.src=`${e.theme_static_path}/img/img_load_error.svg`};document.querySelector(`#search_url button#copy_url`)?.style.setProperty(`display`,`block`),n.selectImage=e=>{document.getElementById(`results`)?.classList.add(`image-detail-open`),window.location.hash=`#image-viewer`,n.scrollPageToSelected?.(),e&&a(e)},n.closeDetail=()=>{document.getElementById(`results`)?.classList.remove(`image-detail-open`),window.location.hash===`#image-viewer`&&window.history.back(),n.scrollPageToSelected?.()},t(`click`,`.btn-collapse`,function(){let e=this.getAttribute(`data-btn-text-collapsed`),t=this.getAttribute(`data-btn-text-not-collapsed`),n=this.getAttribute(`data-target`);if(!(n&&e&&t))return;let i=document.querySelector(n);r(i);let a=this.classList.contains(`collapsed`),o=a?t:e,s=a?e:t;this.innerHTML=this.innerHTML.replace(s,o),this.classList.toggle(`collapsed`),i.classList.toggle(`invisible`)}),t(`click`,`.media-loader`,function(){let e=this.getAttribute(`data-target`);if(!e)return;let t=document.querySelector(`${e} > iframe`);if(r(t),!t.getAttribute(`src`)){let e=t.getAttribute(`data-src`);e&&t.setAttribute(`src`,e)}}),t(`click`,`#copy_url`,async function(){let e=this.parentElement?.querySelector(`pre`);if(r(e),window.isSecureContext)await navigator.clipboard.writeText(e.innerText);else{let t=window.getSelection();if(t){let n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n),document.execCommand(`copy`)}}this.dataset.copiedText&&(this.innerText=this.dataset.copiedText)}),t(`click`,`.result-detail-close`,e=>{e.preventDefault(),n.closeDetail?.()}),t(`click`,`.result-detail-previous`,e=>{e.preventDefault(),n.selectPrevious?.(!1)}),t(`click`,`.result-detail-next`,e=>{e.preventDefault(),n.selectNext?.(!1)}),window.addEventListener(`hashchange`,()=>{window.location.hash!==`#image-viewer`&&n.closeDetail?.()});var s=document.querySelectorAll(`.swipe-horizontal`);for(let e of s)t(`swiped-left`,e,()=>{n.selectNext?.(!1)}),t(`swiped-right`,e,()=>{n.selectPrevious?.(!1)});window.addEventListener(`scroll`,()=>{let e=document.getElementById(`backToTop`),t=document.getElementById(`results`);if(e&&t){let e=(document.documentElement.scrollTop||document.body.scrollTop)>=100;t.classList.toggle(`scrolling`,e)}},!0); +//# sourceMappingURL=od7pNHfk.min.js.map \ No newline at end of file diff --git a/searx/static/themes/simple/chunk/od7pNHfk.min.js.map b/searx/static/themes/simple/chunk/od7pNHfk.min.js.map new file mode 100644 index 000000000..5e80d937e --- /dev/null +++ b/searx/static/themes/simple/chunk/od7pNHfk.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"od7pNHfk.min.js","names":[],"sources":["../../../../../client/simple/node_modules/swiped-events/src/swiped-events.js","../../../../../client/simple/src/js/main/results.ts"],"sourcesContent":["/*!\n * swiped-events.js - v@version@\n * Pure JavaScript swipe events\n * https://github.com/john-doherty/swiped-events\n * @inspiration https://stackoverflow.com/questions/16348031/disable-scrolling-when-touch-moving-certain-element\n * @author John Doherty \n * @license MIT\n */\n(function (window, document) {\n\n 'use strict';\n\n // patch CustomEvent to allow constructor creation (IE/Chrome)\n if (typeof window.CustomEvent !== 'function') {\n\n window.CustomEvent = function (event, params) {\n\n params = params || { bubbles: false, cancelable: false, detail: undefined };\n\n var evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n };\n\n window.CustomEvent.prototype = window.Event.prototype;\n }\n\n document.addEventListener('touchstart', handleTouchStart, false);\n document.addEventListener('touchmove', handleTouchMove, false);\n document.addEventListener('touchend', handleTouchEnd, false);\n\n var xDown = null;\n var yDown = null;\n var xDiff = null;\n var yDiff = null;\n var timeDown = null;\n var startEl = null;\n var touchCount = 0;\n\n /**\n * Fires swiped event if swipe detected on touchend\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchEnd(e) {\n\n // if the user released on a different target, cancel!\n if (startEl !== e.target) return;\n\n var swipeThreshold = parseInt(getNearestAttribute(startEl, 'data-swipe-threshold', '20'), 10); // default 20 units\n var swipeUnit = getNearestAttribute(startEl, 'data-swipe-unit', 'px'); // default px\n var swipeTimeout = parseInt(getNearestAttribute(startEl, 'data-swipe-timeout', '500'), 10); // default 500ms\n var timeDiff = Date.now() - timeDown;\n var eventType = '';\n var changedTouches = e.changedTouches || e.touches || [];\n\n if (swipeUnit === 'vh') {\n swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientHeight); // get percentage of viewport height in pixels\n }\n if (swipeUnit === 'vw') {\n swipeThreshold = Math.round((swipeThreshold / 100) * document.documentElement.clientWidth); // get percentage of viewport height in pixels\n }\n\n if (Math.abs(xDiff) > Math.abs(yDiff)) { // most significant\n if (Math.abs(xDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n if (xDiff > 0) {\n eventType = 'swiped-left';\n }\n else {\n eventType = 'swiped-right';\n }\n }\n }\n else if (Math.abs(yDiff) > swipeThreshold && timeDiff < swipeTimeout) {\n if (yDiff > 0) {\n eventType = 'swiped-up';\n }\n else {\n eventType = 'swiped-down';\n }\n }\n\n if (eventType !== '') {\n\n var eventData = {\n dir: eventType.replace(/swiped-/, ''),\n touchType: (changedTouches[0] || {}).touchType || 'direct',\n fingers: touchCount, // Number of fingers used\n xStart: parseInt(xDown, 10),\n xEnd: parseInt((changedTouches[0] || {}).clientX || -1, 10),\n yStart: parseInt(yDown, 10),\n yEnd: parseInt((changedTouches[0] || {}).clientY || -1, 10)\n };\n\n // fire `swiped` event event on the element that started the swipe\n startEl.dispatchEvent(new CustomEvent('swiped', { bubbles: true, cancelable: true, detail: eventData }));\n\n // fire `swiped-dir` event on the element that started the swipe\n startEl.dispatchEvent(new CustomEvent(eventType, { bubbles: true, cancelable: true, detail: eventData }));\n }\n\n // reset values\n xDown = null;\n yDown = null;\n timeDown = null;\n }\n /**\n * Records current location on touchstart event\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchStart(e) {\n\n // if the element has data-swipe-ignore=\"true\" we stop listening for swipe events\n if (e.target.getAttribute('data-swipe-ignore') === 'true') return;\n\n startEl = e.target;\n\n timeDown = Date.now();\n xDown = e.touches[0].clientX;\n yDown = e.touches[0].clientY;\n xDiff = 0;\n yDiff = 0;\n touchCount = e.touches.length;\n }\n\n /**\n * Records location diff in px on touchmove event\n * @param {object} e - browser event object\n * @returns {void}\n */\n function handleTouchMove(e) {\n\n if (!xDown || !yDown) return;\n\n var xUp = e.touches[0].clientX;\n var yUp = e.touches[0].clientY;\n\n xDiff = xDown - xUp;\n yDiff = yDown - yUp;\n }\n\n /**\n * Gets attribute off HTML element or nearest parent\n * @param {object} el - HTML element to retrieve attribute from\n * @param {string} attributeName - name of the attribute\n * @param {any} defaultValue - default value to return if no match found\n * @returns {any} attribute value or defaultValue\n */\n function getNearestAttribute(el, attributeName, defaultValue) {\n\n // walk up the dom tree looking for attributeName\n while (el && el !== document.documentElement) {\n\n var attributeValue = el.getAttribute(attributeName);\n\n if (attributeValue) {\n return attributeValue;\n }\n\n el = el.parentNode;\n }\n\n return defaultValue;\n }\n\n}(window, document));\n","// SPDX-License-Identifier: AGPL-3.0-or-later\n\nimport \"../../../node_modules/swiped-events/src/swiped-events.js\";\nimport { listen, mutable, settings } from \"../toolkit.ts\";\nimport { assertElement } from \"../util/assertElement.ts\";\n\nlet imgTimeoutID: number;\n\nconst imageLoader = (resultElement: HTMLElement): void => {\n if (imgTimeoutID) clearTimeout(imgTimeoutID);\n\n const imgElement = resultElement.querySelector(\".result-images-source img\");\n if (!imgElement) return;\n\n // use thumbnail until full image loads\n const thumbnail = resultElement.querySelector(\".image_thumbnail\");\n if (thumbnail) {\n if (thumbnail.src === `${settings.theme_static_path}/img/img_load_error.svg`) return;\n\n imgElement.onerror = (): void => {\n imgElement.src = thumbnail.src;\n };\n\n imgElement.src = thumbnail.src;\n }\n\n const imgSource = imgElement.getAttribute(\"data-src\");\n if (!imgSource) return;\n\n // unsafe nodejs specific, cast to https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout#return_value\n // https://github.com/searxng/searxng/pull/5073#discussion_r2265767231\n imgTimeoutID = setTimeout(() => {\n imgElement.src = imgSource;\n imgElement.removeAttribute(\"data-src\");\n }, 1000) as unknown as number;\n};\n\nconst imageThumbnails: NodeListOf = document.querySelectorAll(\n \"#urls img.image_thumbnail, img.thumbnail\"\n);\nfor (const thumbnail of imageThumbnails) {\n if (thumbnail.complete && thumbnail.naturalWidth === 0) {\n thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;\n }\n\n thumbnail.onerror = (): void => {\n thumbnail.src = `${settings.theme_static_path}/img/img_load_error.svg`;\n };\n}\n\nconst copyUrlButton: HTMLButtonElement | null =\n document.querySelector(\"#search_url button#copy_url\");\ncopyUrlButton?.style.setProperty(\"display\", \"block\");\n\nmutable.selectImage = (resultElement: HTMLElement): void => {\n // add a class that can be evaluated in the CSS and indicates that the\n // detail view is open\n const resultsElement = document.getElementById(\"results\");\n resultsElement?.classList.add(\"image-detail-open\");\n\n // add a hash to the browser history so that pressing back doesn't return\n // to the previous page this allows us to dismiss the image details on\n // pressing the back button on mobile devices\n window.location.hash = \"#image-viewer\";\n\n mutable.scrollPageToSelected?.();\n\n // if there is no element given by the caller, stop here\n if (!resultElement) return;\n\n imageLoader(resultElement);\n};\n\nmutable.closeDetail = (): void => {\n const resultsElement = document.getElementById(\"results\");\n resultsElement?.classList.remove(\"image-detail-open\");\n\n // remove #image-viewer hash from url by navigating back\n if (window.location.hash === \"#image-viewer\") {\n window.history.back();\n }\n\n mutable.scrollPageToSelected?.();\n};\n\nlisten(\"click\", \".btn-collapse\", function (this: HTMLElement) {\n const btnLabelCollapsed = this.getAttribute(\"data-btn-text-collapsed\");\n const btnLabelNotCollapsed = this.getAttribute(\"data-btn-text-not-collapsed\");\n const target = this.getAttribute(\"data-target\");\n\n if (!(target && btnLabelCollapsed && btnLabelNotCollapsed)) return;\n\n const targetElement = document.querySelector(target);\n assertElement(targetElement);\n\n const isCollapsed = this.classList.contains(\"collapsed\");\n const newLabel = isCollapsed ? btnLabelNotCollapsed : btnLabelCollapsed;\n const oldLabel = isCollapsed ? btnLabelCollapsed : btnLabelNotCollapsed;\n\n this.innerHTML = this.innerHTML.replace(oldLabel, newLabel);\n this.classList.toggle(\"collapsed\");\n\n targetElement.classList.toggle(\"invisible\");\n});\n\nlisten(\"click\", \".media-loader\", function (this: HTMLElement) {\n const target = this.getAttribute(\"data-target\");\n if (!target) return;\n\n const iframeLoad = document.querySelector(`${target} > iframe`);\n assertElement(iframeLoad);\n\n const srctest = iframeLoad.getAttribute(\"src\");\n if (!srctest) {\n const dataSrc = iframeLoad.getAttribute(\"data-src\");\n if (dataSrc) {\n iframeLoad.setAttribute(\"src\", dataSrc);\n }\n }\n});\n\nlisten(\"click\", \"#copy_url\", async function (this: HTMLElement) {\n const target = this.parentElement?.querySelector(\"pre\");\n assertElement(target);\n\n if (window.isSecureContext) {\n await navigator.clipboard.writeText(target.innerText);\n } else {\n const selection = window.getSelection();\n if (selection) {\n const range = document.createRange();\n range.selectNodeContents(target);\n selection.removeAllRanges();\n selection.addRange(range);\n document.execCommand(\"copy\");\n }\n }\n\n if (this.dataset.copiedText) {\n this.innerText = this.dataset.copiedText;\n }\n});\n\nlisten(\"click\", \".result-detail-close\", (event: Event) => {\n event.preventDefault();\n mutable.closeDetail?.();\n});\n\nlisten(\"click\", \".result-detail-previous\", (event: Event) => {\n event.preventDefault();\n mutable.selectPrevious?.(false);\n});\n\nlisten(\"click\", \".result-detail-next\", (event: Event) => {\n event.preventDefault();\n mutable.selectNext?.(false);\n});\n\n// listen for the back button to be pressed and dismiss the image details when called\nwindow.addEventListener(\"hashchange\", () => {\n if (window.location.hash !== \"#image-viewer\") {\n mutable.closeDetail?.();\n }\n});\n\nconst swipeHorizontal: NodeListOf = document.querySelectorAll(\".swipe-horizontal\");\nfor (const element of swipeHorizontal) {\n listen(\"swiped-left\", element, () => {\n mutable.selectNext?.(false);\n });\n\n listen(\"swiped-right\", element, () => {\n mutable.selectPrevious?.(false);\n });\n}\n\nwindow.addEventListener(\n \"scroll\",\n () => {\n const backToTopElement = document.getElementById(\"backToTop\");\n const resultsElement = document.getElementById(\"results\");\n\n if (backToTopElement && resultsElement) {\n const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;\n const isScrolling = scrollTop >= 100;\n resultsElement.classList.toggle(\"scrolling\", isScrolling);\n }\n },\n true\n);\n"],"x_google_ignoreList":[0],"mappings":"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"} \ No newline at end of file diff --git a/searx/static/themes/simple/manifest.json b/searx/static/themes/simple/manifest.json index ae948fd68..d4a3ebd5f 100644 --- a/searx/static/themes/simple/manifest.json +++ b/searx/static/themes/simple/manifest.json @@ -57,7 +57,7 @@ ] }, "src/js/main/results.ts": { - "file": "chunk/B8prKeWj.min.js", + "file": "chunk/od7pNHfk.min.js", "name": "results", "src": "src/js/main/results.ts", "isDynamicEntry": true, diff --git a/searx/static/themes/simple/sxng-core.min.js b/searx/static/themes/simple/sxng-core.min.js index 58ce2e603..e05b2668f 100644 --- a/searx/static/themes/simple/sxng-core.min.js +++ b/searx/static/themes/simple/sxng-core.min.js @@ -1,3 +1,3 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./chunk/BnnvKC7b.min.js","./sxng-mapview.min.css","./chunk/DpvWr1cn.min.js","./chunk/DK4yUVpy.min.js","./chunk/DcK-mo-Y.min.js","./chunk/C8c7HJzp.min.js","./chunk/C93hSkpT.min.js","./chunk/5Ako-qGW.min.js","./chunk/DvCYLbJr.min.js","./chunk/B8prKeWj.min.js","./chunk/e2-9fzwE.min.js"])))=>i.map(i=>d[i]); -var e=class{id;constructor(e){this.id=e,queueMicrotask(()=>this.invoke())}async invoke(){try{console.debug(`[PLUGIN] ${this.id}: Running...`);let e=await this.run();if(!e)return;console.debug(`[PLUGIN] ${this.id}: Running post-exec...`),await this.post(e)}catch(e){console.error(`[PLUGIN] ${this.id}:`,e)}finally{console.debug(`[PLUGIN] ${this.id}: Done.`)}}},t={index:`index`,results:`results`,preferences:`preferences`,unknown:`unknown`},n={closeDetail:void 0,scrollPageToSelected:void 0,selectImage:void 0,selectNext:void 0,selectPrevious:void 0},r=()=>{let e=document.querySelector(`meta[name="endpoint"]`)?.getAttribute(`content`);return e&&e in t?e:t.unknown},i=()=>{let e=document.querySelector(`script[client_settings]`)?.getAttribute(`client_settings`);if(!e)return{};try{return JSON.parse(atob(e))}catch(e){return console.error(`Failed to load client_settings:`,e),{}}},a=async(e,t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),n?.timeout??3e4),a=await fetch(t,{body:n?.body,method:e,signal:r.signal}).finally(()=>clearTimeout(i));if(!a.ok)throw Error(a.statusText);return a},o=(e,t,n,r)=>{if(typeof t!=`string`){t.addEventListener(e,n,r);return}document.addEventListener(e,e=>{for(let r of e.composedPath())if(r instanceof HTMLElement&&r.matches(t)){try{n.call(r,e)}catch(e){console.error(e)}break}},r)},s=(e,t)=>{for(let e of t?.on??[])if(!e)return;document.readyState===`loading`?o(`DOMContentLoaded`,document,e,{once:!0}):e()},c=r(),l=i(),u=(e,t)=>{d(t)&&e()},d=e=>{switch(e.on){case`global`:return!0;case`endpoint`:return!!e.where.includes(c)}},f=`modulepreload`,p=function(e,t){return new URL(e,t).href},m={},h=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,new URL(`../../../src/node/plugins/importAnalysisBuild.ts`,import.meta.url)).href}r=o(t.map(t=>{if(t=p(t,n),t=s(t),t in m)return;m[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:f,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};s(()=>{document.documentElement.classList.remove(`no-js`),document.documentElement.classList.add(`js`),o(`click`,`.close`,function(){this.parentNode?.classList.add(`invisible`)}),o(`click`,`.searxng_init_map`,async function(e){e.preventDefault(),this.classList.remove(`searxng_init_map`),u(()=>h(async()=>{let{default:e}=await import(`./chunk/BnnvKC7b.min.js`);return{default:e}},__vite__mapDeps([0,1]),import.meta.url).then(({default:e})=>new e(this)),{on:`endpoint`,where:[t.results]})}),l.plugins?.includes(`infiniteScroll`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/DpvWr1cn.min.js`);return{default:e}},__vite__mapDeps([2,3,4]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]}),l.plugins?.includes(`calculator`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/C8c7HJzp.min.js`);return{default:e}},__vite__mapDeps([5,4,3]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]})}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.index]}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/B8prKeWj.min.js`),__vite__mapDeps([9,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.results]}),s(()=>{h(()=>import(`./chunk/e2-9fzwE.min.js`),__vite__mapDeps([10,3]),import.meta.url)},{on:[c===t.preferences]});export{e as a,l as i,o as n,n as r,a as t}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./chunk/BnnvKC7b.min.js","./sxng-mapview.min.css","./chunk/DpvWr1cn.min.js","./chunk/DK4yUVpy.min.js","./chunk/DcK-mo-Y.min.js","./chunk/C8c7HJzp.min.js","./chunk/C93hSkpT.min.js","./chunk/5Ako-qGW.min.js","./chunk/DvCYLbJr.min.js","./chunk/od7pNHfk.min.js","./chunk/e2-9fzwE.min.js"])))=>i.map(i=>d[i]); +var e=class{id;constructor(e){this.id=e,queueMicrotask(()=>this.invoke())}async invoke(){try{console.debug(`[PLUGIN] ${this.id}: Running...`);let e=await this.run();if(!e)return;console.debug(`[PLUGIN] ${this.id}: Running post-exec...`),await this.post(e)}catch(e){console.error(`[PLUGIN] ${this.id}:`,e)}finally{console.debug(`[PLUGIN] ${this.id}: Done.`)}}},t={index:`index`,results:`results`,preferences:`preferences`,unknown:`unknown`},n={closeDetail:void 0,scrollPageToSelected:void 0,selectImage:void 0,selectNext:void 0,selectPrevious:void 0},r=()=>{let e=document.querySelector(`meta[name="endpoint"]`)?.getAttribute(`content`);return e&&e in t?e:t.unknown},i=()=>{let e=document.querySelector(`script[client_settings]`)?.getAttribute(`client_settings`);if(!e)return{};try{return JSON.parse(atob(e))}catch(e){return console.error(`Failed to load client_settings:`,e),{}}},a=async(e,t,n)=>{let r=new AbortController,i=setTimeout(()=>r.abort(),n?.timeout??3e4),a=await fetch(t,{body:n?.body,method:e,signal:r.signal}).finally(()=>clearTimeout(i));if(!a.ok)throw Error(a.statusText);return a},o=(e,t,n,r)=>{if(typeof t!=`string`){t.addEventListener(e,n,r);return}document.addEventListener(e,e=>{for(let r of e.composedPath())if(r instanceof HTMLElement&&r.matches(t)){try{n.call(r,e)}catch(e){console.error(e)}break}},r)},s=(e,t)=>{for(let e of t?.on??[])if(!e)return;document.readyState===`loading`?o(`DOMContentLoaded`,document,e,{once:!0}):e()},c=r(),l=i(),u=(e,t)=>{d(t)&&e()},d=e=>{switch(e.on){case`global`:return!0;case`endpoint`:return!!e.where.includes(c)}},f=`modulepreload`,p=function(e,t){return new URL(e,t).href},m={},h=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,new URL(`../../../src/node/plugins/importAnalysisBuild.ts`,import.meta.url)).href}r=o(t.map(t=>{if(t=p(t,n),t=s(t),t in m)return;m[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:f,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};s(()=>{document.documentElement.classList.remove(`no-js`),document.documentElement.classList.add(`js`),o(`click`,`.close`,function(){this.parentNode?.classList.add(`invisible`)}),o(`click`,`.searxng_init_map`,async function(e){e.preventDefault(),this.classList.remove(`searxng_init_map`),u(()=>h(async()=>{let{default:e}=await import(`./chunk/BnnvKC7b.min.js`);return{default:e}},__vite__mapDeps([0,1]),import.meta.url).then(({default:e})=>new e(this)),{on:`endpoint`,where:[t.results]})}),l.plugins?.includes(`infiniteScroll`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/DpvWr1cn.min.js`);return{default:e}},__vite__mapDeps([2,3,4]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]}),l.plugins?.includes(`calculator`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/C8c7HJzp.min.js`);return{default:e}},__vite__mapDeps([5,4,3]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]})}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.index]}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([6,3]),import.meta.url),h(()=>import(`./chunk/od7pNHfk.min.js`),__vite__mapDeps([9,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([7,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/DvCYLbJr.min.js`),__vite__mapDeps([8,3]),import.meta.url)},{on:[c===t.results]}),s(()=>{h(()=>import(`./chunk/e2-9fzwE.min.js`),__vite__mapDeps([10,3]),import.meta.url)},{on:[c===t.preferences]});export{e as a,l as i,o as n,n as r,a as t}; //# sourceMappingURL=sxng-core.min.js.map \ No newline at end of file