aitu-app 0.5.14 → 0.5.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of aitu-app might be problematic. Click here for more details.

Files changed (110) hide show
  1. package/README.md +3 -2
  2. package/assets/{ChatMessagesArea-CkUX81uB.js → ChatMessagesArea-CJPMwgOQ.js} +3 -3
  3. package/assets/{ToolboxDrawer-By1XMh8B.js → ToolboxDrawer-BZkRey45.js} +1 -1
  4. package/assets/{ai-analyze-Db-iXol6.js → ai-analyze-CKKkojLn.js} +1 -1
  5. package/assets/{arc-ajYHRRnk.js → arc-DpZjyIR9.js} +1 -1
  6. package/assets/{arc-BZXVqUcI.js → arc-amy12ZHI.js} +1 -1
  7. package/assets/{batch-image-generation-Baqb01Lm.js → batch-image-generation-CqSButZp.js} +1 -1
  8. package/assets/{blockDiagram-38ab4fdb-BT3H_WVv.js → blockDiagram-38ab4fdb-Bb_sM5Hm.js} +1 -1
  9. package/assets/{blockDiagram-38ab4fdb-u0xYP3Lt.js → blockDiagram-38ab4fdb-DO5SLxgD.js} +1 -1
  10. package/assets/{c4Diagram-3d4e48cf-CBvM6zjM.js → c4Diagram-3d4e48cf-D1hzTotE.js} +1 -1
  11. package/assets/{c4Diagram-3d4e48cf-WOIEVidH.js → c4Diagram-3d4e48cf-IYlxbdWH.js} +1 -1
  12. package/assets/channel-DuH6cax_.js +1 -0
  13. package/assets/channel-V941kNNl.js +1 -0
  14. package/assets/{classDiagram-70f12bd4-Cl9U1r5F.js → classDiagram-70f12bd4-CMCkiBrF.js} +1 -1
  15. package/assets/{classDiagram-70f12bd4-BMutcvFi.js → classDiagram-70f12bd4-C_DG-_VE.js} +1 -1
  16. package/assets/{classDiagram-v2-f2320105-C0agtbR4.js → classDiagram-v2-f2320105-DdbTRsFm.js} +1 -1
  17. package/assets/{classDiagram-v2-f2320105-tCBzATK6.js → classDiagram-v2-f2320105-Y5yPoT7w.js} +1 -1
  18. package/assets/clone-BoLnjeh7.js +1 -0
  19. package/assets/clone-DufRhyQM.js +1 -0
  20. package/assets/{createText-2e5e7dd3-CZ9_fscE.js → createText-2e5e7dd3-DWMoiN14.js} +1 -1
  21. package/assets/{createText-2e5e7dd3-idrqgJjU.js → createText-2e5e7dd3-Q_TpnKHS.js} +1 -1
  22. package/assets/{edges-e0da2a9e-C-RyePMV.js → edges-e0da2a9e-Br_hn5Hn.js} +1 -1
  23. package/assets/{edges-e0da2a9e-DJXAjJSL.js → edges-e0da2a9e-DMfYzMhl.js} +1 -1
  24. package/assets/{erDiagram-9861fffd-x2Kcy95-.js → erDiagram-9861fffd-8s6fny9G.js} +1 -1
  25. package/assets/{erDiagram-9861fffd-DWJR_3zL.js → erDiagram-9861fffd-CslzjwB2.js} +1 -1
  26. package/assets/{flowDb-956e92f1-CF6y18Tn.js → flowDb-956e92f1-BsxQxnaW.js} +1 -1
  27. package/assets/{flowDb-956e92f1-BgKjOIdz.js → flowDb-956e92f1-Bsz7tEUu.js} +1 -1
  28. package/assets/{flowDiagram-66a62f08-CSAllSFf.js → flowDiagram-66a62f08-C0iQ7Eg0.js} +1 -1
  29. package/assets/{flowDiagram-66a62f08-BPPw0wPU.js → flowDiagram-66a62f08-DLXaK0x0.js} +1 -1
  30. package/assets/flowDiagram-v2-96b9c2cf-Be_fSVIi.js +1 -0
  31. package/assets/flowDiagram-v2-96b9c2cf-C-_-kXrI.js +1 -0
  32. package/assets/{flowchart-elk-definition-4a651766-DWFN9DN3.js → flowchart-elk-definition-4a651766-2JQap1Bs.js} +1 -1
  33. package/assets/{flowchart-elk-definition-4a651766-9XSRJbsr.js → flowchart-elk-definition-4a651766-UQLaW6cl.js} +1 -1
  34. package/assets/{ganttDiagram-c361ad54-D9tbz9tQ.js → ganttDiagram-c361ad54-Cfdrec1H.js} +1 -1
  35. package/assets/{ganttDiagram-c361ad54-ot5pUYpT.js → ganttDiagram-c361ad54-hShkYpY_.js} +1 -1
  36. package/assets/{gitGraphDiagram-72cf32ee-C6qFzgGh.js → gitGraphDiagram-72cf32ee-CJw4loHZ.js} +1 -1
  37. package/assets/{gitGraphDiagram-72cf32ee-BFV3Mt8C.js → gitGraphDiagram-72cf32ee-D6obWSUI.js} +1 -1
  38. package/assets/{graph-BxwlF7JS.js → graph-CUK2kA3Q.js} +1 -1
  39. package/assets/{graph-D-2Ldvxg.js → graph-DvHs9g2k.js} +1 -1
  40. package/assets/{grid-image-cM9AmYC8.js → grid-image-DioDaenp.js} +1 -1
  41. package/assets/{has-CgdIPiQG.js → has-C9yYx3eK.js} +1 -1
  42. package/assets/{hasIn-4iY02rGN.js → hasIn-DZErb2GY.js} +1 -1
  43. package/assets/{index-3862675e-CVZnpwDN.js → index-3862675e-CmpgM8FI.js} +1 -1
  44. package/assets/{index-3862675e-DqdI9cab.js → index-3862675e-DIpatAx8.js} +1 -1
  45. package/assets/{index-DBWqXBIQ.js → index-6dh_xpWk.js} +1 -1
  46. package/assets/{index-DWUAFoZG.js → index-BBCAc4Al.js} +9 -9
  47. package/assets/{index-BicRPzXC.js → index-BENzx6Jm.js} +1 -1
  48. package/assets/{index-BwSGXyRr.js → index-CMnHM-d8.js} +4 -4
  49. package/assets/{index-e05Rs4M6.js → index-D6IbVyW6.js} +1 -1
  50. package/assets/{index-CkpXFt8n.js → index-DDjAsbde.js} +1 -1
  51. package/assets/{index-Dn0YtZ2R.js → index-Dg-P8uA3.js} +1 -1
  52. package/assets/{index-CrxF9gFe.js → index-JzVvCLEO.js} +1 -1
  53. package/assets/{infoDiagram-f8f76790-FKC1Sy9Y.js → infoDiagram-f8f76790-DVba3P4U.js} +1 -1
  54. package/assets/{infoDiagram-f8f76790-CnrpwoOt.js → infoDiagram-f8f76790-n-jV57cF.js} +1 -1
  55. package/assets/{inspiration-board-B_-BBBHt.js → inspiration-board--PQTKq9U.js} +1 -1
  56. package/assets/{isEmpty-Dj2GV0v-.js → isEmpty-CRiX5iwN.js} +1 -1
  57. package/assets/{journeyDiagram-49397b02-B7fP21sU.js → journeyDiagram-49397b02-DxSFNQYs.js} +1 -1
  58. package/assets/{journeyDiagram-49397b02-Dp3X9XWq.js → journeyDiagram-49397b02-WGL-3jNv.js} +1 -1
  59. package/assets/{layout-BD3yCK_X.js → layout-25V5jGUW.js} +1 -1
  60. package/assets/{layout-DHHYqX7p.js → layout-CawIP_cF.js} +1 -1
  61. package/assets/{line-B3bNrkzn.js → line-D5ZQcCU6.js} +1 -1
  62. package/assets/{line-B86HLuqu.js → line-DuKdCx_E.js} +1 -1
  63. package/assets/{linear-wCAlMhOS.js → linear-3V_n7zlW.js} +1 -1
  64. package/assets/{linear-DU2Ciymb.js → linear-BlVhwFrV.js} +1 -1
  65. package/assets/{mermaid.core-DfVvnpgz.js → mermaid.core--Np12uGY.js} +4 -4
  66. package/assets/{mindmap-definition-fc14e90a-D1sxE3xG.js → mindmap-definition-fc14e90a-C96nL64E.js} +1 -1
  67. package/assets/{mindmap-definition-fc14e90a-YuSOJC7P.js → mindmap-definition-fc14e90a-UZifAYnn.js} +1 -1
  68. package/assets/{photo-wall-splitter-BVU2e0aS.js → photo-wall-splitter-DZyQuDUg.js} +1 -1
  69. package/assets/{pick-Cvlwra4g.js → pick-B51S9oWq.js} +1 -1
  70. package/assets/{pieDiagram-8a3498a8-B6mJUqro.js → pieDiagram-8a3498a8-B_UU-v6b.js} +1 -1
  71. package/assets/{pieDiagram-8a3498a8-B91bWgo_.js → pieDiagram-8a3498a8-DXEMg8-z.js} +1 -1
  72. package/assets/{quadrantDiagram-120e2f19-BxS8fQEz.js → quadrantDiagram-120e2f19-BpCIEZWH.js} +1 -1
  73. package/assets/{quadrantDiagram-120e2f19-DwudONqx.js → quadrantDiagram-120e2f19-THiHerb8.js} +1 -1
  74. package/assets/{requirementDiagram-deff3bca-DygaMIoy.js → requirementDiagram-deff3bca-BLEvJckC.js} +1 -1
  75. package/assets/{requirementDiagram-deff3bca-v9xlgfS8.js → requirementDiagram-deff3bca-qJ4hHh6O.js} +1 -1
  76. package/assets/{sankeyDiagram-04a897e0-BXCiXiyw.js → sankeyDiagram-04a897e0-C5moR6iD.js} +1 -1
  77. package/assets/{sankeyDiagram-04a897e0-BV23dp4l.js → sankeyDiagram-04a897e0-Clk-gmpQ.js} +1 -1
  78. package/assets/{sequenceDiagram-704730f1-CObRpNi4.js → sequenceDiagram-704730f1-Ch9GmBP7.js} +1 -1
  79. package/assets/{sequenceDiagram-704730f1-Ck69A6wI.js → sequenceDiagram-704730f1-DRHB_a_K.js} +1 -1
  80. package/assets/{settings-dialog-BlCO49C4.js → settings-dialog-Cgmye4jO.js} +1 -1
  81. package/assets/{stateDiagram-587899a1-J_G6I0oo.js → stateDiagram-587899a1-Bu42pkUv.js} +1 -1
  82. package/assets/{stateDiagram-587899a1-z-tKclr3.js → stateDiagram-587899a1-bnuzZWVC.js} +1 -1
  83. package/assets/{stateDiagram-v2-d93cdb3a-DsThtOzP.js → stateDiagram-v2-d93cdb3a-3bX_yI1j.js} +1 -1
  84. package/assets/{stateDiagram-v2-d93cdb3a-XIvq5t8a.js → stateDiagram-v2-d93cdb3a-DLzO3ON3.js} +1 -1
  85. package/assets/{styles-6aaf32cf-1fjuNMUk.js → styles-6aaf32cf-CyzTJ9FB.js} +1 -1
  86. package/assets/{styles-6aaf32cf-DT2rVNfQ.js → styles-6aaf32cf-qL7GgrGp.js} +1 -1
  87. package/assets/{styles-9a916d00-fLeUSina.js → styles-9a916d00-DYu1WXui.js} +1 -1
  88. package/assets/{styles-9a916d00-q64Umkis.js → styles-9a916d00-Dv_u24Fv.js} +1 -1
  89. package/assets/{styles-c10674c1-CtYpjMYU.js → styles-c10674c1-C8mVn82x.js} +1 -1
  90. package/assets/{styles-c10674c1-BWlxVc3Q.js → styles-c10674c1-CBAvChyC.js} +1 -1
  91. package/assets/{svgDrawCommon-08f97a94-C_DhKfny.js → svgDrawCommon-08f97a94-Cma2KGuK.js} +1 -1
  92. package/assets/{svgDrawCommon-08f97a94-DSBqmUv2.js → svgDrawCommon-08f97a94-p3hABH7b.js} +1 -1
  93. package/assets/{timeline-definition-85554ec2-dTkYwoLF.js → timeline-definition-85554ec2-SwmuytFv.js} +1 -1
  94. package/assets/{timeline-definition-85554ec2-AKpzwLPN.js → timeline-definition-85554ec2-XppLsb9g.js} +1 -1
  95. package/assets/{ttd-dialog-CxiaIUuJ.js → ttd-dialog-DeYFjfFN.js} +5 -5
  96. package/assets/{upload-4sxUU7q_.js → upload-B0RQ9yYL.js} +1 -1
  97. package/assets/{video-recovery-service-BckHbSyK.js → video-recovery-service-XnlUYAOr.js} +1 -1
  98. package/assets/{xychartDiagram-e933f94c-DCmvL0ag.js → xychartDiagram-e933f94c-C8xFRDll.js} +1 -1
  99. package/assets/{xychartDiagram-e933f94c-aqOiXp_u.js → xychartDiagram-e933f94c-CedgK1zZ.js} +1 -1
  100. package/index.html +2 -2
  101. package/package.json +1 -1
  102. package/sw.js +1 -1
  103. package/version.json +3 -7
  104. package/versions.html +374 -0
  105. package/assets/channel-BP25wTsw.js +0 -1
  106. package/assets/channel-HzrLNFUg.js +0 -1
  107. package/assets/clone-B69pF7Y_.js +0 -1
  108. package/assets/clone-oX7o-l4R.js +0 -1
  109. package/assets/flowDiagram-v2-96b9c2cf-B-UGyXRi.js +0 -1
  110. package/assets/flowDiagram-v2-96b9c2cf-Cm596kxZ.js +0 -1
