var L={gemini:{apiKey:"",model:"gemini-3.1-flash-lite-preview"},chatgpt:{apiKey:"",model:"gpt-4.1-mini"},deepseek:{apiKey:"",model:"deepseek-chat"},qwen:{apiKey:"",model:"qwen3.5-flash"},kimi:{apiKey:"",model:"kimi-k2.5"}},$={llm:{activeProvider:"gemini",providers:{...L}},sensitivity:3,scanThreshold:"medium",chunkGranularity:"fine",chunkIntensity:5,disabledSites:[]},he={gemini:{format:"gemini",baseUrl:"",label:"Gemini"},chatgpt:{format:"openai-compatible",baseUrl:"https://api.openai.com",label:"ChatGPT"},deepseek:{format:"openai-compatible",baseUrl:"https://api.deepseek.com",label:"DeepSeek"},qwen:{format:"openai-compatible",baseUrl:"https://dashscope.aliyuncs.com/compatible-mode",label:"Qwen"},kimi:{format:"openai-compatible",baseUrl:"https://api.moonshot.cn",label:"Kimi"}};function k(e){let t=e.activeProvider,n=e.providers[t],r=he[t];return{format:r.format,apiKey:n.apiKey,baseUrl:r.baseUrl,model:n.model}}function G(e){if(e&&typeof e=="object"&&"activeProvider"in e)return e;let t=e,n={...L};if(t?.apiKey){let r=t.format==="gemini"?"gemini":"chatgpt";return n[r]={apiKey:t.apiKey,model:t.model||L[r].model},{activeProvider:r,providers:n}}return{activeProvider:"gemini",providers:n}}var q=10080*60*1e3;var fe="openen-cache",we=1,b="chunks";function F(){return new Promise((e,t)=>{let n=indexedDB.open(fe,we);n.onupgradeneeded=()=>{let r=n.result;r.objectStoreNames.contains(b)||r.createObjectStore(b,{keyPath:"hash"})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}function H(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=t*16777619>>>0;return t.toString(36)}async function z(e){let t=new Map;try{let a=(await F()).transaction(b,"readonly").objectStore(b);await Promise.all(e.map(s=>new Promise(i=>{let d=H(s),o=a.get(d);o.onsuccess=()=>{let u=o.result;u&&Date.now()-u.timestamp<=q&&t.set(s,u.result),i()},o.onerror=()=>i()})))}catch{}return t}async function J(e){try{let r=(await F()).transaction(b,"readwrite").objectStore(b);for(let{sentence:a,result:s}of e){let i=H(a);r.put({hash:i,result:s,timestamp:Date.now()})}}catch{}}function _e(e,t=[]){return`You are an English reading assistant. Your job is to restructure complex English sentences into indented chunks that reveal their grammatical structure, making them easier to parse visually.

## Rules

1. **Skeleton first**: The main clause (subject-verb-object) stays at the top level (no indentation).
2. **Indent subordinate elements**: Each level of nesting gets 2 more spaces of indentation:
   - Subordinate clauses (that, which, who, if, because, although, etc.)
   - Relative clauses
   - Conditional clauses
   - Temporal clauses
   - Participial phrases, prepositional phrases, and appositive phrases
3. **Simple sentences**: If a sentence has no subordinate clauses and is straightforward, return it unchanged with is_simple=true.
4. **Preserve original text**: Do not change any words. Only add line breaks and indentation. Do NOT add brackets, parentheses, or any other symbols that are not in the original text.

## New Words

${t.length>0?`The user already knows these words (do NOT mark them as new): ${t.join(", ")}`:"The user is at an advanced English level (IELTS 7+). Be very selective \u2014 only mark words that a proficient non-native reader would genuinely not know."}

For each sentence, identify words that the user likely doesn't know. Provide a brief Chinese definition for each.

Important constraints for new_words:
- Do NOT mark proper nouns, brand names, or product names (e.g. ChatGPT, Google, Tesla, iPhone)
- Do NOT mark common tech/internet terms (e.g. AI, API, app, blog, email, online)
- Do NOT mark words that appear in any standard 6000-word English vocabulary list
- Only mark words that would genuinely challenge an advanced reader \u2014 rare, literary, domain-specific, or highly idiomatic expressions
- When in doubt, do NOT mark it. Fewer is better.

## Input

${e.map((r,a)=>`[${a}] ${r}`).join(`
`)}

## Output Format

Return a JSON array with one object per input sentence, in the same order:

\`\`\`json
[
  {
    "index": 0,
    "original": "the original sentence",
    "chunked": "the chunked version with\\n  indentation\\n    and nested clauses",
    "is_simple": false,
    "new_words": [
      {"word": "example", "definition": "\u4F8B\u5B50\uFF0C\u5B9E\u4F8B"}
    ]
  }
]
\`\`\`

Important:
- Use \\n for line breaks in the chunked field
- Use spaces (not tabs) for indentation, 2 spaces per level
- Return valid JSON only, no markdown fences
- The array must have exactly ${e.length} elements`}var xe="https://generativelanguage.googleapis.com/v1beta/models";function Y(e,t){let n=t.model||"gemini-2.0-flash";return{url:`${xe}/${n}:generateContent?key=${t.apiKey}`,body:{contents:[{parts:[{text:e}]}],generationConfig:{temperature:.1,responseMimeType:"application/json",thinkingConfig:{thinkingBudget:0}}}}}function X(e,t){let r=`${t.baseUrl.replace(/\/+$/,"")}/v1/chat/completions`,a={model:t.model,messages:[{role:"system",content:"You are a helpful English reading assistant. Always respond with valid JSON."},{role:"user",content:e}]},s={"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`};return{url:r,body:a,headers:s}}function Ie(e){let n=e?.candidates?.[0]?.content?.parts?.[0]?.text;if(!n)throw new Error("Gemini \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return Z(n)}function De(e){let n=e?.choices?.[0]?.message?.content;if(!n)throw new Error("OpenAI \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return Z(n)}function Z(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/);n&&(t=n[1].trim());let r;try{r=JSON.parse(t)}catch{throw new Error(`LLM \u8FD4\u56DE\u7684 JSON \u683C\u5F0F\u65E0\u6548: ${t.slice(0,100)}...`)}if(r&&typeof r=="object"&&!Array.isArray(r)){let a=r,s=Object.keys(a).find(i=>Array.isArray(a[i]));s&&(r=a[s])}if(!Array.isArray(r))throw new Error("LLM \u8FD4\u56DE\u7684\u4E0D\u662F\u6570\u7EC4\u683C\u5F0F");return r.map(a=>({index:a.index??0,original:a.original??"",chunked:a.chunked??a.original??"",is_simple:a.is_simple??!0,new_words:Array.isArray(a.new_words)?a.new_words:[]}))}function Q(e,t){return e.map((n,r)=>{let a=t.find(s=>s.index===r);return a?{original:a.original||n,chunked:a.chunked,isSimple:a.is_simple,newWords:a.new_words??[]}:{original:n,chunked:n,isSimple:!0,newWords:[]}})}async function ee(e,t,n=[]){let r=_e(e,n),a;if(t.format==="gemini"){let{url:s,body:i}=Y(r,t),d=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!d.ok){let u=await d.text();throw new Error(`Gemini API \u9519\u8BEF (${d.status}): ${u.slice(0,200)}`)}a=await d.json();let o=Ie(a);return Q(e,o)}else{let{url:s,body:i,headers:d}=X(r,t),o=await fetch(s,{method:"POST",headers:d,body:JSON.stringify(i)});if(!o.ok){let be=await o.text();throw new Error(`OpenAI API \u9519\u8BEF (${o.status}): ${be.slice(0,200)}`)}a=await o.json();let u=De(a);return Q(e,u)}}var te=["insertion","background_first","nested","long_list","inverted","long_subject","omission","contrast","condition","long_modifier","other"];function Re(e){return`You are an English reading assistant for Chinese learners. Analyze the following English sentence in depth.

## Input sentence

${e}

## Output format

Return a single JSON object (NOT an array) with these fields:

\`\`\`json
{
  "chunked": "the chunked version with\\n  indentation",
  "pattern_key": "one of the allowed keys",
  "sentence_analysis": "\u7528\u4E2D\u6587\u89E3\u91CA\u8FD9\u53E5\u8BDD\u4E3A\u4EC0\u4E48\u96BE\u8BFB\uFF0C\u6307\u51FA\u54EA\u4E9B\u7ED3\u6784\u9020\u6210\u4E86\u9605\u8BFB\u969C\u788D",
  "expression_tips": "\u7528\u4E2D\u6587\u8BB2\u89E3\u8FD9\u53E5\u8BDD\u4E2D\u503C\u5F97\u5B66\u4E60\u7684\u8868\u8FBE\u65B9\u5F0F\u548C\u53E5\u5F0F\uFF0C\u7528 **\u52A0\u7C97** \u6807\u6CE8\u5173\u952E\u8868\u8FBE",
  "new_words": [{"word": "example", "definition": "\u4F8B\u5B50\uFF0C\u5B9E\u4F8B"}],
  "is_worth_practicing": true
}
\`\`\`

## Rules

### chunked
- Main clause (subject-verb-object) at top level (no indentation)
- Indent subordinate elements with 2 spaces per level
- Preserve original text exactly, only add \\n and spaces

### pattern_key
Must be one of: ${te.join(", ")}

### sentence_analysis & expression_tips
- Write in Chinese (\u4E2D\u6587)
- Be concise but insightful

### new_words
- Only words that a IELTS 7+ Chinese reader might not know
- Do NOT mark proper nouns, brand names, common tech terms
- Provide brief Chinese definitions

### is_worth_practicing
- true if the sentence has interesting structure worth studying
- false if it's straightforward despite being long

Return valid JSON only, no markdown fences.`}function ve(e){let t=e.trim(),n=t.match(/```(?:json)?\s*([\s\S]*?)```/);n&&(t=n[1].trim());let r;try{r=JSON.parse(t)}catch{throw new Error(`LLM \u8FD4\u56DE\u7684 JSON \u683C\u5F0F\u65E0\u6548: ${t.slice(0,100)}...`)}let a=r,s=String(a.pattern_key||"other");return te.includes(s)||(s="other"),{chunked:String(a.chunked||""),pattern_key:s,sentence_analysis:String(a.sentence_analysis||""),expression_tips:String(a.expression_tips||""),new_words:Array.isArray(a.new_words)?a.new_words.map(i=>({word:String(i.word||""),definition:String(i.definition||"")})):[],is_worth_practicing:!!a.is_worth_practicing}}function ke(e,t){if(t==="gemini"){let r=e?.candidates?.[0]?.content?.parts?.[0]?.text;if(!r)throw new Error("Gemini \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return r}else{let r=e?.choices?.[0]?.message?.content;if(!r)throw new Error("OpenAI \u8FD4\u56DE\u4E86\u7A7A\u54CD\u5E94");return r}}async function ne(e,t){let n=Re(e),r;if(t.format==="gemini"){let{url:s,body:i}=Y(n,t),d=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!d.ok){let o=await d.text();throw new Error(`Gemini API \u9519\u8BEF (${d.status}): ${o.slice(0,200)}`)}r=await d.json()}else{let{url:s,body:i,headers:d}=X(n,t),o=await fetch(s,{method:"POST",headers:d,body:JSON.stringify(i)});if(!o.ok){let u=await o.text();throw new Error(`OpenAI API \u9519\u8BEF (${o.status}): ${u.slice(0,200)}`)}r=await o.json()}let a=ke(r,t.format);return ve(a)}var Pe="openen-data";var c={vocab:"vocab",vocab_contexts:"vocab_contexts",patterns:"patterns",pattern_examples:"pattern_examples",learning_records:"learning_records",settings:"settings",weekly_reports:"weekly_reports",review_items:"review_items",wallpaper_records:"wallpaper_records",pending_sentences:"pending_sentences"};function S(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var h=null;function re(e=indexedDB){return h?Promise.resolve(h):new Promise((t,n)=>{let r=e.open(Pe,2);r.onupgradeneeded=a=>{let s=r.result,i=a.oldVersion,d=r.transaction;Se(s,i,d)},r.onsuccess=()=>{h=r.result,h.onclose=()=>{h=null},t(h)},r.onerror=()=>n(r.error)})}function Se(e,t,n){t<1&&Be(e),t<2&&Te(e,n)}function Be(e){let t=e.createObjectStore(c.vocab,{keyPath:"id"});t.createIndex("by_word","word",{unique:!0}),t.createIndex("by_status","status"),t.createIndex("by_updated_at","updated_at");let n=e.createObjectStore(c.vocab_contexts,{keyPath:"id"});n.createIndex("by_vocab_id","vocab_id"),n.createIndex("by_updated_at","updated_at");let r=e.createObjectStore(c.patterns,{keyPath:"id"});r.createIndex("by_key","key",{unique:!0}),r.createIndex("by_updated_at","updated_at");let a=e.createObjectStore(c.pattern_examples,{keyPath:"id"});a.createIndex("by_pattern_id","pattern_id"),a.createIndex("by_updated_at","updated_at");let s=e.createObjectStore(c.learning_records,{keyPath:"id"});s.createIndex("by_created_at","created_at"),s.createIndex("by_pattern_key","pattern_key"),s.createIndex("by_source_url","source_url"),s.createIndex("by_updated_at","updated_at"),e.createObjectStore(c.settings,{keyPath:"key"}).createIndex("by_updated_at","updated_at");let d=e.createObjectStore(c.weekly_reports,{keyPath:"id"});d.createIndex("by_week_start","week_start",{unique:!0}),d.createIndex("by_updated_at","updated_at");let o=e.createObjectStore(c.review_items,{keyPath:"id"});o.createIndex("by_type","type"),o.createIndex("by_reference_id","reference_id"),o.createIndex("by_next_review_at","next_review_at"),o.createIndex("by_updated_at","updated_at");let u=e.createObjectStore(c.wallpaper_records,{keyPath:"id"});u.createIndex("by_created_at","created_at"),u.createIndex("by_updated_at","updated_at")}function Te(e,t){let n=e.createObjectStore(c.pending_sentences,{keyPath:"id"});n.createIndex("by_text","text",{unique:!0}),n.createIndex("by_analyzed","analyzed"),n.createIndex("by_created_at","created_at"),n.createIndex("by_source_hostname","source_hostname"),n.createIndex("by_manual","manual"),n.createIndex("by_updated_at","updated_at"),t.objectStore(c.learning_records).createIndex("by_sentence","sentence")}function _(e,t,n){return e.transaction(t,n).objectStore(t)}function x(e){return new Promise((t,n)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>n(e.error)})}function ae(e){return new Promise((t,n)=>{e.oncomplete=()=>t(),e.onerror=()=>n(e.error),e.onabort=()=>n(e.error)})}async function E(e,t,n){return x(_(e,t,"readonly").get(n))}async function P(e,t,n,r){let s=_(e,t,"readonly").index(n);return x(s.getAll(r))}async function B(e,t){return x(_(e,t,"readonly").getAll())}async function m(e,t,n){let r=e.transaction(t,"readwrite");r.objectStore(t).put(n),await ae(r)}async function T(e,t,n){let r=e.transaction(t,"readwrite");r.objectStore(t).delete(n),await ae(r)}async function M(e,t,n,r){let s=_(e,t,"readonly").index(n);return x(s.get(r))}var f={async add(e,t){let n=Date.now(),r={id:S(),encounter_count:1,first_seen_at:n,updated_at:n,is_dirty:!0,...t};return await m(e,c.vocab,r),r},async getById(e,t){return E(e,c.vocab,t)},async getByWord(e,t){return M(e,c.vocab,"by_word",t)},async getByStatus(e,t){return P(e,c.vocab,"by_status",t)},async getAll(e){return B(e,c.vocab)},async update(e,t,n){let r=await this.getById(e,t);if(!r)return;let a={...r,...n,id:t,updated_at:Date.now(),is_dirty:!0};return await m(e,c.vocab,a),a},async delete(e,t){await T(e,c.vocab,t)},async recordEncounter(e,t){let n=await this.getById(e,t);if(n)return this.update(e,t,{encounter_count:n.encounter_count+1})},async markMastered(e,t){return this.update(e,t,{status:"mastered",mastered_at:Date.now()})},async getMasteredWords(e){let t=await this.getByStatus(e,"mastered");return new Set(t.map(n=>n.word))}},se={async add(e,t){let n=Date.now(),r={id:S(),created_at:n,updated_at:n,is_dirty:!0,...t};return await m(e,c.vocab_contexts,r),r},async getByVocabId(e,t){return P(e,c.vocab_contexts,"by_vocab_id",t)},async getAll(e){return B(e,c.vocab_contexts)},async delete(e,t){await T(e,c.vocab_contexts,t)}};var j={async add(e,t){let n=Date.now(),r={id:S(),created_at:n,updated_at:n,is_dirty:!0,...t};return await m(e,c.learning_records,r),r},async getById(e,t){return E(e,c.learning_records,t)},async getAll(e){return B(e,c.learning_records)},async getByPatternKey(e,t){return P(e,c.learning_records,"by_pattern_key",t)},async getBySourceUrl(e,t){return P(e,c.learning_records,"by_source_url",t)},async update(e,t,n){let r=await this.getById(e,t);if(!r)return;let a={...r,...n,id:t,updated_at:Date.now(),is_dirty:!0};return await m(e,c.learning_records,a),a},async delete(e,t){await T(e,c.learning_records,t)},async getBySentence(e,t){return M(e,c.learning_records,"by_sentence",t)},async getByDateRange(e,t,n){let a=_(e,c.learning_records,"readonly").index("by_created_at"),s=IDBKeyRange.bound(t,n);return x(a.getAll(s))}};var I={async add(e,t){if(await this.getByText(e,t.text))return null;let r=Date.now(),a={id:S(),analyzed:!1,created_at:r,updated_at:r,is_dirty:!0,...t};return await m(e,c.pending_sentences,a),a},async getById(e,t){return E(e,c.pending_sentences,t)},async getByText(e,t){return M(e,c.pending_sentences,"by_text",t)},async getAll(e){return B(e,c.pending_sentences)},async getUnanalyzed(e){return(await this.getAll(e)).filter(n=>!n.analyzed).sort((n,r)=>n.manual!==r.manual?n.manual?-1:1:r.created_at-n.created_at)},async getPage(e,t,n){let r=await this.getAll(e);r.sort((s,i)=>s.manual!==i.manual?s.manual?-1:1:i.created_at-s.created_at);let a=(t-1)*n;return{records:r.slice(a,a+n),total:r.length}},async markAnalyzed(e,t){let n=await this.getById(e,t);n&&await m(e,c.pending_sentences,{...n,analyzed:!0,updated_at:Date.now(),is_dirty:!0})},async delete(e,t){await T(e,c.pending_sentences,t)}};var N=new Map;async function ie(e){if(N.has(e))return N.get(e);let t=chrome.runtime.getURL(e),n=await fetch(t);if(!n.ok)throw new Error(`Failed to load ${e}: ${n.status}`);let r=await n.json();return N.set(e,r),r}var A=null,C=null;async function Ce(){A||(C||(C=ie("data/core-imagery.json").then(e=>{A=e}).catch(e=>{console.warn("[\u63B0it] \u6838\u5FC3\u610F\u8C61\u6570\u636E\u52A0\u8F7D\u5931\u8D25:",e),C=null})),await C)}async function oe(e){return await Ce(),A?A[e.toLowerCase()]??null:null}var ce="phc_USA7kkQsvO2IHXCQiwsgy4Z58W7IP4eEKMxTpNFbBBD",de="https://us.i.posthog.com",Ae={analyticsOptIn:null,installTimestamp:0};async function Oe(){return await chrome.storage.sync.get(Ae)}async function K(){return(await Oe()).analyticsOptIn===!0}async function ue(){let t=(await chrome.storage.local.get("analyticsClientId")).analyticsClientId;return t||(t=crypto.randomUUID(),await chrome.storage.local.set({analyticsClientId:t})),t}var p=[];var Le=20;function le(){chrome.alarms.create("analytics-flush",{periodInMinutes:.5}),chrome.alarms.onAlarm.addListener(e=>{e.name==="analytics-flush"&&V().catch(()=>{})}),Ee().then(()=>{V().catch(()=>{})})}function pe(){chrome.storage.sync.get("installTimestamp",e=>{e.installTimestamp||chrome.storage.sync.set({installTimestamp:Date.now()})})}async function ge(e,t){await K()&&(p.push({event:e,properties:t,timestamp:new Date().toISOString()}),await U(),p.length>=Le&&await V())}async function V(){if(p.length===0)return;if(!await K()){p=[],await U();return}let t=await ue(),n=p.splice(0);try{(await fetch(`${de}/batch/`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({api_key:ce,batch:n.map(a=>({event:a.event,properties:{...a.properties,distinct_id:t,$lib:"bait-chrome-extension"},timestamp:a.timestamp}))})})).ok||p.unshift(...n)}catch{p.unshift(...n)}await U()}async function U(){let e=p.slice(0,100);await chrome.storage.local.set({analyticsQueue:e})}async function Ee(){let t=(await chrome.storage.local.get({analyticsQueue:[]})).analyticsQueue;t.length>0&&p.push(...t)}async function y(){let e=Object.keys($),n=await chrome.storage.sync.get(e);return Array.isArray(n.disabledSites)||(n.disabledSites=[]),n.chunkGranularity||(n.chunkGranularity="fine"),n.llm=G(n.llm),n}async function Me(e){let t=await y(),n={...t,...e};return e.llm&&(n.llm={...t.llm,...e.llm}),await chrome.storage.sync.set(n),n}function D(e){try{return new URL(e).hostname}catch{return""}}async function R(e){return!(await y()).disabledSites.includes(e)}async function je(e){let t=await y(),n=t.disabledSites.indexOf(e),r;return n>=0?(t.disabledSites.splice(n,1),r=!0):(t.disabledSites.push(e),r=!1),await chrome.storage.sync.set({disabledSites:t.disabledSites}),{enabled:r,disabledSites:t.disabledSites}}async function g(e,t){let n=t?"-on":"";try{await chrome.action.setIcon({path:{16:`icons/icon16${n}.png`,48:`icons/icon48${n}.png`,128:`icons/icon128${n}.png`},tabId:e})}catch{}}async function v(e){return(await chrome.storage.session.get({pausedTabs:[]})).pausedTabs.includes(e)}async function ye(e){let n=(await chrome.storage.session.get({pausedTabs:[]})).pausedTabs;n.includes(e)||(n.push(e),await chrome.storage.session.set({pausedTabs:n}))}async function W(e){let n=(await chrome.storage.session.get({pausedTabs:[]})).pausedTabs.filter(r=>r!==e);await chrome.storage.session.set({pausedTabs:n})}chrome.tabs.onRemoved.addListener(async e=>{await W(e)});var l=null,Ne=50,Ke=5;function Ve(e,t){return new Promise(n=>{l||(l={sentences:[],source_url:t,resolvers:new Map,timer:null}),l.sentences.push(e),l.resolvers.set(e,n),l.timer&&clearTimeout(l.timer),l.sentences.length>=Ke?me():l.timer=setTimeout(me,Ne)})}async function me(){if(!l||l.sentences.length===0)return;let e=l;l=null,e.timer&&clearTimeout(e.timer);try{let t=await y(),n=k(t.llm);if(!n.apiKey)throw new Error("API key \u672A\u914D\u7F6E");let r=await ee(e.sentences,n),a=r.map((s,i)=>({sentence:e.sentences[i],result:s}));J(a).catch(()=>{});for(let s=0;s<r.length;s++){let i=e.resolvers.get(e.sentences[s]);i&&i(r[s])}Ue(r.filter(s=>!s.isSimple).length)}catch{for(let[t,n]of e.resolvers)n({original:t,chunked:t,isSimple:!0,newWords:[]})}}async function Ue(e){let t=new Date().toISOString().slice(0,10),n=await chrome.storage.local.get({statsDate:"",todayChunked:0});n.statsDate!==t?await chrome.storage.local.set({statsDate:t,todayChunked:e}):await chrome.storage.local.set({todayChunked:n.todayChunked+e})}var w=null;async function O(){return w||(w=await re(),w.onclose=()=>{w=null},w)}async function We(e){let t=await O(),n=await y(),r=k(n.llm);if(r.apiKey)for(let a=0;a<e.length;a++){let s=e[a];try{let i=await I.getById(t,s);if(!i||i.analyzed)continue;let d=await j.getBySentence(t,i.text);if(d){await I.markAnalyzed(t,s),chrome.runtime.sendMessage({type:"sentenceAnalyzed",pendingId:s,learningRecord:d}).catch(()=>{});continue}let o=await ne(i.text,r),u=await j.add(t,{sentence:i.text,chunked:o.chunked,sentence_analysis:o.sentence_analysis,expression_tips:o.expression_tips,pattern_key:o.pattern_key,new_words:o.new_words,source_url:i.source_url,llm_provider:n.llm.activeProvider});await I.markAnalyzed(t,s),chrome.runtime.sendMessage({type:"sentenceAnalyzed",pendingId:s,learningRecord:u}).catch(()=>{})}catch(i){chrome.runtime.sendMessage({type:"sentenceAnalysisFailed",pendingId:s,error:i instanceof Error?i.message:"Unknown error"}).catch(()=>{})}a<e.length-1&&await new Promise(i=>setTimeout(i,500))}}chrome.runtime.onMessage.addListener((e,t,n)=>($e(e,t).then(r=>{try{n(r)}catch{}}),!0));async function $e(e,t){switch(e.type){case"chunk":{let{sentences:n,source_url:r}=e,a=await z(n),s=n.filter(o=>!a.has(o));if(s.length===0)return{results:n.map(o=>a.get(o))};let i=await Promise.all(s.map(o=>Ve(o,r))),d=new Map;return s.forEach((o,u)=>d.set(o,i[u])),{results:n.map(o=>a.get(o)??d.get(o))}}case"checkActive":{let n=t.tab?.id,r=t.tab?.url??"",a=D(r),i=(a?await R(a):!1)&&!(n&&await v(n));return n&&g(n,i),{active:i}}case"toggleSite":{let{hostname:n}=e,r=await je(n),a=await chrome.tabs.query({});for(let s of a)s.id&&s.url&&D(s.url)===n&&(g(s.id,r.enabled),chrome.tabs.sendMessage(s.id,{type:r.enabled?"activate":"deactivate"}).catch(()=>{}));return{enabled:r.enabled,disabledSites:r.disabledSites}}case"pauseTab":{let{tabId:n}=e;return await ye(n),g(n,!1),chrome.tabs.sendMessage(n,{type:"pause"}).catch(()=>{}),{ok:!0}}case"resumeTab":{let{tabId:n}=e;return await W(n),g(n,!0),chrome.tabs.sendMessage(n,{type:"resume"}).catch(()=>{}),{ok:!0}}case"getTabState":{let{tabId:n,hostname:r}=e;return await v(n)?{state:"paused"}:(r?await R(r):!1)?{state:"active"}:{state:"disabled"}}case"hasApiKey":{let n=await y();return{hasKey:!!k(n.llm).apiKey}}case"getConfig":return y();case"updateConfig":return Me(e.config);case"saveSentence":try{let n=await O();return{ok:!0,saved:await I.add(n,{text:e.text,source_url:e.source_url,source_hostname:e.source_hostname,manual:e.manual,new_words:e.new_words})!==null}}catch{return{ok:!0,saved:!1}}case"analyzeSentences":{let{sentenceIds:n}=e;return We(n).catch(()=>{}),{ok:!0}}case"getImagery":return{imagery:await oe(e.word)};case"markMastered":try{let n=await O(),r=await f.getByWord(n,e.word);return r&&await f.markMastered(n,r.id),{ok:!0}}catch{return{ok:!1}}case"ANALYTICS":return await ge(e.event,e.properties),{ok:!0};case"addToVocab":try{let n=await O(),{word:r,definition:a,sentence:s,sourceUrl:i}=e,d=await f.getByWord(n,r),o;return d?(await f.recordEncounter(n,d.id),o=d.id):o=(await f.add(n,{word:r,status:"new",definition:a})).id,s&&await se.add(n,{vocab_id:o,sentence:s,context_definition:a,source_url:i}),{ok:!0}}catch{return{ok:!1}}default:return{error:"Unknown message type"}}}chrome.tabs.onActivated.addListener(async e=>{try{let t=await chrome.tabs.get(e.tabId);if(t.url){let n=D(t.url),a=(n?await R(n):!1)&&!await v(e.tabId);g(e.tabId,a)}}catch{}});chrome.tabs.onUpdated.addListener(async(e,t,n)=>{if(t.status==="complete"&&n.url){let r=D(n.url),s=(r?await R(r):!1)&&!await v(e);g(e,s)}});chrome.runtime.onInstalled.addListener(async()=>{pe();let e=await chrome.tabs.query({url:["http://*/*","https://*/*"]});for(let t of e)if(t.id)try{await chrome.scripting.executeScript({target:{tabId:t.id},files:["content.js"]})}catch{}});le();chrome.commands.onCommand.addListener(async e=>{if(e!=="toggle-page")return;let[t]=await chrome.tabs.query({active:!0,currentWindow:!0});if(!t?.id||!t.url)return;let n=D(t.url);if(!(n?await R(n):!1))return;await v(t.id)?(await W(t.id),g(t.id,!0),chrome.tabs.sendMessage(t.id,{type:"resume"}).catch(()=>{})):(await ye(t.id),g(t.id,!1),chrome.tabs.sendMessage(t.id,{type:"pause"}).catch(()=>{}))});
