@electron-memory/monitor 0.2.5 → 0.2.6
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.
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +47 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +47 -4
- package/dist/index.mjs.map +1 -1
- package/dist/ui/assets/index-DnuSyhKD.js +9 -0
- package/dist/ui/assets/index-DrFTVGFf.css +1 -0
- package/dist/ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/ui/assets/index-BTI73y9e.css +0 -1
- package/dist/ui/assets/index-mExwYeTZ.js +0 -9
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import{r as De,a as Ve,g as Ge,b as h,R as Z,L as fe,C as ve,X as ge,Y as Ne,T as X,c as Q,d as C,e as ze,P as He,f as _e,h as Oe,i as We}from"./vendor-BMPuFM9B.js";(function(){const a=document.createElement("link").relList;if(a&&a.supports&&a.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))r(c);new MutationObserver(c=>{for(const n of c)if(n.type==="childList")for(const u of n.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&r(u)}).observe(document,{childList:!0,subtree:!0});function i(c){const n={};return c.integrity&&(n.integrity=c.integrity),c.referrerPolicy&&(n.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?n.credentials="include":c.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function r(c){if(c.ep)return;c.ep=!0;const n=i(c);fetch(c.href,n)}})();var J={exports:{}},R={};/**
|
|
2
|
+
* @license React
|
|
3
|
+
* react-jsx-runtime.production.min.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/var de;function qe(){if(de)return R;de=1;var s=De(),a=Symbol.for("react.element"),i=Symbol.for("react.fragment"),r=Object.prototype.hasOwnProperty,c=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,n={key:!0,ref:!0,__self:!0,__source:!0};function u(m,t,p){var d,b={},g=null,v=null;p!==void 0&&(g=""+p),t.key!==void 0&&(g=""+t.key),t.ref!==void 0&&(v=t.ref);for(d in t)r.call(t,d)&&!n.hasOwnProperty(d)&&(b[d]=t[d]);if(m&&m.defaultProps)for(d in t=m.defaultProps,t)b[d]===void 0&&(b[d]=t[d]);return{$$typeof:a,type:m,key:g,ref:v,props:b,_owner:c.current}}return R.Fragment=i,R.jsx=u,R.jsxs=u,R}var me;function Je(){return me||(me=1,J.exports=qe()),J.exports}var e=Je(),G={},he;function Ye(){if(he)return G;he=1;var s=Ve();return G.createRoot=s.createRoot,G.hydrateRoot=s.hydrateRoot,G}var Ze=Ye();const Xe=Ge(Ze),B=({title:s,value:a,unit:i,trend:r,trendValue:c,color:n="#646cff",icon:u})=>{const m=r==="up"?"↑":r==="down"?"↓":"→",t=r==="up"?"#ff4d4f":r==="down"?"#52c41a":"#faad14";return e.jsxs("div",{className:"metric-card",style:{borderTopColor:n},children:[e.jsxs("div",{className:"metric-card-header",children:[u&&e.jsx("span",{className:"metric-card-icon",children:u}),e.jsx("span",{className:"metric-card-title",children:s})]}),e.jsxs("div",{className:"metric-card-value",children:[e.jsx("span",{className:"metric-card-number",children:a}),i&&e.jsx("span",{className:"metric-card-unit",children:i})]}),r&&c&&e.jsxs("div",{className:"metric-card-trend",style:{color:t},children:[e.jsx("span",{children:m}),e.jsx("span",{children:c})]})]})},ue=s=>s>1024*1024?`${(s/1024/1024).toFixed(1)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,Qe=s=>{switch(s){case"Browser":return"#646cff";case"Tab":return"#61dafb";case"GPU":return"#f5a623";case"Utility":return"#8b8b8b";default:return"#999"}},es=s=>{switch(s){case"Browser":return"主进程";case"Tab":return"渲染进程";case"GPU":return"GPU";case"Utility":return"辅助进程";default:return s}},ee=({processes:s})=>{const a=[...s].sort((i,r)=>r.memory.workingSetSize-i.memory.workingSetSize);return e.jsx("div",{className:"process-table-container",children:e.jsxs("table",{className:"process-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"PID"}),e.jsx("th",{children:"类型"}),e.jsx("th",{children:"名称"}),e.jsx("th",{children:"工作集"}),e.jsx("th",{children:"峰值"}),e.jsx("th",{children:"CPU"})]})}),e.jsx("tbody",{children:a.map(i=>e.jsxs("tr",{className:i.isMonitorProcess?"monitor-process":"",children:[e.jsx("td",{className:"pid",children:i.pid}),e.jsx("td",{children:e.jsx("span",{className:"process-type-badge",style:{backgroundColor:Qe(i.type)},children:es(i.type)})}),e.jsxs("td",{className:"process-name",children:[i.isMonitorProcess?"🔍 ":"",i.name||i.windowTitle||"-"]}),e.jsx("td",{className:"memory-value",children:ue(i.memory.workingSetSize)}),e.jsx("td",{className:"memory-value",children:ue(i.memory.peakWorkingSetSize)}),e.jsxs("td",{className:"cpu-value",children:[i.cpu.percentCPUUsage.toFixed(1),"%"]})]},i.pid))})]})})},xe=s=>{const a=new Date(s);return`${a.getHours().toString().padStart(2,"0")}:${a.getMinutes().toString().padStart(2,"0")}:${a.getSeconds().toString().padStart(2,"0")}`},A={total:"#646cff",browser:"#f5a623",renderer:"#61dafb",gpu:"#ff6b6b",other:"#8b8b8b"},be=({snapshots:s,height:a=300})=>{var u,m;const i=h.useMemo(()=>s.map(t=>{const p=t.processes.filter(v=>v.type==="Browser").reduce((v,N)=>v+N.memory.workingSetSize,0),d=t.processes.filter(v=>v.type==="Tab"&&!v.isMonitorProcess).reduce((v,N)=>v+N.memory.workingSetSize,0),b=t.processes.filter(v=>v.type==="GPU").reduce((v,N)=>v+N.memory.workingSetSize,0),g=t.processes.filter(v=>!v.isMonitorProcess&&v.type!=="Browser"&&v.type!=="GPU"&&v.type!=="Tab").reduce((v,N)=>v+N.memory.workingSetSize,0);return{timestamp:t.timestamp,total:Math.round(t.totalWorkingSetSize/1024*10)/10,browser:Math.round(p/1024*10)/10,renderer:Math.round(d/1024*10)/10,gpu:Math.round(b/1024*10)/10,other:Math.round(g/1024*10)/10}}),[s]),r=h.useMemo(()=>{const t=[];for(const p of s)p.marks&&t.push(...p.marks);return t},[s]);if(i.length===0)return e.jsx("div",{className:"chart-empty",children:"等待数据采集..."});const c=((u=i[0])==null?void 0:u.timestamp)??0,n=((m=i[i.length-1])==null?void 0:m.timestamp)??0;return e.jsx(Z,{width:"100%",height:a,children:e.jsxs(fe,{data:i,margin:{top:5,right:30,left:20,bottom:5},children:[e.jsx(ve,{strokeDasharray:"3 3",stroke:"rgba(255,255,255,0.1)"}),e.jsx(ge,{type:"number",dataKey:"timestamp",domain:[c,n],stroke:"rgba(255,255,255,0.5)",fontSize:12,tickFormatter:t=>xe(t)}),e.jsx(Ne,{stroke:"rgba(255,255,255,0.5)",fontSize:12,tickFormatter:t=>`${t} MB`}),e.jsx(X,{contentStyle:{background:"rgba(26, 26, 46, 0.95)",border:"1px solid rgba(255,255,255,0.1)",borderRadius:8,color:"#e0e0e0"},labelFormatter:t=>xe(Number(t)),formatter:(t,p)=>[`${t.toFixed(1)} MB`,p]}),e.jsx(Q,{}),e.jsx(C,{type:"monotone",dataKey:"total",name:"总内存",stroke:A.total,dot:!1,strokeWidth:2}),e.jsx(C,{type:"monotone",dataKey:"browser",name:"主进程",stroke:A.browser,dot:!1,strokeWidth:1.5}),e.jsx(C,{type:"monotone",dataKey:"renderer",name:"渲染进程",stroke:A.renderer,dot:!1,strokeWidth:1.5}),e.jsx(C,{type:"monotone",dataKey:"gpu",name:"GPU",stroke:A.gpu,dot:!1,strokeWidth:1.5}),e.jsx(C,{type:"monotone",dataKey:"other",name:"其他",stroke:A.other,dot:!1,strokeWidth:1,strokeDasharray:"4 2"}),r.map((t,p)=>e.jsx(ze,{x:t.timestamp,stroke:"#faad14",strokeDasharray:"3 3",strokeWidth:1.5,label:{value:t.label,position:"top",fill:"#faad14",fontSize:10}},`${t.timestamp}-${p}-${t.label}`))]})})},M=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,se=({v8Detail:s,title:a="主进程 V8 堆详情(Browser / Node)"})=>{const i=(s==null?void 0:s.heapTotal)>0?Math.round((s.heapUsed||0)/s.heapTotal*100):0;return e.jsxs("div",{className:"v8-heap-detail",children:[e.jsx("h3",{children:a}),e.jsxs("p",{className:"v8-heap-detail-caption",children:["来自主进程内 Node 的 ",e.jsx("code",{children:"process.memoryUsage"})," 与 ",e.jsx("code",{children:"v8.getHeapStatistics"}),",不是各网页标签里的 Chromium JS 堆(后者见「渲染进程 V8」表)。"]}),e.jsxs("div",{className:"v8-overview",children:[e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Heap Used"}),e.jsx("span",{className:"v8-stat-value",children:M(s.heapUsed)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Heap Total"}),e.jsx("span",{className:"v8-stat-value",children:M(s.heapTotal)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"使用率"}),e.jsxs("span",{className:`v8-stat-value ${i>80?"danger":i>60?"warn":""}`,children:[i,"%"]})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"External"}),e.jsx("span",{className:"v8-stat-value",children:M(s.external)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"ArrayBuffers"}),e.jsx("span",{className:"v8-stat-value",children:M(s.arrayBuffers)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"RSS"}),e.jsx("span",{className:"v8-stat-value",children:M(s.rss)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Heap Limit"}),e.jsx("span",{className:"v8-stat-value",children:M(s.heapSizeLimit)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Malloced"}),e.jsx("span",{className:"v8-stat-value",children:M(s.mallocedMemory)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Detached Contexts"}),e.jsx("span",{className:`v8-stat-value ${(s.numberOfDetachedContexts??0)>0?"danger":""}`,children:s.numberOfDetachedContexts??0})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Native Contexts"}),e.jsx("span",{className:"v8-stat-value",children:s.numberOfNativeContexts??0})]})]}),s.heapSpaces&&s.heapSpaces.length>0&&e.jsxs("div",{className:"v8-heap-spaces",children:[e.jsx("h4",{children:"堆空间详情"}),e.jsxs("table",{className:"v8-spaces-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"空间"}),e.jsx("th",{children:"大小"}),e.jsx("th",{children:"已使用"}),e.jsx("th",{children:"使用率"}),e.jsx("th",{children:"可用"})]})}),e.jsx("tbody",{children:s.heapSpaces.map(r=>{const c=r.size??0,n=r.usedSize??0,u=r.availableSize??0,m=c>0?Math.round(n/c*100):0;return e.jsxs("tr",{children:[e.jsx("td",{className:"space-name",children:r.name}),e.jsx("td",{children:M(c)}),e.jsx("td",{children:M(n)}),e.jsx("td",{children:e.jsxs("div",{className:"usage-bar",children:[e.jsx("div",{className:"usage-bar-fill",style:{width:`${m}%`,backgroundColor:m>80?"#ff4d4f":m>60?"#faad14":"#52c41a"}}),e.jsxs("span",{className:"usage-bar-text",children:[m,"%"]})]})}),e.jsx("td",{children:M(u)})]},r.name)})})]})]})]})},z=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`;function ss(s,a,i){const r=s.find(n=>n.pid===a);if(r!=null&&r.name)return r.name;if(r!=null&&r.windowTitle)return r.windowTitle;const c=s.find(n=>n.webContentsId===i);return c!=null&&c.name?c.name:c!=null&&c.windowTitle?c.windowTitle:`渲染进程 PID ${a}`}const te=({processes:s,details:a,emptyHint:i})=>{const r=h.useMemo(()=>a!=null&&a.length?[...a].sort((n,u)=>n.pid-u.pid):[],[a]);return e.jsxs("div",{className:"renderer-v8-panel",children:[e.jsx("h3",{children:"渲染进程 V8(各标签页 Chromium JS 堆)"}),e.jsxs("p",{className:"renderer-v8-caption",children:["数据来自各渲染进程定时 IPC 上报,与上方「主进程 V8」不是同一套运行时。进程表中的",e.jsx("strong",{children:"所有"})," Tab 行会同时列出,与当前是否激活该标签无关。"]}),r.length===0?e.jsx("p",{className:"renderer-v8-empty",children:i??"当前快照无渲染进程 V8 数据。请在业务 WebContents 的 preload 中调用 injectRendererReporter(),并设置 enableRendererDetail: true。"}):e.jsx("div",{className:"report-marks-table-wrap",children:e.jsxs("table",{className:"report-marks-table renderer-v8-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"页面 / 标题"}),e.jsx("th",{children:"PID"}),e.jsx("th",{children:"webContentsId"}),e.jsx("th",{children:"Heap Used"}),e.jsx("th",{children:"Heap Total"}),e.jsx("th",{children:"External"}),e.jsx("th",{children:"ArrayBuffers"})]})}),e.jsx("tbody",{children:r.map(n=>e.jsxs("tr",{children:[e.jsx("td",{className:"mark-label-cell",children:ss(s,n.pid,n.webContentsId)}),e.jsx("td",{children:n.pid}),e.jsx("td",{children:n.webContentsId}),e.jsx("td",{children:z(n.heapUsed)}),e.jsx("td",{children:z(n.heapTotal)}),e.jsx("td",{children:z(n.external)}),e.jsx("td",{children:z(n.arrayBuffers)})]},`${n.pid}-${n.webContentsId}`))})]})})]})};function ts(s){var r;const a=[];let i=0;for(const c of s)if((r=c.marks)!=null&&r.length)for(const n of c.marks)i+=1,a.push({key:`m-${n.timestamp}-${i}-${n.label.slice(0,24)}`,mark:n,snapshot:c});return a.sort((c,n)=>c.mark.timestamp-n.mark.timestamp),a}const H={browser:"#f5a623",renderer:"#61dafb",gpu:"#ff6b6b",other:"#8b8b8b"},ye=s=>{const a=new Date(s);return`${a.getHours().toString().padStart(2,"0")}:${a.getMinutes().toString().padStart(2,"0")}:${a.getSeconds().toString().padStart(2,"0")}`},rs=(s,a)=>s.length<=a?s:`${s.slice(0,a-1)}…`;function as(s){const a=s.processes.filter(n=>n.type==="Browser").reduce((n,u)=>n+u.memory.workingSetSize,0),i=s.processes.filter(n=>n.type==="Tab"&&!n.isMonitorProcess).reduce((n,u)=>n+u.memory.workingSetSize,0),r=s.processes.filter(n=>n.type==="GPU").reduce((n,u)=>n+u.memory.workingSetSize,0),c=s.processes.filter(n=>!n.isMonitorProcess&&n.type!=="Browser"&&n.type!=="GPU"&&n.type!=="Tab").reduce((n,u)=>n+u.memory.workingSetSize,0);return{browser:Math.round(a/1024*10)/10,renderer:Math.round(i/1024*10)/10,gpu:Math.round(r/1024*10)/10,other:Math.round(c/1024*10)/10}}function ns(s){return s.map((a,i)=>{const r=as(a.snapshot),c=rs(a.mark.label,14);return{key:a.key,axisLabel:`#${i+1} ${c}`,title:`${ye(a.mark.timestamp)} · ${a.mark.label}`,mark:a.mark,snapshot:a.snapshot,...r}})}function _(s,a){const{cx:i,cy:r,index:c,stroke:n}=s;return i==null||r==null||c==null?null:e.jsx("circle",{cx:i,cy:r,r:4,fill:n||"#888",stroke:"rgba(0,0,0,0.35)",strokeWidth:1,style:{cursor:"pointer"},onClick:()=>a(c)})}const Se=({snapshots:s,variant:a="dashboard"})=>{const i=h.useMemo(()=>ts(s),[s]),r=h.useMemo(()=>ns(i),[i]),[c,n]=h.useState("");h.useEffect(()=>{if(r.length===0){n("");return}n(t=>t&&r.some(p=>p.key===t)?t:r[0].key)},[r]);const u=h.useCallback(t=>{const p=r[t];p&&n(p.key)},[r]),m=h.useMemo(()=>r.find(t=>t.key===c)??null,[r,c]);return r.length===0?e.jsx("div",{className:"mark-explorer mark-explorer-empty",children:e.jsx("p",{className:"mark-explorer-hint",children:a==="dashboard"?"暂无标记:在代码中调用 monitor.mark(),或使用上方「事件标记」在下一拍采样写入后,此处会出现各标记时刻的内存对比图。":"当前加载的快照中无标记数据;若会话内曾打标,请确认未过度缩小时间范围。"})}):e.jsxs("div",{className:"mark-explorer",children:[e.jsxs("div",{className:"mark-explorer-toolbar",children:[e.jsxs("label",{className:"mark-explorer-select-label",children:[e.jsx("span",{children:"选中标记"}),e.jsx("select",{className:"mark-explorer-select",value:c,onChange:t=>n(t.target.value),children:r.map(t=>e.jsx("option",{value:t.key,children:t.title},t.key))})]}),e.jsxs("span",{className:"mark-explorer-caption",children:["折线按标记时间顺序连接各",e.jsx("strong",{children:"采样时刻"}),"工作集(MB):Browser / 渲染 / GPU / 其他。点击折线上圆点可切换下方进程表与 V8(主进程 + 各渲染进程)。"]})]}),e.jsx("div",{className:"mark-explorer-chart-wrap",children:e.jsx(Z,{width:"100%",height:320,children:e.jsxs(fe,{data:r,margin:{top:8,right:16,left:8,bottom:48},children:[e.jsx(ve,{strokeDasharray:"3 3",stroke:"rgba(255,255,255,0.08)"}),e.jsx(ge,{dataKey:"axisLabel",stroke:"rgba(255,255,255,0.5)",fontSize:11,interval:0,angle:-28,textAnchor:"end",height:70}),e.jsx(Ne,{stroke:"rgba(255,255,255,0.5)",fontSize:12,tickFormatter:t=>`${t} MB`,label:{value:"工作集",angle:-90,position:"insideLeft",fill:"rgba(255,255,255,0.45)",fontSize:11}}),e.jsx(X,{contentStyle:{background:"rgba(26, 26, 46, 0.96)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"#e0e0e0"},formatter:(t,p)=>[`${t.toFixed(1)} MB`,p],labelFormatter:(t,p)=>{var b;const d=(b=p==null?void 0:p[0])==null?void 0:b.payload;return d?d.title:""}}),e.jsx(Q,{}),e.jsx(C,{type:"monotone",dataKey:"browser",name:"主进程",stroke:H.browser,strokeWidth:2,dot:t=>_(t,u),activeDot:{r:6},connectNulls:!0}),e.jsx(C,{type:"monotone",dataKey:"renderer",name:"渲染进程",stroke:H.renderer,strokeWidth:2,dot:t=>_(t,u),activeDot:{r:6},connectNulls:!0}),e.jsx(C,{type:"monotone",dataKey:"gpu",name:"GPU",stroke:H.gpu,strokeWidth:2,dot:t=>_(t,u),activeDot:{r:6},connectNulls:!0}),e.jsx(C,{type:"monotone",dataKey:"other",name:"其他",stroke:H.other,strokeWidth:2,dot:t=>_(t,u),activeDot:{r:6},connectNulls:!0})]})})}),m&&e.jsxs("div",{className:"mark-explorer-detail",children:[e.jsxs("div",{className:"mark-explorer-detail-head",children:[e.jsxs("h4",{children:["📌 标记「",m.mark.label,"」时刻详情"]}),e.jsxs("p",{className:"mark-explorer-detail-meta",children:["采样时间 ",ye(m.snapshot.timestamp),"(seq #",m.snapshot.seq,") · 进程 ",m.snapshot.processes.length," 个",m.mark.metadata&&Object.keys(m.mark.metadata).length>0&&e.jsxs("span",{className:"mark-explorer-meta-json",children:[" · ",JSON.stringify(m.mark.metadata)]})]})]}),e.jsxs("div",{className:"section mark-explorer-process-section",children:[e.jsx("h3",{children:"📋 进程详情"}),e.jsx(ee,{processes:m.snapshot.processes})]}),m.snapshot.mainProcessV8Detail&&e.jsx("div",{className:"section mark-explorer-v8-section",children:e.jsx(se,{v8Detail:m.snapshot.mainProcessV8Detail,title:"📌 标记时刻 · 主进程 V8 堆详情"})}),e.jsx("div",{className:"section mark-explorer-renderer-v8-section",children:e.jsx(te,{processes:m.snapshot.processes,details:m.snapshot.rendererDetails})})]})]})},is={Browser:"#7c83ff",Tab:"#61dafb",GPU:"#ffb347",Utility:"#a8a8a8",Zygote:"#ff8a8a"},os={Browser:"主进程",Tab:"渲染进程",GPU:"GPU",Utility:"辅助进程",Zygote:"Zygote"},pe=Math.PI/180,ls=({cx:s,cy:a,midAngle:i,outerRadius:r,name:c,value:n,percent:u})=>{const m=r+25,t=s+m*Math.cos(-i*pe),p=a+m*Math.sin(-i*pe);return e.jsx("text",{x:t,y:p,fill:"#e0e0e0",textAnchor:t>s?"start":"end",dominantBaseline:"central",fontSize:12,children:`${c} ${n}MB (${(u*100).toFixed(1)}%)`})},ke=({processes:s,height:a=280})=>{const i=h.useMemo(()=>{const r=new Map;for(const c of s){if(c.isMonitorProcess)continue;const n=c.type;r.set(n,(r.get(n)||0)+c.memory.workingSetSize)}return Array.from(r.entries()).map(([c,n])=>({name:os[c]||c,value:Math.round(n/1024),color:is[c]||"#bbb"})).sort((c,n)=>n.value-c.value)},[s]);return e.jsx(Z,{width:"100%",height:a,children:e.jsxs(He,{children:[e.jsx(_e,{data:i,dataKey:"value",nameKey:"name",cx:"50%",cy:"50%",outerRadius:80,innerRadius:28,label:ls,labelLine:{stroke:"rgba(255,255,255,0.4)",strokeWidth:1},paddingAngle:2,isAnimationActive:!1,children:i.map((r,c)=>e.jsx(Oe,{fill:r.color,stroke:"rgba(0,0,0,0.3)",strokeWidth:1},c))}),e.jsx(X,{contentStyle:{background:"rgba(26, 26, 46, 0.95)",border:"1px solid rgba(255,255,255,0.1)",borderRadius:8,color:"#e0e0e0"},formatter:r=>[`${r} MB`,"内存"]}),e.jsx(Q,{})]})})},cs={info:{icon:"ℹ️",color:"#1890ff",bg:"rgba(24, 144, 255, 0.1)"},warning:{icon:"⚠️",color:"#faad14",bg:"rgba(250, 173, 20, 0.1)"},critical:{icon:"🔴",color:"#ff4d4f",bg:"rgba(255, 77, 79, 0.1)"}},ds=({anomalies:s,onClear:a,onAction:i})=>{const[r,c]=h.useState(null);if(s.length===0)return e.jsxs("div",{className:"alert-panel-empty",children:[e.jsx("span",{className:"alert-panel-empty-icon",children:"✅"}),e.jsx("span",{children:"暂无异常检测到"})]});const n=u=>{c(m=>m===u?null:u)};return e.jsxs("div",{className:"alert-panel",children:[e.jsxs("div",{className:"alert-panel-header",children:[e.jsxs("span",{children:["异常告警 (",s.length,")"]}),e.jsx("button",{className:"alert-panel-clear",onClick:a,children:"清除"})]}),e.jsx("div",{className:"alert-panel-list",children:s.slice(-10).reverse().map(u=>{const m=cs[u.severity],t=r===u.id,p=u.suggestions&&u.suggestions.length>0,d=u.actions&&u.actions.length>0,b=p||d;return e.jsxs("div",{className:`alert-item ${t?"alert-item-expanded":""}`,style:{borderLeftColor:m.color,background:m.bg},children:[e.jsxs("div",{className:"alert-item-header",onClick:()=>b&&n(u.id),style:{cursor:b?"pointer":"default"},children:[e.jsx("span",{className:"alert-item-icon",children:m.icon}),e.jsx("span",{className:"alert-item-title",children:u.title}),e.jsx("span",{className:"alert-item-time",children:new Date(u.timestamp).toLocaleTimeString()}),b&&e.jsx("span",{className:"alert-item-toggle",children:t?"▾":"▸"})]}),e.jsx("div",{className:"alert-item-desc",children:u.description}),t&&e.jsxs("div",{className:"alert-item-detail",children:[p&&e.jsxs("div",{className:"alert-suggestions",children:[e.jsx("div",{className:"alert-suggestions-title",children:"🔍 排查建议"}),e.jsx("ul",{className:"alert-suggestions-list",children:u.suggestions.map((g,v)=>e.jsx("li",{children:g},v))})]}),d&&i&&e.jsxs("div",{className:"alert-actions",children:[e.jsx("div",{className:"alert-actions-title",children:"⚡ 快捷操作"}),e.jsx("div",{className:"alert-actions-btns",children:u.actions.map(g=>e.jsx("button",{className:"btn btn-sm alert-action-btn",onClick:v=>{v.stopPropagation(),i(g)},children:g.label},g.id))})]})]})]},u.id)})})]})},ms=({isRunning:s,currentSessionId:a,onStart:i,onStop:r,onTriggerGC:c,onAddMark:n,onTakeHeapSnapshot:u,markCount:m=0})=>{const[t,p]=h.useState(""),[d,b]=h.useState(""),[g,v]=h.useState(!1),N=()=>{t.trim()&&(i(t.trim()),p(""))},l=async()=>{v(!0);try{await r()}finally{v(!1)}},j=()=>{d.trim()&&(n(d.trim()),b(""))};return e.jsxs("div",{className:"session-control",children:[e.jsxs("div",{className:"session-control-status",children:[e.jsx("span",{className:`status-dot ${s?"running":"idle"}`}),e.jsx("span",{children:s?`会话进行中: ${a==null?void 0:a.slice(0,8)}...`:"未开始会话"})]}),e.jsxs("div",{className:"session-control-actions",children:[s?e.jsx("button",{type:"button",className:"btn btn-danger",onClick:l,disabled:g,children:g?"⏳ 结束中...":"⏹ 结束会话"}):e.jsxs("div",{className:"session-start-form",children:[e.jsx("input",{type:"text",placeholder:"会话标签(如 v1.2.0 空载基准)",value:t,onChange:x=>p(x.target.value),onKeyDown:x=>x.key==="Enter"&&N()}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:N,disabled:!t.trim(),children:"▶ 开始会话"})]}),e.jsxs("div",{className:"session-tools",children:[e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:c,title:"手动触发垃圾回收",children:"🗑️ GC"}),u&&e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:u,title:"导出主进程 V8 堆快照",children:"📸 堆快照"}),e.jsxs("div",{className:"mark-form",children:[e.jsx("input",{type:"text",placeholder:"事件标记",value:d,onChange:x=>b(x.target.value),onKeyDown:x=>x.key==="Enter"&&j()}),e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:j,disabled:!d.trim(),children:"📌 标记"}),m>0&&e.jsxs("span",{className:"mark-count-badge",title:"当前图表缓冲区内已记录的标记数",children:["已记录 ",m," 条"]})]})]})]})]})};function we(s){var i;const a=[];for(const r of s){if(!((i=r.marks)!=null&&i.length))continue;const c=r.processes.filter(m=>m.type==="Browser").reduce((m,t)=>m+t.memory.workingSetSize,0),n=r.processes.filter(m=>m.type==="Tab"&&!m.isMonitorProcess).reduce((m,t)=>m+t.memory.workingSetSize,0),u=r.processes.filter(m=>m.type==="GPU").reduce((m,t)=>m+t.memory.workingSetSize,0);for(const m of r.marks)a.push({timestamp:m.timestamp,label:m.label,metadata:m.metadata,totalWorkingSetKB:r.totalWorkingSetSize,browserKB:c,rendererKB:n,gpuKB:u})}return a}function hs(){const[s,a]=h.useState([]),[i,r]=h.useState(null),[c,n]=h.useState([]),[u,m]=h.useState(!1),t=h.useRef([]);h.useEffect(()=>{var j,x;const N=S=>{r(S),m(!0),t.current=[...t.current,S].slice(-300),a(t.current)},l=S=>{n(y=>[...y,S])};return(j=window.monitorAPI)==null||j.onSnapshot(N),(x=window.monitorAPI)==null||x.onAnomaly(l),()=>{var S,y;(S=window.monitorAPI)==null||S.removeSnapshotListener(),(y=window.monitorAPI)==null||y.removeAnomalyListener()}},[]);const p=h.useCallback(async()=>{var N;return(N=window.monitorAPI)==null?void 0:N.triggerGC()},[]),d=h.useCallback(async N=>{var l;return(l=window.monitorAPI)==null?void 0:l.addMark(N)},[]),b=h.useCallback(()=>{n([])},[]),g=h.useCallback(async N=>{var l;return(l=window.monitorAPI)==null?void 0:l.takeHeapSnapshot(N)},[]),v=h.useMemo(()=>we(s),[s]);return{snapshots:s,latestSnapshot:i,anomalies:c,isCollecting:u,triggerGC:p,addMark:d,clearAnomalies:b,markTimeline:v,takeHeapSnapshot:g}}function re(){const[s,a]=h.useState(null),[i,r]=h.useState(!1),[c,n]=h.useState([]),u=h.useCallback(async(l,j)=>{const x=window.monitorAPI;if(!(x!=null&&x.startSession))return console.error("[@electron-memory/monitor] monitorAPI.startSession 不可用(请确认监控面板 preload 已注入)"),null;try{const S=await x.startSession(l,j);return S&&(a(S),r(!0)),S}catch(S){return console.error("[@electron-memory/monitor] startSession failed:",S),null}},[]),m=h.useCallback(async()=>{var S,y;const l=await((S=window.monitorAPI)==null?void 0:S.getSessions());if(l==null)return;let j,x=null;if(Array.isArray(l))j=l,x=((y=j.find(k=>k.status==="running"))==null?void 0:y.id)??null;else{const k=l;j=Array.isArray(k.sessions)?k.sessions:[],x=k.activeSessionId??null}n(j),a(x),r(!!x)},[]),t=h.useCallback(async()=>{const l=window.monitorAPI;if(!(l!=null&&l.stopSession))return console.error("[@electron-memory/monitor] monitorAPI.stopSession 不可用(请确认监控面板 preload 已注入)"),await m(),null;const j=12e4;try{const x=await Promise.race([l.stopSession(),new Promise((S,y)=>setTimeout(()=>y(new Error(`stopSession 超过 ${j/1e3}s 未返回(主进程可能仍在读 snapshots / 写 report)`)),j))]);return await m(),x&&typeof x=="object"&&"ok"in x&&(x.ok===!0||x.reason==="no_active_session"?(a(null),r(!1)):console.error("[@electron-memory/monitor] stopSession failed:",x)),null}catch(x){return console.error("[@electron-memory/monitor] stopSession failed:",x),await m(),null}},[m]),p=h.useCallback(async l=>{var j;return await((j=window.monitorAPI)==null?void 0:j.getSessionReport(l))},[]),d=h.useCallback(async(l,j,x,S)=>{var k;return await((k=window.monitorAPI)==null?void 0:k.getSessionSnapshots(l,j,x,S))||[]},[]),b=h.useCallback(async(l,j)=>{var x;return(x=window.monitorAPI)==null?void 0:x.compareSessions(l,j)},[]),g=h.useCallback(async l=>{var x;return await((x=window.monitorAPI)==null?void 0:x.exportSession(l))},[]),v=h.useCallback(async()=>{var j;const l=await((j=window.monitorAPI)==null?void 0:j.importSession());return l!=null&&l.success&&await m(),l},[m]),N=h.useCallback(async l=>{var x;const j=await((x=window.monitorAPI)==null?void 0:x.deleteSession(l));return j&&await m(),j},[m]);return{currentSessionId:s,isRunning:i,sessions:c,startSession:u,stopSession:t,refreshSessions:m,getSessionReport:p,getSessionSnapshots:d,compareSessions:b,exportSession:g,importSession:v,deleteSession:N}}const Y=s=>s==null||isNaN(s)?"0 KB":s>1024*1024?`${(s/1024/1024).toFixed(2)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,us=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,xs=({paneVisible:s=!0})=>{const{snapshots:a,latestSnapshot:i,anomalies:r,triggerGC:c,addMark:n,clearAnomalies:u,markTimeline:m,takeHeapSnapshot:t}=hs(),{currentSessionId:p,isRunning:d,startSession:b,stopSession:g,refreshSessions:v}=re(),N=h.useCallback(async()=>{try{const y=await t();y&&console.log("[EMM] Heap snapshot saved:",y)}catch(y){console.error("[EMM] Failed to take heap snapshot:",y)}},[t]),l=h.useCallback(y=>{switch(y.type){case"heap-snapshot":N();break;case"trigger-gc":c();break;case"open-devtools":console.log("[EMM] open-devtools action not implemented yet");break}},[N,c]);if(h.useEffect(()=>{s&&v()},[s,v]),!i)return e.jsxs("div",{className:"dashboard-loading",children:[e.jsx("div",{className:"loading-spinner"}),e.jsx("p",{children:"等待内存数据..."})]});const j=i.processes.find(y=>y.type==="Browser"),x=i.processes.filter(y=>y.type==="Tab"&&!y.isMonitorProcess),S=x.reduce((y,k)=>y+k.memory.workingSetSize,0);return e.jsxs("div",{className:"dashboard",children:[e.jsx(ms,{isRunning:d,currentSessionId:p,onStart:b,onStop:g,onTriggerGC:c,onAddMark:n,onTakeHeapSnapshot:N,markCount:m.length}),e.jsxs("div",{className:"metric-cards-row",children:[e.jsx(B,{icon:"💻",title:"总内存",value:Y(i.totalWorkingSetSize),color:"#646cff"}),e.jsx(B,{icon:"🧠",title:"Browser 工作集",value:Y((j==null?void 0:j.memory.workingSetSize)||0),color:"#f5a623"}),e.jsx(B,{icon:"🖼️",title:"渲染进程",value:Y(S),unit:`(${x.length}个)`,color:"#61dafb"}),e.jsx(B,{icon:"📊",title:"主进程 V8 Used",value:us(i.mainProcessMemory.heapUsed),color:"#52c41a"}),e.jsx(B,{icon:"⚙️",title:"系统内存",value:`${i.system.usagePercent}%`,color:"#ff6b6b"}),e.jsx(B,{icon:"🔢",title:"进程数",value:`${i.processes.length}`,color:"#8b8b8b"})]}),e.jsxs("div",{className:"charts-row",children:[e.jsxs("div",{className:"chart-container chart-wide",children:[e.jsx("h3",{children:"📈 内存趋势"}),e.jsxs("p",{className:"chart-marks-caption",children:["代码里 ",e.jsx("code",{children:"monitor.mark()"})," 或手动「标记」会在",e.jsx("strong",{children:"下一拍采样"}),"写入;趋势图横轴为时间戳,橙色竖线为各 Mark 时刻。"]}),e.jsx(be,{snapshots:a,height:300})]}),e.jsxs("div",{className:"chart-container chart-narrow",children:[e.jsx("h3",{children:"🥧 内存分布"}),e.jsx(ke,{processes:i.processes,height:300})]})]}),e.jsxs("div",{className:"section dashboard-mark-explorer-section",children:[e.jsx("h3",{children:"📍 标记点内存对比与详情"}),e.jsx("p",{className:"report-marks-hint",style:{marginTop:0},children:"下图汇总当前缓冲区内各标记所在采样时刻;下拉或点击柱形查看该时刻的进程表、主进程 V8 与各渲染进程 V8 表。完整会话请结束后在「历史报告」查看。"}),e.jsx(Se,{snapshots:a,variant:"dashboard"})]}),e.jsxs("div",{className:"section",children:[e.jsx("h3",{children:"📋 进程详情"}),e.jsxs("p",{className:"process-table-caption",children:["由系统枚举",e.jsx("strong",{children:"全部"})," Electron 子进程(含每个 Tab),与当前焦点标签无关,无需为了看内存去切换 Tab。"]}),e.jsx(ee,{processes:i.processes})]}),i.mainProcessV8Detail&&e.jsx("div",{className:"section",children:e.jsx(se,{v8Detail:i.mainProcessV8Detail})}),e.jsx("div",{className:"section",children:e.jsx(te,{processes:i.processes,details:i.rendererDetails})}),e.jsxs("div",{className:"section",children:[e.jsx("h3",{children:"🚨 异常告警"}),e.jsx(ds,{anomalies:r,onClear:u,onAction:l})]})]})},ps={info:{icon:"ℹ️",color:"#1890ff"},warning:{icon:"⚠️",color:"#faad14"},critical:{icon:"🔴",color:"#ff4d4f"}},js=s=>{const a=["堆快照","heap snapshot","Heap Snapshot","Detached"],i=[s.title,s.description,...s.suggestions].join(" ");return a.some(r=>i.includes(r))},fs=s=>{const a=["GC","垃圾回收","触发 GC","内存回落"],i=[s.title,s.description,...s.suggestions].join(" ");return a.some(r=>i.includes(r))},vs=({suggestions:s,onTakeHeapSnapshot:a,onTriggerGC:i})=>s.length===0?e.jsx("div",{className:"suggestion-panel-empty",children:e.jsx("span",{children:"✅ 未发现需要改进的地方"})}):e.jsx("div",{className:"suggestion-panel",children:s.map(r=>{const c=ps[r.severity],n=a&&js(r),u=i&&fs(r),m=n||u;return e.jsxs("div",{className:"suggestion-item",style:{borderLeftColor:c.color},children:[e.jsxs("div",{className:"suggestion-header",children:[e.jsx("span",{className:"suggestion-icon",children:c.icon}),e.jsx("span",{className:"suggestion-title",children:r.title}),e.jsx("span",{className:"suggestion-category",children:r.category})]}),e.jsx("p",{className:"suggestion-desc",children:r.description}),e.jsx("ul",{className:"suggestion-list",children:r.suggestions.map((t,p)=>e.jsx("li",{children:t},p))}),r.relatedCode&&r.relatedCode.length>0&&e.jsx("div",{className:"suggestion-code",children:r.relatedCode.map((t,p)=>e.jsx("code",{children:t},p))}),m&&e.jsxs("div",{className:"suggestion-actions",children:[n&&e.jsx("button",{className:"btn btn-sm suggestion-action-btn",onClick:a,children:"📸 导出堆快照"}),u&&e.jsx("button",{className:"btn btn-sm suggestion-action-btn",onClick:i,children:"🗑️ 触发 GC"})]})]},r.id)})}),je=s=>{const a=Math.floor(s/1e3),i=Math.floor(a/60),r=Math.floor(i/60);return r>0?`${r}h ${i%60}m ${a%60}s`:i>0?`${i}m ${a%60}s`:`${a}s`},I=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,w=s=>s==null||isNaN(s)?"0 KB":s>1024*1024?`${(s/1024/1024).toFixed(2)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,F=s=>{const a=new Date(s);return`${a.getHours().toString().padStart(2,"0")}:${a.getMinutes().toString().padStart(2,"0")}:${a.getSeconds().toString().padStart(2,"0")}`},gs=[{label:"全部",value:"all"},{label:"最近 1 分钟",value:"1m"},{label:"最近 5 分钟",value:"5m"},{label:"最近 10 分钟",value:"10m"},{label:"最近 30 分钟",value:"30m"},{label:"自定义",value:"custom"}],Ns=[{label:"自动",value:0},{label:"最多 200 点",value:200},{label:"最多 400 点",value:400},{label:"最多 600 点",value:600},{label:"最多 1000 点",value:1e3}],bs=({paneVisible:s=!0})=>{const{sessions:a,refreshSessions:i,getSessionReport:r,getSessionSnapshots:c,exportSession:n,importSession:u,deleteSession:m}=re(),[t,p]=h.useState(null),[d,b]=h.useState(null),[g,v]=h.useState([]),[N,l]=h.useState(!1),[j,x]=h.useState(!1),[S,y]=h.useState(!1),[k,ae]=h.useState(!1),[E,ne]=h.useState("all"),[U,Me]=h.useState(""),[K,Ce]=h.useState(""),[L,Pe]=h.useState(0),[O,$e]=h.useState(!0),[D,Be]=h.useState(!0),[T,Te]=h.useState(!0),[W,Re]=h.useState(!0),[q,Ae]=h.useState(!0);h.useEffect(()=>{s&&i()},[s,i]),h.useEffect(()=>{p(o=>{if(!o)return o;const f=a.find(P=>P.id===o.id);return f?o.status===f.status&&o.snapshotCount===f.snapshotCount&&o.endTime===f.endTime&&o.duration===f.duration?o:f:null})},[a]);const Ie=o=>{p(o),ne("all")};h.useEffect(()=>{if(!t){b(null);return}let o=!1;return l(!0),(async()=>{try{const f=await r(t.id);o||b(f)}catch(f){console.error("Failed to load report:",f),o||b(null)}finally{o||l(!1)}})(),()=>{o=!0}},[t==null?void 0:t.id,t==null?void 0:t.status,t==null?void 0:t.endTime,r]);const V=h.useMemo(()=>{if(!d)return{start:void 0,end:void 0};const o=d.endTime;switch(E){case"1m":return{start:o-60*1e3,end:o};case"5m":return{start:o-300*1e3,end:o};case"10m":return{start:o-600*1e3,end:o};case"30m":return{start:o-1800*1e3,end:o};case"custom":{const f=U?new Date(U).getTime():void 0,P=K?new Date(K).getTime():void 0;return{start:f&&!isNaN(f)?f:void 0,end:P&&!isNaN(P)?P:void 0}}default:return{start:void 0,end:void 0}}},[d,E,U,K]),ie=h.useMemo(()=>{if(L>0)return L;if(!d)return 600;const o=d.duration/6e4;return o>30?300:o>10?400:600},[L,d]),oe=h.useCallback(async()=>{if(t){x(!0);try{const o=await c(t.id,V.start,V.end,ie);v(o)}catch(o){console.error("Failed to load snapshots:",o)}x(!1)}},[t,c,V.start,V.end,ie]);h.useEffect(()=>{t&&d&&oe()},[t,d,oe]);const Fe=async o=>{y(!0);try{const f=await n(o);f!=null&&f.success?console.log("导出成功:",f.filePath):f!=null&&f.error&&f.error!=="用户取消"&&(console.error("导出失败:",f.error),alert("导出失败: "+f.error))}catch(f){console.error("导出异常:",f)}y(!1)},Ee=async()=>{ae(!0);try{const o=await u();o!=null&&o.success?console.log("导入成功"):o!=null&&o.error&&o.error!=="用户取消"&&(console.error("导入失败:",o.error),alert("导入失败: "+o.error))}catch(o){console.error("导入异常:",o)}ae(!1)},Ue=async(o,f)=>{if(o.stopPropagation(),!confirm("确定要删除这个会话吗?此操作不可恢复。"))return;await m(f)&&(t==null?void 0:t.id)===f&&(p(null),b(null),v([]))},$=h.useMemo(()=>g.length>0?g[g.length-1]:null,[g]),le=h.useMemo(()=>g.length===0?null:g[Math.floor(g.length/2)],[g]),ce=h.useMemo(()=>d!=null&&d.eventMarks&&d.eventMarks.length>0?d.eventMarks:we(g),[d==null?void 0:d.eventMarks,g]);return e.jsx("div",{className:"report-page",children:e.jsxs("div",{className:"report-layout",children:[e.jsxs("div",{className:"session-list",children:[e.jsx("h3",{children:"📋 历史会话"}),e.jsxs("div",{className:"session-list-actions",children:[e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:i,children:"🔄 刷新"}),e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:Ee,disabled:k,children:k?"⏳ 导入中...":"📥 导入"})]}),a.length===0?e.jsxs("div",{className:"session-list-empty",children:[e.jsx("p",{children:"暂无历史会话"}),e.jsx("p",{className:"hint",children:"在实时监控页面开始一个测试会话"})]}):e.jsx("div",{className:"session-items",children:a.map(o=>e.jsxs("div",{className:`session-item ${(t==null?void 0:t.id)===o.id?"active":""}`,onClick:()=>Ie(o),children:[e.jsxs("div",{className:"session-item-header",children:[e.jsx("div",{className:"session-item-label",children:o.label}),e.jsxs("div",{className:"session-item-actions",children:[e.jsx("button",{className:"btn-icon",title:"导出会话",onClick:f=>{f.stopPropagation(),Fe(o.id)},disabled:S,children:"📤"}),e.jsx("button",{className:"btn-icon btn-icon-danger",title:"删除会话",onClick:f=>Ue(f,o.id),children:"🗑️"})]})]}),e.jsxs("div",{className:"session-item-meta",children:[e.jsx("span",{children:new Date(o.startTime).toLocaleDateString()}),e.jsx("span",{children:o.duration?je(o.duration):"进行中"}),e.jsxs("span",{children:[o.snapshotCount," 条"]})]}),e.jsx("span",{className:`session-status ${o.status}`,children:o.status})]},o.id))})]}),e.jsxs("div",{className:"report-detail",children:[N&&e.jsx("div",{className:"report-loading",children:"加载中..."}),!N&&!d&&e.jsxs("div",{className:"report-placeholder",children:[e.jsx("span",{className:"report-placeholder-icon",children:"📊"}),e.jsx("p",{children:"选择左侧的会话查看报告"})]}),!N&&d&&e.jsxs("div",{className:"report-content",children:[e.jsx("h2",{children:d.label}),d.description&&e.jsx("p",{className:"report-desc",children:d.description}),e.jsxs("div",{className:"report-meta-bar",children:[e.jsxs("span",{children:["⏱️ ",je(d.duration)]}),e.jsxs("span",{children:["📅 ",new Date(d.startTime).toLocaleString()," ~ ",new Date(d.endTime).toLocaleString()]})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"🖥️ 运行环境"}),e.jsxs("div",{className:"env-grid",children:[e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"Electron"}),e.jsxs("span",{className:"env-value",children:["v",d.environment.electronVersion]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"Chrome"}),e.jsxs("span",{className:"env-value",children:["v",d.environment.chromeVersion]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"Node.js"}),e.jsxs("span",{className:"env-value",children:["v",d.environment.nodeVersion]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"平台"}),e.jsxs("span",{className:"env-value",children:[d.environment.platform,"/",d.environment.arch]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"系统内存"}),e.jsx("span",{className:"env-value",children:I(d.environment.totalSystemMemory)})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"CPU"}),e.jsxs("span",{className:"env-value",children:[d.environment.cpuCores," 核"]})]})]})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"📊 统计汇总"}),e.jsxs("table",{className:"report-stats-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"指标"}),e.jsx("th",{children:"初始值"}),e.jsx("th",{children:"最终值"}),e.jsx("th",{children:"平均值"}),e.jsx("th",{children:"P95"}),e.jsx("th",{children:"变化"})]})}),e.jsxs("tbody",{children:[e.jsxs("tr",{children:[e.jsx("td",{children:"总内存"}),e.jsx("td",{children:w(d.summary.totalMemory.initial)}),e.jsx("td",{children:w(d.summary.totalMemory.final)}),e.jsx("td",{children:w(d.summary.totalMemory.avg)}),e.jsx("td",{children:w(d.summary.totalMemory.p95)}),e.jsxs("td",{className:d.summary.totalMemory.deltaPercent>5?"degraded":"",children:[d.summary.totalMemory.deltaPercent>0?"+":"",d.summary.totalMemory.deltaPercent.toFixed(1),"%"]})]}),e.jsxs("tr",{children:[e.jsx("td",{children:"主进程"}),e.jsx("td",{children:w(d.summary.byProcessType.browser.initial)}),e.jsx("td",{children:w(d.summary.byProcessType.browser.final)}),e.jsx("td",{children:w(d.summary.byProcessType.browser.avg)}),e.jsx("td",{children:w(d.summary.byProcessType.browser.p95)}),e.jsxs("td",{className:d.summary.byProcessType.browser.deltaPercent>10?"degraded":"",children:[d.summary.byProcessType.browser.deltaPercent>0?"+":"",d.summary.byProcessType.browser.deltaPercent.toFixed(1),"%"]})]}),e.jsxs("tr",{children:[e.jsx("td",{children:"V8 Heap Used"}),e.jsx("td",{children:I(d.summary.mainV8Heap.heapUsed.initial)}),e.jsx("td",{children:I(d.summary.mainV8Heap.heapUsed.final)}),e.jsx("td",{children:I(d.summary.mainV8Heap.heapUsed.avg)}),e.jsx("td",{children:I(d.summary.mainV8Heap.heapUsed.p95)}),e.jsxs("td",{className:d.summary.mainV8Heap.heapUsed.deltaPercent>10?"degraded":"",children:[d.summary.mainV8Heap.heapUsed.deltaPercent>0?"+":"",d.summary.mainV8Heap.heapUsed.deltaPercent.toFixed(1),"%"]})]})]})]})]}),ce.length>0&&e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"📍 阶段标记(Mark)"}),e.jsxs("p",{className:"report-marks-hint",children:["下列数值为",e.jsx("strong",{children:"该次采样时刻"}),"的快照内存;趋势图中以橙色竖线标出对应时间。未手动点「标记」的会话此处为空。"]}),e.jsx("div",{className:"report-marks-table-wrap",children:e.jsxs("table",{className:"report-marks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"时间"}),e.jsx("th",{children:"标签"}),e.jsx("th",{children:"总内存"}),e.jsx("th",{children:"主进程"}),e.jsx("th",{children:"渲染"}),e.jsx("th",{children:"GPU"}),e.jsx("th",{children:"附注"})]})}),e.jsx("tbody",{children:ce.map((o,f)=>e.jsxs("tr",{children:[e.jsx("td",{children:F(o.timestamp)}),e.jsx("td",{className:"mark-label-cell",children:o.label}),e.jsx("td",{children:w(o.totalWorkingSetKB)}),e.jsx("td",{children:w(o.browserKB)}),e.jsx("td",{children:w(o.rendererKB)}),e.jsx("td",{children:w(o.gpuKB)}),e.jsx("td",{className:"mark-meta-cell",children:o.metadata&&Object.keys(o.metadata).length>0?JSON.stringify(o.metadata):"—"})]},`${o.timestamp}-${f}-${o.label}`))})]})})]}),e.jsxs("div",{className:"report-section report-visual-section",children:[e.jsx("h3",{children:"📈 数据可视化"}),e.jsxs("div",{className:"report-time-controls",children:[e.jsxs("div",{className:"time-presets",children:[e.jsx("span",{className:"control-label",children:"时间范围:"}),gs.map(o=>e.jsx("button",{className:`btn btn-sm ${E===o.value?"btn-primary":"btn-secondary"}`,onClick:()=>ne(o.value),children:o.label},o.value))]}),E==="custom"&&e.jsxs("div",{className:"time-custom-range",children:[e.jsx("span",{className:"control-label",children:"自定义范围:"}),e.jsx("input",{type:"text",placeholder:`起始 (如 ${F(d.startTime)})`,value:U,onChange:o=>Me(o.target.value)}),e.jsx("span",{children:"~"}),e.jsx("input",{type:"text",placeholder:`结束 (如 ${F(d.endTime)})`,value:K,onChange:o=>Ce(o.target.value)})]}),e.jsxs("div",{className:"granularity-control",children:[e.jsx("span",{className:"control-label",children:"显示粒度:"}),e.jsx("select",{value:L,onChange:o=>Pe(Number(o.target.value)),children:Ns.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))}),e.jsx("span",{className:"data-info",children:j?"加载中...":`已加载 ${g.length} 个数据点`})]})]}),e.jsxs("div",{className:"report-panel-toggles",children:[e.jsx("button",{className:`panel-toggle ${O?"active":""}`,onClick:()=>$e(!O),children:"📈 内存趋势"}),e.jsx("button",{className:`panel-toggle ${D?"active":""}`,onClick:()=>Be(!D),children:"🥧 内存分布"}),e.jsx("button",{className:`panel-toggle ${T?"active":""}`,onClick:()=>Te(!T),children:"📋 进程详情"}),e.jsx("button",{className:`panel-toggle ${W?"active":""}`,onClick:()=>Re(!W),children:"🔧 V8(主进程+渲染)"}),e.jsx("button",{className:`panel-toggle ${q?"active":""}`,onClick:()=>Ae(!q),children:"📌 标记对比与详情"})]}),j&&e.jsxs("div",{className:"report-snapshots-loading",children:[e.jsx("div",{className:"loading-spinner",style:{width:24,height:24}}),e.jsx("span",{children:"正在加载快照数据..."})]}),!j&&g.length===0&&e.jsxs("div",{className:"report-no-data report-no-snapshots-detail",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"该时间范围内没有快照点"}),",因此不会显示趋势图、进程表、主进程/渲染 V8 表。"]}),(t==null?void 0:t.status)==="aborted"&&e.jsxs("p",{className:"report-aborted-hint",children:["当前会话为 ",e.jsx("strong",{children:"aborted"}),":通常是",e.jsx("strong",{children:"上次未点看板「结束会话」就关了应用"}),",或",e.jsx("strong",{children:"开发时 vite / electron 主进程频繁热重启"}),"。 下次启动时 SDK 会把磁盘上仍为 running 的旧会话标为 aborted,且若进程死得太快可能",e.jsx("strong",{children:"0 条采样"}),"。 正常关应用前让当前会话走完 ",e.jsx("code",{children:"stopSession"}),"(browser-sim 已在退出时自动调用)可减少此类记录。"]}),e.jsxs("p",{className:"report-renderer-v8-hint",children:[e.jsx("strong",{children:"渲染进程 V8"}),"写在每条快照的 ",e.jsx("code",{children:"rendererDetails"})," 里;无快照就无从展示。有数据时请在「",e.jsx("strong",{children:"V8(主进程+渲染)"}),"」折叠里向下滚动查看「渲染进程 V8」表,并确认业务 WebContents 的 preload 已 ",e.jsx("code",{children:"injectRendererReporter()"})," 且 ",e.jsx("code",{children:"enableRendererDetail: true"}),"。"]})]}),!j&&g.length>0&&e.jsxs(e.Fragment,{children:[O&&e.jsx("div",{className:"report-chart-panel",children:e.jsxs("div",{className:"chart-container",style:{margin:0},children:[e.jsxs("h4",{children:["📈 内存趋势(",F(g[0].timestamp)," ~ ",F(g[g.length-1].timestamp),")"]}),e.jsx("p",{className:"chart-marks-caption",children:"有 Mark 时以橙色竖线标在对应时间;详见「标记对比与详情」查看各标记时刻的进程与 V8 堆。"}),e.jsx(be,{snapshots:g,height:320})]})}),q&&e.jsxs("div",{className:"report-chart-panel mark-explorer-report-panel",children:[e.jsx("h4",{children:"📌 标记点内存对比与详情"}),e.jsx(Se,{snapshots:g,variant:"report"})]}),(D||T)&&e.jsxs("div",{className:"report-charts-row",children:[D&&le&&e.jsxs("div",{className:"chart-container",style:{margin:0,flex:T?"0 0 360px":"1"},children:[e.jsx("h4",{children:"🥧 内存分布(中间时刻快照)"}),e.jsx(ke,{processes:le.processes,height:280})]}),T&&$&&e.jsxs("div",{className:"chart-container",style:{margin:0,flex:1,overflow:"auto"},children:[e.jsx("h4",{children:"📋 进程详情(最后时刻快照)"}),e.jsx(ee,{processes:$.processes})]})]}),W&&$&&e.jsxs("div",{className:"report-chart-panel",children:[$.mainProcessV8Detail&&e.jsx("div",{className:"chart-container",style:{margin:0},children:e.jsx(se,{v8Detail:$.mainProcessV8Detail})}),e.jsx("div",{className:"chart-container",style:{marginTop:16},children:e.jsx(te,{processes:$.processes,details:$.rendererDetails,emptyHint:"该时间范围内最后一条快照无渲染进程 V8;请确认业务页 preload 已 injectRendererReporter。"})})]})]})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"📈 趋势分析"}),e.jsx("div",{className:"trend-grid",children:["totalMemory","browserMemory","rendererMemory"].map(o=>{const f=d.summary.trends[o],P=f.direction==="growing"?"📈":f.direction==="shrinking"?"📉":"→",Ke=f.direction==="growing"?"增长":f.direction==="shrinking"?"下降":"稳定",Le=o==="totalMemory"?"总内存":o==="browserMemory"?"主进程":"渲染进程";return e.jsxs("div",{className:"trend-item",children:[e.jsx("span",{className:"trend-label",children:Le}),e.jsxs("span",{className:"trend-direction",children:[P," ",Ke]}),e.jsxs("span",{className:"trend-slope",children:[f.slope.toFixed(2)," KB/s"]}),e.jsxs("span",{className:"trend-r2",children:["R²=",f.r2.toFixed(3)]}),e.jsx("span",{className:`trend-confidence ${f.confidence}`,children:f.confidence})]},o)})})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"💡 改进建议"}),e.jsx(vs,{suggestions:d.suggestions})]}),d.anomalies.length>0&&e.jsxs("div",{className:"report-section",children:[e.jsxs("h3",{children:["🚨 异常事件 (",d.anomalies.length,")"]}),e.jsx("div",{className:"anomaly-timeline",children:d.anomalies.map(o=>e.jsxs("div",{className:`anomaly-item severity-${o.severity}`,children:[e.jsx("span",{className:"anomaly-time",children:new Date(o.timestamp).toLocaleTimeString()}),e.jsx("span",{className:"anomaly-title",children:o.title}),e.jsx("span",{className:"anomaly-desc",children:o.description})]},o.id))})]})]})]})]})})},ys=s=>s>1024*1024?`${(s/1024/1024).toFixed(2)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,Ss=s=>s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,ks=({paneVisible:s=!0})=>{const{sessions:a,refreshSessions:i,compareSessions:r}=re(),[c,n]=h.useState(""),[u,m]=h.useState(""),[t,p]=h.useState(null),[d,b]=h.useState(!1);h.useEffect(()=>{s&&i()},[s,i]);const g=async()=>{if(!(!c||!u)){b(!0);try{const l=await r(c,u);p(l)}catch(l){console.error("Compare failed:",l)}b(!1)}},v=a.filter(l=>l.status==="completed"),N={pass:{icon:"✅",color:"#52c41a",label:"PASS - 通过"},warn:{icon:"🟡",color:"#faad14",label:"WARN - 存在轻微劣化"},fail:{icon:"🔴",color:"#ff4d4f",label:"FAIL - 存在严重劣化"}};return e.jsxs("div",{className:"compare-page",children:[e.jsx("h2",{children:"🔄 迭代对比"}),e.jsxs("div",{className:"compare-selector",children:[e.jsxs("div",{className:"compare-select-group",children:[e.jsx("label",{children:"基准会话 (旧版本)"}),e.jsxs("select",{value:c,onChange:l=>n(l.target.value),children:[e.jsx("option",{value:"",children:"-- 选择基准会话 --"}),v.map(l=>e.jsxs("option",{value:l.id,children:[l.label," (",new Date(l.startTime).toLocaleDateString(),")"]},l.id))]})]}),e.jsx("span",{className:"compare-arrow",children:"→"}),e.jsxs("div",{className:"compare-select-group",children:[e.jsx("label",{children:"对比会话 (新版本)"}),e.jsxs("select",{value:u,onChange:l=>m(l.target.value),children:[e.jsx("option",{value:"",children:"-- 选择对比会话 --"}),v.map(l=>e.jsxs("option",{value:l.id,children:[l.label," (",new Date(l.startTime).toLocaleDateString(),")"]},l.id))]})]}),e.jsx("button",{className:"btn btn-primary",onClick:g,disabled:!c||!u||d,children:d?"对比中...":"开始对比"})]}),t&&e.jsxs("div",{className:"compare-result",children:[e.jsxs("div",{className:"compare-verdict",style:{borderColor:N[t.verdict].color},children:[e.jsx("span",{className:"verdict-icon",children:N[t.verdict].icon}),e.jsx("span",{className:"verdict-label",style:{color:N[t.verdict].color},children:N[t.verdict].label}),e.jsx("p",{className:"verdict-reason",children:t.verdictReason})]}),e.jsxs("div",{className:"compare-section",children:[e.jsx("h3",{children:"📊 指标对比"}),e.jsxs("table",{className:"compare-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"指标"}),e.jsx("th",{children:t.base.label}),e.jsx("th",{children:t.target.label}),e.jsx("th",{children:"变化"}),e.jsx("th",{children:"状态"})]})}),e.jsx("tbody",{children:[{name:"总内存 (avg)",diff:t.overall.totalMemory,isBytes:!1},{name:"主进程 (avg)",diff:t.overall.browserMemory,isBytes:!1},{name:"渲染进程 (avg)",diff:t.overall.rendererMemory,isBytes:!1},...t.overall.gpuMemory?[{name:"GPU (avg)",diff:t.overall.gpuMemory,isBytes:!1}]:[],{name:"V8 Heap Used",diff:t.v8Heap.heapUsed,isBytes:!0},{name:"V8 Heap Total",diff:t.v8Heap.heapTotal,isBytes:!0},{name:"V8 External",diff:t.v8Heap.external,isBytes:!0}].map(l=>{const j=l.diff.status==="improved"?"✅":l.diff.status==="degraded"?"🔴":"➖",x=l.isBytes?Ss:ys;return e.jsxs("tr",{className:`status-${l.diff.status}`,children:[e.jsx("td",{children:l.name}),e.jsx("td",{children:x(l.diff.base)}),e.jsx("td",{children:x(l.diff.target)}),e.jsxs("td",{className:l.diff.deltaPercent>5?"degraded":l.diff.deltaPercent<-3?"improved":"",children:[l.diff.deltaPercent>0?"+":"",l.diff.deltaPercent.toFixed(1),"%"]}),e.jsx("td",{children:j})]},l.name)})})]})]}),e.jsxs("div",{className:"compare-section",children:[e.jsx("h3",{children:"📈 趋势变化"}),e.jsx("div",{className:"trend-changes",children:t.trendChanges.map(l=>{const j=l.change==="improved"?"✅":l.change==="degraded"?"🔴":"➖";return e.jsxs("div",{className:`trend-change-item ${l.change}`,children:[e.jsx("span",{className:"trend-change-metric",children:l.metric}),e.jsxs("span",{children:["基准: ",l.baseSlope.toFixed(2)," KB/s"]}),e.jsxs("span",{children:["目标: ",l.targetSlope.toFixed(2)," KB/s"]}),e.jsx("span",{children:j})]},l.metric)})})]}),t.regressions.length>0&&e.jsxs("div",{className:"compare-section",children:[e.jsxs("h3",{children:["⚠️ 劣化项 (",t.regressions.length,")"]}),e.jsx("div",{className:"regression-list",children:t.regressions.map((l,j)=>e.jsxs("div",{className:`regression-item severity-${l.severity}`,children:[e.jsxs("div",{className:"regression-header",children:[e.jsx("span",{className:"regression-metric",children:l.metric}),e.jsxs("span",{className:"regression-delta",children:["+",l.deltaPercent.toFixed(1),"%"]}),e.jsx("span",{className:`regression-severity ${l.severity}`,children:l.severity})]}),e.jsx("p",{className:"regression-desc",children:l.description}),e.jsxs("p",{className:"regression-suggestion",children:["💡 ",l.suggestion]})]},j))})]}),t.improvements.length>0&&e.jsxs("div",{className:"compare-section",children:[e.jsxs("h3",{children:["✅ 改进项 (",t.improvements.length,")"]}),e.jsx("div",{className:"improvement-list",children:t.improvements.map((l,j)=>e.jsxs("div",{className:"improvement-item",children:[e.jsx("span",{className:"improvement-metric",children:l.metric}),e.jsxs("span",{className:"improvement-delta",children:[l.deltaPercent.toFixed(1),"%"]}),e.jsx("span",{className:"improvement-desc",children:l.description})]},j))})]})]})]})},ws=()=>{const[s,a]=h.useState("dashboard");return e.jsxs("div",{className:"monitor-app",children:[e.jsxs("nav",{className:"monitor-nav",children:[e.jsxs("div",{className:"monitor-nav-brand",children:[e.jsx("span",{className:"monitor-nav-icon",children:"📊"}),e.jsx("span",{className:"monitor-nav-title",children:"Electron Memory Monitor"})]}),e.jsxs("div",{className:"monitor-nav-tabs",children:[e.jsx("button",{className:`monitor-nav-tab ${s==="dashboard"?"active":""}`,onClick:()=>a("dashboard"),children:"🔴 实时监控"}),e.jsx("button",{className:`monitor-nav-tab ${s==="report"?"active":""}`,onClick:()=>a("report"),children:"📋 历史报告"}),e.jsx("button",{className:`monitor-nav-tab ${s==="compare"?"active":""}`,onClick:()=>a("compare"),children:"🔄 迭代对比"})]})]}),e.jsxs("main",{className:"monitor-main",children:[s==="dashboard"&&e.jsx(xs,{paneVisible:!0}),s==="report"&&e.jsx(bs,{paneVisible:!0}),s==="compare"&&e.jsx(ks,{paneVisible:!0})]})]})};Xe.createRoot(document.getElementById("monitor-root")).render(e.jsx(We.StrictMode,{children:e.jsx(ws,{})}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*{margin:0;padding:0;box-sizing:border-box}html,body{width:100%;height:100%;font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;background-color:#1a1a2e;color:#e0e0e0;-webkit-font-smoothing:antialiased;font-size:14px}#monitor-root{width:100%;min-height:100vh}.monitor-app{display:flex;flex-direction:column;min-height:100vh}.monitor-nav{display:flex;align-items:center;justify-content:space-between;background:#16213e;padding:0 24px;height:52px;border-bottom:1px solid rgba(255,255,255,.1)}.monitor-nav-brand{display:flex;align-items:center;gap:10px}.monitor-nav-icon{font-size:20px}.monitor-nav-title{font-size:16px;font-weight:600;color:#e0e0e0}.monitor-nav-tabs{display:flex;gap:4px}.monitor-nav-tab{background:none;border:none;color:#ffffff80;padding:8px 16px;border-radius:8px;cursor:pointer;font-size:13px;transition:all .2s}.monitor-nav-tab:hover{background:#ffffff0d;color:#e0e0e0}.monitor-nav-tab.active{background:#646cff;color:#fff}.monitor-main{flex:1;padding:20px 24px;overflow-y:auto}.metric-cards-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:20px}.metric-card{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-top:3px solid #646cff;border-radius:12px;padding:16px;transition:transform .2s}.metric-card:hover{transform:translateY(-2px)}.metric-card-header{display:flex;align-items:center;gap:6px;margin-bottom:8px}.metric-card-icon{font-size:16px}.metric-card-title{font-size:12px;color:#ffffff80;text-transform:uppercase;letter-spacing:.5px}.metric-card-value{display:flex;align-items:baseline;gap:4px}.metric-card-number{font-size:22px;font-weight:700;color:#e0e0e0}.metric-card-unit{font-size:12px;color:#ffffff80}.metric-card-trend{font-size:12px;margin-top:4px;display:flex;gap:4px}.charts-row{display:grid;grid-template-columns:2fr 1fr;gap:16px;margin-bottom:20px}.chart-container{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px}.chart-container h3{font-size:14px;margin-bottom:12px;color:#e0e0e0}.chart-empty{display:flex;align-items:center;justify-content:center;height:200px;color:#ffffff80;font-size:14px}.process-table-container{overflow-x:auto}.process-table{width:100%;border-collapse:collapse}.process-table th,.process-table td{padding:10px 12px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1)}.process-table th{font-size:12px;color:#ffffff80;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.process-table td{font-size:13px}.process-table tr:hover{background:#ffffff08}.process-table tr.monitor-process{opacity:.6}.process-table .pid{font-family:monospace;color:#ffffff80}.process-table .memory-value{font-family:monospace;color:#1890ff}.process-table .cpu-value{font-family:monospace}.process-table .process-name{max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.process-type-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;color:#fff;font-weight:500}.session-control{position:relative;z-index:5;pointer-events:auto;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px;margin-bottom:20px}.session-control-status{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-size:13px}.session-control-actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center}.status-dot{width:8px;height:8px;border-radius:50%}.status-dot.running{background:#52c41a;animation:pulse 1.5s infinite}.status-dot.idle{background:#ffffff80}@keyframes pulse{0%,to{opacity:1}50%{opacity:.4}}.session-start-form{display:flex;gap:8px}.session-start-form input{flex:1;min-width:200px}.session-tools{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.mark-form{display:flex;gap:4px;align-items:center;flex-wrap:wrap}.mark-count-badge{font-size:11px;color:#ffffff80;white-space:nowrap;padding:2px 8px;border-radius:8px;background:#faad1426;color:#faad14}.btn{padding:8px 16px;border-radius:8px;border:1px solid rgba(255,255,255,.1);font-size:13px;cursor:pointer;transition:all .2s;display:inline-flex;align-items:center;gap:4px}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-sm{padding:4px 10px;font-size:12px}.btn-primary{background:#646cff;border-color:#646cff;color:#fff}.btn-primary:hover:not(:disabled){background:#535bf2}.btn-secondary{background:#ffffff0d;color:#e0e0e0}.btn-secondary:hover:not(:disabled){background:#ffffff1a}.btn-danger{background:#ff4d4f;border-color:#ff4d4f;color:#fff}.btn-danger:hover:not(:disabled){background:#ff1a1d}input[type=text],select{padding:8px 12px;border-radius:8px;border:1px solid rgba(255,255,255,.1);background:#ffffff0d;color:#e0e0e0;font-size:13px;outline:none;transition:border-color .2s}input[type=text]:focus,select:focus{border-color:#646cff}input[type=text]::placeholder,select::placeholder{color:#ffffff80}select{cursor:pointer}select option{background:#16213e}.section{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px;margin-bottom:20px}.section h3{font-size:14px;margin-bottom:12px;color:#e0e0e0}.v8-heap-detail h3{font-size:14px;margin-bottom:8px}.v8-heap-detail h4{font-size:13px;margin:16px 0 8px;color:#ffffff80}.v8-heap-detail-caption{font-size:11px;color:#ffffff80;line-height:1.5;margin:0 0 12px}.v8-heap-detail-caption code{font-size:10px;padding:1px 4px;border-radius:3px;background:#00000059;font-family:ui-monospace,monospace}.process-table-caption{font-size:11px;color:#ffffff80;margin:-4px 0 10px;line-height:1.45}.renderer-v8-panel h3{font-size:14px;margin-bottom:8px;color:#e0e0e0}.renderer-v8-caption{font-size:11px;color:#ffffff80;line-height:1.5;margin:0 0 12px}.renderer-v8-empty{font-size:12px;color:#ffffff80;margin:0;line-height:1.5}.renderer-v8-table th,.renderer-v8-table td{font-size:11px}.v8-overview{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px}.v8-stat{background:#ffffff08;border-radius:8px;padding:8px 12px;display:flex;flex-direction:column;gap:4px}.v8-stat-label{font-size:11px;color:#ffffff80;text-transform:uppercase}.v8-stat-value{font-size:14px;font-weight:600;font-family:monospace}.v8-stat-value.danger{color:#ff4d4f}.v8-stat-value.warn{color:#faad14}.v8-spaces-table{width:100%;border-collapse:collapse}.v8-spaces-table th,.v8-spaces-table td{padding:6px 10px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1);font-size:12px}.v8-spaces-table th{color:#ffffff80;font-weight:500}.v8-spaces-table .space-name{font-family:monospace;color:#1890ff}.usage-bar{position:relative;height:18px;background:#ffffff0d;border-radius:4px;overflow:hidden}.usage-bar-fill{height:100%;border-radius:4px;transition:width .3s}.usage-bar-text{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-size:10px;color:#fff;font-weight:500}.alert-panel-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.alert-panel-clear{background:none;border:none;color:#ffffff80;cursor:pointer;font-size:12px}.alert-panel-clear:hover{color:#e0e0e0}.alert-panel-empty{display:flex;align-items:center;gap:8px;padding:16px;color:#ffffff80}.alert-panel-empty-icon{font-size:16px}.alert-panel-list{display:flex;flex-direction:column;gap:8px;max-height:300px;overflow-y:auto}.alert-item{padding:10px 12px;border-radius:8px;border-left:3px solid;transition:all .2s}.alert-item-expanded{background:#ffffff0a!important}.alert-item-header{display:flex;align-items:center;gap:8px;margin-bottom:4px}.alert-item-icon{font-size:14px}.alert-item-title{font-size:13px;font-weight:500;flex:1}.alert-item-time{font-size:11px;color:#ffffff80}.alert-item-desc{font-size:12px;color:#ffffff80}.alert-item-toggle{font-size:12px;color:#ffffff80;-webkit-user-select:none;user-select:none;min-width:14px;text-align:center}.alert-item-detail{margin-top:10px;padding-top:10px;border-top:1px solid rgba(255,255,255,.08)}.alert-suggestions{margin-bottom:10px}.alert-suggestions-title{font-size:12px;font-weight:600;color:#e0e0e0;margin-bottom:6px}.alert-suggestions-list{list-style:none;padding:0;margin:0}.alert-suggestions-list li{padding:3px 0 3px 16px;font-size:12px;color:#ffffff80;position:relative;line-height:1.5}.alert-suggestions-list li:before{content:"•";position:absolute;left:4px;color:#646cff}.alert-actions-title{font-size:12px;font-weight:600;color:#e0e0e0;margin-bottom:6px}.alert-actions-btns{display:flex;gap:8px;flex-wrap:wrap}.alert-action-btn{background:#646cff26;border-color:#646cff4d;color:#a5abff;font-size:12px}.alert-action-btn:hover:not(:disabled){background:#646cff40;border-color:#646cff;color:#fff}.suggestion-panel{display:flex;flex-direction:column;gap:12px}.suggestion-panel-empty{padding:16px;color:#ffffff80}.suggestion-item{padding:14px;border-radius:8px;border-left:3px solid;background:#ffffff05}.suggestion-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.suggestion-icon{font-size:14px}.suggestion-title{font-size:14px;font-weight:600;flex:1}.suggestion-category{font-size:10px;padding:2px 6px;border-radius:3px;background:#ffffff1a;color:#ffffff80}.suggestion-desc{font-size:13px;color:#ffffff80;margin-bottom:8px}.suggestion-list{list-style:none;padding:0}.suggestion-list li{padding:4px 0 4px 16px;font-size:12px;color:#e0e0e0;position:relative}.suggestion-list li:before{content:"•";position:absolute;left:4px;color:#646cff}.suggestion-code{margin-top:8px}.suggestion-code code{display:block;background:#0000004d;padding:6px 10px;border-radius:4px;font-size:12px;color:#52c41a;margin-bottom:4px;font-family:monospace}.suggestion-actions{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px;padding-top:10px;border-top:1px solid rgba(255,255,255,.06)}.suggestion-action-btn{background:#646cff26;border-color:#646cff4d;color:#a5abff;font-size:12px}.suggestion-action-btn:hover:not(:disabled){background:#646cff40;border-color:#646cff;color:#fff}.report-page{height:100%}.report-layout{display:grid;grid-template-columns:280px 1fr;gap:20px;height:calc(100vh - 92px)}.session-list{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px;overflow-y:auto}.session-list h3{font-size:14px;margin-bottom:12px}.session-list-actions{display:flex;gap:6px;margin-bottom:8px}.session-list-empty{text-align:center;padding:30px 10px;color:#ffffff80}.session-list-empty .hint{font-size:12px;margin-top:8px}.session-items{display:flex;flex-direction:column;gap:8px;margin-top:12px}.session-item{padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,.1);cursor:pointer;transition:all .2s}.session-item:hover{border-color:#646cff}.session-item.active{border-color:#646cff;background:#646cff1a}.session-item-header{display:flex;align-items:flex-start;justify-content:space-between;gap:4px}.session-item-label{font-size:13px;font-weight:600;margin-bottom:4px;flex:1;word-break:break-all}.session-item-actions{display:flex;gap:2px;flex-shrink:0}.session-item-meta{display:flex;gap:8px;font-size:11px;color:#ffffff80}.btn-icon{background:none;border:none;cursor:pointer;padding:2px 4px;font-size:12px;border-radius:4px;transition:all .2s;opacity:.6;line-height:1}.btn-icon:hover{opacity:1;background:#ffffff1a}.btn-icon:disabled{opacity:.3;cursor:not-allowed}.btn-icon-danger:hover{background:#ff4d4f33}.session-status{font-size:10px;padding:1px 6px;border-radius:3px}.session-status.completed{background:#52c41a33;color:#52c41a}.session-status.running{background:#faad1433;color:#faad14}.session-status.aborted{background:#ff4d4f33;color:#ff4d4f}.report-detail{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:20px;overflow-y:auto}.report-loading,.report-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:#ffffff80}.report-placeholder-icon{font-size:48px;margin-bottom:16px}.report-desc{color:#ffffff80;margin-bottom:16px}.report-section{margin-bottom:24px}.report-section h3{font-size:14px;margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid rgba(255,255,255,.1)}.env-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.env-item{display:flex;flex-direction:column;gap:2px;padding:8px;background:#ffffff08;border-radius:8px}.env-label{font-size:11px;color:#ffffff80}.env-value{font-size:13px;font-weight:500}.report-stats-table{width:100%;border-collapse:collapse}.report-stats-table th,.report-stats-table td{padding:8px 12px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1);font-size:13px}.report-stats-table th{color:#ffffff80;font-weight:500;font-size:12px}.report-stats-table .degraded{color:#ff4d4f;font-weight:600}.report-stats-table .improved{color:#52c41a;font-weight:600}.report-marks-hint{font-size:12px;color:#ffffff80;margin:-4px 0 12px;line-height:1.5}.report-marks-table-wrap{overflow-x:auto;border:1px solid rgba(255,255,255,.1);border-radius:8px}.report-marks-table{width:100%;border-collapse:collapse;font-size:12px}.report-marks-table th,.report-marks-table td{padding:8px 10px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1)}.report-marks-table th{color:#ffffff80;font-weight:500;white-space:nowrap}.report-marks-table .mark-label-cell{font-weight:600;color:#faad14;max-width:200px;word-break:break-all}.report-marks-table .mark-meta-cell{font-family:ui-monospace,monospace;font-size:11px;color:#ffffff80;max-width:280px;overflow:hidden;text-overflow:ellipsis}.chart-marks-caption{font-size:11px;color:#ffffff80;margin:0 0 8px}.chart-marks-caption code{font-size:10px;padding:1px 5px;border-radius:3px;background:#00000059;color:#52c41a;font-family:ui-monospace,monospace}.dashboard-mark-explorer-section{margin-top:8px}.mark-explorer-report-panel{margin-top:16px;padding-top:12px;border-top:1px solid rgba(255,255,255,.1)}.mark-explorer-report-panel h4{font-size:14px;margin-bottom:10px}.mark-explorer{border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:12px 14px;background:#ffffff05}.mark-explorer-empty .mark-explorer-hint{margin:0;font-size:12px;color:#ffffff80;line-height:1.55}.mark-explorer-toolbar{display:flex;flex-wrap:wrap;align-items:flex-start;gap:12px;margin-bottom:12px}.mark-explorer-select-label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:#ffffff80}.mark-explorer-select-label span{white-space:nowrap}.mark-explorer-select{min-width:280px;max-width:100%;padding:6px 10px;border-radius:8px;border:1px solid rgba(255,255,255,.1);background:#ffffff0d;color:#e0e0e0;font-size:12px}.mark-explorer-caption{flex:1;min-width:200px;font-size:11px;color:#ffffff80;line-height:1.5}.mark-explorer-caption strong{color:#e0e0e0;font-weight:600}.mark-explorer-chart-wrap{width:100%;margin-bottom:8px}.mark-explorer-detail{margin-top:16px;padding-top:14px;border-top:1px solid rgba(255,255,255,.1)}.mark-explorer-detail-head{margin-bottom:12px}.mark-explorer-detail-head h4{font-size:14px;margin:0 0 6px;color:#faad14}.mark-explorer-detail-meta{margin:0;font-size:12px;color:#ffffff80;line-height:1.45}.mark-explorer-meta-json{font-family:ui-monospace,monospace;font-size:11px;opacity:.9}.mark-explorer-process-section,.mark-explorer-v8-section{margin-top:12px}.mark-explorer-process-section h3,.mark-explorer-v8-section h3{font-size:13px}.trend-grid{display:flex;flex-direction:column;gap:8px}.trend-item{display:flex;align-items:center;gap:12px;padding:8px 12px;background:#ffffff08;border-radius:8px;font-size:13px}.trend-label{font-weight:600;min-width:80px}.trend-slope{font-family:monospace;color:#1890ff}.trend-r2{font-family:monospace;color:#ffffff80;font-size:12px}.trend-confidence{font-size:11px;padding:1px 6px;border-radius:3px}.trend-confidence.high{background:#52c41a33;color:#52c41a}.trend-confidence.medium{background:#faad1433;color:#faad14}.trend-confidence.low{background:#ffffff1a;color:#ffffff80}.report-meta-bar{display:flex;gap:16px;margin-bottom:16px;font-size:13px;color:#ffffff80}.report-visual-section .report-time-controls{display:flex;flex-direction:column;gap:10px;margin-bottom:16px;padding:12px;background:#ffffff05;border-radius:8px}.report-visual-section .time-presets{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.report-visual-section .time-custom-range{display:flex;align-items:center;gap:8px}.report-visual-section .time-custom-range input{max-width:180px}.report-visual-section .granularity-control{display:flex;align-items:center;gap:8px}.report-visual-section .granularity-control select{max-width:160px}.report-visual-section .control-label{font-size:12px;color:#ffffff80;min-width:70px;white-space:nowrap}.report-visual-section .data-info{font-size:12px;color:#ffffff80;margin-left:8px}.report-panel-toggles{display:flex;gap:6px;margin-bottom:16px;flex-wrap:wrap}.panel-toggle{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);color:#ffffff80;padding:6px 12px;border-radius:8px;cursor:pointer;font-size:12px;transition:all .2s}.panel-toggle:hover{border-color:#646cff;color:#e0e0e0}.panel-toggle.active{background:#646cff26;border-color:#646cff;color:#e0e0e0}.report-snapshots-loading,.report-no-data{display:flex;align-items:center;justify-content:center;gap:8px;padding:30px;color:#ffffff80;font-size:13px}.report-no-snapshots-detail{flex-direction:column;align-items:stretch;justify-content:flex-start;text-align:left;max-width:720px;margin-left:auto;margin-right:auto;line-height:1.55}.report-no-snapshots-detail p{margin:0 0 12px;font-size:12px;color:#ffffff80}.report-no-snapshots-detail p:last-child{margin-bottom:0}.report-no-snapshots-detail strong{color:#e0e0e0}.report-no-snapshots-detail code{font-size:11px;padding:1px 5px;border-radius:3px;background:#00000059;font-family:ui-monospace,monospace}.report-aborted-hint{border-left:3px solid #faad14;padding-left:12px}.report-renderer-v8-hint{font-size:11px!important}.report-chart-panel{margin-bottom:16px}.report-charts-row{display:flex;gap:16px;margin-bottom:16px}.report-charts-row>.chart-container{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px}.report-charts-row h4{font-size:13px;margin-bottom:10px;color:#e0e0e0}.report-chart-panel>.chart-container{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px}.report-chart-panel>.chart-container h4{font-size:13px;margin-bottom:10px;color:#e0e0e0}.compare-page h2{font-size:18px;margin-bottom:20px}.compare-selector{display:flex;align-items:flex-end;gap:16px;margin-bottom:24px;padding:16px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px}.compare-select-group{display:flex;flex-direction:column;gap:6px;flex:1}.compare-select-group label{font-size:12px;color:#ffffff80}.compare-select-group select{width:100%}.compare-arrow{font-size:20px;color:#ffffff80;padding-bottom:4px}.compare-verdict{padding:20px;border:2px solid;border-radius:12px;text-align:center;margin-bottom:24px}.verdict-icon{font-size:28px}.verdict-label{display:block;font-size:18px;font-weight:700;margin:8px 0}.verdict-reason{color:#ffffff80;font-size:13px}.compare-section{margin-bottom:24px}.compare-section h3{font-size:14px;margin-bottom:12px}.compare-table{width:100%;border-collapse:collapse}.compare-table th,.compare-table td{padding:10px 12px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1);font-size:13px}.compare-table th{color:#ffffff80;font-weight:500;font-size:12px}.compare-table .degraded{color:#ff4d4f;font-weight:600}.compare-table .improved{color:#52c41a;font-weight:600}.trend-changes{display:flex;flex-direction:column;gap:8px}.trend-change-item{display:flex;align-items:center;gap:12px;padding:8px 12px;background:#ffffff08;border-radius:8px;font-size:13px}.trend-change-item.degraded{border-left:3px solid #ff4d4f}.trend-change-item.improved{border-left:3px solid #52c41a}.trend-change-metric{font-weight:600;min-width:100px}.regression-list,.improvement-list{display:flex;flex-direction:column;gap:8px}.regression-item{padding:12px;border-radius:8px;background:#ffffff05}.regression-item.severity-critical{border-left:3px solid #ff4d4f}.regression-item.severity-major{border-left:3px solid #faad14}.regression-item.severity-minor{border-left:3px solid rgba(255,255,255,.5)}.regression-header{display:flex;align-items:center;gap:8px;margin-bottom:6px}.regression-metric{font-weight:600}.regression-delta{color:#ff4d4f;font-weight:600}.regression-severity{font-size:10px;padding:1px 6px;border-radius:3px;background:#ffffff1a}.regression-desc{font-size:12px;color:#ffffff80;margin-bottom:4px}.regression-suggestion{font-size:12px;color:#faad14}.improvement-item{display:flex;gap:12px;padding:8px 12px;background:#52c41a0d;border-radius:8px;border-left:3px solid #52c41a;font-size:13px}.improvement-metric{font-weight:600}.improvement-delta{color:#52c41a;font-weight:600}.dashboard-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;height:60vh;color:#ffffff80}.loading-spinner{width:40px;height:40px;border:3px solid rgba(255,255,255,.1);border-top-color:#646cff;border-radius:50%;animation:spin 1s linear infinite;margin-bottom:16px}@keyframes spin{to{transform:rotate(360deg)}}.anomaly-timeline{display:flex;flex-direction:column;gap:8px}.anomaly-item{display:flex;align-items:flex-start;gap:10px;padding:8px 12px;border-radius:8px;background:#ffffff05}.anomaly-item.severity-critical{border-left:3px solid #ff4d4f}.anomaly-item.severity-warning{border-left:3px solid #faad14}.anomaly-item.severity-info{border-left:3px solid #1890ff}.anomaly-time{font-size:11px;color:#ffffff80;min-width:70px}.anomaly-title{font-size:13px;font-weight:500}.anomaly-desc{font-size:12px;color:#ffffff80}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff26;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#ffffff40}@media(max-width:1200px){.charts-row{grid-template-columns:1fr}.report-layout{grid-template-columns:240px 1fr}}@media(max-width:800px){.report-layout{grid-template-columns:1fr}.env-grid{grid-template-columns:repeat(2,1fr)}.compare-selector{flex-direction:column;align-items:stretch}.compare-arrow{text-align:center}}
|
package/dist/ui/index.html
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Electron Memory Monitor</title>
|
|
7
|
-
<script type="module" src="./assets/index-
|
|
7
|
+
<script type="module" src="./assets/index-DnuSyhKD.js"></script>
|
|
8
8
|
<link rel="modulepreload" href="./assets/vendor-BMPuFM9B.js">
|
|
9
|
-
<link rel="stylesheet" href="./assets/index-
|
|
9
|
+
<link rel="stylesheet" href="./assets/index-DrFTVGFf.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="monitor-root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electron-memory/monitor",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Electron memory profiling SDK - zero-intrusion memory monitoring, anomaly detection, and regression analysis",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
*{margin:0;padding:0;box-sizing:border-box}html,body{width:100%;height:100%;font-family:Segoe UI,PingFang SC,Microsoft YaHei,sans-serif;background-color:#1a1a2e;color:#e0e0e0;-webkit-font-smoothing:antialiased;font-size:14px}#monitor-root{width:100%;min-height:100vh}.monitor-app{display:flex;flex-direction:column;min-height:100vh}.monitor-nav{display:flex;align-items:center;justify-content:space-between;background:#16213e;padding:0 24px;height:52px;border-bottom:1px solid rgba(255,255,255,.1)}.monitor-nav-brand{display:flex;align-items:center;gap:10px}.monitor-nav-icon{font-size:20px}.monitor-nav-title{font-size:16px;font-weight:600;color:#e0e0e0}.monitor-nav-tabs{display:flex;gap:4px}.monitor-nav-tab{background:none;border:none;color:#ffffff80;padding:8px 16px;border-radius:8px;cursor:pointer;font-size:13px;transition:all .2s}.monitor-nav-tab:hover{background:#ffffff0d;color:#e0e0e0}.monitor-nav-tab.active{background:#646cff;color:#fff}.monitor-main{flex:1;padding:20px 24px;overflow-y:auto}.metric-cards-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:20px}.metric-card{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-top:3px solid #646cff;border-radius:12px;padding:16px;transition:transform .2s}.metric-card:hover{transform:translateY(-2px)}.metric-card-header{display:flex;align-items:center;gap:6px;margin-bottom:8px}.metric-card-icon{font-size:16px}.metric-card-title{font-size:12px;color:#ffffff80;text-transform:uppercase;letter-spacing:.5px}.metric-card-value{display:flex;align-items:baseline;gap:4px}.metric-card-number{font-size:22px;font-weight:700;color:#e0e0e0}.metric-card-unit{font-size:12px;color:#ffffff80}.metric-card-trend{font-size:12px;margin-top:4px;display:flex;gap:4px}.charts-row{display:grid;grid-template-columns:2fr 1fr;gap:16px;margin-bottom:20px}.chart-container{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px}.chart-container h3{font-size:14px;margin-bottom:12px;color:#e0e0e0}.chart-empty{display:flex;align-items:center;justify-content:center;height:200px;color:#ffffff80;font-size:14px}.process-table-container{overflow-x:auto}.process-table{width:100%;border-collapse:collapse}.process-table th,.process-table td{padding:10px 12px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1)}.process-table th{font-size:12px;color:#ffffff80;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.process-table td{font-size:13px}.process-table tr:hover{background:#ffffff08}.process-table tr.monitor-process{opacity:.6}.process-table .pid{font-family:monospace;color:#ffffff80}.process-table .memory-value{font-family:monospace;color:#1890ff}.process-table .cpu-value{font-family:monospace}.process-table .process-name{max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.process-type-badge{display:inline-block;padding:2px 8px;border-radius:4px;font-size:11px;color:#fff;font-weight:500}.session-control{position:relative;z-index:5;pointer-events:auto;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px;margin-bottom:20px}.session-control-status{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-size:13px}.session-control-actions{display:flex;flex-wrap:wrap;gap:12px;align-items:center}.status-dot{width:8px;height:8px;border-radius:50%}.status-dot.running{background:#52c41a;animation:pulse 1.5s infinite}.status-dot.idle{background:#ffffff80}@keyframes pulse{0%,to{opacity:1}50%{opacity:.4}}.session-start-form{display:flex;gap:8px}.session-start-form input{flex:1;min-width:200px}.session-tools{display:flex;gap:8px;align-items:center;flex-wrap:wrap}.mark-form{display:flex;gap:4px;align-items:center;flex-wrap:wrap}.mark-count-badge{font-size:11px;color:#ffffff80;white-space:nowrap;padding:2px 8px;border-radius:8px;background:#faad1426;color:#faad14}.btn{padding:8px 16px;border-radius:8px;border:1px solid rgba(255,255,255,.1);font-size:13px;cursor:pointer;transition:all .2s;display:inline-flex;align-items:center;gap:4px}.btn:disabled{opacity:.5;cursor:not-allowed}.btn-sm{padding:4px 10px;font-size:12px}.btn-primary{background:#646cff;border-color:#646cff;color:#fff}.btn-primary:hover:not(:disabled){background:#535bf2}.btn-secondary{background:#ffffff0d;color:#e0e0e0}.btn-secondary:hover:not(:disabled){background:#ffffff1a}.btn-danger{background:#ff4d4f;border-color:#ff4d4f;color:#fff}.btn-danger:hover:not(:disabled){background:#ff1a1d}input[type=text],select{padding:8px 12px;border-radius:8px;border:1px solid rgba(255,255,255,.1);background:#ffffff0d;color:#e0e0e0;font-size:13px;outline:none;transition:border-color .2s}input[type=text]:focus,select:focus{border-color:#646cff}input[type=text]::placeholder,select::placeholder{color:#ffffff80}select{cursor:pointer}select option{background:#16213e}.section{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px;margin-bottom:20px}.section h3{font-size:14px;margin-bottom:12px;color:#e0e0e0}.v8-heap-detail h3{font-size:14px;margin-bottom:8px}.v8-heap-detail h4{font-size:13px;margin:16px 0 8px;color:#ffffff80}.v8-heap-detail-caption{font-size:11px;color:#ffffff80;line-height:1.5;margin:0 0 12px}.v8-heap-detail-caption code{font-size:10px;padding:1px 4px;border-radius:3px;background:#00000059;font-family:ui-monospace,monospace}.process-table-caption{font-size:11px;color:#ffffff80;margin:-4px 0 10px;line-height:1.45}.renderer-v8-panel h3{font-size:14px;margin-bottom:8px;color:#e0e0e0}.renderer-v8-caption{font-size:11px;color:#ffffff80;line-height:1.5;margin:0 0 12px}.renderer-v8-empty{font-size:12px;color:#ffffff80;margin:0;line-height:1.5}.renderer-v8-table th,.renderer-v8-table td{font-size:11px}.v8-overview{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px}.v8-stat{background:#ffffff08;border-radius:8px;padding:8px 12px;display:flex;flex-direction:column;gap:4px}.v8-stat-label{font-size:11px;color:#ffffff80;text-transform:uppercase}.v8-stat-value{font-size:14px;font-weight:600;font-family:monospace}.v8-stat-value.danger{color:#ff4d4f}.v8-stat-value.warn{color:#faad14}.v8-spaces-table{width:100%;border-collapse:collapse}.v8-spaces-table th,.v8-spaces-table td{padding:6px 10px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1);font-size:12px}.v8-spaces-table th{color:#ffffff80;font-weight:500}.v8-spaces-table .space-name{font-family:monospace;color:#1890ff}.usage-bar{position:relative;height:18px;background:#ffffff0d;border-radius:4px;overflow:hidden}.usage-bar-fill{height:100%;border-radius:4px;transition:width .3s}.usage-bar-text{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-size:10px;color:#fff;font-weight:500}.alert-panel-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.alert-panel-clear{background:none;border:none;color:#ffffff80;cursor:pointer;font-size:12px}.alert-panel-clear:hover{color:#e0e0e0}.alert-panel-empty{display:flex;align-items:center;gap:8px;padding:16px;color:#ffffff80}.alert-panel-empty-icon{font-size:16px}.alert-panel-list{display:flex;flex-direction:column;gap:8px;max-height:300px;overflow-y:auto}.alert-item{padding:10px 12px;border-radius:8px;border-left:3px solid}.alert-item-header{display:flex;align-items:center;gap:8px;margin-bottom:4px}.alert-item-icon{font-size:14px}.alert-item-title{font-size:13px;font-weight:500;flex:1}.alert-item-time{font-size:11px;color:#ffffff80}.alert-item-desc{font-size:12px;color:#ffffff80}.suggestion-panel{display:flex;flex-direction:column;gap:12px}.suggestion-panel-empty{padding:16px;color:#ffffff80}.suggestion-item{padding:14px;border-radius:8px;border-left:3px solid;background:#ffffff05}.suggestion-header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.suggestion-icon{font-size:14px}.suggestion-title{font-size:14px;font-weight:600;flex:1}.suggestion-category{font-size:10px;padding:2px 6px;border-radius:3px;background:#ffffff1a;color:#ffffff80}.suggestion-desc{font-size:13px;color:#ffffff80;margin-bottom:8px}.suggestion-list{list-style:none;padding:0}.suggestion-list li{padding:4px 0 4px 16px;font-size:12px;color:#e0e0e0;position:relative}.suggestion-list li:before{content:"•";position:absolute;left:4px;color:#646cff}.suggestion-code{margin-top:8px}.suggestion-code code{display:block;background:#0000004d;padding:6px 10px;border-radius:4px;font-size:12px;color:#52c41a;margin-bottom:4px;font-family:monospace}.report-page{height:100%}.report-layout{display:grid;grid-template-columns:280px 1fr;gap:20px;height:calc(100vh - 92px)}.session-list{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px;overflow-y:auto}.session-list h3{font-size:14px;margin-bottom:12px}.session-list-actions{display:flex;gap:6px;margin-bottom:8px}.session-list-empty{text-align:center;padding:30px 10px;color:#ffffff80}.session-list-empty .hint{font-size:12px;margin-top:8px}.session-items{display:flex;flex-direction:column;gap:8px;margin-top:12px}.session-item{padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,.1);cursor:pointer;transition:all .2s}.session-item:hover{border-color:#646cff}.session-item.active{border-color:#646cff;background:#646cff1a}.session-item-header{display:flex;align-items:flex-start;justify-content:space-between;gap:4px}.session-item-label{font-size:13px;font-weight:600;margin-bottom:4px;flex:1;word-break:break-all}.session-item-actions{display:flex;gap:2px;flex-shrink:0}.session-item-meta{display:flex;gap:8px;font-size:11px;color:#ffffff80}.btn-icon{background:none;border:none;cursor:pointer;padding:2px 4px;font-size:12px;border-radius:4px;transition:all .2s;opacity:.6;line-height:1}.btn-icon:hover{opacity:1;background:#ffffff1a}.btn-icon:disabled{opacity:.3;cursor:not-allowed}.btn-icon-danger:hover{background:#ff4d4f33}.session-status{font-size:10px;padding:1px 6px;border-radius:3px}.session-status.completed{background:#52c41a33;color:#52c41a}.session-status.running{background:#faad1433;color:#faad14}.session-status.aborted{background:#ff4d4f33;color:#ff4d4f}.report-detail{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:20px;overflow-y:auto}.report-loading,.report-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:#ffffff80}.report-placeholder-icon{font-size:48px;margin-bottom:16px}.report-desc{color:#ffffff80;margin-bottom:16px}.report-section{margin-bottom:24px}.report-section h3{font-size:14px;margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid rgba(255,255,255,.1)}.env-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}.env-item{display:flex;flex-direction:column;gap:2px;padding:8px;background:#ffffff08;border-radius:8px}.env-label{font-size:11px;color:#ffffff80}.env-value{font-size:13px;font-weight:500}.report-stats-table{width:100%;border-collapse:collapse}.report-stats-table th,.report-stats-table td{padding:8px 12px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1);font-size:13px}.report-stats-table th{color:#ffffff80;font-weight:500;font-size:12px}.report-stats-table .degraded{color:#ff4d4f;font-weight:600}.report-stats-table .improved{color:#52c41a;font-weight:600}.report-marks-hint{font-size:12px;color:#ffffff80;margin:-4px 0 12px;line-height:1.5}.report-marks-table-wrap{overflow-x:auto;border:1px solid rgba(255,255,255,.1);border-radius:8px}.report-marks-table{width:100%;border-collapse:collapse;font-size:12px}.report-marks-table th,.report-marks-table td{padding:8px 10px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1)}.report-marks-table th{color:#ffffff80;font-weight:500;white-space:nowrap}.report-marks-table .mark-label-cell{font-weight:600;color:#faad14;max-width:200px;word-break:break-all}.report-marks-table .mark-meta-cell{font-family:ui-monospace,monospace;font-size:11px;color:#ffffff80;max-width:280px;overflow:hidden;text-overflow:ellipsis}.chart-marks-caption{font-size:11px;color:#ffffff80;margin:0 0 8px}.chart-marks-caption code{font-size:10px;padding:1px 5px;border-radius:3px;background:#00000059;color:#52c41a;font-family:ui-monospace,monospace}.dashboard-mark-explorer-section{margin-top:8px}.mark-explorer-report-panel{margin-top:16px;padding-top:12px;border-top:1px solid rgba(255,255,255,.1)}.mark-explorer-report-panel h4{font-size:14px;margin-bottom:10px}.mark-explorer{border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:12px 14px;background:#ffffff05}.mark-explorer-empty .mark-explorer-hint{margin:0;font-size:12px;color:#ffffff80;line-height:1.55}.mark-explorer-toolbar{display:flex;flex-wrap:wrap;align-items:flex-start;gap:12px;margin-bottom:12px}.mark-explorer-select-label{display:flex;flex-direction:column;gap:4px;font-size:12px;color:#ffffff80}.mark-explorer-select-label span{white-space:nowrap}.mark-explorer-select{min-width:280px;max-width:100%;padding:6px 10px;border-radius:8px;border:1px solid rgba(255,255,255,.1);background:#ffffff0d;color:#e0e0e0;font-size:12px}.mark-explorer-caption{flex:1;min-width:200px;font-size:11px;color:#ffffff80;line-height:1.5}.mark-explorer-caption strong{color:#e0e0e0;font-weight:600}.mark-explorer-chart-wrap{width:100%;margin-bottom:8px}.mark-explorer-detail{margin-top:16px;padding-top:14px;border-top:1px solid rgba(255,255,255,.1)}.mark-explorer-detail-head{margin-bottom:12px}.mark-explorer-detail-head h4{font-size:14px;margin:0 0 6px;color:#faad14}.mark-explorer-detail-meta{margin:0;font-size:12px;color:#ffffff80;line-height:1.45}.mark-explorer-meta-json{font-family:ui-monospace,monospace;font-size:11px;opacity:.9}.mark-explorer-process-section,.mark-explorer-v8-section{margin-top:12px}.mark-explorer-process-section h3,.mark-explorer-v8-section h3{font-size:13px}.trend-grid{display:flex;flex-direction:column;gap:8px}.trend-item{display:flex;align-items:center;gap:12px;padding:8px 12px;background:#ffffff08;border-radius:8px;font-size:13px}.trend-label{font-weight:600;min-width:80px}.trend-slope{font-family:monospace;color:#1890ff}.trend-r2{font-family:monospace;color:#ffffff80;font-size:12px}.trend-confidence{font-size:11px;padding:1px 6px;border-radius:3px}.trend-confidence.high{background:#52c41a33;color:#52c41a}.trend-confidence.medium{background:#faad1433;color:#faad14}.trend-confidence.low{background:#ffffff1a;color:#ffffff80}.report-meta-bar{display:flex;gap:16px;margin-bottom:16px;font-size:13px;color:#ffffff80}.report-visual-section .report-time-controls{display:flex;flex-direction:column;gap:10px;margin-bottom:16px;padding:12px;background:#ffffff05;border-radius:8px}.report-visual-section .time-presets{display:flex;align-items:center;gap:6px;flex-wrap:wrap}.report-visual-section .time-custom-range{display:flex;align-items:center;gap:8px}.report-visual-section .time-custom-range input{max-width:180px}.report-visual-section .granularity-control{display:flex;align-items:center;gap:8px}.report-visual-section .granularity-control select{max-width:160px}.report-visual-section .control-label{font-size:12px;color:#ffffff80;min-width:70px;white-space:nowrap}.report-visual-section .data-info{font-size:12px;color:#ffffff80;margin-left:8px}.report-panel-toggles{display:flex;gap:6px;margin-bottom:16px;flex-wrap:wrap}.panel-toggle{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);color:#ffffff80;padding:6px 12px;border-radius:8px;cursor:pointer;font-size:12px;transition:all .2s}.panel-toggle:hover{border-color:#646cff;color:#e0e0e0}.panel-toggle.active{background:#646cff26;border-color:#646cff;color:#e0e0e0}.report-snapshots-loading,.report-no-data{display:flex;align-items:center;justify-content:center;gap:8px;padding:30px;color:#ffffff80;font-size:13px}.report-no-snapshots-detail{flex-direction:column;align-items:stretch;justify-content:flex-start;text-align:left;max-width:720px;margin-left:auto;margin-right:auto;line-height:1.55}.report-no-snapshots-detail p{margin:0 0 12px;font-size:12px;color:#ffffff80}.report-no-snapshots-detail p:last-child{margin-bottom:0}.report-no-snapshots-detail strong{color:#e0e0e0}.report-no-snapshots-detail code{font-size:11px;padding:1px 5px;border-radius:3px;background:#00000059;font-family:ui-monospace,monospace}.report-aborted-hint{border-left:3px solid #faad14;padding-left:12px}.report-renderer-v8-hint{font-size:11px!important}.report-chart-panel{margin-bottom:16px}.report-charts-row{display:flex;gap:16px;margin-bottom:16px}.report-charts-row>.chart-container{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px}.report-charts-row h4{font-size:13px;margin-bottom:10px;color:#e0e0e0}.report-chart-panel>.chart-container{background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px;padding:16px}.report-chart-panel>.chart-container h4{font-size:13px;margin-bottom:10px;color:#e0e0e0}.compare-page h2{font-size:18px;margin-bottom:20px}.compare-selector{display:flex;align-items:flex-end;gap:16px;margin-bottom:24px;padding:16px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:12px}.compare-select-group{display:flex;flex-direction:column;gap:6px;flex:1}.compare-select-group label{font-size:12px;color:#ffffff80}.compare-select-group select{width:100%}.compare-arrow{font-size:20px;color:#ffffff80;padding-bottom:4px}.compare-verdict{padding:20px;border:2px solid;border-radius:12px;text-align:center;margin-bottom:24px}.verdict-icon{font-size:28px}.verdict-label{display:block;font-size:18px;font-weight:700;margin:8px 0}.verdict-reason{color:#ffffff80;font-size:13px}.compare-section{margin-bottom:24px}.compare-section h3{font-size:14px;margin-bottom:12px}.compare-table{width:100%;border-collapse:collapse}.compare-table th,.compare-table td{padding:10px 12px;text-align:left;border-bottom:1px solid rgba(255,255,255,.1);font-size:13px}.compare-table th{color:#ffffff80;font-weight:500;font-size:12px}.compare-table .degraded{color:#ff4d4f;font-weight:600}.compare-table .improved{color:#52c41a;font-weight:600}.trend-changes{display:flex;flex-direction:column;gap:8px}.trend-change-item{display:flex;align-items:center;gap:12px;padding:8px 12px;background:#ffffff08;border-radius:8px;font-size:13px}.trend-change-item.degraded{border-left:3px solid #ff4d4f}.trend-change-item.improved{border-left:3px solid #52c41a}.trend-change-metric{font-weight:600;min-width:100px}.regression-list,.improvement-list{display:flex;flex-direction:column;gap:8px}.regression-item{padding:12px;border-radius:8px;background:#ffffff05}.regression-item.severity-critical{border-left:3px solid #ff4d4f}.regression-item.severity-major{border-left:3px solid #faad14}.regression-item.severity-minor{border-left:3px solid rgba(255,255,255,.5)}.regression-header{display:flex;align-items:center;gap:8px;margin-bottom:6px}.regression-metric{font-weight:600}.regression-delta{color:#ff4d4f;font-weight:600}.regression-severity{font-size:10px;padding:1px 6px;border-radius:3px;background:#ffffff1a}.regression-desc{font-size:12px;color:#ffffff80;margin-bottom:4px}.regression-suggestion{font-size:12px;color:#faad14}.improvement-item{display:flex;gap:12px;padding:8px 12px;background:#52c41a0d;border-radius:8px;border-left:3px solid #52c41a;font-size:13px}.improvement-metric{font-weight:600}.improvement-delta{color:#52c41a;font-weight:600}.dashboard-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;height:60vh;color:#ffffff80}.loading-spinner{width:40px;height:40px;border:3px solid rgba(255,255,255,.1);border-top-color:#646cff;border-radius:50%;animation:spin 1s linear infinite;margin-bottom:16px}@keyframes spin{to{transform:rotate(360deg)}}.anomaly-timeline{display:flex;flex-direction:column;gap:8px}.anomaly-item{display:flex;align-items:flex-start;gap:10px;padding:8px 12px;border-radius:8px;background:#ffffff05}.anomaly-item.severity-critical{border-left:3px solid #ff4d4f}.anomaly-item.severity-warning{border-left:3px solid #faad14}.anomaly-item.severity-info{border-left:3px solid #1890ff}.anomaly-time{font-size:11px;color:#ffffff80;min-width:70px}.anomaly-title{font-size:13px;font-weight:500}.anomaly-desc{font-size:12px;color:#ffffff80}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff26;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#ffffff40}@media(max-width:1200px){.charts-row{grid-template-columns:1fr}.report-layout{grid-template-columns:240px 1fr}}@media(max-width:800px){.report-layout{grid-template-columns:1fr}.env-grid{grid-template-columns:repeat(2,1fr)}.compare-selector{flex-direction:column;align-items:stretch}.compare-arrow{text-align:center}}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import{r as De,a as Ve,g as ze,b as h,R as Z,L as fe,C as ve,X as ge,Y as Ne,T as X,c as Q,d as M,e as Ge,P as _e,f as Oe,h as He,i as We}from"./vendor-BMPuFM9B.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))a(c);new MutationObserver(c=>{for(const o of c)if(o.type==="childList")for(const x of o.addedNodes)x.tagName==="LINK"&&x.rel==="modulepreload"&&a(x)}).observe(document,{childList:!0,subtree:!0});function i(c){const o={};return c.integrity&&(o.integrity=c.integrity),c.referrerPolicy&&(o.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?o.credentials="include":c.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function a(c){if(c.ep)return;c.ep=!0;const o=i(c);fetch(c.href,o)}})();var J={exports:{}},R={};/**
|
|
2
|
-
* @license React
|
|
3
|
-
* react-jsx-runtime.production.min.js
|
|
4
|
-
*
|
|
5
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
6
|
-
*
|
|
7
|
-
* This source code is licensed under the MIT license found in the
|
|
8
|
-
* LICENSE file in the root directory of this source tree.
|
|
9
|
-
*/var de;function qe(){if(de)return R;de=1;var s=De(),t=Symbol.for("react.element"),i=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,c=s.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,o={key:!0,ref:!0,__self:!0,__source:!0};function x(m,r,v){var d,b={},g=null,f=null;v!==void 0&&(g=""+v),r.key!==void 0&&(g=""+r.key),r.ref!==void 0&&(f=r.ref);for(d in r)a.call(r,d)&&!o.hasOwnProperty(d)&&(b[d]=r[d]);if(m&&m.defaultProps)for(d in r=m.defaultProps,r)b[d]===void 0&&(b[d]=r[d]);return{$$typeof:t,type:m,key:g,ref:f,props:b,_owner:c.current}}return R.Fragment=i,R.jsx=x,R.jsxs=x,R}var me;function Je(){return me||(me=1,J.exports=qe()),J.exports}var e=Je(),z={},he;function Ye(){if(he)return z;he=1;var s=Ve();return z.createRoot=s.createRoot,z.hydrateRoot=s.hydrateRoot,z}var Ze=Ye();const Xe=ze(Ze),B=({title:s,value:t,unit:i,trend:a,trendValue:c,color:o="#646cff",icon:x})=>{const m=a==="up"?"↑":a==="down"?"↓":"→",r=a==="up"?"#ff4d4f":a==="down"?"#52c41a":"#faad14";return e.jsxs("div",{className:"metric-card",style:{borderTopColor:o},children:[e.jsxs("div",{className:"metric-card-header",children:[x&&e.jsx("span",{className:"metric-card-icon",children:x}),e.jsx("span",{className:"metric-card-title",children:s})]}),e.jsxs("div",{className:"metric-card-value",children:[e.jsx("span",{className:"metric-card-number",children:t}),i&&e.jsx("span",{className:"metric-card-unit",children:i})]}),a&&c&&e.jsxs("div",{className:"metric-card-trend",style:{color:r},children:[e.jsx("span",{children:m}),e.jsx("span",{children:c})]})]})},ue=s=>s>1024*1024?`${(s/1024/1024).toFixed(1)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,Qe=s=>{switch(s){case"Browser":return"#646cff";case"Tab":return"#61dafb";case"GPU":return"#f5a623";case"Utility":return"#8b8b8b";default:return"#999"}},es=s=>{switch(s){case"Browser":return"主进程";case"Tab":return"渲染进程";case"GPU":return"GPU";case"Utility":return"辅助进程";default:return s}},ee=({processes:s})=>{const t=[...s].sort((i,a)=>a.memory.workingSetSize-i.memory.workingSetSize);return e.jsx("div",{className:"process-table-container",children:e.jsxs("table",{className:"process-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"PID"}),e.jsx("th",{children:"类型"}),e.jsx("th",{children:"名称"}),e.jsx("th",{children:"工作集"}),e.jsx("th",{children:"峰值"}),e.jsx("th",{children:"CPU"})]})}),e.jsx("tbody",{children:t.map(i=>e.jsxs("tr",{className:i.isMonitorProcess?"monitor-process":"",children:[e.jsx("td",{className:"pid",children:i.pid}),e.jsx("td",{children:e.jsx("span",{className:"process-type-badge",style:{backgroundColor:Qe(i.type)},children:es(i.type)})}),e.jsxs("td",{className:"process-name",children:[i.isMonitorProcess?"🔍 ":"",i.name||i.windowTitle||"-"]}),e.jsx("td",{className:"memory-value",children:ue(i.memory.workingSetSize)}),e.jsx("td",{className:"memory-value",children:ue(i.memory.peakWorkingSetSize)}),e.jsxs("td",{className:"cpu-value",children:[i.cpu.percentCPUUsage.toFixed(1),"%"]})]},i.pid))})]})})},xe=s=>{const t=new Date(s);return`${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}`},I={total:"#646cff",browser:"#f5a623",renderer:"#61dafb",gpu:"#ff6b6b",other:"#8b8b8b"},be=({snapshots:s,height:t=300})=>{var x,m;const i=h.useMemo(()=>s.map(r=>{const v=r.processes.filter(f=>f.type==="Browser").reduce((f,N)=>f+N.memory.workingSetSize,0),d=r.processes.filter(f=>f.type==="Tab"&&!f.isMonitorProcess).reduce((f,N)=>f+N.memory.workingSetSize,0),b=r.processes.filter(f=>f.type==="GPU").reduce((f,N)=>f+N.memory.workingSetSize,0),g=r.processes.filter(f=>!f.isMonitorProcess&&f.type!=="Browser"&&f.type!=="GPU"&&f.type!=="Tab").reduce((f,N)=>f+N.memory.workingSetSize,0);return{timestamp:r.timestamp,total:Math.round(r.totalWorkingSetSize/1024*10)/10,browser:Math.round(v/1024*10)/10,renderer:Math.round(d/1024*10)/10,gpu:Math.round(b/1024*10)/10,other:Math.round(g/1024*10)/10}}),[s]),a=h.useMemo(()=>{const r=[];for(const v of s)v.marks&&r.push(...v.marks);return r},[s]);if(i.length===0)return e.jsx("div",{className:"chart-empty",children:"等待数据采集..."});const c=((x=i[0])==null?void 0:x.timestamp)??0,o=((m=i[i.length-1])==null?void 0:m.timestamp)??0;return e.jsx(Z,{width:"100%",height:t,children:e.jsxs(fe,{data:i,margin:{top:5,right:30,left:20,bottom:5},children:[e.jsx(ve,{strokeDasharray:"3 3",stroke:"rgba(255,255,255,0.1)"}),e.jsx(ge,{type:"number",dataKey:"timestamp",domain:[c,o],stroke:"rgba(255,255,255,0.5)",fontSize:12,tickFormatter:r=>xe(r)}),e.jsx(Ne,{stroke:"rgba(255,255,255,0.5)",fontSize:12,tickFormatter:r=>`${r} MB`}),e.jsx(X,{contentStyle:{background:"rgba(26, 26, 46, 0.95)",border:"1px solid rgba(255,255,255,0.1)",borderRadius:8,color:"#e0e0e0"},labelFormatter:r=>xe(Number(r)),formatter:(r,v)=>[`${r.toFixed(1)} MB`,v]}),e.jsx(Q,{}),e.jsx(M,{type:"monotone",dataKey:"total",name:"总内存",stroke:I.total,dot:!1,strokeWidth:2}),e.jsx(M,{type:"monotone",dataKey:"browser",name:"主进程",stroke:I.browser,dot:!1,strokeWidth:1.5}),e.jsx(M,{type:"monotone",dataKey:"renderer",name:"渲染进程",stroke:I.renderer,dot:!1,strokeWidth:1.5}),e.jsx(M,{type:"monotone",dataKey:"gpu",name:"GPU",stroke:I.gpu,dot:!1,strokeWidth:1.5}),e.jsx(M,{type:"monotone",dataKey:"other",name:"其他",stroke:I.other,dot:!1,strokeWidth:1,strokeDasharray:"4 2"}),a.map((r,v)=>e.jsx(Ge,{x:r.timestamp,stroke:"#faad14",strokeDasharray:"3 3",strokeWidth:1.5,label:{value:r.label,position:"top",fill:"#faad14",fontSize:10}},`${r.timestamp}-${v}-${r.label}`))]})})},w=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,se=({v8Detail:s,title:t="主进程 V8 堆详情(Browser / Node)"})=>{const i=(s==null?void 0:s.heapTotal)>0?Math.round((s.heapUsed||0)/s.heapTotal*100):0;return e.jsxs("div",{className:"v8-heap-detail",children:[e.jsx("h3",{children:t}),e.jsxs("p",{className:"v8-heap-detail-caption",children:["来自主进程内 Node 的 ",e.jsx("code",{children:"process.memoryUsage"})," 与 ",e.jsx("code",{children:"v8.getHeapStatistics"}),",不是各网页标签里的 Chromium JS 堆(后者见「渲染进程 V8」表)。"]}),e.jsxs("div",{className:"v8-overview",children:[e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Heap Used"}),e.jsx("span",{className:"v8-stat-value",children:w(s.heapUsed)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Heap Total"}),e.jsx("span",{className:"v8-stat-value",children:w(s.heapTotal)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"使用率"}),e.jsxs("span",{className:`v8-stat-value ${i>80?"danger":i>60?"warn":""}`,children:[i,"%"]})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"External"}),e.jsx("span",{className:"v8-stat-value",children:w(s.external)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"ArrayBuffers"}),e.jsx("span",{className:"v8-stat-value",children:w(s.arrayBuffers)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"RSS"}),e.jsx("span",{className:"v8-stat-value",children:w(s.rss)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Heap Limit"}),e.jsx("span",{className:"v8-stat-value",children:w(s.heapSizeLimit)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Malloced"}),e.jsx("span",{className:"v8-stat-value",children:w(s.mallocedMemory)})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Detached Contexts"}),e.jsx("span",{className:`v8-stat-value ${(s.numberOfDetachedContexts??0)>0?"danger":""}`,children:s.numberOfDetachedContexts??0})]}),e.jsxs("div",{className:"v8-stat",children:[e.jsx("span",{className:"v8-stat-label",children:"Native Contexts"}),e.jsx("span",{className:"v8-stat-value",children:s.numberOfNativeContexts??0})]})]}),s.heapSpaces&&s.heapSpaces.length>0&&e.jsxs("div",{className:"v8-heap-spaces",children:[e.jsx("h4",{children:"堆空间详情"}),e.jsxs("table",{className:"v8-spaces-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"空间"}),e.jsx("th",{children:"大小"}),e.jsx("th",{children:"已使用"}),e.jsx("th",{children:"使用率"}),e.jsx("th",{children:"可用"})]})}),e.jsx("tbody",{children:s.heapSpaces.map(a=>{const c=a.size??0,o=a.usedSize??0,x=a.availableSize??0,m=c>0?Math.round(o/c*100):0;return e.jsxs("tr",{children:[e.jsx("td",{className:"space-name",children:a.name}),e.jsx("td",{children:w(c)}),e.jsx("td",{children:w(o)}),e.jsx("td",{children:e.jsxs("div",{className:"usage-bar",children:[e.jsx("div",{className:"usage-bar-fill",style:{width:`${m}%`,backgroundColor:m>80?"#ff4d4f":m>60?"#faad14":"#52c41a"}}),e.jsxs("span",{className:"usage-bar-text",children:[m,"%"]})]})}),e.jsx("td",{children:w(x)})]},a.name)})})]})]})]})},G=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`;function ss(s,t,i){const a=s.find(o=>o.pid===t);if(a!=null&&a.name)return a.name;if(a!=null&&a.windowTitle)return a.windowTitle;const c=s.find(o=>o.webContentsId===i);return c!=null&&c.name?c.name:c!=null&&c.windowTitle?c.windowTitle:`渲染进程 PID ${t}`}const re=({processes:s,details:t,emptyHint:i})=>{const a=h.useMemo(()=>t!=null&&t.length?[...t].sort((o,x)=>o.pid-x.pid):[],[t]);return e.jsxs("div",{className:"renderer-v8-panel",children:[e.jsx("h3",{children:"渲染进程 V8(各标签页 Chromium JS 堆)"}),e.jsxs("p",{className:"renderer-v8-caption",children:["数据来自各渲染进程定时 IPC 上报,与上方「主进程 V8」不是同一套运行时。进程表中的",e.jsx("strong",{children:"所有"})," Tab 行会同时列出,与当前是否激活该标签无关。"]}),a.length===0?e.jsx("p",{className:"renderer-v8-empty",children:i??"当前快照无渲染进程 V8 数据。请在业务 WebContents 的 preload 中调用 injectRendererReporter(),并设置 enableRendererDetail: true。"}):e.jsx("div",{className:"report-marks-table-wrap",children:e.jsxs("table",{className:"report-marks-table renderer-v8-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"页面 / 标题"}),e.jsx("th",{children:"PID"}),e.jsx("th",{children:"webContentsId"}),e.jsx("th",{children:"Heap Used"}),e.jsx("th",{children:"Heap Total"}),e.jsx("th",{children:"External"}),e.jsx("th",{children:"ArrayBuffers"})]})}),e.jsx("tbody",{children:a.map(o=>e.jsxs("tr",{children:[e.jsx("td",{className:"mark-label-cell",children:ss(s,o.pid,o.webContentsId)}),e.jsx("td",{children:o.pid}),e.jsx("td",{children:o.webContentsId}),e.jsx("td",{children:G(o.heapUsed)}),e.jsx("td",{children:G(o.heapTotal)}),e.jsx("td",{children:G(o.external)}),e.jsx("td",{children:G(o.arrayBuffers)})]},`${o.pid}-${o.webContentsId}`))})]})})]})};function rs(s){var a;const t=[];let i=0;for(const c of s)if((a=c.marks)!=null&&a.length)for(const o of c.marks)i+=1,t.push({key:`m-${o.timestamp}-${i}-${o.label.slice(0,24)}`,mark:o,snapshot:c});return t.sort((c,o)=>c.mark.timestamp-o.mark.timestamp),t}const _={browser:"#f5a623",renderer:"#61dafb",gpu:"#ff6b6b",other:"#8b8b8b"},ye=s=>{const t=new Date(s);return`${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}`},ts=(s,t)=>s.length<=t?s:`${s.slice(0,t-1)}…`;function as(s){const t=s.processes.filter(o=>o.type==="Browser").reduce((o,x)=>o+x.memory.workingSetSize,0),i=s.processes.filter(o=>o.type==="Tab"&&!o.isMonitorProcess).reduce((o,x)=>o+x.memory.workingSetSize,0),a=s.processes.filter(o=>o.type==="GPU").reduce((o,x)=>o+x.memory.workingSetSize,0),c=s.processes.filter(o=>!o.isMonitorProcess&&o.type!=="Browser"&&o.type!=="GPU"&&o.type!=="Tab").reduce((o,x)=>o+x.memory.workingSetSize,0);return{browser:Math.round(t/1024*10)/10,renderer:Math.round(i/1024*10)/10,gpu:Math.round(a/1024*10)/10,other:Math.round(c/1024*10)/10}}function ns(s){return s.map((t,i)=>{const a=as(t.snapshot),c=ts(t.mark.label,14);return{key:t.key,axisLabel:`#${i+1} ${c}`,title:`${ye(t.mark.timestamp)} · ${t.mark.label}`,mark:t.mark,snapshot:t.snapshot,...a}})}function O(s,t){const{cx:i,cy:a,index:c,stroke:o}=s;return i==null||a==null||c==null?null:e.jsx("circle",{cx:i,cy:a,r:4,fill:o||"#888",stroke:"rgba(0,0,0,0.35)",strokeWidth:1,style:{cursor:"pointer"},onClick:()=>t(c)})}const Se=({snapshots:s,variant:t="dashboard"})=>{const i=h.useMemo(()=>rs(s),[s]),a=h.useMemo(()=>ns(i),[i]),[c,o]=h.useState("");h.useEffect(()=>{if(a.length===0){o("");return}o(r=>r&&a.some(v=>v.key===r)?r:a[0].key)},[a]);const x=h.useCallback(r=>{const v=a[r];v&&o(v.key)},[a]),m=h.useMemo(()=>a.find(r=>r.key===c)??null,[a,c]);return a.length===0?e.jsx("div",{className:"mark-explorer mark-explorer-empty",children:e.jsx("p",{className:"mark-explorer-hint",children:t==="dashboard"?"暂无标记:在代码中调用 monitor.mark(),或使用上方「事件标记」在下一拍采样写入后,此处会出现各标记时刻的内存对比图。":"当前加载的快照中无标记数据;若会话内曾打标,请确认未过度缩小时间范围。"})}):e.jsxs("div",{className:"mark-explorer",children:[e.jsxs("div",{className:"mark-explorer-toolbar",children:[e.jsxs("label",{className:"mark-explorer-select-label",children:[e.jsx("span",{children:"选中标记"}),e.jsx("select",{className:"mark-explorer-select",value:c,onChange:r=>o(r.target.value),children:a.map(r=>e.jsx("option",{value:r.key,children:r.title},r.key))})]}),e.jsxs("span",{className:"mark-explorer-caption",children:["折线按标记时间顺序连接各",e.jsx("strong",{children:"采样时刻"}),"工作集(MB):Browser / 渲染 / GPU / 其他。点击折线上圆点可切换下方进程表与 V8(主进程 + 各渲染进程)。"]})]}),e.jsx("div",{className:"mark-explorer-chart-wrap",children:e.jsx(Z,{width:"100%",height:320,children:e.jsxs(fe,{data:a,margin:{top:8,right:16,left:8,bottom:48},children:[e.jsx(ve,{strokeDasharray:"3 3",stroke:"rgba(255,255,255,0.08)"}),e.jsx(ge,{dataKey:"axisLabel",stroke:"rgba(255,255,255,0.5)",fontSize:11,interval:0,angle:-28,textAnchor:"end",height:70}),e.jsx(Ne,{stroke:"rgba(255,255,255,0.5)",fontSize:12,tickFormatter:r=>`${r} MB`,label:{value:"工作集",angle:-90,position:"insideLeft",fill:"rgba(255,255,255,0.45)",fontSize:11}}),e.jsx(X,{contentStyle:{background:"rgba(26, 26, 46, 0.96)",border:"1px solid rgba(255,255,255,0.12)",borderRadius:8,color:"#e0e0e0"},formatter:(r,v)=>[`${r.toFixed(1)} MB`,v],labelFormatter:(r,v)=>{var b;const d=(b=v==null?void 0:v[0])==null?void 0:b.payload;return d?d.title:""}}),e.jsx(Q,{}),e.jsx(M,{type:"monotone",dataKey:"browser",name:"主进程",stroke:_.browser,strokeWidth:2,dot:r=>O(r,x),activeDot:{r:6},connectNulls:!0}),e.jsx(M,{type:"monotone",dataKey:"renderer",name:"渲染进程",stroke:_.renderer,strokeWidth:2,dot:r=>O(r,x),activeDot:{r:6},connectNulls:!0}),e.jsx(M,{type:"monotone",dataKey:"gpu",name:"GPU",stroke:_.gpu,strokeWidth:2,dot:r=>O(r,x),activeDot:{r:6},connectNulls:!0}),e.jsx(M,{type:"monotone",dataKey:"other",name:"其他",stroke:_.other,strokeWidth:2,dot:r=>O(r,x),activeDot:{r:6},connectNulls:!0})]})})}),m&&e.jsxs("div",{className:"mark-explorer-detail",children:[e.jsxs("div",{className:"mark-explorer-detail-head",children:[e.jsxs("h4",{children:["📌 标记「",m.mark.label,"」时刻详情"]}),e.jsxs("p",{className:"mark-explorer-detail-meta",children:["采样时间 ",ye(m.snapshot.timestamp),"(seq #",m.snapshot.seq,") · 进程 ",m.snapshot.processes.length," 个",m.mark.metadata&&Object.keys(m.mark.metadata).length>0&&e.jsxs("span",{className:"mark-explorer-meta-json",children:[" · ",JSON.stringify(m.mark.metadata)]})]})]}),e.jsxs("div",{className:"section mark-explorer-process-section",children:[e.jsx("h3",{children:"📋 进程详情"}),e.jsx(ee,{processes:m.snapshot.processes})]}),m.snapshot.mainProcessV8Detail&&e.jsx("div",{className:"section mark-explorer-v8-section",children:e.jsx(se,{v8Detail:m.snapshot.mainProcessV8Detail,title:"📌 标记时刻 · 主进程 V8 堆详情"})}),e.jsx("div",{className:"section mark-explorer-renderer-v8-section",children:e.jsx(re,{processes:m.snapshot.processes,details:m.snapshot.rendererDetails})})]})]})},is={Browser:"#7c83ff",Tab:"#61dafb",GPU:"#ffb347",Utility:"#a8a8a8",Zygote:"#ff8a8a"},os={Browser:"主进程",Tab:"渲染进程",GPU:"GPU",Utility:"辅助进程",Zygote:"Zygote"},pe=Math.PI/180,ls=({cx:s,cy:t,midAngle:i,outerRadius:a,name:c,value:o,percent:x})=>{const m=a+25,r=s+m*Math.cos(-i*pe),v=t+m*Math.sin(-i*pe);return e.jsx("text",{x:r,y:v,fill:"#e0e0e0",textAnchor:r>s?"start":"end",dominantBaseline:"central",fontSize:12,children:`${c} ${o}MB (${(x*100).toFixed(1)}%)`})},ke=({processes:s,height:t=280})=>{const i=h.useMemo(()=>{const a=new Map;for(const c of s){if(c.isMonitorProcess)continue;const o=c.type;a.set(o,(a.get(o)||0)+c.memory.workingSetSize)}return Array.from(a.entries()).map(([c,o])=>({name:os[c]||c,value:Math.round(o/1024),color:is[c]||"#bbb"})).sort((c,o)=>o.value-c.value)},[s]);return e.jsx(Z,{width:"100%",height:t,children:e.jsxs(_e,{children:[e.jsx(Oe,{data:i,dataKey:"value",nameKey:"name",cx:"50%",cy:"50%",outerRadius:80,innerRadius:28,label:ls,labelLine:{stroke:"rgba(255,255,255,0.4)",strokeWidth:1},paddingAngle:2,isAnimationActive:!1,children:i.map((a,c)=>e.jsx(He,{fill:a.color,stroke:"rgba(0,0,0,0.3)",strokeWidth:1},c))}),e.jsx(X,{contentStyle:{background:"rgba(26, 26, 46, 0.95)",border:"1px solid rgba(255,255,255,0.1)",borderRadius:8,color:"#e0e0e0"},formatter:a=>[`${a} MB`,"内存"]}),e.jsx(Q,{})]})})},cs={info:{icon:"ℹ️",color:"#1890ff",bg:"rgba(24, 144, 255, 0.1)"},warning:{icon:"⚠️",color:"#faad14",bg:"rgba(250, 173, 20, 0.1)"},critical:{icon:"🔴",color:"#ff4d4f",bg:"rgba(255, 77, 79, 0.1)"}},ds=({anomalies:s,onClear:t})=>s.length===0?e.jsxs("div",{className:"alert-panel-empty",children:[e.jsx("span",{className:"alert-panel-empty-icon",children:"✅"}),e.jsx("span",{children:"暂无异常检测到"})]}):e.jsxs("div",{className:"alert-panel",children:[e.jsxs("div",{className:"alert-panel-header",children:[e.jsxs("span",{children:["异常告警 (",s.length,")"]}),e.jsx("button",{className:"alert-panel-clear",onClick:t,children:"清除"})]}),e.jsx("div",{className:"alert-panel-list",children:s.slice(-10).reverse().map(i=>{const a=cs[i.severity];return e.jsxs("div",{className:"alert-item",style:{borderLeftColor:a.color,background:a.bg},children:[e.jsxs("div",{className:"alert-item-header",children:[e.jsx("span",{className:"alert-item-icon",children:a.icon}),e.jsx("span",{className:"alert-item-title",children:i.title}),e.jsx("span",{className:"alert-item-time",children:new Date(i.timestamp).toLocaleTimeString()})]}),e.jsx("div",{className:"alert-item-desc",children:i.description})]},i.id)})})]}),ms=({isRunning:s,currentSessionId:t,onStart:i,onStop:a,onTriggerGC:c,onAddMark:o,markCount:x=0})=>{const[m,r]=h.useState(""),[v,d]=h.useState(""),[b,g]=h.useState(!1),f=()=>{m.trim()&&(i(m.trim()),r(""))},N=async()=>{g(!0);try{await a()}finally{g(!1)}},l=()=>{v.trim()&&(o(v.trim()),d(""))};return e.jsxs("div",{className:"session-control",children:[e.jsxs("div",{className:"session-control-status",children:[e.jsx("span",{className:`status-dot ${s?"running":"idle"}`}),e.jsx("span",{children:s?`会话进行中: ${t==null?void 0:t.slice(0,8)}...`:"未开始会话"})]}),e.jsxs("div",{className:"session-control-actions",children:[s?e.jsx("button",{type:"button",className:"btn btn-danger",onClick:N,disabled:b,children:b?"⏳ 结束中...":"⏹ 结束会话"}):e.jsxs("div",{className:"session-start-form",children:[e.jsx("input",{type:"text",placeholder:"会话标签(如 v1.2.0 空载基准)",value:m,onChange:u=>r(u.target.value),onKeyDown:u=>u.key==="Enter"&&f()}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:f,disabled:!m.trim(),children:"▶ 开始会话"})]}),e.jsxs("div",{className:"session-tools",children:[e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:c,title:"手动触发垃圾回收",children:"🗑️ GC"}),e.jsxs("div",{className:"mark-form",children:[e.jsx("input",{type:"text",placeholder:"事件标记",value:v,onChange:u=>d(u.target.value),onKeyDown:u=>u.key==="Enter"&&l()}),e.jsx("button",{type:"button",className:"btn btn-secondary",onClick:l,disabled:!v.trim(),children:"📌 标记"}),x>0&&e.jsxs("span",{className:"mark-count-badge",title:"当前图表缓冲区内已记录的标记数",children:["已记录 ",x," 条"]})]})]})]})]})};function we(s){var i;const t=[];for(const a of s){if(!((i=a.marks)!=null&&i.length))continue;const c=a.processes.filter(m=>m.type==="Browser").reduce((m,r)=>m+r.memory.workingSetSize,0),o=a.processes.filter(m=>m.type==="Tab"&&!m.isMonitorProcess).reduce((m,r)=>m+r.memory.workingSetSize,0),x=a.processes.filter(m=>m.type==="GPU").reduce((m,r)=>m+r.memory.workingSetSize,0);for(const m of a.marks)t.push({timestamp:m.timestamp,label:m.label,metadata:m.metadata,totalWorkingSetKB:a.totalWorkingSetSize,browserKB:c,rendererKB:o,gpuKB:x})}return t}function hs(){const[s,t]=h.useState([]),[i,a]=h.useState(null),[c,o]=h.useState([]),[x,m]=h.useState(!1),r=h.useRef([]);h.useEffect(()=>{var l,u;const f=p=>{a(p),m(!0),r.current=[...r.current,p].slice(-300),t(r.current)},N=p=>{o(y=>[...y,p])};return(l=window.monitorAPI)==null||l.onSnapshot(f),(u=window.monitorAPI)==null||u.onAnomaly(N),()=>{var p,y;(p=window.monitorAPI)==null||p.removeSnapshotListener(),(y=window.monitorAPI)==null||y.removeAnomalyListener()}},[]);const v=h.useCallback(async()=>{var f;return(f=window.monitorAPI)==null?void 0:f.triggerGC()},[]),d=h.useCallback(async f=>{var N;return(N=window.monitorAPI)==null?void 0:N.addMark(f)},[]),b=h.useCallback(()=>{o([])},[]),g=h.useMemo(()=>we(s),[s]);return{snapshots:s,latestSnapshot:i,anomalies:c,isCollecting:x,triggerGC:v,addMark:d,clearAnomalies:b,markTimeline:g}}function te(){const[s,t]=h.useState(null),[i,a]=h.useState(!1),[c,o]=h.useState([]),x=h.useCallback(async(l,u)=>{const p=window.monitorAPI;if(!(p!=null&&p.startSession))return console.error("[@electron-memory/monitor] monitorAPI.startSession 不可用(请确认监控面板 preload 已注入)"),null;try{const y=await p.startSession(l,u);return y&&(t(y),a(!0)),y}catch(y){return console.error("[@electron-memory/monitor] startSession failed:",y),null}},[]),m=h.useCallback(async()=>{var y,C;const l=await((y=window.monitorAPI)==null?void 0:y.getSessions());if(l==null)return;let u,p=null;if(Array.isArray(l))u=l,p=((C=u.find(k=>k.status==="running"))==null?void 0:C.id)??null;else{const k=l;u=Array.isArray(k.sessions)?k.sessions:[],p=k.activeSessionId??null}o(u),t(p),a(!!p)},[]),r=h.useCallback(async()=>{const l=window.monitorAPI;if(!(l!=null&&l.stopSession))return console.error("[@electron-memory/monitor] monitorAPI.stopSession 不可用(请确认监控面板 preload 已注入)"),await m(),null;const u=12e4;try{const p=await Promise.race([l.stopSession(),new Promise((y,C)=>setTimeout(()=>C(new Error(`stopSession 超过 ${u/1e3}s 未返回(主进程可能仍在读 snapshots / 写 report)`)),u))]);return await m(),p&&typeof p=="object"&&"ok"in p&&(p.ok===!0||p.reason==="no_active_session"?(t(null),a(!1)):console.error("[@electron-memory/monitor] stopSession failed:",p)),null}catch(p){return console.error("[@electron-memory/monitor] stopSession failed:",p),await m(),null}},[m]),v=h.useCallback(async l=>{var u;return await((u=window.monitorAPI)==null?void 0:u.getSessionReport(l))},[]),d=h.useCallback(async(l,u,p,y)=>{var k;return await((k=window.monitorAPI)==null?void 0:k.getSessionSnapshots(l,u,p,y))||[]},[]),b=h.useCallback(async(l,u)=>{var p;return(p=window.monitorAPI)==null?void 0:p.compareSessions(l,u)},[]),g=h.useCallback(async l=>{var p;return await((p=window.monitorAPI)==null?void 0:p.exportSession(l))},[]),f=h.useCallback(async()=>{var u;const l=await((u=window.monitorAPI)==null?void 0:u.importSession());return l!=null&&l.success&&await m(),l},[m]),N=h.useCallback(async l=>{var p;const u=await((p=window.monitorAPI)==null?void 0:p.deleteSession(l));return u&&await m(),u},[m]);return{currentSessionId:s,isRunning:i,sessions:c,startSession:x,stopSession:r,refreshSessions:m,getSessionReport:v,getSessionSnapshots:d,compareSessions:b,exportSession:g,importSession:f,deleteSession:N}}const Y=s=>s==null||isNaN(s)?"0 KB":s>1024*1024?`${(s/1024/1024).toFixed(2)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,us=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,xs=({paneVisible:s=!0})=>{const{snapshots:t,latestSnapshot:i,anomalies:a,triggerGC:c,addMark:o,clearAnomalies:x,markTimeline:m}=hs(),{currentSessionId:r,isRunning:v,startSession:d,stopSession:b,refreshSessions:g}=te();if(h.useEffect(()=>{s&&g()},[s,g]),!i)return e.jsxs("div",{className:"dashboard-loading",children:[e.jsx("div",{className:"loading-spinner"}),e.jsx("p",{children:"等待内存数据..."})]});const f=i.processes.find(u=>u.type==="Browser"),N=i.processes.filter(u=>u.type==="Tab"&&!u.isMonitorProcess),l=N.reduce((u,p)=>u+p.memory.workingSetSize,0);return e.jsxs("div",{className:"dashboard",children:[e.jsx(ms,{isRunning:v,currentSessionId:r,onStart:d,onStop:b,onTriggerGC:c,onAddMark:o,markCount:m.length}),e.jsxs("div",{className:"metric-cards-row",children:[e.jsx(B,{icon:"💻",title:"总内存",value:Y(i.totalWorkingSetSize),color:"#646cff"}),e.jsx(B,{icon:"🧠",title:"Browser 工作集",value:Y((f==null?void 0:f.memory.workingSetSize)||0),color:"#f5a623"}),e.jsx(B,{icon:"🖼️",title:"渲染进程",value:Y(l),unit:`(${N.length}个)`,color:"#61dafb"}),e.jsx(B,{icon:"📊",title:"主进程 V8 Used",value:us(i.mainProcessMemory.heapUsed),color:"#52c41a"}),e.jsx(B,{icon:"⚙️",title:"系统内存",value:`${i.system.usagePercent}%`,color:"#ff6b6b"}),e.jsx(B,{icon:"🔢",title:"进程数",value:`${i.processes.length}`,color:"#8b8b8b"})]}),e.jsxs("div",{className:"charts-row",children:[e.jsxs("div",{className:"chart-container chart-wide",children:[e.jsx("h3",{children:"📈 内存趋势"}),e.jsxs("p",{className:"chart-marks-caption",children:["代码里 ",e.jsx("code",{children:"monitor.mark()"})," 或手动「标记」会在",e.jsx("strong",{children:"下一拍采样"}),"写入;趋势图横轴为时间戳,橙色竖线为各 Mark 时刻。"]}),e.jsx(be,{snapshots:t,height:300})]}),e.jsxs("div",{className:"chart-container chart-narrow",children:[e.jsx("h3",{children:"🥧 内存分布"}),e.jsx(ke,{processes:i.processes,height:300})]})]}),e.jsxs("div",{className:"section dashboard-mark-explorer-section",children:[e.jsx("h3",{children:"📍 标记点内存对比与详情"}),e.jsx("p",{className:"report-marks-hint",style:{marginTop:0},children:"下图汇总当前缓冲区内各标记所在采样时刻;下拉或点击柱形查看该时刻的进程表、主进程 V8 与各渲染进程 V8 表。完整会话请结束后在「历史报告」查看。"}),e.jsx(Se,{snapshots:t,variant:"dashboard"})]}),e.jsxs("div",{className:"section",children:[e.jsx("h3",{children:"📋 进程详情"}),e.jsxs("p",{className:"process-table-caption",children:["由系统枚举",e.jsx("strong",{children:"全部"})," Electron 子进程(含每个 Tab),与当前焦点标签无关,无需为了看内存去切换 Tab。"]}),e.jsx(ee,{processes:i.processes})]}),i.mainProcessV8Detail&&e.jsx("div",{className:"section",children:e.jsx(se,{v8Detail:i.mainProcessV8Detail})}),e.jsx("div",{className:"section",children:e.jsx(re,{processes:i.processes,details:i.rendererDetails})}),e.jsxs("div",{className:"section",children:[e.jsx("h3",{children:"🚨 异常告警"}),e.jsx(ds,{anomalies:a,onClear:x})]})]})},ps={info:{icon:"ℹ️",color:"#1890ff"},warning:{icon:"⚠️",color:"#faad14"},critical:{icon:"🔴",color:"#ff4d4f"}},js=({suggestions:s})=>s.length===0?e.jsx("div",{className:"suggestion-panel-empty",children:e.jsx("span",{children:"✅ 未发现需要改进的地方"})}):e.jsx("div",{className:"suggestion-panel",children:s.map(t=>{const i=ps[t.severity];return e.jsxs("div",{className:"suggestion-item",style:{borderLeftColor:i.color},children:[e.jsxs("div",{className:"suggestion-header",children:[e.jsx("span",{className:"suggestion-icon",children:i.icon}),e.jsx("span",{className:"suggestion-title",children:t.title}),e.jsx("span",{className:"suggestion-category",children:t.category})]}),e.jsx("p",{className:"suggestion-desc",children:t.description}),e.jsx("ul",{className:"suggestion-list",children:t.suggestions.map((a,c)=>e.jsx("li",{children:a},c))}),t.relatedCode&&t.relatedCode.length>0&&e.jsx("div",{className:"suggestion-code",children:t.relatedCode.map((a,c)=>e.jsx("code",{children:a},c))})]},t.id)})}),je=s=>{const t=Math.floor(s/1e3),i=Math.floor(t/60),a=Math.floor(i/60);return a>0?`${a}h ${i%60}m ${t%60}s`:i>0?`${i}m ${t%60}s`:`${t}s`},F=s=>s==null||isNaN(s)||s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,S=s=>s==null||isNaN(s)?"0 KB":s>1024*1024?`${(s/1024/1024).toFixed(2)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,A=s=>{const t=new Date(s);return`${t.getHours().toString().padStart(2,"0")}:${t.getMinutes().toString().padStart(2,"0")}:${t.getSeconds().toString().padStart(2,"0")}`},fs=[{label:"全部",value:"all"},{label:"最近 1 分钟",value:"1m"},{label:"最近 5 分钟",value:"5m"},{label:"最近 10 分钟",value:"10m"},{label:"最近 30 分钟",value:"30m"},{label:"自定义",value:"custom"}],vs=[{label:"自动",value:0},{label:"最多 200 点",value:200},{label:"最多 400 点",value:400},{label:"最多 600 点",value:600},{label:"最多 1000 点",value:1e3}],gs=({paneVisible:s=!0})=>{const{sessions:t,refreshSessions:i,getSessionReport:a,getSessionSnapshots:c,exportSession:o,importSession:x,deleteSession:m}=te(),[r,v]=h.useState(null),[d,b]=h.useState(null),[g,f]=h.useState([]),[N,l]=h.useState(!1),[u,p]=h.useState(!1),[y,C]=h.useState(!1),[k,ae]=h.useState(!1),[U,ne]=h.useState("all"),[K,Me]=h.useState(""),[L,Ce]=h.useState(""),[E,Pe]=h.useState(0),[H,$e]=h.useState(!0),[D,Be]=h.useState(!0),[T,Te]=h.useState(!0),[W,Re]=h.useState(!0),[q,Ie]=h.useState(!0);h.useEffect(()=>{s&&i()},[s,i]),h.useEffect(()=>{v(n=>{if(!n)return n;const j=t.find(P=>P.id===n.id);return j?n.status===j.status&&n.snapshotCount===j.snapshotCount&&n.endTime===j.endTime&&n.duration===j.duration?n:j:null})},[t]);const Fe=n=>{v(n),ne("all")};h.useEffect(()=>{if(!r){b(null);return}let n=!1;return l(!0),(async()=>{try{const j=await a(r.id);n||b(j)}catch(j){console.error("Failed to load report:",j),n||b(null)}finally{n||l(!1)}})(),()=>{n=!0}},[r==null?void 0:r.id,r==null?void 0:r.status,r==null?void 0:r.endTime,a]);const V=h.useMemo(()=>{if(!d)return{start:void 0,end:void 0};const n=d.endTime;switch(U){case"1m":return{start:n-60*1e3,end:n};case"5m":return{start:n-300*1e3,end:n};case"10m":return{start:n-600*1e3,end:n};case"30m":return{start:n-1800*1e3,end:n};case"custom":{const j=K?new Date(K).getTime():void 0,P=L?new Date(L).getTime():void 0;return{start:j&&!isNaN(j)?j:void 0,end:P&&!isNaN(P)?P:void 0}}default:return{start:void 0,end:void 0}}},[d,U,K,L]),ie=h.useMemo(()=>{if(E>0)return E;if(!d)return 600;const n=d.duration/6e4;return n>30?300:n>10?400:600},[E,d]),oe=h.useCallback(async()=>{if(r){p(!0);try{const n=await c(r.id,V.start,V.end,ie);f(n)}catch(n){console.error("Failed to load snapshots:",n)}p(!1)}},[r,c,V.start,V.end,ie]);h.useEffect(()=>{r&&d&&oe()},[r,d,oe]);const Ae=async n=>{C(!0);try{const j=await o(n);j!=null&&j.success?console.log("导出成功:",j.filePath):j!=null&&j.error&&j.error!=="用户取消"&&(console.error("导出失败:",j.error),alert("导出失败: "+j.error))}catch(j){console.error("导出异常:",j)}C(!1)},Ue=async()=>{ae(!0);try{const n=await x();n!=null&&n.success?console.log("导入成功"):n!=null&&n.error&&n.error!=="用户取消"&&(console.error("导入失败:",n.error),alert("导入失败: "+n.error))}catch(n){console.error("导入异常:",n)}ae(!1)},Ke=async(n,j)=>{if(n.stopPropagation(),!confirm("确定要删除这个会话吗?此操作不可恢复。"))return;await m(j)&&(r==null?void 0:r.id)===j&&(v(null),b(null),f([]))},$=h.useMemo(()=>g.length>0?g[g.length-1]:null,[g]),le=h.useMemo(()=>g.length===0?null:g[Math.floor(g.length/2)],[g]),ce=h.useMemo(()=>d!=null&&d.eventMarks&&d.eventMarks.length>0?d.eventMarks:we(g),[d==null?void 0:d.eventMarks,g]);return e.jsx("div",{className:"report-page",children:e.jsxs("div",{className:"report-layout",children:[e.jsxs("div",{className:"session-list",children:[e.jsx("h3",{children:"📋 历史会话"}),e.jsxs("div",{className:"session-list-actions",children:[e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:i,children:"🔄 刷新"}),e.jsx("button",{className:"btn btn-secondary btn-sm",onClick:Ue,disabled:k,children:k?"⏳ 导入中...":"📥 导入"})]}),t.length===0?e.jsxs("div",{className:"session-list-empty",children:[e.jsx("p",{children:"暂无历史会话"}),e.jsx("p",{className:"hint",children:"在实时监控页面开始一个测试会话"})]}):e.jsx("div",{className:"session-items",children:t.map(n=>e.jsxs("div",{className:`session-item ${(r==null?void 0:r.id)===n.id?"active":""}`,onClick:()=>Fe(n),children:[e.jsxs("div",{className:"session-item-header",children:[e.jsx("div",{className:"session-item-label",children:n.label}),e.jsxs("div",{className:"session-item-actions",children:[e.jsx("button",{className:"btn-icon",title:"导出会话",onClick:j=>{j.stopPropagation(),Ae(n.id)},disabled:y,children:"📤"}),e.jsx("button",{className:"btn-icon btn-icon-danger",title:"删除会话",onClick:j=>Ke(j,n.id),children:"🗑️"})]})]}),e.jsxs("div",{className:"session-item-meta",children:[e.jsx("span",{children:new Date(n.startTime).toLocaleDateString()}),e.jsx("span",{children:n.duration?je(n.duration):"进行中"}),e.jsxs("span",{children:[n.snapshotCount," 条"]})]}),e.jsx("span",{className:`session-status ${n.status}`,children:n.status})]},n.id))})]}),e.jsxs("div",{className:"report-detail",children:[N&&e.jsx("div",{className:"report-loading",children:"加载中..."}),!N&&!d&&e.jsxs("div",{className:"report-placeholder",children:[e.jsx("span",{className:"report-placeholder-icon",children:"📊"}),e.jsx("p",{children:"选择左侧的会话查看报告"})]}),!N&&d&&e.jsxs("div",{className:"report-content",children:[e.jsx("h2",{children:d.label}),d.description&&e.jsx("p",{className:"report-desc",children:d.description}),e.jsxs("div",{className:"report-meta-bar",children:[e.jsxs("span",{children:["⏱️ ",je(d.duration)]}),e.jsxs("span",{children:["📅 ",new Date(d.startTime).toLocaleString()," ~ ",new Date(d.endTime).toLocaleString()]})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"🖥️ 运行环境"}),e.jsxs("div",{className:"env-grid",children:[e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"Electron"}),e.jsxs("span",{className:"env-value",children:["v",d.environment.electronVersion]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"Chrome"}),e.jsxs("span",{className:"env-value",children:["v",d.environment.chromeVersion]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"Node.js"}),e.jsxs("span",{className:"env-value",children:["v",d.environment.nodeVersion]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"平台"}),e.jsxs("span",{className:"env-value",children:[d.environment.platform,"/",d.environment.arch]})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"系统内存"}),e.jsx("span",{className:"env-value",children:F(d.environment.totalSystemMemory)})]}),e.jsxs("div",{className:"env-item",children:[e.jsx("span",{className:"env-label",children:"CPU"}),e.jsxs("span",{className:"env-value",children:[d.environment.cpuCores," 核"]})]})]})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"📊 统计汇总"}),e.jsxs("table",{className:"report-stats-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"指标"}),e.jsx("th",{children:"初始值"}),e.jsx("th",{children:"最终值"}),e.jsx("th",{children:"平均值"}),e.jsx("th",{children:"P95"}),e.jsx("th",{children:"变化"})]})}),e.jsxs("tbody",{children:[e.jsxs("tr",{children:[e.jsx("td",{children:"总内存"}),e.jsx("td",{children:S(d.summary.totalMemory.initial)}),e.jsx("td",{children:S(d.summary.totalMemory.final)}),e.jsx("td",{children:S(d.summary.totalMemory.avg)}),e.jsx("td",{children:S(d.summary.totalMemory.p95)}),e.jsxs("td",{className:d.summary.totalMemory.deltaPercent>5?"degraded":"",children:[d.summary.totalMemory.deltaPercent>0?"+":"",d.summary.totalMemory.deltaPercent.toFixed(1),"%"]})]}),e.jsxs("tr",{children:[e.jsx("td",{children:"主进程"}),e.jsx("td",{children:S(d.summary.byProcessType.browser.initial)}),e.jsx("td",{children:S(d.summary.byProcessType.browser.final)}),e.jsx("td",{children:S(d.summary.byProcessType.browser.avg)}),e.jsx("td",{children:S(d.summary.byProcessType.browser.p95)}),e.jsxs("td",{className:d.summary.byProcessType.browser.deltaPercent>10?"degraded":"",children:[d.summary.byProcessType.browser.deltaPercent>0?"+":"",d.summary.byProcessType.browser.deltaPercent.toFixed(1),"%"]})]}),e.jsxs("tr",{children:[e.jsx("td",{children:"V8 Heap Used"}),e.jsx("td",{children:F(d.summary.mainV8Heap.heapUsed.initial)}),e.jsx("td",{children:F(d.summary.mainV8Heap.heapUsed.final)}),e.jsx("td",{children:F(d.summary.mainV8Heap.heapUsed.avg)}),e.jsx("td",{children:F(d.summary.mainV8Heap.heapUsed.p95)}),e.jsxs("td",{className:d.summary.mainV8Heap.heapUsed.deltaPercent>10?"degraded":"",children:[d.summary.mainV8Heap.heapUsed.deltaPercent>0?"+":"",d.summary.mainV8Heap.heapUsed.deltaPercent.toFixed(1),"%"]})]})]})]})]}),ce.length>0&&e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"📍 阶段标记(Mark)"}),e.jsxs("p",{className:"report-marks-hint",children:["下列数值为",e.jsx("strong",{children:"该次采样时刻"}),"的快照内存;趋势图中以橙色竖线标出对应时间。未手动点「标记」的会话此处为空。"]}),e.jsx("div",{className:"report-marks-table-wrap",children:e.jsxs("table",{className:"report-marks-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"时间"}),e.jsx("th",{children:"标签"}),e.jsx("th",{children:"总内存"}),e.jsx("th",{children:"主进程"}),e.jsx("th",{children:"渲染"}),e.jsx("th",{children:"GPU"}),e.jsx("th",{children:"附注"})]})}),e.jsx("tbody",{children:ce.map((n,j)=>e.jsxs("tr",{children:[e.jsx("td",{children:A(n.timestamp)}),e.jsx("td",{className:"mark-label-cell",children:n.label}),e.jsx("td",{children:S(n.totalWorkingSetKB)}),e.jsx("td",{children:S(n.browserKB)}),e.jsx("td",{children:S(n.rendererKB)}),e.jsx("td",{children:S(n.gpuKB)}),e.jsx("td",{className:"mark-meta-cell",children:n.metadata&&Object.keys(n.metadata).length>0?JSON.stringify(n.metadata):"—"})]},`${n.timestamp}-${j}-${n.label}`))})]})})]}),e.jsxs("div",{className:"report-section report-visual-section",children:[e.jsx("h3",{children:"📈 数据可视化"}),e.jsxs("div",{className:"report-time-controls",children:[e.jsxs("div",{className:"time-presets",children:[e.jsx("span",{className:"control-label",children:"时间范围:"}),fs.map(n=>e.jsx("button",{className:`btn btn-sm ${U===n.value?"btn-primary":"btn-secondary"}`,onClick:()=>ne(n.value),children:n.label},n.value))]}),U==="custom"&&e.jsxs("div",{className:"time-custom-range",children:[e.jsx("span",{className:"control-label",children:"自定义范围:"}),e.jsx("input",{type:"text",placeholder:`起始 (如 ${A(d.startTime)})`,value:K,onChange:n=>Me(n.target.value)}),e.jsx("span",{children:"~"}),e.jsx("input",{type:"text",placeholder:`结束 (如 ${A(d.endTime)})`,value:L,onChange:n=>Ce(n.target.value)})]}),e.jsxs("div",{className:"granularity-control",children:[e.jsx("span",{className:"control-label",children:"显示粒度:"}),e.jsx("select",{value:E,onChange:n=>Pe(Number(n.target.value)),children:vs.map(n=>e.jsx("option",{value:n.value,children:n.label},n.value))}),e.jsx("span",{className:"data-info",children:u?"加载中...":`已加载 ${g.length} 个数据点`})]})]}),e.jsxs("div",{className:"report-panel-toggles",children:[e.jsx("button",{className:`panel-toggle ${H?"active":""}`,onClick:()=>$e(!H),children:"📈 内存趋势"}),e.jsx("button",{className:`panel-toggle ${D?"active":""}`,onClick:()=>Be(!D),children:"🥧 内存分布"}),e.jsx("button",{className:`panel-toggle ${T?"active":""}`,onClick:()=>Te(!T),children:"📋 进程详情"}),e.jsx("button",{className:`panel-toggle ${W?"active":""}`,onClick:()=>Re(!W),children:"🔧 V8(主进程+渲染)"}),e.jsx("button",{className:`panel-toggle ${q?"active":""}`,onClick:()=>Ie(!q),children:"📌 标记对比与详情"})]}),u&&e.jsxs("div",{className:"report-snapshots-loading",children:[e.jsx("div",{className:"loading-spinner",style:{width:24,height:24}}),e.jsx("span",{children:"正在加载快照数据..."})]}),!u&&g.length===0&&e.jsxs("div",{className:"report-no-data report-no-snapshots-detail",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"该时间范围内没有快照点"}),",因此不会显示趋势图、进程表、主进程/渲染 V8 表。"]}),(r==null?void 0:r.status)==="aborted"&&e.jsxs("p",{className:"report-aborted-hint",children:["当前会话为 ",e.jsx("strong",{children:"aborted"}),":通常是",e.jsx("strong",{children:"上次未点看板「结束会话」就关了应用"}),",或",e.jsx("strong",{children:"开发时 vite / electron 主进程频繁热重启"}),"。 下次启动时 SDK 会把磁盘上仍为 running 的旧会话标为 aborted,且若进程死得太快可能",e.jsx("strong",{children:"0 条采样"}),"。 正常关应用前让当前会话走完 ",e.jsx("code",{children:"stopSession"}),"(browser-sim 已在退出时自动调用)可减少此类记录。"]}),e.jsxs("p",{className:"report-renderer-v8-hint",children:[e.jsx("strong",{children:"渲染进程 V8"}),"写在每条快照的 ",e.jsx("code",{children:"rendererDetails"})," 里;无快照就无从展示。有数据时请在「",e.jsx("strong",{children:"V8(主进程+渲染)"}),"」折叠里向下滚动查看「渲染进程 V8」表,并确认业务 WebContents 的 preload 已 ",e.jsx("code",{children:"injectRendererReporter()"})," 且 ",e.jsx("code",{children:"enableRendererDetail: true"}),"。"]})]}),!u&&g.length>0&&e.jsxs(e.Fragment,{children:[H&&e.jsx("div",{className:"report-chart-panel",children:e.jsxs("div",{className:"chart-container",style:{margin:0},children:[e.jsxs("h4",{children:["📈 内存趋势(",A(g[0].timestamp)," ~ ",A(g[g.length-1].timestamp),")"]}),e.jsx("p",{className:"chart-marks-caption",children:"有 Mark 时以橙色竖线标在对应时间;详见「标记对比与详情」查看各标记时刻的进程与 V8 堆。"}),e.jsx(be,{snapshots:g,height:320})]})}),q&&e.jsxs("div",{className:"report-chart-panel mark-explorer-report-panel",children:[e.jsx("h4",{children:"📌 标记点内存对比与详情"}),e.jsx(Se,{snapshots:g,variant:"report"})]}),(D||T)&&e.jsxs("div",{className:"report-charts-row",children:[D&&le&&e.jsxs("div",{className:"chart-container",style:{margin:0,flex:T?"0 0 360px":"1"},children:[e.jsx("h4",{children:"🥧 内存分布(中间时刻快照)"}),e.jsx(ke,{processes:le.processes,height:280})]}),T&&$&&e.jsxs("div",{className:"chart-container",style:{margin:0,flex:1,overflow:"auto"},children:[e.jsx("h4",{children:"📋 进程详情(最后时刻快照)"}),e.jsx(ee,{processes:$.processes})]})]}),W&&$&&e.jsxs("div",{className:"report-chart-panel",children:[$.mainProcessV8Detail&&e.jsx("div",{className:"chart-container",style:{margin:0},children:e.jsx(se,{v8Detail:$.mainProcessV8Detail})}),e.jsx("div",{className:"chart-container",style:{marginTop:16},children:e.jsx(re,{processes:$.processes,details:$.rendererDetails,emptyHint:"该时间范围内最后一条快照无渲染进程 V8;请确认业务页 preload 已 injectRendererReporter。"})})]})]})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"📈 趋势分析"}),e.jsx("div",{className:"trend-grid",children:["totalMemory","browserMemory","rendererMemory"].map(n=>{const j=d.summary.trends[n],P=j.direction==="growing"?"📈":j.direction==="shrinking"?"📉":"→",Le=j.direction==="growing"?"增长":j.direction==="shrinking"?"下降":"稳定",Ee=n==="totalMemory"?"总内存":n==="browserMemory"?"主进程":"渲染进程";return e.jsxs("div",{className:"trend-item",children:[e.jsx("span",{className:"trend-label",children:Ee}),e.jsxs("span",{className:"trend-direction",children:[P," ",Le]}),e.jsxs("span",{className:"trend-slope",children:[j.slope.toFixed(2)," KB/s"]}),e.jsxs("span",{className:"trend-r2",children:["R²=",j.r2.toFixed(3)]}),e.jsx("span",{className:`trend-confidence ${j.confidence}`,children:j.confidence})]},n)})})]}),e.jsxs("div",{className:"report-section",children:[e.jsx("h3",{children:"💡 改进建议"}),e.jsx(js,{suggestions:d.suggestions})]}),d.anomalies.length>0&&e.jsxs("div",{className:"report-section",children:[e.jsxs("h3",{children:["🚨 异常事件 (",d.anomalies.length,")"]}),e.jsx("div",{className:"anomaly-timeline",children:d.anomalies.map(n=>e.jsxs("div",{className:`anomaly-item severity-${n.severity}`,children:[e.jsx("span",{className:"anomaly-time",children:new Date(n.timestamp).toLocaleTimeString()}),e.jsx("span",{className:"anomaly-title",children:n.title}),e.jsx("span",{className:"anomaly-desc",children:n.description})]},n.id))})]})]})]})]})})},Ns=s=>s>1024*1024?`${(s/1024/1024).toFixed(2)} GB`:s>1024?`${(s/1024).toFixed(1)} MB`:`${Math.round(s)} KB`,bs=s=>s===0?"0 B":s>1024*1024*1024?`${(s/1024/1024/1024).toFixed(2)} GB`:s>1024*1024?`${(s/1024/1024).toFixed(1)} MB`:s>1024?`${(s/1024).toFixed(1)} KB`:`${s} B`,ys=({paneVisible:s=!0})=>{const{sessions:t,refreshSessions:i,compareSessions:a}=te(),[c,o]=h.useState(""),[x,m]=h.useState(""),[r,v]=h.useState(null),[d,b]=h.useState(!1);h.useEffect(()=>{s&&i()},[s,i]);const g=async()=>{if(!(!c||!x)){b(!0);try{const l=await a(c,x);v(l)}catch(l){console.error("Compare failed:",l)}b(!1)}},f=t.filter(l=>l.status==="completed"),N={pass:{icon:"✅",color:"#52c41a",label:"PASS - 通过"},warn:{icon:"🟡",color:"#faad14",label:"WARN - 存在轻微劣化"},fail:{icon:"🔴",color:"#ff4d4f",label:"FAIL - 存在严重劣化"}};return e.jsxs("div",{className:"compare-page",children:[e.jsx("h2",{children:"🔄 迭代对比"}),e.jsxs("div",{className:"compare-selector",children:[e.jsxs("div",{className:"compare-select-group",children:[e.jsx("label",{children:"基准会话 (旧版本)"}),e.jsxs("select",{value:c,onChange:l=>o(l.target.value),children:[e.jsx("option",{value:"",children:"-- 选择基准会话 --"}),f.map(l=>e.jsxs("option",{value:l.id,children:[l.label," (",new Date(l.startTime).toLocaleDateString(),")"]},l.id))]})]}),e.jsx("span",{className:"compare-arrow",children:"→"}),e.jsxs("div",{className:"compare-select-group",children:[e.jsx("label",{children:"对比会话 (新版本)"}),e.jsxs("select",{value:x,onChange:l=>m(l.target.value),children:[e.jsx("option",{value:"",children:"-- 选择对比会话 --"}),f.map(l=>e.jsxs("option",{value:l.id,children:[l.label," (",new Date(l.startTime).toLocaleDateString(),")"]},l.id))]})]}),e.jsx("button",{className:"btn btn-primary",onClick:g,disabled:!c||!x||d,children:d?"对比中...":"开始对比"})]}),r&&e.jsxs("div",{className:"compare-result",children:[e.jsxs("div",{className:"compare-verdict",style:{borderColor:N[r.verdict].color},children:[e.jsx("span",{className:"verdict-icon",children:N[r.verdict].icon}),e.jsx("span",{className:"verdict-label",style:{color:N[r.verdict].color},children:N[r.verdict].label}),e.jsx("p",{className:"verdict-reason",children:r.verdictReason})]}),e.jsxs("div",{className:"compare-section",children:[e.jsx("h3",{children:"📊 指标对比"}),e.jsxs("table",{className:"compare-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"指标"}),e.jsx("th",{children:r.base.label}),e.jsx("th",{children:r.target.label}),e.jsx("th",{children:"变化"}),e.jsx("th",{children:"状态"})]})}),e.jsx("tbody",{children:[{name:"总内存 (avg)",diff:r.overall.totalMemory,isBytes:!1},{name:"主进程 (avg)",diff:r.overall.browserMemory,isBytes:!1},{name:"渲染进程 (avg)",diff:r.overall.rendererMemory,isBytes:!1},...r.overall.gpuMemory?[{name:"GPU (avg)",diff:r.overall.gpuMemory,isBytes:!1}]:[],{name:"V8 Heap Used",diff:r.v8Heap.heapUsed,isBytes:!0},{name:"V8 Heap Total",diff:r.v8Heap.heapTotal,isBytes:!0},{name:"V8 External",diff:r.v8Heap.external,isBytes:!0}].map(l=>{const u=l.diff.status==="improved"?"✅":l.diff.status==="degraded"?"🔴":"➖",p=l.isBytes?bs:Ns;return e.jsxs("tr",{className:`status-${l.diff.status}`,children:[e.jsx("td",{children:l.name}),e.jsx("td",{children:p(l.diff.base)}),e.jsx("td",{children:p(l.diff.target)}),e.jsxs("td",{className:l.diff.deltaPercent>5?"degraded":l.diff.deltaPercent<-3?"improved":"",children:[l.diff.deltaPercent>0?"+":"",l.diff.deltaPercent.toFixed(1),"%"]}),e.jsx("td",{children:u})]},l.name)})})]})]}),e.jsxs("div",{className:"compare-section",children:[e.jsx("h3",{children:"📈 趋势变化"}),e.jsx("div",{className:"trend-changes",children:r.trendChanges.map(l=>{const u=l.change==="improved"?"✅":l.change==="degraded"?"🔴":"➖";return e.jsxs("div",{className:`trend-change-item ${l.change}`,children:[e.jsx("span",{className:"trend-change-metric",children:l.metric}),e.jsxs("span",{children:["基准: ",l.baseSlope.toFixed(2)," KB/s"]}),e.jsxs("span",{children:["目标: ",l.targetSlope.toFixed(2)," KB/s"]}),e.jsx("span",{children:u})]},l.metric)})})]}),r.regressions.length>0&&e.jsxs("div",{className:"compare-section",children:[e.jsxs("h3",{children:["⚠️ 劣化项 (",r.regressions.length,")"]}),e.jsx("div",{className:"regression-list",children:r.regressions.map((l,u)=>e.jsxs("div",{className:`regression-item severity-${l.severity}`,children:[e.jsxs("div",{className:"regression-header",children:[e.jsx("span",{className:"regression-metric",children:l.metric}),e.jsxs("span",{className:"regression-delta",children:["+",l.deltaPercent.toFixed(1),"%"]}),e.jsx("span",{className:`regression-severity ${l.severity}`,children:l.severity})]}),e.jsx("p",{className:"regression-desc",children:l.description}),e.jsxs("p",{className:"regression-suggestion",children:["💡 ",l.suggestion]})]},u))})]}),r.improvements.length>0&&e.jsxs("div",{className:"compare-section",children:[e.jsxs("h3",{children:["✅ 改进项 (",r.improvements.length,")"]}),e.jsx("div",{className:"improvement-list",children:r.improvements.map((l,u)=>e.jsxs("div",{className:"improvement-item",children:[e.jsx("span",{className:"improvement-metric",children:l.metric}),e.jsxs("span",{className:"improvement-delta",children:[l.deltaPercent.toFixed(1),"%"]}),e.jsx("span",{className:"improvement-desc",children:l.description})]},u))})]})]})]})},Ss=()=>{const[s,t]=h.useState("dashboard");return e.jsxs("div",{className:"monitor-app",children:[e.jsxs("nav",{className:"monitor-nav",children:[e.jsxs("div",{className:"monitor-nav-brand",children:[e.jsx("span",{className:"monitor-nav-icon",children:"📊"}),e.jsx("span",{className:"monitor-nav-title",children:"Electron Memory Monitor"})]}),e.jsxs("div",{className:"monitor-nav-tabs",children:[e.jsx("button",{className:`monitor-nav-tab ${s==="dashboard"?"active":""}`,onClick:()=>t("dashboard"),children:"🔴 实时监控"}),e.jsx("button",{className:`monitor-nav-tab ${s==="report"?"active":""}`,onClick:()=>t("report"),children:"📋 历史报告"}),e.jsx("button",{className:`monitor-nav-tab ${s==="compare"?"active":""}`,onClick:()=>t("compare"),children:"🔄 迭代对比"})]})]}),e.jsxs("main",{className:"monitor-main",children:[s==="dashboard"&&e.jsx(xs,{paneVisible:!0}),s==="report"&&e.jsx(gs,{paneVisible:!0}),s==="compare"&&e.jsx(ys,{paneVisible:!0})]})]})};Xe.createRoot(document.getElementById("monitor-root")).render(e.jsx(We.StrictMode,{children:e.jsx(Ss,{})}));
|