@hienlh/ppm 0.13.75 → 0.13.76

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.
Files changed (128) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/assets/skills/ppm/SKILL.md +1 -1
  3. package/assets/skills/ppm/references/cli-reference.md +4 -4
  4. package/assets/skills/ppm/references/http-api.md +7 -1
  5. package/bun.lock +2142 -0
  6. package/bunfig.toml +2 -0
  7. package/dist/web/assets/ai-settings-section-D0VMZ4aE.js +1 -0
  8. package/dist/web/assets/{api-settings-BJTjIG4U.js → api-settings-Byph7lae.js} +1 -1
  9. package/dist/web/assets/architecture-PBZL5I3N-DyeqgxGw.js +1 -0
  10. package/dist/web/assets/{audio-preview-BQUzmaMW.js → audio-preview-DXCxll7f.js} +1 -1
  11. package/dist/web/assets/chat-tab-D5j5gP5j.js +16 -0
  12. package/dist/web/assets/code-editor-CL2gcvDj.js +10 -0
  13. package/dist/web/assets/{conflict-editor-CrpXDFE1.js → conflict-editor-RMsNwUKp.js} +1 -1
  14. package/dist/web/assets/{csv-preview-asMfgR0r.js → csv-preview-CwEbP_iZ.js} +1 -1
  15. package/dist/web/assets/{data-grid-overlay-editor-DGjqvYn6.js → data-grid-overlay-editor-C36FRqE8.js} +1 -1
  16. package/dist/web/assets/database-viewer-2TbU0m7s.js +1 -0
  17. package/dist/web/assets/{diff-viewer-CdZ15fOk.js → diff-viewer--SSMwMoS.js} +1 -1
  18. package/dist/web/assets/{docx-preview-AgoO5zwo.js → docx-preview-BL398ELS.js} +1 -1
  19. package/dist/web/assets/{esm-xVTUq__o.js → esm-DH3rpl0I.js} +1 -1
  20. package/dist/web/assets/{extension-webview-C4D4PnO3.js → extension-webview-DrnDwQpM.js} +2 -2
  21. package/dist/web/assets/git-log-panel-u6ehykcl.js +1 -0
  22. package/dist/web/assets/gitGraph-HDMCJU4V-CZAWeLUi.js +1 -0
  23. package/dist/web/assets/{glide-data-grid-BfXnM2CC.js → glide-data-grid-Benw7NI4.js} +6 -6
  24. package/dist/web/assets/globe-CQ8NAYvi.js +1 -0
  25. package/dist/web/assets/{image-preview-CyL9Lj_O.js → image-preview-DeNH71Ez.js} +1 -1
  26. package/dist/web/assets/index-BS3CQIT3.js +27 -0
  27. package/dist/web/assets/info-3K5VOQVL-BqVOLnRc.js +1 -0
  28. package/dist/web/assets/{input-CArJe9WS.js → input-DSELw5zU.js} +1 -1
  29. package/dist/web/assets/keybindings-store-gFa7vUoe.js +1 -0
  30. package/dist/web/assets/{markdown-renderer-Cat4uT8B.js → markdown-renderer-D5B629qw.js} +3 -3
  31. package/dist/web/assets/notification-store-qViiZZaY.js +1 -0
  32. package/dist/web/assets/{number-overlay-editor-DtUBprPW.js → number-overlay-editor-JsUdft7z.js} +1 -1
  33. package/dist/web/assets/packet-RMMSAZCW-BGMrAgbD.js +1 -0
  34. package/dist/web/assets/{panel-store-C9VAhbZz.js → panel-store-DlvwzOll.js} +1 -1
  35. package/dist/web/assets/{pdf-preview-BSrz_N0g.js → pdf-preview-yUMARG8r.js} +1 -1
  36. package/dist/web/assets/pie-UPGHQEXC-9IRPAyAe.js +1 -0
  37. package/dist/web/assets/port-forwarding-tab-D7rVcasa.js +1 -0
  38. package/dist/web/assets/{postgres-viewer-GpXLzmnT.js → postgres-viewer-C28tRuh5.js} +3 -3
  39. package/dist/web/assets/{project-store-DlbHpIq0.js → project-store-CpC02pIv.js} +1 -1
  40. package/dist/web/assets/radar-KQ55EAFF-CxjdSb6M.js +1 -0
  41. package/dist/web/assets/refresh-cw-CRD2qr4U.js +1 -0
  42. package/dist/web/assets/{settings-store-DQUFTPk2.js → settings-store-MXJgFUnl.js} +2 -2
  43. package/dist/web/assets/settings-tab-0kWZtlCi.js +1 -0
  44. package/dist/web/assets/{sql-query-editor-PFN7evxv.js → sql-query-editor-DCx7kPlY.js} +1 -1
  45. package/dist/web/assets/sqlite-viewer-W1RhaCr0.js +1 -0
  46. package/dist/web/assets/system-monitor-tab-CJojQd3x.js +1 -0
  47. package/dist/web/assets/{tab-store-CIcbSn0c.js → tab-store-Bdw8DIbZ.js} +1 -1
  48. package/dist/web/assets/{terminal-tab-D2OwQv1h.js → terminal-tab-B1_sAuIi.js} +2 -2
  49. package/dist/web/assets/treemap-KZPCXAKY-BYrmfSj5.js +1 -0
  50. package/dist/web/assets/{use-blob-url-DrPfBQBM.js → use-blob-url-CBi0HMq5.js} +1 -1
  51. package/dist/web/assets/{use-monaco-theme-BLIgarH5.js → use-monaco-theme-CbzQcrwD.js} +1 -1
  52. package/dist/web/assets/{vendor-mermaid-DkqjpqJK.js → vendor-mermaid-D2cOxeao.js} +3 -3
  53. package/dist/web/assets/{video-preview-49zZk7VQ.js → video-preview-D-nAiQsv.js} +1 -1
  54. package/dist/web/index.html +20 -17
  55. package/dist/web/sw.js +1 -1
  56. package/package.json +1 -1
  57. package/src/index.ts +0 -0
  58. package/src/providers/claude-agent-sdk.ts +6 -2
  59. package/src/server/index.ts +2 -0
  60. package/src/server/routes/chat.ts +7 -6
  61. package/src/server/routes/push.ts +54 -0
  62. package/src/services/cloud-ws.service.ts +1 -27
  63. package/src/services/config.service.ts +1 -1
  64. package/src/services/db.service.ts +24 -0
  65. package/src/services/notification.service.ts +5 -14
  66. package/src/services/push-notification.service.ts +104 -0
  67. package/src/types/config.ts +7 -0
  68. package/src/web/components/chat/chat-tab.tsx +10 -0
  69. package/src/web/components/settings/settings-tab.tsx +66 -12
  70. package/src/web/hooks/use-push-notification.ts +114 -0
  71. package/src/web/sw.ts +45 -0
  72. package/.opencode/.env.example +0 -98
  73. package/.opencode/skills/ads-management/scripts/.env.example +0 -13
  74. package/.opencode/skills/ai-multimodal/.env.example +0 -230
  75. package/.opencode/skills/cip-design/.env.example +0 -6
  76. package/.opencode/skills/devops/.env.example +0 -76
  77. package/.opencode/skills/docs-seeker/.env.example +0 -15
  78. package/.opencode/skills/elevenlabs/.env.example +0 -3
  79. package/.opencode/skills/marketing-dashboard/.env.example +0 -15
  80. package/.opencode/skills/marketing-dashboard/app/.env.example +0 -2
  81. package/.opencode/skills/marketing-dashboard/server/.env.example +0 -2
  82. package/.opencode/skills/mcp-management/scripts/dist/analyze-tools.js +0 -70
  83. package/.opencode/skills/mcp-management/scripts/dist/cli.js +0 -160
  84. package/.opencode/skills/mcp-management/scripts/dist/mcp-client.js +0 -183
  85. package/.opencode/skills/payment-integration/scripts/.env.example +0 -20
  86. package/.opencode/skills/sequential-thinking/.env.example +0 -8
  87. package/dist/web/assets/architecture-PBZL5I3N-CkdUQjA_.js +0 -1
  88. package/dist/web/assets/chat-tab-B80a21gx.js +0 -16
  89. package/dist/web/assets/code-editor-hFO6vAKT.js +0 -10
  90. package/dist/web/assets/database-viewer-CAjJc7bL.js +0 -1
  91. package/dist/web/assets/git-log-panel-J0pVWvZl.js +0 -1
  92. package/dist/web/assets/gitGraph-HDMCJU4V-D3UR56AG.js +0 -1
  93. package/dist/web/assets/index-Dd6YEaE6.js +0 -27
  94. package/dist/web/assets/info-3K5VOQVL-DUhLSKI2.js +0 -1
  95. package/dist/web/assets/keybindings-store-C1yHwKEc.js +0 -1
  96. package/dist/web/assets/notification-store-CBTVrgEf.js +0 -1
  97. package/dist/web/assets/packet-RMMSAZCW-BIpeVUGW.js +0 -1
  98. package/dist/web/assets/pie-UPGHQEXC-CNoizzjb.js +0 -1
  99. package/dist/web/assets/port-forwarding-tab-BpeFzbAM.js +0 -1
  100. package/dist/web/assets/radar-KQ55EAFF-7dns-ho5.js +0 -1
  101. package/dist/web/assets/settings-tab-Cjiu2egJ.js +0 -1
  102. package/dist/web/assets/sqlite-viewer-ONh1tmxh.js +0 -1
  103. package/dist/web/assets/system-monitor-tab-BznIBj8p.js +0 -1
  104. package/dist/web/assets/treemap-KZPCXAKY-D3DZCLoE.js +0 -1
  105. /package/dist/web/assets/{api-client-BK4NPNoY.js → api-client-DG9qwosT.js} +0 -0
  106. /package/dist/web/assets/{chevron-down-CiFNPrfI.js → chevron-down-BMo4cBth.js} +0 -0
  107. /package/dist/web/assets/{chevron-right-BzAdxJRG.js → chevron-right-CD8e6Aj4.js} +0 -0
  108. /package/dist/web/assets/{code-CuravVys.js → code-DiNmA3eR.js} +0 -0
  109. /package/dist/web/assets/{csv-parser-D1b_lg2T.js → csv-parser-B_TuHmnd.js} +0 -0
  110. /package/dist/web/assets/{data-grid-types-DzL5W2em.js → data-grid-types-CO_3iSwd.js} +0 -0
  111. /package/dist/web/assets/{database-NmqHg29g.js → database-Dc8mr-dP.js} +0 -0
  112. /package/dist/web/assets/{dist-CohudVKa.js → dist-C1jciI67.js} +0 -0
  113. /package/dist/web/assets/{dist-BM2EHhLH.js → dist-D4dFaZkK.js} +0 -0
  114. /package/dist/web/assets/{file-exclamation-point-Baz81y5z.js → file-exclamation-point-B__2Hrd6.js} +0 -0
  115. /package/dist/web/assets/{katex-CHaeM9QC.js → katex-DveWxdWJ.js} +0 -0
  116. /package/dist/web/assets/{lib-LPmTkMu4.js → lib-D4YDpYv4.js} +0 -0
  117. /package/dist/web/assets/{react-DHBl6KRc.js → react-BXxixfbh.js} +0 -0
  118. /package/dist/web/assets/{search-BEy08Exr.js → search-D90WJ5fo.js} +0 -0
  119. /package/dist/web/assets/{shield-check-77W0OMbn.js → shield-check-DeIMQtEj.js} +0 -0
  120. /package/dist/web/assets/{shield-off-C_MK1u09.js → shield-off-D4jBmG5E.js} +0 -0
  121. /package/dist/web/assets/{sparkles-CulWHe4c.js → sparkles-DyeiGE7Q.js} +0 -0
  122. /package/dist/web/assets/{table-BzjWcs87.js → table-DCYlHUNQ.js} +0 -0
  123. /package/dist/web/assets/{text-wrap-DJz9Bgpa.js → text-wrap-B3mYv9Yo.js} +0 -0
  124. /package/dist/web/assets/{trash-2-D5P4y8p_.js → trash-2-DkIfBY8d.js} +0 -0
  125. /package/dist/web/assets/{utils-CSCvNZxE.js → utils-Bs_TFEQf.js} +0 -0
  126. /package/dist/web/assets/{vendor-xterm-t3d5xZdz.js → vendor-xterm-BHJtSw6L.js} +0 -0
  127. /package/dist/web/assets/{wifi-CgM9T6HR.js → wifi-DifNnmbA.js} +0 -0
  128. /package/dist/web/assets/{x-Dx3jsRgu.js → x-WwAMX3EB.js} +0 -0