package/sw.js CHANGED
@@ -2,7 +2,7 @@
2
2
  `);R=Re.pop()||"";for(const ns of Re)if(ns.startsWith("data: ")){const as=ns.slice(6).trim();if(as==="[DONE]")continue;try{const is=(es=(Zt=(Ae=JSON.parse(as).choices)==null?void 0:Ae[0])==null?void 0:Zt.delta)==null?void 0:es.content;is&&(C+=is,a==null||a(C))}catch{}}}if(R.startsWith("data: ")){const H=R.slice(6).trim();if(H&&H!=="[DONE]")try{const Re=(os=(ss=(ts=JSON.parse(H).choices)==null?void 0:ts[0])==null?void 0:ss.delta)==null?void 0:os.content;Re&&(C+=Re,a==null||a(C))}catch{}}}finally{T.releaseLock()}if(f.__debugLogId&&C){const{updateLogResponseBody:H}=await Promise.resolve().then(()=>P);H(f.__debugLogId,C)}const{completeLLMApiLog:x}=await Promise.resolve().then(()=>L);return x(E,{httpStatus:f.status,duration:Date.now()-p,resultType:"text",resultCount:1,resultText:C}),C}}class Hs{constructor(e,t){this.tasks=new Map,this.runningTasks=new Set,this.geminiConfig=null,this.videoConfig=null,this.initialized=!1,this.chatResultCache=new Map,this.CHAT_CACHE_TTL=60*1e3,this.sw=e,this.config={...cs,...t},this.imageHandler=new qs,this.videoHandler=new Gs,this.characterHandler=new Fs,this.chatHandler=new $s,this.storageRestorePromise=this.restoreFromStorage()}setTaskStatusChangeCallback(e){this.onTaskStatusChange=e}getGeminiConfig(){return this.geminiConfig}getVideoConfig(){return this.videoConfig}getSW(){return this.sw}async restoreFromStorage(){var e;try{const{geminiConfig:t,videoConfig:o}=await y.loadConfig();t&&o&&(this.geminiConfig=t,this.videoConfig=o,this.initialized=!0);const n=await y.getAllTasks();let r=0;for(const a of n){if(a.status===b.COMPLETED&&((e=a.result)!=null&&e.url)&&a.result.url.startsWith("data:image/")){const{url:i,migrated:c}=await Us(a.result.url);c&&(a.result.url=i,await y.updateTask(a),r++)}if(this.tasks.set(a.id,a),a.type===D.CHAT&&a.status===b.PROCESSING){await this.markTaskFailed(a.id,{code:"INTERRUPTED",message:"Chat 请求被中断(页面刷新),请重试"});continue}this.shouldResumeTask(a)&&this.resumeTaskExecution(a)}r>0&&console.log(`[SWTaskQueue] Migrated ${r} Base64 URLs to cache`)}catch(t){console.error("[SWTaskQueue] Failed to restore from storage:",t)}}shouldResumeTask(e){return e.type===D.CHAT&&e.status===b.PROCESSING?!1:!!(e.status===b.PROCESSING||e.status===b.PENDING||(e.type===D.VIDEO||e.type===D.CHARACTER)&&e.status===b.FAILED&&e.remoteId&&this.isNetworkError(e))}isNetworkError(e){var i,c,l,h;const t=((i=e.error)==null?void 0:i.message)||"",o=((l=(c=e.error)==null?void 0:c.details)==null?void 0:l.originalError)||"",n=((h=e.error)==null?void 0:h.code)||"",r=`${t} ${o}`.toLowerCase();return r.includes("generation_failed")||r.includes("invalid_argument")||r.includes("prohibited")||r.includes("content policy")||r.includes("视频生成失败")||n.includes("generation_failed")||n.includes("INVALID")?!1:r.includes("failed to fetch")||r.includes("network")||r.includes("fetch")||r.includes("timeout")||r.includes("aborted")||r.includes("connection")||r.includes("status query failed")}async resumeTaskExecution(e){if(this.initialized){if(e.remoteId&&(e.type===D.VIDEO||e.type===D.CHARACTER))e.status===b.FAILED&&(e.status=b.PROCESSING,e.error=void 0,e.executionPhase=W.POLLING,e.updatedAt=Date.now(),this.tasks.set(e.id,e),await y.saveTask(e)),this.runningTasks.add(e.id),this.broadcastToClients({type:"TASK_STATUS",taskId:e.id,status:b.PROCESSING,progress:e.progress,phase:W.POLLING,updatedAt:e.updatedAt}),this.executeResume(e,e.remoteId);else if(e.status===b.PENDING)this.processQueue();else if((e.type===D.VIDEO||e.type===D.CHARACTER)&&e.status===b.PROCESSING&&!e.remoteId){const{findSuccessLogByTaskId:t}=await Promise.resolve().then(()=>L),o=await t(e.id);if(o&&o.resultUrl){let n,r,a;if(o.responseBody)try{const i=JSON.parse(o.responseBody);n=i.width,r=i.height,a=parseInt(i.seconds||"0")||0}catch{}await this.handleTaskSuccess(e.id,{url:o.resultUrl,format:e.type===D.VIDEO?"mp4":"png",size:0,width:n,height:r,duration:a});return}await this.handleTaskError(e.id,new Error("任务中断且无法恢复(未找到已完成的结果)"))}else if((e.type===D.IMAGE||e.type===D.INSPIRATION_BOARD)&&e.status===b.PROCESSING){const{findSuccessLogByTaskId:t}=await Promise.resolve().then(()=>L),o=await t(e.id);if(o&&o.resultUrl){await this.handleTaskSuccess(e.id,{url:o.resultUrl,format:"png",size:0});return}await this.handleTaskError(e.id,new Error("任务中断且无法恢复(未找到已完成的结果)"))}}}async initialize(e,t){await this.storageRestorePromise,this.geminiConfig=e,this.videoConfig=t,this.initialized=!0,await y.saveConfig(e,t),this.broadcastToClients({type:"TASK_QUEUE_INITIALIZED",success:!0}),this.syncTasksToClients();for(const o of this.tasks.values())this.shouldResumeTask(o)&&!this.runningTasks.has(o.id)&&this.resumeTaskExecution(o);this.processQueue()}async updateConfig(e,t){e&&this.geminiConfig&&(this.geminiConfig={...this.geminiConfig,...e}),t&&this.videoConfig&&(this.videoConfig={...this.videoConfig,...t}),await y.saveConfig(this.geminiConfig,this.videoConfig)}async submitTask(e,t,o,n){if(this.tasks.has(e)){console.warn(`[SWTaskQueue] Task ${e} already exists`);return}const r=Date.now(),a={id:e,type:t,status:b.PENDING,params:o,createdAt:r,updatedAt:r};this.tasks.set(e,a),await y.saveTask(a),this.broadcastToClients({type:"TASK_CREATED",task:a}),this.processQueue()}async cancelTask(e){var o;const t=this.tasks.get(e);t&&(this.runningTasks.has(e)&&((o=this.getHandler(t.type))==null||o.cancel(e),this.runningTasks.delete(e)),t.status=b.CANCELLED,t.updatedAt=Date.now(),this.tasks.set(e,t),await y.saveTask(t),this.broadcastToClients({type:"TASK_CANCELLED",taskId:e}))}async retryTask(e){const t=this.tasks.get(e);!t||t.status!==b.FAILED&&t.status!==b.CANCELLED||(t.status=b.PENDING,t.error=void 0,t.updatedAt=Date.now(),this.tasks.set(e,t),await y.saveTask(t),this.broadcastToClients({type:"TASK_STATUS",taskId:t.id,status:t.status,updatedAt:t.updatedAt}),this.processQueue())}async resumeTask(e,t,o,n){let r=this.tasks.get(e);if(!r){const a=Date.now();r={id:e,type:o,status:b.PROCESSING,params:{prompt:""},createdAt:a,updatedAt:a,remoteId:t,executionPhase:W.POLLING},this.tasks.set(e,r),await y.saveTask(r)}(o===D.VIDEO||o===D.CHARACTER)&&(this.runningTasks.add(e),this.executeResume(r,t))}getTask(e){return this.tasks.get(e)||null}getAllTasks(){return Array.from(this.tasks.values())}async deleteTask(e){var o;const t=this.tasks.get(e);t&&(this.runningTasks.has(e)&&((o=this.getHandler(t.type))==null||o.cancel(e),this.runningTasks.delete(e)),this.tasks.delete(e),await y.deleteTask(e),this.broadcastToClients({type:"TASK_DELETED",taskId:e}))}async markTaskInserted(e){const t=this.tasks.get(e);if(!t)return;const o={...t,insertedToCanvas:!0,updatedAt:Date.now()};this.tasks.set(e,o),await y.saveTask(o)}async restoreTasks(e){for(const t of e)t.status!==b.COMPLETED&&t.status!==b.CANCELLED&&(this.tasks.set(t.id,t),await y.saveTask(t));this.processQueue()}async startChat(e,t,o){if(!this.geminiConfig){this.broadcastToClients({type:"CHAT_ERROR",chatId:e,error:"Gemini config not initialized"});return}try{const n=await this.chatHandler.stream(e,t,this.geminiConfig,a=>{this.broadcastToClients({type:"CHAT_CHUNK",chatId:e,content:a})});this.chatResultCache.set(e,{chatId:e,fullContent:n,timestamp:Date.now(),delivered:!1}),this.broadcastToClients({type:"CHAT_DONE",chatId:e,fullContent:n});const r=this.chatResultCache.get(e);r&&(r.delivered=!0),this.cleanupChatCache()}catch(n){this.broadcastToClients({type:"CHAT_ERROR",chatId:e,error:n instanceof Error?n.message:String(n)})}}getCachedChatResult(e){return this.chatResultCache.get(e)}getAllCachedChatResults(){return Array.from(this.chatResultCache.values())}cleanupChatCache(){const e=Date.now();for(const[t,o]of this.chatResultCache.entries())e-o.timestamp>this.CHAT_CACHE_TTL&&this.chatResultCache.delete(t)}stopChat(e){this.chatHandler.stop(e)}syncTasksToClients(){const e=this.getAllTasks();this.broadcastToClients({type:"TASK_ALL_RESPONSE",tasks:e})}async getTasksPaginated(e){return y.getTasksPaginated(e)}async syncPaginatedTasksToClients(e){const t=await this.getTasksPaginated(e);this.broadcastToClients({type:"TASK_PAGINATED_RESPONSE",tasks:t.tasks,total:t.total,offset:e.offset,hasMore:t.hasMore})}processQueue(){if(!this.initialized){console.warn("[SWTaskQueue] Not initialized, skipping queue processing");return}const e=Array.from(this.tasks.values()).filter(t=>t.status===b.PENDING).sort((t,o)=>t.createdAt-o.createdAt);for(const t of e)this.executeTask(t)}async executeTask(e){if(!this.geminiConfig||!this.videoConfig){console.warn("[SWTaskQueue] Config not set, cannot execute task:",e.id);return}this.runningTasks.add(e.id),e.status=b.PROCESSING,e.startedAt=Date.now(),e.updatedAt=Date.now(),e.executionPhase=W.SUBMITTING,this.tasks.set(e.id,e),await y.saveTask(e),this.broadcastToClients({type:"TASK_STATUS",taskId:e.id,status:e.status,phase:e.executionPhase,updatedAt:e.updatedAt});const t={geminiConfig:this.geminiConfig,videoConfig:this.videoConfig,onProgress:async(o,n,r)=>{const a=this.tasks.get(o);if(a&&a.status!==b.COMPLETED&&a.status!==b.FAILED&&a.status!==b.CANCELLED){const i=a.status;a.progress=n,r&&(a.executionPhase=r),a.updatedAt=Date.now(),this.tasks.set(o,a),await y.saveTask(a);const c=this.tasks.get(o);c&&c.status===i&&this.broadcastToClients({type:"TASK_STATUS",taskId:o,status:i,progress:n,phase:r,updatedAt:a.updatedAt})}},onRemoteId:async(o,n)=>{const r=this.tasks.get(o);r&&(r.remoteId=n,r.executionPhase=W.POLLING,r.updatedAt=Date.now(),this.tasks.set(o,r),await y.saveTask(r),this.broadcastToClients({type:"TASK_SUBMITTED",taskId:o,remoteId:n}))}};try{const o=this.getHandler(e.type);if(!o)throw new Error(`No handler for task type: ${e.type}`);const n=this.config.timeouts[e.type]||600*1e3,r=await Promise.race([o.execute(e,t),new Promise((a,i)=>{setTimeout(()=>{var c;(c=o.cancel)==null||c.call(o,e.id),i(new Error(`Task timeout after ${Math.round(n/6e4)} minutes`))},n)})]);await this.handleTaskSuccess(e.id,r)}catch(o){await this.handleTaskError(e.id,o)}}async executeResume(e,t){if(!this.geminiConfig||!this.videoConfig)return;const o={geminiConfig:this.geminiConfig,videoConfig:this.videoConfig,onProgress:async(n,r,a)=>{const i=this.tasks.get(n);if(i&&i.status!==b.COMPLETED&&i.status!==b.FAILED&&i.status!==b.CANCELLED){const c=i.status;i.progress=r,a&&(i.executionPhase=a),i.updatedAt=Date.now(),this.tasks.set(n,i),await y.saveTask(i);const l=this.tasks.get(n);l&&l.status===c&&this.broadcastToClients({type:"TASK_STATUS",taskId:n,status:c,progress:r,phase:a,updatedAt:i.updatedAt})}},onRemoteId:()=>{}};try{const n=this.getHandler(e.type);if(!(n!=null&&n.resume))throw new Error(`Handler does not support resume: ${e.type}`);e.remoteId=t;const r=await n.resume(e,o);await this.handleTaskSuccess(e.id,r)}catch(n){console.error(`[SWTaskQueue] executeResume: 任务 ${e.id} 恢复失败`,n),await this.handleTaskError(e.id,n)}}async handleTaskSuccess(e,t){var n;const o=this.tasks.get(e);o&&(o.status=b.COMPLETED,o.result=t,o.completedAt=Date.now(),o.updatedAt=Date.now(),o.executionPhase=void 0,this.tasks.set(e,o),this.runningTasks.delete(e),await y.saveTask(o),this.broadcastToClients({type:"TASK_COMPLETED",taskId:e,result:t,completedAt:o.completedAt}),(n=this.onTaskStatusChange)==null||n.call(this,e,"completed",t),this.processQueue())}async handleTaskError(e,t){var r;const o=this.tasks.get(e);if(!o)return;this.runningTasks.delete(e);const n={code:"EXECUTION_ERROR",message:t instanceof Error?t.message:String(t),details:{originalError:t instanceof Error?t.stack:String(t),timestamp:Date.now()}};o.status=b.FAILED,o.error=n,o.updatedAt=Date.now(),this.tasks.set(e,o),await y.saveTask(o),this.broadcastToClients({type:"TASK_FAILED",taskId:e,error:n}),(r=this.onTaskStatusChange)==null||r.call(this,e,"failed",void 0,n.message),this.processQueue()}async markTaskFailed(e,t){const o=this.tasks.get(e);o&&(o.status=b.FAILED,o.error=t,o.updatedAt=Date.now(),this.tasks.set(e,o),await y.saveTask(o),this.broadcastToClients({type:"TASK_FAILED",taskId:e,error:t}))}getHandler(e){switch(e){case D.IMAGE:case D.INSPIRATION_BOARD:return this.imageHandler;case D.VIDEO:return this.videoHandler;case D.CHARACTER:return this.characterHandler;case D.CHAT:return this.chatHandler;default:return null}}async broadcastToClients(e){try{const t=await this.sw.clients.matchAll({type:"window"});for(const o of t)wt(o,e)}catch(t){console.error("[SWTaskQueue] Failed to broadcast:",t)}}}let xe=null;function zs(s,e){return xe||(xe=new Hs(s,e)),xe}function je(){return xe}function Ks(s,e){var o,n;const t=je();if(!t&&s.type!=="TASK_QUEUE_INIT"){console.warn("[SWTaskQueue] Queue not initialized");return}switch(s.type){case"TASK_QUEUE_INIT":t&&t.initialize(s.geminiConfig,s.videoConfig);break;case"TASK_QUEUE_UPDATE_CONFIG":t==null||t.updateConfig(s.geminiConfig,s.videoConfig);break;case"TASK_SUBMIT":t==null||t.submitTask(s.taskId,s.taskType,s.params,e);break;case"TASK_CANCEL":t==null||t.cancelTask(s.taskId);break;case"TASK_RETRY":t==null||t.retryTask(s.taskId);break;case"TASK_RESUME":t==null||t.resumeTask(s.taskId,s.remoteId,s.taskType,e);break;case"TASK_GET_STATUS":{t==null||t.syncTasksToClients();break}case"TASK_GET_ALL":{t==null||t.syncTasksToClients();break}case"TASK_GET_PAGINATED":{t==null||t.syncPaginatedTasksToClients({offset:s.offset,limit:s.limit,status:(o=s.filters)==null?void 0:o.status,type:(n=s.filters)==null?void 0:n.type,sortOrder:s.sortOrder});break}case"TASK_DELETE":t==null||t.deleteTask(s.taskId);break;case"TASK_MARK_INSERTED":t==null||t.markTaskInserted(s.taskId);break;case"CHAT_START":t==null||t.startChat(s.chatId,s.params,e);break;case"CHAT_STOP":t==null||t.stopChat(s.chatId);break;case"CHAT_GET_CACHED":{const r=t==null?void 0:t.getCachedChatResult(s.chatId);r?Ie(e,{type:"CHAT_CACHED_RESULT",chatId:s.chatId,fullContent:r.fullContent,found:!0}).then(a=>{a||console.warn("[SWTaskQueue] Failed to send CHAT_CACHED_RESULT to client:",e)}):Ie(e,{type:"CHAT_CACHED_RESULT",chatId:s.chatId,found:!1}).then(a=>{a||console.warn("[SWTaskQueue] Failed to send CHAT_CACHED_RESULT (not found) to client:",e)});break}case"TASK_RESTORE":t==null||t.restoreTasks(s.tasks);break;case"MCP_TOOL_EXECUTE":{Promise.resolve().then(()=>yr).then(({executeMCPTool:r})=>{const a=je(),i=a==null?void 0:a.getGeminiConfig(),c=a==null?void 0:a.getVideoConfig(),l=a==null?void 0:a.getSW();a&&i&&c&&l?r(s.requestId,s.toolName,s.args,i,c,e,l):l==null||l.clients.get(e).then(h=>{h&&h.postMessage({type:"MCP_TOOL_RESULT",requestId:s.requestId,success:!1,error:"Task queue not initialized",resultType:"error"})})});break}}}const js={name:"generate_image",description:"Generate images using AI",async execute(s,e){const{geminiConfig:t,onProgress:o,signal:n}=e,{prompt:r,size:a,referenceImages:i,quality:c,model:l,count:h=1}=s;if(!r)return{success:!1,error:"缺少必填参数 prompt",type:"error"};try{o==null||o(0,W.SUBMITTING);const m=Ct({prompt:r,model:l,size:a,referenceImages:i,quality:c,n:Math.min(Math.max(1,h),10)},t.modelName);o==null||o(10,W.SUBMITTING);const{debugFetch:S}=await Promise.resolve().then(()=>P),w=await S(`${t.baseUrl}/images/generations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t.apiKey}`},body:JSON.stringify(m),signal:n},{label:`🎨 生成图片 (${t.modelName})`,logRequestBody:!0,logResponseBody:!0});if(!w.ok){const f=await w.text();throw console.error("[SW:generateImage] ✗ API error:",w.status,f.substring(0,200)),new Error(`Image generation failed: ${w.status} - ${f}`)}o==null||o(80,W.DOWNLOADING);const g=await w.json(),{url:d,urls:u}=await bt(g);return o==null||o(100),{success:!0,type:"image",data:{url:d,urls:u,format:"png",prompt:r,size:a||"1x1"}}}catch(m){return console.error("[SW:generateImage] Error:",m),{success:!1,error:m.message||"图片生成失败",type:"error"}}}},Vs={name:"generate_video",description:"Generate videos using AI",async execute(s,e){const{videoConfig:t,onProgress:o,onRemoteId:n,signal:r}=e,{prompt:a,model:i="veo3",seconds:c="8",size:l="1280x720",inputReference:h,inputReferences:m,referenceImages:S}=s;if(!a)return{success:!1,error:"缺少必填参数 prompt",type:"error"};try{o==null||o(0,W.SUBMITTING);const w={model:i,prompt:a,seconds:c,size:l},g=[];m&&m.length>0?m.forEach(T=>{const _=typeof T=="string"?T:T==null?void 0:T.url;_&&g.push(_)}):S&&S.length>0?g.push(...S):h&&g.push(h),g.length>0&&(g.length===1?w.input_reference=g[0]:w.input_references=g);const{debugFetch:d}=await Promise.resolve().then(()=>P),u=await d(`${t.baseUrl}/videos/generations`,{method:"POST",headers:{"Content-Type":"application/json",...t.apiKey?{Authorization:`Bearer ${t.apiKey}`}:{}},body:JSON.stringify(w),signal:r},{label:`🎬 提交视频生成 (${t.model||"default"})`,logRequestBody:!0,logResponseBody:!0});if(!u.ok){const T=await u.text();throw console.error("[SW:generateVideo] ✗ Submit failed:",u.status,T.substring(0,200)),new Error(`Video submission failed: ${u.status} - ${T}`)}const f=await u.json(),p=f.id||f.video_id;if(!p)throw console.error("[SW:generateVideo] ✗ No video ID in response:",f),new Error("No video ID in response");n==null||n(p),o==null||o(10,W.POLLING);const E=await Tt(t.baseUrl,p,{onProgress:o,signal:r,apiKey:t.apiKey});return{success:!0,type:"video",data:{url:E.video_url||E.url,format:"mp4",prompt:a,duration:parseInt(E.seconds||"")||parseInt(c)}}}catch(w){return console.error("[SW:generateVideo] ✗ Error:",w.message),{success:!1,error:w.message||"视频生成失败",type:"error"}}}},At=new Map([["generate_image",js],["generate_video",Vs]]);function Rt(s){return At.get(s)}async function Ve(s,e,t){const o=At.get(s);return o?o.execute(e,t):{success:!1,error:`Unknown tool: ${s}`,type:"error"}}function Qe(s){return["canvas_insert","insert_to_canvas","insert_mermaid","insert_mindmap","insert_svg","ai_analyze","generate_image","generate_video","generate_grid_image","generate_inspiration_board","split_image","generate_long_video"].includes(s)}class Qs{constructor(e){this.workflows=new Map,this.runningWorkflows=new Set,this.abortControllers=new Map,this.pendingToolRequests=new Map,this.config=e,this.restoreFromStorage()}async restoreFromStorage(){try{const e=await y.getAllWorkflows();for(const t of e){if(t.status==="completed"||t.status==="cancelled"||t.status==="failed"){this.workflows.set(t.id,t);continue}(t.status==="running"||t.status==="pending")&&await this.handleInterruptedWorkflow(t)}}catch(e){console.error("[WorkflowExecutor] Failed to restore from storage:",e)}}async handleInterruptedWorkflow(e){const t=e.steps.find(o=>o.status==="running");e.status="failed",e.error=t?`工作流在步骤 "${t.description||t.mcp}" 执行时中断,请重试`:"工作流执行时中断,请重试",e.updatedAt=Date.now(),t&&(t.status="failed",t.error="Service Worker 重启导致执行中断"),this.workflows.set(e.id,e),await y.saveWorkflow(e),await y.deletePendingToolRequestsByWorkflow(e.id)}updateConfig(e){this.config={...this.config,...e}}async handleMainThreadToolResponse(e){var o;console.log("[SW-WorkflowExecutor] ◀ Received tool response:",{requestId:e.requestId,success:e.success,hasPending:this.pendingToolRequests.has(e.requestId),hasAddSteps:!!((o=e.addSteps)!=null&&o.length),timestamp:new Date().toISOString()});const t=this.pendingToolRequests.get(e.requestId);if(t)console.log("[SW-WorkflowExecutor] ✓ Resolving pending tool request:",e.requestId),this.pendingToolRequests.delete(e.requestId),t.resolve(e);else{console.log("[SW-WorkflowExecutor] Tool response received after SW restart, attempting recovery:",e.requestId);const n=await y.getPendingToolRequest(e.requestId);if(!n){console.log("[SW-WorkflowExecutor] No stored request found for:",e.requestId);return}console.log("[SW-WorkflowExecutor] Found stored request:",{workflowId:n.workflowId,stepId:n.stepId,toolName:n.toolName});let r=this.workflows.get(n.workflowId);if(r||(r=await y.getWorkflow(n.workflowId),r&&this.workflows.set(r.id,r)),!r){console.log("[SW-WorkflowExecutor] Workflow not found:",n.workflowId),await y.deletePendingToolRequest(e.requestId);return}const a=r.steps.find(i=>i.id===n.stepId);if(!a){console.log("[SW-WorkflowExecutor] Step not found:",n.stepId),await y.deletePendingToolRequest(e.requestId);return}if(e.success){a.status="completed",a.result={success:!0,type:"text",data:e.result};const i=e.addSteps;if(i&&i.length>0){console.log("[SW-WorkflowExecutor] Adding",i.length,"new steps from recovered response");const c=[];for(const l of i)r.steps.find(h=>h.id===l.id)||(r.steps.push({id:l.id,mcp:l.mcp,args:l.args,description:l.description,status:l.status||"pending"}),c.push(l));c.length>0&&this.config.broadcast({type:"WORKFLOW_STEPS_ADDED",workflowId:r.id,steps:c})}await y.saveWorkflow(r),this.config.broadcast({type:"WORKFLOW_STEP_STATUS",workflowId:r.id,stepId:a.id,status:"completed",result:a.result})}else{a.status="failed",a.error=e.error||"Unknown error",a.result={success:!1,type:"error",error:a.error},await y.saveWorkflow(r),this.config.broadcast({type:"WORKFLOW_STEP_STATUS",workflowId:r.id,stepId:a.id,status:"failed",error:a.error}),this.config.broadcast({type:"WORKFLOW_FAILED",workflowId:r.id,error:a.error}),await y.deletePendingToolRequest(e.requestId);return}await y.deletePendingToolRequest(e.requestId),console.log("[SW-WorkflowExecutor] Continuing workflow execution after recovery:",r.id),await this.executeWorkflow(r)}}async updateWorkflowStepForTask(e,t,o,n){for(const r of this.workflows.values()){const a=r.steps.find(i=>{var l;const c=i.result;return(c==null?void 0:c.taskId)===e||((l=c==null?void 0:c.taskIds)==null?void 0:l.includes(e))});if(a){a.status=t,t==="completed"&&o?a.result={...a.result,success:!0,data:o}:t==="failed"&&(a.error=n,a.result={...a.result,success:!1,error:n}),a.updatedAt=Date.now(),r.updatedAt=Date.now(),await y.saveWorkflow(r),this.broadcastStepStatus(r.id,a),r.status==="running"&&this.executeWorkflow(r.id);return}}}broadcastRecoveredWorkflows(){for(const e of this.workflows.values())this.config.broadcast({type:"WORKFLOW_RECOVERED",workflowId:e.id,workflow:e})}resendPendingToolRequests(){if(this.pendingToolRequests.size===0)return;const e=[];console.log("[SW-WorkflowExecutor] resendPendingToolRequests:",{pendingCount:this.pendingToolRequests.size,pendingTools:Array.from(this.pendingToolRequests.values()).map(t=>({toolName:t.requestInfo.toolName,workflowId:t.requestInfo.workflowId})),timestamp:new Date().toISOString()});for(const[,t]of this.pendingToolRequests){const{requestInfo:o}=t;if(e.includes(o.toolName)){console.log("[SW-WorkflowExecutor] Skipping resend for tool (already in progress):",{toolName:o.toolName,workflowId:o.workflowId,requestId:o.requestId});continue}this.config.broadcast({type:"MAIN_THREAD_TOOL_REQUEST",requestId:o.requestId,workflowId:o.workflowId,stepId:o.stepId,toolName:o.toolName,args:o.args})}}cancelAllPendingToolRequests(){if(this.pendingToolRequests.size!==0){for(const[e,t]of this.pendingToolRequests)t.reject(new Error("页面刷新导致请求中断,请重试"));this.pendingToolRequests.clear()}}async submitWorkflow(e){var o,n;console.log("[SW-WorkflowExecutor] submitWorkflow:",{workflowId:e.id,existingWorkflowsCount:this.workflows.size,hasContext:!!e.context,referenceImagesCount:((n=(o=e.context)==null?void 0:o.referenceImages)==null?void 0:n.length)||0,timestamp:new Date().toISOString()});const t=this.workflows.get(e.id);if(t){if(t.status==="running"||t.status==="pending"){console.log(`[SW-WorkflowExecutor] Re-claiming active workflow ${e.id}, status: ${t.status}`),this.broadcastWorkflowStatus(t),t.steps.forEach(r=>this.broadcastStepStatus(t.id,r));return}console.warn(`[SW-WorkflowExecutor] Workflow ${e.id} already exists with terminal status ${t.status}, skipping`),this.broadcastWorkflowStatus(t);return}console.log("[SW-WorkflowExecutor] ✓ New workflow, starting execution:",e.id),e.status="pending",e.updatedAt=Date.now(),this.workflows.set(e.id,e),await y.saveWorkflow(e),this.executeWorkflow(e.id)}async cancelWorkflow(e){const t=this.workflows.get(e);if(!t)return;const o=this.abortControllers.get(e);o&&(o.abort(),this.abortControllers.delete(e)),t.status="cancelled",t.updatedAt=Date.now(),this.runningWorkflows.delete(e),await y.saveWorkflow(t),await y.deletePendingToolRequestsByWorkflow(e),this.broadcastWorkflowStatus(t)}getWorkflow(e){return this.workflows.get(e)}getAllWorkflows(){return Array.from(this.workflows.values())}async executeWorkflow(e){console.log("[SW-WorkflowExecutor] executeWorkflow called:",{workflowId:e,timestamp:new Date().toISOString()});const t=this.workflows.get(e);if(!t){console.error(`[WorkflowExecutor] ✗ Workflow ${e} not found`);return}if(this.runningWorkflows.has(e)){console.warn(`[SW-WorkflowExecutor] Workflow ${e} is already running, skipping duplicate execution`);return}this.runningWorkflows.add(e),console.log(`[SW-WorkflowExecutor] ▶ Starting workflow execution: ${e}`);const o=new AbortController;this.abortControllers.set(e,o),t.status="running",t.updatedAt=Date.now(),await y.saveWorkflow(t),this.broadcastWorkflowStatus(t);try{let n=0;for(;;){const a=t.steps.filter(c=>c.status==="completed"||c.status==="failed"||c.status==="skipped"||c.status==="running"?!1:c.dependsOn&&c.dependsOn.length>0?c.dependsOn.every(l=>{const h=t.steps.find(m=>m.id===l);return h&&(h.status==="completed"||h.status==="skipped")}):!0),i=t.steps.some(c=>c.status==="running");if(a.length===0){if(i||t.steps.every(l=>l.status==="completed"||l.status==="failed"||l.status==="skipped"))break;console.warn("[WorkflowExecutor] Workflow stuck: no executable steps and none running");break}for(const c of a){if(o.signal.aborted)throw new Error("Workflow cancelled");if(n++,await this.executeStep(t,c,o.signal),c.status==="failed")throw console.error(`[WorkflowExecutor] ✗ Step ${c.id} failed: ${c.error}`),new Error(`Step ${c.id} failed: ${c.error}`);c.status}}t.steps.every(a=>a.status==="completed"||a.status==="failed"||a.status==="skipped")?(t.status="completed",t.completedAt=Date.now(),t.updatedAt=Date.now(),await y.saveWorkflow(t),this.config.broadcast({type:"WORKFLOW_COMPLETED",workflowId:e,workflow:t})):await y.saveWorkflow(t)}catch(n){console.error(`[WorkflowExecutor] ✗ Workflow ${e} failed:`,n),t.status="failed",t.error=n.message,t.updatedAt=Date.now(),await y.saveWorkflow(t),this.config.broadcast({type:"WORKFLOW_FAILED",workflowId:e,error:n.message})}finally{this.runningWorkflows.delete(e),this.abortControllers.delete(e)}}replaceImagePlaceholders(e,t){if(!t||t.length===0)return e;const o=n=>{if(typeof n=="string"){let r=n.replace(/\[图片(\d+)\]/g,(a,i)=>{const c=parseInt(i,10)-1;return c>=0&&c<t.length?t[c]:a});return r=r.replace(/\[Image\s*(\d+)\]/gi,(a,i)=>{const c=parseInt(i,10)-1;return c>=0&&c<t.length?t[c]:a}),r}if(Array.isArray(n))return n.map(r=>o(r));if(n&&typeof n=="object"){const r={};for(const[a,i]of Object.entries(n))r[a]=o(i);return r}return n};return o(e)}async executeStep(e,t,o){var l,h,m,S,w,g;console.log("[SW-WorkflowExecutor] executeStep:",{workflowId:e.id,stepId:t.id,mcp:t.mcp,hasContext:!!e.context,referenceImagesCount:((h=(l=e.context)==null?void 0:l.referenceImages)==null?void 0:h.length)||0,timestamp:new Date().toISOString()});const n=Date.now(),r=((m=e.context)==null?void 0:m.referenceImages)||[];(t.mcp==="generate_image"||t.mcp==="generate_video")&&console.log("[SW-WorkflowExecutor] Image/Video step args before processing:",{stepId:t.id,referenceImagesInContext:r.length,referenceImagesValues:r.slice(0,2).map(d=>d.substring(0,50)+"..."),argsReferenceImages:t.args.referenceImages});const a=this.replaceImagePlaceholders(t.args,r),i=JSON.stringify(t.args),c=JSON.stringify(a);i!==c?(console.log("[SW-WorkflowExecutor] ✓ Replaced image placeholders:",{stepId:t.id,referenceImagesCount:r.length}),t.args=a):r.length>0&&(t.mcp==="generate_image"||t.mcp==="generate_video")&&console.log("[SW-WorkflowExecutor] No placeholders replaced (args unchanged):",{stepId:t.id,referenceImagesCount:r.length}),t.status="running",await y.saveWorkflow(e),this.broadcastStepStatus(e.id,t);try{if(Qe(t.mcp)||!Rt(t.mcp)){const d=await this.requestMainThreadTool(e.id,t.id,t.mcp,t.args);if(!d.success)throw new Error(d.error||"Main thread tool execution failed");if(d.addSteps&&d.addSteps.length>0){const f=[];for(const p of d.addSteps)e.steps.find(E=>E.id===p.id)||(e.steps.push({id:p.id,mcp:p.mcp,args:p.args,description:p.description,status:p.status}),f.push(p));f.length>0&&(await y.saveWorkflow(e),this.config.broadcast({type:"WORKFLOW_STEPS_ADDED",workflowId:e.id,steps:f}))}const u=d.result;if((t.mcp==="generate_image"||t.mcp==="generate_video")&&d.taskId){t.result={success:!0,type:t.mcp==="generate_image"?"image":"video",data:u,taskId:d.taskId,taskIds:d.taskIds},t.status="running",t.duration=Date.now()-n,this.broadcastStepStatus(e.id,t);return}t.result={success:!0,type:(u==null?void 0:u.type)||"text",data:u}}else{const d={geminiConfig:this.config.geminiConfig,videoConfig:this.config.videoConfig,signal:o,onProgress:(f,p)=>{},onRemoteId:f=>{}},u=await Ve(t.mcp,t.args,d);if(u.success&&u.type==="canvas"&&((S=u.data)!=null&&S.delegateToMainThread)){const f=await this.requestCanvasOperation(u.data.operation,u.data.args);if(!f.success)throw new Error(f.error||"Canvas operation failed");t.result={success:!0,type:"canvas",data:{completed:!0}}}else if(u.success&&u.type==="image"&&((w=u.data)!=null&&w.url)){const f=u.data,p=await this.requestCanvasOperation("canvas_insert",{items:[{type:"image",url:f.url}]});p.success||console.warn("[WorkflowExecutor] Failed to insert image to canvas:",p.error),t.result={success:!0,type:"image",data:u.data}}else if(u.success&&u.type==="video"&&((g=u.data)!=null&&g.url)){const f=u.data,p=await this.requestCanvasOperation("canvas_insert",{items:[{type:"video",url:f.url}]});p.success||console.warn("[WorkflowExecutor] Failed to insert video to canvas:",p.error),t.result={success:!0,type:"video",data:u.data}}else if(t.result={success:u.success,type:u.type||"text",data:u.data,error:u.error},!u.success)throw new Error(u.error||"Step execution failed");if(u.addSteps&&u.addSteps.length>0){console.log(`[SW-WorkflowExecutor] Adding ${u.addSteps.length} new steps from ${t.mcp}`);const f=[];for(const p of u.addSteps)e.steps.find(E=>E.id===p.id)||(e.steps.push({id:p.id,mcp:p.mcp,args:p.args,description:p.description,status:p.status}),f.push(p));f.length>0&&this.config.broadcast({type:"WORKFLOW_STEPS_ADDED",workflowId:e.id,steps:f})}}t.status="completed",t.duration=Date.now()-n}catch(d){t.status="failed",t.error=d.message,t.duration=Date.now()-n,t.result={success:!1,type:"error",error:d.message}}await y.saveWorkflow(e),this.broadcastStepStatus(e.id,t)}async requestMainThreadTool(e,t,o,n){if(this.config.requestMainThreadTool)return this.config.requestMainThreadTool(e,t,o,n);const r=`tool_${Date.now()}_${Math.random().toString(36).slice(2,11)}`;return new Promise((a,i)=>{const c=setTimeout(()=>{this.pendingToolRequests.delete(r),i(new Error(`Main thread tool request timed out: ${o}`))},3e5);this.pendingToolRequests.set(r,{resolve:l=>{clearTimeout(c),y.deletePendingToolRequest(r),a(l)},reject:l=>{clearTimeout(c),y.deletePendingToolRequest(r),i(l)},requestInfo:{requestId:r,workflowId:e,stepId:t,toolName:o,args:n},timeout:c}),y.savePendingToolRequest({requestId:r,workflowId:e,stepId:t,toolName:o,args:n,createdAt:Date.now()}),this.config.broadcast({type:"MAIN_THREAD_TOOL_REQUEST",requestId:r,workflowId:e,stepId:t,toolName:o,args:n})})}async requestCanvasOperation(e,t){if(this.config.requestCanvasOperation)return this.config.requestCanvasOperation(e,t);const o=`canvas_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;return this.config.broadcast({type:"CANVAS_OPERATION_REQUEST",requestId:o,operation:e,params:t}),{success:!0}}broadcastWorkflowStatus(e){this.config.broadcast({type:"WORKFLOW_STATUS",workflowId:e.id,status:e.status,updatedAt:e.updatedAt})}broadcastStepStatus(e,t){this.config.broadcast({type:"WORKFLOW_STEP_STATUS",workflowId:e,stepId:t.id,status:t.status,result:t.result,error:t.error,duration:t.duration})}}function Wt(s=0){return`tc_${Date.now()}_${s}_${Math.random().toString(36).substr(2,9)}`}function te(s){const e=s.trim();try{return JSON.parse(e)}catch{try{return JSON.parse(Zs(e))}catch{return null}}}function Dt(s){let e=s;return e=e.replace(/<think>[\s\S]*?<\/think>\s*/gi,""),e=e.replace(/```(?:json)?\s*\n?/gi,"").replace(/\n?```/gi,""),e.trim()}function Xs(s){const e=s.trim();if(!e.startsWith("{")||!e.endsWith("}")||!e.includes('"content"')||!e.includes('"next"'))return!1;let t=0,o=0,n=!1,r=!1;for(const a of e){if(r){r=!1;continue}if(a==="\\"){r=!0;continue}if(a==='"'){n=!n;continue}n||(a==="{"?t++:a==="}"?t--:a==="["?o++:a==="]"&&o--)}return t===0&&o===0}function Lt(s){const e=Dt(s);if(!Xs(e))return null;let t=te(e);if(!t){const r=e.match(/\{\s*"content"\s*:\s*"[^"]*"\s*,\s*"next"\s*:\s*\[[\s\S]*?\]\s*\}/);r&&(t=te(r[0]))}if(!t){const r=e.match(/\{[\s\S]*"content"[\s\S]*"next"[\s\S]*\}/);r&&(t=te(r[0]))}if(!t||typeof t.content!="string")return null;const n=(Array.isArray(t.next)?t.next:[]).filter(r=>typeof r=="object"&&r!==null&&typeof r.mcp=="string"&&typeof r.args=="object").map(r=>({mcp:r.mcp,args:r.args}));return{content:t.content,next:n}}function Js(s){const e=Lt(s);if(e&&e.next.length>0)return e.next.map((a,i)=>({id:Wt(i),name:a.mcp,arguments:a.args}));const t=[],o=a=>{if(!a.name||typeof a.name!="string")return null;const i=a.arguments||a.params||a.parameters||{};return{id:Wt(),name:a.name,arguments:typeof i=="object"&&i!==null?i:{}}},n=/```tool_call\s*\n?([\s\S]*?)\n?```/gi;let r;for(;(r=n.exec(s))!==null;){const a=te(r[1]);if(a){const i=o(a);i&&t.push(i)}}if(t.length===0){const a=/```(?:json)?\s*\n?([\s\S]*?)\n?```/gi;for(;(r=a.exec(s))!==null;){const i=te(r[1]);if(i){const c=o(i);c&&t.push(c)}}}if(t.length===0){const a=/<tool_call>([\s\S]*?)<\/tool_call>/gi;for(;(r=a.exec(s))!==null;){const i=te(r[1]);if(i){const c=o(i);c&&t.push(c)}}}if(t.length===0){const a=/\{[\s\S]*?"name"\s*:\s*"(?:generate_image|generate_video|generate_grid_image|generate_photo_wall)"[\s\S]*?\}/g;for(;(r=a.exec(s))!==null;){const i=te(r[0]);if(i){const c=o(i);if(c){t.push(c);break}}}}return t}function Ys(s){const e=Lt(s);if(e)return e.content;let t=Dt(s);return t=t.replace(/```tool_call\s*\n?[\s\S]*?\n?```/gi,""),t=t.replace(/<tool_call>[\s\S]*?<\/tool_call>/gi,""),t=t.replace(/```(?:json)?\s*\n?\s*\{\s*"name"\s*:[\s\S]*?\n?```/gi,""),t=t.replace(/\{\s*"content"\s*:\s*"[^"]*"\s*,\s*"next"\s*:\s*\[[\s\S]*?\]\s*\}/gi,""),t=t.replace(/\n{3,}/g,`
3
3
 
4
4
  `),t.trim()}function Zs(s){let e=s.trim();const t=e.indexOf("{");t>0&&(e=e.substring(t));const o=e.lastIndexOf("}");return o<e.length-1&&o>0&&(e=e.substring(0,o+1)),e=e.replace(/:\s*"([^"]*)\n([^"]*)"/g,(n,r,a)=>`: "${r}\\n${a}"`),e=e.replace(/'([^']*?)'/g,(n,r)=>!r.includes(":")||r.length>50?`"${r}"`:n),e=e.replace(/([{,]\s*)(\w+)(\s*:)/g,'$1"$2"$3'),e=e.replace(/,(\s*[}\]])/g,"$1"),e=e.replace(/,\s*,/g,","),e=e.replace(/\/\/[^\n]*/g,""),e=e.replace(/\/\*[\s\S]*?\*\//g,""),e=e.replace(/:\s*undefined\b/g,": null"),e}function eo(s){return Js(s).map(t=>({...t,status:"pending"}))}class to{constructor(e){this.workflows=new Map,this.abortControllers=new Map,this.workflowClients=new Map,this.pendingToolRequests=new Map,this.storageRestored=!1,this.config=e,this.restoreFromStorage()}async restoreFromStorage(){try{const e=await y.getAllChatWorkflows();for(const t of e){if(t.status==="completed"||t.status==="cancelled"||t.status==="failed"){this.workflows.set(t.id,t);continue}await this.handleInterruptedWorkflow(t)}this.storageRestored=!0}catch(e){console.error("[ChatWorkflowHandler] Failed to restore from storage:",e),this.storageRestored=!0}}async handleInterruptedWorkflow(e){let t;switch(e.status){case"streaming":t="AI 响应流传输时中断,请重试";break;case"parsing":t="工具调用解析时中断,请重试";break;case"executing_tools":t="工具执行时中断,请重试";break;case"pending":t="工作流尚未开始执行,请重试";break;default:t="工作流执行时中断,请重试"}e.status="failed",e.error=t,e.updatedAt=Date.now();for(const o of e.toolCalls)(o.status==="running"||o.status==="pending")&&(o.status="failed",o.result={success:!1,error:"Service Worker 重启导致执行中断"});this.workflows.set(e.id,e),await y.saveChatWorkflow(e)}updateConfig(e){this.config={...this.config,...e}}async startWorkflow(e,t,o){console.log("[SW-ChatWorkflow] ▶ startWorkflow:",{chatId:e,clientId:o,existingWorkflows:this.workflows.size,timestamp:new Date().toISOString()});const n=this.workflows.get(e);if(n){if(n.status==="streaming"||n.status==="pending"||n.status==="executing_tools"){console.log("[SW-ChatWorkflow] Re-claiming active workflow:",{chatId:e,status:n.status}),this.broadcastStatus(n);return}console.warn("[SW-ChatWorkflow] Workflow already exists, skipping:",{chatId:e,status:n.status}),this.broadcastStatus(n);return}this.workflowClients.set(e,o);const r={id:e,status:"pending",params:t,content:"",toolCalls:[],createdAt:Date.now(),updatedAt:Date.now()};this.workflows.set(e,r),await y.saveChatWorkflow(r);const a=new AbortController;this.abortControllers.set(e,a),this.executeWorkflow(r,a.signal)}async cancelWorkflow(e){const t=this.abortControllers.get(e);t&&(t.abort(),this.abortControllers.delete(e));const o=this.workflows.get(e);o&&(o.status="cancelled",o.updatedAt=Date.now(),await y.saveChatWorkflow(o),this.broadcastStatus(o))}broadcastRecoveredWorkflows(){for(const e of this.workflows.values())this.config.broadcast({type:"CHAT_WORKFLOW_RECOVERED",chatId:e.id,workflow:e})}getWorkflow(e){return this.workflows.get(e)}getAllWorkflows(){return Array.from(this.workflows.values()).filter(e=>e.status!=="completed"&&e.status!=="failed"&&e.status!=="cancelled")}handleMainThreadToolResponse(e){const t=this.pendingToolRequests.get(e.requestId);t&&(this.pendingToolRequests.delete(e.requestId),t.resolve(e))}async executeWorkflow(e,t){try{e.status="streaming",await y.saveChatWorkflow(e),this.broadcastStatus(e);const o=await this.streamChat(e,t);if(e.content=o,t.aborted)throw new Error("Workflow cancelled");e.status="parsing",await y.saveChatWorkflow(e),this.broadcastStatus(e);const n=eo(o),r=Ys(o);e.toolCalls=n,e.aiAnalysis=r,n.length>0&&this.config.broadcast({type:"CHAT_WORKFLOW_TOOL_CALLS",chatId:e.id,aiAnalysis:r,toolCalls:n}),n.length>0&&(e.status="executing_tools",await y.saveChatWorkflow(e),this.broadcastStatus(e),await this.executeTools(e,t)),e.status="completed",e.completedAt=Date.now(),e.updatedAt=Date.now(),await y.saveChatWorkflow(e),this.config.broadcast({type:"CHAT_WORKFLOW_COMPLETE",chatId:e.id,content:e.content,aiAnalysis:e.aiAnalysis,toolCalls:e.toolCalls})}catch(o){o.message==="Workflow cancelled"?e.status="cancelled":(e.status="failed",e.error=o.message,this.config.broadcast({type:"CHAT_WORKFLOW_FAILED",chatId:e.id,error:o.message})),e.updatedAt=Date.now(),await y.saveChatWorkflow(e)}finally{this.abortControllers.delete(e.id)}}async streamChat(e,t){var g,d,u,f,p,E;const{params:o}=e,{geminiConfig:n}=this.config,r=this.convertToGeminiMessages(o),a=o.temporaryModel||n.modelName||"gemini-2.5-flash";console.log("[SW-ChatWorkflow] streamChat called:",{workflowId:e.id,model:a,messagesCount:r.length,timestamp:new Date().toISOString()});const i={model:a,messages:r,stream:!0},{debugFetch:c}=await Promise.resolve().then(()=>P),l=await c(`${n.baseUrl}/chat/completions`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`},body:JSON.stringify(i),signal:t},{label:`💬 工作流对话 (${a})`,logRequestBody:!0,isStreaming:!0});if(!l.ok){const T=await l.text();throw new Error(`Chat request failed: ${l.status} - ${T}`)}if(!l.body)throw new Error("No response body");const h=l.body.getReader(),m=new TextDecoder;let S="",w="";try{for(;;){const{done:T,value:_}=await h.read();if(T)break;w+=m.decode(_,{stream:!0});const C=w.split(`
5
- `);w=C.pop()||"";for(const R of C)if(R.startsWith("data: ")){const x=R.slice(6).trim();if(x==="[DONE]")continue;try{const ee=(u=(d=(g=JSON.parse(x).choices)==null?void 0:g[0])==null?void 0:d.delta)==null?void 0:u.content;ee&&(S+=ee,this.config.broadcast({type:"CHAT_WORKFLOW_STREAM",chatId:e.id,content:S}))}catch{}}}if(w.startsWith("data: ")){const T=w.slice(6).trim();if(T&&T!=="[DONE]")try{const C=(E=(p=(f=JSON.parse(T).choices)==null?void 0:f[0])==null?void 0:p.delta)==null?void 0:E.content;C&&(S+=C,this.config.broadcast({type:"CHAT_WORKFLOW_STREAM",chatId:e.id,content:S}))}catch{}}}finally{h.releaseLock()}if(l.__debugLogId&&S){const{updateLogResponseBody:T}=await Promise.resolve().then(()=>P);T(l.__debugLogId,S)}return S}async executeTools(e,t){const o=this.workflowClients.get(e.id);for(const n of e.toolCalls){if(t.aborted)throw new Error("Workflow cancelled");n.status="running",this.config.broadcast({type:"CHAT_WORKFLOW_TOOL_START",chatId:e.id,toolCallId:n.id,toolName:n.name});try{let r;if(Qe(n.name)||!Rt(n.name)){if(!o)throw new Error("No client ID found for workflow");const a=await this.config.requestMainThreadTool(o,e.id,n.id,n.name,n.arguments);r={success:a.success,data:a.result,error:a.error}}else{const a={geminiConfig:this.config.geminiConfig,videoConfig:this.config.videoConfig,signal:t},i=await Ve(n.name,n.arguments,a);r={success:i.success,data:i.data,error:i.error,taskId:i.taskId}}n.status=r.success?"completed":"failed",n.result=r,await y.saveChatWorkflow(e),this.config.broadcast({type:"CHAT_WORKFLOW_TOOL_COMPLETE",chatId:e.id,toolCallId:n.id,success:r.success,result:r.data,error:r.error,taskId:r.taskId})}catch(r){n.status="failed",n.result={success:!1,error:r.message},await y.saveChatWorkflow(e),this.config.broadcast({type:"CHAT_WORKFLOW_TOOL_COMPLETE",chatId:e.id,toolCallId:n.id,success:!1,error:r.message})}}}convertToGeminiMessages(e){var o;const t=[];e.systemPrompt&&t.push({role:"system",content:[{type:"text",text:e.systemPrompt}]});for(const n of e.messages){const r=[];if(n.content&&r.push({type:"text",text:n.content}),n.attachments)for(const a of n.attachments)a.type==="image"&&r.push({type:"image_url",image_url:{url:`data:${a.mimeType};base64,${a.data}`}});t.push({role:n.role,content:r})}if(e.newContent||(o=e.attachments)!=null&&o.length){const n=[];if(e.newContent&&n.push({type:"text",text:e.newContent}),e.attachments)for(const r of e.attachments)r.type==="image"&&n.push({type:"image_url",image_url:{url:`data:${r.mimeType};base64,${r.data}`}});t.push({role:"user",content:n})}return t}broadcastStatus(e){this.config.broadcast({type:"CHAT_WORKFLOW_STATUS",chatId:e.id,status:e.status,updatedAt:e.updatedAt})}}let O=null,K=null,ie=null,ce=null;function Xe(s,e,t){ie=e,ce=t,O=new Qs({geminiConfig:e,videoConfig:t,broadcast:n=>de(n)});const o=je();o&&o.setTaskStatusChangeCallback((n,r,a,i)=>{O==null||O.updateWorkflowStepForTask(n,r,a,i)}),K=new to({geminiConfig:e,videoConfig:t,broadcast:n=>de(n),sendToClient:(n,r)=>Ye(n,r),requestMainThreadTool:async(n,r,a,i,c)=>{const l=`chat_tool_${Date.now()}_${Math.random().toString(36).slice(2,11)}`;return new Promise((h,m)=>{const S=setTimeout(()=>{le.delete(l),y.deletePendingToolRequest(l),m(new Error(`Tool request timed out: ${i}`))},3e5);le.set(l,{resolve:w=>{clearTimeout(S),y.deletePendingToolRequest(l),h(w)},reject:w=>{clearTimeout(S),y.deletePendingToolRequest(l),m(w)},requestInfo:{requestId:l,chatId:r,toolCallId:a,toolName:i,args:c,clientId:n},timeout:S}),y.savePendingToolRequest({requestId:l,workflowId:r,stepId:a,toolName:i,args:c,createdAt:Date.now(),clientId:n}),Ye(n,{type:"MAIN_THREAD_TOOL_REQUEST",requestId:l,workflowId:r,stepId:a,toolName:i,args:c})})}})}const le=new Map;function so(s,e){if(!O){console.warn("[WorkflowHandler] Not initialized");return}s&&(ie={...ie||{},...s}),e&&(ce={...ce||{},...e}),!(!ie||!ce)&&(O.updateConfig({geminiConfig:ie,videoConfig:ce}),K&&K.updateConfig({geminiConfig:ie,videoConfig:ce}))}function oo(s){var t,o;if(!s||typeof s!="object")return!1;const e=s;return((t=e.type)==null?void 0:t.startsWith("WORKFLOW_"))||((o=e.type)==null?void 0:o.startsWith("CHAT_WORKFLOW_"))||!1}function Je(s,e){if(s.type.startsWith("CHAT_WORKFLOW_")){ro(s,e);return}if(!O){console.error("[WorkflowHandler] ✗ Not initialized, ignoring message:",s.type);return}const t=s;switch(t.type){case"WORKFLOW_SUBMIT":console.log("[SW-WorkflowHandler] ▶ WORKFLOW_SUBMIT received:",{workflowId:t.workflow.id,clientId:e,timestamp:new Date().toISOString()}),O.submitWorkflow(t.workflow);break;case"WORKFLOW_CANCEL":O.cancelWorkflow(t.workflowId);break;case"WORKFLOW_GET_STATUS":{const o=O.getWorkflow(t.workflowId);de({type:"WORKFLOW_STATUS_RESPONSE",workflowId:t.workflowId,workflow:o||null});break}case"WORKFLOW_GET_ALL":{const o=O.getAllWorkflows();de({type:"WORKFLOW_ALL_RESPONSE",workflows:o});break}}}function ro(s,e){var t;if(!K){console.error("[WorkflowHandler] ✗ Chat workflow handler not initialized");return}switch(s.type){case"CHAT_WORKFLOW_START":console.log("[SW-Workflow] ▶ CHAT_WORKFLOW_START received:",{chatId:s.chatId,clientId:e,stepsCount:(t=s.params.steps)==null?void 0:t.length,timestamp:new Date().toISOString()}),K.startWorkflow(s.chatId,s.params,e);break;case"CHAT_WORKFLOW_CANCEL":K.cancelWorkflow(s.chatId);break;case"CHAT_WORKFLOW_GET_STATUS":{const o=K.getWorkflow(s.chatId);de({type:"CHAT_WORKFLOW_STATUS_RESPONSE",chatId:s.chatId,workflow:o||null});break}case"CHAT_WORKFLOW_GET_ALL":{const o=K.getAllWorkflows();de({type:"CHAT_WORKFLOW_ALL_RESPONSE",workflows:o});break}}}async function no(s){const e=le.get(s.requestId);if(e){le.delete(s.requestId),e.resolve(s);return}if(await y.deletePendingToolRequest(s.requestId),!O){console.error("[WorkflowHandler] ✗ Not initialized, ignoring tool response");return}O.handleMainThreadToolResponse(s)}function ao(){if(O&&(O.broadcastRecoveredWorkflows(),O.resendPendingToolRequests()),K&&K.broadcastRecoveredWorkflows(),le.size!==0)for(const[,s]of le){const{requestInfo:e}=s;Ye(e.clientId,{type:"MAIN_THREAD_TOOL_REQUEST",requestId:e.requestId,workflowId:e.chatId,stepId:e.toolCallId,toolName:e.toolName,args:e.args})}}function de(s){St(s)}async function Ye(s,e){await Ie(s,e)||St(e)}const Ce=[],io=100;let Ze=!1,Q=null;function co(s){Ze=s}function et(){return Ze}function It(s){Q=s}function Ot(){return[...Ce]}function lo(s,e){const t=Ce.find(o=>o.id===s);t&&(t.responseBody=e.length>5e3?e.substring(0,5e3)+"...(truncated)":e,Q&&Q({...t}))}async function uo(s){return new Promise((e,t)=>{const o=new FileReader;o.onloadend=()=>e(o.result),o.onerror=t,o.readAsDataURL(s)})}async function ho(s){const e=[];for(const[t,o]of s.entries())if(o instanceof Blob){const n={name:t,value:`[${o.type||"binary"}] ${o.size} bytes`,isFile:!0,mimeType:o.type};if(o.type.startsWith("image/")&&o.size<5*1024*1024)try{n.dataUrl=await uo(o)}catch{}o instanceof File&&(n.fileName=o.name),e.push(n)}else e.push({name:t,value:String(o).length>500?String(o).substring(0,500)+"...":String(o)});return e}async function fo(s,e,t){if(!Ze)return fetch(s,e);const o=typeof s=="string"?s:s instanceof URL?s.href:s.url,n=(e==null?void 0:e.method)||"GET",r=Date.now(),a=Math.random().toString(36).substring(2,10);let i,c,l;if(e!=null&&e.body){if(e.body instanceof FormData)try{c=await ho(e.body)}catch{i="[FormData - unable to parse]"}else if(t!=null&&t.logRequestBody)try{const m=typeof e.body=="string"?e.body:JSON.stringify(e.body),S=/data:image\/([^;]+);base64,([A-Za-z0-9+/=]+)/g;let w,g=0;for(l=[];(w=S.exec(m))!==null;){const f=`image/${w[1]}`,p=w[2];p.length>1e3&&(l.push({key:`image[${g}]`,dataUrl:`data:${f};base64,${p}`,mimeType:f,size:Math.round(p.length*.75/1024)}),g++)}l.length===0&&(l=void 0);let d=m.replace(/data:image\/([^;]+);base64,[A-Za-z0-9+/=]+/g,(f,p)=>`[📷 image/${p}]`);i=!o.includes("/chat/completions")&&d.length>3e3?d.substring(0,3e3)+"...(truncated)":d}catch{i="[unable to serialize body]"}}const h={id:a,timestamp:r,url:o,method:n,requestType:"sw-internal",details:(t==null?void 0:t.label)||`SW Internal: ${n} ${new URL(o).pathname}`,requestBody:i,formData:c,base64Images:l,isStreaming:t==null?void 0:t.isStreaming};Ce.unshift(h),Ce.length>io&&Ce.pop(),Q&&Q({...h});try{const m=await fetch(s,e);if(h.status=m.status,h.statusText=m.statusText,h.duration=Date.now()-r,t!=null&&t.isStreaming)h.responseBody="[流式响应 - 数据通过 SSE/Stream 实时传输,无法捕获完整响应体]";else if(t!=null&&t.logResponseBody)try{const S=m.headers.get("content-type")||"";if(S.includes("application/json")||S.includes("text/")){const g=await m.clone().text();h.responseBody=g.length>2e3?g.substring(0,2e3)+"...(truncated)":g}}catch{}return Q&&Q({...h}),m.__debugLogId=a,m}catch(m){const S=m.message||String(m);let w="NETWORK_ERROR";throw S.includes("ERR_CONNECTION_CLOSED")?w="ERR_CONNECTION_CLOSED":S.includes("ERR_CONNECTION_REFUSED")?w="ERR_CONNECTION_REFUSED":S.includes("ERR_CONNECTION_RESET")?w="ERR_CONNECTION_RESET":S.includes("ERR_CONNECTION_TIMED_OUT")||S.includes("timeout")?w="ERR_TIMEOUT":S.includes("ERR_NAME_NOT_RESOLVED")?w="ERR_DNS_FAILED":S.includes("ERR_INTERNET_DISCONNECTED")?w="ERR_OFFLINE":S.includes("ERR_SSL")||S.includes("certificate")?w="ERR_SSL":S.includes("Failed to fetch")?w="FETCH_FAILED":(S.includes("AbortError")||S.includes("aborted"))&&(w="ABORTED"),h.status=0,h.statusText=w,h.error=S,h.duration=Date.now()-r,Q&&Q({...h}),m}}const P=Object.freeze(Object.defineProperty({__proto__:null,debugFetch:fo,getInternalFetchLogs:Ot,isDebugFetchEnabled:et,setDebugFetchBroadcast:It,setDebugFetchEnabled:co,updateLogResponseBody:lo},Symbol.toStringTag,{value:"Module"})),A=self;zs(A),bs();const se={log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console)};function go(){console.log=(...s)=>{se.log(...s),et()&&Me("log",s)},console.info=(...s)=>{se.info(...s),et()&&Me("info",s)},console.warn=(...s)=>{se.warn(...s),Me("warn",s)},console.error=(...s)=>{se.error(...s),Me("error",s)}}function Me(s,e){const t=e.map(n=>{if(typeof n=="object")try{return JSON.stringify(n)}catch{return String(n)}return String(n)}).join(" "),o=t.startsWith("[SW]")||t.startsWith("[SW-")?t:`[SW] ${t}`;typeof tt=="function"&&tt({logLevel:s,logMessage:o,logSource:"service-worker"})}let tt=null;go(),It(s=>{A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_DEBUG_LOG",entry:{...s,type:"fetch"}})})})}),Promise.resolve().then(()=>L).then(({setLLMApiLogBroadcast:s})=>{s(e=>{A.clients.matchAll().then(t=>{t.forEach(o=>{o.postMessage({type:"SW_DEBUG_LLM_API_LOG",log:e})})})})});const ue="0.5.14",Pe=`drawnix-v${ue}`,k="drawnix-images",he=`drawnix-static-v${ue}`,ve="drawnix-fonts",po="/__aitu_cache__/",mo="/asset-library/",kt=location.hostname==="localhost"||location.hostname==="127.0.0.1",wo=[{hostname:"google.datas.systems",pathPattern:"response_images",fallbackDomain:"cdn.i666.fun"},{hostname:"googlecdn2.datas.systems",pathPattern:"response_images",fallbackDomain:"googlecdn2.i666.fun"},{hostname:"filesystem.i666.fun",pathPattern:"response_images",fallbackDomain:"filesystem.i666.fun"}],So=/\.(jpg|jpeg|png|gif|webp|svg|bmp|ico)$/i,yo=/\.(mp4|webm|ogg|mov|avi|mkv|flv|wmv|m4v)$/i,F=new Map,oe=new Map,xt=30*1e3,_e=new Map,q=new Map,To=300*1e3,Mt=10,fe=new Set,ge=new Set,Eo=3600*1e3,st=new Map;function Pt(s){ge.add(s),st.set(s,Date.now()),console.warn(`Service Worker: 标记 ${s} 为 CORS 问题域名,后续请求将跳过 SW`)}function Co(s){if(!ge.has(s))return!1;const e=st.get(s);return e&&Date.now()-e>Eo?(ge.delete(s),st.delete(s),!1):!0}const be=[],_o=7,j=[],bo=500;let G=!1,pe=0;const Ao=15e3;let V=null;function vt(){if(!G)return;const s=Date.now();pe>0&&s-pe>Ao?(se.log("Service Worker: Debug heartbeat timeout, auto-disabling debug mode"),G=!1,pe=0,$e(!1),Promise.resolve().then(()=>P).then(({setDebugFetchEnabled:e})=>{e(!1)}),A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_DEBUG_DISABLED"})})}),V&&(clearTimeout(V),V=null)):G&&(V=setTimeout(vt,5e3))}function $(s){if(!G)return"";const e=Math.random().toString(36).substring(2,10),t={...s,id:e,timestamp:Date.now()};return j.unshift(t),j.length>bo&&j.pop(),Bt(t),e}function M(s,e){if(!G||!s)return;const t=j.find(o=>o.id===s);t&&(Object.assign(t,e),Bt(t))}async function Bt(s){try{(await A.clients.matchAll()).forEach(t=>{t.postMessage({type:"SW_DEBUG_LOG",entry:s})})}catch{}}function Be(){return new Promise((s,e)=>{const t=indexedDB.open("ConsoleLogDB",1);t.onerror=()=>e(t.error),t.onsuccess=()=>s(t.result),t.onupgradeneeded=o=>{const n=o.target.result;if(!n.objectStoreNames.contains("logs")){const r=n.createObjectStore("logs",{keyPath:"id"});r.createIndex("timestamp","timestamp",{unique:!1}),r.createIndex("logLevel","logLevel",{unique:!1})}}})}async function Ro(s){try{const e=await Be(),t=e.transaction(["logs"],"readwrite");return t.objectStore("logs").add(s),new Promise((n,r)=>{t.oncomplete=()=>{e.close(),n()},t.onerror=()=>{e.close(),r(t.error)}})}catch(e){console.warn("Service Worker: 无法保存控制台日志:",e)}}async function Nt(){try{const s=await Be(),o=s.transaction(["logs"],"readonly").objectStore("logs").index("timestamp");return new Promise((n,r)=>{const a=o.openCursor(null,"prev"),i=[];a.onsuccess=()=>{const c=a.result;c?(i.push(c.value),c.continue()):(s.close(),n(i))},a.onerror=()=>{s.close(),r(a.error)}})}catch(s){return console.warn("Service Worker: 无法加载控制台日志:",s),[]}}async function Wo(){try{const s=await Be(),o=s.transaction(["logs"],"readwrite").objectStore("logs").index("timestamp"),n=Date.now()-_o*24*60*60*1e3,r=IDBKeyRange.upperBound(n);return new Promise((a,i)=>{const c=o.openCursor(r);let l=0;c.onsuccess=()=>{const h=c.result;h?(h.delete(),l++,h.continue()):(s.close(),l>0&&console.log(`Service Worker: 清理了 ${l} 条过期控制台日志`),a(l))},c.onerror=()=>{s.close(),i(c.error)}})}catch(s){return console.warn("Service Worker: 无法清理过期日志:",s),0}}async function Ut(){try{const s=await Be(),e=s.transaction(["logs"],"readwrite");return e.objectStore("logs").clear(),new Promise((o,n)=>{e.oncomplete=()=>{s.close(),o()},e.onerror=()=>{s.close(),n(e.error)}})}catch(s){console.warn("Service Worker: 无法清空控制台日志:",s)}}function qt(s){if(!G)return;const t={id:Math.random().toString(36).substring(2,10),timestamp:Date.now(),type:"console",...s};be.unshift(t),Ro(t),Do(t)}tt=qt;async function Do(s){try{(await A.clients.matchAll()).forEach(t=>{t.postMessage({type:"SW_CONSOLE_LOG",entry:s})})}catch{}}function Lo(){let s=0;return q.forEach(e=>{e.blob&&(s+=e.blob.size)}),s}function Ne(){return{version:ue,cacheNames:[Pe,k,he,ve],pendingImageRequests:F.size,pendingVideoRequests:_e.size,videoBlobCacheSize:q.size,videoBlobCacheTotalBytes:Lo(),completedImageRequestsSize:oe.size,failedDomainsCount:fe.size,failedDomains:Array.from(fe),corsFailedDomainsCount:ge.size,corsFailedDomains:Array.from(ge),debugLogsCount:j.length,consoleLogsCount:be.length,debugModeEnabled:G,workflowHandlerInitialized:re,memoryStats:{pendingRequestsMapSize:F.size,completedRequestsMapSize:oe.size,videoBlobCacheMapSize:q.size,failedDomainsSetSize:fe.size,corsFailedDomainsSetSize:ge.size,debugLogsArraySize:j.length,consoleLogsArraySize:be.length}}}function Gt(s){for(const e of wo)if(s.hostname===e.hostname&&s.pathname.includes(e.pathPattern))return e;return null}function Io(s,e){return So.test(s.pathname)||e.destination==="image"||Gt(s)!==null}function Oo(s,e){return yo.test(s.pathname)||e.destination==="video"||s.pathname.includes("/video/")||s.hash.startsWith("#merged-video-")||s.hash.includes("video")}function ko(s,e){return s.hostname==="fonts.googleapis.com"||s.hostname==="fonts.gstatic.com"?!0:/\.(woff|woff2|ttf|otf|eot)$/i.test(s.pathname)||e.destination==="font"}async function xo(){try{const s=indexedDB.open("ServiceWorkerDB",1);return new Promise((e,t)=>{s.onerror=()=>t(s.error),s.onsuccess=()=>{const o=s.result;if(o.objectStoreNames.contains("failedDomains")){const a=o.transaction(["failedDomains"],"readonly").objectStore("failedDomains").getAll();a.onsuccess=()=>{a.result.forEach(c=>fe.add(c.domain)),e()},a.onerror=()=>t(a.error)}else e()},s.onupgradeneeded=o=>{const n=o.target.result;n.objectStoreNames.contains("failedDomains")||n.createObjectStore("failedDomains",{keyPath:"domain"})}})}catch(s){console.warn("Service Worker: 无法加载失败域名列表:",s)}}async function Mo(s){try{const e=indexedDB.open("ServiceWorkerDB",1);return new Promise((t,o)=>{e.onerror=()=>o(e.error),e.onsuccess=()=>{const r=e.result.transaction(["failedDomains"],"readwrite");r.objectStore("failedDomains").put({domain:s,timestamp:Date.now()}),r.oncomplete=()=>{t()},r.onerror=()=>o(r.error)},e.onupgradeneeded=n=>{const r=n.target.result;r.objectStoreNames.contains("failedDomains")||r.createObjectStore("failedDomains",{keyPath:"domain"})}})}catch(e){console.warn("Service Worker: 无法保存失败域名:",e)}}function Po(s){s&&A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_NEW_VERSION_READY",version:ue})})})}async function vo(s){try{const e=await s.keys();if(e.length<=10)return;const t=[];for(const a of e)try{const i=await s.match(a);if(i){const c=i.headers.get("sw-cache-date"),l=i.headers.get("sw-image-size");t.push({request:a,cacheDate:c?parseInt(c):0,imageSize:l?parseInt(l):0})}}catch(i){console.warn("Service Worker: Error reading cache entry:",i)}t.sort((a,i)=>a.cacheDate-i.cacheDate);const o=Math.max(1,Math.floor(t.length*.25));let n=0,r=0;for(let a=0;a<o&&a<t.length;a++)try{await s.delete(t[a].request),n++,r+=t[a].imageSize}catch(i){console.warn("Service Worker: Error deleting cache entry:",i)}}catch(e){console.warn("Service Worker: Cache cleanup failed:",e)}}const Bo=["/","/index.html","/manifest.json","/favicon.ico","/icons/favicon-new.svg"];A.addEventListener("install",s=>{const e=[];e.push(xo()),kt||e.push(caches.open(he).then(async t=>{const n=(await Promise.allSettled(Bo.map(async r=>{try{const a=await fetch(r,{cache:"reload"});return a.ok?(await t.put(r,a),{url:r,success:!0}):{url:r,success:!1,status:a.status}}catch(a){return{url:r,success:!1,error:String(a)}}}))).filter(r=>r.status==="rejected"||r.status==="fulfilled"&&!r.value.success);n.length>0&&console.warn("Service Worker: Some static files failed to cache:",n.length)}).catch(t=>{console.warn("Service Worker: Cache pre-loading failed:",t)})),s.waitUntil(Promise.all(e).then(async()=>{const t=await caches.keys(),o=t.some(a=>a.startsWith("drawnix-static-v")&&a!==he),n=t.some(a=>a.startsWith("drawnix-v")&&a!==Pe&&a!==k&&!a.startsWith("drawnix-static-v"));Po(o||n)}))}),A.addEventListener("activate",s=>{s.waitUntil(caches.keys().then(async e=>{const t=e.filter(r=>r.startsWith("drawnix-images-v")&&r!==k);if(t.length>0){const r=await caches.open(k);for(const a of t)try{const i=await caches.open(a),c=await i.keys();for(const l of c){const h=await i.match(l);h&&await r.put(l,h)}await caches.delete(a)}catch(i){console.warn(`Failed to migrate cache ${a}:`,i)}}const o=e.filter(r=>r.startsWith("drawnix-static-v")&&r!==he),n=e.filter(r=>r.startsWith("drawnix-v")&&r!==Pe&&r!==k&&!r.startsWith("drawnix-static-v"));return(o.length>0||n.length>0)&&setTimeout(async()=>{for(const r of[...o,...n])try{await caches.delete(r)}catch(a){console.warn("Failed to delete old cache:",r,a)}},3e4),Wo().catch(r=>{console.warn("Failed to cleanup expired console logs:",r)}),A.clients.claim()}))});const No=["TASK_QUEUE_INIT","TASK_QUEUE_UPDATE_CONFIG","TASK_SUBMIT","TASK_CANCEL","TASK_RETRY","TASK_RESUME","TASK_GET_STATUS","TASK_GET_ALL","TASK_DELETE","TASK_MARK_INSERTED","CHAT_START","CHAT_STOP","CHAT_GET_CACHED","TASK_RESTORE"];function Uo(s){if(!s||typeof s!="object")return!1;const e=s;return e.type?No.includes(e.type):!1}let re=!1,me=null,we=null;const Ue=[];function Ft(s){G&&A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_POSTMESSAGE_LOG",entry:s})})})}_s(Ft),A.addEventListener("message",s=>{var n,r,a,i,c,l,h,m,S,w,g;const e=((n=s.data)==null?void 0:n.type)||"unknown",t=((r=s.source)==null?void 0:r.id)||"";let o="";if(Ge()&&(o=Ss(e,s.data,t),o&&G)){const u=Te().find(f=>f.id===o);u&&Ft(u)}if(s.data&&Uo(s.data)){const d=((a=s.source)==null?void 0:a.id)||"";if(Ks(s.data,d),s.data.type==="TASK_QUEUE_INIT"){const{geminiConfig:u,videoConfig:f}=s.data;if(me=u,we=f,!re&&(Xe(A,u,f),re=!0,Ue.length>0)){for(const p of Ue)Je(p.message,p.clientId);Ue.length=0}ao()}if(s.data.type==="TASK_QUEUE_UPDATE_CONFIG"){const{geminiConfig:u,videoConfig:f}=s.data;u&&(me={...me,...u}),f&&(we={...we,...f}),so(u,f)}return}if(s.data&&oo(s.data)){const d=((i=s.source)==null?void 0:i.id)||"";if(!re&&me&&we&&(Xe(A,me,we),re=!0),!re){(async()=>{try{const{geminiConfig:u,videoConfig:f}=await y.loadConfig();if(u&&f)me=u,we=f,Xe(A,u,f),re=!0,Je(s.data,d);else{console.warn("[SW] Cannot initialize workflow handler: no config in storage, requesting config from main thread");const p=await A.clients.matchAll({type:"window"});for(const E of p)E.postMessage({type:"SW_REQUEST_CONFIG",reason:"workflow_handler_not_initialized",pendingMessageType:s.data.type});Ue.push({message:s.data,clientId:d})}}catch(u){console.error("[SW] Failed to load config from storage:",u)}})();return}Je(s.data,d);return}if(s.data&&s.data.type==="MAIN_THREAD_TOOL_RESPONSE"){no(s.data);return}if(s.data&&s.data.type==="SKIP_WAITING")A.skipWaiting(),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_UPDATED"})})});else if(s.data&&s.data.type==="GET_UPGRADE_STATUS")(c=s.source)==null||c.postMessage({type:"UPGRADE_STATUS",version:ue});else if(s.data&&s.data.type==="FORCE_UPGRADE")A.skipWaiting(),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_UPDATED"})})});else if(s.data&&s.data.type==="DELETE_CACHE"){const{url:d}=s.data;d&&Vo(d).then(()=>{A.clients.matchAll().then(u=>{u.forEach(f=>{f.postMessage({type:"CACHE_DELETED",url:d})})})}).catch(u=>{console.error("Service Worker: Failed to delete cache:",u)})}else if(s.data&&s.data.type==="DELETE_CACHE_BATCH"){const{urls:d}=s.data;d&&Array.isArray(d)&&Qo(d).then(()=>{}).catch(u=>{console.error("Service Worker: Failed to batch delete caches:",u)})}else if(s.data&&s.data.type==="CLEAR_ALL_CACHE")Xo().then(()=>{}).catch(d=>{console.error("Service Worker: Failed to clear all cache:",d)});else if(s.data&&s.data.type==="SW_DEBUG_ENABLE")G=!0,pe=Date.now(),Promise.resolve().then(()=>P).then(({setDebugFetchEnabled:d})=>{d(!0)}),$e(!0),se.log("Service Worker: Debug mode enabled"),V&&clearTimeout(V),V=setTimeout(vt,5e3),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_DEBUG_ENABLED"})})}),(l=s.source)==null||l.postMessage({type:"SW_DEBUG_STATUS",status:Ne()});else if(s.data&&s.data.type==="SW_DEBUG_HEARTBEAT")G&&(pe=Date.now());else if(s.data&&s.data.type==="SW_DEBUG_DISABLE")G=!1,pe=0,V&&(clearTimeout(V),V=null),Promise.resolve().then(()=>P).then(({setDebugFetchEnabled:d})=>{d(!1)}),$e(!1),be.length=0,j.length=0,Ut().catch(()=>{}),se.log("Service Worker: Debug mode disabled, logs cleared"),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_DEBUG_DISABLED"})})}),(h=s.source)==null||h.postMessage({type:"SW_DEBUG_STATUS",status:Ne()});else if(s.data&&s.data.type==="SW_DEBUG_GET_STATUS")(async()=>{var f;const d=Ne(),u=await jo();(f=s.source)==null||f.postMessage({type:"SW_DEBUG_STATUS",status:{...d,cacheStats:u}})})();else if(s.data&&s.data.type==="SW_DEBUG_GET_LOGS"){const{limit:d=100,offset:u=0,filter:f}=s.data,p=Ot().map(C=>({...C,type:"fetch"})),E=new Map;for(const C of j)E.set(C.id,C);for(const C of p)E.set(C.id,C);let T=Array.from(E.values()).sort((C,R)=>R.timestamp-C.timestamp);f&&(f.type&&(T=T.filter(C=>C.type===f.type)),f.requestType&&(T=T.filter(C=>C.requestType===f.requestType)),f.url&&(T=T.filter(C=>{var R;return(R=C.url)==null?void 0:R.includes(f.url)})),f.status&&(T=T.filter(C=>C.status===f.status)));const _=T.slice(u,u+d);(m=s.source)==null||m.postMessage({type:"SW_DEBUG_LOGS",logs:_,total:T.length,offset:u,limit:d})}else if(s.data&&s.data.type==="SW_DEBUG_CLEAR_LOGS")j.length=0,(S=s.source)==null||S.postMessage({type:"SW_DEBUG_LOGS_CLEARED"});else if(s.data&&s.data.type==="SW_DEBUG_GET_CACHE_ENTRIES"){const{cacheName:d,limit:u=50,offset:f=0}=s.data;(async()=>{var p,E;try{const T=await caches.open(d||k),_=await T.keys(),C=[];for(let R=f;R<Math.min(f+u,_.length);R++){const x=_[R],v=await T.match(x);if(v){const ee=v.headers.get("sw-cache-date"),Ae=v.headers.get("sw-image-size")||v.headers.get("content-length");C.push({url:x.url,cacheDate:ee?parseInt(ee):void 0,size:Ae?parseInt(Ae):void 0})}}(p=s.source)==null||p.postMessage({type:"SW_DEBUG_CACHE_ENTRIES",cacheName:d||k,entries:C,total:_.length,offset:f,limit:u})}catch(T){(E=s.source)==null||E.postMessage({type:"SW_DEBUG_CACHE_ENTRIES",error:String(T)})}})()}else if(s.data&&s.data.type==="SW_CONSOLE_LOG_REPORT"){const{logLevel:d,logMessage:u,logStack:f,logSource:p,url:E}=s.data;qt({logLevel:d,logMessage:u,logStack:f,logSource:p,url:E})}else if(s.data&&s.data.type==="SW_DEBUG_GET_CONSOLE_LOGS")(async()=>{var d,u;try{const{limit:f=500,offset:p=0,filter:E}=s.data;let T=await Nt();if(E&&(E.logLevel&&(T=T.filter(C=>C.logLevel===E.logLevel)),E.search)){const C=E.search.toLowerCase();T=T.filter(R=>{var x,v;return((x=R.logMessage)==null?void 0:x.toLowerCase().includes(C))||((v=R.logStack)==null?void 0:v.toLowerCase().includes(C))})}const _=T.slice(p,p+f);(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CONSOLE_LOGS",logs:_,total:T.length,offset:p,limit:f})}catch(f){(u=s.source)==null||u.postMessage({type:"SW_DEBUG_CONSOLE_LOGS",logs:[],total:0,error:String(f)})}})();else if(s.data&&s.data.type==="SW_DEBUG_CLEAR_CONSOLE_LOGS")(async()=>{var d;be.length=0,await Ut(),(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CONSOLE_LOGS_CLEARED"})})();else if(s.data&&s.data.type==="SW_DEBUG_EXPORT_LOGS")(async()=>{var p;const d=await Nt(),u=Te(),f={exportTime:new Date().toISOString(),swVersion:ue,userAgent:"",status:Ne(),fetchLogs:j,consoleLogs:d,postmessageLogs:u};(p=s.source)==null||p.postMessage({type:"SW_DEBUG_EXPORT_DATA",data:f})})();else if(s.data&&s.data.type==="SW_DEBUG_GET_POSTMESSAGE_LOGS"){const{limit:d=200,offset:u=0,filter:f}=s.data;let p=Te();if(f&&(f.direction&&(p=p.filter(T=>T.direction===f.direction)),f.messageType)){const T=f.messageType.toLowerCase();p=p.filter(_=>{var C;return(C=_.messageType)==null?void 0:C.toLowerCase().includes(T)})}const E=p.slice(u,u+d);(w=s.source)==null||w.postMessage({type:"SW_DEBUG_POSTMESSAGE_LOGS",logs:E,total:p.length,offset:u,limit:d,stats:Cs()})}else if(s.data&&s.data.type==="SW_DEBUG_CLEAR_POSTMESSAGE_LOGS")ys(),(g=s.source)==null||g.postMessage({type:"SW_DEBUG_POSTMESSAGE_LOGS_CLEARED"});else if(s.data&&s.data.type==="CRASH_SNAPSHOT"){const d=s.data.snapshot;d&&(Go(d),A.clients.matchAll().then(u=>{u.forEach(f=>{f.postMessage({type:"SW_DEBUG_NEW_CRASH_SNAPSHOT",snapshot:d})})}))}else s.data&&s.data.type==="SW_DEBUG_GET_CRASH_SNAPSHOTS"?(async()=>{var d,u;try{const f=await Fo();(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CRASH_SNAPSHOTS",snapshots:f,total:f.length})}catch(f){(u=s.source)==null||u.postMessage({type:"SW_DEBUG_CRASH_SNAPSHOTS",snapshots:[],total:0,error:String(f)})}})():s.data&&s.data.type==="SW_DEBUG_CLEAR_CRASH_SNAPSHOTS"?(async()=>{var d;await $o(),(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CRASH_SNAPSHOTS_CLEARED"})})():s.data&&s.data.type==="SW_DEBUG_GET_LLM_API_LOGS"?(async()=>{var d,u;try{const{getAllLLMApiLogs:f}=await Promise.resolve().then(()=>L),p=await f();(d=s.source)==null||d.postMessage({type:"SW_DEBUG_LLM_API_LOGS",logs:p,total:p.length})}catch(f){(u=s.source)==null||u.postMessage({type:"SW_DEBUG_LLM_API_LOGS",logs:[],total:0,error:String(f)})}})():s.data&&s.data.type==="SW_DEBUG_CLEAR_LLM_API_LOGS"&&(async()=>{var u;const{clearAllLLMApiLogs:d}=await Promise.resolve().then(()=>L);await d(),(u=s.source)==null||u.postMessage({type:"SW_DEBUG_LLM_API_LOGS_CLEARED"})})()});const qo="MemorySnapshotDB",J="snapshots",$t=50;async function ot(){return new Promise((s,e)=>{const t=indexedDB.open(qo,1);t.onerror=()=>e(t.error),t.onsuccess=()=>s(t.result),t.onupgradeneeded=o=>{const n=o.target.result;if(!n.objectStoreNames.contains(J)){const r=n.createObjectStore(J,{keyPath:"id"});r.createIndex("timestamp","timestamp",{unique:!1}),r.createIndex("type","type",{unique:!1})}}})}async function Go(s){try{const e=await ot(),t=e.transaction(J,"readwrite"),o=t.objectStore(J);o.put(s);const n=o.count();n.onsuccess=()=>{const r=n.result;if(r>$t){const i=o.index("timestamp").openCursor();let c=0;const l=r-$t;i.onsuccess=h=>{const m=h.target.result;m&&c<l&&(o.delete(m.value.id),c++,m.continue())}}},await new Promise((r,a)=>{t.oncomplete=()=>{e.close(),r()},t.onerror=()=>{e.close(),a(t.error)}})}catch(e){console.warn("[SW] Failed to save crash snapshot:",e)}}async function Fo(){try{const s=await ot(),o=s.transaction(J,"readonly").objectStore(J).index("timestamp");return new Promise((n,r)=>{const a=o.getAll();a.onsuccess=()=>{s.close();const i=a.result.sort((c,l)=>l.timestamp-c.timestamp);n(i)},a.onerror=()=>{s.close(),r(a.error)}})}catch(s){return console.warn("[SW] Failed to get crash snapshots:",s),[]}}async function $o(){try{const s=await ot(),e=s.transaction(J,"readwrite");e.objectStore(J).clear(),await new Promise((o,n)=>{e.oncomplete=()=>{s.close(),o()},e.onerror=()=>{s.close(),n(e.error)}}),console.log("[SW] Crash snapshots cleared")}catch(s){console.warn("[SW] Failed to clear crash snapshots:",s)}}const Ho=["ConsoleLogDB","ServiceWorkerDB","sw-task-queue","aitu-workspace","drawnix-unified-cache","drawnix-kv-storage","drawnix-prompts","drawnix-chat-db","MemorySnapshotDB"];function zo(s){try{const e=JSON.stringify(s);return new Blob([e]).size}catch{return 0}}async function Ko(s){return new Promise(e=>{try{const t=indexedDB.open(s);t.onerror=()=>e({count:0,totalSize:0}),t.onsuccess=()=>{const o=t.result,n=Array.from(o.objectStoreNames);if(n.length===0){o.close(),e({count:0,totalSize:0});return}let r=0,a=0,i=0,c=0;const l=10;try{const h=o.transaction(n,"readonly");for(const m of n){const S=h.objectStore(m),w=S.count();w.onsuccess=()=>{const g=w.result;if(r+=g,g>0){const d=S.openCursor();let u=0;d.onsuccess=f=>{const p=f.target.result;if(p&&u<l)a+=zo(p.value),i++,u++,p.continue();else if(c++,c===n.length){o.close();const E=i>0?a/i:0,T=Math.round(E*r);e({count:r,totalSize:T})}},d.onerror=()=>{if(c++,c===n.length){o.close();const f=i>0?a/i:0,p=Math.round(f*r);e({count:r,totalSize:p})}}}else c++,c===n.length&&(o.close(),e({count:r,totalSize:0}))},w.onerror=()=>{if(c++,c===n.length){o.close();const g=i>0?a/i:0,d=Math.round(g*r);e({count:r,totalSize:d})}}}}catch{o.close(),e({count:0,totalSize:0})}},t.onupgradeneeded=o=>{o.target.result.close();try{indexedDB.deleteDatabase(s)}catch{}e({count:0,totalSize:0})}}catch{e({count:0,totalSize:0})}})}async function jo(){const s={},e=[Pe,k,he,ve];for(const t of e)try{const o=await caches.open(t),n=await o.keys();let r=0;const a=Math.min(n.length,100);let i=0;for(let c=0;c<a;c++){const l=await o.match(n[c]);if(l){const h=l.headers.get("sw-image-size")||l.headers.get("content-length");h&&(i+=parseInt(h))}}a>0&&n.length>a?r=Math.round(i/a*n.length):r=i,s[t]={count:n.length,totalSize:r,type:"cache"}}catch{s[t]={count:0,totalSize:0,type:"cache"}}for(const t of Ho)try{const o=await Ko(t);o.count>0&&(s[`[IDB] ${t}`]={...o,type:"indexeddb"})}catch{}return s}async function Vo(s){try{await(await caches.open(k)).delete(s)}catch(e){throw console.error("Service Worker: Failed to delete cache entry:",s,e),e}}async function Qo(s){try{const e=await caches.open(k);let t=0;for(const o of s)try{await e.delete(o),t++}catch(n){console.warn("Service Worker: Failed to delete cache in batch:",o,n)}}catch(e){throw console.error("Service Worker: Failed to batch delete caches:",e),e}}async function Xo(){try{const s=await caches.open(k),e=await s.keys();for(const t of e)await s.delete(t)}catch(s){throw console.error("Service Worker: Failed to clear image cache:",s),s}}async function Ht(s,e,t){try{(await A.clients.matchAll()).forEach(n=>{n.postMessage({type:"IMAGE_CACHED",url:s,size:e,mimeType:t,timestamp:Date.now()})})}catch(o){console.warn("Service Worker: Failed to notify image cached:",o)}}async function Jo(){try{if(navigator.storage&&navigator.storage.estimate){const s=await navigator.storage.estimate(),e=s.usage||0,t=s.quota||0,o=t>0?e/t*100:0;o>90&&(console.warn("Service Worker: Storage quota warning:",{usage:e,quota:t,percentage:o}),(await A.clients.matchAll()).forEach(r=>{r.postMessage({type:"QUOTA_WARNING",usage:e,quota:t})}))}}catch(s){console.warn("Service Worker: Failed to check storage quota:",s)}}A.addEventListener("fetch",s=>{const e=new URL(s.request.url),t=Date.now();if(e.protocol!=="http:"&&e.protocol!=="https:"){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"other",details:`Skipped: non-http protocol (${e.protocol})`,status:0,duration:0});return}if(e.pathname.startsWith(po)){const o=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"cache-url",details:"Intercepting cache URL request"});s.respondWith(Zo(s.request).then(n=>(M(o,{status:n.status,statusText:n.statusText,responseType:n.type,duration:Date.now()-t,cached:n.status===200}),n)).catch(n=>{throw M(o,{error:String(n),duration:Date.now()-t}),n}));return}if(e.pathname.startsWith(mo)){const o=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"asset-library",details:"Intercepting asset library request"});s.respondWith(er(s.request).then(n=>(M(o,{status:n.status,statusText:n.statusText,responseType:n.type,duration:Date.now()-t,cached:n.status===200}),n)).catch(n=>{throw M(o,{error:String(n),duration:Date.now()-t}),n}));return}if(e.hostname==="cdn.i666.fun"){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:"Passthrough: cdn.i666.fun (fallback domain)",status:0,duration:0});return}if(e.hostname.endsWith(".volces.com")||e.hostname.endsWith(".volccdn.com")){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:"Passthrough: Volcengine domain (no CORS)",status:0,duration:0});return}if(e.hostname.endsWith(".aliyuncs.com")){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:"Passthrough: Aliyun OSS domain (no CORS)",status:0,duration:0});return}if(Co(e.hostname)){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:`Passthrough: ${e.hostname} (CORS failed domain, auto-detected)`,status:0,duration:0});return}if(Oo(e,s.request)){const o=Date.now(),n=s.request.headers.get("range"),r=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"video",headers:n?{range:n}:void 0,details:n?`Video Range request: ${n}`:"Video request"});s.respondWith(tr(s.request).then(a=>(M(r,{status:a.status,statusText:a.statusText,responseType:a.type,duration:Date.now()-o,responseHeaders:{"content-type":a.headers.get("content-type")||"","content-length":a.headers.get("content-length")||"","content-range":a.headers.get("content-range")||""}}),a)).catch(a=>{throw M(r,{error:String(a),duration:Date.now()-o}),a}));return}if(ko(e,s.request)){const o=Date.now(),n=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"font",details:"Font request"});s.respondWith(Yo(s.request).then(r=>(M(n,{status:r.status,statusText:r.statusText,responseType:r.type,duration:Date.now()-o,cached:r.headers.has("sw-cache-date")}),r)).catch(r=>{throw M(n,{error:String(r),duration:Date.now()-o}),r}));return}if(e.origin!==location.origin&&Io(e,s.request)){const o=Date.now(),n=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"image",details:"External image request"});s.respondWith(nr(s.request).then(r=>(M(n,{status:r.status,statusText:r.statusText,responseType:r.type,duration:Date.now()-o,cached:r.headers.has("sw-cache-date"),size:parseInt(r.headers.get("content-length")||"0")}),r)).catch(r=>{throw M(n,{error:String(r),duration:Date.now()-o}),r}));return}if(s.request.method==="GET"){const o=s.request.mode==="navigate",n=s.request.destination!=="";if(o||n){const r=Date.now(),a=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"static",details:o?"Navigation request":`Static resource (${s.request.destination})`});s.respondWith(sr(s.request).then(i=>(M(a,{status:i.status,statusText:i.statusText,responseType:i.type,duration:Date.now()-r}),i)).catch(i=>{throw M(a,{error:String(i),duration:Date.now()-r}),i}));return}}if(G){const o=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"xhr",details:`XHR/API request (${s.request.method})`});s.respondWith((async()=>{try{const n=s.request.clone();let r,a={};if(s.request.headers.forEach((m,S)=>{a[S]=m}),["POST","PUT","PATCH"].includes(s.request.method))try{const m=s.request.headers.get("content-type")||"";m.includes("application/json")?(r=await n.text(),r.length>2e3&&(r=r.substring(0,2e3)+"... (truncated)")):m.includes("application/x-www-form-urlencoded")?(r=await n.text(),r.length>2e3&&(r=r.substring(0,2e3)+"... (truncated)")):r=`[${m||"binary data"}]`}catch{r="[unable to read body]"}M(o,{headers:a,details:r?`XHR/API request (${s.request.method})
5
+ `);w=C.pop()||"";for(const R of C)if(R.startsWith("data: ")){const x=R.slice(6).trim();if(x==="[DONE]")continue;try{const ee=(u=(d=(g=JSON.parse(x).choices)==null?void 0:g[0])==null?void 0:d.delta)==null?void 0:u.content;ee&&(S+=ee,this.config.broadcast({type:"CHAT_WORKFLOW_STREAM",chatId:e.id,content:S}))}catch{}}}if(w.startsWith("data: ")){const T=w.slice(6).trim();if(T&&T!=="[DONE]")try{const C=(E=(p=(f=JSON.parse(T).choices)==null?void 0:f[0])==null?void 0:p.delta)==null?void 0:E.content;C&&(S+=C,this.config.broadcast({type:"CHAT_WORKFLOW_STREAM",chatId:e.id,content:S}))}catch{}}}finally{h.releaseLock()}if(l.__debugLogId&&S){const{updateLogResponseBody:T}=await Promise.resolve().then(()=>P);T(l.__debugLogId,S)}return S}async executeTools(e,t){const o=this.workflowClients.get(e.id);for(const n of e.toolCalls){if(t.aborted)throw new Error("Workflow cancelled");n.status="running",this.config.broadcast({type:"CHAT_WORKFLOW_TOOL_START",chatId:e.id,toolCallId:n.id,toolName:n.name});try{let r;if(Qe(n.name)||!Rt(n.name)){if(!o)throw new Error("No client ID found for workflow");const a=await this.config.requestMainThreadTool(o,e.id,n.id,n.name,n.arguments);r={success:a.success,data:a.result,error:a.error}}else{const a={geminiConfig:this.config.geminiConfig,videoConfig:this.config.videoConfig,signal:t},i=await Ve(n.name,n.arguments,a);r={success:i.success,data:i.data,error:i.error,taskId:i.taskId}}n.status=r.success?"completed":"failed",n.result=r,await y.saveChatWorkflow(e),this.config.broadcast({type:"CHAT_WORKFLOW_TOOL_COMPLETE",chatId:e.id,toolCallId:n.id,success:r.success,result:r.data,error:r.error,taskId:r.taskId})}catch(r){n.status="failed",n.result={success:!1,error:r.message},await y.saveChatWorkflow(e),this.config.broadcast({type:"CHAT_WORKFLOW_TOOL_COMPLETE",chatId:e.id,toolCallId:n.id,success:!1,error:r.message})}}}convertToGeminiMessages(e){var o;const t=[];e.systemPrompt&&t.push({role:"system",content:[{type:"text",text:e.systemPrompt}]});for(const n of e.messages){const r=[];if(n.content&&r.push({type:"text",text:n.content}),n.attachments)for(const a of n.attachments)a.type==="image"&&r.push({type:"image_url",image_url:{url:`data:${a.mimeType};base64,${a.data}`}});t.push({role:n.role,content:r})}if(e.newContent||(o=e.attachments)!=null&&o.length){const n=[];if(e.newContent&&n.push({type:"text",text:e.newContent}),e.attachments)for(const r of e.attachments)r.type==="image"&&n.push({type:"image_url",image_url:{url:`data:${r.mimeType};base64,${r.data}`}});t.push({role:"user",content:n})}return t}broadcastStatus(e){this.config.broadcast({type:"CHAT_WORKFLOW_STATUS",chatId:e.id,status:e.status,updatedAt:e.updatedAt})}}let O=null,K=null,ie=null,ce=null;function Xe(s,e,t){ie=e,ce=t,O=new Qs({geminiConfig:e,videoConfig:t,broadcast:n=>de(n)});const o=je();o&&o.setTaskStatusChangeCallback((n,r,a,i)=>{O==null||O.updateWorkflowStepForTask(n,r,a,i)}),K=new to({geminiConfig:e,videoConfig:t,broadcast:n=>de(n),sendToClient:(n,r)=>Ye(n,r),requestMainThreadTool:async(n,r,a,i,c)=>{const l=`chat_tool_${Date.now()}_${Math.random().toString(36).slice(2,11)}`;return new Promise((h,m)=>{const S=setTimeout(()=>{le.delete(l),y.deletePendingToolRequest(l),m(new Error(`Tool request timed out: ${i}`))},3e5);le.set(l,{resolve:w=>{clearTimeout(S),y.deletePendingToolRequest(l),h(w)},reject:w=>{clearTimeout(S),y.deletePendingToolRequest(l),m(w)},requestInfo:{requestId:l,chatId:r,toolCallId:a,toolName:i,args:c,clientId:n},timeout:S}),y.savePendingToolRequest({requestId:l,workflowId:r,stepId:a,toolName:i,args:c,createdAt:Date.now(),clientId:n}),Ye(n,{type:"MAIN_THREAD_TOOL_REQUEST",requestId:l,workflowId:r,stepId:a,toolName:i,args:c})})}})}const le=new Map;function so(s,e){if(!O){console.warn("[WorkflowHandler] Not initialized");return}s&&(ie={...ie||{},...s}),e&&(ce={...ce||{},...e}),!(!ie||!ce)&&(O.updateConfig({geminiConfig:ie,videoConfig:ce}),K&&K.updateConfig({geminiConfig:ie,videoConfig:ce}))}function oo(s){var t,o;if(!s||typeof s!="object")return!1;const e=s;return((t=e.type)==null?void 0:t.startsWith("WORKFLOW_"))||((o=e.type)==null?void 0:o.startsWith("CHAT_WORKFLOW_"))||!1}function Je(s,e){if(s.type.startsWith("CHAT_WORKFLOW_")){ro(s,e);return}if(!O){console.error("[WorkflowHandler] ✗ Not initialized, ignoring message:",s.type);return}const t=s;switch(t.type){case"WORKFLOW_SUBMIT":console.log("[SW-WorkflowHandler] ▶ WORKFLOW_SUBMIT received:",{workflowId:t.workflow.id,clientId:e,timestamp:new Date().toISOString()}),O.submitWorkflow(t.workflow);break;case"WORKFLOW_CANCEL":O.cancelWorkflow(t.workflowId);break;case"WORKFLOW_GET_STATUS":{const o=O.getWorkflow(t.workflowId);de({type:"WORKFLOW_STATUS_RESPONSE",workflowId:t.workflowId,workflow:o||null});break}case"WORKFLOW_GET_ALL":{const o=O.getAllWorkflows();de({type:"WORKFLOW_ALL_RESPONSE",workflows:o});break}}}function ro(s,e){var t;if(!K){console.error("[WorkflowHandler] ✗ Chat workflow handler not initialized");return}switch(s.type){case"CHAT_WORKFLOW_START":console.log("[SW-Workflow] ▶ CHAT_WORKFLOW_START received:",{chatId:s.chatId,clientId:e,stepsCount:(t=s.params.steps)==null?void 0:t.length,timestamp:new Date().toISOString()}),K.startWorkflow(s.chatId,s.params,e);break;case"CHAT_WORKFLOW_CANCEL":K.cancelWorkflow(s.chatId);break;case"CHAT_WORKFLOW_GET_STATUS":{const o=K.getWorkflow(s.chatId);de({type:"CHAT_WORKFLOW_STATUS_RESPONSE",chatId:s.chatId,workflow:o||null});break}case"CHAT_WORKFLOW_GET_ALL":{const o=K.getAllWorkflows();de({type:"CHAT_WORKFLOW_ALL_RESPONSE",workflows:o});break}}}async function no(s){const e=le.get(s.requestId);if(e){le.delete(s.requestId),e.resolve(s);return}if(await y.deletePendingToolRequest(s.requestId),!O){console.error("[WorkflowHandler] ✗ Not initialized, ignoring tool response");return}O.handleMainThreadToolResponse(s)}function ao(){if(O&&(O.broadcastRecoveredWorkflows(),O.resendPendingToolRequests()),K&&K.broadcastRecoveredWorkflows(),le.size!==0)for(const[,s]of le){const{requestInfo:e}=s;Ye(e.clientId,{type:"MAIN_THREAD_TOOL_REQUEST",requestId:e.requestId,workflowId:e.chatId,stepId:e.toolCallId,toolName:e.toolName,args:e.args})}}function de(s){St(s)}async function Ye(s,e){await Ie(s,e)||St(e)}const Ce=[],io=100;let Ze=!1,Q=null;function co(s){Ze=s}function et(){return Ze}function It(s){Q=s}function Ot(){return[...Ce]}function lo(s,e){const t=Ce.find(o=>o.id===s);t&&(t.responseBody=e.length>5e3?e.substring(0,5e3)+"...(truncated)":e,Q&&Q({...t}))}async function uo(s){return new Promise((e,t)=>{const o=new FileReader;o.onloadend=()=>e(o.result),o.onerror=t,o.readAsDataURL(s)})}async function ho(s){const e=[];for(const[t,o]of s.entries())if(o instanceof Blob){const n={name:t,value:`[${o.type||"binary"}] ${o.size} bytes`,isFile:!0,mimeType:o.type};if(o.type.startsWith("image/")&&o.size<5*1024*1024)try{n.dataUrl=await uo(o)}catch{}o instanceof File&&(n.fileName=o.name),e.push(n)}else e.push({name:t,value:String(o).length>500?String(o).substring(0,500)+"...":String(o)});return e}async function fo(s,e,t){if(!Ze)return fetch(s,e);const o=typeof s=="string"?s:s instanceof URL?s.href:s.url,n=(e==null?void 0:e.method)||"GET",r=Date.now(),a=Math.random().toString(36).substring(2,10);let i,c,l;if(e!=null&&e.body){if(e.body instanceof FormData)try{c=await ho(e.body)}catch{i="[FormData - unable to parse]"}else if(t!=null&&t.logRequestBody)try{const m=typeof e.body=="string"?e.body:JSON.stringify(e.body),S=/data:image\/([^;]+);base64,([A-Za-z0-9+/=]+)/g;let w,g=0;for(l=[];(w=S.exec(m))!==null;){const f=`image/${w[1]}`,p=w[2];p.length>1e3&&(l.push({key:`image[${g}]`,dataUrl:`data:${f};base64,${p}`,mimeType:f,size:Math.round(p.length*.75/1024)}),g++)}l.length===0&&(l=void 0);let d=m.replace(/data:image\/([^;]+);base64,[A-Za-z0-9+/=]+/g,(f,p)=>`[📷 image/${p}]`);i=!o.includes("/chat/completions")&&d.length>3e3?d.substring(0,3e3)+"...(truncated)":d}catch{i="[unable to serialize body]"}}const h={id:a,timestamp:r,url:o,method:n,requestType:"sw-internal",details:(t==null?void 0:t.label)||`SW Internal: ${n} ${new URL(o).pathname}`,requestBody:i,formData:c,base64Images:l,isStreaming:t==null?void 0:t.isStreaming};Ce.unshift(h),Ce.length>io&&Ce.pop(),Q&&Q({...h});try{const m=await fetch(s,e);if(h.status=m.status,h.statusText=m.statusText,h.duration=Date.now()-r,t!=null&&t.isStreaming)h.responseBody="[流式响应 - 数据通过 SSE/Stream 实时传输,无法捕获完整响应体]";else if(t!=null&&t.logResponseBody)try{const S=m.headers.get("content-type")||"";if(S.includes("application/json")||S.includes("text/")){const g=await m.clone().text();h.responseBody=g.length>2e3?g.substring(0,2e3)+"...(truncated)":g}}catch{}return Q&&Q({...h}),m.__debugLogId=a,m}catch(m){const S=m.message||String(m);let w="NETWORK_ERROR";throw S.includes("ERR_CONNECTION_CLOSED")?w="ERR_CONNECTION_CLOSED":S.includes("ERR_CONNECTION_REFUSED")?w="ERR_CONNECTION_REFUSED":S.includes("ERR_CONNECTION_RESET")?w="ERR_CONNECTION_RESET":S.includes("ERR_CONNECTION_TIMED_OUT")||S.includes("timeout")?w="ERR_TIMEOUT":S.includes("ERR_NAME_NOT_RESOLVED")?w="ERR_DNS_FAILED":S.includes("ERR_INTERNET_DISCONNECTED")?w="ERR_OFFLINE":S.includes("ERR_SSL")||S.includes("certificate")?w="ERR_SSL":S.includes("Failed to fetch")?w="FETCH_FAILED":(S.includes("AbortError")||S.includes("aborted"))&&(w="ABORTED"),h.status=0,h.statusText=w,h.error=S,h.duration=Date.now()-r,Q&&Q({...h}),m}}const P=Object.freeze(Object.defineProperty({__proto__:null,debugFetch:fo,getInternalFetchLogs:Ot,isDebugFetchEnabled:et,setDebugFetchBroadcast:It,setDebugFetchEnabled:co,updateLogResponseBody:lo},Symbol.toStringTag,{value:"Module"})),A=self;zs(A),bs();const se={log:console.log.bind(console),info:console.info.bind(console),warn:console.warn.bind(console),error:console.error.bind(console)};function go(){console.log=(...s)=>{se.log(...s),et()&&Me("log",s)},console.info=(...s)=>{se.info(...s),et()&&Me("info",s)},console.warn=(...s)=>{se.warn(...s),Me("warn",s)},console.error=(...s)=>{se.error(...s),Me("error",s)}}function Me(s,e){const t=e.map(n=>{if(typeof n=="object")try{return JSON.stringify(n)}catch{return String(n)}return String(n)}).join(" "),o=t.startsWith("[SW]")||t.startsWith("[SW-")?t:`[SW] ${t}`;typeof tt=="function"&&tt({logLevel:s,logMessage:o,logSource:"service-worker"})}let tt=null;go(),It(s=>{A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_DEBUG_LOG",entry:{...s,type:"fetch"}})})})}),Promise.resolve().then(()=>L).then(({setLLMApiLogBroadcast:s})=>{s(e=>{A.clients.matchAll().then(t=>{t.forEach(o=>{o.postMessage({type:"SW_DEBUG_LLM_API_LOG",log:e})})})})});const ue="0.5.15",Pe=`drawnix-v${ue}`,k="drawnix-images",he=`drawnix-static-v${ue}`,ve="drawnix-fonts",po="/__aitu_cache__/",mo="/asset-library/",kt=location.hostname==="localhost"||location.hostname==="127.0.0.1",wo=[{hostname:"google.datas.systems",pathPattern:"response_images",fallbackDomain:"cdn.i666.fun"},{hostname:"googlecdn2.datas.systems",pathPattern:"response_images",fallbackDomain:"googlecdn2.i666.fun"},{hostname:"filesystem.i666.fun",pathPattern:"response_images",fallbackDomain:"filesystem.i666.fun"}],So=/\.(jpg|jpeg|png|gif|webp|svg|bmp|ico)$/i,yo=/\.(mp4|webm|ogg|mov|avi|mkv|flv|wmv|m4v)$/i,F=new Map,oe=new Map,xt=30*1e3,_e=new Map,q=new Map,To=300*1e3,Mt=10,fe=new Set,ge=new Set,Eo=3600*1e3,st=new Map;function Pt(s){ge.add(s),st.set(s,Date.now()),console.warn(`Service Worker: 标记 ${s} 为 CORS 问题域名,后续请求将跳过 SW`)}function Co(s){if(!ge.has(s))return!1;const e=st.get(s);return e&&Date.now()-e>Eo?(ge.delete(s),st.delete(s),!1):!0}const be=[],_o=7,j=[],bo=500;let G=!1,pe=0;const Ao=15e3;let V=null;function vt(){if(!G)return;const s=Date.now();pe>0&&s-pe>Ao?(se.log("Service Worker: Debug heartbeat timeout, auto-disabling debug mode"),G=!1,pe=0,$e(!1),Promise.resolve().then(()=>P).then(({setDebugFetchEnabled:e})=>{e(!1)}),A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_DEBUG_DISABLED"})})}),V&&(clearTimeout(V),V=null)):G&&(V=setTimeout(vt,5e3))}function $(s){if(!G)return"";const e=Math.random().toString(36).substring(2,10),t={...s,id:e,timestamp:Date.now()};return j.unshift(t),j.length>bo&&j.pop(),Bt(t),e}function M(s,e){if(!G||!s)return;const t=j.find(o=>o.id===s);t&&(Object.assign(t,e),Bt(t))}async function Bt(s){try{(await A.clients.matchAll()).forEach(t=>{t.postMessage({type:"SW_DEBUG_LOG",entry:s})})}catch{}}function Be(){return new Promise((s,e)=>{const t=indexedDB.open("ConsoleLogDB",1);t.onerror=()=>e(t.error),t.onsuccess=()=>s(t.result),t.onupgradeneeded=o=>{const n=o.target.result;if(!n.objectStoreNames.contains("logs")){const r=n.createObjectStore("logs",{keyPath:"id"});r.createIndex("timestamp","timestamp",{unique:!1}),r.createIndex("logLevel","logLevel",{unique:!1})}}})}async function Ro(s){try{const e=await Be(),t=e.transaction(["logs"],"readwrite");return t.objectStore("logs").add(s),new Promise((n,r)=>{t.oncomplete=()=>{e.close(),n()},t.onerror=()=>{e.close(),r(t.error)}})}catch(e){console.warn("Service Worker: 无法保存控制台日志:",e)}}async function Nt(){try{const s=await Be(),o=s.transaction(["logs"],"readonly").objectStore("logs").index("timestamp");return new Promise((n,r)=>{const a=o.openCursor(null,"prev"),i=[];a.onsuccess=()=>{const c=a.result;c?(i.push(c.value),c.continue()):(s.close(),n(i))},a.onerror=()=>{s.close(),r(a.error)}})}catch(s){return console.warn("Service Worker: 无法加载控制台日志:",s),[]}}async function Wo(){try{const s=await Be(),o=s.transaction(["logs"],"readwrite").objectStore("logs").index("timestamp"),n=Date.now()-_o*24*60*60*1e3,r=IDBKeyRange.upperBound(n);return new Promise((a,i)=>{const c=o.openCursor(r);let l=0;c.onsuccess=()=>{const h=c.result;h?(h.delete(),l++,h.continue()):(s.close(),l>0&&console.log(`Service Worker: 清理了 ${l} 条过期控制台日志`),a(l))},c.onerror=()=>{s.close(),i(c.error)}})}catch(s){return console.warn("Service Worker: 无法清理过期日志:",s),0}}async function Ut(){try{const s=await Be(),e=s.transaction(["logs"],"readwrite");return e.objectStore("logs").clear(),new Promise((o,n)=>{e.oncomplete=()=>{s.close(),o()},e.onerror=()=>{s.close(),n(e.error)}})}catch(s){console.warn("Service Worker: 无法清空控制台日志:",s)}}function qt(s){if(!G)return;const t={id:Math.random().toString(36).substring(2,10),timestamp:Date.now(),type:"console",...s};be.unshift(t),Ro(t),Do(t)}tt=qt;async function Do(s){try{(await A.clients.matchAll()).forEach(t=>{t.postMessage({type:"SW_CONSOLE_LOG",entry:s})})}catch{}}function Lo(){let s=0;return q.forEach(e=>{e.blob&&(s+=e.blob.size)}),s}function Ne(){return{version:ue,cacheNames:[Pe,k,he,ve],pendingImageRequests:F.size,pendingVideoRequests:_e.size,videoBlobCacheSize:q.size,videoBlobCacheTotalBytes:Lo(),completedImageRequestsSize:oe.size,failedDomainsCount:fe.size,failedDomains:Array.from(fe),corsFailedDomainsCount:ge.size,corsFailedDomains:Array.from(ge),debugLogsCount:j.length,consoleLogsCount:be.length,debugModeEnabled:G,workflowHandlerInitialized:re,memoryStats:{pendingRequestsMapSize:F.size,completedRequestsMapSize:oe.size,videoBlobCacheMapSize:q.size,failedDomainsSetSize:fe.size,corsFailedDomainsSetSize:ge.size,debugLogsArraySize:j.length,consoleLogsArraySize:be.length}}}function Gt(s){for(const e of wo)if(s.hostname===e.hostname&&s.pathname.includes(e.pathPattern))return e;return null}function Io(s,e){return So.test(s.pathname)||e.destination==="image"||Gt(s)!==null}function Oo(s,e){return yo.test(s.pathname)||e.destination==="video"||s.pathname.includes("/video/")||s.hash.startsWith("#merged-video-")||s.hash.includes("video")}function ko(s,e){return s.hostname==="fonts.googleapis.com"||s.hostname==="fonts.gstatic.com"?!0:/\.(woff|woff2|ttf|otf|eot)$/i.test(s.pathname)||e.destination==="font"}async function xo(){try{const s=indexedDB.open("ServiceWorkerDB",1);return new Promise((e,t)=>{s.onerror=()=>t(s.error),s.onsuccess=()=>{const o=s.result;if(o.objectStoreNames.contains("failedDomains")){const a=o.transaction(["failedDomains"],"readonly").objectStore("failedDomains").getAll();a.onsuccess=()=>{a.result.forEach(c=>fe.add(c.domain)),e()},a.onerror=()=>t(a.error)}else e()},s.onupgradeneeded=o=>{const n=o.target.result;n.objectStoreNames.contains("failedDomains")||n.createObjectStore("failedDomains",{keyPath:"domain"})}})}catch(s){console.warn("Service Worker: 无法加载失败域名列表:",s)}}async function Mo(s){try{const e=indexedDB.open("ServiceWorkerDB",1);return new Promise((t,o)=>{e.onerror=()=>o(e.error),e.onsuccess=()=>{const r=e.result.transaction(["failedDomains"],"readwrite");r.objectStore("failedDomains").put({domain:s,timestamp:Date.now()}),r.oncomplete=()=>{t()},r.onerror=()=>o(r.error)},e.onupgradeneeded=n=>{const r=n.target.result;r.objectStoreNames.contains("failedDomains")||r.createObjectStore("failedDomains",{keyPath:"domain"})}})}catch(e){console.warn("Service Worker: 无法保存失败域名:",e)}}function Po(s){s&&A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_NEW_VERSION_READY",version:ue})})})}async function vo(s){try{const e=await s.keys();if(e.length<=10)return;const t=[];for(const a of e)try{const i=await s.match(a);if(i){const c=i.headers.get("sw-cache-date"),l=i.headers.get("sw-image-size");t.push({request:a,cacheDate:c?parseInt(c):0,imageSize:l?parseInt(l):0})}}catch(i){console.warn("Service Worker: Error reading cache entry:",i)}t.sort((a,i)=>a.cacheDate-i.cacheDate);const o=Math.max(1,Math.floor(t.length*.25));let n=0,r=0;for(let a=0;a<o&&a<t.length;a++)try{await s.delete(t[a].request),n++,r+=t[a].imageSize}catch(i){console.warn("Service Worker: Error deleting cache entry:",i)}}catch(e){console.warn("Service Worker: Cache cleanup failed:",e)}}const Bo=["/","/index.html","/manifest.json","/favicon.ico","/icons/favicon-new.svg"];A.addEventListener("install",s=>{const e=[];e.push(xo()),kt||e.push(caches.open(he).then(async t=>{const n=(await Promise.allSettled(Bo.map(async r=>{try{const a=await fetch(r,{cache:"reload"});return a.ok?(await t.put(r,a),{url:r,success:!0}):{url:r,success:!1,status:a.status}}catch(a){return{url:r,success:!1,error:String(a)}}}))).filter(r=>r.status==="rejected"||r.status==="fulfilled"&&!r.value.success);n.length>0&&console.warn("Service Worker: Some static files failed to cache:",n.length)}).catch(t=>{console.warn("Service Worker: Cache pre-loading failed:",t)})),s.waitUntil(Promise.all(e).then(async()=>{const t=await caches.keys(),o=t.some(a=>a.startsWith("drawnix-static-v")&&a!==he),n=t.some(a=>a.startsWith("drawnix-v")&&a!==Pe&&a!==k&&!a.startsWith("drawnix-static-v"));Po(o||n)}))}),A.addEventListener("activate",s=>{s.waitUntil(caches.keys().then(async e=>{const t=e.filter(r=>r.startsWith("drawnix-images-v")&&r!==k);if(t.length>0){const r=await caches.open(k);for(const a of t)try{const i=await caches.open(a),c=await i.keys();for(const l of c){const h=await i.match(l);h&&await r.put(l,h)}await caches.delete(a)}catch(i){console.warn(`Failed to migrate cache ${a}:`,i)}}const o=e.filter(r=>r.startsWith("drawnix-static-v")&&r!==he),n=e.filter(r=>r.startsWith("drawnix-v")&&r!==Pe&&r!==k&&!r.startsWith("drawnix-static-v"));return(o.length>0||n.length>0)&&setTimeout(async()=>{for(const r of[...o,...n])try{await caches.delete(r)}catch(a){console.warn("Failed to delete old cache:",r,a)}},3e4),Wo().catch(r=>{console.warn("Failed to cleanup expired console logs:",r)}),A.clients.claim()}))});const No=["TASK_QUEUE_INIT","TASK_QUEUE_UPDATE_CONFIG","TASK_SUBMIT","TASK_CANCEL","TASK_RETRY","TASK_RESUME","TASK_GET_STATUS","TASK_GET_ALL","TASK_DELETE","TASK_MARK_INSERTED","CHAT_START","CHAT_STOP","CHAT_GET_CACHED","TASK_RESTORE"];function Uo(s){if(!s||typeof s!="object")return!1;const e=s;return e.type?No.includes(e.type):!1}let re=!1,me=null,we=null;const Ue=[];function Ft(s){G&&A.clients.matchAll().then(e=>{e.forEach(t=>{t.postMessage({type:"SW_POSTMESSAGE_LOG",entry:s})})})}_s(Ft),A.addEventListener("message",s=>{var n,r,a,i,c,l,h,m,S,w,g;const e=((n=s.data)==null?void 0:n.type)||"unknown",t=((r=s.source)==null?void 0:r.id)||"";let o="";if(Ge()&&(o=Ss(e,s.data,t),o&&G)){const u=Te().find(f=>f.id===o);u&&Ft(u)}if(s.data&&Uo(s.data)){const d=((a=s.source)==null?void 0:a.id)||"";if(Ks(s.data,d),s.data.type==="TASK_QUEUE_INIT"){const{geminiConfig:u,videoConfig:f}=s.data;if(me=u,we=f,!re&&(Xe(A,u,f),re=!0,Ue.length>0)){for(const p of Ue)Je(p.message,p.clientId);Ue.length=0}ao()}if(s.data.type==="TASK_QUEUE_UPDATE_CONFIG"){const{geminiConfig:u,videoConfig:f}=s.data;u&&(me={...me,...u}),f&&(we={...we,...f}),so(u,f)}return}if(s.data&&oo(s.data)){const d=((i=s.source)==null?void 0:i.id)||"";if(!re&&me&&we&&(Xe(A,me,we),re=!0),!re){(async()=>{try{const{geminiConfig:u,videoConfig:f}=await y.loadConfig();if(u&&f)me=u,we=f,Xe(A,u,f),re=!0,Je(s.data,d);else{console.warn("[SW] Cannot initialize workflow handler: no config in storage, requesting config from main thread");const p=await A.clients.matchAll({type:"window"});for(const E of p)E.postMessage({type:"SW_REQUEST_CONFIG",reason:"workflow_handler_not_initialized",pendingMessageType:s.data.type});Ue.push({message:s.data,clientId:d})}}catch(u){console.error("[SW] Failed to load config from storage:",u)}})();return}Je(s.data,d);return}if(s.data&&s.data.type==="MAIN_THREAD_TOOL_RESPONSE"){no(s.data);return}if(s.data&&s.data.type==="SKIP_WAITING")A.skipWaiting(),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_UPDATED"})})});else if(s.data&&s.data.type==="GET_UPGRADE_STATUS")(c=s.source)==null||c.postMessage({type:"UPGRADE_STATUS",version:ue});else if(s.data&&s.data.type==="FORCE_UPGRADE")A.skipWaiting(),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_UPDATED"})})});else if(s.data&&s.data.type==="DELETE_CACHE"){const{url:d}=s.data;d&&Vo(d).then(()=>{A.clients.matchAll().then(u=>{u.forEach(f=>{f.postMessage({type:"CACHE_DELETED",url:d})})})}).catch(u=>{console.error("Service Worker: Failed to delete cache:",u)})}else if(s.data&&s.data.type==="DELETE_CACHE_BATCH"){const{urls:d}=s.data;d&&Array.isArray(d)&&Qo(d).then(()=>{}).catch(u=>{console.error("Service Worker: Failed to batch delete caches:",u)})}else if(s.data&&s.data.type==="CLEAR_ALL_CACHE")Xo().then(()=>{}).catch(d=>{console.error("Service Worker: Failed to clear all cache:",d)});else if(s.data&&s.data.type==="SW_DEBUG_ENABLE")G=!0,pe=Date.now(),Promise.resolve().then(()=>P).then(({setDebugFetchEnabled:d})=>{d(!0)}),$e(!0),se.log("Service Worker: Debug mode enabled"),V&&clearTimeout(V),V=setTimeout(vt,5e3),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_DEBUG_ENABLED"})})}),(l=s.source)==null||l.postMessage({type:"SW_DEBUG_STATUS",status:Ne()});else if(s.data&&s.data.type==="SW_DEBUG_HEARTBEAT")G&&(pe=Date.now());else if(s.data&&s.data.type==="SW_DEBUG_DISABLE")G=!1,pe=0,V&&(clearTimeout(V),V=null),Promise.resolve().then(()=>P).then(({setDebugFetchEnabled:d})=>{d(!1)}),$e(!1),be.length=0,j.length=0,Ut().catch(()=>{}),se.log("Service Worker: Debug mode disabled, logs cleared"),A.clients.matchAll().then(d=>{d.forEach(u=>{u.postMessage({type:"SW_DEBUG_DISABLED"})})}),(h=s.source)==null||h.postMessage({type:"SW_DEBUG_STATUS",status:Ne()});else if(s.data&&s.data.type==="SW_DEBUG_GET_STATUS")(async()=>{var f;const d=Ne(),u=await jo();(f=s.source)==null||f.postMessage({type:"SW_DEBUG_STATUS",status:{...d,cacheStats:u}})})();else if(s.data&&s.data.type==="SW_DEBUG_GET_LOGS"){const{limit:d=100,offset:u=0,filter:f}=s.data,p=Ot().map(C=>({...C,type:"fetch"})),E=new Map;for(const C of j)E.set(C.id,C);for(const C of p)E.set(C.id,C);let T=Array.from(E.values()).sort((C,R)=>R.timestamp-C.timestamp);f&&(f.type&&(T=T.filter(C=>C.type===f.type)),f.requestType&&(T=T.filter(C=>C.requestType===f.requestType)),f.url&&(T=T.filter(C=>{var R;return(R=C.url)==null?void 0:R.includes(f.url)})),f.status&&(T=T.filter(C=>C.status===f.status)));const _=T.slice(u,u+d);(m=s.source)==null||m.postMessage({type:"SW_DEBUG_LOGS",logs:_,total:T.length,offset:u,limit:d})}else if(s.data&&s.data.type==="SW_DEBUG_CLEAR_LOGS")j.length=0,(S=s.source)==null||S.postMessage({type:"SW_DEBUG_LOGS_CLEARED"});else if(s.data&&s.data.type==="SW_DEBUG_GET_CACHE_ENTRIES"){const{cacheName:d,limit:u=50,offset:f=0}=s.data;(async()=>{var p,E;try{const T=await caches.open(d||k),_=await T.keys(),C=[];for(let R=f;R<Math.min(f+u,_.length);R++){const x=_[R],v=await T.match(x);if(v){const ee=v.headers.get("sw-cache-date"),Ae=v.headers.get("sw-image-size")||v.headers.get("content-length");C.push({url:x.url,cacheDate:ee?parseInt(ee):void 0,size:Ae?parseInt(Ae):void 0})}}(p=s.source)==null||p.postMessage({type:"SW_DEBUG_CACHE_ENTRIES",cacheName:d||k,entries:C,total:_.length,offset:f,limit:u})}catch(T){(E=s.source)==null||E.postMessage({type:"SW_DEBUG_CACHE_ENTRIES",error:String(T)})}})()}else if(s.data&&s.data.type==="SW_CONSOLE_LOG_REPORT"){const{logLevel:d,logMessage:u,logStack:f,logSource:p,url:E}=s.data;qt({logLevel:d,logMessage:u,logStack:f,logSource:p,url:E})}else if(s.data&&s.data.type==="SW_DEBUG_GET_CONSOLE_LOGS")(async()=>{var d,u;try{const{limit:f=500,offset:p=0,filter:E}=s.data;let T=await Nt();if(E&&(E.logLevel&&(T=T.filter(C=>C.logLevel===E.logLevel)),E.search)){const C=E.search.toLowerCase();T=T.filter(R=>{var x,v;return((x=R.logMessage)==null?void 0:x.toLowerCase().includes(C))||((v=R.logStack)==null?void 0:v.toLowerCase().includes(C))})}const _=T.slice(p,p+f);(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CONSOLE_LOGS",logs:_,total:T.length,offset:p,limit:f})}catch(f){(u=s.source)==null||u.postMessage({type:"SW_DEBUG_CONSOLE_LOGS",logs:[],total:0,error:String(f)})}})();else if(s.data&&s.data.type==="SW_DEBUG_CLEAR_CONSOLE_LOGS")(async()=>{var d;be.length=0,await Ut(),(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CONSOLE_LOGS_CLEARED"})})();else if(s.data&&s.data.type==="SW_DEBUG_EXPORT_LOGS")(async()=>{var p;const d=await Nt(),u=Te(),f={exportTime:new Date().toISOString(),swVersion:ue,userAgent:"",status:Ne(),fetchLogs:j,consoleLogs:d,postmessageLogs:u};(p=s.source)==null||p.postMessage({type:"SW_DEBUG_EXPORT_DATA",data:f})})();else if(s.data&&s.data.type==="SW_DEBUG_GET_POSTMESSAGE_LOGS"){const{limit:d=200,offset:u=0,filter:f}=s.data;let p=Te();if(f&&(f.direction&&(p=p.filter(T=>T.direction===f.direction)),f.messageType)){const T=f.messageType.toLowerCase();p=p.filter(_=>{var C;return(C=_.messageType)==null?void 0:C.toLowerCase().includes(T)})}const E=p.slice(u,u+d);(w=s.source)==null||w.postMessage({type:"SW_DEBUG_POSTMESSAGE_LOGS",logs:E,total:p.length,offset:u,limit:d,stats:Cs()})}else if(s.data&&s.data.type==="SW_DEBUG_CLEAR_POSTMESSAGE_LOGS")ys(),(g=s.source)==null||g.postMessage({type:"SW_DEBUG_POSTMESSAGE_LOGS_CLEARED"});else if(s.data&&s.data.type==="CRASH_SNAPSHOT"){const d=s.data.snapshot;d&&(Go(d),A.clients.matchAll().then(u=>{u.forEach(f=>{f.postMessage({type:"SW_DEBUG_NEW_CRASH_SNAPSHOT",snapshot:d})})}))}else s.data&&s.data.type==="SW_DEBUG_GET_CRASH_SNAPSHOTS"?(async()=>{var d,u;try{const f=await Fo();(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CRASH_SNAPSHOTS",snapshots:f,total:f.length})}catch(f){(u=s.source)==null||u.postMessage({type:"SW_DEBUG_CRASH_SNAPSHOTS",snapshots:[],total:0,error:String(f)})}})():s.data&&s.data.type==="SW_DEBUG_CLEAR_CRASH_SNAPSHOTS"?(async()=>{var d;await $o(),(d=s.source)==null||d.postMessage({type:"SW_DEBUG_CRASH_SNAPSHOTS_CLEARED"})})():s.data&&s.data.type==="SW_DEBUG_GET_LLM_API_LOGS"?(async()=>{var d,u;try{const{getAllLLMApiLogs:f}=await Promise.resolve().then(()=>L),p=await f();(d=s.source)==null||d.postMessage({type:"SW_DEBUG_LLM_API_LOGS",logs:p,total:p.length})}catch(f){(u=s.source)==null||u.postMessage({type:"SW_DEBUG_LLM_API_LOGS",logs:[],total:0,error:String(f)})}})():s.data&&s.data.type==="SW_DEBUG_CLEAR_LLM_API_LOGS"&&(async()=>{var u;const{clearAllLLMApiLogs:d}=await Promise.resolve().then(()=>L);await d(),(u=s.source)==null||u.postMessage({type:"SW_DEBUG_LLM_API_LOGS_CLEARED"})})()});const qo="MemorySnapshotDB",J="snapshots",$t=50;async function ot(){return new Promise((s,e)=>{const t=indexedDB.open(qo,1);t.onerror=()=>e(t.error),t.onsuccess=()=>s(t.result),t.onupgradeneeded=o=>{const n=o.target.result;if(!n.objectStoreNames.contains(J)){const r=n.createObjectStore(J,{keyPath:"id"});r.createIndex("timestamp","timestamp",{unique:!1}),r.createIndex("type","type",{unique:!1})}}})}async function Go(s){try{const e=await ot(),t=e.transaction(J,"readwrite"),o=t.objectStore(J);o.put(s);const n=o.count();n.onsuccess=()=>{const r=n.result;if(r>$t){const i=o.index("timestamp").openCursor();let c=0;const l=r-$t;i.onsuccess=h=>{const m=h.target.result;m&&c<l&&(o.delete(m.value.id),c++,m.continue())}}},await new Promise((r,a)=>{t.oncomplete=()=>{e.close(),r()},t.onerror=()=>{e.close(),a(t.error)}})}catch(e){console.warn("[SW] Failed to save crash snapshot:",e)}}async function Fo(){try{const s=await ot(),o=s.transaction(J,"readonly").objectStore(J).index("timestamp");return new Promise((n,r)=>{const a=o.getAll();a.onsuccess=()=>{s.close();const i=a.result.sort((c,l)=>l.timestamp-c.timestamp);n(i)},a.onerror=()=>{s.close(),r(a.error)}})}catch(s){return console.warn("[SW] Failed to get crash snapshots:",s),[]}}async function $o(){try{const s=await ot(),e=s.transaction(J,"readwrite");e.objectStore(J).clear(),await new Promise((o,n)=>{e.oncomplete=()=>{s.close(),o()},e.onerror=()=>{s.close(),n(e.error)}}),console.log("[SW] Crash snapshots cleared")}catch(s){console.warn("[SW] Failed to clear crash snapshots:",s)}}const Ho=["ConsoleLogDB","ServiceWorkerDB","sw-task-queue","aitu-workspace","drawnix-unified-cache","drawnix-kv-storage","drawnix-prompts","drawnix-chat-db","MemorySnapshotDB"];function zo(s){try{const e=JSON.stringify(s);return new Blob([e]).size}catch{return 0}}async function Ko(s){return new Promise(e=>{try{const t=indexedDB.open(s);t.onerror=()=>e({count:0,totalSize:0}),t.onsuccess=()=>{const o=t.result,n=Array.from(o.objectStoreNames);if(n.length===0){o.close(),e({count:0,totalSize:0});return}let r=0,a=0,i=0,c=0;const l=10;try{const h=o.transaction(n,"readonly");for(const m of n){const S=h.objectStore(m),w=S.count();w.onsuccess=()=>{const g=w.result;if(r+=g,g>0){const d=S.openCursor();let u=0;d.onsuccess=f=>{const p=f.target.result;if(p&&u<l)a+=zo(p.value),i++,u++,p.continue();else if(c++,c===n.length){o.close();const E=i>0?a/i:0,T=Math.round(E*r);e({count:r,totalSize:T})}},d.onerror=()=>{if(c++,c===n.length){o.close();const f=i>0?a/i:0,p=Math.round(f*r);e({count:r,totalSize:p})}}}else c++,c===n.length&&(o.close(),e({count:r,totalSize:0}))},w.onerror=()=>{if(c++,c===n.length){o.close();const g=i>0?a/i:0,d=Math.round(g*r);e({count:r,totalSize:d})}}}}catch{o.close(),e({count:0,totalSize:0})}},t.onupgradeneeded=o=>{o.target.result.close();try{indexedDB.deleteDatabase(s)}catch{}e({count:0,totalSize:0})}}catch{e({count:0,totalSize:0})}})}async function jo(){const s={},e=[Pe,k,he,ve];for(const t of e)try{const o=await caches.open(t),n=await o.keys();let r=0;const a=Math.min(n.length,100);let i=0;for(let c=0;c<a;c++){const l=await o.match(n[c]);if(l){const h=l.headers.get("sw-image-size")||l.headers.get("content-length");h&&(i+=parseInt(h))}}a>0&&n.length>a?r=Math.round(i/a*n.length):r=i,s[t]={count:n.length,totalSize:r,type:"cache"}}catch{s[t]={count:0,totalSize:0,type:"cache"}}for(const t of Ho)try{const o=await Ko(t);o.count>0&&(s[`[IDB] ${t}`]={...o,type:"indexeddb"})}catch{}return s}async function Vo(s){try{await(await caches.open(k)).delete(s)}catch(e){throw console.error("Service Worker: Failed to delete cache entry:",s,e),e}}async function Qo(s){try{const e=await caches.open(k);let t=0;for(const o of s)try{await e.delete(o),t++}catch(n){console.warn("Service Worker: Failed to delete cache in batch:",o,n)}}catch(e){throw console.error("Service Worker: Failed to batch delete caches:",e),e}}async function Xo(){try{const s=await caches.open(k),e=await s.keys();for(const t of e)await s.delete(t)}catch(s){throw console.error("Service Worker: Failed to clear image cache:",s),s}}async function Ht(s,e,t){try{(await A.clients.matchAll()).forEach(n=>{n.postMessage({type:"IMAGE_CACHED",url:s,size:e,mimeType:t,timestamp:Date.now()})})}catch(o){console.warn("Service Worker: Failed to notify image cached:",o)}}async function Jo(){try{if(navigator.storage&&navigator.storage.estimate){const s=await navigator.storage.estimate(),e=s.usage||0,t=s.quota||0,o=t>0?e/t*100:0;o>90&&(console.warn("Service Worker: Storage quota warning:",{usage:e,quota:t,percentage:o}),(await A.clients.matchAll()).forEach(r=>{r.postMessage({type:"QUOTA_WARNING",usage:e,quota:t})}))}}catch(s){console.warn("Service Worker: Failed to check storage quota:",s)}}A.addEventListener("fetch",s=>{const e=new URL(s.request.url),t=Date.now();if(e.protocol!=="http:"&&e.protocol!=="https:"){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"other",details:`Skipped: non-http protocol (${e.protocol})`,status:0,duration:0});return}if(e.pathname.startsWith(po)){const o=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"cache-url",details:"Intercepting cache URL request"});s.respondWith(Zo(s.request).then(n=>(M(o,{status:n.status,statusText:n.statusText,responseType:n.type,duration:Date.now()-t,cached:n.status===200}),n)).catch(n=>{throw M(o,{error:String(n),duration:Date.now()-t}),n}));return}if(e.pathname.startsWith(mo)){const o=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"asset-library",details:"Intercepting asset library request"});s.respondWith(er(s.request).then(n=>(M(o,{status:n.status,statusText:n.statusText,responseType:n.type,duration:Date.now()-t,cached:n.status===200}),n)).catch(n=>{throw M(o,{error:String(n),duration:Date.now()-t}),n}));return}if(e.hostname==="cdn.i666.fun"){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:"Passthrough: cdn.i666.fun (fallback domain)",status:0,duration:0});return}if(e.hostname.endsWith(".volces.com")||e.hostname.endsWith(".volccdn.com")){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:"Passthrough: Volcengine domain (no CORS)",status:0,duration:0});return}if(e.hostname.endsWith(".aliyuncs.com")){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:"Passthrough: Aliyun OSS domain (no CORS)",status:0,duration:0});return}if(Co(e.hostname)){$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"passthrough",details:`Passthrough: ${e.hostname} (CORS failed domain, auto-detected)`,status:0,duration:0});return}if(Oo(e,s.request)){const o=Date.now(),n=s.request.headers.get("range"),r=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"video",headers:n?{range:n}:void 0,details:n?`Video Range request: ${n}`:"Video request"});s.respondWith(tr(s.request).then(a=>(M(r,{status:a.status,statusText:a.statusText,responseType:a.type,duration:Date.now()-o,responseHeaders:{"content-type":a.headers.get("content-type")||"","content-length":a.headers.get("content-length")||"","content-range":a.headers.get("content-range")||""}}),a)).catch(a=>{throw M(r,{error:String(a),duration:Date.now()-o}),a}));return}if(ko(e,s.request)){const o=Date.now(),n=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"font",details:"Font request"});s.respondWith(Yo(s.request).then(r=>(M(n,{status:r.status,statusText:r.statusText,responseType:r.type,duration:Date.now()-o,cached:r.headers.has("sw-cache-date")}),r)).catch(r=>{throw M(n,{error:String(r),duration:Date.now()-o}),r}));return}if(e.origin!==location.origin&&Io(e,s.request)){const o=Date.now(),n=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"image",details:"External image request"});s.respondWith(nr(s.request).then(r=>(M(n,{status:r.status,statusText:r.statusText,responseType:r.type,duration:Date.now()-o,cached:r.headers.has("sw-cache-date"),size:parseInt(r.headers.get("content-length")||"0")}),r)).catch(r=>{throw M(n,{error:String(r),duration:Date.now()-o}),r}));return}if(s.request.method==="GET"){const o=s.request.mode==="navigate",n=s.request.destination!=="";if(o||n){const r=Date.now(),a=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"static",details:o?"Navigation request":`Static resource (${s.request.destination})`});s.respondWith(sr(s.request).then(i=>(M(a,{status:i.status,statusText:i.statusText,responseType:i.type,duration:Date.now()-r}),i)).catch(i=>{throw M(a,{error:String(i),duration:Date.now()-r}),i}));return}}if(G){const o=$({type:"fetch",url:s.request.url,method:s.request.method,requestType:"xhr",details:`XHR/API request (${s.request.method})`});s.respondWith((async()=>{try{const n=s.request.clone();let r,a={};if(s.request.headers.forEach((m,S)=>{a[S]=m}),["POST","PUT","PATCH"].includes(s.request.method))try{const m=s.request.headers.get("content-type")||"";m.includes("application/json")?(r=await n.text(),r.length>2e3&&(r=r.substring(0,2e3)+"... (truncated)")):m.includes("application/x-www-form-urlencoded")?(r=await n.text(),r.length>2e3&&(r=r.substring(0,2e3)+"... (truncated)")):r=`[${m||"binary data"}]`}catch{r="[unable to read body]"}M(o,{headers:a,details:r?`XHR/API request (${s.request.method})
6
6
 
7
7
  Request Body:
8
8
  ${r}`:`XHR/API request (${s.request.method})`});const i=await fetch(s.request),c=i.clone();let l,h={};i.headers.forEach((m,S)=>{h[S]=m});try{const m=i.headers.get("content-type")||"";m.includes("application/json")||m.includes("text/")?(l=await c.text(),l.length>5e3&&(l=l.substring(0,5e3)+"... (truncated)")):l=`[${m||"binary data"}] (${i.headers.get("content-length")||"unknown"} bytes)`}catch{l="[unable to read response body]"}return M(o,{status:i.status,statusText:i.statusText,responseType:i.type,duration:Date.now()-t,responseHeaders:h,size:parseInt(i.headers.get("content-length")||"0"),details:r?`XHR/API request (${s.request.method})
package/version.json CHANGED
@@ -1,10 +1,6 @@
1
1
  {
2
- "version": "0.5.14",
3
- "buildTime": "2026-01-20T00:40:25.063Z",
2
+ "version": "0.5.15",
3
+ "buildTime": "2026-01-20T01:14:42.914Z",
4
4
  "gitCommit": "unknown",
5
- "changelog": [
6
- "修复 workflows Map 和 setInterval 内存泄漏",
7
- "封装函数不应被绕过、页面卸载清理定时器",
8
- "添加更多版本"
9
- ]
5
+ "changelog": []
10
6
  }