PageSourceSearch

https://kindredly.ai/js/libraryHealth.bgroutetcejcbsT.js

js kindredly.ai collected 2026-10-02 01:14:30 UTC 59,445 bytes, 2 lines download raw bytes

1var ye=Object.defineProperty;var Ie=(d,e,t)=>e in d?ye(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var E=(d,e,t)=>Ie(d,typeof e!="symbol"?e+"":e,t);import{f as _,U as G}from"./chunkReloadRecoveryrjuMb-b8.js";import{U as de}from"./OperationQueueKzEpmh-u.js";import{w as be,i as X,b as B,c as N,a as oe,l as we}from"./recommendationPrunetgiUUAih.js";import{I as O,b as ae}from"./ItemServiceDYS7Z6Pr.js";import{a as Se,T as me}from"./TextEmbeddingServiceD7QjSnH7.js";import{e as Z}from"./textEmbeddingUtilsBRNkRshv.js";import{I as z}from"./item.typesx7Q7rrX9.js";import{u as P}from"./url.utils3SlYVg-c.js";import"./dexie2jmnBxhj.js";import{a as Q,r as ve}from"./item-name.utilsBH3paGZr.js";import{s as Ce,a as Te,c as xe,f as Ae}from"./libraryWritesCIlf8O8q.js";import"./vue-runtimeBHGad_ZB.js";import"./cjs-helpersC4iS2aBk.js";import"./bootstrap-vue-nextDXY4qsO1.js";import"./content.typesyje91KzF.js";import"./constantsDW26WJ6H.js";import"./extraction.pure.utilsDQPW8yIh.js";import"./noteAttachmentDId5R_kp.js";import"./file_utilsBvAXo0vA.js";import"./api-typesD1zIcSfT.js";import"./freshSignInv8N2vL5e.js";import"./searchContentKindsBGoDYC-k.js";import"./feedback.utilscwcZGi10.js";import"./feedDiscoveryCsjZq3pR.js";import"./itemImageSourcesCubmTdva.js";import"./search-provider.utilsBiOzVtNa.js";import"./statusFacetsB0tsuUpJ.js";import"./browseFacets8dSOpUAG.js";import"./rolloutCapsBJsLLLO7.js";import"./sentryUtilsC8JjCXHs.js";import"./analysis-utilsDkY9KbJt.js";import"./remoteActionApprovalC_byoH4M.js";import"./classificationEvalProgramStatusBazwXda2.js";import"./ActivityUtilsDiYdCK40.js";import"./reason-code.utilswudkndKE.js";import"./reason-metadataDPJV5z5v.js";import"./socialMediaSitesDTleWHW6.js";import"./regexCcuTG5WM.js";import"./appUsageDisplayBY7OQki1.js";import"./urlGuardsBFjEFH91.js";import"./deviceAppIdsBqiQQIm5.js";import"./classificationRulesDUyL5GMw.js";import"./browserTabsCpW6SD42.js";import"./settingsMenuCatalogBT0bsy85.js";import"./tourGateGu4icdk6.js";import"./searchTargets.pureDLBWinh3.js";import"./SearchHistoryStoreBNg-02Jq.js";import"./urlDuplicateMatchingB9T_GhRn.js";import"./siteBlockModeCGmJVg0R.js";import"./alwaysAllowedBZhbIqQn.js";import"./familyClockv2WXhBE2.js";import"./deviceAppPolicyG0TWkbSX.js";import"./familyDowntimeDMv_mvJ9.js";import"./google-ai-modeaEFJUNOw.js";import"./usageBDNfLijZ.js";import"./v4CtRu48qb.js";import"./restrictionPresetsAJUpiAxw.js";import"./deviceAppInventoryMergevnYbxNmN.js";import"./usageIdentityCn48n3s8.js";import"./usageInterventionModeBjzyP5YP.js";import"./queryEmbeddingl6fVc4SQ.js";import"./usageRuleStateD0i2H3LO.js";import"./libraryWriteGuardslN41qmuD.js";import"./restrictedSiteAccessWarning.utilsCD4Urb73.js";const re={enabledTypes:{merge_duplicates:!0,group_similar:!0,archive_stale:!0,create_collection:!0,add_to_collection:!0,remove_empty_collection:!0,organize_orphans:!0},duplicateThreshold:.85,staleDaysThreshold:180,dismissedExpiryDays:30,autoAnalyze:!1,similarityAlgorithm:"embeddings",hybridWeight:.5,orphanSimilarityThreshold:.3,clusterSimilarityThreshold:.4,debugMode:!0},Y="libraryHealthRecommendations",U=class U{constructor(){E(this,"stateCache",null);E(this,"lastLoadedUserId",null)}static get instance(){return this._instance||(this._instance=new U),this._instance}async getCurrentUserId(){return await de.instance.getCurrentUserId()||null}async loadState(){const e=await this.getCurrentUserId();if(!e)return _("RecommendationStorage: No user, returning defaults"),this.getDefaultState();if(this.stateCache&&this.lastLoadedUserId===e)return this.stateCache;try{const t=await G.get(e,Y);if(t)return this.stateCache=this.migrateState(t),this.lastLoadedUserId=e,_("RecommendationStorage: Loaded state",this.stateCache),this.stateCache}catch(t){console.error("RecommendationStorage: Error loading state",t)}return this.stateCache=this.getDefaultState(),this.lastLoadedUserId=e,this.stateCache}async saveState(e){const t=await this.getCurrentUserId();if(!t){_("RecommendationStorage: No user, cannot save");return}try{await G.set(t,Y,e),this.stateCache=e,this.lastLoadedUserId=t,_("RecommendationStorage: State saved")}catch(n){console.error("RecommendationStorage: Error saving state",n)}}getDefaultState(){return{dismissedRecommendations:{},snoozedRecommendations:{},preferences:{...re}}}migrateState(e){const t=this.getDefaultState();return{dismissedRecommendations:e.dismissedRecommendations||{},snoozedRecommendations:e.snoozedRecommendations||{},cachedAnalysis:e.cachedAnalysis,preferences:{...t.preferences,...e.preferences||{}},lastAnalysisTime:e.lastAnalysisTime}}async dismissRecommendation(e){const t=await this.loadState();t.dismissedRecommendations[e]=Date.now(),this.cleanupExpiredDismissals(t),await this.saveState(t),_("RecommendationStorage: Dismissed",e)}async snoozeRecommendation(e,t){const n=await this.loadState();n.snoozedRecommendations[e]=t,await this.saveState(n),_("RecommendationStorage: Snoozed until",new Date(t),e)}async isDismissed(e){const t=await this.loadState(),n=t.dismissedRecommendations[e];if(!n)return!1;
1const i=t.preferences.dismissedExpiryDays*24*60*60*1e3;return!(Date.now()-n>i)}async isSnoozed(e){const n=(await this.loadState()).snoozedRecommendations[e];return n?Date.now()<n:!1}async getActiveRecommendations(){var t,n;const e=await this.loadState();return(n=(t=e.cachedAnalysis)==null?void 0:t.result)!=null&&n.recommendations?this.withoutDismissed(e.cachedAnalysis.result.recommendations):[]}async withoutDismissed(e){const t=await this.loadState(),n=Date.now(),i=t.preferences.dismissedExpiryDays*24*60*60*1e3;return e.filter(s=>{const o=t.dismissedRecommendations[s.id];if(o&&n-o<i)return!1;const a=t.snoozedRecommendations[s.id];return!(a&&n<a)})}cleanupExpiredDismissals(e){const t=Date.now(),n=e.preferences.dismissedExpiryDays*24*60*60*1e3,i=500,o=Object.entries(e.dismissedRecommendations).filter(([,r])=>t-r<n);o.length>i&&(o.sort((r,m)=>m[1]-r[1]),o.length=i),e.dismissedRecommendations=Object.fromEntries(o);const a=Object.entries(e.snoozedRecommendations);e.snoozedRecommendations=Object.fromEntries(a.filter(([,r])=>t<r))}async cacheAnalysisResult(e,t,n){const i=await this.loadState();i.cachedAnalysis={result:e,timestamp:Date.now(),itemCount:t,fingerprint:n},i.lastAnalysisTime=Date.now(),await this.saveState(i),_("RecommendationStorage: Analysis cached")}async getCachedAnalysis(e=24*60*60*1e3,t,n,i){var a;const o=(await this.loadState()).cachedAnalysis;if(!o)return null;if(i!==void 0&&o.fingerprint!==i)return _("RecommendationStorage: Library changed since the cached analysis, invalidating cache"),null;if(n!==void 0){const r=(a=o.result)==null?void 0:a.analysisVersion;if(r!==n)return _(`RecommendationStorage: Cache version mismatch (cached=${r??"none"}, expected=${n}), invalidating cache`),null}return Date.now()-o.timestamp>e?(_("RecommendationStorage: Cache expired"),null):t!==void 0&&Math.abs(t-o.itemCount)/o.itemCount>.1?(_("RecommendationStorage: Item count changed significantly, invalidating cache"),null):(_("RecommendationStorage: Returning cached analysis"),o.result)}async removeAppliedFromCache(e,t){var o;const n=await this.loadState(),i=(o=n.cachedAnalysis)==null?void 0:o.result;if(!i)return;const s=new Set(t);i.recommendations=i.recommendations.filter(a=>a.id!==e).map(a=>a.itemIds.some(r=>s.has(r))?be(a,s):a).filter(a=>a.itemIds.length>0),await this.saveState(n)}async clearCache(){const e=await this.loadState();e.cachedAnalysis=void 0,await this.saveState(e),_("RecommendationStorage: Cache cleared")}async getPreferences(){return(await this.loadState()).preferences}async updatePreferences(e){const t=await this.loadState();t.preferences={...t.preferences,...e},await this.saveState(t),_("RecommendationStorage: Preferences updated",e)}async resetPreferences(){const e=await this.loadState();e.preferences={...re},await this.saveState(e),_("RecommendationStorage: Preferences reset to defaults")}async clearAllState(){const e=await this.getCurrentUserId();e&&await G.clear(e,Y),this.stateCache=null,this.lastLoadedUserId=null,_("RecommendationStorage: All state cleared")}async getStats(){const e=await this.loadState();return{dismissedCount:Object.keys(e.dismissedRecommendations).length,snoozedCount:Object.keys(e.snoozedRecommendations).length,hasCachedAnalysis:!!e.cachedAnalysis,cacheAge:e.cachedAnalysis?Date.now()-e.cachedAnalysis.timestamp:void 0,lastAnalysisTime:e.lastAnalysisTime}}};E(U,"_instance",null);let $=U;const F=[{id:"movies_tv",name:"Movies & TV",icon:"film",matchPhrases:["movies and films to watch","TV shows, series and episodes","movie trailers and reviews","streaming on Netflix, Disney+ and Hulu","TV series recap and full episodes"]},{id:"music",name:"Music",icon:"music-note-beamed",matchPhrases:["songs, albums and playlists","music videos and artists","Spotify playlist","song lyrics and guitar chords","learn an instrument: piano, guitar or drums"]},{id:"podcasts",name:"Podcasts",icon:"headphones",matchPhrases:["podcast episodes to listen to","podcast show and interviews","audio episode on Apple Podcasts or Spotify","a podcast about science, history or stories"]},{id:"games",name:"Games",icon:"controller",matchPhrases:["video games and online games","Minecraft, Roblox and Fortnite","game walkthroughs and tips","board games and card games","Nintendo Switch, Xbox and PlayStation games","Minecraft tutorials and builds"]},{id:"funny",name:"Funny",icon:"emoji-laughing",matchPhrases:["funny videos and memes","comedy clips and jokes","hilarious fails and pranks"]},{id:"books",name:"Books",icon:"book",matchPhrases:["books to read and book reviews","novels, authors and series","reading list and audiobooks","picture books and chapter books"]},{id:"learning",name:"Learning",icon:"mortarboard",matchPhrases:["educational videos and lessons","learn math, reading and spelling","math lessons for elementary school","sight words, spelling and vocabulary","homework help and practice worksheets","online course and study guide","phonics and learning to read"]},{id:"science_nature",name:"Science & Nature",icon:"globe-americas",matchPhrases:["science experiments and facts","space, planets and astronomy","nature, weather, oceans and dinosaurs","how things work","planets and the solar system"]},{id:"animals_pets",name:"Animals & Pets",icon:"feather",matchPhrases:["cute animal videos","dogs, cats and pet care","wild animals and zoo animals","animal facts","dog training and puppy t
1ips"]},{id:"tech_coding",name:"Tech & Coding",icon:"cpu",matchPhrases:["learn to code and programming","computers, gadgets and phones","Scratch, Python and JavaScript","technology news and reviews","phone and laptop reviews","web development: HTML, CSS and building websites"]},{id:"art_drawing",name:"Art & Drawing",icon:"palette",matchPhrases:["how to draw and drawing tutorials","painting and art projects","coloring pages","artists and artwork","easy drawing lessons"]},{id:"crafts_diy",name:"Crafts & DIY",icon:"scissors",matchPhrases:["craft ideas and DIY projects","crafts with paper and glue","sewing, knitting and crochet","slime, Lego builds and origami","jewelry making, tie-dye and bead crafts"]},{id:"recipes",name:"Recipes",icon:"egg-fried",matchPhrases:["recipes and cooking","dinner ideas and meal planning","baking cookies, cakes and bread","healthy snacks and lunch ideas"]},{id:"parenting",name:"Parenting",icon:"people",matchPhrases:["parenting advice and tips","child development and toddlers","screen time and family rules","raising teenagers","discipline and behavior"]},{id:"kids_activities",name:"Kids Activities",icon:"balloon",matchPhrases:["things to do this weekend with the family","rainy day activities and indoor games","summer camps, classes and after-school programs","family outings nearby","playgrounds, play places and trampoline parks"]},{id:"home_garden",name:"Home & Garden",icon:"house",matchPhrases:["home decor and organizing","cleaning tips and chores","gardening, plants and yard","home improvement and renovation","kitchen and closet organization"]},{id:"holidays_parties",name:"Holidays & Parties",icon:"gift",matchPhrases:["birthday party ideas","Christmas, Halloween and Easter","Thanksgiving, Fourth of July and Valentine's Day","holiday decorations and traditions","party games and themes","Halloween costumes","Elf on the Shelf and Christmas ideas"]},{id:"health_fitness",name:"Health & Fitness",icon:"heart-pulse",matchPhrases:["workouts and exercise","yoga, running and sports training","nutrition and healthy eating","running plan and training program","mental health and sleep"]},{id:"school",name:"School",icon:"backpack",collectionTemplateId:"personal.school.v1",matchPhrases:["school portal and grades","teacher contact and class schedule","school calendar and lunch menu","district website and classroom app"]},{id:"finance",name:"Finance",icon:"piggy-bank",collectionTemplateId:"personal.finance.v1",matchPhrases:["bank account and budgeting","taxes and bills","saving money and investing","retirement accounts, IRA and 401k","credit card and insurance"]},{id:"shopping",name:"Shopping",icon:"cart",collectionTemplateId:"home.shoppingcart.v1",matchPhrases:["products to buy","wishlist and gift ideas","Amazon product page and price","deals and discounts","gift ideas"]},{id:"travel",name:"Travel",icon:"airplane",matchPhrases:["trip planning and vacation ideas","hotels, flights and rentals","places to visit and things to do","national parks and road trips"]},{id:"work",name:"Work",icon:"briefcase",matchPhrases:["work documents and meetings","career and job search","productivity and business","resume and interview tips","career advice, salary and promotion"]},{id:"news",name:"News",icon:"newspaper",matchPhrases:["news articles and current events","politics and world news","local news","opinion and analysis","court rulings and government"]},{id:"sports",name:"Sports",icon:"trophy",matchPhrases:["soccer, basketball and baseball","team scores and highlights","practice drills and coaching","sports news"]},{id:"apps_tools",name:"Apps & Tools",icon:"tools",matchPhrases:["useful websites and web apps","software tools and utilities","app for productivity","online tool and generator","free online design and photo editing tools"]},{id:"fashion_beauty",name:"Fashion & Beauty",icon:"bag",matchPhrases:["clothes, outfits and fashion","makeup, hair and skincare","style ideas","hairstyles and braids","wardrobe and seasonal outfits"]}],he=.3,_e=.03,De=2,Re=.25,ue=3;function Ee(d){return d.split(/\s+/).filter(e=>/[a-z]{2,}/i.test(e)).length}function ge(d,e){if(e<De||d.length===0)return null;const t=[...d].sort((s,o)=>o.score-s.score),[n,i]=t;return n.score<he||i&&n.score-i.score<_e?null:n}function Me(d,e=new Map){const t=new Map;for(const i of d){const s=ge(i.scores,i.wordCount);if(!s)continue;const o=t.get(s.id);o?o.push({value:i.value,score:s.score}):t.set(s.id,[{value:i.value,score:s.score}])}const n=[];for(const i of F){const s=t.get(i.id);if(!s)continue;const o=e.get(i.id);o===void 0&&s.length<ue||(s.sort((a,r)=>r.score-a.score),n.push(o===void 0?{organization:i,members:s}:{organization:i,members:s,collection:o}))}return n.sort((i,s)=>s.members.length-i.members.length)}function $e(d){const e=new Map;for(const s of F)e.set(ce(s.name),s.id);const t=new Map,n=(s,o,a)=>{const r=t.get(s);(!r||a>r.strength)&&t.set(s,{value:o,strength:a})};for(const s of d){const o=e.get(ce(s.name));if(o){n(o,s.value,Number.POSITIVE_INFINITY);continue}const a=new Map;for(const r of s.members){const m=ge(r.scores,r.wordCount);m&&a.set(m.id,(a.get(m.id)??0)+1)}for(const[r,m]of a)m>=2&&m/s.members.length>=.6&&n(r,s.value,m)}const i=new Map;for(const[s,{value:o,strength:a}]of t)i.set(s,{value:o,byName:a===Number.POSITIVE_INFINITY});return i}function ce(d){return d.toLowerCase().replace(/&/g," and ").split(/[^a-z0-9]+/).filter(
1Boolean).map(e=>e.length>3&&e.endsWith("s")?e.slice(0,-1):e).join(" ")}const ke={algorithm:"tfidf",hybridWeight:.5,minSimilarity:.3,debug:!1,embeddingCacheEnabled:!0},H=class H{constructor(e={}){E(this,"tfidfClassifier");E(this,"embeddingService");E(this,"config");E(this,"indexedDocuments",new Map);E(this,"documentFrequency",new Map);E(this,"totalDocuments",0);this.config={...ke,...e},this.tfidfClassifier=new Se,this.embeddingService=me.instance}static get instance(){return this._instance||(this._instance=new H),this._instance}setConfig(e){this.config={...this.config,...e},this.config.debug&&_("SimilarityEngine: Config updated",this.config)}getConfig(){return{...this.config}}async indexDocuments(e,t){var i;const n=performance.now();this.clear(),this.totalDocuments=e.length;for(const s of e){const o=this.tfidfClassifier.calculateTermFrequency(s.text);for(const a of Object.keys(o))this.documentFrequency.set(a,(this.documentFrequency.get(a)||0)+1);this.indexedDocuments.set(s.id,{id:s.id,text:s.text,tfidfVector:o})}for(const[s,o]of this.indexedDocuments.entries())if(o.tfidfVector){const a={};for(const[r,m]of Object.entries(o.tfidfVector)){const b=this.documentFrequency.get(r)||1,y=Math.log((this.totalDocuments+1)/(b+1))+1;a[r]=m*y}o.tfidfVector=a}if(this.config.algorithm==="embeddings"||this.config.algorithm==="hybrid"){const o=this.config.embeddingCacheEnabled??!0;for(let a=0;a<e.length;a+=10){const r=e.slice(a,a+10),m=r.map(y=>({id:y.id,text:y.text})),b=await this.embeddingService.batchEmbeddings(m,{cacheEnabled:o});for(let y=0;y<r.length;y++){const C=this.indexedDocuments.get(r[y].id);C&&((i=b[y])!=null&&i.embedding)&&(C.embedding=b[y].embedding)}t==null||t(Math.min(a+10,e.length),e.length)}}else t==null||t(e.length,e.length);this.config.debug&&_(`SimilarityEngine: Indexed ${e.length} documents in ${(performance.now()-n).toFixed(0)}ms (${this.documentFrequency.size} unique terms)`)}getDocument(e){return this.indexedDocuments.get(e)}similarity(e,t){const n=this.indexedDocuments.get(e),i=this.indexedDocuments.get(t);if(!n||!i)return{score:0,method:this.config.algorithm};switch(this.config.algorithm){case"tfidf":return this.computeTfIdfSimilarity(n,i);case"embeddings":return this.computeEmbeddingSimilarity(n,i);case"hybrid":return this.computeHybridSimilarity(n,i);case"keyword":return this.computeKeywordSimilarity(n,i);default:return this.computeTfIdfSimilarity(n,i)}}computeTfIdfSimilarity(e,t){if(!e.tfidfVector||!t.tfidfVector)return{score:0,method:"tfidf"};const n=new Map(Object.entries(e.tfidfVector)),i=this.tfidfClassifier.cosineSimilarity(n,t.tfidfVector),s=new Set(Object.keys(e.tfidfVector)),o=new Set(Object.keys(t.tfidfVector)),a=[...s].filter(r=>o.has(r));return{score:i,method:"tfidf",breakdown:{tfidfScore:i,commonTerms:a.slice(0,10),topTerms1:this.getTopTerms(e.tfidfVector),topTerms2:this.getTopTerms(t.tfidfVector)}}}computeEmbeddingSimilarity(e,t){if(!e.embedding||!t.embedding)return{score:0,method:"embeddings"};const n=this.embeddingService.cosineSimilarity(e.embedding,t.embedding);return{score:n,method:"embeddings",breakdown:{embeddingScore:n}}}computeHybridSimilarity(e,t){var a,r,m;const n=this.computeTfIdfSimilarity(e,t),i=this.computeEmbeddingSimilarity(e,t),s=this.config.hybridWeight||.5;return{score:n.score*s+i.score*(1-s),method:"hybrid",breakdown:{tfidfScore:n.score,embeddingScore:i.score,commonTerms:(a=n.breakdown)==null?void 0:a.commonTerms,topTerms1:(r=n.breakdown)==null?void 0:r.topTerms1,topTerms2:(m=n.breakdown)==null?void 0:m.topTerms2}}}computeKeywordSimilarity(e,t){if(!e.tfidfVector||!t.tfidfVector)return{score:0,method:"keyword"};const n=new Set(Object.keys(e.tfidfVector)),i=new Set(Object.keys(t.tfidfVector)),s=new Set([...n].filter(r=>i.has(r))),o=new Set([...n,...i]);return{score:o.size>0?s.size/o.size:0,method:"keyword",breakdown:{commonTerms:[...s].slice(0,10),topTerms1:[...n].slice(0,5),topTerms2:[...i].slice(0,5)}}}getTopTerms(e,t=5){return Object.entries(e).sort((n,i)=>i[1]-n[1]).slice(0,t).map(([n])=>n)}findSimilarPairs(e){const t=e??this.config.minSimilarity,n=[],i=[...this.indexedDocuments.keys()];for(let s=0;s<i.length;s++)for(let o=s+1;o<i.length;o++){const a=this.similarity(i[s],i[o]);a.score>=t&&n.push({id1:i[s],id2:i[o],similarity:a})}return n.sort((s,o)=>o.similarity.score-s.similarity.score),n}
1findSimilar(e,t=10){const n=[];for(const i of this.indexedDocuments.keys()){if(i===e)continue;const s=this.similarity(e,i);s.score>=this.config.minSimilarity&&n.push({id:i,similarity:s})}return n.sort((i,s)=>s.similarity.score-i.similarity.score),n.slice(0,t)}similarityToVector(e,t){const n=this.indexedDocuments.get(e);if(!n)return{score:0,method:this.config.algorithm};switch(this.config.algorithm){case"tfidf":case"keyword":if(n.tfidfVector&&t.tfidf){const r=new Map(Object.entries(n.tfidfVector));return{score:this.tfidfClassifier.cosineSimilarity(r,t.tfidf),method:"tfidf"}}return{score:0,method:"tfidf"};case"embeddings":return n.embedding&&t.embedding?{score:this.embeddingService.cosineSimilarity(n.embedding,t.embedding),method:"embeddings"}:{score:0,method:"embeddings"};case"hybrid":let i=0,s=0;if(n.tfidfVector&&t.tfidf){const r=new Map(Object.entries(n.tfidfVector));i=this.tfidfClassifier.cosineSimilarity(r,t.tfidf)}n.embedding&&t.embedding&&(s=this.embeddingService.cosineSimilarity(n.embedding,t.embedding));const o=this.config.hybridWeight||.5;return{score:i*o+s*(1-o),method:"hybrid",breakdown:{tfidfScore:i,embeddingScore:s}};default:return{score:0,method:this.config.algorithm}}}computeCentroid(e){const t=e.map(o=>this.indexedDocuments.get(o)).filter(Boolean);if(t.length===0)return{};const n={};for(const o of t)if(o.tfidfVector)for(const[a,r]of Object.entries(o.tfidfVector))n[a]=(n[a]||0)+r/t.length;let i;const s=t.filter(o=>o.embedding&&o.embedding.length>0);if(s.length>0){const o=s[0].embedding.length;i=new Array(o).fill(0);for(const a of s)for(let r=0;r<o;r++)i[r]+=a.embedding[r]/s.length}return{tfidf:Object.keys(n).length>0?n:void 0,embedding:i}}clear(){this.indexedDocuments.clear(),this.documentFrequency.clear(),this.totalDocuments=0}};E(H,"_instance",null);let J=H;const L=class L{constructor(){E(this,"indexService",O.instance);E(this,"embeddingService",me.instance);E(this,"storageService",$.instance);E(this,"userService",de.instance);E(this,"similarityEngine",J.instance)}static get instance(){return this._instance||(this._instance=new L),this._instance}async analyzeLibrary(e={},t){const n=performance.now(),i=[],s=e.disableCaches===!0;try{const o=s;o&&(_("LibraryAnalysis: disableCaches=true; clearing embedding cache for fresh vectors"),await this.embeddingService.clearCache()),(e.forceRefresh===!0||o)&&this.similarityEngine.clear(),t==null||t({phase:"loading",progress:0,message:"Loading library items..."});const a=await this.loadAllItems(),m={...await this.storageService.getPreferences(),...e.preferences},b=m.similarityAlgorithm||"embeddings";this.similarityEngine.setConfig({algorithm:b,hybridWeight:m.hybridWeight||.5,minSimilarity:m.orphanSimilarityThreshold||.3,debug:m.debugMode||e.debug||!1,embeddingCacheEnabled:!s}),_(`LibraryAnalysis: Using algorithm "${b}" with duplicate threshold ${m.duplicateThreshold}`);const y=a.filter(I=>{var D,R;return!((D=I.details)!=null&&D.archived)&&!((R=I.details)!=null&&R.deleted)}),C=y.filter(I=>{var D;return((D=I.details)==null?void 0:D.type)!==z.collection}),h=y.filter(I=>{var D;return((D=I.details)==null?void 0:D.type)===z.collection&&!X(I)}),w=await(await this.indexService.getDataIndex()).itemRelationStore.getCollectionIdsForItems(y.map(I=>I.itemId)),v=`${ze(y,w)}:${fe(JSON.stringify(F))}`;if(!e.forceRefresh&&!o){const I=await this.storageService.getCachedAnalysis(void 0,C.length,L.ANALYSIS_IMPLEMENTATION_VERSION,v);if(I)return _("LibraryAnalysis: Using cached result"),{...I,recommendations:await this.storageService.withoutDismissed(I.recommendations),analysisVersion:L.ANALYSIS_IMPLEMENTATION_VERSION,fromCache:!0}}_(`LibraryAnalysis: Analyzing ${C.length} items, ${h.length} collections`);const T=e.maxItems||5e3,c=C.length<=T?C:[...C].sort((I,D)=>le(D)-le(I)).slice(0,T);t==null||t({phase:"embedding",progress:10,message:"Generating embeddings...",totalItems:c.length});const l=await this.generateItemEmbeddings(c,w,I=>{t==null||t({phase:"embedding",progress:10+I/c.length*30,message:`Generating embeddings (${I}/${c.length})...`,itemsProcessed:I,totalItems:c.length})}),g=[];if(m.enabledTypes.merge_duplicates){t==null||t({phase:"duplicates",progress:45,message:"Finding duplicates..."});const I=await this.findDuplicates(l,e.duplicateThreshold||m.duplicateThreshold,e.debug||!1);_(`LibraryAnalysis: Found ${I.length} duplicate recommendations`),g.push(...I)}if(m.enabledTypes.archive_stale){t==null||t({phase:"stale",progress:65,message:"Finding stale items..."});const I=await this.findStaleItems(C,e.staleDaysThreshold||m.staleDaysThreshold);_(`LibraryAnalysis: Found ${I.length} stale item recommendations`),g.push(...I)}let f=new Set;if(m.enabledTypes.create_collection){t==null||t({phase:"clustering",progress:55,message:"Finding collections to suggest..."});const I=await this.suggestCommonOrganizations(l,h,m);f=I.organizedCollectionIds,_(`LibraryAnalysis: Found ${I.recommendations.length} collection recommendations`),g.push(...I.recommendations)}if(m.enabledTypes.organize_orphans){t==null||t({phase:"clustering",progress:70,message:"Analyzing uncategorized 
1items..."});const I=new Set(g.filter(M=>M.type==="create_collection"||M.type==="add_to_collection").flatMap(M=>M.itemIds)),D=h.filter(M=>!f.has(M.itemId)),R=await this.analyzeOrphanItems(l,D,m,I);_(`LibraryAnalysis: Found ${R.length} orphan recommendations`),g.push(...R)}if(m.enabledTypes.remove_empty_collection){const I=new Set(g.map(R=>R.targetCollectionId).filter(Boolean)),D=await this.findEmptyCollections(h.filter(R=>!I.has(R.itemId)));_(`LibraryAnalysis: Found ${D.length} empty collection recommendations`),g.push(...D)}t==null||t({phase:"scoring",progress:90,message:"Calculating health score..."});const x=this.calculateHealthScore(C,h,g,l);let A;if(e.includeEmbeddingsByItemId===!0){A={};for(const I of l){const D=I.item.itemId,R=this.similarityEngine.getDocument(D);R!=null&&R.embedding&&R.embedding.length>0&&(A[D]=R.embedding)}}const u=performance.now()-n,S={analysisVersion:L.ANALYSIS_IMPLEMENTATION_VERSION,fromCache:!1,recommendations:g,smartCollections:[],healthScore:x,durationMs:u,itemsAnalyzed:l.length,itemsInLibrary:C.length,errors:i.length>0?i:void 0,debugEmbeddingsByItemId:A};return t==null||t({phase:"complete",progress:100,message:"Analysis complete"}),s||await this.storageService.cacheAnalysisResult(S,C.length,v),{...S,recommendations:await this.storageService.withoutDismissed(g)}}catch(o){console.error("LibraryAnalysis: Error during analysis",o);const a=o instanceof Error?o.message:String(o);i.push(a);const r=performance.now()-n;return{analysisVersion:L.ANALYSIS_IMPLEMENTATION_VERSION,fromCache:!1,recommendations:[],smartCollections:[],healthScore:{overallScore:0,grade:"F",metrics:[],stats:{totalItems:0,totalCollections:0,orphanItems:0,staleItems:0,duplicatePairs:0,emptyCollections:0,avgItemsPerCollection:0},calculatedAt:Date.now(),quickWins:[]},durationMs:r,itemsAnalyzed:0,errors:i}}}async getSimilarCollections(e){const t=typeof e.topK=="number"?e.topK:10,n=typeof e.minScore=="number"?e.minScore:.25,i=await this.resolveSimilarCollectionsSource(e);if(!i.sourceText&&!i.sourceCollectionId)throw new Error("Provide sourceText, sourceItemId, or sourceCollectionId");
1switch(e.method){case"rollup":return await this.getSimilarCollectionsByRollup({...e,...i},{topK:t,minScore:n});case"neighborVote":return await this.getSimilarCollectionsByNeighborVote({...e,...i},{topK:t,minScore:n});default:throw new Error(`Unsupported method: ${e.method}`)}}async resolveSimilarCollectionsSource(e){var n,i,s,o,a;if(e.sourceText&&e.sourceText.trim().length>0)return{sourceText:e.sourceText.trim(),sourceLabel:e.sourceLabel||"Free text",sourceItemId:e.sourceItemId,sourceCollectionId:e.sourceCollectionId};const t=await this.indexService.getDataIndex();if(e.sourceItemId){const r=await t.itemDataStore.getById(e.sourceItemId);if(!r)throw new Error(`Unknown source item: ${e.sourceItemId}`);const m=B(r);return{sourceItemId:e.sourceItemId,sourceText:m,sourceLabel:e.sourceLabel||N(r)||e.sourceItemId,sourceCollectionId:e.sourceCollectionId}}if(e.sourceCollectionId){const r=await t.itemDataStore.getById(e.sourceCollectionId);if(r&&((n=r.details)==null?void 0:n.type)===z.collection){const m=Z({title:((i=r.details)==null?void 0:i.name)||void 0,description:((s=r.details)==null?void 0:s.description)||void 0})||((o=r.details)==null?void 0:o.name)||"";return{sourceCollectionId:e.sourceCollectionId,sourceText:m,sourceLabel:e.sourceLabel||((a=r.details)==null?void 0:a.name)||e.sourceCollectionId}}return{sourceCollectionId:e.sourceCollectionId,sourceLabel:e.sourceLabel||e.sourceCollectionId}}return{}}async getSimilarCollectionsByRollup(e,t){var l,g,f,x,A;const n=await this.indexService.getDataIndex(),i=await this.loadAllItems(),s=i.filter(u=>{var S;return((S=u.details)==null?void 0:S.type)===z.collection});new Map(s.map(u=>[u.itemId,u]));const o=e.sourceCollectionId,a=typeof e.maxCollections=="number"?e.maxCollections:s.length,r=s.slice(0,Math.max(0,a)),m=new Map(i.map(u=>[u.itemId,u])),b=new Map,y=new Set;for(const u of r){const S=await n.itemRelationStore.getItemIdsForCollection(u.itemId);b.set(u.itemId,S);for(const I of S)y.add(I)}const C=[];for(const u of y){const S=m.get(u);if(!S||((l=S.details)==null?void 0:l.type)===z.collection)continue;const I=B(S);I.trim().length>0&&C.push({id:u,text:I})}const h=await this.embeddingService.batchEmbeddings(C),p=new Map;for(const u of h)Array.isArray(u.embedding)&&u.embedding.length>0&&p.set(u.id,u.embedding);const w=new Map;for(const u of r){const S=Z({title:((g=u.details)==null?void 0:g.name)||void 0,description:((f=u.details)==null?void 0:f.description)||void 0})||((x=u.details)==null?void 0:x.name)||"";if(S.trim().length===0)continue;const I=await this.embeddingService.generateEmbedding(S);!I.error&&Array.isArray(I.embedding)&&I.embedding.length>0&&w.set(u.itemId,I.embedding)}const v=new Map;for(const u of r){const I=(b.get(u.itemId)||[]).map(M=>p.get(M)).filter(M=>Array.isArray(M)&&M.length>0),D=w.get(u.itemId);D&&I.push(D);const R=this.meanEmbedding(I);R&&v.set(u.itemId,R)}let T=null;if(o&&(T=v.get(o)||null),!T&&e.sourceText&&e.sourceText.trim().length>0){const u=await this.embeddingService.generateEmbedding(e.sourceText);!u.error&&Array.isArray(u.embedding)&&u.embedding.length>0&&(T=u.embedding)}if(!T)return{method:"rollup",sourceCollectionId:e.sourceCollectionId,sourceItemId:e.sourceItemId,sourceLabel:e.sourceLabel,results:[],debug:{sourceItemCount:o?(b.get(o)||[]).length:void 0,candidateCollectionCount:r.length}};const c=[];for(const u of r){if(o&&u.itemId===o)continue;const S=v.get(u.itemId);if(!S)continue;const I=this.embeddingService.cosineSimilarity(T,S);I>=t.minScore&&c.push({collectionId:u.itemId,collectionName:((A=u.details)==null?void 0:A.name)||u.itemId,score:I,reason:"rollup: cosine(source_rollup, candidate_rollup)"})}return c.sort((u,S)=>S.score-u.score),{method:"rollup",sourceCollectionId:e.sourceCollectionId,sourceItemId:e.sourceItemId,sourceLabel:e.sourceLabel,results:c.slice(0,t.topK),debug:{sourceItemCount:o?(b.get(o)||[]).length:void 0,candidateCollectionCount:r.length}}}async getSimilarCollectionsByNeighborVote(e,t){const n=await this.indexService.getDataIndex(),i=await this.loadAllItems(),s=i.filter(l=>{var g;return((g=l.details)==null?void 0:g.type)===z.collection}),o=new Map(s.map(l=>{var g;return[l.itemId,((g=l.details)==null?void 0:g.name)||l.itemId]})),a=(e.sourceText||"").trim();if(a.length===0)return{method:"neighborVote",sourceCollectionId:e.sourceCollectionId,sourceItemId:e.sourceItemId,sourceLabel:e.sourceLabel,results:[],debug:{indexedItemCount:0}};const r=typeof e.maxItemsToIndex=="number"?e.maxItemsToIndex:2e3,b=i.filter(l=>{var g;return((g=l.details)==null?void 0:g.type)!==z.collection}
1).slice(0,Math.max(0,r)).map(l=>{const g=B(l);return{id:l.itemId,text:g}}),y=typeof e.neighborTopKPerItem=="number"?e.neighborTopKPerItem:40,C=await this.embeddingService.findSimilar(a,b,y),h=C.map(l=>l.id),p=await n.itemRelationStore.getCollectionIdsForItems(h),w=new Map,v=new Map;for(const l of C){const g=p.get(l.id)||[];for(const f of g){if(e.sourceCollectionId&&f===e.sourceCollectionId)continue;w.set(f,(w.get(f)||0)+l.score);const x=v.get(f)||[];x.push({itemId:l.id,score:l.score}),x.sort((A,u)=>u.score-A.score),v.set(f,x.slice(0,5))}}const T=1,c=[];for(const[l,g]of w.entries()){const f=g/T;f<t.minScore||c.push({collectionId:l,collectionName:o.get(l)||l,score:f,reason:"neighborVote: sum(similarity(neighbor))/sourceItemCount",debugTopSupportingItems:v.get(l)})}return c.sort((l,g)=>g.score-l.score),{method:"neighborVote",sourceCollectionId:e.sourceCollectionId,sourceItemId:e.sourceItemId,sourceLabel:e.sourceLabel,results:c.slice(0,t.topK),debug:{indexedItemCount:b.length}}}meanEmbedding(e){const t=e.filter(s=>Array.isArray(s)&&s.length>0);if(t.length===0)return null;const n=t[0].length;for(const s of t)if(s.length!==n)return null;const i=new Array(n).fill(0);for(const s of t)for(let o=0;o<n;o++)i[o]+=s[o]/t.length;return i}async loadAllItems(){return await(await this.indexService.getDataIndex()).itemDataStore.listAll()}async generateItemEmbeddings(e,t,n){const i=e.map(s=>{const o=B(s);return{item:s,text:o,collectionIds:t.get(s.itemId)||[]}});return await this.similarityEngine.indexDocuments(i.map(s=>({id:s.item.itemId,text:s.text})),s=>n==null?void 0:n(s)),i}async findDuplicates(e,t,n){var m,b,y,C;const i=[],s=new Set,o=new Map,a=new Map;for(const h of e){const p=(m=h.item.details)==null?void 0:m.url,w=p?P(p):null;if(w){const c=o.get(w);c?c.push(h):o.set(w,[h])}const v=N(h.item);if(v.split(/\s+/).filter(c=>c.length>0).length>=3){const c=this.normalizeTitle(v);if(c.length>0){const l=a.get(c);l?l.push(h):a.set(c,[h])}}}for(const[h,p]of o.entries())if(p.length>1)for(let w=0;w<p.length;w++)for(let v=w+1;v<p.length;v++){const T=[p[w].item.itemId,p[v].item.itemId].sort().join("_");s.has(T)||(s.add(T),i.push({item1Id:p[w].item.itemId,item2Id:p[v].item.itemId,similarity:1,detectionMethod:"exact_url",decisionFactors:[`Same URL key: ${h}`,`URL 1: ${(b=p[w].item.details)==null?void 0:b.url}`,`URL 2: ${(y=p[v].item.details)==null?void 0:y.url}`]}))}_(`LibraryAnalysis: Found ${i.length} exact URL duplicates`);let r=0;for(const[h,p]of a.entries())if(p.length>1){const w=new Map;for(const v of p){const T=((C=v.item.details)==null?void 0:C.type)||"item",c=w.get(T);c?c.push(v):w.set(T,[v])}for(const[v,T]of w.entries())if(T.length>1)for(let c=0;c<T.length;c++)for(let l=c+1;l<T.length;l++){const g=[T[c].item.itemId,T[l].item.itemId].sort().join("_");if(!s.has(g)){const f=N(T[c].item),x=N(T[l].item),A=f.split(/\s+/).filter(S=>S.length>0).length,u=x.split(/\s+/).filter(S=>S.length>0).length;s.add(g),r++,i.push({item1Id:T[c].item.itemId,item2Id:T[l].item.itemId,similarity:.98,detectionMethod:"exact_title",titleSimilarity:1,decisionFactors:[`Same title (${Math.min(A,u)} words): "${h}"`,`Same type: ${v}`,`Title 1: "${f}"`,`Title 2: "${x}"`]})}}}return _(`LibraryAnalysis: Found ${r} exact title duplicates (3+ words)`),_("LibraryAnalysis: Semantic similarity DISABLED - only exact matches shown"),i.map(h=>{var f,x,A,u,S,I,D,R,M,ee,te,ie,ne,se;const p=e.find(W=>W.item.itemId===h.item1Id),w=e.find(W=>W.item.itemId===h.item2Id);let v="";switch(h.detectionMethod){case"exact_url":v="Same URL (definite duplicate)";break;case"exact_title":v="Identical title (3+ words) and same type";break;default:v=h.decisionFactors.join("; ")}const T={id:`dup_${[h.item1Id,h.item2Id].sort().join("_")}`,type:"merge_duplicates",title:"Merge duplicates",description:"These items appear to be duplicates",itemIds:[h.item1Id,h.item2Id],itemPreviews:[this.createItemPreview(p.item),this.createItemPreview(w.item)],score:h.similarity,priority:"high",createdAt:Date.now(),status:"pending",reason:v,metadata:{similarityScore:h.similarity}},c=this.similarityEngine.similarity(h.item1Id,h.item2Id),l=this.similarityEngine.getDocument(h.item1Id),g=this.similarityEngine.getDocument(h.item2Id);return T.debugInfo={detectionMethod:h.detectionMethod,item1:{id:p.item.itemId,name:N(p.item)||void 0,url:((f=p.item.details)==null?void 0:f.url)||void 0,normalizedUrl:(x=p.item.details)!=null&&x.url&&P(p.item.details.url)||void 0,type:((A=p.item.details)==null?void 0:A.type)||void 0,textPreview:p.text.substring(0,200),embeddingDimensions:((u=l==null?void 0:l.embedding)==null?void 0:u.length)||0,embeddingSample:((S=l==null?void 0:l.embedding)==null?void 0:S.slice(0,5))||[]},item2:{id:w.item.itemId,name:N(w.item)||void 0,url:((I=w.item.details)==null?void 0:I.url)||void 0,normalizedUrl:(D=w.item.details)!=null&&D.url&&P(w.item.details.url)||void 0,type:((R=w.item.details)==null?void 0:R.type)||void 0,textPreview:w.text.substring(0,200),embeddingDimensions:((M=g==null?void 0:g.embedding)==null?void 0:M.length)||0,embeddingSample:((ee=g==null?void 0:g.embedding)==null?void 0:ee.slice(0,5))||[]},scores:{embeddingSimilarity:(te=c.breakdown)==null?void 0:te.embeddingScore,titleSimilarity:h.titleSimilarity,finalScore:h.similarity},decisionFactors:[...h.decisionFactors,`Algorithm: ${c.method}`,((ie=c.breakdown)==null?void 0:ie.tfidfScore)!==void 0?`TF-IDF score: ${(c.breakdown.tfidfScore*100).toFixed(1)}%`:"",(se=(ne=c.breakdown)==null?void 0:ne.commonTerms)!=null&&se.length?`Common terms: ${c.breakdown.commonTerms.slice(0,5).join(", ")}
1`:""].filter(Boolean)},T})}normalizeTitle(e){return e.toLowerCase().trim().replace(/[^\w\s]/g,"").replace(/\s+/g," ")}calculateTitleSimilarity(e,t){if(!e||!t)return 0;if(e===t)return 1;const n=r=>r.toLowerCase().replace(/[^\w\s]/g,"").split(/\s+/).filter(m=>m.length>2),i=new Set(n(e)),s=new Set(n(t));if(i.size===0||s.size===0)return 0;const o=new Set([...i].filter(r=>s.has(r))),a=new Set([...i,...s]);return o.size/a.size}async analyzeOrphanItems(e,t,n,i=new Set){var r,m,b,y,C,h,p,w,v,T,c,l,g,f,x,A;const s=e.filter(u=>u.collectionIds.length===0);if(s.length===0)return[];const o=[],a=s.filter(u=>!i.has(u.item.itemId));for(const u of a.slice(0,50)){const S=await this.findBestCollectionForItem(u,t,e,{minSimilarity:n.orphanSimilarityThreshold??.3});if(S){const I={id:`add_${u.item.itemId}_${S.collection.itemId}`,type:"add_to_collection",title:`Add to "${(r=S.collection.details)==null?void 0:r.name}"`,description:"Suggested based on content similarity",itemIds:[u.item.itemId],itemPreviews:[this.createItemPreview(S.collection),this.createItemPreview(u.item)],targetCollectionId:S.collection.itemId,targetCollectionName:((m=S.collection.details)==null?void 0:m.name)||"Unknown",score:S.score,priority:S.score>.7?"medium":"low",createdAt:Date.now(),status:"pending",reason:"Best match among your collections"},D=this.similarityEngine.getDocument(u.item.itemId);I.debugInfo={detectionMethod:"semantic_similarity",item1:{id:u.item.itemId,name:N(u.item)||void 0,url:((b=u.item.details)==null?void 0:b.url)||void 0,normalizedUrl:(y=u.item.details)!=null&&y.url&&P(u.item.details.url)||void 0,type:((C=u.item.details)==null?void 0:C.type)||void 0,textPreview:u.text.substring(0,200),embeddingDimensions:((h=D==null?void 0:D.embedding)==null?void 0:h.length)||0,embeddingSample:((p=D==null?void 0:D.embedding)==null?void 0:p.slice(0,5))||[]},item2:{id:S.collection.itemId,name:((w=S.collection.details)==null?void 0:w.name)||void 0,url:void 0,normalizedUrl:void 0,type:"collection",textPreview:((T=(v=S.collection.details)==null?void 0:v.description)==null?void 0:T.substring(0,200))||"",embeddingDimensions:0,embeddingSample:[]}
1,scores:{embeddingSimilarity:(l=(c=S.simResult)==null?void 0:c.breakdown)==null?void 0:l.embeddingScore,titleSimilarity:void 0,finalScore:S.score},decisionFactors:[`Algorithm: ${((g=S.simResult)==null?void 0:g.method)||"tfidf"}`,`Similarity: ${(S.score*100).toFixed(1)}%`,"Item is uncategorized",`Best matching collection among ${t.length} collections`,(A=(x=(f=S.simResult)==null?void 0:f.breakdown)==null?void 0:x.commonTerms)!=null&&A.length?`Common terms: ${S.simResult.breakdown.commonTerms.slice(0,5).join(", ")}`:""].filter(Boolean)},o.push(I)}}return s.length>10&&o.unshift({id:"orphans_summary",type:"organize_orphans",title:`${s.length} uncategorized items`,description:"These items are not in any collection. Consider organizing them.",itemIds:s.map(u=>u.item.itemId),itemPreviews:s.slice(0,5).map(u=>this.createItemPreview(u.item)),score:.6,priority:"medium",createdAt:Date.now(),status:"pending",reason:`${s.length} ${s.length===1?"item has":"items have"} no collection`}),o}async findBestCollectionForItem(e,t,n,i){if(t.length===0)return null;const s=(i==null?void 0:i.minSimilarity)??.3,o=Math.max(1,(i==null?void 0:i.topK)??3),a=Math.max(1,(i==null?void 0:i.minCollectionSize)??3),r=Math.max(0,(i==null?void 0:i.minMargin)??.05),m=new Map;for(const C of n)for(const h of C.collectionIds){const p=m.get(h);p?p.push(C.item.itemId):m.set(h,[C.item.itemId])}let b=null,y=-1/0;for(const C of t){const h=m.get(C.itemId)||[];if(h.length<a)continue;let p=null;const w=[];for(const c of h){const l=this.similarityEngine.similarity(e.item.itemId,c);w.push(l.score),(!p||l.score>p.score)&&(p=l)}if(!p||w.length===0)continue;w.sort((c,l)=>l-c);const v=w.slice(0,o),T=v.reduce((c,l)=>c+l,0)/v.length;!b||T>b.score?(y=(b==null?void 0:b.score)??y,b={collection:C,score:T,simResult:p}):T>y&&(y=T)}return!b||b.score<s||b.score-y<r?null:b}async findStaleItems(e,t){var a,r,m,b;const n=Date.now(),i=t*24*60*60*1e3,s=e.filter(y=>{var w,v;const C=(w=y.feedback)!=null&&w.lastVisit?new Date(y.feedback.lastVisit).getTime():null,h=(v=y.details)!=null&&v.createdAt?new Date(y.details.createdAt).getTime():n;return n-(C||h)>i});if(s.length===0)return[];s.sort((y,C)=>{var w,v;const h=(w=y.feedback)!=null&&w.lastVisit?new Date(y.feedback.lastVisit).getTime():0,p=(v=C.feedback)!=null&&v.lastVisit?new Date(C.feedback.lastVisit).getTime():0;return h-p});const o=[];if(s.length>=5){const y=s.slice(0,20),C={id:"archive_stale",type:"archive_stale",title:s.length>y.length?`Archive the ${y.length} oldest items`:`Archive ${y.length} old items`,description:`These items haven't been accessed in over ${t} days`,itemIds:y.map(w=>w.itemId),itemPreviews:y.slice(0,5).map(w=>this.createItemPreview(w)),score:.7,priority:"low",createdAt:Date.now(),status:"pending",reason:`${s.length} ${s.length===1?"item":"items"} older than ${t} days`,metadata:{daysSinceAccess:t}},h=y[0],p=(a=h==null?void 0:h.feedback)!=null&&a.lastVisit?new Date(h.feedback.lastVisit).toLocaleDateString():(r=h==null?void 0:h.details)!=null&&r.createdAt?new Date(h.details.createdAt).toLocaleDateString():"unknown";C.debugInfo={detectionMethod:"exact_url",item1:{id:(h==null?void 0:h.itemId)||"",name:N(h)||void 0,url:((m=h==null?void 0:h.details)==null?void 0:m.url)||void 0,type:((b=h==null?void 0:h.details)==null?void 0:b.type)||void 0,textPreview:`Last accessed: ${p}`,embeddingDimensions:0,embeddingSample:[]},item2:{id:"",name:`+${y.length-1} more items`,type:void 0},scores:{finalScore:.7},decisionFactors:[`Threshold: ${t} days`,`Found ${s.length} stale items`,`Oldest item last accessed: ${p}`,`Showing top ${y.length} oldest items`]},o.push(C)}return o}async findEmptyCollections(e){const t=await this.indexService.getDataIndex(),n=[];for(const i of e)(await t.itemRelationStore.getItemIdsForCollection(i.itemId)).length===0&&n.push(i);return n.map(i=>{var o,a,r,m,b;const s={id:`empty_${i.itemId}`,type:"remove_empty_collection",title:"Remove empty collection",description:`"${(o=i.details)==null?void 0:o.name}" has no items`,itemIds:[i.itemId],itemPreviews:[this.createItemPreview(i)],targetCollectionId:i.itemId,score:.5,priority:"low",createdAt:Date.now(),status:"pending",reason:"Collection contains 
1no items"};return s.debugInfo={detectionMethod:"exact_url",item1:{id:i.itemId,name:((a=i.details)==null?void 0:a.name)||void 0,url:void 0,normalizedUrl:void 0,type:"collection",textPreview:((m=(r=i.details)==null?void 0:r.description)==null?void 0:m.substring(0,200))||"",embeddingDimensions:0,embeddingSample:[]},item2:{id:"",name:void 0,type:void 0},scores:{finalScore:.5},decisionFactors:["Collection has 0 items",`Created: ${(b=i.details)!=null&&b.createdAt?new Date(i.details.createdAt).toLocaleDateString():"unknown"}`,"Checked via itemRelationStore (source of truth)"]},s})}async suggestCommonOrganizations(e,t,n){var v,T;const i={recommendations:[],organizedCollectionIds:new Set},s=e.filter(c=>c.collectionIds.length===0);if(s.length===0)return i;const o=this.similarityEngine.getConfig().embeddingCacheEnabled??!0,a=new Map;for(const c of F){const l=[];for(const g of c.matchPhrases){const f=await this.embeddingService.generateEmbedding(g,{mode:"query",cacheEnabled:o});f.embedding&&f.embedding.length>0&&l.push(f.embedding)}l.length>0&&a.set(c.id,l)}if(a.size===0)return i;const r=async c=>{const l=await this.getItemEmbedding(c,o);if(!l)return null;const g=[];for(const[f,x]of a){let A=-1/0;for(const u of x)A=Math.max(A,this.embeddingService.cosineSimilarity(u,l));g.push({id:f,score:A})}return{value:c,scores:g,wordCount:Ee(c.text)}},m=[];for(const c of s){const l=await r(c);l&&m.push(l)}const b=new Map;for(const c of e)for(const l of c.collectionIds){const g=b.get(l);g?g.push(c):b.set(l,[c])}const y=[];for(const c of t){const l=[];for(const g of b.get(c.itemId)||[]){const f=await r(g);f&&l.push(f)}y.push({value:c,name:((v=c.details)==null?void 0:v.name)||"",members:l})}const C=$e(y),h=new Set([...C.values()].map(c=>c.value.itemId)),p=[];for(const c of Me(m,C)){const l=c.collection;if(!l){p.push({organization:c.organization,members:c.members});continue}if(l.byName){p.push({organization:c.organization,members:c.members,collection:l.value});continue}const g=((T=b.get(l.value.itemId))==null?void 0:T.map(A=>A.item.itemId))||[],f=c.members.filter(A=>this.closestMembersSimilarity(A.value.item.itemId,g)>=Re),x=c.members.filter(A=>!f.includes(A));f.length>0&&p.push({organization:c.organization,members:f,collection:l.value}),x.length>=ue&&p.push({organization:c.organization,members:x})}return p.sort((c,l)=>l.members.length-c.members.length),{recommendations:p.map(({organization:c,members:l,collection:g})=>{var x,A,u;const f=g?this.fileIntoCollectionRecommendation(c,l,g):this.createCollectionRecommendation(c,l);if(n.debugMode){const S=l[0];f.debugInfo={detectionMethod:"semantic_similarity",item1:{id:`organization:${c.id}`,name:c.name,type:"organization",textPreview:c.matchPhrases.join(" · ").substring(0,200)},item2:{id:S.value.item.itemId,name:N(S.value.item)||void 0,url:((x=S.value.item.details)==null?void 0:x.url)||void 0,type:((A=S.value.item.details)==null?void 0:A.type)||void 0,textPreview:S.value.text.substring(0,200)},scores:{embeddingSimilarity:S.score,finalScore:f.score},decisionFactors:["Best phrase match per organization",g?`Existing collection for ${c.name}: "${(u=g.details)==null?void 0:u.name}"`:"No existing collection",`Minimum score: ${(he*100).toFixed(0)}%`,`Items: ${l.length}`,`Top similarity: ${(S.score*100).toFixed(1)}%`]}}return f}),organizedCollectionIds:h}}closestMembersSimilarity(e,t){const n=t.map(i=>this.similarityEngine.similarity(e,i).score).sort((i,s)=>s-i).slice(0,3);return n.length===0?0:n.reduce((i,s)=>i+s,0)/n.length}createCollectionRecommendation(e,t){const n=t.length;return{id:`organize_${e.id}`,type:"create_collection",title:`Create "${e.name}" collection`,description:`${n} uncategorized items`,itemIds:t.map(i=>i.value.item.itemId),itemPreviews:t.slice(0,5).map(i=>this.createItemPreview(i.value.item)),suggestedCollectionName:e.name,score:this.topScore(t),priority:n>=10?"high":"medium",createdAt:Date.now(),status:"pending",reason:`Best match for ${n} items among ${F.length} common organizations`,metadata:{templateId:e.id}}}fileIntoCollectionRecommendation(e,t,n){const i=t.length,s=oe(n);
1return{id:`file_${e.id}_${n.itemId}`,type:"add_to_collection",title:`Add ${i} ${i===1?"item":"items"} to "${s}"`,description:`Uncategorized ${i===1?"item":"items"} that match ${e.name}`,itemIds:t.map(o=>o.value.item.itemId),itemPreviews:[this.createItemPreview(n),...t.slice(0,5).map(o=>this.createItemPreview(o.value.item))],targetCollectionId:n.itemId,targetCollectionName:s,score:this.topScore(t),priority:i>=10?"high":"medium",createdAt:Date.now(),status:"pending",reason:`"${s}" already holds ${e.name}`,metadata:{templateId:e.id}}}topScore(e){const t=e.slice(0,3);return t.reduce((n,i)=>n+i.score,0)/Math.max(1,t.length)}async getItemEmbedding(e,t){const n=this.similarityEngine.getDocument(e.item.itemId);if(n!=null&&n.embedding&&n.embedding.length>0)return n.embedding;const i=await this.embeddingService.generateEmbedding(e.text,{mode:"document",cacheEnabled:t});return i.embedding&&i.embedding.length>0?i.embedding:null}calculateHealthScore(e,t,n,i){const s=[],o=i.filter(f=>f.collectionIds.length===0).length,a=e.length>0?(e.length-o)/e.length:1;s.push({id:"organized",name:"Organization",score:Math.round(a*100),weight:.3,description:"Percentage of items in collections",improvementTip:o>0?`Organize ${o} uncategorized items`:void 0,currentValue:`${o} orphan items`,targetValue:"0 orphan items"});const r=n.filter(f=>f.type==="merge_duplicates"),m=Math.max(0,100-r.length*10);s.push({id:"uniqueness",name:"Uniqueness",score:m,weight:.2,description:"Absence of duplicate items",improvementTip:r.length>0?`Merge ${r.length} duplicate pairs`:void 0,currentValue:`${r.length} duplicate pairs`,targetValue:"0 duplicates"});const b=t.length>0?e.length/t.length:0,y=b>=3&&b<=50?100:b<3?b*33:Math.max(0,100-(b-50)*2);s.push({id:"balance",name:"Collection Balance",score:Math.round(y),weight:.2,description:"Balanced distribution of items across collections",currentValue:`${b.toFixed(1)} items/collection`,targetValue:"5-20 items/collection"});const h=Date.now()-30*24*60*60*1e3,p=e.filter(f=>{var A;return((A=f.feedback)!=null&&A.lastVisit?new Date(f.feedback.lastVisit).getTime():0)>h}),w=e.length>0?p.length/e.length*100:100;s.push({id:"freshness",name:"Freshness",score:Math.round(Math.min(w*2,100)),weight:.15,description:"Items accessed in last 30 days",currentValue:`${p.length} recently accessed`,targetValue:"Regular usage"});const v=n.filter(f=>f.type==="remove_empty_collection"),T=t.length>0?(t.length-v.length)/t.length*100:100;s.push({id:"completeness",name:"Completeness",score:Math.round(T),weight:.15,description:"Collections with items",currentValue:`${v.length} empty collections`,targetValue:"0 empty collections"});const c=Math.round(s.reduce((f,x)=>f+x.score*x.weight,0)/s.reduce((f,x)=>f+x.weight,0)),l=c>=90?"A":c>=80?"B":c>=70?"C":c>=60?"D":"F",g=n.filter(f=>f.score>.8&&f.priority!=="low").slice(0,3);return{overallScore:c,grade:l,metrics:s,stats:{totalItems:e.length,totalCollections:t.length,orphanItems:o,staleItems:n.filter(f=>f.type==="archive_stale").reduce((f,x)=>f+x.itemIds.length,0),duplicatePairs:r.length,emptyCollections:v.length,avgItemsPerCollection:b},calculatedAt:Date.now(),quickWins:g}}createItemPreview(e){var n,i,s,o,a,r;const t=we(e);return{itemId:e.itemId,name:oe(e),url:((n=e.details)==null?void 0:n.url)||void 0,type:((i=e.details)==null?void 0:i.type)||"item",typeLabel:t==null?void 0:t.label,typeIcon:t==null?void 0:t.icon,favicon:((o=(s=e.details)==null?void 0:s.meta)==null?void 0:o.favicon)||void 0,bannerImagePath:((r=(a=e.details)==null?void 0:a.meta)==null?void 0:r.bannerImagePath)||void 0}}};E(L,"ANALYSIS_IMPLEMENTATION_VERSION",13),E(L,"_instance",null);let j=L;function ze(d,e){const t=d.map(n=>{const i=n.details,s=i!=null&&i.updatedAt?String(i.updatedAt):"",o=[...e.get(n.itemId)||[]].sort().join(",");return`${n.itemId}|${s}|${String((i==null?void 0:i.name)??"")}|${o}`});return t.sort(),`${d.length}:${fe(t.join(`
2`))}`}function fe(d){let e=2166136261;for(let t=0;t<d.length;t++)e^=d.charCodeAt(t),e=Math.imul(e,16777619)>>>0;return e.toString(16)}function le(d){var t;const e=(t=d.details)!=null&&t.createdAt?new Date(d.details.createdAt).getTime():0;return Number.isFinite(e)?e:0}const Ne={getItem:async d=>await ae.instance.getItemInfoById({itemId:d},{})??null,collectionItemIds:async d=>await(await O.instance.getDataIndex()).itemRelationStore.getItemIdsForCollection(d),findCollectionNamed:d=>Ae(d,null),createCollection:d=>xe({name:d}),addItemsToCollection:(d,e)=>Te({itemIds:d,collectionId:e}),archiveItem:d=>Ce(d,!0),deleteCollection:d=>ae.instance.deleteItem({itemId:d,deleteChildren:!1}),afterChange:async(d,e)=>
2{await $.instance.removeAppliedFromCache(d,e),await O.instance.updateDataIndex(!1,!1,!1,!0)}};async function Le(d,e=Ne){let t;switch(d.type){case"create_collection":t=await Ve(d,e);break;case"add_to_collection":t=await Fe(d,e);break;case"archive_stale":t=await Oe(d,e);break;case"remove_empty_collection":t=await Be(d,e);break;case"merge_duplicates":return V("Duplicates are merged in the Duplicates tab.");default:return V("This suggestion has nothing to apply.")}if(t.changed>0||t.collectionId){const n=new Set(t.failed.map(i=>i.id));await e.afterChange(d.id,d.itemIds.filter(i=>!n.has(i)))}return t}async function Ve(d,e){var m;const t=(m=d.suggestedCollectionName)==null?void 0:m.trim();if(!t)return V("This suggestion has no collection name.");if(d.itemIds.length===0)return V("This suggestion has no items.");const n=await e.findCollectionNamed(t),i=n??await e.createCollection(t),{added:s,failed:o}=await e.addItemsToCollection(d.itemIds,i),a=q(s.length),r=n?`Added ${a} to "${t}"`:`Created "${t}" with ${a}`;return{success:o.length===0,changed:s.length,failed:o,collectionId:i,collectionName:t,message:K(r,o.length,"could not be added")}}async function Fe(d,e){const t=d.targetCollectionId,n=t?await e.getItem(t):null;if(!t||!(n!=null&&n.details)||n.details.type!==z.collection)return V("That collection is gone.");if(X(n))return V("Items are not filed into this collection.");const i=Q(n.details)||d.targetCollectionName||"the collection",s=new Set(await e.collectionItemIds(t)),o=d.itemIds.filter(m=>!s.has(m));if(o.length===0)return{success:!0,changed:0,failed:[],collectionId:t,collectionName:i,message:`Already in "${i}"`};const{added:a,failed:r}=await e.addItemsToCollection(o,t);return{success:r.length===0,changed:a.length,failed:r,collectionId:t,collectionName:i,message:K(`Added ${q(a.length)} to "${i}"`,r.length,"could not be added")}}async function Oe(d,e){let t=0;const n=[];for(const i of d.itemIds)try{await e.archiveItem(i),t++}catch(s){n.push({id:i,name:pe(d,i),error:(s==null?void 0:s.message)||String(s)})}return{success:n.length===0,changed:t,failed:n,message:K(`Archived ${q(t)}`,n.length,"could not be archived")}}async function Be(d,e){const t=d.targetCollectionId?[d.targetCollectionId]:d.itemIds;let n=0;const i=[];for(const o of t){const a=await e.getItem(o),r=a!=null&&a.details?Q(a.details):pe(d,o);try{if(!(a!=null&&a.details)||a.details.type!==z.collection)throw new Error("It is gone");if(X(a))throw new Error("The app keeps this collection");if((await e.collectionItemIds(o)).length>0)throw new Error("It has items now");if(Number(a.details.itemCount)>0)throw new Error("It has items now");await e.deleteCollection(o),n++}catch(m){i.push({id:o,name:r,error:(m==null?void 0:m.message)||String(m)})}}const s=n===1?"Deleted 1 empty collection":`Deleted ${n} empty collections`;return{success:i.length===0,changed:n,failed:i,message:n===0&&i.length===1?`Not deleted: ${i[0].error}`:K(s,i.length,"kept")}}function V(d){return{success:!1,changed:0,failed:[],message:d}}function q(d){return d===1?"1 item":`${d} items`}function K(d,e,t){return e===0?d:`${d}; ${e} ${t}`}function pe(d,e){var t,n;return((n=(t=d.itemPreviews)==null?void 0:t.find(i=>i.itemId===e))==null?void 0:n.name)||""}const k=[];k.push({path:"/libraryHealth/analyze",handler:async(d,e,t)=>await j.instance.analyzeLibrary({forceRefresh:e.forceRefresh,disableCaches:e.disableCaches,includeEmbeddingsByItemId:e.includeEmbeddingsByItemId,maxItems:e.maxItems,duplicateThreshold:e.duplicateThreshold,staleDaysThreshold:e.staleDaysThreshold,debug:e.debug,preferences:e.preferences})});k.push({path:"/libraryHealth/getRecommendations",handler:async(d,e,t)=>{var o;const n=$.instance;if(e.includeAll){const a=await n.getCachedAnalysis();return _(`LibraryHealth: getRecommendations (includeAll) returned ${((o=a==null?void 0:a.recommendations)==null?void 0:o.length)||0} recs`),{recommendations:(a==null?void 0:a.recommendations)||[],healthScore:a==null?void 0:a.healthScore}}const i=await n.getActiveRecommendations(),s=await n.getCachedAnalysis();return _(`LibraryHealth: getRecommendations returned ${i.length} active recs`),{recommendations:i,healthScore:s==null?void 0:s.healthScore}}});k.push({path:"/libraryHealth/dismissRecommendation",handler:async(d,e,t)=>(await $.instance.dismissRecommendation(e.recommendationId),{success:!0})});k.push({path:"/libraryHealth/snoozeRecommendation",handler:async(d,e,t)=>{const n=e.days||7,i=Date.now()+n*24*60*60*1e3;return await $.instance.snoozeRecommendation(e.recommendationId,i),{success:!0}}});k.push({path:"/libraryHealth/applyRecommendation",handler:async(d,e,t)=>{var s;const n=e.recommendation,i=n&&typeof n.type=="string"&&Array.isArray(n.itemIds)?n:(s=await $.instance.getCachedAnalysis(Number.POSITIVE_INFINITY))==null?void 0:s.recommendations.find(o=>o.id===e.recommendationId);return i?await Le(i):{success:!1,message:"That suggestion is no longer there. Run the analysis again."}}});k.push({path:"/libraryHealth/getSmartCollections",handler:async(d,e,t)=>{const n=await $.instance.getCachedAnalysis();return{smartCollections:(n==null?void 0:n.smartCollections)||[]}}});k.push({path:"/libraryHealth/getPreferences",handler:async(d,e,t)=>({preferences:await $.instance.getPreferences()})});k.push({path:"/libraryHealth/updatePreferences",handler:async(d,e,t)=>(await $.instance.updatePreferences(e.preferences),{success:!0})});k.push({path:"/libraryHealth/clearCache",handler:async(d,e,t)=>(await $.instance.clearCache(),{success:!0})});k.push({path:"/libraryHealth/getStats",handler:async(d,e,t)=>({stats:await $.instance.getStats()})});k.push({path:"/libraryHealth/listCollections",handler:async(d,e,t)=>{const n=typeof e.maxCollections=="number"?e.maxCollections:2e3;return{collections:(await(await O.instance.getDataIndex()).itemDataStore.listAll()).filter(a=>{var r;return((r=a.details)==null?void 0:r.type)===z.collection}).slice(0,n).map(a=>{var r,m;return{id:a.itemId,name:((r=a.details)==null?void 0:r.name)||a.itemId,description:((m=a.details)==null?void 0:m.description)||""}})}}});k.push({path:"/libraryHealth/getSimilarCollections",handler:async(d,e,t)=>await j.instance.getSimilarCollections({sourceCollectionId:e.sourceCollectionId,sourceItemId:e.sourceItemId,sourceText:e.sourceText,sourceLabel:e.sourceLabel,method:e.method,topK:e.topK,minScore:e.minScore,maxCollections:e.maxCollections,maxSourceItems:e.maxSourceItems,neighborTopKPerItem:e.neighborTopKPerItem,maxItemsToIndex:e.maxItemsToIndex})});k.push({path:"/libraryHealth/getAnalyzableItems",handler:async(d,e,t)=>{const n=typeof e.maxItems=="number"?e.maxItems:1e3;return{items:(await(await O.instance.getDataIndex()).itemDataStore.listAll()).filter(a=>{var r;return((r=a.details)==null?void 0:r.type)!==z.collection}).slice(0,n).map(a=>{var m,b,y;const r=Z({title:ve(a.details),description:((m=a.details)==null?void 0:m.description)||"",url:((b=a.details)==null?void 0:b.url)||""});return{id:a.itemId,name:Q(a.details),url:((y=a.details)==null?void 0:y.url)||"",text:r}})}}});
2export{k as default};

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.