@@ -1 +1 @@
1
- import{b as e}from"./vendor-markdown-0Mxgxy0L.js";import{t}from"./file-exclamation-point-Baz81y5z.js";import"./api-client-BK4NPNoY.js";import{pt as n}from"./index-Dd6YEaE6.js";import{t as r}from"./use-blob-url-DrPfBQBM.js";var i=e();function a({filePath:e,projectName:a}){let{blobUrl:o,error:s}=r(e,a);return s?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,i.jsx)(t,{className:`size-10 text-text-subtle`}),(0,i.jsx)(`p`,{className:`text-sm`,children:`Failed to load video.`})]}):o?(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,i.jsx)(`video`,{src:o,controls:!0,className:`max-w-full max-h-full`})}):(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,i.jsx)(n,{className:`size-5 animate-spin text-text-subtle`})})}export{a as VideoPreview};
1
+ import{b as e}from"./vendor-markdown-0Mxgxy0L.js";import{t}from"./file-exclamation-point-B__2Hrd6.js";import"./api-client-DG9qwosT.js";import{et as n}from"./index-BS3CQIT3.js";import{t as r}from"./use-blob-url-CBi0HMq5.js";var i=e();function a({filePath:e,projectName:a}){let{blobUrl:o,error:s}=r(e,a);return s?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,i.jsx)(t,{className:`size-10 text-text-subtle`}),(0,i.jsx)(`p`,{className:`text-sm`,children:`Failed to load video.`})]}):o?(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,i.jsx)(`video`,{src:o,controls:!0,className:`max-w-full max-h-full`})}):(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,i.jsx)(n,{className:`size-5 animate-spin text-text-subtle`})})}export{a as VideoPreview};
@@ -39,28 +39,31 @@
39
39
  <link rel="preconnect" href="https://fonts.googleapis.com" />
