-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathbackground.js
More file actions
13 lines (13 loc) · 21 KB
/
background.js
File metadata and controls
13 lines (13 loc) · 21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
var background=function(){"use strict";var V,z;function X(i){return i==null||typeof i=="function"?{main:i}:i}var Z=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function G(i){return i&&i.__esModule&&Object.prototype.hasOwnProperty.call(i,"default")?i.default:i}var _={exports:{}};(function(i,v){(function(n,C){C(i)})(typeof globalThis<"u"?globalThis:typeof self<"u"?self:Z,function(n){if(!(globalThis.chrome&&globalThis.chrome.runtime&&globalThis.chrome.runtime.id))throw new Error("This script should only be loaded in a browser extension.");if(globalThis.browser&&globalThis.browser.runtime&&globalThis.browser.runtime.id)n.exports=globalThis.browser;else{const C="The message port closed before a response was received.",L=w=>{const y={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(Object.keys(y).length===0)throw new Error("api-metadata.json has not been included in browser-polyfill");class E extends WeakMap{constructor(t,o=void 0){super(o),this.createItem=t}get(t){return this.has(t)||this.set(t,this.createItem(t)),super.get(t)}}const $=r=>r&&typeof r=="object"&&typeof r.then=="function",S=(r,t)=>(...o)=>{w.runtime.lastError?r.reject(new Error(w.runtime.lastError.message)):t.singleCallbackArg||o.length<=1&&t.singleCallbackArg!==!1?r.resolve(o[0]):r.resolve(o)},M=r=>r==1?"argument":"arguments",N=(r,t)=>function(g,...q){if(q.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${M(t.minArgs)} for ${r}(), got ${q.length}`);if(q.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${M(t.maxArgs)} for ${r}(), got ${q.length}`);return new Promise((T,b)=>{if(t.fallbackToNoCallback)try{g[r](...q,S({resolve:T,reject:b},t))}catch(s){console.warn(`${r} API method doesn't seem to support the callback parameter, falling back to call it without a callback: `,s),g[r](...q),t.fallbackToNoCallback=!1,t.noCallback=!0,T()}else t.noCallback?(g[r](...q),T()):g[r](...q,S({resolve:T,reject:b},t))})},H=(r,t,o)=>new Proxy(t,{apply(g,q,T){return o.call(q,r,...T)}});let D=Function.call.bind(Object.prototype.hasOwnProperty);const I=(r,t={},o={})=>{let g=Object.create(null),q={has(b,s){return s in r||s in g},get(b,s,p){if(s in g)return g[s];if(!(s in r))return;let d=r[s];if(typeof d=="function")if(typeof t[s]=="function")d=H(r,r[s],t[s]);else if(D(o,s)){let u=N(s,o[s]);d=H(r,r[s],u)}else d=d.bind(r);else if(typeof d=="object"&&d!==null&&(D(t,s)||D(o,s)))d=I(d,t[s],o[s]);else if(D(o,"*"))d=I(d,t[s],o["*"]);else return Object.defineProperty(g,s,{configurable:!0,enumerable:!0,get(){return r[s]},set(u){r[s]=u}}),d;return g[s]=d,d},set(b,s,p,d){return s in g?g[s]=p:r[s]=p,!0},defineProperty(b,s,p){return Reflect.defineProperty(g,s,p)},deleteProperty(b,s){return Reflect.deleteProperty(g,s)}},T=Object.create(r);return new Proxy(T,q)},e=r=>({addListener(t,o,...g){t.addListener(r.get(o),...g)},hasListener(t,o){return t.hasListener(r.get(o))},removeListener(t,o){t.removeListener(r.get(o))}}),c=new E(r=>typeof r!="function"?r:function(o){const g=I(o,{},{getContent:{minArgs:0,maxArgs:0}});r(g)}),a=new E(r=>typeof r!="function"?r:function(o,g,q){let T=!1,b,s=new Promise(x=>{b=function(h){T=!0,x(h)}}),p;try{p=r(o,g,b)}catch(x){p=Promise.reject(x)}const d=p!==!0&&$(p);if(p!==!0&&!d&&!T)return!1;const u=x=>{x.then(h=>{q(h)},h=>{let k;h&&(h instanceof Error||typeof h.message=="string")?k=h.message:k="An unexpected error occurred",q({__mozWebExtensionPolyfillReject__:!0,message:k})}).catch(h=>{console.error("Failed to send onMessage rejected reply",h)})};return u(d?p:s),!0}),m=({reject:r,resolve:t},o)=>{w.runtime.lastError?w.runtime.lastError.message===C?t():r(new Error(w.runtime.lastError.message)):o&&o.__mozWebExtensionPolyfillReject__?r(new Error(o.message)):t(o)},A=(r,t,o,...g)=>{if(g.length<t.minArgs)throw new Error(`Expected at least ${t.minArgs} ${M(t.minArgs)} for ${r}(), got ${g.length}`);if(g.length>t.maxArgs)throw new Error(`Expected at most ${t.maxArgs} ${M(t.maxArgs)} for ${r}(), got ${g.length}`);return new Promise((q,T)=>{const b=m.bind(null,{resolve:q,reject:T});g.push(b),o.sendMessage(...g)})},l={devtools:{network:{onRequestFinished:e(c)}},runtime:{onMessage:e(a),onMessageExternal:e(a),sendMessage:A.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:A.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},f={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return y.privacy={network:{"*":f},services:{"*":f},websites:{"*":f}},I(w,l,y)};n.exports=L(chrome)}})})(_);var J=_.exports;const R=G(J);function W(i){const v=i.replace(/\r/g,"").split(`
`),n=v.shift()||"",[C,L]=n.split(" "),w=[];let y,E=!0;for(const $ of v){if(E&&$===""){E=!1;continue}if(E){const S=$.split(": ");S.length===2&&w.push({name:S[0],value:S[1]})}else y=(y?y+`
`:"")+$}return{method:C,url:L,headers:w,postData:y}}const K=i=>{const v=i.find(n=>n.name.toLowerCase()==="content-type");if(v){const n=v.value.match(/charset=([^;]+)/);if(n)return n[1].trim()}return"utf-8"},Q=i=>{const v={};return i.forEach(n=>{v[n.name]=n.value}),v},Y=X(()=>{console.log("Background script loaded.");let i=!1,v="intercept",n=[];const C=new Map,L="1.3",w=new Set,y=new Map,E=new Map;let $=[];function S(e){e?(R.action.setBadgeText({text:"ON"}),R.action.setBadgeBackgroundColor({color:v==="proxy"?"#2196F3":"#4CAF50"})):R.action.setBadgeText({text:""})}async function M(e){if(C.has(e)){console.log(`Debugger already attached to tab ${e}.`);return}console.log(`Attempting to attach debugger to tab ${e}...`);try{await chrome.debugger.attach({tabId:e},L),C.set(e,L),await chrome.debugger.sendCommand({tabId:e},"Fetch.enable",{patterns:[{requestStage:"Request",resourceType:"Document"},{requestStage:"Request",resourceType:"XHR"},{requestStage:"Response",resourceType:"Document"},{requestStage:"Response",resourceType:"XHR"}]}),console.log(`Successfully attached debugger to tab ${e}.`)}catch(c){console.error(`Failed to attach debugger to tab ${e}:`,c.message),C.delete(e),c.message.includes("another debugger")&&R.notifications.create(`attach-fail-${e}`,{type:"basic",iconUrl:"icon/128.png",title:"附加调试器失败",message:`无法附加到标签页 ${e}。请确保该标签页未打开开发者工具(F12)。`})}}async function N(e){if(C.has(e))try{await chrome.debugger.detach({tabId:e}),console.log(`Debugger detached from tab ${e}`)}catch(c){console.error(`Failed to detach debugger from tab ${e}:`,c)}finally{C.delete(e)}}async function H(e){console.log(`Toggling all tabs to enabled: ${e}`),i=e,S(i);const c=await R.tabs.query({url:["http://*/*","https://*/*"]});for(const a of c)a.id&&(e?await M(a.id):await N(a.id))}async function D(){console.log("Initializing extension...");const e=await R.storage.local.get(["networkInterceptorEnabled","networkInterceptorMode","aiApiEndpoint"]);if(i=!!e.networkInterceptorEnabled,v=e.networkInterceptorMode||"intercept",S(i),console.log("Initial state:",{isEnabled:i,mode:v}),e.aiApiEndpoint)try{$=[new URL(e.aiApiEndpoint).origin],console.log("Added API endpoint to whitelist:",$)}catch{console.error("Invalid API endpoint URL:",e.aiApiEndpoint)}i&&await H(!0)}D();const I=()=>{R.runtime.sendMessage({action:"update-requests",data:n}).catch(()=>{})};R.webRequest.onBeforeRequest.addListener(e=>{console.log("webRequest.onBeforeRequest:",e.url)},{urls:["<all_urls>"]}),R.webRequest.onBeforeSendHeaders.addListener(e=>{const c=n.findIndex(a=>a.request.url===e.url&&a.status==="paused"&&a.tabId===e.tabId);if(c!==-1&&e.requestHeaders){const a=e.requestHeaders.map(m=>{var A;return{name:m.name,value:((A=m.value)==null?void 0:A.toString())||""}});n[c].requestHeaders=a,I()}return{requestHeaders:e.requestHeaders}},{urls:["<all_urls>"]},["requestHeaders"]),R.webRequest.onHeadersReceived.addListener(e=>{const c=n.findIndex(a=>a.request.url===e.url&&a.tabId===e.tabId);if(c!==-1&&e.responseHeaders){const a=e.responseHeaders.map(m=>{var A;return{name:m.name,value:((A=m.value)==null?void 0:A.toString())||""}});n[c].responseHeaders=a,I()}return{responseHeaders:e.responseHeaders}},{urls:["<all_urls>"]},["responseHeaders"]),chrome.debugger.onEvent.addListener(async(e,c,a)=>{if(c!=="Fetch.requestPaused"||!e.tabId)return;const{requestId:m,request:A,responseStatusCode:l,responseHeaders:f,networkId:r,redirectResponse:t}=a;if(!m){console.warn("Received event with invalid requestId",a);return}if($.some(s=>A.url.startsWith(s))){console.log("Allowing whitelisted request:",A.url);try{await chrome.debugger.sendCommand({tabId:e.tabId},"Fetch.continueRequest",{requestId:m})}catch(s){console.error("Failed to continue whitelisted request:",s)}return}const g=A.headers["X-Replay-Id"];if(g&&y.has(g)){const s=y.get(g);clearTimeout(s.timeoutId),y.delete(g),E.set(m,s.originalId),w.add(s.originalId);try{await chrome.debugger.sendCommand({tabId:e.tabId},"Fetch.continueRequest",{requestId:m,headers:s.headers,postData:s.postData?btoa(unescape(encodeURIComponent(s.postData))):void 0})}catch(p){console.error("Failed to continue replay request:",p),E.delete(m),w.delete(s.originalId)}return}const T=E.get(m)||r||`${e.tabId}-${m}`,b=n.findIndex(s=>s.id===T);if(f){if(b!==-1){try{const s=await chrome.debugger.sendCommand({tabId:e.tabId},"Fetch.getResponseBody",{requestId:m});let p="";if(s.body){const u=K(f);if(s.base64Encoded){const x=atob(s.body),h=new Uint8Array(x.length);for(let k=0;k<x.length;k++)h[k]=x.charCodeAt(k);p=new TextDecoder(u).decode(h)}else p=new TextDecoder(u).decode(new TextEncoder().encode(s.body))}let d=`HTTP/1.1 ${l}\r
`;f.forEach(u=>d+=`${u.name}: ${u.value}\r
`),d+=`\r
${p}`,n[b].rawResponse=d,n[b].status="finished",n[b].responseHeaders=f.map(u=>({name:u.name,value:u.value}))}catch(s){n[b].rawResponse=`Error getting response body: ${s.message}`,n[b].status="finished"}finally{w.delete(T),E.delete(m),I()}try{await chrome.debugger.sendCommand({tabId:e.tabId},"Fetch.continueRequest",{requestId:m})}catch(s){console.error(`Failed to continue response request ${m}:`,s)}}}else{if(b!==-1){n[b].requestId=m;return}let s=`${A.method} ${A.url} HTTP/1.1\r
`;const p=[];Object.entries(A.headers).forEach(([x,h])=>{const k=String(h);s+=`${x}: ${k}\r
`,p.push({name:x,value:k})}),A.postData&&(s+=`\r
${A.postData}`);const d=v==="proxy"?"finished":"paused",u={id:T,tabId:e.tabId,requestId:m,request:A,rawRequest:s,status:d,isRedirect:!!t,requestHeaders:p};if(n.push(u),I(),v==="proxy")try{await chrome.debugger.sendCommand({tabId:e.tabId},"Fetch.continueRequest",{requestId:m})}catch(x){console.error(`Failed to continue proxy request ${m}:`,x);const h=n.findIndex(k=>k.id===T);h!==-1&&(n[h].status="finished",n[h].rawResponse=`继续请求失败: ${x instanceof Error?x.message:JSON.stringify(x)}`,I())}}}),R.storage.onChanged.addListener((e,c)=>{if(c==="local"){if(e.networkInterceptorEnabled){const{newValue:a}=e.networkInterceptorEnabled;if(H(!!a),!a){const m=n.filter(A=>A.status==="paused");m.length>0&&(m.forEach(A=>{A.status="finished",A.rawResponse="代理已关闭,请求自动放行"}),I())}}if(e.networkInterceptorMode&&(v=e.networkInterceptorMode.newValue,S(i)),e.aiApiEndpoint)try{$=[new URL(e.aiApiEndpoint.newValue).origin],console.log("Updated API whitelist:",$)}catch{console.error("Invalid API endpoint URL:",e.aiApiEndpoint.newValue)}}}),R.tabs.onCreated.addListener(async e=>{i&&e.id&&await M(e.id)}),R.tabs.onUpdated.addListener(async(e,c,a)=>{i&&c.url&&a.url&&(C.has(e)||await M(e))}),R.tabs.onRemoved.addListener(e=>{C.has(e)&&N(e)}),chrome.debugger.onDetach.addListener(e=>{e.tabId&&C.has(e.tabId)&&(C.delete(e.tabId),console.log(`Debugger detached from tab ${e.tabId} by user or other extension.`))}),R.runtime.onSuspend.addListener(()=>{console.log("Extension is being suspended, clearing data..."),n=[]}),R.runtime.onMessage.addListener(async e=>{const{action:c,requestData:a,rawRequest:m,headers:A}=e;if(c==="get-initial-requests")I();else if(c==="resume-request"&&a){if(w.has(a.id))return!0;w.add(a.id);const l=n.findIndex(f=>f.id===a.id);try{if(l===-1||!a.requestId)throw new Error("请求已失效或超时");try{await chrome.debugger.sendCommand({tabId:a.tabId},"Fetch.continueRequest",{requestId:a.requestId,headers:A||W(m).headers}),l!==-1&&(n[l].status="finished",I())}catch(f){const r=f instanceof Error?f.message:JSON.stringify(f);console.error(`Failed to continue request ${a.id}:`,r),r.includes("Invalid InterceptionId")||r.includes("-32602")?l!==-1&&(n[l].status="finished",n[l].rawResponse="请求已自动完成或超时",I()):l!==-1&&(n[l].status="finished",n[l].rawResponse=`放行失败: ${r}`,I())}}catch(f){console.error(`处理请求 ${a.id} 时出错:`,f),l!==-1&&(n[l].status="finished",n[l].rawResponse=`处理失败: ${f instanceof Error?f.message:JSON.stringify(f)}`,I())}finally{w.delete(a.id)}}else if(c==="replay-request"&&a){if(w.has(a.id))return!0;w.add(a.id);const l=`${Date.now()}-${Math.random()}`,{url:f,method:r,postData:t}=W(m),o=A||[],g=`replay-${Date.now()}`,q={id:g,tabId:a.tabId,requestId:`replay-${a.requestId}`,request:{url:f,method:r,headers:Q(o)},rawRequest:m,status:"finished",isRedirect:!1,requestHeaders:o};n.push(q);const T=(d=!1,u)=>{const x=y.get(l);if(x&&(clearTimeout(x.timeoutId),y.delete(l),d)){const h=n.findIndex(k=>k.id===g);h!==-1&&(n[h].rawResponse=u||"重放请求超时或失败",I())}w.delete(a.id)},b=setTimeout(()=>{console.warn(`Replay ${l} timed out and was cleaned up.`),T(!0,"重放请求超时")},3e4);y.set(l,{originalId:a.id,replayId:g,headers:o,postData:t,timeoutId:b});const p={func:(d,u,x,h,k)=>{const j={method:u,headers:{"X-Replay-Id":x,"Cache-Control":"no-cache, no-store, must-revalidate",Pragma:"no-cache",Expires:"0"},credentials:"include"};if(k&&k.length>0){const P=j.headers;k.forEach(F=>{["content-length","host"].includes(F.name.toLowerCase())||(P[F.name]=F.value)})}h&&["POST","PUT","PATCH"].includes(u.toUpperCase())&&(j.body=h),fetch(d,j).then(async P=>{try{const F=await P.text();let U=`HTTP/1.1 ${P.status} ${P.statusText}\r
`;P.headers.forEach((se,te)=>{U+=`${te}: ${se}\r
`}),U+=`\r
`;const re=U+F;chrome.runtime.sendMessage({action:"replay-fetch-success",replayId:x,response:re}).catch(()=>{})}catch(F){chrome.runtime.sendMessage({action:"replay-fetch-failed",replayId:x,error:F instanceof Error?F.message:String(F)}).catch(()=>{})}}).catch(P=>{console.error(`Injected replay fetch for ${x} failed:`,P),chrome.runtime.sendMessage({action:"replay-fetch-failed",replayId:x,error:P.message}).catch(()=>{})})},args:[f,r,l,t,o]};I(),(async()=>{try{await R.scripting.executeScript({target:{tabId:a.tabId},...p})}catch(d){console.warn(`Injecting script into original tab ${a.tabId} failed. Trying active tab.`,d);try{const[u]=await R.tabs.query({active:!0,currentWindow:!0});if(u&&u.id)await R.scripting.executeScript({target:{tabId:u.id},...p});else throw new Error("No active tab found to initiate replay.")}catch(u){console.error("Failed to inject script into any suitable tab. Aborting replay.",u),T(!0,"重放失败: 无法注入脚本")}}})()}else if(c==="replay-fetch-success"){const{replayId:l,response:f}=e;if(l&&y.has(l)){const r=y.get(l),t=n.findIndex(o=>o.id===r.replayId);t!==-1&&(n[t].rawResponse=f,I()),clearTimeout(r.timeoutId),y.delete(l),w.delete(r.originalId)}}else if(c==="replay-fetch-failed"){const{replayId:l,error:f}=e;if(l&&y.has(l)){const r=y.get(l),t=n.findIndex(o=>o.id===r.replayId);t!==-1&&(n[t].rawResponse=`重放请求失败: ${f||"未知错误"}`,I()),clearTimeout(r.timeoutId),y.delete(l),w.delete(r.originalId)}}else c==="clear-requests"?(n=[],I()):c==="set-mode"&&(v=e.mode,S(i),console.log(`Mode changed to: ${v}`));return!0})});function ne(){}(z=(V=globalThis.browser)==null?void 0:V.runtime)!=null&&z.id?globalThis.browser:globalThis.chrome;function B(i,...v){}const ee={debug:(...i)=>B(console.debug,...i),log:(...i)=>B(console.log,...i),warn:(...i)=>B(console.warn,...i),error:(...i)=>B(console.error,...i)};let O;try{O=Y.main(),O instanceof Promise&&console.warn("The background's main() function return a promise, but it must be synchronous")}catch(i){throw ee.error("The background crashed on startup!"),i}return O}();
background;