1import{k as c}from"./D39WfGqu.js";class i{constructor(){this.cache=new Map,this.cacheExpiry=1440*60*1e3,this.enableCaching=!0,this.fallbackWords={words:{damn:["function:swear"],hell:["function:swear"],shit:["function:swear"],fuck:["function:swear"],fucking:["function:swear"],ass:["function:swear"],bitch:["function:swear"],bastard:["function:swear"]},stems:{"damn*":["function:swear"],"fuck*":["function:swear"],"shit*":["function:swear"],"bitch*":["function:swear"]}}}async getWordList(e,t="en"){const o=`${e.sort().join(",")}-${t}`;if(this.enableCaching&&this.cache.has(o)){const a=this.cache.get(o);if(Date.now()-a.timestamp<this.cacheExpiry)return console.log(`ðï¸ Using cached word list for categories: ${e.join(", ")}`),a.data;console.log(`â° Cache expired for categories: ${e.join(", ")}, refetching...`)}else this.enableCaching||console.log(`ð Development mode: bypassing cache for categories: ${e.join(", ")}`);try{console.log(`ð Fetching word list from API for categories: ${e.join(", ")}`);const s=c().public.railsApiUrl,n=await $fetch("/api/v1/analyze/wordlist",{baseURL:s,params:{categories:e.join(","),lang:t,format:"detailed"}});if(!n.words||!n.stems)throw new Error("Invalid API response structure");return this.enableCaching?(this.cache.set(o,{data:n,timestamp:Date.now()}),this.saveToLocalStorage(o,n),console.log("ð¾ Cached word list for future use")):console.log("ð« Development mode: skipping cache storage"),console.log(`â
Fetched ${Object.keys(n.words).length} words and ${Object.keys(n.stems).length} stems`),n}catch(a){if(console.warn(`â Redaction API failed: ${a.message}`),this.enableCaching){const s=this.loadFromLocalStorage(o);if(s)return console.log("ð± Using stored word list from localStorage"),s}return console.log("ð Using fallback word list"),{categories:e,language:t,words:this.fallbackWords.words,stems:this.fallbackWords.stems,metadata:{total_words:Object.keys(this.fallbackWords.words).length,total_stems:Object.keys(this.fallbackWords.stems).length,fallback:!0}}}}matchesRedactionRule(e,t){const o=e.toLowerCase().replace(/[^\w]/g,"");if(o.length<3)return null;const a=this.exactMatch(o,t);if(a)return a;const s=this.stemMatch(o,t);if(s)return s;const n=this.progressiveMatch(o,t);return n||null}exactMatch(e,t){return t.words[e]?(console.log(`ð¯ EXACT MATCH! "${e}" found in categories: ${t.words[e].join(", ")}`),t.words[e]):null}stemMatch(e,t){for(const[o,a]of Object.entries(t.stems)){const s=o.replace("*","");if(e.startsWith(s))return console.log(`ð¯ STEM MATCH! "${e}" matched pattern "${o}" in categories: ${a.join(", ")}`),a}return null}progressiveMatch(e,t){let o=e.length;for(;o>=3;){o--;const a=e.substring(0,o)+"*";if(t.stems[a])return console.log(`ð¯ PROGRESSIVE MATCH! "${e}" matched progressive stem "${a}" in categories: ${t.stems[a].join(", ")}`),t.stems[a]}return null}getRedactionLevel(e){return!e||e.length===0?1:e.includes("topic:violence")?4:e.includes("topic:sex")?3:e.includes("function:swear")||e.includes("emotion:anger")?2:1}async getAvailableCategories(e="en"){try{const o=c().public.railsApiUrl;return(await $fetch("/api/v1/analyze/wordlist",{baseURL:o,params:{categories:"all",lang:e,format:"simple"}})).categories}catch(t){return console.warn("Failed to fetch available categories:",t),["function:swear","topic:sex","topic:violence","emotion:anger","body"]}}clearCache(){if(!this.enableCaching){console.log("ð Development mode: no cache to clear");return}this.cache.clear(),Object.keys(localStorage).forEach(e=>{e.startsWith("redaction-cache-")&&localStorage.removeItem(e)}),console.log("ðï¸ Redaction cache cleared")}getCacheStats(){const e={cachingEnabled:this.enableCaching,mode:this.enableCaching?"production":"development",memoryCache:{entries:this.enableCaching?this.cache.size:"disabled",keys:this.enableCaching?Array.from(this.cache.keys()):[]},localStorage:{entries:0,keys:[]}};return this.enableCaching?Object.keys(localStorage).forEach(t=>{t.startsWith("redaction-cache-")&&(e.localStorage.entries++,e.localStorage.keys.push(t))}):this.enableCaching||(e.localStorage.entries="disabled"),e}saveToLocalStorage(e,t){if(this.enableCaching)try{const o=`redaction-cache-${e}`,a={data:t,timestamp:Date.now()};localStorage.setItem(o,JSON.stringify(a))}catch(o){console.warn("Failed to save to localStorage:",o)}}loadFromLocalStorage(e){if(!this.enableCaching)return null;try{const t=`redaction-cache-${e}`,o=localStorage.getItem(t);if(!o)return null;const a=JSON.parse(o);return Date.now()-a.timestamp<this.cacheExpiry?a.data:(localStorage.removeItem(t),null)}catch(t){return console.warn("Failed to load from localStorage:",t),null}}async preloadCommonCategories(e="en"){const t=[["function:swear"],["function:swear","topic:sex"],["function:swear","topic:sex","topic:violence"]];console.log("ð Preloading common redaction categories...");const o=t.map(a=>this.getWordList(a,e).catch(s=>(console.warn(`Failed to preload categories ${a.join(",")}: ${s.message}`),null)));await Promise.all(o),console.log("â
Preloading complete")}}const r=new i;r.enableCaching?console.log("ðï¸ Redaction service initialized with caching enabled (production mode)"):console.log("ð Redaction service initialized with caching disabled (development mode)");window.redactionService=r;export{i as RedactionService,r as redactionService};
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.