import{b as c,g as k}from"./settings-mco8QK8Y.js";import{n as mt,a as $t}from"./downloadIntent-Dv31jC2S.js";import{n as x,a as qt}from"./clipTypes-C_ha5Ash.js";const yt="org.gdown.nativehost";async function At(t){return c.runtime.sendNativeMessage(yt,{action:"addUri",...t})}async function Ot(){return c.runtime.sendNativeMessage(yt,{action:"focus"})}const G="history";async function Nt(){const e=(await c.storage.local.get([G]))[G];return Array.isArray(e)?e:[]}async function Rt(t){await c.storage.local.set({[G]:t.slice(0,300)})}async function Et(t){const e=await Nt(),n=e.findIndex(r=>r.gid===t.gid);n>=0?e[n]=t:e.unshift(t),await Rt(e)}function ht(t,e){const n=Array.isArray(t?.responseHeaders)?t.responseHeaders:[],r=e.toLowerCase(),o=n.find(i=>String(i?.name||"").toLowerCase()===r);return String(o?.value||"")}function Lt(t){const e=t.toLowerCase();return e?e.includes("application/vnd.apple.mpegurl")||e.includes("application/x-mpegurl")||e.includes("audio/mpegurl")?"m3u8":e.includes("video/mp4")?"mp4":e.includes("application/octet-stream")&&e.includes("m3u8")?"m3u8":e.includes("hls")?"hls":"unknown":"unknown"}function Dt(t){const e=String(t||"").toLowerCase();return e.includes(".m3u8")?"m3u8":e.includes(".m3u")?"m3u":e.includes(".mp4")?"mp4":e.includes("m3u8")?"m3u8":e.includes("hls")?"hls":"unknown"}function wt(t,e){const n=Lt(e);return n!=="unknown"?n:Dt(t)}function Ht(t){if(!t?.url)return!1;const e=String(t?.method||"").toUpperCase();if(e&&e!=="GET")return!1;const n=Number(t?.statusCode||0);if(n>0&&(n<200||n>299))return!1;const r=String(t?.type||"");if(!["xmlhttprequest","media","other","main_frame","sub_frame","fetch"].includes(r))return!1;const o=ht(t,"content-type");return wt(t.url,o)!=="unknown"}function Bt(t,e=""){const n=ht(t,"content-type"),r=String(t?.url||""),o=wt(r,n),i=Number.isInteger(t?.tabId)?Number(t.tabId):-1,a=Date.now();return{id:`${a}:${i}:${o}:${r}`,url:r,kind:o,tabId:i,pageUrl:String(t?.documentUrl||t?.initiator||""),referer:String(e||t?.documentUrl||t?.initiator||""),contentType:n,detectedAt:a}}function rt(t){try{const e=new URL(t);return`${e.protocol}//${e.host}${e.pathname}`.toLowerCase()}catch{return String(t||"").toLowerCase()}}const F="media_candidates",_t=200;async function St(){const e=(await c.storage.local.get([F]))[F];return Array.isArray(e)?e:[]}async function Ft(t){const e=[...t].sort((n,r)=>r.detectedAt-n.detectedAt);await c.storage.local.set({[F]:e.slice(0,_t)})}async function Pt(t,e){const n=await St(),r=n.findIndex(o=>{try{const i=new URL(o.url);return`${i.protocol}//${i.host}${i.pathname}`.toLowerCase()===e}catch{return o.url.toLowerCase()===e}});r>=0?n[r]={...n[r],...t,detectedAt:Date.now()}:n.unshift(t),await Ft(n)}async function zt(){await c.storage.local.set({[F]:[]})}const V="clips",jt=500;function xt(t,e){return Date.parse(e.createdAt||"")-Date.parse(t.createdAt||"")}function q(t){return`${x(t.pageUrl)}::${qt(t.quote).toLowerCase()}`}async function b(){const e=(await c.storage.local.get([V]))[V];return Array.isArray(e)?e:[]}async function O(t){const e=[...t].sort(xt).slice(0,jt);await c.storage.local.set({[V]:e})}async function ot(t){const e=x(t);return(await b()).filter(r=>x(r.pageUrl)===e).sort(xt)}async function Wt(t){return(await b()).find(r=>r.id===t)||null}async function bt(t){const e=await b(),n=q(t),r=e.find(a=>q(a)===n);if(r){const a=e.findIndex(s=>s.id===r.id);return a>=0?(e[a]={...e[a],tabId:t.tabId??e[a].tabId,pageTitle:t.pageTitle||e[a].pageTitle,anchor:t.anchor||e[a].anchor,resolveStatus:t.resolveStatus??e[a].resolveStatus,resolveUpdatedAt:t.resolveUpdatedAt??e[a].resolveUpdatedAt},await O(e),e[a]):r}const o=Date.now(),i=e.find(a=>{const s=Date.parse(a.createdAt||"");return!Number.isFinite(s)||Math.abs(o-s)>8e3?!1:q(a)===n});return i||(e.unshift(t),await O(e),t)}async function Gt(t){const e=await b(),n=e.filter(r=>r.id!==t);return n.length===e.length?!1:(await O(n),!0)}async function B(t,e){const n=await b(),r=n.findIndex(a=>a.id===t);if(r<0)return null;const o=n[r];if(o.resolveStatus===e)return o;const i={...o,resolveStatus:e,resolveUpdatedAt:new Date().toISOString()};return n[r]=i,await O(n),i}function Vt(t){if(!t||typeof t!="object")return null;const e=x(String(t.pageUrl||"")),n=String(t.quote||t?.anchor?.exact||"").trim(),r=String(t?.anchor?.exact||n).trim();if(!e||!n||!r)return null;const o=String(t.createdAt||new Date().toISOString());return{id:String(t.id||`clip-${Date.now()}-${Math.random().toString(36).slice(2,8)}`),tabId:Number.isInteger(t.tabId)?Number(t.tabId):void 0,pageUrl:e,pageTitle:String(t.pageTitle||e),quote:n,quoteHtml:t.quoteHtml?String(t.quoteHtml):void 0,createdAt:o,color:"yellow",resolveStatus:t.resolveStatus==="broken"?"broken":t.resolveStatus==="ok"?"ok":void 0,resolveUpdatedAt:t.resolveUpdatedAt?String(t.resolveUpdatedAt):void 0,anchor:{exact:r,prefix:t?.anchor?.prefix?String(t.anchor.prefix):void 0,suffix:t?.anchor?.suffix?String(t.anchor.suffix):void 0,xpathStart:t?.anchor?.xpathStart?String(t.anchor.xpathStart):void 0,xpathEnd:t?.anchor?.xpathEnd?String(t.anchor.xpathEnd):void 0,startOffset:Number.isInteger(t?.anchor?.startOffset)?Number(t.anchor.startOffset):void 0,endOffset:Number.isInteger(t?.anchor?.endOffset)?Number(t.anchor.endOffset):void 0,startTextOffset:Number.isInteger(t?.anchor?.startTextOffset)?Number(t.anchor.startTextOffset):void 0,endTextOffset:Number.isInteger(t?.anchor?.endTextOffset)?Number(t.anchor.endTextOffset):void 0}}}async function Xt(t){const e=Array.isArray(t)?t.map(Vt).filter(Boolean):[];if(e.length===0)return{imported:0,total:0};const r=[...await b()];let o=0;for(const i of e){const a=r.findIndex(f=>f.id===i.id);if(a>=0){r[a]={...r[a],...i},o+=1;continue}const s=q(i),u=r.findIndex(f=>q(f)===s);if(u>=0){r[u]={...r[u],...i,id:r[u].id},o+=1;continue}r.unshift(i),o+=1}return await O(r),{imported:o,total:e.length}}const P=8e3,Yt=7e3,X="gomdown-helper-download-context-menu-option",Y="obsidianLastVault",A=new Map,K=new Map,J=new Map,Q=new Map,N=new Map,Z=new Map,tt=new Map;let ct=!1,lt=!1,ut=!1,$=null;const kt="bv*[ext=mp4]+ba[ext=m4a]/b[ext=mp4]/best",Kt=[{hosts:["youtube.com","www.youtube.com","m.youtube.com","youtu.be"],extractor:"yt-dlp",format:kt}];function w(...t){console.log("[gomdown-helper][clip][bg]",...t)}function z(t){try{const e=new URL(t),n=(e.pathname||"/").replace(/\/+$/,"")||"/";return`${e.protocol}//${e.host}${n}`.toLowerCase()}catch{return String(t||"").toLowerCase()}}function I(t){const e=Date.now();for(const[n,r]of t.entries())r<=e&&t.delete(n)}function vt(t){const e=Date.now()+P;K.set(mt(t),e),J.set(z(t),e)}function Ct(t){!Number.isInteger(t)||(t??-1)<0||Z.set(t,Date.now()+P)}function Jt(t){I(K),I(J);const e=mt(t);return K.has(e)||J.has(z(t))}function Qt(t){return I(Z),!Number.isInteger(t)||(t??-1)<0?!1:Z.has(t)}function Zt(t){return I(Q),Q.has(z(t))}function te(t){Q.set(z(t),Date.now()+Yt)}function ee(t){return I(N),!!t&&N.has(t)}function ne(t){t&&N.set(t,Date.now()+P)}function re(t){I(tt);const e=rt(t);return tt.has(e)}function oe(t){tt.set(rt(t),Date.now()+P)}async function ie(){try{await Ot()}catch{}}async function _(t){await c.notifications.create(`gomdown-notice-${Date.now()}`,{type:"basic",iconUrl:"/images/icon-large.png",title:"Gomdown Helper",message:t}).catch(()=>null)}async function C(t,e="",n,r,o,i){if(Zt(t))return{ok:!1,error:"duplicate transfer suppressed"};const a=await k();if(!a.extensionStatus)return{ok:!1,error:"extension disabled"};if(!a.motrixAPIkey)return{ok:!1,error:"motrixAPIkey is not set"};try{const s=await At({url:t,rpcPort:a.motrixPort,rpcSecret:a.motrixAPIkey,referer:e,split:64,out:o?.trim()||void 0,cookie:i?.cookie?.trim()||void 0,userAgent:i?.userAgent?.trim()||void 0,authorization:i?.authorization?.trim()||void 0,proxy:i?.proxy?.trim()||void 0,extractor:n==="yt-dlp"?"yt-dlp":void 0,format:n==="yt-dlp"?r||kt:void 0});if(!s?.ok)return{ok:!1,error:s?.error||"native host addUri failed"};a.activateAppOnDownload&&await ie(),te(t);const u=String(s?.gid||s?.requestId||`pending-${Date.now()}`),d=(()=>{try{return new URL(t).pathname}catch{return""}})().split("/").filter(Boolean).pop()||t;return await Et({gid:u,downloader:"native",startTime:new Date().toISOString(),icon:"/images/32.png",name:decodeURIComponent(d),path:null,status:s?.pending?"queued":"downloading",size:0,downloaded:0}),a.enableNotifications&&await c.notifications.create(`gomdown-transfer-${Date.now()}`,{type:"basic",iconUrl:"/images/icon-large.png",title:"Gomdown Helper",message:"Download sent to gdown"}),{ok:!0}}catch(s){return{ok:!1,error:String(s)}}}function dt(t){try{return new URL(t).hostname.toLowerCase()}catch{return""}}function It(t,e="",n=""){const r=[dt(t),dt(e)].filter(Boolean);for(const i of Kt)if(r.some(a=>i.hosts.includes(a)))return{extractor:i.extractor,format:i.format};const o=n.toLowerCase();return o==="m3u8"||o==="m3u"||o==="hls"?{extractor:"yt-dlp",format:"best"}:o==="mp4"?{extractor:"aria2"}:{extractor:"aria2"}}function ft(t,e){const n=e.toLowerCase(),r=t.find(o=>String(o?.name||"").toLowerCase()===n);return String(r?.value||"").trim()}async function ae(t){if(t.type!=="main_frame"||(t.method||"").toUpperCase()!=="GET"||typeof t.statusCode=="number"&&(t.statusCode<200||t.statusCode>299))return!1;const e=await k();if(!e.extensionStatus||!e.motrixAPIkey)return!1;const n=String(Array.isArray(t?.responseHeaders)&&t.responseHeaders.find(o=>String(o?.name||"").toLowerCase()==="content-length")?.value||""),r=Number(n||0);return e.minFileSize>0&&r>0&&r=0){const m=await c.tabs.get(s.tabId).catch(()=>null);u=String(m?.title||"").trim()}const f=de(s.url,s.kind,u),d={...s,pageTitle:u||void 0,cookie:i||void 0,userAgent:a||void 0,suggestedOut:f||void 0};await Pt(d,rt(d.url)),oe(d.url),d.tabId>=0&&await c.tabs.sendMessage(d.tabId,{type:"media:captured",kind:d.kind,url:d.url,suggestedOut:d.suggestedOut||""}).catch(()=>null)}function le(t){let e=t.trim().replace(/[\\/:*?"<>|]/g,"_").replace(/\s+/g," ").replace(/^\.+/,"").replace(/\.+$/,"");return e.length>180&&(e=e.slice(0,180).trim()),e}function ue(t){try{return new URL(t).pathname.toLowerCase().match(/\.([a-z0-9]{2,6})(?:$|[?#])/)?.[1]||""}catch{return""}}function de(t,e,n){const r=le(n||""),i=ue(t)||(e==="mp4"||e==="m3u8"||e==="m3u"||e==="hls"?"mp4":"");return r?!i||r.toLowerCase().endsWith(`.${i}`)?r:`${r}.${i}`:""}async function E(){const t=c.downloads;if(!t.setShelfEnabled)return;const e=await k();if(!e.extensionStatus)return;const n=e.useNativeHost?!1:!e.hideChromeBar;await t.setShelfEnabled(n)}function it(){lt||(lt=!0,c.downloads.onCreated.addListener(async t=>{await E();const e=t,n=e.finalUrl||e.url||"";!Jt(n)&&!Qt(e.tabId)||(await c.downloads.cancel(t.id).catch(()=>null),await c.downloads.erase({id:t.id}).catch(()=>null),await c.downloads.removeFile(t.id).catch(()=>null))}))}function at(){ct||(ct=!0,c.webRequest.onSendHeaders.addListener(t=>{A.set(t.requestId,t)},{urls:[""]},["requestHeaders","extraHeaders"]),c.webRequest.onErrorOccurred.addListener(t=>{A.delete(t.requestId),N.delete(String(t.requestId))},{urls:[""]}),c.webRequest.onCompleted.addListener(t=>{A.delete(t.requestId),N.delete(String(t.requestId))},{urls:[""]}),c.webRequest.onHeadersReceived.addListener(t=>{se(t),ce(t)},{urls:[""]},["responseHeaders"]))}async function pt(t,e){console.log("[gomdown-helper] context menu clicked",{menuItemId:t?.menuItemId,linkUrl:t?.linkUrl,srcUrl:t?.srcUrl,frameUrl:t?.frameUrl,pageUrl:t?.pageUrl,tabUrl:e?.url});const n=t?.menuItemId;if(n!=null&&String(n)!==X)return;const r=String(t?.linkUrl||t?.srcUrl||"").trim(),o=String(t?.frameUrl||t?.pageUrl||e?.url||"").trim(),a=String(r||o||"").trim();if(!a||/^(about:|chrome:|chrome-extension:|edge:|brave:)/i.test(a)){await _("다운로드 가능한 URL을 찾지 못했습니다.");return}const s=It(a,String(t?.pageUrl||e?.url||""),""),u=await C(a,String(t?.pageUrl||e?.url||""),s.extractor,s.format);if(!u.ok){await _(`전송 실패: ${u.error||"unknown error"}`);return}await _(s.extractor==="yt-dlp"?"페이지 URL을 yt-dlp로 gdown에 전송했습니다.":"gdown으로 전송했습니다.")}function fe(){if(typeof chrome>"u"||!chrome.contextMenus?.create){c.contextMenus.create({id:X,title:"Download with Gomdown",visible:!0,contexts:["all"]});return}chrome.contextMenus.create({id:X,title:"Download with Gomdown",contexts:["all"]},()=>{chrome.runtime.lastError})}function st(){ut||(typeof chrome<"u"&&chrome.contextMenus?.onClicked?chrome.contextMenus.onClicked.addListener((t,e)=>{pt(t,e)}):c.contextMenus.onClicked.addListener((t,e)=>{pt(t,e)}),ut=!0)}async function pe(){const t=await k();if(!t.extensionStatus||!t.showContextOption){await c.contextMenus.removeAll().catch(()=>null);return}await c.contextMenus.removeAll().catch(()=>null),fe()}function R(){return $||($=pe().finally(()=>{$=null}),$)}async function Ut(){w("requestCreateClipOnActiveTab:start");const e=(await c.tabs.query({active:!0,currentWindow:!0}))[0],n=Number(e?.id);if(w("active tab",{tabId:n,url:String(e?.url||""),title:String(e?.title||"")}),!Number.isInteger(n)||n<0)return w("requestCreateClipOnActiveTab:fail","active tab is unavailable"),{ok:!1,error:"active tab is unavailable"};const r=async()=>await c.tabs.sendMessage(n,{type:"clip:create-from-selection"});try{let o;try{o=await r()}catch(i){throw w("first sendMessage failed, using scripting fallback",String(i)),i}return w("content response",o),o?.ok?{ok:!0}:(w("requestCreateClipOnActiveTab:fail",o?.error||"failed to create clip in active tab"),{ok:!1,error:o?.error||"failed to create clip in active tab"})}catch(o){w("requestCreateClipOnActiveTab:exception",String(o));const i=await be(n,{url:String(e?.url||""),title:String(e?.title||"")}).catch(a=>(w("scripting fallback exception",String(a)),{ok:!1,error:String(a)}));return i.ok?{ok:!0}:{ok:!1,error:i.error||"content script is not ready on active tab"}}}async function ge(t){try{return!!(await c.scripting.executeScript({target:{tabId:t},func:()=>{const n="gomdown-inline-actionbar-fallback",r=document.getElementById(n);if(r)return r.style.display="flex",{ok:!0};const o=document.createElement("div");o.id=n,o.style.position="fixed",o.style.left="50%",o.style.bottom="14px",o.style.transform="translateX(-50%)",o.style.zIndex="2147483647",o.style.display="flex",o.style.gap="8px",o.style.padding="10px",o.style.background="rgba(15, 20, 31, 0.94)",o.style.border="1px solid rgba(97, 112, 155, 0.52)",o.style.borderRadius="12px",o.style.boxShadow="0 12px 24px rgba(0, 0, 0, 0.3)",o.style.fontFamily="ui-sans-serif, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif";const i=document.createElement("div");i.textContent="Gomdown Quick Action",i.style.fontSize="11px",i.style.color="#c9d4f2",i.style.display="flex",i.style.alignItems="center",i.style.padding="0 2px";const a=(l,p=!1)=>{const y=document.createElement("button");return y.type="button",y.textContent=l,y.style.height="32px",y.style.padding="0 12px",y.style.borderRadius="8px",y.style.border=p?"1px solid #5c6cf3":"1px solid #4b5873",y.style.background=p?"#5c6cf3":"#2a3346",y.style.color="#e8edff",y.style.fontSize="12px",y.style.fontWeight="700",y.style.cursor="pointer",y},s=a("클립 저장",!0),u=a("현재 페이지"),f=a("MD"),d=a("JSON"),m=a("Obsidian"),h=a("닫기"),g=document.createElement("div");return g.style.display="none",g.style.gap="6px",g.style.alignItems="center",g.style.flexWrap="wrap",g.appendChild(f),g.appendChild(d),g.appendChild(m),s.onclick=()=>{try{chrome.runtime.sendMessage({type:"clip:create-active-tab"},l=>{const p=!!l?.ok;i.textContent=p?"클립 저장 완료":`실패: ${String(l?.error||"unknown error")}`,i.style.color=p?"#8ff0a4":"#ffaaaa",p&&(g.style.display="flex")})}catch(l){i.textContent=`실패: ${String(l)}`,i.style.color="#ffaaaa"}},u.onclick=()=>{try{chrome.runtime.sendMessage({type:"page:enqueue-ytdlp-url",url:window.location.href,referer:window.location.href},l=>{const p=!!l?.ok;i.textContent=p?"현재 페이지 전송 완료":`실패: ${String(l?.error||"unknown error")}`,i.style.color=p?"#8ff0a4":"#ffaaaa"})}catch(l){i.textContent=`실패: ${String(l)}`,i.style.color="#ffaaaa"}},f.onclick=()=>{try{chrome.runtime.sendMessage({type:"clip:export-current-page-md",pageUrl:window.location.href,pageTitle:document.title||window.location.href},l=>{const p=!!l?.ok;i.textContent=p?"MD 내보내기 완료":`실패: ${String(l?.error||"unknown error")}`,i.style.color=p?"#8ff0a4":"#ffaaaa"})}catch(l){i.textContent=`실패: ${String(l)}`,i.style.color="#ffaaaa"}},d.onclick=()=>{try{chrome.runtime.sendMessage({type:"clip:export-current-page-json",pageUrl:window.location.href,pageTitle:document.title||window.location.href},l=>{const p=!!l?.ok;i.textContent=p?"JSON 내보내기 완료":`실패: ${String(l?.error||"unknown error")}`,i.style.color=p?"#8ff0a4":"#ffaaaa"})}catch(l){i.textContent=`실패: ${String(l)}`,i.style.color="#ffaaaa"}},m.onclick=()=>{try{chrome.runtime.sendMessage({type:"clip:send-obsidian-current-page",pageUrl:window.location.href,pageTitle:document.title||window.location.href},l=>{if(!!(l?.ok&&l?.uri)){try{window.open(String(l.uri),"_blank")}catch{window.location.href=String(l.uri)}i.textContent="Obsidian 전송 시도 완료",i.style.color="#8ff0a4";return}i.textContent=`실패: ${String(l?.error||"unknown error")}`,i.style.color="#ffaaaa"})}catch(l){i.textContent=`실패: ${String(l)}`,i.style.color="#ffaaaa"}},h.onclick=()=>{o.remove()},o.appendChild(s),o.appendChild(u),o.appendChild(h),o.appendChild(g),o.appendChild(i),document.documentElement.appendChild(o),window.setTimeout(()=>{o.remove()},9e3),{ok:!0}}}))?.[0]?.result?.ok}catch{return!1}}function Tt(){try{return crypto.randomUUID()}catch{return`clip-${Date.now()}-${Math.random().toString(36).slice(2,8)}`}}function me(t,e){const n=String(t.quote||t.anchor?.exact||"").replace(/\r\n/g,` `).trim(),o=(n.length>4e3?`${n.slice(0,4e3)} ...(truncated)`:n).split(` `).map(a=>a.trimEnd()).filter((a,s,u)=>!(a===""&&u[s-1]==="")),i=o.length===0?"> ":o.map(a=>`> ${a}`).join(` `);return[`### ${e+1}. Clip`,i,"",`- created: ${t.createdAt}`,`- status: ${t.resolveStatus||"ok"}`].join(` `)}function Mt(t,e,n=""){const o=[`# ${n||t[0]?.pageTitle||e||"Untitled"}`,`- source: ${e}`,`- exportedAt: ${new Date().toISOString()}`,`- clips: ${t.length}`,"","---",""];for(let i=0;i|]/g,"_").replace(/[(){}[\]]/g,"").replace(/\s+/g," ").replace(/[._-]{2,}/g,"-").replace(/^[._\-\s]+|[._\-\s]+$/g,"").slice(0,90)||"clips"}function ye(t,e){let n=String(t||"").trim(),r=String(e||"").trim();if(n.includes("/")||n.includes("\\")){const o=n.split(/[\\/]+/).filter(Boolean);n=o[o.length-1]||""}return(/^myvault$/i.test(n)||/^example$/i.test(n))&&(n=""),r=r.replace(/^\/+|\/+$/g,""),{vault:n,folder:r}}async function he(){try{const t=await c.storage.local.get(Y);return String(t?.[Y]||"").trim()}catch{return""}}async function we(t){const e=String(t||"").trim();if(e)try{await c.storage.local.set({[Y]:e})}catch{}}async function nt(t,e,n){if(!t.trim())return{ok:!1,error:"filename is empty"};const r=`data:${e},${encodeURIComponent(n)}`;try{return{ok:!0,downloadId:await c.downloads.download({url:r,filename:t.trim(),saveAs:!0})}}catch(o){return{ok:!1,error:String(o)}}}async function gt(t,e,n){const r=x(String(t||"").trim());if(!r)return{ok:!1,error:"pageUrl is empty"};const o=await ot(r);if(o.length===0)return{ok:!1,error:"no clips for current page"};const i=String(e||o[0]?.pageTitle||r).trim();if(n==="md"){const f=Mt(o,r,i),d=`${et(i)}-clips.md`,m=await nt(d,"text/markdown;charset=utf-8",f);return{ok:m.ok,error:m.error,count:o.length,downloadId:m.downloadId}}const a={exportedAt:new Date().toISOString(),version:1,count:o.length,clips:o},s=`${et(i)}-clips.json`,u=await nt(s,"application/json;charset=utf-8",JSON.stringify(a,null,2));return{ok:u.ok,error:u.error,count:o.length,downloadId:u.downloadId}}async function Se(t,e){const n=x(String(t||"").trim());if(!n)return{ok:!1,error:"pageUrl is empty"};const r=await ot(n);if(r.length===0)return{ok:!1,error:"no clips for current page"};const o=await k(),i=ye(o.obsidianVault,o.obsidianFolder);i.vault&&await we(i.vault);const a=i.vault||await he(),s=String(e||r[0]?.pageTitle||n).trim(),u=Mt(r,n,s),f=i.folder,d=`${et(s)}-${new Date().toISOString().slice(0,19).replace(/[:T]/g,"-")}`,m=f?`${f}/${d}`:d,h=`file=${encodeURIComponent(m)}&content=${encodeURIComponent(u)}`;return{ok:!0,uri:a?`obsidian://new?vault=${encodeURIComponent(a)}&${h}`:`obsidian://new?${h}`,count:r.length}}async function xe(t,e){try{return!!(await c.scripting.executeScript({target:{tabId:t},args:[e.quote||e.anchor?.exact||"",e.anchor?.prefix||"",e.anchor?.suffix||""],func:(r,o,i)=>{const a=String(r||"").trim();if(!a)return{ok:!1,error:"quote is empty"};const s=String(o||"").trim(),u=String(i||"").trim(),f=document.body?.innerText||document.documentElement?.innerText||"";if(!f)return{ok:!1,error:"document text is empty"};let d=f.indexOf(a),m=-1;for(;d>=0;){const M=s?f.slice(Math.max(0,d-s.length),d).trim():"",W=u?f.slice(d+a.length,d+a.length+u.length).trim():"";if((!s||M===s)&&(!u||W===u)){m=d;break}d=f.indexOf(a,d+Math.max(1,Math.floor(a.length/2)))}if(m<0)return{ok:!1,error:"quote not found in page text"};const h=document.createTreeWalker(document.body||document.documentElement,NodeFilter.SHOW_TEXT);let g=0,l=null,p=null,y=0,L=0;const U=m,v=m+a.length;let D=h.nextNode();for(;D;){if(D.nodeType===Node.TEXT_NODE){const M=D,W=M.nodeValue||"",H=g+W.length;!l&&U>=g&&U<=H&&(l=M,y=Math.max(0,U-g)),!p&&v>=g&&v<=H&&(p=M,L=Math.max(0,v-g)),g=H}D=h.nextNode()}if(!l||!p)return{ok:!1,error:"failed to map quote to text nodes"};const j=document.createRange();j.setStart(l,Math.min(l.length,y)),j.setEnd(p,Math.min(p.length,L));const T=j.getBoundingClientRect(),S=document.createElement("span");return S.style.position="absolute",S.style.left=`${window.scrollX+T.left-2}px`,S.style.top=`${window.scrollY+T.top-2}px`,S.style.width=`${Math.max(8,T.width+4)}px`,S.style.height=`${Math.max(14,T.height+4)}px`,S.style.pointerEvents="none",S.style.borderRadius="6px",S.style.background="rgba(255, 240, 130, 0.42)",S.style.border="1px solid rgba(230, 190, 70, 0.72)",S.style.zIndex="2147483647",document.documentElement.appendChild(S),window.scrollTo({top:Math.max(0,window.scrollY+T.top-window.innerHeight*.35),behavior:"smooth"}),window.setTimeout(()=>S.remove(),1800),{ok:!0}}}))?.[0]?.result?.ok}catch{return!1}}async function be(t,e){w("createClipFromSelectionByScriptingFallback:start",{tabId:t});const r=(await c.scripting.executeScript({target:{tabId:t},func:()=>{const d=window.getSelection();if(!d||d.rangeCount===0)return{ok:!1,error:"empty selection"};const m=String(d.toString()||"").trim();if(!m)return{ok:!1,error:"empty selection"};const h=d.getRangeAt(0),g=h.startContainer,l=h.endContainer,p=g.nodeType===Node.TEXT_NODE?String(g.nodeValue||""):"",y=l.nodeType===Node.TEXT_NODE?String(l.nodeValue||""):"",L=p?p.slice(Math.max(0,h.startOffset-24),h.startOffset).trim():"",U=y?y.slice(h.endOffset,Math.min(y.length,h.endOffset+24)).trim():"";return{ok:!0,quote:m,quoteHtml:(()=>{try{const v=document.createElement("div");return v.appendChild(h.cloneContents()),v.innerHTML.trim()}catch{return""}})(),pageUrl:String(location.href||"").split("#")[0],pageTitle:String(document.title||""),anchor:{exact:m,prefix:L||void 0,suffix:U||void 0}}}}))?.[0]?.result;if(!r?.ok){const d=r?.error||"selection capture fallback failed";return w("createClipFromSelectionByScriptingFallback:fail",d),{ok:!1,error:d}}const o=x(String(r.pageUrl||e?.url||"")),i=String(r.pageTitle||e?.title||o).trim(),a=String(r.quote||r.anchor?.exact||"").trim(),s=r.anchor||{exact:a};if(!o||!a||!String(s?.exact||"").trim())return{ok:!1,error:"invalid clip payload from fallback"};const u={id:Tt(),tabId:t,pageUrl:o,pageTitle:i||o,quote:a,quoteHtml:String(r.quoteHtml||"").trim()||void 0,createdAt:new Date().toISOString(),color:"yellow",anchor:s},f=await bt(u);return w("createClipFromSelectionByScriptingFallback:ok",{id:f.id,pageUrl:f.pageUrl}),{ok:!0,item:f}}async function ke(t){const e=x(t),r=(await c.tabs.query({})).find(o=>x(String(o.url||""))===e);return Number.isInteger(r?.id)?r?.id:null}c.runtime.onMessage.addListener((t,e)=>{if(t?.type?.startsWith?.("clip:")&&w("runtime.onMessage",t?.type,{senderTabId:Number(e?.tab?.id),senderUrl:String(e?.tab?.url||"")}),t?.type==="capture-link-download"){const n=String(t?.url||"").trim();if(!n)return Promise.resolve({ok:!1,error:"url is empty"});const r=Number(e?.tab?.id);return C(n,String(t?.referer||"")).then(o=>(o.ok&&(vt(n),Ct(r)),o))}if(t?.type==="media:list")return St().then(n=>({ok:!0,items:n}));if(t?.type==="media:clear")return zt().then(()=>({ok:!0}));if(t?.type==="media:enqueue"){const n=String(t?.url||"").trim(),r=String(t?.kind||"").trim(),o=String(t?.suggestedOut||"").trim(),i=String(t?.referer||"").trim(),a=String(t?.cookie||"").trim(),s=String(t?.userAgent||"").trim();if(!n)return Promise.resolve({ok:!1,error:"url is empty"});const u=It(n,i,r);return C(n,i,u.extractor,u.format,o,{cookie:a,userAgent:s}).then(f=>f)}if(t?.type==="page:enqueue-ytdlp")return c.tabs.query({active:!0,currentWindow:!0}).then(async n=>{const r=n[0],o=String(r?.url||"").trim();return o?C(o,o,"yt-dlp"):{ok:!1,error:"active tab url is empty"}});if(t?.type==="page:enqueue-ytdlp-url"){const n=String(t?.url||"").trim(),r=String(t?.referer||n).trim();return n?C(n,r||n,"yt-dlp"):Promise.resolve({ok:!1,error:"url is empty"})}if(t?.type==="file:download-text"){const n=String(t?.filename||"").trim(),r=String(t?.mime||"text/plain;charset=utf-8").trim(),o=String(t?.content||"");return nt(n,r,o)}if(t?.type==="clip:export-current-page-md")return gt(String(t?.pageUrl||""),String(t?.pageTitle||""),"md");if(t?.type==="clip:export-current-page-json")return gt(String(t?.pageUrl||""),String(t?.pageTitle||""),"json");if(t?.type==="clip:send-obsidian-current-page")return Se(String(t?.pageUrl||""),String(t?.pageTitle||""));if(t?.type==="clip:create")return k().then(async n=>{if(!n.extensionStatus)return{ok:!1,error:"extension disabled"};const r=x(String(t?.pageUrl||e?.tab?.url||"")),o=String(t?.pageTitle||e?.tab?.title||"").trim(),i=String(t?.quote||t?.anchor?.exact||"").trim(),a=String(t?.quoteHtml||"").trim(),s=t?.anchor;if(!r)return{ok:!1,error:"pageUrl is empty"};if(!s||!String(s.exact||"").trim())return{ok:!1,error:"anchor is empty"};const u={id:Tt(),tabId:Number.isInteger(e?.tab?.id)?Number(e.tab.id):void 0,pageUrl:r,pageTitle:o||r,quote:i||String(s.exact||"").trim(),quoteHtml:a||void 0,createdAt:new Date().toISOString(),color:"yellow",anchor:s};return{ok:!0,item:await bt(u)}});if(t?.type==="clip:list"){const n=String(t?.pageUrl||"").trim();return n?ot(n).then(r=>({ok:!0,items:r})):b().then(r=>({ok:!0,items:r}))}if(t?.type==="clip:export")return b().then(n=>({ok:!0,items:n}));if(t?.type==="clip:import"){const n=Array.isArray(t?.items)?t.items:[];return Xt(n).then(r=>({ok:!0,...r}))}if(t?.type==="clip:delete"){const n=String(t?.id||"").trim();return n?Gt(n).then(r=>({ok:r})):Promise.resolve({ok:!1,error:"id is empty"})}if(t?.type==="clip:create-active-tab")return Ut();if(t?.type==="clip:resolve-status"){const n=String(t?.id||"").trim(),r=String(t?.status||"").trim();return n?r!=="ok"&&r!=="broken"?Promise.resolve({ok:!1,error:"invalid status"}):B(n,r).then(o=>({ok:!!o,item:o})):Promise.resolve({ok:!1,error:"id is empty"})}if(t?.type==="clip:reveal"){const n=String(t?.id||"").trim();return n?Wt(n).then(async r=>{if(!r)return{ok:!1,error:"clip not found"};const o=Number.isInteger(r.tabId)&&(r.tabId||0)>=0?r.tabId:await ke(r.pageUrl);if(!Number.isInteger(o)||o<0){const a=await c.tabs.create({url:r.pageUrl,active:!0}).catch(()=>null);return Number.isInteger(a?.id)?{ok:!0,opened:!0}:{ok:!1,error:"failed to open clip page"}}return await c.tabs.update(o,{active:!0}).catch(()=>null),(await c.tabs.sendMessage(o,{type:"clip:reveal",id:r.id}).catch(()=>null))?.ok?(await B(r.id,"ok"),{ok:!0}):await xe(o,r)?(await B(r.id,"ok"),{ok:!0,fallback:"scripting"}):(await B(r.id,"broken"),{ok:!1,error:"clip anchor not found in current dom"})}):Promise.resolve({ok:!1,error:"id is empty"})}});c.commands.onCommand.addListener(t=>{w("commands.onCommand",t),t==="create_clip_from_selection"&&(async()=>{const e=await c.tabs.query({active:!0,currentWindow:!0}),n=Number(e[0]?.id);if(Number.isInteger(n)&&n>=0&&(await c.tabs.sendMessage(n,{type:"clip:show-action-bar"}).then(a=>!!a?.ok).catch(()=>!1)||await ge(n)))return;const r=await Ut();r.ok||(w("commands.onCommand:fail",r),await _(`클립 생성 실패: ${r.error||"unknown error"}`))})()});c.runtime.onInstalled.addListener(()=>{console.log("[gomdown-helper] onInstalled"),at(),it(),st(),R(),E()});c.runtime.onStartup.addListener(()=>{console.log("[gomdown-helper] onStartup"),at(),it(),st(),R(),E()});c.storage.onChanged.addListener((t,e)=>{e==="sync"&&((t.hideChromeBar||t.useNativeHost||t.extensionStatus)&&(E(),R()),t.showContextOption&&R())});at();it();st();R();E();console.log("[gomdown-helper] service worker initialized");