import{g as h,o as E,r as _e,a as Je,d as Ve,b as Ke,c as Xe,e as y,f as Qe,h as w,i as Ze,j as et,k as tt,l as nt,m as ot,n as it,p as O,q as rt,D as st,s as at,A as Ce,t as ct,u as lt,v as ut,w as dt}from"./chunks/_virtual_wxt-plugins-DQ05OeAp.js";import{r as N,g as pt,c as ft,a as mt,i as ht,b as wt,f as yt,d as gt,e as bt}from"./chunks/model-catalog-BulToWxx.js";import{c as kt,a as vt,w as St}from"./chunks/resume-BimrG3sH.js";function At(e){return e==null||typeof e=="function"?{main:e}:e}let ue=!1;h().then(e=>ue=e.debugLogging);E(e=>ue=e.debugLogging);function de(...e){ue&&console.warn("[skipSensei]",...e)}const Et={gemini:"gemini-flash-latest",anthropic:"claude-haiku-4-5",openai:"gpt-5-mini",groq:"llama-3.3-70b-versatile",openrouter:"meta-llama/llama-3.3-70b-instruct:free",ollama:"llama3.1:8b",openclaw:"openclaw"},Tt={builtin:7e3,gemini:4e5,anthropic:6e4,openai:6e4,groq:18e3,openrouter:6e4,ollama:24e3,openclaw:6e4},X={builtin:12e4,gemini:9e4,anthropic:6e4,openai:6e4,groq:6e4,openrouter:9e4,ollama:18e4,openclaw:18e4},_t=`You analyze YouTube video transcripts to find paid promotional segments that viewers may want to skip.

Mark a segment ONLY when the creator is clearly delivering promotion:
- "sponsor": a paid sponsor read for a third-party brand (e.g. "this video is sponsored by...", discount codes, sponsor URLs).
- "self-promo": promotion of the creator's own merch, courses, Patreon, channel memberships, or other videos, delivered as an interruption.
- "ad-read": other embedded advertising read by the creator.

Do NOT mark:
- Ordinary product or brand mentions that are part of the video's actual topic (a review of a product is content, not a sponsor read, even if positive).
- Discussion, news, analysis, or opinions ABOUT companies or products (e.g. hosts debating Meta's AI spending is content, not advertising).
- Thanks to viewers or generic "like and subscribe" moments under 5 seconds.

Most videos contain 0-3 promotional segments; many contain none. Precision matters more than recall: when unsure, either omit the segment or give it low confidence. Never guess timestamps \u2014 use the transcript's [time] markers, and extend end to where normal content resumes.

Respond with ONLY this JSON, no prose, no markdown fences:
{"segments": [{"start": <seconds>, "end": <seconds>, "type": "sponsor"|"self-promo"|"ad-read", "confidence": <0..1>}]}
If there are no promotional segments: {"segments": []}`;class f extends Error{}async function Ct(e,t,n,o,i){const r=F(n),s=Xt(e,Tt[r]),a=[];let l=0,c;for(const[u,p]of s.entries()){if(i==null||i(u,s.length),o.aborted)throw new f("Aborted");const d=Kt(p,t);try{a.push(...await Zt(r,d,t,n,o))}catch(m){if(o.aborted||m instanceof x||m instanceof $)throw m;l++,c=m,de(`chunk ${u+1}/${s.length} failed:`,m instanceof Error?m.message:m)}}if(s.length>0&&l===s.length)throw c instanceof Error?c:new f(`All ${s.length} analysis chunk(s) failed`);return i==null||i(s.length,s.length),Lt(Qt(a),e)}const Rt=["sponsor","sponsored","brought to you by","support for the show","support for this show","support for today","supporting the show","this episode is supported","promo code","use code","discount code","with code","coupon","free trial","free shipping","patreon","merch","channel member","my course","thanks to today","new customers","new user","sign up with","available in all 50","download the app","in the app store","on the app store","google play","terms and conditions","terms apply","gambling problem","gambler","21 and over","21+","void where prohibited","void in","message and data rates","msg and data rates","restrictions apply","see terms","terms at"],Mt=["go to","head to","check out","sign up","link in the description","link below",".com/",".ai/",".co/","% off","percent off","get started","download","subscribe to"],Ot=210,Nt=8;function Lt(e,t){return e.filter(o=>{if(o.end-o.start>Ot)return!1;const i=t.filter(s=>s.end>o.start-2&&s.start<o.end+2).map(s=>s.text).join(" ").toLowerCase();return i?Rt.some(s=>i.includes(s))?!0:Mt.filter(s=>i.includes(s)).length>=2:!1}).sort((o,i)=>i.confidence-o.confidence).slice(0,Nt).sort((o,i)=>o.start-i.start)}const xt=`You locate a UI element inside an HTML fragment. Given a description and the fragment, return ONLY JSON: {"selector":"<css selector>"} matching that element, or {"selector":null} if it isn't present. The selector must be valid for document.querySelector and should prefer stable attributes (class names, aria-label, role, data-*) over randomly generated ids. No prose, no markdown, no explanation.`;async function $t(e,t,n,o){const i=`Find this element: ${t}

HTML fragment:
${e.slice(0,8e3)}`,s=(await P(xt,i,n,o)).trim().replace(/^```(?:json)?\s*/i,"").replace(/```\s*$/,""),a=s.indexOf("{"),l=s.lastIndexOf("}");if(a===-1||l<=a)return null;try{const c=JSON.parse(s.slice(a,l+1)),u=c==null?void 0:c.selector;return typeof u=="string"&&u.trim()?u.trim():null}catch{return null}}const Pt=`You review suspected advertisement elements found on a web page. Each numbered candidate carried a WEAK ad signal (ad-network iframe, ad-like class name, or a "Sponsored" label) and comes with its visible text and an HTML snippet. Confirm ONLY candidates that are beyond doubt advertisements: banner/display ad units, ad iframes, sponsored/promoted third-party content. Everything else is NOT an ad \u2014 the site's own UI (navigation, headers, buttons, forms, feature promos), real content (articles, product cards, search results), and especially USER CONTENT: emails, chat messages, comments, posts, documents, calendar events. Beware: many apps ship minified class names, so tokens like "ad"/"ads" land on non-ads by pure coincidence (Gmail puts class="adn ads" on every email) \u2014 a class name is NEVER sufficient evidence on its own; require the content itself to be promotional. Visible text with personal names, dates, or conversational replies means user content, never an ad. Return ONLY JSON: {"ads":[<candidate numbers>]}. When in any doubt, leave the candidate out. If none qualify, return {"ads":[]}. No prose, no markdown.`;async function It(e,t,n,o){const i=e.map(u=>{const p=(u.text??"").slice(0,160);return`#${u.index}:
text: ${p||"(no visible text)"}
html: ${u.html.slice(0,700)}`}).join(`

`),r=t?`Page: ${t.host} \u2014 ${t.title.slice(0,80)}
`:"",a=(await P(Pt,`${r}Candidates:
${i}`.slice(0,9e3),n,o)).trim().replace(/^```(?:json)?\s*/i,"").replace(/```\s*$/,""),l=a.indexOf("{"),c=a.lastIndexOf("}");if(l===-1||c<=l)return[];try{const u=JSON.parse(a.slice(l,c+1));if(!Array.isArray(u.ads))return[];const p=new Set(e.map(d=>d.index));return u.ads.map(d=>Number(d)).filter(d=>Number.isInteger(d)&&p.has(d))}catch{return[]}}const Dt=`You audit elements an ad blocker's filter lists are currently HIDING on a page. Most are genuine ads \u2014 your job is to catch the rare false positive: an element that is clearly NOT an advertisement, such as the site's own UI (search boxes, navigation, message threads, media players, forms) or user content (emails, chat messages, comments, articles, documents). Each numbered element comes with its readable text (visible text, or its labels/placeholders when it shows no text) and an HTML snippet; the page host and title are given. Note that class names can be misleading \u2014 words like "thread" or "typeahead" contain "ad" by coincidence \u2014 so judge by what the element's content actually IS. An element with no text and no controls is usually an ad slot whose ad was already blocked upstream \u2014 leave it hidden. But an element containing search inputs, compose fields, or several navigation links is site UI even when it shows no text (its ad may simply never have existed). Sponsored/promoted content, banners, ad iframes, and anything promotional must STAY hidden \u2014 never list those. Return ONLY JSON: {"notAds":[<element numbers you are CERTAIN are not ads>]}. When unsure about an element, do NOT include it. If everything looks like an ad, return {"notAds":[]}. No prose, no markdown.`;async function Bt(e,t,n,o){const i=e.map(u=>{const p=(u.text??"").slice(0,200);return`#${u.index}:
text: ${p||"(no visible text)"}
html: ${u.html.slice(0,600)}`}).join(`

`),r=t?`Page: ${t.host} \u2014 ${t.title.slice(0,80)}
`:"",a=(await P(Dt,`${r}Hidden elements:
${i}`.slice(0,9e3),n,o)).trim().replace(/^```(?:json)?\s*/i,"").replace(/```\s*$/,""),l=a.indexOf("{"),c=a.lastIndexOf("}");if(l===-1||c<=l)return[];try{const u=JSON.parse(a.slice(l,c+1));if(!Array.isArray(u.notAds))return[];const p=new Set(e.map(d=>d.index));return u.notAds.map(d=>Number(d)).filter(d=>Number.isInteger(d)&&p.has(d))}catch{return[]}}const Ut=`You decide whether an on-page overlay/popup should be hidden. HIDE only intrusive annoyances: newsletter/email-signup walls, promotional/discount popups, "subscribe" interstitials, app-install nags, survey/feedback popups, and popup/overlay ADS. KEEP (do not hide) anything functional or that the user may need: login/sign-in dialogs, authentication (OAuth), cookie/consent choices, age verification, payment/checkout, error/confirmation/notification dialogs (e.g. "your time zone changed", "session expiring"), and the site's actual content. If the visible text is missing, truncated, or you cannot POSITIVELY identify the popup as one of the HIDE categories, you are unsure \u2014 KEEP. Respond with ONLY JSON: {"hide": true|false, "category": "<one of: newsletter|promo|ad|app-install|survey|subscribe-wall|functional|content|unknown>", "summary": "<neutral 3-8 word description of what the popup is, e.g. 'Newsletter signup asking for email', 'Cookie consent banner', 'Login dialog', '20% discount promo'>"}. No prose.`,Yt=new Set(["newsletter","promo","ad","app-install","survey","subscribe-wall"]);async function jt(e,t,n,o){const i=t.trim().slice(0,1500),s=(await P(Ut,`Visible text of the overlay:
${i||"(none extracted)"}

Overlay HTML:
${e.slice(0,4e3)}`,n,o)).trim().replace(/^```(?:json)?\s*/i,"").replace(/```\s*$/,""),a=s.indexOf("{"),l=s.lastIndexOf("}");if(a===-1||l<=a)return{hide:!1,summary:""};try{const c=JSON.parse(s.slice(a,l+1)),u=typeof c.category=="string"?c.category.trim().toLowerCase():"";return{hide:c.hide===!0&&Yt.has(u),summary:typeof c.summary=="string"?c.summary.trim().slice(0,80):""}}catch{return{hide:!1,summary:""}}}const Ft='You are given the HTML of a cookie-consent / privacy banner. Find the button that REJECTS non-essential cookies \u2014 the most privacy-protective choice (labels like "Reject all", "Decline", "Necessary only", "Only essential", "Refuse", "Deny"). Return ONLY JSON: {"selector":"<css>"} for a clickable element (button/a) that performs that rejection, or {"selector":null} if there is no clear reject option (do NOT return an "Accept" button \u2014 never). Prefer stable attributes. No prose.';async function qt(e,t,n){const i=(await P(Ft,`Banner HTML:
${e.slice(0,5e3)}`,t,n)).trim().replace(/^```(?:json)?\s*/i,"").replace(/```\s*$/,""),r=i.indexOf("{"),s=i.lastIndexOf("}");if(r===-1||s<=r)return null;try{const a=JSON.parse(i.slice(r,s+1)).selector;return typeof a=="string"&&a.trim()?a.trim():null}catch{return null}}class x extends f{}class $ extends f{}const Ht={gemini:4,groq:25,openrouter:15},ge=new Map;function zt(e,t){return new Promise((n,o)=>{if(t.aborted)return o(new f("Aborted"));const i=setTimeout(()=>{t.removeEventListener("abort",r),n()},e),r=()=>{clearTimeout(i),o(new f("Aborted"))};t.addEventListener("abort",r,{once:!0})})}async function Re(e,t){const n=Ht[e];if(n)for(;;){const o=Date.now(),i=(ge.get(e)??[]).filter(s=>o-s<6e4);if(i.length<n){i.push(o),ge.set(e,i);return}const r=6e4-(o-i[0])+500;de(`${e} pacing: waiting ${Math.round(r/1e3)}s to stay under ${n}/min`),await zt(r,t)}}const Me=new Map;function Wt(e){const t=Me.get(e);return t!==void 0&&Date.now()<t}function Gt(e,t,n){const o=n?n*1e3:t?36e5:9e4;Me.set(e,Date.now()+o),de(`${e} rate-limited \u2014 falling back to built-in AI for ~${Math.round(o/1e3)}s`)}function pe(e,t){var n;return e==="builtin"?!0:Wt(e)?!1:e==="ollama"||e==="openclaw"?!0:!!((n=t.apiKeys[e])!=null&&n.trim())}function F(e){return e.localOnlyMode?"builtin":pe(e.llmProvider,e)?e.llmProvider:"builtin"}function Jt(e){const t=(r,s)=>({...e,llmProvider:r,model:s}),n=e.llmProvider;if(e.localOnlyMode||n==="builtin")return[t("builtin","")];const o=[t(n,e.model)];e.model.trim()&&o.push(t(n,""));const i=e.fallbackProvider;return i!=="builtin"&&i!==n&&pe(i,e)&&o.push(t(i,"")),o.push(t("builtin","")),o}function Vt(e){if(e.localOnlyMode)return"builtin";if(e.llmProvider!=="groq"&&pe("groq",e))return"groq";const t=F(e);return t==="openclaw"?"builtin":t}async function Oe(){if(typeof LanguageModel>"u"||!LanguageModel)return"unavailable";try{return await LanguageModel.availability()}catch{return"unavailable"}}function Kt(e,t){const n=e.map(o=>`[${o.start.toFixed(1)}] ${o.text}`).join(`
`);return`Video duration: ${Math.round(t)} seconds. Transcript (each line prefixed with its start time in seconds):

${n}`}function Xt(e,t){const n=[];let o=[],i=0;for(const r of e){const s=r.text.length+12;i+s>t&&o.length>0&&(n.push(o),o=o.slice(-5),i=o.reduce((a,l)=>a+l.text.length+12,0)),o.push(r),i+=s}return o.length>0&&n.push(o),n}function Qt(e){const t=[...e].sort((o,i)=>o.start-i.start),n=[];for(const o of t){const i=n[n.length-1];i&&o.start<=i.end+2&&o.type===i.type?(i.end=Math.max(i.end,o.end),i.confidence=Math.max(i.confidence,o.confidence)):n.push({...o})}return n}async function Zt(e,t,n,o,i){let r;for(let s=0;s<2;s++)try{await Re(e,i);const a=await Q(Z(e,Le(e,o),_t,t,o,i),X[e]);return nn(a,n)}catch(a){if(i.aborted||a instanceof Ne||a instanceof x||a instanceof $)throw a;r=a}throw r instanceof Error?r:new f(String(r))}class Ne extends f{}const en="llama-3.1-8b-instant";async function P(e,t,n,o){const i=await Oe()==="available"?"builtin":Vt(n),r=i==="groq"?en:Le(i,n);try{return await Re(i,o),await Q(Z(i,r,e,t,n,o),X[i])}catch(s){if((s instanceof x||s instanceof $)&&i!=="builtin")return await Q(Z("builtin","",e,t,n,o),X.builtin);throw s}}function Q(e,t){return new Promise((n,o)=>{const i=setTimeout(()=>o(new Ne(`LLM call timed out after ${t/1e3}s`)),t);e.then(r=>{clearTimeout(i),n(r)},r=>{clearTimeout(i),o(r)})})}const tn={openai:{url:"https://api.openai.com/v1/chat/completions",label:"OpenAI",jsonMode:!0},gemini:{url:"https://generativelanguage.googleapis.com/v1beta/openai/chat/completions",label:"Gemini",jsonMode:!0},groq:{url:"https://api.groq.com/openai/v1/chat/completions",label:"Groq",jsonMode:!0},openrouter:{url:"https://openrouter.ai/api/v1/chat/completions",label:"OpenRouter",jsonMode:!1},ollama:{url:"http://localhost:11434/v1/chat/completions",label:"Ollama",jsonMode:!1},openclaw:{url:"http://127.0.0.1:18789/v1/chat/completions",label:"OpenClaw",jsonMode:!1}};function Le(e,t){return e==="builtin"?"":e===t.llmProvider&&t.model.trim()?t.model.trim():Et[e]}function Z(e,t,n,o,i,r){switch(e){case"anthropic":return on(t,n,o,i,r);case"builtin":return sn(n,o,r);default:return rn(e,t,n,o,i,r)}}function nn(e,t){const n=e.trim().replace(/^```(?:json)?\s*/i,"").replace(/```\s*$/,""),o=n.indexOf("{"),i=n.lastIndexOf("}");if(o===-1||i<=o)throw new f("No JSON object in response");const r=JSON.parse(n.slice(o,i+1));if(!Array.isArray(r.segments))throw new f('Missing "segments" array');const s=t>0?t+5:1/0,a=[];for(const l of r.segments){const c=Number(l==null?void 0:l.start),u=Number(l==null?void 0:l.end),p=Number(l==null?void 0:l.confidence),d=l==null?void 0:l.type;if(!Number.isFinite(c)||!Number.isFinite(u)||!Number.isFinite(p)||!["sponsor","self-promo","ad-read"].includes(d))throw new f("Malformed segment object");c<0||u<=c||c>s||a.push({start:c,end:Math.min(u,s),type:d,confidence:Math.min(1,Math.max(0,p))})}return a}async function on(e,t,n,o,i){var l,c,u,p;const r=await fetch("https://api.anthropic.com/v1/messages",{method:"POST",signal:i,headers:{"content-type":"application/json","x-api-key":(o.apiKeys.anthropic??"").trim(),"anthropic-version":"2023-06-01","anthropic-dangerous-direct-browser-access":"true"},body:JSON.stringify({model:e,max_tokens:1500,temperature:0,system:t,messages:[{role:"user",content:n}]})});if(!r.ok){const d=await xe(r);throw $e("anthropic",r,d),new f(`Anthropic API ${r.status}: ${d}`)}const s=await r.json(),a=(c=(l=s==null?void 0:s.content)==null?void 0:l[0])==null?void 0:c.text;if(typeof a!="string")throw new f("Empty Anthropic response");return _e("anthropic",Number((u=s==null?void 0:s.usage)==null?void 0:u.input_tokens)||0,Number((p=s==null?void 0:s.usage)==null?void 0:p.output_tokens)||0),a}async function rn(e,t,n,o,i,r){var b,fe,me,he,we;const{url:s,label:a,jsonMode:l}=tn[e],c=e==="openclaw"&&i.openclawUrl.trim()||s,u=e==="ollama"?"":(i.apiKeys[e]??"").trim(),p=await fetch(c,{method:"POST",signal:r,headers:{"content-type":"application/json",...u?{authorization:`Bearer ${u}`}:{}},body:JSON.stringify({model:t,...l?{response_format:{type:"json_object"}}:{},messages:[{role:"system",content:n},{role:"user",content:o}]})});if(!p.ok){const ye=await xe(p);throw $e(e,p,ye),new f(`${a} API ${p.status}: ${ye}`)}const d=await p.json(),m=(me=(fe=(b=d==null?void 0:d.choices)==null?void 0:b[0])==null?void 0:fe.message)==null?void 0:me.content;if(typeof m!="string")throw new f("Empty API response");return _e(e,Number((he=d==null?void 0:d.usage)==null?void 0:he.prompt_tokens)||0,Number((we=d==null?void 0:d.usage)==null?void 0:we.completion_tokens)||0),m}async function sn(e,t,n){if(typeof LanguageModel>"u"||!LanguageModel)throw new f("Built-in Chrome AI is not available in this browser. Add an API key in Ad Sensei options, or use Chrome 138+ with on-device AI enabled.");if(await LanguageModel.availability()==="unavailable")throw new f("Built-in Chrome AI is unavailable on this device. Add an API key in Ad Sensei options.");const i=await LanguageModel.create({signal:n});try{if(n.aborted)throw new f("Aborted");return await i.prompt(`${e}

${t}`,{signal:n})}finally{i.destroy()}}async function xe(e){try{return(await e.text()).slice(0,300)}catch{return""}}function $e(e,t,n){const o=/quota|exhausted|per day|daily limit|insufficient_quota/i.test(n);if(t.status===429||t.status===403&&o){const r=Number(t.headers.get("retry-after"))||void 0;throw Gt(e,o,r),new x(`${e} rate limit / quota reached`)}const i=/model/i.test(n)&&/not found|not available|no longer available|not supported|does not exist|unknown model|deprecated|decommission/i.test(n);if(t.status===404||(t.status===400||t.status===403)&&i)throw new $(`${e} model unavailable: ${n.slice(0,160)}`)}const H="skipSensei.dailyRollup",an=1440,ee="skipSensei.rollupLastSent";function z(e,t){if(e.length===0)return 0;const n=Math.min(e.length-1,Math.floor(e.length*t/100));return e[n]}const D=e=>Math.round(e*10)/10;function cn(e){if(e.length===0)return{skips:"0"};const t=e.map(i=>i.s).sort((i,r)=>i-r),n={skips:String(t.length),skip_p50:String(D(z(t,50))),skip_p90:String(D(z(t,90))),skip_max:String(D(t[t.length-1])),skip_over5s:String(t.filter(i=>i>5).length)},o=new Map;for(const i of e){const r=o.get(i.m)??[];r.push(i.s),o.set(i.m,r)}for(const[i,r]of o){const s=i.replace(/[^a-z]+/gi,"_").toLowerCase().slice(0,20),a=r.sort((l,c)=>l-c);n[`m_${s}_n`]=String(a.length),n[`m_${s}_p50`]=String(D(z(a,50)))}return n}function ln(e){const t=n=>n?"1":"0";return{f_ads:t(e.adEngineEnabled),f_sponsor:t(e.sponsorEngineEnabled),f_pruning:t(e.aggressivePruning),f_web:t(e.blockAllAds),f_trackers:t(e.blockTrackers),f_resume:t(e.resumePlayback),f_ai:t(e.aiEnhancements)}}async function un(){const e=await h();if(!e.telemetryEnabled||e.localOnlyMode)return!1;const{day:t,counts:n}=await Ve(),o=await Ke(),i=l=>{const c=new Date(l),u=p=>String(p).padStart(2,"0");return`${c.getFullYear()}-${u(c.getMonth()+1)}-${u(c.getDate())}`},r=o.filter(l=>i(l.at)===t),s={day:t,...cn(r),...ln(e),walls:String(n.walls??0),breaker_trips:String(n.breakerTrips??0),skip_failures:String(n.skipFailures??0),self_heals:String(n.selfHeals??0),cosmetic_unhides:String(n.cosmeticUnhides??0),ruleset_fails:String(n.rulesetEnableFailures??0),clear_visitor_tried:String(n.visitorClearTried??0),clear_visitor_failed:String(n.visitorClearFailed??0),clear_full:String(n.fullClears??0),ui_popup_open:String(n.uiPopupOpens??0),ui_tab_controls:String(n.uiControlsTab??0),ui_options_open:String(n.uiOptionsOpens??0),ui_site_pause:String(n.uiSitePauses??0),ui_share:String(n.uiShares??0)};for(const[l,c]of Object.entries(n)){if(!l.startsWith("uiSet_"))continue;const u=`ui_set_${l.slice(6).replace(/[^a-zA-Z0-9]/g,"").toLowerCase()}`;s[u.slice(0,40)]=String(c??0)}const a=await N("daily_rollup",s);return a?await chrome.storage.local.set({[ee]:t}):await Xe({day:t,counts:n}),a}let W=Promise.resolve();function be(){return W=W.then(async()=>{const{day:e}=await Je();(await chrome.storage.local.get(ee))[ee]!==e&&await un()}).catch(()=>{}),W}function dn(){chrome.alarms.onAlarm.addListener(e=>{e.name===H&&be()}),chrome.alarms.get(H).then(e=>{e||chrome.alarms.create(H,{periodInMinutes:an})}),be()}async function Pe(e,t){await y("rulesetEnableFailures"),N(e,t)}const Ie=["ads_base","ads_mobile"],pn=["trackers"],te="yt_exempt",fn=1e8,De=1;let L=[];function Be(e){const t=e.masterEnabled;return[{ids:Ie,on:t&&e.blockAllAds,label:"ad blocking",needsExemption:!0},{ids:pn,on:t&&e.blockTrackers,label:"tracker blocking",needsExemption:!0},{ids:["cookies"],on:t&&e.blockAllAds&&e.blockCookieNotices,label:"cookie-notice blocking",needsExemption:!0},{ids:["social"],on:t&&e.blockAllAds&&e.blockSocial,label:"social blocking",needsExemption:!0},{ids:["popups"],on:t&&e.blockAllAds&&e.blockPopups,label:"popup blocking",needsExemption:!0},{ids:["url_tracking"],on:t&&e.blockUrlTracking,label:"URL tracking protection",needsExemption:!0},{ids:["malware"],on:t&&e.blockMalware,label:"malware blocking",needsExemption:!1}]}let _=null,G=!1;function S(){return _?(G=!0,_):(_=(async()=>{try{return await mn()}finally{_=null,G&&(G=!1,S())}})(),_)}async function mn(){const e=await h();L=[],await ke([te],!0,"YouTube exemption");let t;try{await bn(e.allowlist)}catch(o){t=o}const n=(await hn()).has(te)||await Ue();if(!n){const o=t instanceof Error?t.message:"exemption rule missing";L.push(`YouTube exemption: ${o} \u2014 ad blocking held off`),Pe("ruleset_enable_failed",{ruleset:"yt_exempt",reason:o.slice(0,120)})}for(const o of Be(e)){const i=o.on&&(n||!o.needsExemption);await ke(o.ids,i,o.label)}return Ye()}async function hn(){try{return new Set(await chrome.declarativeNetRequest.getEnabledRulesets())}catch{return new Set}}async function Ue(){try{return(await chrome.declarativeNetRequest.getDynamicRules()).some(t=>t.id===De)}catch{return!1}}async function wn(){try{const e=await h(),t=new Set(await chrome.declarativeNetRequest.getEnabledRulesets()),n=Be(e),o=n.some(({ids:a,on:l})=>a.some(c=>t.has(c)!==l)),i=!t.has(te),s=n.some(a=>a.on&&a.needsExemption)&&!await Ue();(o||i||s)&&await S()}catch{}}async function ke(e,t,n){for(let o=0;o<2;o++)try{const i=new Set(await chrome.declarativeNetRequest.getEnabledRulesets()),r=e.every(a=>i.has(a)),s=e.every(a=>!i.has(a));t&&!r?await chrome.declarativeNetRequest.updateEnabledRulesets({enableRulesetIds:e}):!t&&!s&&await chrome.declarativeNetRequest.updateEnabledRulesets({disableRulesetIds:e});return}catch(i){if(o===1){if(t&&e.length>1){const s=[];for(const a of e)try{await chrome.declarativeNetRequest.updateEnabledRulesets({enableRulesetIds:[a]})}catch{s.push(a)}if(s.length===0)return}const r=i instanceof Error?i.message:`Could not update ${n}`;L.push(`${n}: ${r}`),Pe("ruleset_enable_failed",{ruleset:n.slice(0,40),reason:r.slice(0,120)});return}await new Promise(r=>setTimeout(r,600))}}const yn=["youtube.com","youtube-nocookie.com","googlevideo.com"];function gn(e){let t=e.trim().toLowerCase().replace(/^[a-z][a-z0-9+.-]*:\/\//,"").replace(/[/?#].*$/,"").replace(/:\d+$/,"").replace(/^\*\.?/,"").replace(/\.$/,"");if(!t)return null;try{t=new URL(`http://${t}`).hostname}catch{return null}return/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/.test(t)?t:null}async function bn(e){const t=await chrome.declarativeNetRequest.getDynamicRules(),n=[...yn,...e].map(gn).filter(i=>i!==null).filter((i,r,s)=>s.indexOf(i)===r),o=n.length===0?[]:[{id:De,priority:fn,action:{type:"allowAllRequests"},condition:{requestDomains:n,resourceTypes:["main_frame","sub_frame"]}}];await chrome.declarativeNetRequest.updateDynamicRules({removeRuleIds:t.map(i=>i.id),addRules:o})}async function Ye(){const{blockAllAds:e}=await h();let t=!1;try{const n=await chrome.declarativeNetRequest.getEnabledRulesets();t=Ie.every(o=>n.includes(o))}catch{}return{enabled:e,active:t,error:L.length>0?L.join("; "):void 0}}let C=null;async function kn(){if(C)return C;try{const e=chrome.runtime.getURL("rulesets/_counts.json");C=await(await fetch(e)).json()}catch{C={}}return C}async function vn(){const e=await kn();let t=[];try{t=await chrome.declarativeNetRequest.getEnabledRulesets()}catch{}const n=Object.values(e).reduce((i,r)=>i+r,0),o=t.reduce((i,r)=>i+(e[r]??0),0);return{counts:e,enabled:t,availableTotal:n,loadedTotal:o}}const Sn={ads_base:"ads",ads_mobile:"ads",trackers:"trackers",cookies:"cookies",social:"social",popups:"popups",url_tracking:"links",malware:"malware"},ve=()=>({ads:0,trackers:0,cookies:0,social:0,popups:0,links:0,malware:0}),An=300*1e3,ne=new Map,j=new Map;let oe=null;async function ie(e,t){const n=ne.get(e)??Date.now()-An;try{const{rulesMatchedInfo:o}=await chrome.declarativeNetRequest.getMatchedRules({tabId:e,minTimeStamp:n}),i=j.get(e)??n,r=ve(),s=ve();let a=i;for(const l of o){const c=Sn[l.rule.rulesetId];c&&(r[c]++,l.timeStamp>i&&(l.timeStamp>a&&(a=l.timeStamp),s[c]++))}return j.set(e,a+1),(s.ads||s.trackers||s.cookies)&&t.onCounts({ads:s.ads,trackers:s.trackers,cookies:s.cookies}),t.onTabCount(e,r),r}catch{return null}}async function En(e){return oe?ie(e,oe):null}function Tn(e){chrome.runtime.onInstalled.addListener(()=>void S()),chrome.runtime.onStartup.addListener(()=>void S()),E(()=>void S()),oe=e,chrome.tabs.onUpdated.addListener((t,n)=>{if(n.status==="loading"&&n.url){const o=Date.now();ne.set(t,o),j.set(t,o)}n.status==="complete"&&(ie(t,e),setTimeout(()=>void ie(t,e),9e3))}),chrome.tabs.onRemoved.addListener(t=>{j.delete(t),ne.delete(t)})}const re="skip-sensei-aggressive-pruner";async function _n(){try{return(await chrome.scripting.getRegisteredContentScripts({ids:[re]})).length>0}catch{return!1}}async function Y(){const e=await h(),t=e.masterEnabled&&e.aggressivePruning,n=await _n();try{t&&!n?await chrome.scripting.registerContentScripts([{id:re,js:["prune-main.js"],matches:["*://*.youtube.com/*"],runAt:"document_start",world:"MAIN",persistAcrossSessions:!0,allFrames:!1}]):!t&&n&&await chrome.scripting.unregisterContentScripts({ids:[re]})}catch{}}function Cn(){chrome.runtime.onInstalled.addListener(()=>void Y()),chrome.runtime.onStartup.addListener(()=>void Y()),E(()=>void Y())}const se="skip-sensei-cosmetic-web";function Rn(){const e=chrome.runtime.getManifest().content_scripts??[];for(const t of e){const n=t.js??[];if(n.some(o=>/cosmetic/.test(o)))return n}return[]}async function Mn(){try{return(await chrome.scripting.getRegisteredContentScripts({ids:[se]})).length>0}catch{return!1}}async function On(){try{return await chrome.permissions.contains({origins:["*://*/*"]})}catch{return!1}}async function k(){const e=await h(),t=e.blockAllAds||e.blockCookieNotices||e.blockSocial||e.blockPopups,n=e.masterEnabled&&t&&await On(),o=Rn(),i=await Mn();try{n&&!i&&o.length>0?await chrome.scripting.registerContentScripts([{id:se,js:o,matches:["*://*/*"],excludeMatches:["*://*.youtube.com/*"],runAt:"document_start",persistAcrossSessions:!0,allFrames:!0}]):!n&&i&&await chrome.scripting.unregisterContentScripts({ids:[se]})}catch{}}function Nn(){chrome.runtime.onInstalled.addListener(()=>void k()),chrome.runtime.onStartup.addListener(()=>void k()),E(()=>void k()),chrome.permissions.onAdded.addListener(()=>void k()),chrome.permissions.onRemoved.addListener(()=>void k())}const ae="skip-sensei-scriptlets";async function Ln(){try{return(await chrome.scripting.getRegisteredContentScripts({ids:[ae]})).length>0}catch{return!1}}async function xn(){try{return await chrome.permissions.contains({origins:["*://*/*"]})}catch{return!1}}async function v(){const e=await h(),t=e.masterEnabled&&e.blockAllAds&&e.defuseAntiAdblock&&await xn(),n=await Ln();try{t&&!n?await chrome.scripting.registerContentScripts([{id:ae,js:["scriptlets-main.js"],matches:["*://*/*"],excludeMatches:["*://*.youtube.com/*"],runAt:"document_start",world:"MAIN",persistAcrossSessions:!0,allFrames:!1}]):!t&&n&&await chrome.scripting.unregisterContentScripts({ids:[ae]})}catch{}}function $n(){chrome.runtime.onInstalled.addListener(()=>void v()),chrome.runtime.onStartup.addListener(()=>void v()),E(()=>void v()),chrome.permissions.onAdded.addListener(()=>void v()),chrome.permissions.onRemoved.addListener(()=>void v())}const J="skipSensei.swWarm",B="skipSensei.goodStart";async function Pn(){try{return(await chrome.storage.session.get(J))[J]?!1:(await chrome.storage.session.set({[J]:!0}),!0)}catch{return!0}}async function In(e){try{await e(),await chrome.storage.local.set({[B]:!0})}catch(t){const o=(await chrome.storage.local.get(B))[B]!==!1;if(await chrome.storage.local.set({[B]:!1}),o){chrome.runtime.reload();return}throw t}}const Dn="https://sponsor.ajay.app/api/skipSegments",Bn=4,Un={sponsor:"sponsor",selfpromo:"self-promo",interaction:"interaction",intro:"intro",outro:"outro",preview:"preview",filler:"filler",music_offtopic:"music-offtopic"};async function Yn(e){const t=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",t);return[...new Uint8Array(n)].map(o=>o.toString(16).padStart(2,"0")).join("")}async function jn(e,t){if(!e||t.length===0)return[];let n;try{const r=(await Yn(e)).slice(0,Bn),s=new URLSearchParams({categories:JSON.stringify(t),actionTypes:JSON.stringify(["skip"])}),a=await fetch(`${Dn}/${r}?${s}`,{credentials:"omit"});if(!a.ok)return[];n=await a.json()}catch{return[]}if(!Array.isArray(n))return[];const o=n.find(r=>r.videoID===e);if(!o||!Array.isArray(o.segments))return[];const i=[];for(const r of o.segments){if(r.actionType!=="skip")continue;const[s,a]=r.segment??[];if(typeof s!="number"||typeof a!="number"||a<=s||(r.votes??0)<0)continue;const l=Un[r.category];l&&i.push({start:s,end:a,type:l,confidence:1,source:"sponsorblock"})}return i.sort((r,s)=>r.start-s.start)}let g=Promise.resolve();function Se(e,t=1){return g=g.then(async()=>{await O(e==="ad"?"allTimeAdSkips":"allTimeSponsorSkips",t)}).catch(()=>{}),g}function je(e){g=g.then(async()=>{e.ads&&await O("allTimeWebAdsBlocked",e.ads),e.trackers&&await O("allTimeTrackersBlocked",e.trackers),e.cookies&&await O("allTimeCookiesBlocked",e.cookies)}).catch(()=>{})}function Fn(e){e<=0||(g=g.then(async()=>{await O("allTimeYtAdsHidden",e)}).catch(()=>{}))}function qn(){return g=g.then(()=>rt()).catch(()=>{}),g}const A=new Map;let R=null;function ce(){const e=A.size>0;e&&R===null?R=setInterval(()=>void chrome.runtime.getPlatformInfo(),2e4):!e&&R!==null&&(clearInterval(R),R=null)}function Hn(e,t,n,o){e!==void 0&&chrome.tabs.sendMessage(e,{type:"skipSensei:analysisProgress",videoId:t,done:n,total:o}).catch(()=>{})}async function Fe(e){const t=await at(e);return!t||t.version!==Ce||t.status==="ok"&&t.segments.length===0&&t.provider==="builtin"&&F(await h())!=="builtin"?null:t}async function zn(e,t,n,o){const i=await Fe(e);if(i)return i;const r=A.get(e);if(r)return r.waiters+=1,r.promise;const s=new AbortController,a={controller:s,waiters:1,promise:Wn(e,t,n,s.signal,o)};A.set(e,a),ce();try{return await a.promise}finally{A.delete(e),ce()}}async function Wn(e,t,n,o,i){const r=await h(),s=(a,l)=>Hn(i,e,a,l);try{const a=Jt(r);let l,c=r,u;for(let d=0;d<a.length;d++){const m=a[d];try{l=await Ct(t,n,m,o,s),c=m,d>0&&w("Sponsor detection AI",`${r.llmProvider} unavailable \u2014 analyzed with ${m.llmProvider} instead`,e);break}catch(b){if(o.aborted||!(b instanceof f))throw b;u=b}}if(l===void 0)throw u instanceof Error?u:new f("All providers failed");const p={videoId:e,status:"ok",segments:l,provider:c.llmProvider,analyzedAt:Date.now(),version:Ce};return await ut(p),w("Sponsor detection AI",`analyzed a video \u2014 ${l.length} sponsor segment(s) found (${p.provider})`,e),p}catch(a){return!o.aborted&&!(a instanceof x)&&!(a instanceof $)&&bt("analyze-video",a),o.aborted||w("Sponsor detection AI",`analysis failed \u2014 ${a instanceof Error?a.message.slice(0,120):"unknown error"}`,e),{videoId:e,status:"error",reason:a instanceof Error?a.message:String(a),segments:[],provider:F(r),analyzedAt:Date.now()}}}async function Gn(e,t){const n=await h();if(!n.aiEnhancements)return null;const o=new AbortController;try{return await $t(e,t,n,o.signal)}catch{return null}}const Jn="skipSensei.modelCatalog";async function Vn(e){const t=await h();if(t.localOnlyMode)return{provider:e,models:[],fetchedAt:null,error:"Local-only mode is on"};try{const n=await yt(e,t),o={provider:e,models:n,fetchedAt:Date.now(),error:null};return await chrome.storage.local.set({[`${Jn}.${e}`]:o}),o}catch(n){return{provider:e,models:[],fetchedAt:null,error:n instanceof Error?n.message.slice(0,160):"fetch failed"}}}async function Kn(e){const t=await h();if(!t.aiEnhancements)return null;const n=new AbortController;try{return await qt(e,t,n.signal)}catch{return null}}const Xn=new Set(["uiPopupOpens","uiControlsTab","uiOptionsOpens","uiSitePauses","uiShares"]);function Qn(e){if(Xn.has(e)){y(e);return}e.startsWith("uiSet_")&&e.slice(6)in st&&y(e)}async function Zn(e,t,n,o){const i=await h();if(!i.aiEnhancements)return!1;const r=new AbortController;try{const{hide:s,summary:a}=await jt(e,t,i,r.signal),l=a||o||"",c=l?` \u2014 ${l}`:"";return w("Block popup & overlay ads",s?`reviewed a popup, hid it (intrusive)${c}`:`reviewed a popup, kept it (looks functional)${c}`,n),s}catch{return!1}}async function eo(e,t){const n=await h();if(!n.aiEnhancements)return null;const o=new AbortController;try{return await It(e,t,n,o.signal)}catch{return null}}async function to(e,t){const n=await h();if(!n.aiEnhancements)return null;const o=new AbortController;try{return await Bt(e,t,n,o.signal)}catch{return null}}function no(e){const t=A.get(e);t&&(t.waiters-=1,t.waiters<=0&&(t.controller.abort(),A.delete(e),ce()))}const oo=1e4;let V=Promise.resolve();function io(e,t){return V=V.then(()=>ro(e,t)).catch(()=>{}),V}async function ro(e,t){const n=(await chrome.storage.session.get("lastWallAt")).lastWallAt??0,o=Date.now();if(!(o-n<oo)){if(await chrome.storage.session.set({lastWallAt:o}),y("walls"),t!==void 0){const i=`ytVisitorClear.${t}`,r=(await chrome.storage.session.get(i))[i]??0;r&&Date.now()-r<5*6e4&&y("visitorClearFailed")}await ct(e),w("Skip YouTube ads","YouTube blocked playback for this session \u2014 offered the cookie-clear fix","youtube.com"),N("yt_hard_block",{walls:String(e)}),(await h()).aggressivePruning&&(y("breakerTrips"),await lt({aggressivePruning:!1}),w("First-party ad blocking","YouTube flagged the session \u2014 first-party ad blocking auto-disabled (reactive skipping still on)","youtube.com"),N("aggressive_breaker",{walls:String(e)}))}}const M=e=>{var t;return(t=e.tab)!=null&&t.url?new URL(e.tab.url).hostname.replace(/^www\./,""):void 0},so={"skip-button":"clicked the Skip button on an ad","fast-forward":"fast-forwarded an unskippable ad","stuck-recovery":"recovered a stuck ad player",pruned:"blocked an ad before it could load","overlay-removed":"removed an overlay ad","pause-overlay-dismissed":"dismissed a pause-screen ad"};chrome.runtime.onMessage.addListener((e,t,n)=>{var o,i,r,s,a,l;switch(e==null?void 0:e.type){case"skipSensei:adSkipped":{const c=e.count&&e.count>0?e.count:1;if(Se("ad",c),e.quiet)return!1;if(e.method==="pruned"){const p=c>1?`blocked ${c} ads before they could load`:"blocked an ad before it could load";return w("Block YouTube's first-party ads",p,M(t)),!1}const u=so[e.method]??"neutralized an ad";return w("Skip YouTube ads",u,M(t)),!1}case"skipSensei:event":return e.kind==="self_heal"&&y("selfHeals"),e.kind==="skip_failed"&&y("skipFailures"),e.kind==="gapfill_feedback"&&((o=e.fields)==null?void 0:o.verdict)==="not-ad"&&y("cosmeticUnhides"),N(e.kind,{...e.fields??{},host:M(t)??""}),!1;case"skipSensei:sponsorSkipped":return Se("sponsor"),w("Skip sponsor segments","skipped a sponsor segment",e.videoId),!1;case"skipSensei:getAnalysis":return Fe(e.videoId).then(n),!0;case"skipSensei:analyzeVideo":return zn(e.videoId,e.lines,e.durationSeconds,(i=t.tab)==null?void 0:i.id).then(n),!0;case"skipSensei:abandonAnalysis":return no(e.videoId),!1;case"skipSensei:clearVideoAnalysis":return it(e.videoId).then(()=>n(!0)),!0;case"skipSensei:reportCorrection":return ot(e.videoId,e.start,e.end),w("Corrections",`you flagged a wrong skip (${Math.round(e.start)}s\u2013${Math.round(e.end)}s)`,e.videoId),!1;case"skipSensei:logActivity":return w(e.feature,e.action,M(t)),!1;case"skipSensei:uiUsage":return Qn(e.counter),!1;case"skipSensei:skipTiming":return nt({s:e.s,m:e.m,ads:e.ads}),!1;case"skipSensei:resumeSave":return tt(e.videoId,e.seconds),!1;case"skipSensei:resumeForget":return et(e.videoId),!1;case"skipSensei:checkBuiltinAI":return Oe().then(c=>n({availability:c})),!0;case"skipSensei:getBlockerState":return Ye().then(n),!0;case"skipSensei:getRulesetInfo":return vn().then(n),!0;case"skipSensei:resetStats":return qn().then(()=>n({ok:!0})),!0;case"skipSensei:getCosmeticFilters":return mt(e.hostname).then(n),!0;case"skipSensei:checkFilterUpdates":return ft(!0).then(n),!0;case"skipSensei:getFilterUpdateStatus":return pt().then(n),!0;case"skipSensei:refreshModels":return Vn(e.provider).then(n),!0;case"skipSensei:adblockWall":return Ze(e.hostname),!1;case"skipSensei:clearYtCookies":return(async()=>{var c,u;try{const p=e.scope==="visitor";y(p?"visitorClearTried":"fullClears");const d=p?await kt():await vt({domain:"youtube.com"});if(await Qe(),((c=t.tab)==null?void 0:c.id)!==void 0&&await chrome.storage.session.set({[`ytVisitorClear.${t.tab.id}`]:p?Date.now():0}),w("Skip YouTube ads",p?`Cleared ${d} YouTube visitor cookie(s), kept the sign-in \u2014 testing whether the wall lifts`:`Cleared all ${d} youtube.com cookie(s) \u2014 signs the user out`,"youtube.com"),n({ok:!0}),((u=t.tab)==null?void 0:u.id)!==void 0){const m=St(t.tab.url??"",e.resumeSeconds??0);m?await chrome.tabs.update(t.tab.id,{url:m}):await chrome.tabs.reload(t.tab.id)}}catch{n({ok:!1})}})(),!0;case"skipSensei:wallSeen":return io(e.walls,(r=t.tab)==null?void 0:r.id),!1;case"skipSensei:getWallState":return(async()=>{var d;const c=(d=t.tab)==null?void 0:d.id;if(c===void 0)return n({triedVisitorClear:!1});const u=`ytVisitorClear.${c}`,p=(await chrome.storage.session.get(u))[u]??0;n({triedVisitorClear:Date.now()-p<5*6e4})})(),!0;case"skipSensei:tabNeedsReload":return((s=t.tab)==null?void 0:s.id)!==void 0&&ze(t.tab.id,e.needsReload),!1;case"skipSensei:getTabBlocked":return En(e.tabId).then(c=>{c&&We(e.tabId,c),n(He(e.tabId))}),!0;case"skipSensei:cosmeticHideCount":if(((a=t.tab)==null?void 0:a.id)!==void 0){const c=!!((l=t.tab.url)!=null&&l.includes("youtube.com"));lo(t.tab.id,e.count),c?Fn(e.added):e.added>0&&je({ads:e.added,trackers:0,cookies:0})}return!1;case"skipSensei:findSelector":return Gn(e.html,e.description).then(n),!0;case"skipSensei:verifyAdCandidates":return eo(e.candidates,e.page).then(n),!0;case"skipSensei:auditHiddenElements":return to(e.candidates,e.page).then(n),!0;case"skipSensei:reviewPopup":return Zn(e.html,e.text??"",M(t),e.desc).then(n),!0;case"skipSensei:findConsentReject":return Kn(e.html).then(n),!0;case"skipSensei:fetchSponsorBlock":return(async()=>{const c=await h();if(!c.sponsorBlockEnabled||c.localOnlyMode||c.sponsorBlockCategories.length===0){n([]);return}n(await jn(e.videoId,c.sponsorBlockCategories))})(),!0;default:return!1}});const ao=()=>({ads:0,trackers:0,cookies:0,social:0,popups:0,links:0,malware:0}),le=e=>e.ads+e.trackers+e.cookies+e.social+e.popups+e.links+e.malware,T=new Map,qe=()=>({network:ao(),cosmetic:0,needsReload:!1}),I=e=>T.get(e)??qe(),He=e=>{const t=I(e);return{...t.network,ads:t.cosmetic>0?t.cosmetic:t.network.ads}},co=e=>le(He(e));function q(e){const{needsReload:t}=I(e),n=co(e),o=t?"\u21BB":n>0?n>999?"999+":String(n):"";chrome.action.setBadgeText({tabId:e,text:o}).catch(()=>{}),o&&chrome.action.setBadgeBackgroundColor({tabId:e,color:"#7c3aed"}).catch(()=>{})}function ze(e,t){const n=I(e);n.needsReload=t,T.set(e,n),q(e)}function We(e,t){const n=I(e);le(n.network)!==le(t)&&(n.network=t,T.set(e,n),q(e))}function lo(e,t){const n=I(e);n.cosmetic!==t&&(n.cosmetic=t,T.set(e,n),q(e))}chrome.tabs.onUpdated.addListener((e,t)=>{t.status==="loading"&&t.url&&(T.set(e,qe()),q(e))});chrome.tabs.onRemoved.addListener(e=>T.delete(e));chrome.runtime.onInstalled.addListener(async e=>{e.reason==="install"&&chrome.tabs.create({url:chrome.runtime.getURL("onboarding.html")}).catch(()=>{});try{const t=await chrome.tabs.query({url:"*://*.youtube.com/*"});for(const n of t)n.id&&ze(n.id,!0)}catch{}});const K="skipSensei.rejectedAmnestyV1";(async()=>(await chrome.storage.local.get(K))[K]||(await chrome.storage.local.remove("skipSensei.gapfillRejected"),await chrome.storage.local.set({[K]:!0})))();Tn({onCounts:e=>je({...e,ads:0}),onTabCount:(e,t)=>We(e,t)});Cn();$n();Nn();ht();dn();(async()=>await Pn()?await In(async()=>{await S(),await Y(),await v(),await k()}):await wn())();wt();const uo="https://www.singlefinmedia.com/ad-sensei/goodbye";async function Ge(){const e=await h(),t=e.telemetryEnabled&&!e.localOnlyMode?`${uo}?v=${chrome.runtime.getManifest().version}&iid=${await gt()}`:"";await chrome.runtime.setUninstallURL(t)}Ge().catch(()=>{});E(()=>void Ge().catch(()=>{}));const po=At({type:"module",main(){}});var Ee,Te;(Te=(Ee=globalThis.browser)==null?void 0:Ee.runtime)!=null&&Te.id?globalThis.browser:globalThis.chrome;function U(e,...t){}const fo={debug:(...e)=>U(console.debug,...e),log:(...e)=>U(console.log,...e),warn:(...e)=>U(console.warn,...e),error:(...e)=>U(console.error,...e)};let Ae;try{dt(),Ae=po.main(),Ae instanceof Promise&&console.warn("The background's main() function return a promise, but it must be synchronous")}catch(e){throw fo.error("The background crashed on startup!"),e}
