PageSourceSearch

https://kindredly.ai/js/CategoryMatchServiceDl5Lq4E2.js

js kindredly.ai collected 2026-10-02 01:14:05 UTC 3,423 bytes, 1 lines download raw bytes

1var O=Object.defineProperty;var A=(l,e,t)=>e in l?O(l,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[e]=t;var p=(l,e,t)=>A(l,typeof e!="symbol"?e+"":e,t);import{T as w}from"./TextEmbeddingServiceD7QjSnH7.js";import{h as W,b as k,c as x}from"./textEmbeddingUtilsBRNkRshv.js";const E={embeddingWeight:.7,minScore:.35},M=50,m=class m{constructor(){p(this,"assignmentCache",new Map);p(this,"cacheModelId","");p(this,"cacheFingerprint","")}static get instance(){return m._staticInstance||(m._staticInstance=new m),m._staticInstance}computeItemsFingerprint(e){return W([...e.map(t=>t.id)].sort().join(","))}hydrateAssignmentCache(e,t,n){this.assignmentCache.clear(),this.cacheModelId=t,this.cacheFingerprint=n;for(const[i,r]of Object.entries(e))this.assignmentCache.set(this.assignmentKey(i,t,n),r)}assignmentKey(e,t,n){return`${e}:${t}:${n}`}buildCategoryText(e){var n;const t=[e.label];return e.description&&t.push(e.description),(n=e.tags)!=null&&n.length&&t.push(e.tags.join(" ")),t.join(". ")}buildItemText(e){return k(e)}async getCategoryEmbedding(e){return this.getOrCreateEmbedding(this.buildCategoryText(e))}async matchItems(e,t,n){var y;const i={...E,...n},r=w.instance.getCurrentModelId(),c=this.computeItemsFingerprint(e),a=this.assignmentKey(t.id,r,c),u=this.assignmentCache.get(a);if(u)return u;const o=await this.getCategoryEmbedding(t),d=(t.tags??[]).map(s=>s.toLowerCase()),b=e.filter(s=>this.buildItemText(s).trim().length>0),I=new Map;for(let s=0;s<b.length;s+=M){const h=b.slice(s,s+M),S=await w.instance.batchEmbeddings(h.map(g=>({id:g.id,text:this.buildItemText(g)})));for(const g of S)I.set(g.id,g)}const C=[];for(const s of e){const h=I.get(s.id),S=(y=h==null?void 0:h.embedding)!=null&&y.length&&o.length?Math.max(0,x(h.embedding,o)):0,g=this.tagOverlapScore(s.tags,d),L=i.embeddingWeight*S+(1-i.embeddingWeight)*g,T=this.hasAnyTagMatch(s,d)?1:L;T>=i.minScore&&C.push({itemId:s.id,score:T})}const f=C.sort((s,h)=>h.score-s.score);return this.assignmentCache.set(a,f),f}nameTokenSet(e){const t=new Set;if(!e)return t;for(const n of e.toLowerCase().split(/[^a-z0-9]+/))n&&(t.add(n),n.length>3&&n.endsWith("s")&&t.add(n.slice(0,-1)));return t}hasAnyTagMatch(e,t){var r;if(!t.length)return!1;if((r=e.tags)!=null&&r.length){const c=new Set(e.tags.map(a=>a.toLowerCase()));if(t.some(a=>c.has(a)))return!0}const n=(e.name??"").toLowerCase();if(!n)return!1;const i=this.nameTokenSet(e.name);return t.some(c=>c.includes(" ")?n.includes(c):i.has(c)||c.endsWith("s")&&i.has(c.slice(0,-1)))}tagOverlapScore(e,t){if(!(e!=null&&e.length)||!t.length)return 0;const n=new Set(e.map(r=>r.toLowerCase()));return t.filter(r=>n.has(r)).length/t.length}scoreItemsFromEmbeddings(e,t,n,i,r){const c={...E,...r},a=(n.tags??[]).map(o=>o.toLowerCase()),u=[];for(const o of e){const d=t.get(o.id);if(!(d!=null&&d.length))continue;const b=Math.max(0,x(d,i)),I=this.tagOverlapScore(o.tags,a),C=c.embeddingWeight*b+(1-c.embeddingWeight)*I,f=this.hasAnyTagMatch(o,a)?1:C;f>=c.minScore&&u.push({itemId:o.id,score:f})}return u}getNodeMatches(e){return!this.cacheModelId||!this.cacheFingerprint?null:this.assignmentCache.get(this.assignmentKey(e,this.cacheModelId,this.cacheFingerprint))??null}async getOrCreateEmbedding(e){var i;const t=e.trim();if(!t)return[];const n=await w.instance.generateEmbedding(t);return n.error||!((i=n.embedding)!=null&&i.length)?[]:n.embedding}};p(m,"_staticInstance",null);let F=m;export{F as C};

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.