40
40
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
41
41
  <link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600;700&family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
42
- <script type="module" crossorigin src="/assets/index-Dd6YEaE6.js"></script>
42
+ <script type="module" crossorigin src="/assets/index-BS3CQIT3.js"></script>
43
43
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-FhOqtrmT.js">
44
- <link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-DkqjpqJK.js">
44
+ <link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-D2cOxeao.js">
45
45
  <link rel="modulepreload" crossorigin href="/assets/vendor-markdown-0Mxgxy0L.js">
46
46
  <link rel="modulepreload" crossorigin href="/assets/vendor-ui-UXCWAcmi.js">
47
- <link rel="modulepreload" crossorigin href="/assets/utils-CSCvNZxE.js">
47
+ <link rel="modulepreload" crossorigin href="/assets/utils-Bs_TFEQf.js">
48
48
  <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BjHrJDVb.js">
49
- <link rel="modulepreload" crossorigin href="/assets/x-Dx3jsRgu.js">
50
- <link rel="modulepreload" crossorigin href="/assets/input-CArJe9WS.js">
51
- <link rel="modulepreload" crossorigin href="/assets/react-DHBl6KRc.js">
52
- <link rel="modulepreload" crossorigin href="/assets/api-client-BK4NPNoY.js">
53
- <link rel="modulepreload" crossorigin href="/assets/settings-store-DQUFTPk2.js">
49
+ <link rel="modulepreload" crossorigin href="/assets/x-WwAMX3EB.js">
50
+ <link rel="modulepreload" crossorigin href="/assets/input-DSELw5zU.js">
51
+ <link rel="modulepreload" crossorigin href="/assets/react-BXxixfbh.js">
52
+ <link rel="modulepreload" crossorigin href="/assets/api-client-DG9qwosT.js">
53
+ <link rel="modulepreload" crossorigin href="/assets/settings-store-MXJgFUnl.js">
54
54
  <link rel="modulepreload" crossorigin href="/assets/eye-off-BacF7RVS.js">
