PageSourceSearch

https://www.kigili.com/cdn/shop/t/4/assets/batch-search.js?v=17959691706545372831789386018

js kigili.com collected 2026-10-01 11:52:49 UTC 9,439 bytes, 2 lines download raw bytes

1(function(){"use strict";const EXPLICIT_BATCH_SEPARATOR=/(?:\s+OR\s+|[;\r\n]+)/i,COMMA_SEPARATOR=/,+/,NATIVE_SEARCH_FIELDS=["tag","variants.sku","variants.barcode","title"],NATIVE_FIELD_PREFIX=/^(?:tag|title|product_type|vendor|variants\.(?:sku|barcode|title)):/i;function parseTerms(value){const query=String(value||"").trim();if(!query)return[];let parts;if(EXPLICIT_BATCH_SEPARATOR.test(query))parts=query.split(EXPLICIT_BATCH_SEPARATOR);else if(query.includes(",")){const commaParts=query.split(COMMA_SEPARATOR).map(part=>part.trim());if(!commaParts.every(part=>part&&!/\s/.test(part)&&/\d/.test(part)))return[];parts=commaParts}else return[];const terms=[];return parts.forEach(part=>{const term=part.trim();term&&terms.push(term)}),terms.length>1?terms:[]}function createSearchUrl(action,query,useClientFallback=!1){const url=new URL(action,window.location.origin);return url.search="",url.searchParams.set("q",query),url.searchParams.set("type","product"),useClientFallback&&url.searchParams.set("batch","1"),url}function uniqueTerms(terms){const seen=new Set;return terms.filter(term=>{const key=term.toLowerCase();return seen.has(key)?!1:(seen.add(key),!0)})}function isNativeScopedQuery(terms){return terms.length>1&&terms.every(term=>NATIVE_FIELD_PREFIX.test(term))}function formatSearchValue(value){return/^[A-Za-z0-9._-]+$/.test(value)?value:`"${value.replace(/([\\"])/g,"\\$1")}"`}function getNativeFieldCandidates(term){return/^\d{8,}$/.test(term)?["variants.barcode","tag","variants.sku","title"]:NATIVE_SEARCH_FIELDS}async function fieldHasProducts(field,term){const route=window.theme?.routes?.predictive_search_url||"/search/suggest",url=new URL(route,window.location.origin);url.pathname=`${url.pathname.replace(/\.json$/,"")}.json`,url.searchParams.set("q",`${field}:${formatSearchValue(term)}`),url.searchParams.set("resources[type]","product"),url.searchParams.set("resources[limit]","1"),url.searchParams.set("resources[options][fields]","title,product_type,vendor,variants.title,variants.sku,tag,variants.barcode");const response=await fetch(url.toString());if(!response.ok)throw new Error(`Search field probe failed with status ${response.status}`);return((await response.json()).resources?.results?.products?.length||0)>0}async function resolveNativeTerm(term){if(NATIVE_FIELD_PREFIX.test(term))return term;for(const field of getNativeFieldCandidates(term))if(await fieldHasProducts(field,term))return`${field}:${formatSearchValue(term)}`;return null}async function resolveNativeQuery(terms){const distinctTerms=uniqueTerms(terms),results=await mapWithConcurrency(distinctTerms,resolveNativeTerm);return results.some(result=>result.status!=="fulfilled"||!result.value)?null:results.map(result=>result.value).join(" OR ")}async function mapWithConcurrency(items,mapper,concurrency=4){const results=new Array(items.length);let nextIndex=0;async function worker(){for(;nextIndex<items.length;){const index=nextIndex;nextIndex+=1;try{results[index]={status:"fulfilled",value:await mapper(items[index],index)}}catch(reason){results[index]={status:"rejected",reason}}}}const workerCount=Math.min(concurrency,items.length);return await Promise.all(Array.from({length:workerCount},()=>worker())),results}function getProductKey(element){const link=element.querySelector('.product-card-title[href], .product-card--image-link[href], a[href*="/products/"]');if(!link)return"";try{const url=new URL(link.getAttribute("href"),window.location.origin),productPath=url.pathname.match(/\/products\/([^/]+)/i);return(productPath?productPath[1]:url.pathname).toLowerCase()}catch{return link.getAttribute("href").split("?")[0].toLowerCase()}}function collectUniqueElements(documents,selector){const seen=new Set,elements=[];return documents.forEach(documentItem=>{documentItem.querySelectorAll(selector).forEach(element=>{const key=getProductKey(element);!key||seen.has(key)||(seen.add(key),elements.push(element))})}),elements}function setBatchSearchLoading(root,loading){const productGridContainer=root.querySelector("#ProductGridContainer");if(!productGridContainer)return;const loader=root.querySelector("[data-batch-search-loader]");loader&&(loader.hidden=!loading),productGridContainer.hidden=loading,productGridContainer.toggleAttribute("aria-busy",loading),productGridContainer.querySelector(".products")?.classList.toggle("loading",loading)}
1function toggleBatchOnlyControls(root,hidden){[root.querySelector("facetfiltersformmobile"),root.querySelector("facet-filters-form.facets--bar")].forEach(control=>{control&&(control.hidden=hidden)})}function updateResultCount(root,count){const countText=((count===1?root.dataset.resultCountTemplateOne:root.dataset.resultCountTemplateOther)||"__COUNT__").replace("__COUNT__",String(count));document.querySelectorAll(".search-filter-count").forEach(element=>{element.textContent=countText}),window.__SEARCH_RESULTS_COUNT__=count}function revealProductImages(container){if(window.lazySizes?.loader&&container.querySelectorAll(".lazyload").forEach(image=>{window.lazySizes.loader.unveil(image)}),window.gsap&&window.ScrollTrigger){const images=container.querySelectorAll(".product-card--image-primary");images.length&&window.gsap.to(images,{scale:1,opacity:1,stagger:.1,ease:window.theme?.settings?.animation_easing})}}function renderBatchProducts(root,products,sourceGrid){const target=root.querySelector("#ProductGridContainer");if(!target||!sourceGrid)return!1;const grid=sourceGrid.cloneNode(!1);grid.innerHTML="",grid.setAttribute("data-no-next",""),grid.classList.remove("loading"),products.forEach(product=>{grid.appendChild(product.cloneNode(!0))});const content=document.createElement("div");content.appendChild(grid);const sidebar=document.createElement("div");return sidebar.className="sidebar-container facets--sidebar-false facets--sidebar-open sticky-scroller--parent",sidebar.appendChild(content),target.replaceChildren(sidebar),setBatchSearchLoading(root,!1),revealProductImages(target),!0}function renderBatchEmpty(root,query,sourceEmpty){const target=root.querySelector("#ProductGridContainer");if(!target||!sourceEmpty)return!1;const empty=sourceEmpty.cloneNode(!0),message=empty.querySelector("p"),template=root.dataset.noResultsTemplate||"No results found for '__QUERY__'.";return message&&(message.textContent=template.replace("__QUERY__",query)),target.replaceChildren(empty),setBatchSearchLoading(root,!1),!0}async function fetchSearchSection(term,sectionId){const url=new URL(window.theme?.routes?.search_url||window.location.pathname,window.location.origin);url.searchParams.set("section_id",sectionId),url.searchParams.set("type","product"),url.searchParams.set("q",term);const response=await fetch(url.toString(),{headers:{"Cache-Control":"public"}});if(!response.ok)throw new Error(`Batch search failed with status ${response.status}`);return new DOMParser().parseFromString(await response.text(),"text/html")}async function initializeBatchSearchPage(){const root=document.querySelector("[data-batch-search-root]");if(!root)return;const currentUrl=new URL(window.location.href),query=currentUrl.searchParams.get("q")||"",terms=parseTerms(query);if(terms.length<2||isNativeScopedQuery(terms))return;if(currentUrl.searchParams.get("batch")!=="1"){const nativeQuery=await resolveNativeQuery(terms);if(nativeQuery){window.location.replace(createSearchUrl(window.theme?.routes?.search_url||currentUrl.pathname,nativeQuery).toString());return}}const sectionId=root.dataset.sectionId||root.querySelector("#product-grid")?.dataset.id;if(!sectionId)return;root.dataset.batchSearchActive="true",toggleBatchOnlyControls(root,!0),setBatchSearchLoading(root,!0);const documents=(await mapWithConcurrency(uniqueTerms(terms),term=>fetchSearchSection(term,sectionId))).filter(result=>result.status==="fulfilled").map(result=>result.value);if(!documents.length){toggleBatchOnlyControls(root,!1),setBatchSearchLoading(root,!1);return}const products=collectUniqueElements(documents,"#product-grid.products > .products--column"),sourceGrid=documents.map(doc=>doc.querySelector("#product-grid.products")).find(Boolean);if(products.length)renderBatchProducts(root,products,sourceGrid);else{const sourceEmpty=documents.map(doc=>doc.querySelector("#product-grid.collection-empty")).find(Boolean);renderBatchEmpty(root,query,sourceEmpty)||setBatchSearchLoading(root,!1)}updateResultCount(root,products.length),document.dispatchEvent(new CustomEvent("batch-search:rendered",{detail:{query,terms,count:products.length}}))}window.ThemeBatchSearch=Object.freeze({collectUniqueElements,createSearchUrl,getProductKey,isNativeScopedQuery,mapWithConcurrency,parseTerms,resolveNativeQuery,uniqueTerms}),document.addEventListener("submit",async event=>{const form=event.target;if(!(form instanceof HTMLFormElement)||form.getAttribute("role")!=="search")return;const query=form.querySelector('input[name="q"]')?.value.trim()||"";if(parseTerms(query).length<2)return;event.preventDefault(),event.stopPropagation(),form.setAttribute("aria-busy","true");const nativeQuery=await resolveNativeQuery(parseTerms(query)),url=nativeQuery?createSearchUrl(form.action,nativeQuery):createSearchUrl(form.action,query,!0);window.location.assign(url.toString())},!0),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initializeBatchSearchPage,{once:!0}):initializeBatchSearchPage()})();
2//# sourceMappingURL=/cdn/shop/t/4/assets/batch-search.js.map?v=17959691706545372831789386018

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.