[feat] plugin: AI summary of search results from a self-hosted LLM

Adds an optional plugin that shows a generated summary above the search
results, similar to the answer boxes in Brave and Google.  The text is
produced by an LLM server the administrator runs, reached over the
OpenAI chat completions API, so queries never leave the operator's own
network.

The summary is grounded on the top search results rather than the
model's training data.  It is generated asynchronously: post_search adds
an empty placeholder and returns, and the browser fills it from the
/ai_summary endpoint, which streams the answer as NDJSON.  No summary is
generated beyond page one, outside the general category, for non-HTML
formats, or when an engine already answered with an infobox or an
instant answer.

The client side follows the existing plugin pattern: one file in
client/simple/src/js/plugin/, one conditional load in router.ts, one
LESS import.  No build configuration changes and no new dependencies.

The plugin is not activated by default.  Instance defaults live in an
ai_summary: section; the server, model, API key and grounding are user
preferences, and all four can be locked.

Signed-off-by: Jason Witty <jasonpwitty+github@proton.me>
This commit is contained in:
Jason Witty
2026-08-15 19:55:07 -07:00
committed by jasonwitty
parent 094c33d406
commit f4a003d355
43 changed files with 1951 additions and 54 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-2
View File
@@ -1,2 +0,0 @@
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.`)}}};export{e as t};
//# sourceMappingURL=BuurKv-k.min.js.map
@@ -1 +0,0 @@
{"version":3,"file":"BuurKv-k.min.js","names":[],"sources":["../../../../../client/simple/src/js/Plugin.ts"],"sourcesContent":["// SPDX-License-Identifier: AGPL-3.0-or-later\n\n/**\n * Base class for client-side plugins.\n *\n * @remarks\n * Handle conditional loading of the plugin in:\n *\n * - client/simple/src/js/router.ts\n *\n * @abstract\n */\nexport abstract class Plugin {\n /**\n * Plugin name.\n */\n protected readonly id: string;\n\n /**\n * @remarks\n * Don't hold references of this instance outside the class.\n */\n protected constructor(id: string) {\n this.id = id;\n\n queueMicrotask(() => this.invoke());\n }\n\n private async invoke(): Promise<void> {\n try {\n console.debug(`[PLUGIN] ${this.id}: Running...`);\n const result = await this.run();\n if (!result) return;\n\n console.debug(`[PLUGIN] ${this.id}: Running post-exec...`);\n // @ts-expect-error\n void (await this.post(result as NonNullable<Awaited<ReturnType<this[\"run\"]>>>));\n } catch (error) {\n console.error(`[PLUGIN] ${this.id}:`, error);\n } finally {\n console.debug(`[PLUGIN] ${this.id}: Done.`);\n }\n }\n\n /**\n * Plugin goes here.\n *\n * @remarks\n * The plugin is already loaded at this point. If you wish to execute\n * conditions to exit early, consider moving the logic to:\n *\n * - client/simple/src/js/router.ts\n *\n * ...to avoid unnecessarily loading this plugin on the client.\n */\n protected abstract run(): Promise<unknown>;\n\n /**\n * Post-execution hook.\n *\n * @remarks\n * The hook is only executed if `#run()` returns a truthy value.\n */\n // @ts-expect-error\n protected abstract post(result: NonNullable<Awaited<ReturnType<this[\"run\"]>>>): Promise<void>;\n}\n"],"mappings":"AAYA,IAAsB,EAAtB,KAA6B,CAI3B,GAMA,YAAsB,EAAY,CAChC,KAAK,GAAK,EAEV,mBAAqB,KAAK,OAAO,CAAC,CACpC,CAEA,MAAc,QAAwB,CACpC,GAAI,CACF,QAAQ,MAAM,YAAY,KAAK,GAAG,aAAa,EAC/C,IAAM,EAAS,MAAM,KAAK,IAAI,EAC9B,GAAI,CAAC,EAAQ,OAEb,QAAQ,MAAM,YAAY,KAAK,GAAG,uBAAuB,EAEzD,MAAY,KAAK,KAAK,CAAuD,CAC/E,OAAS,EAAO,CACd,QAAQ,MAAM,YAAY,KAAK,GAAG,GAAI,CAAK,CAC7C,QAAU,CACR,QAAQ,MAAM,YAAY,KAAK,GAAG,QAAQ,CAC5C,CACF,CAuBF"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-2
View File
@@ -1,2 +0,0 @@
import{t as e}from"./BuurKv-k.min.js";import{i as t,t as n}from"../sxng-core.min.js";import{t as r}from"./DK4yUVpy.min.js";import{t as i}from"./DcK-mo-Y.min.js";var a=class extends e{constructor(){super(`infiniteScroll`)}async run(){let e=i(`results`).classList.contains(`only_template_images`),a=`article.result:last-child`,o=document.createElement(`div`);o.className=`loader`;let s=async i=>{let a=document.querySelector(`#search`);r(a);let s=document.querySelector(`#pagination form.next_page`);r(s);let c=a.getAttribute(`action`);if(!c)throw Error(`Form action not defined`);let l=document.querySelector(`#pagination`);r(l),l.replaceChildren(o);try{let t=await(await n(`POST`,c,{body:new FormData(s)})).text();if(!t)return;let r=new DOMParser().parseFromString(t,`text/html`),a=r.querySelectorAll(`#urls article`),o=r.querySelector(`#pagination`);document.querySelector(`#pagination`)?.remove();let l=document.querySelector(`#urls`);if(!l)throw Error(`URLs element not found`);a.length>0&&!e&&l.appendChild(document.createElement(`hr`)),l.append(...a),o&&(document.querySelector(`#results`)?.appendChild(o),i())}catch(e){console.error(`Error loading next page:`,e);let n=Object.assign(document.createElement(`div`),{textContent:t.translations?.error_loading_next_page??`Error loading next page`,className:`dialog-error`});n.setAttribute(`role`,`alert`),document.querySelector(`#pagination`)?.replaceChildren(n)}},c=new IntersectionObserver(async e=>{let[t]=e;t?.isIntersecting&&(c.unobserve(t.target),await s(()=>{let e=document.querySelector(a);e&&c.observe(e)}))},{rootMargin:`320px`}),l=document.querySelector(a);l&&c.observe(l)}async post(){}};export{a as default};
//# sourceMappingURL=D3mcqWOe.min.js.map
+4
View File
@@ -0,0 +1,4 @@
import{a as e,i as t}from"../sxng-core.min.js";import{t as n}from"./DK4yUVpy.min.js";var r=5,i=12,a=300,o=1e3,s=class s extends e{messages=[];context=[];controller;constructor(){super(`ai_summary`)}async run(){let e=document.getElementById(`ai_summary`);if(e)try{let{query:t}=e.dataset;if(!t)return;e.dataset.grounding===`1`&&(this.context=s.collectContext()),this.wireControls(e),this.messages.push({role:`user`,content:t}),await this.exchange(e)}catch(t){s.showError(e,t)}}async post(){}static collectContext(){let e=[];for(let t of document.querySelectorAll(`#urls article.result`)){if(e.length>=r)break;let n=t.querySelector(`h3 a`);n&&e.push({title:(n.textContent??``).trim().slice(0,a),url:n.href,snippet:(t.querySelector(`.content`)?.textContent??``).trim().slice(0,o)})}return e}wireControls(e){let t=e.querySelector(`.ai-summary-body`),r=e.querySelector(`.ai-summary-more`),a=e.querySelector(`.ai-summary-followup`);n(t),n(r),n(a),r.addEventListener(`click`,()=>{let e=t.classList.toggle(`collapsed`);r.textContent=e?r.dataset.btnTextCollapsed??``:r.dataset.btnTextNotCollapsed??``,a.classList.toggle(`invisible`,e)}),a.addEventListener(`submit`,t=>{t.preventDefault();let r=a.querySelector(`input`);n(r);let o=r.value.trim();if(!o||this.controller)return;r.value=``,this.messages.push({role:`user`,content:o}),this.messages.splice(0,this.messages.length-(i-1));let s=Object.assign(document.createElement(`p`),{textContent:o,className:`ai-summary-question`});e.querySelector(`.ai-summary-answers`)?.append(s),this.exchange(e)})}async exchange(e){let t=e.querySelector(`.ai-summary-answers`);n(t);let r=Object.assign(document.createElement(`p`),{className:`ai-summary-content typing`});t.append(r);let i=new AbortController;this.controller=i;let a=``,o=t=>{if(!t.trim())return;let n=JSON.parse(t);if(n.error)throw Error(n.error);if(n.delta&&(a+=n.delta,r.textContent=a,this.updateMoreButton(e)),n.done&&n.model){let t=e.querySelector(`.ai-summary-model`);t&&(t.textContent=n.model)}};try{let e=await fetch(`./ai_summary`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({messages:this.messages,context:this.context}),signal:i.signal});if(!e.ok)throw Error(`HTTP ${e.status}`);if(e.body){let t=e.body.getReader(),n=new TextDecoder,r=``;for(;;){let{done:e,value:i}=await t.read();if(e)break;r+=n.decode(i,{stream:!0});let a=r.split(`
`);r=a.pop()??``;for(let e of a)o(e)}o(r)}else{let t=await e.text();for(let e of t.split(`
`))o(e)}this.messages.push({role:`assistant`,content:a})}catch(t){s.showError(e,t)}finally{r.classList.remove(`typing`),this.controller=void 0,this.updateMoreButton(e)}}static showError(e,n){console.error(`Error loading AI summary:`,n);let r=t.translations?.error_loading_ai_summary??`Error loading the AI summary`,i=n instanceof Error&&n.message?` (${n.message})`:``,a=Object.assign(document.createElement(`div`),{textContent:`${r}${i}`,className:`dialog-error`});a.setAttribute(`role`,`alert`),(e.querySelector(`.ai-summary-answers`)??e).append(a)}updateMoreButton(e){let t=e.querySelector(`.ai-summary-body`),n=e.querySelector(`.ai-summary-more`);t&&n&&(!t.classList.contains(`collapsed`)||t.scrollHeight>t.clientHeight+4)&&n.classList.remove(`invisible`)}};export{s as default};
//# sourceMappingURL=DBBLNmaq.min.js.map
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
import{a as e,i as t,t as n}from"../sxng-core.min.js";import{t as r}from"./DK4yUVpy.min.js";import{t as i}from"./DcK-mo-Y.min.js";var a=class extends e{constructor(){super(`infiniteScroll`)}async run(){let e=i(`results`).classList.contains(`only_template_images`),a=`article.result:last-child`,o=document.createElement(`div`);o.className=`loader`;let s=async i=>{let a=document.querySelector(`#search`);r(a);let s=document.querySelector(`#pagination form.next_page`);r(s);let c=a.getAttribute(`action`);if(!c)throw Error(`Form action not defined`);let l=document.querySelector(`#pagination`);r(l),l.replaceChildren(o);try{let t=await(await n(`POST`,c,{body:new FormData(s)})).text();if(!t)return;let r=new DOMParser().parseFromString(t,`text/html`),a=r.querySelectorAll(`#urls article`),o=r.querySelector(`#pagination`);document.querySelector(`#pagination`)?.remove();let l=document.querySelector(`#urls`);if(!l)throw Error(`URLs element not found`);a.length>0&&!e&&l.appendChild(document.createElement(`hr`)),l.append(...a),o&&(document.querySelector(`#results`)?.appendChild(o),i())}catch(e){console.error(`Error loading next page:`,e);let n=Object.assign(document.createElement(`div`),{textContent:t.translations?.error_loading_next_page??`Error loading next page`,className:`dialog-error`});n.setAttribute(`role`,`alert`),document.querySelector(`#pagination`)?.replaceChildren(n)}},c=new IntersectionObserver(async e=>{let[t]=e;t?.isIntersecting&&(c.unobserve(t.target),await s(()=>{let e=document.querySelector(a);e&&c.observe(e)}))},{rootMargin:`320px`}),l=document.querySelector(a);l&&c.observe(l)}async post(){}};export{a as default};
//# sourceMappingURL=DpvWr1cn.min.js.map
File diff suppressed because one or more lines are too long
+16 -10
View File
@@ -1,8 +1,4 @@
{
"_BuurKv-k.min.js": {
"file": "chunk/BuurKv-k.min.js",
"name": "plugin"
},
"_DK4yUVpy.min.js": {
"file": "chunk/DK4yUVpy.min.js",
"name": "assertelement"
@@ -23,6 +19,7 @@
"src/js/plugin/MapView.ts",
"src/js/plugin/InfiniteScroll.ts",
"src/js/plugin/Calculator.ts",
"src/js/plugin/AiSummary.ts",
"src/js/main/keyboard.ts",
"src/js/main/search.ts",
"src/js/main/autocomplete.ts",
@@ -80,35 +77,44 @@
"_DcK-mo-Y.min.js"
]
},
"src/js/plugin/AiSummary.ts": {
"file": "chunk/DBBLNmaq.min.js",
"name": "aisummary",
"src": "src/js/plugin/AiSummary.ts",
"isDynamicEntry": true,
"imports": [
"src/js/index.ts",
"_DK4yUVpy.min.js"
]
},
"src/js/plugin/Calculator.ts": {
"file": "chunk/BfLIj3Of.min.js",
"file": "chunk/C8c7HJzp.min.js",
"name": "calculator",
"src": "src/js/plugin/Calculator.ts",
"isDynamicEntry": true,
"imports": [
"_BuurKv-k.min.js",
"src/js/index.ts",
"_DcK-mo-Y.min.js"
]
},
"src/js/plugin/InfiniteScroll.ts": {
"file": "chunk/D3mcqWOe.min.js",
"file": "chunk/DpvWr1cn.min.js",
"name": "infinitescroll",
"src": "src/js/plugin/InfiniteScroll.ts",
"isDynamicEntry": true,
"imports": [
"_BuurKv-k.min.js",
"src/js/index.ts",
"_DK4yUVpy.min.js",
"_DcK-mo-Y.min.js"
]
},
"src/js/plugin/MapView.ts": {
"file": "chunk/Bc8fcwWx.min.js",
"file": "chunk/BnnvKC7b.min.js",
"name": "mapview",
"src": "src/js/plugin/MapView.ts",
"isDynamicEntry": true,
"imports": [
"_BuurKv-k.min.js"
"src/js/index.ts"
],
"css": [
"sxng-mapview.min.css"
+2 -2
View File
@@ -1,3 +1,3 @@
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./chunk/Bc8fcwWx.min.js","./chunk/BuurKv-k.min.js","./sxng-mapview.min.css","./chunk/D3mcqWOe.min.js","./chunk/DK4yUVpy.min.js","./chunk/DcK-mo-Y.min.js","./chunk/BfLIj3Of.min.js","./chunk/C93hSkpT.min.js","./chunk/5Ako-qGW.min.js","./chunk/C21EfLAC.min.js","./chunk/od7pNHfk.min.js","./chunk/e2-9fzwE.min.js"])))=>i.map(i=>d[i]);
var e={index:`index`,results:`results`,preferences:`preferences`,unknown:`unknown`},t={closeDetail:void 0,scrollPageToSelected:void 0,selectImage:void 0,selectNext:void 0,selectPrevious:void 0},n=()=>{let t=document.querySelector(`meta[name="endpoint"]`)?.getAttribute(`content`);return t&&t in e?t:e.unknown},r=()=>{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),{}}},i=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},a=(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)},o=(e,t)=>{for(let e of t?.on??[])if(!e)return;document.readyState===`loading`?a(`DOMContentLoaded`,document,e,{once:!0}):e()},s=n(),c=r(),l=(e,t)=>{u(t)&&e()},u=e=>{switch(e.on){case`global`:return!0;case`endpoint`:return!!e.where.includes(s)}},d=`modulepreload`,f=function(e,t){return new URL(e,t).href},p={},m=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,import.meta.url).href}r=o(t.map(t=>{if(t=f(t,n),t=s(t),t in p)return;p[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`:d,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)})};o(()=>{document.documentElement.classList.remove(`no-js`),document.documentElement.classList.add(`js`),a(`click`,`.close`,function(){this.parentNode?.classList.add(`invisible`)}),a(`click`,`.searxng_init_map`,async function(t){t.preventDefault(),this.classList.remove(`searxng_init_map`),l(()=>m(async()=>{let{default:e}=await import(`./chunk/Bc8fcwWx.min.js`);return{default:e}},__vite__mapDeps([0,1,2]),import.meta.url).then(({default:e})=>new e(this)),{on:`endpoint`,where:[e.results]})}),c.plugins?.includes(`infiniteScroll`)&&l(()=>m(async()=>{let{default:e}=await import(`./chunk/D3mcqWOe.min.js`);return{default:e}},__vite__mapDeps([3,1,4,5]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[e.results]}),c.plugins?.includes(`calculator`)&&l(()=>m(async()=>{let{default:e}=await import(`./chunk/BfLIj3Of.min.js`);return{default:e}},__vite__mapDeps([6,1,5,4]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[e.results]})}),o(()=>{m(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([7,4]),import.meta.url),m(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([8,5,4]),import.meta.url),c.autocomplete&&m(()=>import(`./chunk/C21EfLAC.min.js`),__vite__mapDeps([9,4]),import.meta.url)},{on:[s===e.index]}),o(()=>{m(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([7,4]),import.meta.url),m(()=>import(`./chunk/od7pNHfk.min.js`),__vite__mapDeps([10,4]),import.meta.url),m(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([8,5,4]),import.meta.url),c.autocomplete&&m(()=>import(`./chunk/C21EfLAC.min.js`),__vite__mapDeps([9,4]),import.meta.url)},{on:[s===e.results]}),o(()=>{m(()=>import(`./chunk/e2-9fzwE.min.js`),__vite__mapDeps([11,4]),import.meta.url)},{on:[s===e.preferences]});export{c as i,a as n,t as r,i 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/DBBLNmaq.min.js","./chunk/C93hSkpT.min.js","./chunk/5Ako-qGW.min.js","./chunk/C21EfLAC.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,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]}),l.plugins?.includes(`ai_summary`)&&u(()=>h(async()=>{let{default:e}=await import(`./chunk/DBBLNmaq.min.js`);return{default:e}},__vite__mapDeps([6,3]),import.meta.url).then(({default:e})=>new e),{on:`endpoint`,where:[t.results]})}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([7,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([8,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/C21EfLAC.min.js`),__vite__mapDeps([9,3]),import.meta.url)},{on:[c===t.index]}),s(()=>{h(()=>import(`./chunk/C93hSkpT.min.js`),__vite__mapDeps([7,3]),import.meta.url),h(()=>import(`./chunk/od7pNHfk.min.js`),__vite__mapDeps([10,3]),import.meta.url),h(()=>import(`./chunk/5Ako-qGW.min.js`),__vite__mapDeps([8,4,3]),import.meta.url),l.autocomplete&&h(()=>import(`./chunk/C21EfLAC.min.js`),__vite__mapDeps([9,3]),import.meta.url)},{on:[c===t.results]}),s(()=>{h(()=>import(`./chunk/e2-9fzwE.min.js`),__vite__mapDeps([11,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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long