55
- <link rel="modulepreload" crossorigin href="/assets/chevron-down-CiFNPrfI.js">
56
- <link rel="modulepreload" crossorigin href="/assets/database-NmqHg29g.js">
57
- <link rel="modulepreload" crossorigin href="/assets/chevron-right-BzAdxJRG.js">
58
- <link rel="modulepreload" crossorigin href="/assets/search-BEy08Exr.js">
59
- <link rel="modulepreload" crossorigin href="/assets/trash-2-D5P4y8p_.js">
60
- <link rel="modulepreload" crossorigin href="/assets/api-settings-BJTjIG4U.js">
61
- <link rel="modulepreload" crossorigin href="/assets/panel-store-C9VAhbZz.js">
62
- <link rel="modulepreload" crossorigin href="/assets/project-store-DlbHpIq0.js">
63
- <link rel="modulepreload" crossorigin href="/assets/tab-store-CIcbSn0c.js">
55
+ <link rel="modulepreload" crossorigin href="/assets/chevron-down-BMo4cBth.js">
56
+ <link rel="modulepreload" crossorigin href="/assets/globe-CQ8NAYvi.js">
57
+ <link rel="modulepreload" crossorigin href="/assets/trash-2-DkIfBY8d.js">
58
+ <link rel="modulepreload" crossorigin href="/assets/refresh-cw-CRD2qr4U.js">
59
+ <link rel="modulepreload" crossorigin href="/assets/api-settings-Byph7lae.js">
60
+ <link rel="modulepreload" crossorigin href="/assets/ai-settings-section-D0VMZ4aE.js">
61
+ <link rel="modulepreload" crossorigin href="/assets/database-Dc8mr-dP.js">
62
+ <link rel="modulepreload" crossorigin href="/assets/chevron-right-CD8e6Aj4.js">
63
+ <link rel="modulepreload" crossorigin href="/assets/search-D90WJ5fo.js">
64
+ <link rel="modulepreload" crossorigin href="/assets/panel-store-DlvwzOll.js">
65
+ <link rel="modulepreload" crossorigin href="/assets/project-store-CpC02pIv.js">
66
+ <link rel="modulepreload" crossorigin href="/assets/tab-store-Bdw8DIbZ.js">
64
67
  <link rel="stylesheet" crossorigin href="/assets/index-fyMt5gpO.css">
65
68
  <link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
66
69
  <body class="bg-[#0f1419] text-[#e5e7eb] font-sans antialiased">
package/dist/web/sw.js CHANGED
@@ -1 +1 @@
1
- try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"cfb8ac5eb9cc1012e7ef26a67a92f707","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":null,"url":"assets/project-store-DlbHpIq0.js"},{"revision":null,"url":"assets/utils-CSCvNZxE.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":null,"url":"assets/postgres-viewer-GpXLzmnT.js"},{"revision":null,"url":"assets/diff-viewer-CdZ15fOk.js"},{"revision":null,"url":"assets/katex-CHaeM9QC.js"},{"revision":null,"url":"assets/settings-tab-Cjiu2egJ.js"},{"revision":null,"url":"assets/terminal-tab-D2OwQv1h.js"},{"revision":null,"url":"assets/arrow-down-D825m4vm.js"},{"revision":null,"url":"assets/index-fyMt5gpO.css"},{"revision":null,"url":"assets/api-settings-BJTjIG4U.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-CNoizzjb.js"},{"revision":null,"url":"assets/x-Dx3jsRgu.js"},{"revision":null,"url":"assets/esm-xVTUq__o.js"},{"revision":null,"url":"assets/glide-data-grid-BfXnM2CC.js"},{"revision":null,"url":"assets/table-BzjWcs87.js"},{"revision":null,"url":"assets/text-wrap-DJz9Bgpa.js"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/trash-2-D5P4y8p_.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-7dns-ho5.js"},{"revision":null,"url":"assets/sparkles-CulWHe4c.js"},{"revision":null,"url":"assets/react-DHBl6KRc.js"},{"revision":null,"url":"assets/file-exclamation-point-Baz81y5z.js"},{"revision":null,"url":"assets/github.min-D2BCvnWf.css"},{"revision":null,"url":"assets/docx-preview-AgoO5zwo.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-D3DZCLoE.js"},{"revision":null,"url":"assets/image-preview-CyL9Lj_O.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/code-editor-hFO6vAKT.js"},{"revision":null,"url":"assets/chevron-right-BzAdxJRG.js"},{"revision":null,"url":"assets/dist-CohudVKa.js"},{"revision":null,"url":"assets/glide-data-grid-nthEL3fk.css"},{"revision":null,"url":"assets/settings-store-DQUFTPk2.js"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/audio-preview-BQUzmaMW.js"},{"revision":null,"url":"assets/shield-off-C_MK1u09.js"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/markdown-renderer-Cat4uT8B.js"},{"revision":null,"url":"assets/wifi-CgM9T6HR.js"},{"revision":null,"url":"assets/tab-store-CIcbSn0c.js"},{"revision":null,"url":"assets/sqlite-viewer-ONh1tmxh.js"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/use-monaco-theme-BLIgarH5.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/panel-store-C9VAhbZz.js"},{"revision":null,"url":"assets/data-grid-types-DzL5W2em.js"},{"revision":null,"url":"assets/database-NmqHg29g.js"},{"revision":null,"url":"assets/chevron-down-CiFNPrfI.js"},{"revision":null,"url":"assets/keybindings-store-C1yHwKEc.js"},{"revision":null,"url":"assets/database-viewer-CAjJc7bL.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/data-grid-overlay-editor-DGjqvYn6.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-D3UR56AG.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/notification-store-CBTVrgEf.js"},{"revision":null,"url":"assets/vendor-ui-UXCWAcmi.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BIpeVUGW.js"},{"revision":null,"url":"assets/system-monitor-tab-BznIBj8p.js"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/github-dark-dimmed.min-BrpRStFV.css"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/pdf-preview-BSrz_N0g.js"},{"revision":null,"url":"assets/arrow-up-Rcw6_KKu.js"},{"revision":null,"url":"assets/git-log-panel-J0pVWvZl.js"},{"revision":null,"url":"assets/eye-off-BacF7RVS.js"},{"revision":null,"url":"assets/vendor-mermaid-DkqjpqJK.js"},{"revision":null,"url":"assets/conflict-editor-CrpXDFE1.js"},{"revision":null,"url":"assets/lib-LPmTkMu4.js"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/vendor-xterm-t3d5xZdz.js"},{"revision":null,"url":"assets/port-forwarding-tab-BpeFzbAM.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/extension-webview-C4D4PnO3.js"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/architecture-PBZL5I3N-CkdUQjA_.js"},{"revision":null,"url":"assets/number-overlay-editor-DtUBprPW.js"},{"revision":null,"url":"assets/csv-preview-asMfgR0r.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/index-Dd6YEaE6.js"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/code-CuravVys.js"},{"revision":null,"url":"assets/sql-query-editor-PFN7evxv.js"},{"revision":null,"url":"assets/use-blob-url-DrPfBQBM.js"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/search-BEy08Exr.js"},{"revision":null,"url":"assets/api-client-BK4NPNoY.js"},{"revision":null,"url":"assets/shield-check-77W0OMbn.js"},{"revision":null,"url":"assets/chat-tab-B80a21gx.js"},{"revision":null,"url":"assets/video-preview-49zZk7VQ.js"},{"revision":null,"url":"assets/input-CArJe9WS.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/info-3K5VOQVL-DUhLSKI2.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/dist-BM2EHhLH.js"},{"revision":null,"url":"assets/csv-parser-D1b_lg2T.js"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"}]);
1
+ try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"71f8ebcbe9a661db4591c19ba9a24294","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":null,"url":"assets/x-WwAMX3EB.js"},{"revision":null,"url":"assets/wifi-DifNnmbA.js"},{"revision":null,"url":"assets/video-preview-D-nAiQsv.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/vendor-xterm-BHJtSw6L.js"},{"revision":null,"url":"assets/vendor-ui-UXCWAcmi.js"},{"revision":null,"url":"assets/vendor-mermaid-D2cOxeao.js"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/utils-Bs_TFEQf.js"},{"revision":null,"url":"assets/use-monaco-theme-CbzQcrwD.js"},{"revision":null,"url":"assets/use-blob-url-CBi0HMq5.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-BYrmfSj5.js"},{"revision":null,"url":"assets/trash-2-DkIfBY8d.js"},{"revision":null,"url":"assets/text-wrap-B3mYv9Yo.js"},{"revision":null,"url":"assets/terminal-tab-B1_sAuIi.js"},{"revision":null,"url":"assets/table-DCYlHUNQ.js"},{"revision":null,"url":"assets/tab-store-Bdw8DIbZ.js"},{"revision":null,"url":"assets/system-monitor-tab-CJojQd3x.js"},{"revision":null,"url":"assets/sqlite-viewer-W1RhaCr0.js"},{"revision":null,"url":"assets/sql-query-editor-DCx7kPlY.js"},{"revision":null,"url":"assets/sparkles-DyeiGE7Q.js"},{"revision":null,"url":"assets/shield-off-D4jBmG5E.js"},{"revision":null,"url":"assets/shield-check-DeIMQtEj.js"},{"revision":null,"url":"assets/settings-tab-0kWZtlCi.js"},{"revision":null,"url":"assets/settings-store-MXJgFUnl.js"},{"revision":null,"url":"assets/search-D90WJ5fo.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/refresh-cw-CRD2qr4U.js"},{"revision":null,"url":"assets/react-BXxixfbh.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-CxjdSb6M.js"},{"revision":null,"url":"assets/project-store-CpC02pIv.js"},{"revision":null,"url":"assets/postgres-viewer-C28tRuh5.js"},{"revision":null,"url":"assets/port-forwarding-tab-D7rVcasa.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-9IRPAyAe.js"},{"revision":null,"url":"assets/pdf-preview-yUMARG8r.js"},{"revision":null,"url":"assets/panel-store-DlvwzOll.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BGMrAgbD.js"},{"revision":null,"url":"assets/number-overlay-editor-JsUdft7z.js"},{"revision":null,"url":"assets/notification-store-qViiZZaY.js"},{"revision":null,"url":"assets/markdown-renderer-D5B629qw.js"},{"revision":null,"url":"assets/lib-D4YDpYv4.js"},{"revision":null,"url":"assets/keybindings-store-gFa7vUoe.js"},{"revision":null,"url":"assets/katex-DveWxdWJ.js"},{"revision":null,"url":"assets/input-DSELw5zU.js"},{"revision":null,"url":"assets/info-3K5VOQVL-BqVOLnRc.js"},{"revision":null,"url":"assets/index-fyMt5gpO.css"},{"revision":null,"url":"assets/index-BS3CQIT3.js"},{"revision":null,"url":"assets/image-preview-DeNH71Ez.js"},{"revision":null,"url":"assets/globe-CQ8NAYvi.js"},{"revision":null,"url":"assets/glide-data-grid-nthEL3fk.css"},{"revision":null,"url":"assets/glide-data-grid-Benw7NI4.js"},{"revision":null,"url":"assets/github.min-D2BCvnWf.css"},{"revision":null,"url":"assets/github-dark-dimmed.min-BrpRStFV.css"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-CZAWeLUi.js"},{"revision":null,"url":"assets/git-log-panel-u6ehykcl.js"},{"revision":null,"url":"assets/file-exclamation-point-B__2Hrd6.js"},{"revision":null,"url":"assets/eye-off-BacF7RVS.js"},{"revision":null,"url":"assets/extension-webview-DrnDwQpM.js"},{"revision":null,"url":"assets/esm-DH3rpl0I.js"},{"revision":null,"url":"assets/docx-preview-BL398ELS.js"},{"revision":null,"url":"assets/dist-D4dFaZkK.js"},{"revision":null,"url":"assets/dist-C1jciI67.js"},{"revision":null,"url":"assets/diff-viewer--SSMwMoS.js"},{"revision":null,"url":"assets/database-viewer-2TbU0m7s.js"},{"revision":null,"url":"assets/database-Dc8mr-dP.js"},{"revision":null,"url":"assets/data-grid-types-CO_3iSwd.js"},{"revision":null,"url":"assets/data-grid-overlay-editor-C36FRqE8.js"},{"revision":null,"url":"assets/csv-preview-CwEbP_iZ.js"},{"revision":null,"url":"assets/csv-parser-B_TuHmnd.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/conflict-editor-RMsNwUKp.js"},{"revision":null,"url":"assets/code-editor-CL2gcvDj.js"},{"revision":null,"url":"assets/code-DiNmA3eR.js"},{"revision":null,"url":"assets/chevron-right-CD8e6Aj4.js"},{"revision":null,"url":"assets/chevron-down-BMo4cBth.js"},{"revision":null,"url":"assets/chat-tab-D5j5gP5j.js"},{"revision":null,"url":"assets/audio-preview-DXCxll7f.js"},{"revision":null,"url":"assets/arrow-up-Rcw6_KKu.js"},{"revision":null,"url":"assets/arrow-down-D825m4vm.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-DyeqgxGw.js"},{"revision":null,"url":"assets/api-settings-Byph7lae.js"},{"revision":null,"url":"assets/api-client-DG9qwosT.js"},{"revision":null,"url":"assets/ai-settings-section-D0VMZ4aE.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.svg`,badge:`/icon-192.svg`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.13.75",
3
+ "version": "0.13.76",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
File without changes
@@ -1112,8 +1112,12 @@ export class ClaudeAgentSdkProvider implements AIProvider {
1112
1112
  // Partial assistant message — streaming text deltas
1113
1113
  if ((msg as any).type === "partial" || (msg as any).type === "stream_event") {
1114
1114
  const partial = msg as any;
1115
- // Track assistant UUID from top-level messages (not subagent children)
1116
- if (!parentId && partial.uuid) lastAssistantUuid = partial.uuid;
1115
+ // NOTE: Do NOT capture lastAssistantUuid from stream_event/partial here.
1116
+ // SDKPartialAssistantMessage.uuid is a per-event uuid (not the persisted message uuid).
1117
+ // Per SDK contract: "The message ID should be from SDKAssistantMessage.uuid".
1118
+ // Capturing it here produces ghost uuids when the final `assistant` message never
1119
+ // arrives (e.g., auto-compact mid-turn, account rotation abort) — causing fork to fail.
1120
+ // Canonical uuid is captured below in the `assistant` branch only.
1117
1121
  // Handle stream_event (raw API events) for text deltas
1118
1122
  if ((msg as any).type === "stream_event") {
1119
1123
  const event = partial.event;
@@ -5,6 +5,7 @@ import { VERSION } from "../version.ts";
5
5
  import { authMiddleware } from "./middleware/auth.ts";
6
6
  import { projectRoutes } from "./routes/projects.ts";
7
7
  import { settingsRoutes } from "./routes/settings.ts";
8
+ import { pushRoutes } from "./routes/push.ts";
8
9
  import { tunnelRoutes } from "./routes/tunnel.ts";
9
10
  import { staticRoutes } from "./routes/static.ts";
10
11
  import { projectScopedRouter } from "./routes/project-scoped.ts";
@@ -146,6 +147,7 @@ app.route("/api/system", resourceRoutes);
146
147
  app.route("/api/settings", settingsRoutes);
147
148
  app.route("/api/settings/mcp", mcpRoutes);
148
149
  app.route("/api/tunnel", tunnelRoutes);
150
+ app.route("/api/push", pushRoutes);
149
151
  app.route("/api/projects", projectRoutes);
150
152
  app.route("/api/project/:projectName", projectScopedRouter);
151
153
  app.route("/api/postgres", postgresRoutes);
@@ -401,12 +401,13 @@ chatRoutes.post("/sessions/:id/fork", async (c) => {
401
401
  };
402
402
  return c.json(ok({ ...forkedSession, forkedFrom: sourceId }), 201);
403
403
  } catch (forkErr) {
404
- // Message UUID may no longer exist after SDK compaction fall back to fresh session
405
- console.warn(`[chat] forkAtMessage failed (message may be compacted): ${(forkErr as Error).message}`);
406
- const session = await chatService.createSession(providerId, {
407
- projectName, projectPath, title: "Forked Chat",
408
- });
409
- return c.json(ok({ ...session, forkedFrom: sourceId }), 201);
404
+ // SDK forkSession throws when upToMessageId is invalid or missing from the
405
+ // source JSONL (e.g., ghost uuid never persisted, message belongs to another session).
406
+ // Surface as 400 instead of silently creating an empty session FE can show a toast
407
+ // and let the user pick a different fork point.
408
+ const msg = (forkErr as Error).message;
409
+ console.warn(`[chat] forkAtMessage failed: ${msg}`);
410
+ return c.json(err(`Cannot fork at message: ${msg}`), 400);
410
411
  }
411
412
  } else {
412
413
  // No messageId (fork at first message) — create a fresh empty session
@@ -0,0 +1,54 @@
1
+ import { Hono } from "hono";
2
+ import { pushService } from "../../services/push-notification.service.ts";
3
+ import { ok, err } from "../../types/api.ts";
4
+
5
+ export const pushRoutes = new Hono();
6
+
7
+ /** GET /push/vapid-key — return VAPID public key for frontend subscription */
8
+ pushRoutes.get("/vapid-key", (c) => {
9
+ try {
10
+ const publicKey = pushService.getVapidPublicKey();
11
+ return c.json(ok({ publicKey }));
12
+ } catch (e) {
13
+ return c.json(err((e as Error).message), 500);
14
+ }
15
+ });
16
+
17
+ /** POST /push/subscribe — save a push subscription */
18
+ pushRoutes.post("/subscribe", async (c) => {
19
+ try {
20
+ const body = await c.req.json<{
21
+ endpoint?: string;
22
+ keys?: { p256dh?: string; auth?: string };
23
+ expirationTime?: number | null;
24
+ }>();
25
+
26
+ if (!body.endpoint || !body.keys?.p256dh || !body.keys?.auth) {
27
+ return c.json(err("Invalid subscription: missing endpoint or keys"), 400);
28
+ }
29
+
30
+ pushService.saveSubscription({
31
+ endpoint: body.endpoint,
32
+ keys: { p256dh: body.keys.p256dh, auth: body.keys.auth },
33
+ expirationTime: body.expirationTime,
34
+ });
35
+
36
+ return c.json(ok(true));
37
+ } catch (e) {
38
+ return c.json(err((e as Error).message), 400);
39
+ }
40
+ });
41
+
42
+ /** DELETE /push/subscribe — remove a push subscription by endpoint */
43
+ pushRoutes.delete("/subscribe", async (c) => {
44
+ try {
45
+ const body = await c.req.json<{ endpoint?: string }>();
46
+ if (!body.endpoint) {
47
+ return c.json(err("Missing endpoint"), 400);
48
+ }
49
+ pushService.removeSubscription(body.endpoint);
50
+ return c.json(ok(true));
51
+ } catch (e) {
52
+ return c.json(err((e as Error).message), 400);
53
+ }
54
+ });
@@ -44,17 +44,7 @@ interface CommandResultMsg extends WsMessage {
44
44
  data?: Record<string, unknown>;
45
45
  }
46
46
 
47
- interface NotificationMsg extends WsMessage {
48
- type: "notification";
49
- title: string;
50
- body: string;
51
- project: string;
52
- sessionId: string;
53
- sessionTitle?: string;
54
- notificationType: "done" | "approval_request" | "question";
55
- }
56
-
57
- type OutboundMsg = HeartbeatMsg | StateChangeMsg | CommandAckMsg | CommandResultMsg | NotificationMsg;
47
+ type OutboundMsg = HeartbeatMsg | StateChangeMsg | CommandAckMsg | CommandResultMsg;
58
48
 
59
49
  interface CommandMsg extends WsMessage {
60
50
  type: "command";
@@ -141,22 +131,6 @@ export function isConnected(): boolean {
141
131
  return ws !== null && ws.readyState <= WebSocket.OPEN;
142
132
  }
143
133
 
144
- /** Send a push notification via Cloud WS (Cloud dispatches Web Push to subscribed browsers) */
145
- export function sendNotification(payload: {
146
- title: string;
147
- body: string;
148
- project: string;
149
- sessionId: string;
150
- sessionTitle?: string;
151
- notificationType: "done" | "approval_request" | "question";
152
- }): void {
153
- send({
154
- type: "notification",
155
- ...payload,
156
- timestamp: new Date().toISOString(),
157
- } as NotificationMsg);
158
- }
159
-
160
134
  // ─── Internal ───────────────────────────────────────
161
135
 
162
136
  function doConnect(): void {
@@ -16,7 +16,7 @@ import {
16
16
 
17
17
  /** Top-level config keys stored in the config table (not projects) */
18
18
  const CONFIG_TABLE_KEYS: (keyof PpmConfig)[] = [
19
- "device_name", "port", "host", "theme", "auth", "ai", "telegram", "clawbot",
19
+ "device_name", "port", "host", "theme", "auth", "ai", "push", "telegram", "clawbot",
20
20
  ];
21
21
 
22
22
  /** File filter config keys stored in the config table */
@@ -907,6 +907,30 @@ export function deleteSessionTitle(sessionId: string): void {
907
907
  }
908
908
 
909
909
  // ---------------------------------------------------------------------------
910
+ // Push subscription helpers
911
+ // ---------------------------------------------------------------------------
912
+
913
+ export interface PushSubRow {
914
+ endpoint: string;
915
+ p256dh: string;
916
+ auth: string;
917
+ expiration_time: string | null;
918
+ }
919
+
920
+ export function getPushSubscriptions(): PushSubRow[] {
921
+ return getDb().query("SELECT endpoint, p256dh, auth, expiration_time FROM push_subscriptions").all() as PushSubRow[];
922
+ }
923
+
924
+ export function upsertPushSubscription(endpoint: string, p256dh: string, auth: string, expirationTime?: string | null): void {
925
+ getDb().query(
926
+ "INSERT INTO push_subscriptions (endpoint, p256dh, auth, expiration_time) VALUES (?, ?, ?, ?) ON CONFLICT(endpoint) DO UPDATE SET p256dh = excluded.p256dh, auth = excluded.auth, expiration_time = excluded.expiration_time",
927
+ ).run(endpoint, p256dh, auth, expirationTime ?? null);
928
+ }
929
+
930
+ export function deletePushSubscription(endpoint: string): void {
931
+ getDb().query("DELETE FROM push_subscriptions WHERE endpoint = ?").run(endpoint);
932
+ }
933
+
910
934
  // ---------------------------------------------------------------------------
911
935
  // Session log helpers
912
936
  // ---------------------------------------------------------------------------
@@ -19,24 +19,15 @@ class NotificationService {
19
19
  broadcastGlobalEvent(event);
20
20
  }
21
21
 
22
- /** Broadcast notification to all channels (cloud push, telegram). Fire-and-forget. */
23
- async broadcast(type: NotificationType, payload: NotificationPayload): Promise<void> {
22
+ /** Broadcast notification to all channels (push, telegram). Fire-and-forget. */
23
+ async broadcast(_type: NotificationType, payload: NotificationPayload): Promise<void> {
24
24
  const tasks: Promise<void>[] = [];
25
25
  const userOnline = hasActiveClient();
26
26
 
27
- // Cloud Push (replaces local Web Push) Cloud dispatches to all subscribed browsers
27
+ // Push notificationsalways send (works as ambient alert)
28
28
  tasks.push(
29
- import("./cloud-ws.service.ts")
30
- .then(({ sendNotification }) => {
31
- sendNotification({
32
- title: payload.title,
33
- body: payload.body,
34
- project: payload.project,
35
- sessionId: payload.sessionId,
36
- sessionTitle: payload.sessionTitle,
37
- notificationType: type,
38
- });
39
- })
29
+ import("./push-notification.service.ts")
30
+ .then(({ pushService }) => pushService.notifyAll(payload.title, payload.body))
40
31
  .catch(() => {}),
41
32
  );
42
33
 
@@ -0,0 +1,104 @@
1
+ import webpush from "web-push";
2
+ import { configService } from "./config.service.ts";
3
+ import type { PushConfig } from "../types/config.ts";
4
+ import {
5
+ getPushSubscriptions,
6
+ upsertPushSubscription,
7
+ deletePushSubscription,
8
+ } from "./db.service.ts";
9
+
10
+ interface PushSubscriptionData {
11
+ endpoint: string;
12
+ keys: { p256dh: string; auth: string };
13
+ expirationTime?: number | null;
14
+ }
15
+
16
+ class PushNotificationService {
17
+ private initialized = false;
18
+
19
+ /** Initialize VAPID keys — auto-generate if missing */
20
+ init(): void {
21
+ if (this.initialized) return;
22
+
23
+ let push = configService.get("push") as PushConfig | undefined;
24
+ if (!push?.vapid_public_key || !push?.vapid_private_key) {
25
+ const keys = webpush.generateVAPIDKeys();
26
+ push = {
27
+ vapid_public_key: keys.publicKey,
28
+ vapid_private_key: keys.privateKey,
29
+ vapid_subject: "https://ppm.local",
30
+ };
31
+ configService.set("push", push);
32
+ configService.save();
33
+ console.log("[push] VAPID keys generated and saved to config");
34
+ }
35
+
36
+ webpush.setVapidDetails(
37
+ push.vapid_subject,
38
+ push.vapid_public_key,
39
+ push.vapid_private_key,
40
+ );
41
+ this.initialized = true;
42
+ }
43
+
44
+ /** Get VAPID public key for frontend subscription */
45
+ getVapidPublicKey(): string {
46
+ this.init();
47
+ const push = configService.get("push") as PushConfig | undefined;
48
+ return push?.vapid_public_key ?? "";
49
+ }
50
+
51
+ /** Save a new push subscription */
52
+ saveSubscription(sub: PushSubscriptionData): void {
53
+ upsertPushSubscription(
54
+ sub.endpoint,
55
+ sub.keys.p256dh,
56
+ sub.keys.auth,
57
+ sub.expirationTime != null ? String(sub.expirationTime) : null,
58
+ );
59
+ }
60
+
61
+ /** Remove a push subscription by endpoint */
62
+ removeSubscription(endpoint: string): void {
63
+ deletePushSubscription(endpoint);
64
+ }
65
+
66
+ /** Send push notification to all subscriptions (fire-and-forget) */
67
+ async notifyAll(title: string, body: string): Promise<void> {
68
+ this.init();
69
+ const dbSubs = getPushSubscriptions();
70
+ if (dbSubs.length === 0) return;
71
+
72
+ const payload = JSON.stringify({ title, body });
73
+ const expired: string[] = [];
74
+
75
+ const subs: PushSubscriptionData[] = dbSubs.map((r) => ({
76
+ endpoint: r.endpoint,
77
+ keys: { p256dh: r.p256dh, auth: r.auth },
78
+ expirationTime: r.expiration_time ? Number(r.expiration_time) : null,
79
+ }));
80
+
81
+ await Promise.allSettled(
82
+ subs.map(async (sub) => {
83
+ try {
84
+ await webpush.sendNotification(sub, payload);
85
+ } catch (error: unknown) {
86
+ const statusCode = (error as { statusCode?: number }).statusCode;
87
+ if (statusCode === 410 || statusCode === 404) {
88
+ expired.push(sub.endpoint);
89
+ }
90
+ }
91
+ }),
92
+ );
93
+
94
+ for (const endpoint of expired) {
95
+ deletePushSubscription(endpoint);
96
+ }
97
+ if (expired.length > 0) {
98
+ console.log(`[push] Removed ${expired.length} expired subscriptions`);
99
+ }
100
+ }
101
+ }
102
+
103
+ /** Singleton push notification service */
104
+ export const pushService = new PushNotificationService();
@@ -1,3 +1,9 @@
1
+ export interface PushConfig {
2
+ vapid_public_key: string;
3
+ vapid_private_key: string;
4
+ vapid_subject: string;
5
+ }
6
+
1
7
  export interface TelegramConfig {
2
8
  bot_token: string;
3
9
  }
@@ -22,6 +28,7 @@ export interface PpmConfig {
22
28
  auth: AuthConfig;
23
29
  projects: ProjectConfig[];
24
30
  ai: AIConfig;
31
+ push?: PushConfig;
25
32
  telegram?: TelegramConfig;
26
33
  clawbot?: PPMBotConfig;
27
34
  cloud_url?: string;
@@ -1,5 +1,6 @@
1
1
  import { useState, useCallback, useRef, useEffect } from "react";
2
2
  import { Loader2, Upload, X } from "lucide-react";
3
+ import { toast } from "sonner";
3
4
  import { api, projectUrl } from "@/lib/api-client";
4
5
  import { useChat } from "@/hooks/use-chat";
5
6
  import { useUsage } from "@/hooks/use-usage";
@@ -203,6 +204,15 @@ export function ChatTab({ metadata, tabId }: ChatTabProps) {
203
204
  });
204
205
  } catch (e) {
205
206
  console.error("Fork failed:", e);
207
+ // Backend returns 400 when upToMessageId is missing from source JSONL (ghost uuid
208
+ // from interrupted streams, compaction edge cases). Surface to user instead of
209
+ // silent failure / empty session.
210
+ const msg = (e as Error)?.message || "Unknown error";
211
+ toast.error("Cannot fork from this message", {
212
+ description: msg.includes("not found") || msg.includes("Invalid upToMessageId")
213
+ ? "The original message is no longer available in the session transcript. Try forking from a different message."
214
+ : msg,
215
+ });
206
216
  }
207
217
  }, [sessionId, projectName, providerId]);
208
218