forkit-ai-footprints 0.2.0 → 0.2.4
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/PRIVACY.md +57 -27
- package/README.md +43 -41
- package/STATUS.md +92 -37
- package/dist/activity-page.d.ts +13 -0
- package/dist/activity-page.js +105 -0
- package/dist/activity-view-model.d.ts +154 -0
- package/dist/activity-view-model.js +364 -0
- package/dist/agents.d.ts +2 -0
- package/dist/agents.js +108 -6
- package/dist/bootstrap/.metadata_never_index +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app.zip +0 -0
- package/dist/cli.js +91 -14
- package/dist/device-presence.d.ts +17 -0
- package/dist/device-presence.js +64 -0
- package/dist/global-preview.d.ts +34 -0
- package/dist/global-preview.js +209 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -1
- package/dist/insights.d.ts +1 -1
- package/dist/insights.js +10 -8
- package/dist/local-observation-state.d.ts +43 -0
- package/dist/local-observation-state.js +124 -0
- package/dist/locales.json +564 -108
- package/dist/localization.d.ts +564 -108
- package/dist/localization.js +40 -30
- package/dist/monitor.d.ts +38 -2
- package/dist/monitor.js +257 -19
- package/dist/runtime-activity.d.ts +4 -1
- package/dist/runtime-activity.js +21 -5
- package/dist/server.d.ts +5 -0
- package/dist/server.js +160 -17
- package/dist/share-page.d.ts +2 -1
- package/dist/share-page.js +16 -52
- package/dist/sharing.d.ts +12 -1
- package/dist/sharing.js +59 -1
- package/dist/types.d.ts +1 -1
- package/dist/workflow-context.d.ts +13 -0
- package/dist/workflow-context.js +144 -0
- package/docs/GLOBAL_DISTRIBUTION.md +7 -3
- package/docs/MACOS_ACCURACY_GATE.md +3 -3
- package/docs/MACOS_TESTER_GUIDE.md +11 -10
- package/package.json +6 -6
- package/release/channels.json +2 -2
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Info.plist +0 -5
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/MacOS/Forkit AI Footprint +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/ForkitAIFootprint.icns +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/ForkitStatusTemplate.png +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/agents.d.ts +0 -22
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/agents.js +0 -281
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/aggregate.d.ts +0 -28
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/aggregate.js +0 -151
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/assets/forkit-icon-dark.png +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/assets/forkit-icon-light.png +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/census.d.ts +0 -3
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/census.js +0 -196
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/cli.d.ts +0 -32
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/cli.js +0 -404
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/doctor.d.ts +0 -14
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/doctor.js +0 -71
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/endpoints.d.ts +0 -8
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/endpoints.js +0 -45
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/evaluate.d.ts +0 -44
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/evaluate.js +0 -102
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/filesystem.d.ts +0 -11
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/filesystem.js +0 -226
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/format.d.ts +0 -7
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/format.js +0 -78
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/hash.d.ts +0 -4
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/hash.js +0 -16
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/index.d.ts +0 -22
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/index.js +0 -58
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/insights.d.ts +0 -13
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/insights.js +0 -76
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/local-device.d.ts +0 -19
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/local-device.js +0 -81
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/locales.json +0 -272
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/localization.d.ts +0 -277
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/localization.js +0 -55
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/mcp.d.ts +0 -9
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/mcp.js +0 -93
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/monitor.d.ts +0 -99
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/monitor.js +0 -285
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/base.d.ts +0 -34
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/base.js +0 -88
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/index.d.ts +0 -6
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/index.js +0 -24
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/lmstudio.d.ts +0 -9
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/lmstudio.js +0 -71
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/ollama.d.ts +0 -12
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/ollama.js +0 -171
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/openai-compatible.d.ts +0 -10
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/providers/openai-compatible.js +0 -68
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/resource-evidence.d.ts +0 -17
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/resource-evidence.js +0 -52
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-activity.d.ts +0 -5
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-activity.js +0 -66
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-identity.d.ts +0 -7
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/runtime-identity.js +0 -66
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/server.d.ts +0 -21
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/server.js +0 -308
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/share-page.d.ts +0 -75
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/share-page.js +0 -167
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/sharing.d.ts +0 -35
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/sharing.js +0 -67
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/tools.d.ts +0 -9
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/tools.js +0 -106
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/types.d.ts +0 -166
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/types.js +0 -3
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/version.d.ts +0 -4
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/dist/version.js +0 -13
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/index.d.ts +0 -76
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/index.js +0 -366
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/license +0 -9
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/package.json +0 -44
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/readme.md +0 -56
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/vendor/fastlist-0.3.0-x64.exe +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/node_modules/ps-list/vendor/fastlist-0.3.0-x86.exe +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/app/package.json +0 -6
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/Resources/runtime/node +0 -0
- package/dist/bootstrap/Forkit AI Footprint.app/Contents/_CodeSignature/CodeResources +0 -931
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.renderActivityApplicationPage = renderActivityApplicationPage;
|
|
4
|
+
const localization_1 = require("./localization");
|
|
5
|
+
function escapeHtml(value) {
|
|
6
|
+
return String(value).replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", ''');
|
|
7
|
+
}
|
|
8
|
+
function safeScriptJson(value) { return JSON.stringify(value).replaceAll('<', '\\u003c'); }
|
|
9
|
+
function renderActivityApplicationPage(input) {
|
|
10
|
+
const { locale, snapshot, view, rescan, device, brand, shareLogo } = input;
|
|
11
|
+
const t = (key, values = {}) => escapeHtml((0, localization_1.uiText)(locale, key, values));
|
|
12
|
+
const config = rescan ?? null;
|
|
13
|
+
const globalUrl = rescan ? 'https://www.forkit.dev/ai-footprint#global-vision' : null;
|
|
14
|
+
return `<!doctype html>
|
|
15
|
+
<html lang="${locale}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="color-scheme" content="light dark"><title>Forkit AI Footprint</title>
|
|
16
|
+
<style>
|
|
17
|
+
:root{--bg:#f1ece3;--paper:#fbf8f2;--surface:#f6f1e9;--surface-2:#ece7de;--ink:#282624;--muted:#736e66;--line:rgba(40,38,36,.14);--line-strong:rgba(40,38,36,.24);--brand:#00888d;--brand-soft:#d9eeee;--active:#00888d;--idle:#cfc8bd;--excluded:#8a857e;--gold:#d99022;--good:#237d65;--shadow:0 18px 55px rgba(38,34,30,.08)}
|
|
18
|
+
@media(prefers-color-scheme:dark){:root{--bg:#151716;--paper:#202220;--surface:#292b28;--surface-2:#343632;--ink:#f3eee4;--muted:#aaa49a;--line:rgba(243,238,228,.13);--line-strong:rgba(243,238,228,.24);--brand:#69c3bd;--brand-soft:#203c39;--active:#69c3bd;--idle:#4c4944;--excluded:#858079;--gold:#e4ae39;--good:#69bea4;--shadow:0 20px 60px rgba(0,0,0,.27)}}
|
|
19
|
+
*{box-sizing:border-box}html{background:var(--bg)}body{margin:0;overflow-x:hidden;color:var(--ink);background:radial-gradient(circle at 0 0,color-mix(in srgb,var(--gold) 12%,transparent),transparent 28rem),radial-gradient(circle at 100% 0,color-mix(in srgb,var(--brand) 13%,transparent),transparent 30rem),var(--bg);font-family:Inter,ui-sans-serif,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;-webkit-font-smoothing:antialiased}button{font:inherit}[hidden]{display:none!important}.shell{width:min(1220px,calc(100% - 24px));margin:auto;padding:12px 0 24px}.surface{border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--paper) 94%,transparent);box-shadow:var(--shadow)}
|
|
20
|
+
.command{position:relative;display:flex;min-height:54px;align-items:center;justify-content:space-between;gap:16px;padding:8px 10px 8px 12px}.brand{display:flex;min-width:0;align-items:center;gap:10px}.brand-icon,.brand-fallback{width:34px;height:34px;border-radius:10px;object-fit:contain}.brand-fallback{display:grid;place-items:center;color:#fff;background:linear-gradient(145deg,var(--brand),var(--gold));font-weight:900}.brand-copy{min-width:0}.brand-copy strong{display:block;font-size:14px;letter-spacing:-.02em}.status{display:flex;align-items:center;gap:7px;margin-top:2px;color:var(--muted);font-size:10px}.status-dot{width:7px;height:7px;border-radius:999px;background:var(--good);box-shadow:0 0 0 3px color-mix(in srgb,var(--good) 13%,transparent)}.status.paused .status-dot{background:var(--gold)}.status.stopped .status-dot{background:var(--muted)}.command-actions{display:flex;align-items:center;gap:6px}.privacy-chip{display:inline-flex;align-items:center;gap:6px;padding:0 9px;color:var(--muted);font-size:9px;font-weight:760}.privacy-chip b{color:var(--good)}.button,.icon-button{min-height:32px;border:1px solid var(--line-strong);border-radius:9px;color:var(--ink);background:transparent;cursor:pointer;font-size:10px;font-weight:780}.button{padding:0 12px}.button.primary{border-color:var(--brand);color:#fff;background:var(--brand)}.button:disabled{cursor:not-allowed;opacity:.45}.locale{display:flex;padding:2px;border:1px solid var(--line);border-radius:9px}.locale button{min-width:30px;min-height:26px;border:0;border-radius:7px;color:var(--muted);background:transparent;cursor:pointer;font-size:9px;font-weight:850}.locale button.active{color:var(--ink);background:var(--surface-2)}.more{position:relative}.more summary{display:grid;min-width:48px;min-height:32px;place-items:center;border:1px solid var(--line-strong);border-radius:9px;cursor:pointer;font-size:10px;font-weight:780;list-style:none}.more summary::-webkit-details-marker{display:none}.more-menu{position:absolute;z-index:20;right:0;top:40px;display:grid;width:190px;gap:6px;padding:8px;border:1px solid var(--line);border-radius:12px;background:var(--paper);box-shadow:var(--shadow)}.more-menu .button{width:100%;text-align:left}.scan-status{padding:3px 7px;color:var(--muted);font-size:9px;line-height:1.4}
|
|
21
|
+
.metric-rail{display:grid;grid-template-columns:1.12fr .9fr 1fr;margin-top:8px;overflow:hidden}.headline{min-height:70px;padding:11px 14px;border-right:1px solid var(--line)}.headline:last-child{border-right:0}.metric-label{color:var(--muted);font-size:8px;font-weight:850;letter-spacing:.12em;text-transform:uppercase}.metric-value{display:block;margin-top:6px;font-size:22px;font-weight:900;letter-spacing:-.045em}.headline:first-child .metric-value{color:var(--active);font-size:27px}.metric-sub{display:block;margin-top:1px;color:var(--muted);font-size:8px}
|
|
22
|
+
.workspace{display:grid;grid-template-columns:minmax(0,1fr) 350px;gap:8px;margin-top:8px;align-items:start}.explorer{min-width:0;padding:12px}.panel-head{display:flex;align-items:start;justify-content:space-between;gap:12px}.eyebrow{margin:0 0 3px;color:var(--brand);font-size:8px;font-weight:900;letter-spacing:.14em;text-transform:uppercase}.panel-head h1,.panel-head h2,.compact h2{margin:0;font-size:16px;letter-spacing:-.025em}.panel-copy{margin:3px 0 0;color:var(--muted);font-size:9px}.chart-controls{display:flex;gap:4px}.icon-button{min-width:31px;padding:0 8px}.chart-wrap{position:relative;margin-top:8px}.chart-canvas{display:block;width:100%;height:206px;border:1px solid var(--line);border-radius:12px;background:var(--surface);outline:none}.navigator{display:block;width:100%;height:30px;margin-top:5px;border:1px solid var(--line);border-radius:8px;background:var(--surface);cursor:pointer}.chart-tooltip{position:absolute;z-index:10;max-width:240px;padding:8px 9px;border:1px solid var(--line-strong);border-radius:9px;color:var(--ink);background:var(--paper);box-shadow:var(--shadow);font-size:9px;line-height:1.45;pointer-events:none}.chart-help{display:flex;justify-content:space-between;gap:12px;margin-top:5px;color:var(--muted);font-size:8px}.legend{display:flex;gap:11px;flex-wrap:wrap}.legend span{display:inline-flex;align-items:center;gap:5px}.legend i{width:8px;height:8px;border-radius:2px;background:var(--idle)}.legend .active{background:var(--active)}.legend .excluded{background:repeating-linear-gradient(135deg,var(--excluded),var(--excluded) 2px,transparent 2px,transparent 4px);border:1px solid var(--excluded)}.selected-evidence{min-height:34px;padding:7px 8px;border:1px solid var(--line);border-radius:9px;color:var(--muted);background:var(--surface);font-size:9px;line-height:1.4}.selected-evidence strong{color:var(--ink)}
|
|
23
|
+
.insight-rail{display:flex;max-height:calc(100vh - 86px);min-height:420px;flex-direction:column;padding:12px;overflow:auto;scrollbar-width:thin}.insight-rail h2{margin:0;font-size:17px;letter-spacing:-.025em}.insight-copy{margin:3px 0 8px;color:var(--muted);font-size:9px}.device-identity{display:flex;align-items:start;justify-content:space-between;gap:10px;padding-bottom:9px;border-bottom:1px solid var(--line)}.device-identity strong{display:block;max-width:220px;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.observation-number{flex:none;padding:4px 6px;border:1px solid var(--line);border-radius:7px;color:var(--muted);font-size:8px;font-weight:800}.rail-section{padding:10px 0;border-bottom:1px solid var(--line)}.rail-section:last-child{padding-bottom:0;border-bottom:0}.rail-heading{display:flex;align-items:end;justify-content:space-between;gap:8px;margin-bottom:6px}.rail-heading strong{font-size:10px}.rail-heading span{color:var(--muted);font-size:7px}.insight-list{display:grid;gap:6px;margin-top:6px}.insight{width:100%;padding:8px 9px;border:1px solid var(--line);border-left:3px solid var(--accent-system,var(--brand));border-radius:9px;color:var(--ink);background:var(--surface);text-align:left;cursor:pointer;font-size:9px;font-weight:720;line-height:1.35}.insight:hover,.insight:focus-visible{border-color:var(--accent-system,var(--brand));outline:none}.early{padding:10px;border:1px dashed var(--line-strong);border-radius:9px;color:var(--muted);font-size:9px;line-height:1.45}.observation-grid,.resource-grid{display:grid;grid-template-columns:1fr 1fr;gap:5px}.rail-stat{min-width:0;padding:7px 8px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.rail-stat span{display:block;color:var(--muted);font-size:7px;font-weight:780;letter-spacing:.07em;text-transform:uppercase}.rail-stat strong{display:block;margin-top:3px;overflow:hidden;font-size:11px;text-overflow:ellipsis;white-space:nowrap}.rail-list{display:grid;gap:5px}.runtime-item{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:7px 8px;border:1px solid var(--line);border-radius:8px;background:var(--surface);font-size:8px}.runtime-item strong{font-size:9px}.runtime-item span{color:var(--muted);text-align:right}.system-mix{padding-top:10px}.mix-bar{display:flex;height:9px;margin-top:7px;overflow:hidden;border-radius:999px;background:var(--surface-2)}.mix-bar button{height:100%;min-width:3px;border:0;padding:0;cursor:pointer}.mix-list{display:grid;gap:4px;margin-top:7px}.mix-item{display:grid;grid-template-columns:9px minmax(0,1fr) auto;align-items:center;gap:6px;width:100%;border:1px solid transparent;border-radius:8px;padding:6px;color:var(--muted);background:transparent;cursor:pointer;text-align:left;font-size:8px}.mix-item:hover,.mix-item:focus-visible{border-color:var(--line);outline:none}.mix-item i{width:7px;height:7px;border-radius:2px;background:var(--system-color)}.mix-item strong{overflow:hidden;color:var(--ink);font-size:9px;text-overflow:ellipsis;white-space:nowrap}.all-apps{display:block;width:100%;margin-top:7px}.app-inspector{display:grid;gap:6px;margin-top:7px;padding-top:7px;border-top:1px solid var(--line)}
|
|
24
|
+
.observation-tools{display:grid;grid-template-columns:repeat(2,1fr);gap:5px;padding:10px 0;border-bottom:1px solid var(--line)}.feature-tool{position:relative;display:grid;min-width:0;min-height:58px;place-items:center;gap:3px;padding:7px 3px;border:1px solid var(--line);border-radius:10px;color:var(--muted);background:var(--surface);cursor:pointer}.feature-tool:hover,.feature-tool:focus-visible{z-index:4;border-color:var(--brand);color:var(--ink);outline:none}.feature-tool[aria-pressed="true"]{border-color:var(--brand);color:var(--ink);background:color-mix(in srgb,var(--brand-soft) 64%,var(--surface))}.feature-icon{display:grid;width:22px;height:22px;place-items:center;border-radius:7px;color:var(--brand);background:var(--paper);font-size:15px;font-weight:900}.feature-tool>span:last-of-type{overflow:hidden;max-width:100%;font-size:7px;font-weight:850;text-overflow:ellipsis;white-space:nowrap}.feature-tool::after{position:absolute;z-index:30;top:calc(100% + 5px);left:50%;display:none;width:150px;padding:7px 8px;border:1px solid var(--line-strong);border-radius:8px;color:var(--ink);background:var(--paper);box-shadow:var(--shadow);content:attr(data-tip);font-size:8px;font-weight:650;line-height:1.35;transform:translateX(-50%);pointer-events:none}.feature-tool:first-child::after{left:0;transform:none}.feature-tool:last-child::after{right:0;left:auto;transform:none}.feature-tool:hover::after,.feature-tool:focus-visible::after{display:block}.focus-summary{display:grid;grid-template-columns:minmax(150px,.65fr) minmax(0,1.35fr);gap:8px;margin-top:8px;padding:9px;border:1px solid var(--line);border-left:3px solid var(--accent-system,var(--brand));border-radius:10px;background:var(--surface)}.focus-copy strong{display:block;font-size:12px}.focus-copy span{display:block;margin-top:3px;color:var(--muted);font-size:8px;line-height:1.4}.focus-stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:5px}.focus-stats .inspector-stat{padding:6px}.focus-stats .inspector-stat strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rail-section[data-view]{cursor:pointer}.rail-section[data-view]:hover .rail-heading strong{color:var(--brand)}
|
|
25
|
+
.summary-row{display:grid;grid-template-columns:1.55fr 1fr .82fr;gap:8px;margin-top:8px}.compact{min-height:126px;padding:12px}.compact-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:9px}.compact-stat{min-width:0;padding-right:8px;border-right:1px solid var(--line)}.compact-stat:last-child{border-right:0}.compact-stat strong{display:block;margin-top:5px;overflow:hidden;font-size:13px;text-overflow:ellipsis;white-space:nowrap}.compact-stat span{display:block;margin-top:2px;color:var(--muted);font-size:8px}.compact-stat strong>span{display:inline;margin:0;color:inherit;font-size:inherit}.statement{margin:9px 0 0;padding:7px 8px;border-left:3px solid var(--accent-system,var(--brand));border-radius:6px;color:var(--ink);background:var(--surface);font-size:9px;font-weight:720;line-height:1.35}.global-state{display:flex;height:100%;flex-direction:column;justify-content:space-between}.global-state strong{font-size:18px;letter-spacing:-.03em}.global-state p{margin:4px 0;color:var(--muted);font-size:9px;line-height:1.4}
|
|
26
|
+
.advanced{margin-top:8px;padding:0 12px}.advanced>summary{padding:11px 0;cursor:pointer;font-size:10px;font-weight:800}.details-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;padding:0 0 12px}.detail-box{min-height:95px;padding:10px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.detail-box h3{margin:0 0 7px;font-size:10px}.detail-list{display:grid;gap:5px;margin:0;padding:0;list-style:none}.detail-list li{color:var(--muted);font-size:8px;line-height:1.4}.detail-list strong{display:block;color:var(--ink);font-size:9px}.footer{display:flex;justify-content:space-between;gap:14px;padding:10px 3px 0;color:var(--muted);font-size:8px}
|
|
27
|
+
dialog{width:min(780px,calc(100% - 28px));padding:0;border:1px solid var(--line);border-radius:18px;color:var(--ink);background:var(--paper);box-shadow:0 28px 90px rgba(0,0,0,.38)}dialog::backdrop{background:rgba(0,0,0,.72)}.share-layout{display:grid;grid-template-columns:minmax(280px,1fr) 250px;gap:14px;padding:14px}.share-preview{overflow:hidden;border-radius:12px;background:#ede8df}.share-preview canvas{display:block;width:100%;height:auto}.share-side{display:flex;flex-direction:column}.share-side h2{margin:0;font-size:19px}.share-side p{color:var(--muted);font-size:9px;line-height:1.45}.share-actions{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-top:auto}.share-actions .button{min-height:38px}.share-status{min-height:30px;margin-top:8px;color:var(--muted);font-size:8px;line-height:1.4}
|
|
28
|
+
.temporal{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:8px 0 0;padding:7px 10px;border:1px solid var(--line);border-radius:10px;background:var(--surface)}.temporal-main{display:flex;align-items:center;gap:8px}.temporal strong{font-size:10px}.temporal span{color:var(--muted);font-size:8px}.date-picker{position:relative}.date-picker summary{cursor:pointer;list-style:none}.date-picker summary::-webkit-details-marker{display:none}.date-popover{position:absolute;z-index:14;top:28px;left:0;display:grid;min-width:220px;gap:5px;padding:8px;border:1px solid var(--line);border-radius:10px;background:var(--paper);box-shadow:var(--shadow)}.date-option{display:flex;justify-content:space-between;gap:8px;min-height:30px;align-items:center;padding:0 8px;border:1px solid var(--line);border-radius:8px;color:var(--ink);background:var(--surface);cursor:pointer;font-size:9px}.date-option.active{border-color:var(--brand);color:var(--brand)}.resource-modes{display:flex;gap:3px;padding:2px;border:1px solid var(--line);border-radius:8px}.resource-modes button{min-height:25px;padding:0 7px;border:0;border-radius:6px;color:var(--muted);background:transparent;cursor:pointer;font-size:8px;font-weight:800}.resource-modes button.active{color:#fff;background:var(--brand)}.chart-canvas{height:276px}.inspector{display:grid;gap:7px}.inspector-head{display:flex;align-items:start;justify-content:space-between;gap:8px}.inspector-head strong{font-size:14px}.inspector-state{font-size:8px;font-weight:850;text-transform:uppercase}.inspector-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}.inspector-stat{padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.inspector-stat span{display:block;color:var(--muted);font-size:7px;text-transform:uppercase;letter-spacing:.08em}.inspector-stat strong{display:block;margin-top:3px;font-size:10px}.system-selected{color:var(--ink)!important}.mix-item[aria-pressed="true"]{color:var(--ink);font-weight:850}.mix-item[aria-pressed="true"] strong{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:3px}.footprint-strip{display:grid;grid-template-columns:1fr auto;align-items:center;gap:12px;margin-top:8px;padding:10px 12px}.local-strip{display:flex;align-items:center;gap:22px;min-width:0}.local-strip>div{min-width:0}.local-strip strong{display:block;font-size:13px}.local-strip span{color:var(--muted);font-size:8px}.global-action{display:flex;align-items:center;gap:8px}.monitor-line{display:flex;justify-content:space-between;gap:12px;margin-top:7px;padding:0 3px;color:var(--muted);font-size:8px}
|
|
29
|
+
.date-picker[data-single="true"] summary{cursor:default}.date-picker[data-single="true"] .date-popover{display:none}
|
|
30
|
+
.shell{width:min(1760px,calc(100vw - 16px))}.workspace{grid-template-columns:minmax(240px,.25fr) minmax(680px,1fr) minmax(340px,.34fr);gap:10px}.workspace>*{min-width:0}.system-panel{grid-column:1;grid-row:1;align-self:start;max-height:calc(100vh - 86px);overflow:auto;padding:12px;border:1px solid var(--line);border-radius:18px;background:color-mix(in srgb,var(--paper) 94%,transparent);box-shadow:var(--shadow);scrollbar-width:thin}.system-panel .rail-heading{align-items:center}.system-panel .mix-bar{height:6px}.system-panel .mix-list{gap:6px}.system-panel .mix-item{grid-template-columns:10px minmax(0,1fr);padding:9px 8px;border-color:var(--line);background:var(--surface)}.system-panel .mix-item>span{grid-column:2}.system-panel .mix-item[aria-pressed="true"]{border-color:var(--system-color);box-shadow:inset 3px 0 0 var(--system-color)}.system-panel .mix-item.is-focused{background:color-mix(in srgb,var(--system-color) 14%,var(--surface))}.system-actions{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:7px}.system-actions .button{padding:0 7px;font-size:8px}.system-help{margin:6px 0 0;color:var(--muted);font-size:7px;line-height:1.4}.workspace>.explorer{grid-column:2;grid-row:1}.workspace>.insight-rail{grid-column:3;grid-row:1}.explorer{overflow:hidden}.chart-wrap{min-height:270px}.legacy-timeline{position:absolute!important;left:-9999px!important;width:1px!important;height:1px!important;opacity:0;pointer-events:none}.system-timeline{display:grid;gap:7px;min-height:244px;padding:10px;border:1px solid var(--line);border-radius:12px;background:linear-gradient(180deg,color-mix(in srgb,var(--surface) 96%,transparent),var(--surface))}.timeline-axis,.timeline-row{display:grid;grid-template-columns:minmax(88px,112px) minmax(0,1fr);gap:8px;align-items:center}.timeline-axis-label{color:var(--muted);font-size:7px;font-weight:800;text-transform:uppercase}.timeline-ticks{position:relative;height:22px;border-bottom:1px solid var(--line)}.timeline-tick{position:absolute;bottom:4px;color:var(--muted);font-size:7px;transform:translateX(-50%);white-space:nowrap}.timeline-tick:first-child{transform:none}.timeline-tick:last-child{transform:translateX(-100%)}.timeline-row{min-height:50px}.timeline-system{display:grid;grid-template-columns:9px minmax(0,1fr);align-items:center;gap:7px;width:100%;padding:7px;border:1px solid transparent;border-radius:9px;color:var(--ink);background:transparent;cursor:pointer;text-align:left}.timeline-system:hover,.timeline-system:focus-visible{border-color:var(--line-strong);outline:none}.timeline-system[aria-pressed="true"]{border-color:var(--system-color);background:color-mix(in srgb,var(--system-color) 10%,transparent)}.timeline-system i{width:8px;height:8px;border-radius:3px;background:var(--system-color)}.timeline-system strong{overflow:hidden;font-size:9px;text-overflow:ellipsis;white-space:nowrap}.timeline-system span{grid-column:2;color:var(--muted);font-size:7px}.timeline-track{position:relative;height:42px;overflow:hidden;border:1px solid var(--line);border-radius:9px;background:repeating-linear-gradient(135deg,var(--surface-2),var(--surface-2) 5px,color-mix(in srgb,var(--surface-2) 70%,transparent) 5px,color-mix(in srgb,var(--surface-2) 70%,transparent) 10px)}.timeline-row.is-selected .timeline-track{border-color:var(--system-color)}.timeline-row.is-focused .timeline-track{box-shadow:0 0 0 1px var(--system-color),0 0 20px color-mix(in srgb,var(--system-color) 18%,transparent)}.timeline-block{position:absolute;top:4px;bottom:4px;min-width:3px;overflow:hidden;border:1px solid color-mix(in srgb,var(--system-color) 72%,white);border-radius:6px;color:#fff;background:color-mix(in srgb,var(--system-color) 76%,#071315);cursor:pointer;text-align:left;font-size:7px;font-weight:800;white-space:nowrap}.timeline-block:hover,.timeline-block:focus-visible{z-index:3;filter:brightness(1.14);outline:2px solid color-mix(in srgb,var(--system-color) 65%,white)}.timeline-block.is-longest{box-shadow:inset 0 -3px 0 var(--gold)}.timeline-block.is-pinned{outline:2px solid var(--ink);outline-offset:1px}.timeline-empty{display:grid;height:100%;place-items:center;color:var(--muted);font-size:8px}.focus-summary{margin-top:7px}.navigator{height:28px}.below-timeline{display:grid;grid-template-columns:1.25fr 1fr 1fr;gap:7px;margin-top:9px}.below-card{min-width:0;padding:10px;border:1px solid var(--line);border-radius:11px;background:var(--surface)}.below-card h2{margin:0;font-size:11px}.observation-metrics{grid-column:1/-1}.below-metrics{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:5px;margin-top:7px}.below-stat{min-width:0;padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--paper)}.below-stat span{display:block;color:var(--muted);font-size:7px;font-weight:760;text-transform:uppercase}.below-stat strong{display:block;margin-top:3px;overflow:hidden;font-size:10px;text-overflow:ellipsis;white-space:nowrap}.runtime-footprint-list{display:grid;gap:5px;margin-top:7px}.runtime-footprint-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:7px;align-items:center;padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--paper);cursor:pointer}.runtime-footprint-row:hover,.runtime-footprint-row:focus-visible{border-color:var(--system-color);outline:none}.runtime-footprint-row.is-selected{box-shadow:inset 3px 0 0 var(--system-color)}.runtime-footprint-row strong{overflow:hidden;font-size:8px;text-overflow:ellipsis;white-space:nowrap}.runtime-footprint-row span{color:var(--muted);font-size:7px}.resource-summary,.local-summary{display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:7px}.truth-note{margin:7px 0 0;color:var(--muted);font-size:7px;line-height:1.4}.insight-rail [data-view][hidden]{display:none!important}.inspector-app-list{display:grid;gap:5px}.inspector-app-row{padding:7px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}.inspector-app-row strong{display:block;font-size:9px}.inspector-app-row span{display:block;margin-top:2px;color:var(--muted);font-size:7px}.footprint-strip{display:none}.metric-rail{display:none}.center-app-list{display:grid;gap:6px;margin-top:8px}.center-app-row{display:grid;grid-template-columns:minmax(120px,1fr) repeat(3,minmax(74px,.55fr));gap:6px;align-items:center;width:100%;padding:9px;border:1px solid var(--line);border-radius:9px;color:var(--ink);background:var(--paper);cursor:pointer;text-align:left}.center-app-row:hover,.center-app-row:focus-visible,.center-app-row.is-selected{border-color:var(--system-color);outline:none}.center-app-row strong{font-size:9px}.center-app-row span{color:var(--muted);font-size:7px}.below-timeline>[data-center-view]{display:none}.insight-rail .rail-section[data-view="pulse"]{display:block!important}.insight-rail .rail-section[data-view="runtime"],.insight-rail .rail-section[data-view="resources"],.insight-rail .rail-section[data-view="apps"]{display:none!important}html[data-explorer-mode="pulse"] .focus-summary{display:none}html[data-explorer-mode="pulse"] .below-timeline>[data-center-view="pulse"],html[data-explorer-mode="runtime"] .below-timeline>[data-center-view="runtime"],html[data-explorer-mode="resources"] .below-timeline>[data-center-view="resources"],html[data-explorer-mode="apps"] .below-timeline>[data-center-view="apps"]{display:block;grid-column:1/-1}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .temporal,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-wrap,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-help,html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .chart-controls{display:none}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .focus-summary{display:grid;grid-template-columns:minmax(150px,.65fr) minmax(0,1.35fr);min-height:150px;align-content:start}html[data-explorer-mode]:not([data-explorer-mode="pulse"]) .below-timeline{grid-template-columns:1fr}.resource-modes{display:none}
|
|
31
|
+
.system-panel .app-inspector>.eyebrow,.system-panel .app-inspector>.inspector-grid:nth-of-type(2),.system-panel .app-inspector>.inspector{display:none}.system-panel .app-inspector>.inspector-grid:first-of-type .inspector-stat:nth-child(n+4){display:none}
|
|
32
|
+
.system-panel .app-inspector>.inspector-head+.inspector-grid{display:grid}.system-panel .app-inspector>.eyebrow+.inspector-grid{display:none}.system-panel .app-inspector>.inspector-head+.inspector-grid .inspector-stat:nth-child(n+4){display:none}
|
|
33
|
+
:root{--ui-xs:clamp(12px,.76rem + .08vw,14px);--ui-sm:clamp(13px,.82rem + .12vw,16px);--ui-md:clamp(14px,.88rem + .16vw,18px);--ui-lg:clamp(17px,1rem + .26vw,23px);--ui-title:clamp(23px,1.18rem + .55vw,34px);--ui-value:clamp(24px,1.35rem + .72vw,42px);--tap:clamp(42px,3vw,52px)}
|
|
34
|
+
body{font-size:var(--ui-md);line-height:1.45}.brand-copy strong,.inspector-head strong{font-size:var(--ui-lg)}.status,.privacy-chip,.button,.icon-button,.more summary,.scan-status,.metric-sub,.panel-copy,.chart-tooltip,.selected-evidence,.insight-copy,.early,.runtime-item,.mix-item,.feature-tool::after,.focus-copy span,.compact-stat span,.statement,.global-state p,.advanced>summary,.detail-list li,.share-side p,.share-status,.temporal span,.date-option,.resource-modes button,.inspector-state,.footer,.system-help,.timeline-axis-label,.timeline-tick,.timeline-system span,.timeline-block,.timeline-empty,.below-stat span,.runtime-footprint-row span,.truth-note,.inspector-app-row span,.center-app-row span{font-size:var(--ui-xs)}.eyebrow,.metric-label,.rail-stat span,.inspector-stat span{font-size:var(--ui-xs);letter-spacing:.1em}.button,.icon-button,.more summary{min-height:var(--tap)}.feature-tool{min-height:calc(var(--tap) + 22px)}.feature-tool>span:last-of-type,.system-actions .button{font-size:var(--ui-xs)}.panel-head h1,.panel-head h2,.compact h2{font-size:var(--ui-title)}.insight-rail h2{font-size:var(--ui-title)}.rail-heading strong,.detail-box h3,.below-card h2,.temporal strong{font-size:var(--ui-md)}.metric-value,.headline:first-child .metric-value{font-size:var(--ui-value)}.rail-stat strong,.inspector-stat strong,.below-stat strong,.compact-stat strong,.runtime-footprint-row strong,.inspector-app-row strong,.center-app-row strong,.timeline-system strong{font-size:var(--ui-sm)}.timeline-row{min-height:56px}.timeline-track{height:46px}.timeline-block{padding:0 6px}.resource-history-title{margin:12px 0 6px;font-size:var(--ui-md)}.resource-history-list{display:grid;gap:6px;margin-top:7px}.resource-history-row{display:grid;grid-template-columns:minmax(125px,1fr) repeat(4,minmax(78px,.65fr));gap:6px;align-items:center;padding:8px;border:1px solid var(--line);border-left:3px solid var(--system-color,var(--brand));border-radius:8px;background:var(--paper)}.resource-history-row strong{overflow:hidden;font-size:var(--ui-sm);text-overflow:ellipsis;white-space:nowrap}.resource-history-row span{color:var(--muted);font-size:var(--ui-xs)}html[data-explorer-mode="resources"] .below-timeline{display:grid}
|
|
35
|
+
@media(max-width:1320px){.privacy-chip{display:none}.workspace{grid-template-columns:minmax(0,1fr) 310px}.summary-row{grid-template-columns:1fr 1fr}.summary-row .global-card{grid-column:1/-1}.details-grid{grid-template-columns:1fr 1fr}}
|
|
36
|
+
@media(max-width:760px){.shell{width:calc(100% - 14px);padding-top:7px}.command{align-items:flex-start}.command-actions{flex-wrap:wrap;justify-content:flex-end}.metric-rail{grid-template-columns:1fr}.headline{border-right:0;border-bottom:1px solid var(--line)}.workspace,.summary-row{grid-template-columns:1fr}.insight-rail{max-height:none;min-height:0}.compact-grid{grid-template-columns:1fr}.compact-stat{padding:6px 0;border-right:0;border-bottom:1px solid var(--line)}.share-layout{grid-template-columns:1fr}.share-preview{max-height:55vh}.share-preview canvas{height:55vh;object-fit:contain}.footer{display:block}.footer span{display:block;margin-top:3px}.temporal{align-items:flex-start;flex-direction:column}.footprint-strip{grid-template-columns:1fr}.local-strip{align-items:flex-start;flex-wrap:wrap}.global-action{justify-content:space-between}.focus-summary{grid-template-columns:1fr}.focus-stats{grid-template-columns:1fr 1fr}}
|
|
37
|
+
@media(max-width:480px){.brand-copy strong{max-width:145px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.command-actions>.button.primary{order:3}.metric-value{font-size:19px}.chart-canvas{height:260px}.details-grid{grid-template-columns:1fr}.chart-controls{flex-wrap:wrap}.resource-modes{order:2}}
|
|
38
|
+
@media(max-width:1320px){.workspace{grid-template-columns:minmax(210px,.28fr) minmax(0,1fr)}.workspace>.system-panel{grid-column:1;grid-row:1}.workspace>.explorer{grid-column:2;grid-row:1}.workspace>.insight-rail{grid-column:1/-1;grid-row:2;max-height:none}.observation-tools{grid-template-columns:repeat(4,1fr)}.below-timeline{grid-template-columns:1fr 1fr}.observation-metrics{grid-column:1/-1}.below-metrics{grid-template-columns:repeat(3,1fr)}}
|
|
39
|
+
@media(max-width:760px){.workspace{grid-template-columns:1fr}.workspace>.system-panel,.workspace>.explorer,.workspace>.insight-rail{grid-column:1;grid-row:auto;max-height:none}.workspace>.explorer{order:-1}.below-timeline{grid-template-columns:1fr}.observation-metrics{grid-column:1}.below-metrics{grid-template-columns:1fr 1fr}.timeline-axis,.timeline-row{grid-template-columns:82px minmax(0,1fr)}}
|
|
40
|
+
@media(max-width:760px){.timeline-tick:not(:first-child):not(:last-child){display:none}}
|
|
41
|
+
@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}
|
|
42
|
+
</style></head><body><main class="shell">
|
|
43
|
+
<header class="surface command"><div class="brand">${brand}<div class="brand-copy"><strong>Forkit AI Footprint</strong><span class="status stopped" id="monitor-status"><i class="status-dot"></i><span id="monitor-status-text">${t('stopped')}</span></span></div></div><div class="command-actions"><span class="privacy-chip"><b>${t('localOnly')}</b> · ${t('nothingUploaded')}</span><div class="locale" aria-label="Language"><button id="locale-en" class="${locale === 'en' ? 'active' : ''}" type="button">EN</button><button id="locale-de" class="${locale === 'de' ? 'active' : ''}" type="button">DE</button></div><button class="button primary" id="share-button" type="button">${t('share')}</button>${rescan ? `<button class="button" id="monitor-button" type="button">${t('startMonitoring')}</button><details class="more"><summary>${t('more')}</summary><div class="more-menu"><button class="button" id="clear-button" type="button">${t('clearHistory')}</button><button class="button" id="scan-button" type="button">${t('scanAgain')}</button><span class="scan-status" id="scan-status"></span></div></details>` : ''}</div></header>
|
|
44
|
+
<section class="surface metric-rail" aria-label="${t('scorecard')}"><div class="headline"><span class="metric-label">${t('activityRatio')}</span><strong class="metric-value" id="metric-ratio">—</strong><span class="metric-sub" id="metric-active">0s</span></div><div class="headline"><span class="metric-label">${t('activeAiTools')}</span><strong class="metric-value" id="metric-systems">0</strong><span class="metric-sub" id="ratio-label">${t('earlyObservation')}</span></div><div class="headline"><span class="metric-label">${t('localAi')}</span><strong class="metric-value" id="metric-local">${snapshot.model_record_count} · ${snapshot.model_storage_decimal_display}</strong><span class="metric-sub" id="metric-local-running">${snapshot.confirmed_running_model_count} ${t('runningShort')}</span></div></section>
|
|
45
|
+
<section class="workspace"><article class="surface explorer"><div class="panel-head"><div><p class="eyebrow" id="explorer-eyebrow">${t('currentSession')}</p><h1 id="explorer-title">${t('activityExplorer')}</h1><p class="panel-copy" id="explorer-copy">${t('activityExplorerCopy')}</p></div><div class="chart-controls"><div class="resource-modes" aria-label="${t('resourcePulse')}"><button class="active" data-resource-mode="both" type="button">${t('both')}</button><button data-resource-mode="cpu" type="button">${t('cpu')}</button><button data-resource-mode="memory" type="button">${t('memory')}</button></div><button class="icon-button" id="zoom-out" type="button" title="${t('zoomOut')}" aria-label="${t('zoomOut')}">−</button><button class="icon-button" id="zoom-in" type="button" title="${t('zoomIn')}" aria-label="${t('zoomIn')}">+</button><button class="icon-button" id="reset-view" type="button">${t('resetView')}</button></div></div><div class="temporal"><div class="temporal-main"><details class="date-picker" id="date-picker"><summary><span>${t('dateHistory')}</span> <strong id="observation-date">—</strong></summary><div class="date-popover" id="date-options"></div></details><span id="observation-span"></span></div><span id="resource-history-state">${t('resourceCollecting')}</span></div><section class="focus-summary" id="focus-summary" aria-live="polite"><div class="focus-copy"><strong id="focus-title">${t('pulseDetailTitle')}</strong><span id="focus-copy">${t('pulseDetailCopy')}</span></div><div class="focus-stats" id="focus-stats"></div></section><div class="chart-wrap"><div class="system-timeline" id="system-timeline" aria-label="${t('mainChartDescription')}"><div class="timeline-empty">${t('earlyObservationCopy')}</div></div><canvas class="chart-canvas legacy-timeline" id="activity-explorer" tabindex="0" role="img" aria-label="${t('mainChartDescription')}"></canvas><canvas class="navigator" id="activity-navigator" aria-hidden="true"></canvas><div class="chart-tooltip" id="chart-tooltip" hidden></div></div><div class="chart-help"><div class="legend"><span><i class="active"></i>${t('working')}</span><span><i></i>${t('idleTimeLabel')}</span><span><i class="excluded"></i>${t('excluded')}</span></div><span>${t('timelineHelp')}</span></div><section class="below-timeline"><article class="below-card observation-metrics" data-center-view="pulse"><h2>${t('observationMetrics')}</h2><div class="below-metrics"><div class="below-stat"><span>${t('observed')}</span><strong id="below-observed">0s</strong></div><div class="below-stat"><span>${t('aiActive')}</span><strong id="below-active">0s</strong></div><div class="below-stat"><span>${t('activityRatio')}</span><strong id="below-ratio">—</strong></div><div class="below-stat"><span>${t('activityPeriods')}</span><strong id="below-periods">0</strong></div><div class="below-stat"><span>${t('longestActive')}</span><strong id="below-longest">0s</strong></div><div class="below-stat"><span>${t('systems')}</span><strong id="below-systems">0</strong></div></div></article><article class="below-card" data-center-view="runtime"><h2>${t('runtimeFootprint')}</h2><div class="runtime-footprint-list" id="runtime-footprint-list"></div></article><article class="below-card" data-center-view="resources"><h2>${t('liveResourceFootprint')}</h2><div class="resource-summary"><div class="below-stat"><span>${t('cpu')}</span><strong id="below-cpu">—</strong></div><div class="below-stat"><span>${t('memory')}</span><strong id="below-memory">—</strong></div><div class="below-stat"><span>${t('gpu')}</span><strong>${t('notMeasured')}</strong></div><div class="below-stat"><span>${t('resourcePulse')}</span><strong id="resource-history-label">${t('resourceCollecting')}</strong></div></div><h3 class="resource-history-title">${t('resourceHistory')}</h3><div class="resource-history-list" id="center-resource-history"></div><p class="truth-note" id="resource-history-note">${t('resourceCollecting')}</p></article><article class="below-card" data-center-view="apps"><h2>${t('appsDetailTitle')}</h2><div class="center-app-list" id="center-apps-list"></div></article><article class="below-card" data-center-view="pulse"><h2>${t('localAiFootprint')}</h2><div class="local-summary"><div class="below-stat"><span>${t('localRuntimes')}</span><strong id="below-runtimes">0</strong></div><div class="below-stat"><span>${t('modelRecordsShort')}</span><strong id="below-models">${snapshot.model_record_count}</strong></div><div class="below-stat"><span>${t('hostedModelsRunning')}</span><strong id="below-running">${snapshot.confirmed_running_model_count}</strong></div><div class="below-stat"><span>${t('recognizedModelSpace')}</span><strong id="below-space">${snapshot.model_storage_decimal_display}</strong></div></div><p class="statement" id="below-local-insight">${t('localAiNone')}</p></article></section></article>
|
|
46
|
+
<aside class="surface insight-rail"><div class="device-identity"><div><p class="eyebrow">${t('deviceIdentity')}</p><strong>${escapeHtml(device)}</strong></div><span class="observation-number" id="observation-identity">${t('observationIdentity', { number: '—' })}</span></div><nav class="observation-tools" aria-label="${t('observationTools')}"><button class="feature-tool" data-explorer-mode="pulse" data-tip="${t('inspectPulseHint')}" title="${t('inspectPulseHint')}" type="button" aria-pressed="true"><span class="feature-icon" aria-hidden="true">⌁</span><span>${t('pulseView')}</span></button><button class="feature-tool" data-explorer-mode="runtime" data-tip="${t('inspectRuntimeHint')}" title="${t('inspectRuntimeHint')}" type="button" aria-pressed="false"><span class="feature-icon" aria-hidden="true">◷</span><span>${t('runtimeView')}</span></button><button class="feature-tool" data-explorer-mode="resources" data-tip="${t('inspectResourcesHint')}" title="${t('inspectResourcesHint')}" type="button" aria-pressed="false"><span class="feature-icon" aria-hidden="true">◉</span><span>${t('resourcesView')}</span></button><button class="feature-tool" data-explorer-mode="apps" data-tip="${t('inspectAppsHint')}" title="${t('inspectAppsHint')}" type="button" aria-pressed="false"><span class="feature-icon" aria-hidden="true">▦</span><span>${t('appsView')}</span></button></nav><section class="rail-section" data-view="pulse"><div id="inspector-headline"><h2>${t('observationShows')}</h2><p class="insight-copy">${t('selectTimelineBlock')}</p></div><div class="selected-evidence" id="selected-evidence" aria-live="polite">${t('noSelection')}</div><div class="insight-list" id="insight-list"></div></section><section class="rail-section" data-view="runtime"><div class="rail-heading"><strong>${t('observationOverview')}</strong><span>${t('measuredCurrentOnly')}</span></div><div class="observation-grid"><div class="rail-stat"><span>${t('observed')}</span><strong id="rail-observed">0s</strong></div><div class="rail-stat"><span>${t('aiActive')}</span><strong id="rail-active">0s</strong></div><div class="rail-stat"><span>${t('activityRatio')}</span><strong id="rail-ratio">—</strong></div><div class="rail-stat"><span>${t('longestActive')}</span><strong id="rail-longest">0s</strong></div></div></section><section class="rail-section" data-view="resources"><div class="rail-heading"><strong>${t('resourcesNow')}</strong><span>${t('resourceLiveOnly')}</span></div><div class="resource-grid"><div class="rail-stat"><span>${t('cpu')}</span><strong id="rail-cpu">—</strong></div><div class="rail-stat"><span>${t('memory')}</span><strong id="rail-memory">—</strong></div><div class="rail-stat"><span>${t('gpu')}</span><strong>${t('notMeasured')}</strong></div><div class="rail-stat"><span>${t('recognizedModelSpace')}</span><strong id="rail-space">${snapshot.model_storage_decimal_display}</strong></div></div></section><section class="rail-section" data-view="runtime"><div class="rail-heading"><strong>${t('localRuntimes')}</strong><span>${t('localOnly')}</span></div><div class="rail-list" id="rail-runtimes"></div></section><section class="rail-section" data-view="apps"><div class="rail-heading"><strong>${t('appsView')}</strong><span>${t('measuredCurrentOnly')}</span></div><div class="inspector-app-list" id="inspector-apps-list"></div></section><section class="system-mix rail-section"><div class="rail-heading"><strong>${t('aiAppsOnDevice')}</strong></div><p class="insight-copy">${t('focusSystemHelp')}</p><div class="mix-bar" id="mix-bar"></div><div class="mix-list" id="mix-list"></div><div class="system-actions"><button class="button all-apps" id="all-apps" type="button">${t('allApps')}</button><button class="button" id="focus-system" type="button" disabled>${t('focusSystem')}</button></div><div class="app-inspector" id="app-inspector" hidden></div></section></aside></section>
|
|
47
|
+
<section class="surface footprint-strip"><div class="local-strip"><div><p class="eyebrow">${t('localAi')}</p><strong><span id="models-found">${snapshot.model_record_count}</span> ${t('modelRecordsShort').toLowerCase()} · <span id="device-storage">${snapshot.model_storage_decimal_display}</span> · <span id="models-running">${snapshot.confirmed_running_model_count}</span> ${t('runningShort')}</strong><span id="hosted-insight">${t('localAiNone')}</span></div></div><div class="global-action"><div><strong>${t('globalPosition')} · ${t('notAvailableYet')}</strong><span class="scan-status" id="compare-progress"></span><span class="scan-status" id="global-result"></span></div>${rescan ? `<button class="button" id="review-payload" type="button" disabled>${t('openGlobal')}</button>` : ''}</div></section>
|
|
48
|
+
<div class="monitor-line"><span>${t('monitorOverhead')} · <span id="overhead">${t('warmingUp')}</span> · <span id="overhead-note"></span></span><span>${t('validObservation')} <b id="metric-observed">0s</b> · ${t('longestActive')} <b id="metric-longest">0s</b></span></div>
|
|
49
|
+
<details class="surface advanced"><summary>${t('technical')}</summary><div class="details-grid"><article class="detail-box"><h3>${t('engines')}</h3><ul class="detail-list" id="runtime-list"></ul></article><article class="detail-box"><h3>${t('modelsDevice')}</h3><ul class="detail-list" id="model-list"></ul></article><article class="detail-box"><h3>${t('appsTools')}</h3><ul class="detail-list" id="app-list"></ul></article><article class="detail-box"><h3>${t('measurementBoundary')}</h3><ul class="detail-list"><li><strong>${t('activityMeasurement')}</strong>${t('workingBoundary')}</li><li><strong>${t('loadedModel')}</strong>${t('loadedBoundary')}</li><li><strong>${t('storage')}</strong>${t('storageBoundary')}</li><li><strong>${t('resourcePulse')}</strong>${t('resourceLiveOnly')}</li><li><strong>${t('systems')}</strong><span id="raw-system-count">0</span></li></ul></article></div></details>
|
|
50
|
+
<footer class="footer"><span>${t('localDevice')} · ${t('nothingUploaded')}</span><span>${t('noPrivateFooter')} · v${snapshot.product_version}</span></footer></main>
|
|
51
|
+
<dialog id="share-dialog"><div class="share-layout"><div class="share-preview"><canvas id="share-canvas" width="1080" height="1080"></canvas></div><div class="share-side"><p class="eyebrow">${t('shareTitle')}</p><h2 id="share-heading">${t('shareHeading')}</h2><p>${t('shareFormat')}</p><div class="share-actions"><button class="button primary" id="native-share" type="button">${t('share')}</button><button class="button" id="download-share" type="button">${t('savePng')}</button><button class="button" id="copy-image" type="button">${t('copyImage')}</button><button class="button" id="copy-share" type="button">${t('copyCaption')}</button><button class="button" id="close-share" type="button">${t('close')}</button></div><p class="share-status" id="share-status">${t('sharePrivacy')}</p></div></div></dialog>
|
|
52
|
+
<script>
|
|
53
|
+
const copy=${safeScriptJson(localization_1.UI_COPY)},locale=${safeScriptJson(locale)},config=${safeScriptJson(config)},globalUrl=${safeScriptJson(globalUrl)},shareLogo=${safeScriptJson(shareLogo)};
|
|
54
|
+
let footprint=${safeScriptJson(view ?? snapshot)},monitor={lifecycle:'stopped',observed_seconds:0,active_seconds:0,activity_ratio:null,products:[],timeline:[],resource_history:[],insights:[],presence:{state:'active',observation_eligible:true},overhead:{current_cpu_percent:null,current_memory_bytes:0,history_bytes:0},activity_view:{segments:[],contributions:[],insights:[],systems:[],extent:null,active_block_count:0,longest_active_seconds:0,longest_active_range:null,idle_seconds:0,excluded_seconds:0,simultaneous_systems_max:0,active_tool_count:0,observation_ids:[],continuity_ids:[],available_date_keys:[],current_resources:{cpu_percent:null,memory_bytes:null,process_count:0},resource_history:{buckets:[],systems:[]},resource_history_state:'not-retained'},last_observation:null};
|
|
55
|
+
const $=id=>document.getElementById(id),format=new Intl.NumberFormat(locale),clock=new Intl.DateTimeFormat(locale,{day:'2-digit',month:'short',hour:'2-digit',minute:'2-digit',second:'2-digit'}),fullMoment=new Intl.DateTimeFormat(locale,{dateStyle:'medium',timeStyle:'medium'}),dateLabel=new Intl.DateTimeFormat(locale,{weekday:'short',day:'numeric',month:'short',year:'numeric'}),shareDateLabel=new Intl.DateTimeFormat(locale,{day:'numeric',month:'short',year:'numeric'}),systemPalette=['#00888d','#d98a25','#7758c7','#2e8f68','#c85578','#487bc4','#9b6b37','#637b2f'],colorsKey='forkit-footprints-colors-v1',lastSummaryKey='forkit-footprints-last-summary-v1';
|
|
56
|
+
function text(key,values={}){let value=copy[locale][key]||key;for(const [name,replacement] of Object.entries(values))value=value.split('{'+name+'}').join(String(replacement));return value}
|
|
57
|
+
function loadJson(key,fallback){try{return JSON.parse(localStorage.getItem(key)||'null')||fallback}catch{return fallback}}
|
|
58
|
+
let savedColors=loadJson(colorsKey,{});function colorHash(value){let hash=0;for(let i=0;i<value.length;i++)hash=((hash<<5)-hash+value.charCodeAt(i))|0;return Math.abs(hash)}function systemColor(value){const signature=typeof value==='string'?value:value.signature;if(!savedColors[signature]){savedColors[signature]=systemPalette[colorHash(signature)%systemPalette.length];try{localStorage.setItem(colorsKey,JSON.stringify(savedColors))}catch{}}return savedColors[signature]}
|
|
59
|
+
function seconds(value){const total=Math.max(0,Math.round(Number(value)||0)),s=total%60,m=Math.floor(total/60)%60,h=Math.floor(total/3600);if(h)return h+'h '+m+'m '+s+'s';if(m)return m+'m '+s+'s';return s+'s'}function pct(value){return value===null||value===undefined?'—':Math.round(Number(value)*100)+'%'}function bytes(value,binary=false){let n=Math.max(0,Number(value)||0),units=binary?['B','KiB','MiB','GiB','TiB']:['B','KB','MB','GB','TB'],base=binary?1024:1000,index=0;while(index<units.length-1&&n>=base){n/=base;index++}return n.toFixed(n<10&&index>1?2:n<100?1:0)+' '+units[index]}function list(values){return new Intl.ListFormat(locale,{style:'short',type:'conjunction'}).format(values)}
|
|
60
|
+
function productMap(){return new Map((monitor.products||[]).map(product=>[product.signature,product]))}function listedProducts(){const products=monitor.products||[],embedded=products.some(product=>product.signature==='chatgpt-codex');return products.filter(product=>!(embedded&&product.signature==='chatgpt'))}function userFacingProducts(){return listedProducts().filter(product=>product.kind!=='local-model-runtime')}function activeToolNames(){return [...new Set(userFacingProducts().filter(product=>(product.active_seconds||0)>0||product.state==='working-now').map(product=>product.name))]}function dominantProduct(){return [...userFacingProducts()].sort((a,b)=>(b.active_seconds||0)-(a.active_seconds||0))[0]||null}function ratioLabel(){if(monitor.observed_seconds<60)return text('earlyObservation');if((monitor.activity_ratio||0)>=.7)return text('mostlyActive');if((monitor.activity_ratio||0)<=.3)return text('mostlyIdle');return text('mixedActivity')}
|
|
61
|
+
let resourceMode='both',resourceSamples=[],selectedDateKey=null,explorerMode='pulse',selectedSystemSignature=null,focusedSystemSignature=null;function localDateKey(value){const date=new Date(value),year=date.getFullYear(),month=String(date.getMonth()+1).padStart(2,'0'),day=String(date.getDate()).padStart(2,'0');return year+'-'+month+'-'+day}function observationDateRange(){const extent=monitor.activity_view?.extent;if(!extent)return '—';const start=new Date(extent.start_ms),end=new Date(Math.max(extent.start_ms,extent.end_ms-1));return localDateKey(start)===localDateKey(end)?dateLabel.format(start):dateLabel.format(start)+' – '+dateLabel.format(end)}function shareObservationDate(){const extent=monitor.activity_view?.extent;if(!extent)return '';const start=new Date(extent.start_ms),end=new Date(Math.max(extent.start_ms,extent.end_ms-1)),first=shareDateLabel.format(start).toLocaleUpperCase(locale);return localDateKey(start)===localDateKey(end)?first:(first+' – '+shareDateLabel.format(end).toLocaleUpperCase(locale))}function aggregateResources(products){const cpu=products.map(product=>product.cpu_percent).filter(Number.isFinite),memory=products.map(product=>product.memory_bytes).filter(Number.isFinite);return {cpu:cpu.length?cpu.reduce((sum,value)=>sum+Math.max(0,value),0):null,memory:memory.length?memory.reduce((sum,value)=>sum+Math.max(0,value),0):null,processes:products.reduce((sum,product)=>sum+Math.max(0,Number(product.process_count)||0),0)}}function resourceStatusText(state){return state==='retained-local-buckets'?text('resourceRetainedLocal'):state==='collecting'?text('resourceCollecting'):text('resourceNotRetained')}function averageBuckets(buckets,key){let total=0,weight=0;for(const bucket of buckets){const value=bucket[key];if(!Number.isFinite(value))continue;const seconds=Math.max(0,Number(bucket.observed_seconds)||0);if(!seconds)continue;total+=value*seconds;weight+=seconds}return weight?total/weight:null}function summarizeResourceBuckets(buckets){const grouped=new Map();for(const bucket of buckets||[]){const signature=bucket.system_signature;if(!signature)continue;grouped.set(signature,[...(grouped.get(signature)||[]),bucket])}return [...grouped.entries()].map(([signature,items])=>({signature,name:items.at(-1)?.system_name||signature,kind:items.at(-1)?.kind||'unknown',observed_seconds:items.reduce((sum,item)=>sum+(Number(item.observed_seconds)||0),0),active_seconds:items.reduce((sum,item)=>sum+(Number(item.active_seconds)||0),0),avg_cpu_percent:averageBuckets(items,'avg_cpu_percent'),peak_cpu_percent:items.reduce((max,item)=>Number.isFinite(item.peak_cpu_percent)?Math.max(max,Number(item.peak_cpu_percent)):max,0)||null,avg_memory_bytes:averageBuckets(items,'avg_memory_bytes'),peak_memory_bytes:items.reduce((max,item)=>Number.isFinite(item.peak_memory_bytes)?Math.max(max,Number(item.peak_memory_bytes)):max,0)||null,peak_process_count:items.reduce((max,item)=>Math.max(max,Number(item.peak_process_count)||0),0),sample_count:items.reduce((sum,item)=>sum+(Number(item.sample_count)||0),0)})).sort((a,b)=>b.active_seconds-a.active_seconds||b.observed_seconds-a.observed_seconds||a.name.localeCompare(b.name))}function filterResourceHistory(view,{start=null,end=null,signature=null}={}){const buckets=(view?.resource_history?.buckets||[]).filter(bucket=>(!signature||bucket.system_signature===signature)&&(!Number.isFinite(start)||bucket.end_ms>start)&&(!Number.isFinite(end)||bucket.start_ms<end)).map(bucket=>({...bucket,start_ms:Number.isFinite(start)?Math.max(bucket.start_ms,start):bucket.start_ms,end_ms:Number.isFinite(end)?Math.min(bucket.end_ms,end):bucket.end_ms}));return {buckets,systems:summarizeResourceBuckets(buckets)}}function appendResourceSample(){resourceSamples=(monitor.activity_view?.resource_history?.buckets||[]).map(bucket=>({at:bucket.end_ms,cpu:bucket.avg_cpu_percent,memory:bucket.avg_memory_bytes,processes:bucket.peak_process_count,systems:{[bucket.system_signature]:{cpu:bucket.avg_cpu_percent,memory:bucket.avg_memory_bytes,processes:bucket.peak_process_count}}}));if(monitor.lifecycle!=='monitoring')return;const extent=monitor.activity_view?.extent,at=extent?.end_ms;if(!Number.isFinite(at))return;const all=aggregateResources(monitor.products||[]),systems={};for(const product of monitor.products||[])systems[product.signature]={cpu:Number.isFinite(product.cpu_percent)?product.cpu_percent:null,memory:Number.isFinite(product.memory_bytes)?product.memory_bytes:null,processes:product.process_count||0};if(all.cpu===null&&all.memory===null)return;const sample={at,cpu:all.cpu,memory:all.memory,processes:all.processes,systems};const previous=resourceSamples.at(-1);if(previous&&previous.at===sample.at)resourceSamples[resourceSamples.length-1]=sample;else resourceSamples.push(sample);resourceSamples=resourceSamples.slice(-Math.max(60,monitor.history_limit||900))}
|
|
62
|
+
function add(listNode,title,note){const li=document.createElement('li'),strong=document.createElement('strong');strong.textContent=title;li.append(strong,document.createTextNode(note));listNode.append(li)}
|
|
63
|
+
class ActivityExplorer{constructor(canvas,navigator,tooltip,output){this.canvas=canvas;this.navigator=navigator;this.tooltip=tooltip;this.output=output;this.view=monitor.activity_view;this.range=null;this.hover=null;this.selected=null;this.focusSignature=null;this.drag=null;this.frame=0;this.resizeObserver=new ResizeObserver(()=>this.schedule());this.resizeObserver.observe(canvas);this.resizeObserver.observe(navigator);canvas.addEventListener('pointermove',event=>this.pointerMove(event));canvas.addEventListener('pointerleave',()=>{this.hover=null;this.tooltip.hidden=true;this.schedule()});canvas.addEventListener('pointerdown',event=>{this.drag={x:event.clientX,range:this.range&&[...this.range]};canvas.setPointerCapture(event.pointerId)});canvas.addEventListener('pointerup',event=>{if(this.drag&&Math.abs(event.clientX-this.drag.x)<4)this.selectAt(event);this.drag=null});canvas.addEventListener('wheel',event=>{event.preventDefault();this.zoom(event.deltaY<0?.7:1.35,this.eventTime(event))},{passive:false});canvas.addEventListener('dblclick',()=>this.reset());canvas.addEventListener('keydown',event=>this.key(event));navigator.addEventListener('pointerdown',event=>this.navigate(event))}setData(view){const oldExtent=this.view.extent;const wasAtEnd=this.range&&oldExtent&&Math.abs(this.range[1]-oldExtent.end_ms)<2000;this.view=view||monitor.activity_view;if(!this.range&&this.view.extent)this.range=[this.view.extent.start_ms,this.view.extent.end_ms];else if(wasAtEnd&&this.range&&oldExtent&&this.view.extent){const width=this.range[1]-this.range[0];this.range=[Math.max(this.view.extent.start_ms,this.view.extent.end_ms-width),this.view.extent.end_ms]}if(this.selected&&!this.view.segments.some(segment=>segment.id===this.selected))this.selected=null;this.schedule()}schedule(){if(this.frame)return;this.frame=requestAnimationFrame(()=>{this.frame=0;this.draw()})}size(canvas){const rect=canvas.getBoundingClientRect(),dpr=Math.max(1,window.devicePixelRatio||1),width=Math.max(1,Math.round(rect.width*dpr)),height=Math.max(1,Math.round(rect.height*dpr));if(canvas.width!==width||canvas.height!==height){canvas.width=width;canvas.height=height}const context=canvas.getContext('2d');context.setTransform(dpr,0,0,dpr,0,0);return {context,width:rect.width,height:rect.height}}visibleRange(){return this.range||this.view.extent&&[this.view.extent.start_ms,this.view.extent.end_ms]||[0,1]}eventTime(event){const rect=this.canvas.getBoundingClientRect(),range=this.visibleRange(),left=64,right=rect.width-12,ratio=Math.max(0,Math.min(1,(event.clientX-rect.left-left)/(right-left)));return range[0]+ratio*(range[1]-range[0])}segmentAt(time){return this.view.segments.find(segment=>time>=segment.start_ms&&time<=Math.max(segment.end_ms,segment.start_ms+monitor.sample_interval_ms||1000))||null}zoom(factor,center){if(!this.view.extent)return;const range=this.visibleRange(),full=this.view.extent.end_ms-this.view.extent.start_ms,min=Math.min(full,30000),width=Math.max(min,Math.min(full,(range[1]-range[0])*factor)),ratio=(center-range[0])/Math.max(1,range[1]-range[0]);let start=center-width*ratio,end=start+width;if(start<this.view.extent.start_ms){start=this.view.extent.start_ms;end=start+width}if(end>this.view.extent.end_ms){end=this.view.extent.end_ms;start=end-width}this.range=[start,end];this.schedule()}pan(deltaRatio){if(!this.view.extent||!this.range)return;const width=this.range[1]-this.range[0],delta=deltaRatio*width;let start=this.range[0]+delta,end=this.range[1]+delta;if(start<this.view.extent.start_ms){start=this.view.extent.start_ms;end=start+width}if(end>this.view.extent.end_ms){end=this.view.extent.end_ms;start=end-width}this.range=[start,end];this.schedule()}reset(){this.range=this.view.extent?[this.view.extent.start_ms,this.view.extent.end_ms]:null;this.focusSignature=null;this.selected=null;this.output.textContent=text('noSelection');this.schedule()}focusSystem(signature){this.focusSignature=signature;this.selected=null;this.schedule()}focusRange(start,end){if(!this.view.extent)return;const padding=Math.max(5000,(end-start)*.15);this.range=[Math.max(this.view.extent.start_ms,start-padding),Math.min(this.view.extent.end_ms,end+padding)];this.selected=null;this.output.innerHTML='<strong>'+clock.format(start)+'–'+clock.format(end)+'</strong> · '+seconds((end-start)/1000)+' · '+text('longestMarker');this.schedule()}focusSegment(id){const segment=this.view.segments.find(item=>item.id===id);if(!segment)return;const width=Math.max(30000,(segment.end_ms-segment.start_ms)*2),center=(segment.start_ms+segment.end_ms)/2;this.range=[center-width/2,center+width/2];if(this.view.extent){this.range[0]=Math.max(this.view.extent.start_ms,this.range[0]);this.range[1]=Math.min(this.view.extent.end_ms,this.range[1])}this.selected=id;this.describe(segment);this.schedule()}pointerMove(event){if(this.drag&&this.drag.range){const rect=this.canvas.getBoundingClientRect(),delta=(this.drag.x-event.clientX)/Math.max(1,rect.width-76);this.range=[...this.drag.range];this.pan(delta);return}const segment=this.segmentAt(this.eventTime(event));this.hover=segment&&segment.id;this.showTooltip(event,segment);this.schedule()}selectAt(event){const segment=this.segmentAt(this.eventTime(event));this.selected=segment&&segment.id;this.describe(segment);this.schedule()}describe(segment){if(!segment){this.output.textContent=text('noSelection');return}const systems=segment.system_signatures.map(signature=>productMap().get(signature)?.name||signature);this.output.innerHTML='<strong>'+clock.format(segment.start_ms)+'–'+clock.format(segment.end_ms)+'</strong> · '+seconds(segment.duration_seconds)+' · '+this.stateLabel(segment)+(systems.length?' · '+list(systems):'')}stateLabel(segment){return segment.state==='active'?text('working'):segment.state==='idle'?text('idleTimeLabel'):text('observationExcluded')}showTooltip(event,segment){if(!segment){this.tooltip.hidden=true;return}const rect=this.canvas.parentElement.getBoundingClientRect(),systems=segment.system_signatures.map(signature=>productMap().get(signature)?.name||signature);this.tooltip.textContent=clock.format(segment.start_ms)+'–'+clock.format(segment.end_ms)+' · '+seconds(segment.duration_seconds)+' · '+this.stateLabel(segment)+(systems.length?' · '+list(systems):'');this.tooltip.hidden=false;this.tooltip.style.left=Math.min(event.clientX-rect.left+10,rect.width-this.tooltip.offsetWidth-6)+'px';this.tooltip.style.top=Math.max(4,event.clientY-rect.top-this.tooltip.offsetHeight-8)+'px'}key(event){const visible=this.view.segments.filter(segment=>this.range&&segment.end_ms>=this.range[0]&&segment.start_ms<=this.range[1]);if(!visible.length)return;let index=Math.max(0,visible.findIndex(segment=>segment.id===this.selected));if(event.key==='ArrowRight')index=Math.min(visible.length-1,index+1);else if(event.key==='ArrowLeft')index=Math.max(0,index-1);else if(event.key==='Enter'||event.key===' '){const segment=visible[index];if(segment){event.preventDefault();this.selected=segment.id;this.describe(segment);this.schedule()}return}else return;event.preventDefault();const segment=visible[index];if(segment){this.selected=segment.id;this.describe(segment);this.schedule()}}navigate(event){if(!this.view.extent||!this.range)return;const rect=this.navigator.getBoundingClientRect(),ratio=Math.max(0,Math.min(1,(event.clientX-rect.left)/rect.width)),width=this.range[1]-this.range[0],center=this.view.extent.start_ms+ratio*(this.view.extent.end_ms-this.view.extent.start_ms);this.range=[center-width/2,center+width/2];this.pan(0)}paintSegment(context,segment,x,width,y,height){const signatures=segment.system_signatures;if(segment.state==='excluded'){context.fillStyle=getComputedStyle(document.documentElement).getPropertyValue('--surface-2');context.fillRect(x,y,width,height);context.strokeStyle=getComputedStyle(document.documentElement).getPropertyValue('--excluded');for(let offset=-height;offset<width+height;offset+=7){context.beginPath();context.moveTo(x+offset,y+height);context.lineTo(x+offset+height,y);context.stroke()}return}if(segment.state==='idle'){context.fillStyle=getComputedStyle(document.documentElement).getPropertyValue('--idle');context.fillRect(x,y,width,height);return}const parts=signatures.length||1,partHeight=height/parts;for(let index=0;index<parts;index++){context.fillStyle=signatures[index]?systemColor(signatures[index]):getComputedStyle(document.documentElement).getPropertyValue('--active');context.fillRect(x,y+index*partHeight,width,partHeight)}if(this.focusSignature&&!signatures.includes(this.focusSignature)){context.fillStyle='rgba(20,20,20,.58)';context.fillRect(x,y,width,height)}}draw(){const main=this.size(this.canvas),nav=this.size(this.navigator),context=main.context,range=this.visibleRange(),left=64,right=main.width-12,plotWidth=Math.max(1,right-left),segments=this.view.segments.filter(segment=>segment.end_ms>=range[0]&&segment.start_ms<=range[1]),style=getComputedStyle(document.documentElement);context.clearRect(0,0,main.width,main.height);context.font='700 9px Inter, sans-serif';context.fillStyle=style.getPropertyValue('--muted');context.fillText(text('activityDensity'),8,40);context.fillText(text('overallLane'),8,103);context.strokeStyle=style.getPropertyValue('--line');context.beginPath();context.moveTo(left,52);context.lineTo(right,52);context.moveTo(left,116);context.lineTo(right,116);context.stroke();const xFor=time=>left+(time-range[0])/Math.max(1,range[1]-range[0])*plotWidth;for(const segment of segments){const x=xFor(Math.max(range[0],segment.start_ms)),end=xFor(Math.min(range[1],Math.max(segment.end_ms,segment.start_ms+(monitor.sample_interval_ms||1000)))),width=Math.max(2,end-x);if(segment.state==='active'){context.fillStyle=segment.system_signatures[0]?systemColor(segment.system_signatures[0]):style.getPropertyValue('--active');const density=Math.max(1,segment.system_signatures.length),height=Math.min(29,density*8);context.fillRect(x,48-height,width,height)}this.paintSegment(context,segment,x,width,82,34);if(segment.is_longest_active){context.strokeStyle=style.getPropertyValue('--gold');context.lineWidth=2;context.strokeRect(x+1,80,width-2,38)}if(segment.id===this.selected){context.strokeStyle=style.getPropertyValue('--ink');context.lineWidth=2;context.strokeRect(x,78,width,42)}}if(this.hover){const segment=this.view.segments.find(item=>item.id===this.hover);if(segment){const x=xFor(Math.max(range[0],Math.min(range[1],(segment.start_ms+segment.end_ms)/2)));context.strokeStyle=style.getPropertyValue('--ink');context.setLineDash([3,3]);context.beginPath();context.moveTo(x,16);context.lineTo(x,154);context.stroke();context.setLineDash([])}}context.fillStyle=style.getPropertyValue('--muted');context.font='650 8px Inter, sans-serif';context.fillText(clock.format(range[0]),left,178);const endLabel=clock.format(range[1]);context.fillText(endLabel,right-context.measureText(endLabel).width,178);context.fillText(seconds((range[1]-range[0])/1000),left,195);nav.context.clearRect(0,0,nav.width,nav.height);if(this.view.extent){const full=this.view.extent.end_ms-this.view.extent.start_ms||1,xNav=time=>(time-this.view.extent.start_ms)/full*nav.width;for(const segment of this.view.segments){const x=xNav(segment.start_ms),width=Math.max(1,xNav(Math.max(segment.end_ms,segment.start_ms+(monitor.sample_interval_ms||1000)))-x);if(segment.state==='active')nav.context.fillStyle=segment.system_signatures[0]?systemColor(segment.system_signatures[0]):style.getPropertyValue('--active');else if(segment.state==='idle')nav.context.fillStyle=style.getPropertyValue('--idle');else nav.context.fillStyle=style.getPropertyValue('--excluded');nav.context.fillRect(x,5,width,nav.height-10)}nav.context.fillStyle='rgba(20,20,20,.22)';nav.context.fillRect(xNav(this.range[0]),1,Math.max(3,xNav(this.range[1])-xNav(this.range[0])),nav.height-2);nav.context.strokeStyle=style.getPropertyValue('--ink');nav.context.strokeRect(xNav(this.range[0]),1,Math.max(3,xNav(this.range[1])-xNav(this.range[0])),nav.height-2)}}}
|
|
64
|
+
function activeBlockStats(segments){const blocks=[];for(let index=0;index<segments.length;index++){const segment=segments[index];if(segment.state!=='active')continue;const continuity=segment.continuity_id??segment.observation_id??null,previous=blocks.at(-1),continues=previous&&previous.last_index===index-1&&previous.continuity_id===continuity&&segment.start_ms-previous.end_ms<=Math.max(1500,(monitor.sample_interval_ms||1000)*3);if(continues){previous.end_ms=Math.max(previous.end_ms,segment.end_ms);previous.indexes.push(index);previous.last_index=index}else blocks.push({start_ms:segment.start_ms,end_ms:segment.end_ms,indexes:[index],last_index:index,continuity_id:continuity})}const longest=blocks.reduce((best,block)=>!best||block.end_ms-block.start_ms>best.end_ms-best.start_ms?block:best,null);return {count:blocks.length,longest_seconds:longest?(longest.end_ms-longest.start_ms)/1000:0,longest_range:longest?{start_ms:longest.start_ms,end_ms:longest.end_ms}:null,longest_indexes:new Set(longest?.indexes||[])}}function scopedSystemSegments(segments,signature){return segments.map(segment=>segment.state==='active'?{...segment,state:segment.system_signatures.includes(signature)?'active':'idle',system_signatures:segment.system_signatures.includes(signature)?[signature]:[]}:segment)}function viewForDate(view,key){if(!key||!view?.segments?.length)return view;const [year,month,day]=key.split('-').map(Number),start=new Date(year,month-1,day).getTime(),end=new Date(year,month-1,day+1).getTime(),clipped=view.segments.filter(segment=>segment.end_ms>start&&segment.start_ms<end).map(segment=>{const start_ms=Math.max(start,segment.start_ms),end_ms=Math.min(end,segment.end_ms);return {...segment,start_ms,end_ms,duration_seconds:Math.max(0,end_ms-start_ms)/1000,is_longest_active:false}}),resource_history=filterResourceHistory(view,{start,end});if(!clipped.length)return {...view,segments:[],contributions:[],systems:[],extent:null,resource_history,active_block_count:0,longest_active_seconds:0,longest_active_range:null};const blockStats=activeBlockStats(clipped),segments=clipped.map((segment,index)=>({...segment,is_longest_active:blockStats.longest_indexes.has(index)})),secondsBySystem=new Map();for(const segment of segments)if(segment.state==='active')for(const signature of segment.system_signatures)secondsBySystem.set(signature,(secondsBySystem.get(signature)||0)+segment.duration_seconds);const total=[...secondsBySystem.values()].reduce((sum,value)=>sum+value,0),contributions=(view.contributions||[]).filter(item=>secondsBySystem.has(item.signature)).map(item=>({...item,active_seconds:secondsBySystem.get(item.signature),share:total?secondsBySystem.get(item.signature)/total:0})).sort((a,b)=>b.active_seconds-a.active_seconds),systems=(view.systems||[]).filter(item=>secondsBySystem.has(item.signature)||resource_history.systems.some(resource=>resource.signature===item.signature)).map(item=>{const scoped=scopedSystemSegments(segments,item.signature),periods=scoped.filter(segment=>segment.state==='active'),stats=activeBlockStats(scoped),resource=resource_history.systems.find(next=>next.signature===item.signature);return {...item,active_seconds:secondsBySystem.get(item.signature)||0,share:total?((secondsBySystem.get(item.signature)||0)/total):0,period_count:stats.count,longest_active_seconds:stats.longest_seconds,first_observed_ms:periods[0]?.start_ms||null,last_observed_ms:periods.at(-1)?.end_ms||null,resource_observed_seconds:resource?.observed_seconds||0,resource_active_seconds:resource?.active_seconds||0,avg_cpu_percent:resource?.avg_cpu_percent??null,peak_cpu_percent:resource?.peak_cpu_percent??null,avg_memory_bytes:resource?.avg_memory_bytes??null,peak_memory_bytes:resource?.peak_memory_bytes??null,peak_process_count:resource?.peak_process_count||0,resource_sample_count:resource?.sample_count||0}});return {...view,segments,contributions,systems,resource_history,extent:{start_ms:segments[0].start_ms,end_ms:segments.at(-1).end_ms},active_block_count:blockStats.count,longest_active_seconds:blockStats.longest_seconds,longest_active_range:blockStats.longest_range,observation_ids:[...new Set(segments.flatMap(segment=>segment.observation_id===null?[]:[segment.observation_id]))],continuity_ids:[...new Set(segments.flatMap(segment=>segment.continuity_id===null?[]:[segment.continuity_id]))]}}function viewForSystem(view,signature){if(!signature||!view?.segments?.length)return view;const selected=(view.systems||[]).find(system=>system.signature===signature);if(!selected)return view;const resource_history=filterResourceHistory(view,{signature}),resource=resource_history.systems[0],scoped=scopedSystemSegments(view.segments,signature),stats=activeBlockStats(scoped),segments=scoped.map((segment,index)=>({...segment,is_longest_active:stats.longest_indexes.has(index)})),active=segments.filter(segment=>segment.state==='active'),activeSeconds=active.reduce((sum,segment)=>sum+segment.duration_seconds,0),system={...selected,active_seconds:activeSeconds,share:activeSeconds?1:0,period_count:stats.count,longest_active_seconds:stats.longest_seconds,first_observed_ms:active[0]?.start_ms||null,last_observed_ms:active.at(-1)?.end_ms||null,resource_observed_seconds:resource?.observed_seconds||0,resource_active_seconds:resource?.active_seconds||0,avg_cpu_percent:resource?.avg_cpu_percent??null,peak_cpu_percent:resource?.peak_cpu_percent??null,avg_memory_bytes:resource?.avg_memory_bytes??null,peak_memory_bytes:resource?.peak_memory_bytes??null,peak_process_count:resource?.peak_process_count||0,resource_sample_count:resource?.sample_count||0};return {...view,segments,systems:[system],resource_history,contributions:activeSeconds?[{...system,share:1}]:[],active_block_count:stats.count,longest_active_seconds:stats.longest_seconds,longest_active_range:stats.longest_range}}function currentView(){return viewForSystem(viewForDate(monitor.activity_view,selectedDateKey),focusedSystemSignature)}function viewTotals(view){const valid=(view?.segments||[]).filter(segment=>segment.valid),active=valid.filter(segment=>segment.state==='active').reduce((sum,segment)=>sum+segment.duration_seconds,0),observed=valid.reduce((sum,segment)=>sum+segment.duration_seconds,0);return {active,observed,ratio:observed?active/observed:null}}
|
|
65
|
+
class FootprintExplorer extends ActivityExplorer{reset(){super.reset();selectedSystemSignature=null;focusedSystemSignature=null;this.focusSignature=null;renderInspector();renderFocusSummary();renderSystemTimeline()}selectSystem(signature){selectedSystemSignature=signature||null;this.selected=null;this.output.textContent=text('noSelection');renderInspector();renderFocusSummary();renderMix();renderSystemTimeline();renderRuntimeFootprint();renderInspectorApps()}focusSystem(signature){selectedSystemSignature=signature||selectedSystemSignature;focusedSystemSignature=focusedSystemSignature===selectedSystemSignature?null:selectedSystemSignature;this.focusSignature=focusedSystemSignature;this.selected=null;this.output.textContent=text('noSelection');renderMonitor()}focusRange(start,end){super.focusRange(start,end);explorerMode='pulse';syncModeButtons();renderFocusSummary();renderSystemTimeline()}focusSegment(id){super.focusSegment(id);explorerMode='pulse';syncModeButtons();renderFocusSummary();renderSystemTimeline()}describe(segment){super.describe(segment);if(segment?.system_signatures?.length)selectedSystemSignature=segment.system_signatures[0];explorerMode='pulse';syncModeButtons();renderInspector();renderFocusSummary();renderSystemTimeline()}setResourceMode(mode){resourceMode=mode;this.schedule()}resourceValue(sample,key){const scoped=selectedSystemSignature?sample.systems?.[selectedSystemSignature]:sample;return scoped?.[key]??null}showTooltip(event,segment){if(!segment){this.tooltip.hidden=true;return}const time=this.eventTime(event),sample=[...resourceSamples].sort((a,b)=>Math.abs(a.at-time)-Math.abs(b.at-time))[0],systems=segment.system_signatures.map(signature=>productMap().get(signature)?.name||signature),resources=[];if(sample&&Math.abs(sample.at-time)<=Math.max(2500,monitor.sample_interval_ms*2)){const cpu=this.resourceValue(sample,'cpu'),memory=this.resourceValue(sample,'memory');if(Number.isFinite(cpu))resources.push(text('cpu')+' '+format.format(Number(cpu.toFixed(1)))+'%');if(Number.isFinite(memory))resources.push(text('memory')+' '+bytes(memory))}const rect=this.canvas.parentElement.getBoundingClientRect();this.tooltip.textContent=fullMoment.format(segment.start_ms)+' – '+fullMoment.format(segment.end_ms)+' · '+seconds(segment.duration_seconds)+' · '+this.stateLabel(segment)+(systems.length?' · '+list(systems):'')+(resources.length?' · '+resources.join(' · '):'');this.tooltip.hidden=false;this.tooltip.style.left=Math.min(event.clientX-rect.left+10,rect.width-this.tooltip.offsetWidth-6)+'px';this.tooltip.style.top=Math.max(4,event.clientY-rect.top-this.tooltip.offsetHeight-8)+'px'}draw(){super.draw();const main=this.size(this.canvas),context=main.context,range=this.visibleRange(),left=64,right=main.width-12,width=Math.max(1,right-left),style=getComputedStyle(document.documentElement),samples=resourceSamples.filter(sample=>sample.at>=range[0]&&sample.at<=range[1]);context.fillStyle=style.getPropertyValue('--muted');context.font='700 9px Inter,sans-serif';context.fillText(text('resourcePulse'),8,224);context.font='650 8px Inter,sans-serif';context.fillText(!samples.length&&monitor.lifecycle!=='monitoring'?text('resourceNotRetained'):text('resourceLiveOnly'),8,239);context.strokeStyle=style.getPropertyValue('--line');context.beginPath();context.moveTo(left,214);context.lineTo(right,214);context.moveTo(left,258);context.lineTo(right,258);context.stroke();if(!samples.length){if(monitor.lifecycle==='monitoring'){context.fillStyle=style.getPropertyValue('--muted');context.fillText(text('resourceCollecting'),Math.max(left,210),239)}return}const xFor=time=>left+(time-range[0])/Math.max(1,range[1]-range[0])*width,series=[];if(resourceMode!=='memory')series.push({key:'cpu',color:style.getPropertyValue('--brand')});if(resourceMode!=='cpu')series.push({key:'memory',color:'#F49355'});for(const item of series){const values=samples.map(sample=>this.resourceValue(sample,item.key)).filter(Number.isFinite),maximum=Math.max(1,...values);context.strokeStyle=item.color;context.lineWidth=resourceMode==='both'?1.7:2.4;context.beginPath();let started=false;for(const sample of samples){const value=this.resourceValue(sample,item.key);if(!Number.isFinite(value))continue;const x=xFor(sample.at),y=256-(value/maximum)*36;if(!started){context.moveTo(x,y);started=true}else context.lineTo(x,y)}context.stroke()}const key=resourceMode==='memory'?'memory':'cpu',latest=samples.at(-1),value=latest&&this.resourceValue(latest,key);if(Number.isFinite(value)){context.fillStyle=style.getPropertyValue('--muted');const label=(key==='cpu'?format.format(Number(value.toFixed(1)))+'%':bytes(value));context.fillText(label,right-context.measureText(label).width,210)}}}
|
|
66
|
+
const explorer=new FootprintExplorer($('activity-explorer'),$('activity-navigator'),$('chart-tooltip'),$('selected-evidence'));
|
|
67
|
+
const selectSystemBase=explorer.selectSystem.bind(explorer);explorer.selectSystem=signature=>{explorerMode='apps';selectSystemBase(signature);syncModeButtons();renderFocusSummary();renderCenterApps()}
|
|
68
|
+
const systemPanel=document.querySelector('.system-mix'),workspace=document.querySelector('.workspace');if(systemPanel&&workspace){systemPanel.classList.add('system-panel');systemPanel.removeAttribute('data-view');workspace.insertBefore(systemPanel,workspace.firstElementChild)}
|
|
69
|
+
const centerCards=[...document.querySelectorAll('.below-timeline>.below-card')];if(centerCards.length>=4){centerCards[0].dataset.centerView='pulse';centerCards[1].dataset.centerView='runtime';centerCards[2].dataset.centerView='resources';centerCards[3].dataset.centerView='apps'}
|
|
70
|
+
$('all-apps').addEventListener('click',()=>{explorer.reset();setExplorerMode('pulse',false);renderMonitor()});$('focus-system').addEventListener('click',()=>{if(selectedSystemSignature){explorerMode='pulse';syncModeButtons();explorer.focusSystem(selectedSystemSignature)}});
|
|
71
|
+
function syncModeButtons(){document.documentElement.dataset.explorerMode=explorerMode;for(const button of document.querySelectorAll('[data-explorer-mode]'))button.setAttribute('aria-pressed',String(button.dataset.explorerMode===explorerMode));for(const panel of document.querySelectorAll('.insight-rail .rail-section[data-view]'))panel.hidden=panel.dataset.view!=='pulse'}
|
|
72
|
+
function setExplorerMode(mode,selectDefault=true){if(!['pulse','runtime','resources','apps'].includes(mode))return;explorerMode=mode;if(mode==='apps'&&selectDefault&&!selectedSystemSignature){const first=(currentView()?.systems||[])[0]||null;selectedSystemSignature=first?.signature||null}if(mode==='resources'){resourceMode='both';for(const item of document.querySelectorAll('[data-resource-mode]'))item.classList.toggle('active',item.dataset.resourceMode==='both')}syncModeButtons();renderInspector();renderFocusSummary();renderInspectorApps();renderCenterApps();explorer.schedule()}
|
|
73
|
+
function renderFocusSummary(){const view=currentView()||{segments:[],systems:[],active_block_count:0,longest_active_seconds:0},unfiltered=viewForDate(monitor.activity_view,selectedDateKey)||view,totals=selectedDateKey||focusedSystemSignature?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},system=(unfiltered.systems||[]).find(item=>item.signature===selectedSystemSignature)||null,selected=(view.segments||[]).find(item=>item.id===explorer.selected)||(unfiltered.segments||[]).find(item=>item.id===explorer.selected)||null,products=monitor.products||[],resources=aggregateResources(products),historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring',title=$('focus-title'),copyNode=$('focus-copy'),stats=$('focus-stats');stats.replaceChildren();let heading=text('pulseDetailTitle'),description=text('pulseDetailCopy'),eyebrow=text('currentSession'),panelTitle=text('activityExplorer'),panelCopy=text('activityExplorerCopy');if(explorerMode==='pulse'){if(selected){heading=text('selectedBlock');description=fullMoment.format(selected.start_ms)+' – '+fullMoment.format(selected.end_ms);appendInspectorStat(stats,text('selectedDate'),dateLabel.format(new Date(selected.start_ms)));appendInspectorStat(stats,text('selectedTime'),clock.format(selected.start_ms)+' – '+clock.format(selected.end_ms));appendInspectorStat(stats,text('duration'),seconds(selected.duration_seconds));appendInspectorStat(stats,text('state'),explorer.stateLabel(selected))}else{appendInspectorStat(stats,text('observationDate'),observationDateRange());appendInspectorStat(stats,text('observed'),seconds(totals.observed));appendInspectorStat(stats,text('activityBlocks'),format.format(view.active_block_count||0));appendInspectorStat(stats,text('activeAiTools'),format.format((view.systems||[]).filter(item=>item.active_seconds>0).length))}}else if(explorerMode==='runtime'){heading=system?system.name:text('runtimeDetailTitle');description=focusedSystemSignature?text('focusSystemHelp'):text('runtimeDetailCopy');panelTitle=text('runtimeDetailTitle');panelCopy=text('runtimeDetailCopy');appendInspectorStat(stats,text('observationDate'),observationDateRange());appendInspectorStat(stats,text('observed'),seconds(totals.observed));appendInspectorStat(stats,text('aiActive'),seconds(totals.active));appendInspectorStat(stats,text('activityRatio'),pct(totals.ratio));appendInspectorStat(stats,text('longestActive'),seconds(view.longest_active_seconds||0));appendInspectorStat(stats,text('activityBlocks'),format.format(view.active_block_count||0));appendInspectorStat(stats,text('availableRuntimes'),format.format(footprint.local_details?.runtimes?.length||0));appendInspectorStat(stats,text('hostedModelsRunning'),format.format(footprint.confirmed_running_model_count||0))}else if(explorerMode==='resources'){heading=system?system.name+' · '+text('resourcesNow'):text('resourcesDetailTitle');description=live?text('resourcesDetailCopy'):text('resourceNotRetained');eyebrow=system?.name||text('currentSession');panelTitle=text('resourcesDetailTitle');panelCopy=text('resourcesDetailCopy');const scoped=system||resources,cpuValue=system?scoped.current_cpu_percent:scoped.cpu,memoryValue=system?scoped.current_memory_bytes:scoped.memory;appendInspectorStat(stats,text('cpu'),live&&Number.isFinite(cpuValue)?format.format(Number(cpuValue.toFixed(1)))+'%':'—');appendInspectorStat(stats,text('memory'),live&&Number.isFinite(memoryValue)?bytes(memoryValue):'—');appendInspectorStat(stats,text('gpu'),text('notMeasured'));appendInspectorStat(stats,system?text('appSpace'):text('recognizedModelSpace'),system?text('notAttributed'):bytes(footprint.model_storage_bytes||0))}else{heading=system?.name||text('appsDetailTitle');description=system?text('appsDetailCopy'):text('noAppSelected');eyebrow=system?.name||text('currentSession');panelTitle=system?.name||text('appsDetailTitle');panelCopy=text('appsDetailCopy');if(system){document.documentElement.style.setProperty('--accent-system',systemColor(system.signature));appendInspectorStat(stats,text('activeDuration'),seconds(system.active_seconds));appendInspectorStat(stats,text('contribution'),Math.round(system.share*100)+'%');appendInspectorStat(stats,text('currentAppState'),system.state==='working-now'?text('workingNow'):text('openIdle'));appendInspectorStat(stats,text('activityPeriods'),format.format(system.period_count));appendInspectorStat(stats,text('firstObserved'),system.first_observed_ms?fullMoment.format(system.first_observed_ms):'—');appendInspectorStat(stats,text('lastObserved'),system.last_observed_ms?fullMoment.format(system.last_observed_ms):'—');appendInspectorStat(stats,text('cpu'),live&&Number.isFinite(system.current_cpu_percent)?format.format(Number(system.current_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(stats,text('memory'),live&&Number.isFinite(system.current_memory_bytes)?bytes(system.current_memory_bytes):'—')}else{appendInspectorStat(stats,text('observationDate'),observationDateRange());appendInspectorStat(stats,text('appsView'),format.format((view.systems||[]).length));appendInspectorStat(stats,text('activeDuration'),seconds(totals.active));appendInspectorStat(stats,text('observed'),seconds(totals.observed))}}title.textContent=heading;copyNode.textContent=description;$('explorer-eyebrow').textContent=eyebrow;$('explorer-title').textContent=panelTitle;$('explorer-copy').textContent=panelCopy;syncModeButtons()}
|
|
74
|
+
function appendInspectorStat(container,label,value){const node=document.createElement('div'),name=document.createElement('span'),strong=document.createElement('strong');node.className='inspector-stat';name.textContent=label;strong.textContent=value;node.append(name,strong);container.append(node)}function syncMixSelection(){for(const button of document.querySelectorAll('.mix-item')){const selected=button.dataset.signature===selectedSystemSignature,focused=button.dataset.signature===focusedSystemSignature;button.setAttribute('aria-pressed',String(selected));button.classList.toggle('is-focused',focused)}$('all-apps')?.classList.toggle('primary',!selectedSystemSignature&&!focusedSystemSignature);const focus=$('focus-system');if(focus){focus.disabled=!selectedSystemSignature;focus.textContent=focusedSystemSignature===selectedSystemSignature?text('clearFocus'):text('focusSystem');focus.classList.toggle('primary',Boolean(selectedSystemSignature&&focusedSystemSignature===selectedSystemSignature))}}function restoreInsightHeadline(){const headline=$('inspector-headline'),title=document.createElement('h2'),copyNode=document.createElement('p');title.textContent=text('observationShows');copyNode.className='insight-copy';copyNode.textContent=text('selectTimelineBlock');headline.replaceChildren(title,copyNode)}function productKindLabel(kind){return kind==='local-model-runtime'?text('systemModelRuntime'):kind==='ai-app'?text('systemAiApp'):text('systemAgent')}function renderInspector(){syncMixSelection();const container=$('app-inspector'),view=viewForDate(monitor.activity_view,selectedDateKey);if(!selectedSystemSignature){container.hidden=true;container.replaceChildren();return}const system=(view?.systems||[]).find(item=>item.signature===selectedSystemSignature),product=(monitor.products||[]).find(item=>item.signature===selectedSystemSignature);if(!system||!product){selectedSystemSignature=null;container.hidden=true;container.replaceChildren();syncMixSelection();return}container.hidden=false;container.replaceChildren();const head=document.createElement('div'),title=document.createElement('strong'),state=document.createElement('span'),runtime=document.createElement('div'),resources=document.createElement('div'),resourceTitle=document.createElement('p');head.className='inspector-head';title.textContent=system.name;state.className='inspector-state';state.textContent=system.state==='working-now'?text('workingNow'):text('openIdle');head.append(title,state);runtime.className='inspector-grid';appendInspectorStat(runtime,text('appType'),productKindLabel(system.kind));appendInspectorStat(runtime,text('activeDuration'),seconds(system.active_seconds));appendInspectorStat(runtime,text('contribution'),Math.round(system.share*100)+'%');appendInspectorStat(runtime,text('activityPeriods'),format.format(system.period_count));appendInspectorStat(runtime,text('longestActive'),seconds(system.longest_active_seconds));appendInspectorStat(runtime,text('detectedProcesses'),format.format(system.current_process_count));resourceTitle.className='eyebrow';resourceTitle.textContent=text('resourcesNow');resources.className='inspector-grid';const historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring';appendInspectorStat(resources,text('cpu'),live&&Number.isFinite(system.current_cpu_percent)?format.format(Number(system.current_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(resources,text('memory'),live&&Number.isFinite(system.current_memory_bytes)?bytes(system.current_memory_bytes):'—');appendInspectorStat(resources,text('gpu'),text('notMeasured'));appendInspectorStat(resources,text('appSpace'),text('notAttributed'));container.append(head,runtime,resourceTitle,resources)}
|
|
75
|
+
function measuredDateKeys(view){const keys=new Set();for(const segment of view?.segments||[]){if(!segment.valid)continue;const end=Math.max(segment.start_ms,segment.end_ms-1);for(let cursor=segment.start_ms;cursor<end;cursor+=6*60*60*1000)keys.add(localDateKey(cursor));keys.add(localDateKey(end))}return [...keys].sort()}function renderDates(){const view=monitor.activity_view,keys=measuredDateKeys(view),picker=$('date-picker'),options=$('date-options');if(selectedDateKey&&!keys.includes(selectedDateKey))selectedDateKey=null;$('observation-date').textContent=selectedDateKey?dateLabel.format(new Date(selectedDateKey+'T12:00:00')):observationDateRange();$('observation-span').textContent=((view?.continuity_ids?.length||view?.observation_ids?.length||0)>1)?text('observationSessions',{count:format.format(view.continuity_ids?.length||view.observation_ids.length)}):text('observationSpan');picker.dataset.single=String(keys.length<2);options.replaceChildren();for(const key of keys){const button=document.createElement('button'),mark=document.createElement('span');button.type='button';button.className='date-option'+(selectedDateKey===key?' active':'');button.textContent=dateLabel.format(new Date(key+'T12:00:00'));mark.textContent='●';button.append(mark);button.addEventListener('click',()=>{selectedDateKey=key;picker.open=false;renderMonitor()});options.append(button)}$('resource-history-state').textContent=monitor.lifecycle==='monitoring'&&(!selectedDateKey||selectedDateKey===localDateKey(view?.extent?.end_ms||Date.now()))?text('resourceLiveOnly'):text('resourceNotRetained')}
|
|
76
|
+
function renderInsights(){const listNode=$('insight-list'),view=monitor.activity_view||{},insights=view.insights||[];listNode.replaceChildren();if(!insights.length){const note=document.createElement('div');note.className='early';note.textContent=monitor.observed_seconds<60?text('earlyObservationCopy'):text('pulseWaiting');listNode.append(note);return}for(const insight of insights){const button=document.createElement('button');button.type='button';button.className='insight';const evidence=insight.evidence||{type:'observation'},contribution=(view.contributions||[])[0];button.style.setProperty('--accent-system',contribution?systemColor(contribution.signature):'var(--brand)');button.textContent=insight.text;button.addEventListener('click',()=>{if(evidence.type==='range')explorer.focusRange(evidence.start_ms,evidence.end_ms);else if(evidence.type==='segment')explorer.focusSegment(evidence.segment_id);else if(evidence.type==='system')explorer.selectSystem(evidence.signature);else explorer.reset()});listNode.append(button)}}
|
|
77
|
+
function renderSystemTimeline(){const container=$('system-timeline'),view=currentView()||{},extent=view.extent,range=explorer.visibleRange();container.replaceChildren();if(!extent||!view.segments?.length){const empty=document.createElement('div');empty.className='timeline-empty';empty.textContent=text('noMeasuredActivity');container.append(empty);return}const axis=document.createElement('div'),axisLabel=document.createElement('span'),ticks=document.createElement('div');axis.className='timeline-axis';axisLabel.className='timeline-axis-label';axisLabel.textContent=text('systems');ticks.className='timeline-ticks';const trackWidth=Math.max(1,container.clientWidth-130),tickCount=trackWidth<420?2:trackWidth<700?3:5;for(let index=0;index<tickCount;index++){const ratio=index/(tickCount-1),tick=document.createElement('span');tick.className='timeline-tick';tick.style.left=ratio*100+'%';tick.textContent=clock.format(range[0]+ratio*(range[1]-range[0]));ticks.append(tick)}axis.append(axisLabel,ticks);container.append(axis);const products=(focusedSystemSignature?listedProducts().filter(product=>product.signature===focusedSystemSignature):listedProducts()),systems=new Map((view.systems||[]).map(system=>[system.signature,system]));for(const product of products){const system=systems.get(product.signature);if(focusedSystemSignature&&!system)continue;const row=document.createElement('div'),label=document.createElement('button'),dot=document.createElement('i'),name=document.createElement('strong'),meta=document.createElement('span'),track=document.createElement('div'),color=systemColor(product.signature),segments=(view.segments||[]).filter(segment=>segment.state==='active'&&segment.system_signatures.includes(product.signature)&&segment.end_ms>=range[0]&&segment.start_ms<=range[1]);row.className='timeline-row'+(selectedSystemSignature===product.signature?' is-selected':'')+(focusedSystemSignature===product.signature?' is-focused':'');row.style.setProperty('--system-color',color);label.type='button';label.className='timeline-system';label.setAttribute('aria-pressed',String(selectedSystemSignature===product.signature));dot.setAttribute('aria-hidden','true');name.textContent=product.name;meta.textContent=(product.state==='working-now'?text('workingNow'):text('openIdle'))+' · '+seconds(system?.active_seconds||product.active_seconds||0);label.append(dot,name,meta);label.addEventListener('click',()=>explorer.selectSystem(product.signature));track.className='timeline-track';for(const segment of segments){const start=Math.max(range[0],segment.start_ms),end=Math.min(range[1],Math.max(segment.end_ms,segment.start_ms+(monitor.sample_interval_ms||1000))),left=(start-range[0])/Math.max(1,range[1]-range[0])*100,width=Math.max(.35,(end-start)/Math.max(1,range[1]-range[0])*100),block=document.createElement('button');block.type='button';block.className='timeline-block'+(segment.id===explorer.selected?' is-pinned':'')+(segment.is_longest_active||Math.abs(segment.duration_seconds-(system?.longest_active_seconds||-1))<.01?' is-longest':'');block.style.left=left+'%';block.style.width=width+'%';block.style.setProperty('--system-color',color);block.textContent=width>7?seconds(segment.duration_seconds):'';const evidence=product.name+' · '+fullMoment.format(segment.start_ms)+' – '+fullMoment.format(segment.end_ms)+' · '+seconds(segment.duration_seconds)+' · '+explorer.stateLabel(segment);block.setAttribute('aria-label',evidence);block.addEventListener('pointerenter',event=>{explorer.tooltip.textContent=evidence;explorer.tooltip.hidden=false;const rect=container.getBoundingClientRect();explorer.tooltip.style.left=Math.min(event.clientX-rect.left+8,rect.width-explorer.tooltip.offsetWidth-5)+'px';explorer.tooltip.style.top=Math.max(3,event.clientY-rect.top-explorer.tooltip.offsetHeight-8)+'px'});block.addEventListener('pointerleave',()=>{explorer.tooltip.hidden=true});block.addEventListener('click',()=>{selectedSystemSignature=product.signature;explorer.focusSegment(segment.id)});track.append(block)}if(!segments.length){const empty=document.createElement('span');empty.className='timeline-empty';empty.textContent=text('noMeasuredActivity');track.append(empty)}row.append(label,track);container.append(row)}}
|
|
78
|
+
function renderRuntimeFootprint(){const container=$('runtime-footprint-list'),view=currentView()||{},systems=view.systems||[];container.replaceChildren();if(!systems.length){const empty=document.createElement('div');empty.className='early';empty.textContent=text('noMeasuredContribution');container.append(empty);return}for(const system of systems){const row=document.createElement('button'),name=document.createElement('strong'),runtime=document.createElement('span'),share=document.createElement('span');row.type='button';row.className='runtime-footprint-row'+(selectedSystemSignature===system.signature?' is-selected':'');row.style.setProperty('--system-color',systemColor(system.signature));name.textContent=system.name;runtime.textContent=seconds(system.active_seconds);share.textContent=Math.round(system.share*100)+'%';row.append(name,runtime,share);row.addEventListener('click',()=>explorer.selectSystem(system.signature));container.append(row)}}
|
|
79
|
+
function renderInspectorApps(){const container=$('inspector-apps-list');if(!container)return;container.replaceChildren();for(const product of listedProducts()){const row=document.createElement('div'),name=document.createElement('strong'),note=document.createElement('span'),parts=[product.state==='working-now'?text('workingNow'):text('openIdle'),format.format(product.process_count||0)+' '+text((product.process_count||0)===1?'measuredProcess':'measuredProcesses')];if(Number.isFinite(product.cpu_percent))parts.push(format.format(Number(product.cpu_percent.toFixed(1)))+'% '+text('cpu'));if(Number.isFinite(product.memory_bytes))parts.push(bytes(product.memory_bytes)+' '+text('memory'));row.className='inspector-app-row';name.textContent=product.name;note.textContent=parts.join(' · ');row.append(name,note);container.append(row)}if(!container.children.length){const empty=document.createElement('div');empty.className='early';empty.textContent=text('noMeasuredContribution');container.append(empty)}}
|
|
80
|
+
function renderBelowSummary(){const view=currentView()||{systems:[],active_block_count:0,longest_active_seconds:0},totals=selectedDateKey||focusedSystemSignature?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},resources=aggregateResources(monitor.products||[]),historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring';$('below-observed').textContent=seconds(totals.observed);$('below-active').textContent=seconds(totals.active);$('below-ratio').textContent=pct(totals.ratio);$('below-periods').textContent=format.format(view.active_block_count||0);$('below-longest').textContent=seconds(view.longest_active_seconds||0);$('below-systems').textContent=format.format((view.systems||[]).length);$('below-cpu').textContent=live&&Number.isFinite(resources.cpu)?format.format(Number(resources.cpu.toFixed(1)))+'%':'—';$('below-memory').textContent=live&&Number.isFinite(resources.memory)?bytes(resources.memory):'—';$('below-runtimes').textContent=format.format(footprint.local_details?.runtimes?.length||0);$('below-models').textContent=format.format(footprint.model_record_count||0);$('below-running').textContent=format.format(footprint.confirmed_running_model_count||0);$('below-space').textContent=bytes(footprint.model_storage_bytes||0);$('below-local-insight').textContent=$('hosted-insight').textContent;renderRuntimeFootprint()}
|
|
81
|
+
function renderMix(){const bar=$('mix-bar'),listNode=$('mix-list'),view=viewForDate(monitor.activity_view,selectedDateKey)||{},contributions=view.contributions||[],systems=new Map((view.systems||[]).map(system=>[system.signature,system])),products=listedProducts();bar.replaceChildren();listNode.replaceChildren();for(const contribution of contributions){const color=systemColor(contribution.signature),part=document.createElement('button');part.type='button';part.style.width=(contribution.share*100)+'%';part.style.background=color;part.title=contribution.name+' · '+seconds(contribution.active_seconds);part.addEventListener('click',()=>explorer.selectSystem(contribution.signature));bar.append(part)}if(!products.length){listNode.textContent=text('noMeasuredContribution');syncMixSelection();return}for(const product of products){const system=systems.get(product.signature),color=systemColor(product.signature),item=document.createElement('button'),dot=document.createElement('i'),name=document.createElement('strong'),amount=document.createElement('span'),runtime=system?.active_seconds||product.active_seconds||0,state=product.state==='working-now'?text('workingNow'):text('openIdle');item.type='button';item.className='mix-item';item.dataset.signature=product.signature;item.setAttribute('aria-pressed',String(selectedSystemSignature===product.signature));item.style.setProperty('--system-color',color);dot.setAttribute('aria-hidden','true');name.textContent=product.name;amount.textContent=state+' · '+seconds(runtime);item.append(dot,name,amount);item.addEventListener('click',()=>explorer.selectSystem(product.signature));listNode.append(item)}syncMixSelection()}
|
|
82
|
+
function renderHostedLocal(){const products=monitor.products||[],workingLocal=products.filter(product=>product.kind==='local-model-runtime'&&product.state==='working-now'),running=footprint.confirmed_running_model_count||0;$('models-found').textContent=format.format(footprint.model_record_count||0);$('models-running').textContent=format.format(running);$('device-storage').textContent=bytes(footprint.model_storage_bytes||0);$('metric-local').textContent=format.format(footprint.model_record_count||0)+' · '+bytes(footprint.model_storage_bytes||0);$('metric-local-running').textContent=format.format(running)+' '+text('runningShort');$('hosted-insight').textContent=running>0||workingLocal.length?text('hostedModelsRunningInsight'):text('localAiNone')}
|
|
83
|
+
function renderRuntimes(){const container=$('rail-runtimes');container.replaceChildren();for(const runtime of footprint.local_details?.runtimes||[]){const row=document.createElement('button'),name=document.createElement('strong'),status=document.createElement('span');row.type='button';row.className='runtime-item';row.title=text('inspectRuntimeHint');name.textContent=runtime.name;status.textContent=runtime.loaded_model_count?text('modelsLoaded',{count:runtime.loaded_model_count,models:runtime.loaded_model_count===1?text('model'):text('models')}):text('verifiedAvailable');row.append(name,status);row.addEventListener('click',()=>setExplorerMode('runtime'));container.append(row)}if(!container.children.length){const note=document.createElement('div');note.className='early';note.textContent='—';container.append(note)}}function renderDetails(){if(!footprint.local_details)return;const details=footprint.local_details,runtimeList=$('runtime-list'),modelList=$('model-list'),appList=$('app-list');for(const node of [runtimeList,modelList,appList])node.replaceChildren();for(const runtime of details.runtimes)add(runtimeList,runtime.name,runtime.loaded_model_count?text('modelsLoaded',{count:runtime.loaded_model_count,models:runtime.loaded_model_count===1?text('model'):text('models')}):text('verifiedAvailable'));for(const model of details.models.filter(item=>item.loaded))add(modelList,model.name,text('loaded',{count:''}).trim());for(const product of monitor.products||[]){const note=[text(product.state==='working-now'?'working':'openIdleLegend'),format.format(product.process_count)+' '+text(product.process_count===1?'measuredProcess':'measuredProcesses'),product.memory_bytes?bytes(product.memory_bytes):''].filter(Boolean).join(' · ');add(appList,product.name,note)}if(!appList.children.length)for(const agent of details.agents)add(appList,agent.name,text('processActivity'));if($('raw-system-count'))$('raw-system-count').textContent=format.format((monitor.products||[]).length);renderRuntimes()}
|
|
84
|
+
function saveLastSummary(){if(!monitor.observed_seconds)return;const dominant=dominantProduct();try{localStorage.setItem(lastSummaryKey,JSON.stringify({activity_ratio:monitor.activity_ratio,active_tool:dominant?.name||null,local_models_found:footprint.model_record_count||0,local_models_running:footprint.confirmed_running_model_count||0}))}catch{}}
|
|
85
|
+
function renderMonitor(){const products=monitor.products||[],working=userFacingProducts().filter(product=>product.state==='working-now'),presence=monitor.presence||{state:'active',observation_eligible:true},status=$('monitor-status');status.className='status';let statusText;if(monitor.lifecycle==='stopped'){status.classList.add('stopped');statusText=text('stopped')}else if(!presence.observation_eligible){status.classList.add('paused');statusText=text('paused')}else if(working.length)statusText=text('menuWorking',{count:working.length});else statusText=text('menuMonitoring');$('monitor-status-text').textContent=statusText;if($('monitor-button'))$('monitor-button').textContent=monitor.lifecycle==='monitoring'?text('stopMonitoring'):monitor.observed_seconds?text('startMonitoringAgain'):text('startMonitoring');appendResourceSample();renderDates();const view=currentView()||{segments:[],contributions:[],systems:[],insights:[],longest_active_seconds:0},totals=selectedDateKey||focusedSystemSignature?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},resources=aggregateResources(products),historical=selectedDateKey&&selectedDateKey!==localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()),live=!historical&&monitor.lifecycle==='monitoring',dominant=dominantProduct();if(dominant)document.documentElement.style.setProperty('--accent-system',systemColor(dominant));$('metric-ratio').textContent=pct(totals.ratio);$('ratio-label').textContent=totals.observed<60?text('earlyObservation'):totals.ratio>=.7?text('mostlyActive'):totals.ratio<=.3?text('mostlyIdle'):text('mixedActivity');$('metric-active').textContent=seconds(totals.active);$('metric-observed').textContent=seconds(totals.observed);$('metric-systems').textContent=format.format((view.systems||[]).filter(system=>system.active_seconds>0||system.state==='working-now').length);$('metric-longest').textContent=seconds(view.longest_active_seconds||0);$('observation-identity').textContent=text('observationIdentity',{number:monitor.observation_id??'—'});$('rail-observed').textContent=seconds(totals.observed);$('rail-active').textContent=seconds(totals.active);$('rail-ratio').textContent=pct(totals.ratio);$('rail-longest').textContent=seconds(view.longest_active_seconds||0);$('rail-cpu').textContent=live&&Number.isFinite(resources.cpu)?format.format(Number(resources.cpu.toFixed(1)))+'%':'—';$('rail-memory').textContent=live&&Number.isFinite(resources.memory)?bytes(resources.memory):'—';$('rail-space').textContent=bytes(footprint.model_storage_bytes||0);explorer.setData(view);renderInsights();renderMix();renderHostedLocal();renderDetails();renderInspector();renderFocusSummary();renderSystemTimeline();renderInspectorApps();renderBelowSummary();if($('overhead')){$('overhead').textContent=monitor.overhead?.current_cpu_percent===null?text('warmingUp'):format.format(Number(monitor.overhead.current_cpu_percent.toFixed(1)))+'% CPU';$('overhead-note').textContent=bytes(monitor.overhead?.current_memory_bytes||0)+' RAM'}if($('review-payload')){const eligible=monitor.observed_seconds>=3600;$('review-payload').disabled=!eligible;$('compare-progress').textContent=eligible?'':text('globalProgress',{remaining:seconds(Math.max(0,3600-monitor.observed_seconds))});const preview=monitor.global_preview;$('global-result').textContent=preview?.state==='contributed'?text('previewContributed'):preview?.state==='unavailable'?text('previewUnavailable'):monitor.global_permission==='granted'?text('previewWaiting'):text('permissionNeeded')}saveLastSummary()}
|
|
86
|
+
function shareObservationWindow(){const extent=monitor.activity_view?.extent;if(!extent)return text('shareMeasuredLocally');const start=new Date(extent.start_ms),end=new Date(Math.max(extent.start_ms,extent.end_ms-1));return shareDateLabel.format(start)+' '+clock.format(start)+' – '+shareDateLabel.format(end)+' '+clock.format(end)}
|
|
87
|
+
function primaryInsight(){return monitor.insights?.[0]||text('activeShareFallback',{ratio:pct(monitor.activity_ratio)})}function shareInsightLine(){const tools=activeToolNames();if(tools.length===1)return text('shareFocusedLine');if(tools.length>1)return text('shareMultiLine',{count:format.format(tools.length)});if(footprint.model_record_count)return text('shareModelReserveLine');return primaryInsight()}function shareDurationLine(){return monitor.observed_seconds?text('shareMeasuredDurations',{observed:seconds(monitor.observed_seconds),active:seconds(monitor.active_seconds||0)}):''}function shareCaption(){const tools=activeToolNames(),running=footprint.confirmed_running_model_count||0,details=[text('shareActivity',{ratio:pct(monitor.activity_ratio)}),shareDurationLine(),tools.length?text('shareTool',{tools:list(tools)}):'',text('shareModels',{count:footprint.model_record_count,models:footprint.model_record_count===1?text('model'):text('models'),running:format.format(running)})].filter(Boolean).join(' ');return text('captionFirst',{ratio:pct(monitor.activity_ratio)})+'\\n\\n'+details+'\\n\\n'+text('captionQuestion')+'\\n\\nforkit.dev/ai-footprint'}
|
|
88
|
+
function wrap(x,value,left,top,maxWidth,lineHeight,maxLines){const words=String(value||'').split(' '),lines=[];let line='';for(const word of words){const next=line?line+' '+word:word;if(x.measureText(next).width>maxWidth&&line){lines.push(line);line=word}else line=next}if(line)lines.push(line);for(let index=0;index<Math.min(lines.length,maxLines);index++)x.fillText(lines[index],left,top+index*lineHeight)}
|
|
89
|
+
async function drawShare(){const canvas=$('share-canvas'),context=canvas.getContext('2d'),view=currentView()||monitor.activity_view,contributions=(view?.contributions||[]).slice(0,3),tools=activeToolNames(),running=footprint.confirmed_running_model_count||0,totals=selectedDateKey?viewTotals(view):{active:monitor.active_seconds,observed:monitor.observed_seconds,ratio:monitor.activity_ratio},activity=totals.observed?pct(totals.ratio):format.format(footprint.model_record_count),purple='#2A1F55',teal='#008190',lightTeal='#6AA7AB',orange='#F49355',cream='#F1EBDF',gradient=context.createLinearGradient(0,0,1080,1080);gradient.addColorStop(0,purple);gradient.addColorStop(.55,'#342761');gradient.addColorStop(1,teal);context.fillStyle=gradient;context.fillRect(0,0,1080,1080);context.fillStyle=cream;context.beginPath();context.roundRect(42,42,996,996,44);context.fill();context.fillStyle=orange;context.fillRect(42,42,996,16);if(shareLogo){const image=await new Promise(resolve=>{const value=new Image();value.onload=()=>resolve(value);value.onerror=()=>resolve(null);value.src=shareLogo});if(image)context.drawImage(image,78,78,72,72)}context.fillStyle=purple;context.font='900 28px Inter,sans-serif';context.fillText(text('myFootprint'),78,200);context.fillStyle=teal;context.font='950 160px Inter,sans-serif';context.fillText(activity,70,400);context.font='900 31px Inter,sans-serif';context.fillText(totals.observed?text('shareActive'):text('localModels'),82,450);context.fillStyle=purple;context.font='850 24px Inter,sans-serif';context.fillText(shareObservationDate()||text('shareMeasuredLocally').toLocaleUpperCase(locale),82,505);context.fillStyle=lightTeal;context.beginPath();context.roundRect(78,548,924,260,28);context.fill();context.fillStyle=purple;context.font='900 23px Inter,sans-serif';context.fillText(tools.length===1?text('oneActiveTool'):text('activeToolsCount',{count:tools.length}),108,595);let y=650;context.font='850 28px Inter,sans-serif';for(const item of contributions){context.fillStyle=systemColor(item.signature);context.beginPath();context.arc(116,y-9,7,0,Math.PI*2);context.fill();context.fillStyle=purple;context.fillText(item.name,140,y);context.textAlign='right';context.fillText(Math.round(item.share*100)+'%',956,y);context.textAlign='left';y+=47}context.fillStyle=purple;context.font='800 24px Inter,sans-serif';context.fillText(seconds(totals.active)+' '+text('shareActive').toLowerCase()+' · '+seconds(totals.observed)+' '+text('validObservation').toLowerCase(),108,770);context.fillStyle=purple;context.font='900 22px Inter,sans-serif';context.fillText(text('localAi').toLocaleUpperCase(locale),82,872);context.font='820 27px Inter,sans-serif';context.fillText(format.format(footprint.model_record_count)+' '+text('models').toLowerCase()+' · '+bytes(footprint.model_storage_bytes||0)+' · '+format.format(running)+' '+text('runningShort'),82,915);context.fillStyle=teal;context.font='800 22px Inter,sans-serif';context.fillText('forkit.dev/ai-footprint',82,992);context.textAlign='right';context.fillStyle=purple;context.font='750 20px Inter,sans-serif';context.fillText('Forkit AI Footprint',998,992);context.textAlign='left'}
|
|
90
|
+
const drawShareBase=drawShare;drawShare=async function(){await drawShareBase();const canvas=$('share-canvas'),context=canvas.getContext('2d'),purple='#2A1F55',teal='#008190',cream='#F1EBDF';context.fillStyle=cream;context.fillRect(70,474,940,48);context.fillStyle=purple;context.font='850 22px Inter,sans-serif';wrap(context,shareObservationWindow(),82,505,900,26,1);context.fillStyle=teal;context.font='900 22px Inter,sans-serif';wrap(context,text('shareLocalChoice'),82,833,900,27,2)}
|
|
91
|
+
const dialog=$('share-dialog');async function openShare(){$('share-heading').textContent=shareInsightLine();await drawShare();dialog.showModal()}$('share-button').addEventListener('click',openShare);$('close-share').addEventListener('click',()=>dialog.close());async function blob(){await drawShare();return new Promise(resolve=>$('share-canvas').toBlob(resolve,'image/png'))}async function dataUrl(){const value=await blob();if(!value)return null;return new Promise(resolve=>{const reader=new FileReader();reader.onload=()=>resolve(reader.result);reader.onerror=()=>resolve(null);reader.readAsDataURL(value)})}function nativeAction(action,payload={}){const bridge=window.webkit?.messageHandlers?.forkitShare;if(!bridge)return false;bridge.postMessage({action,...payload});return true}window.forkitNativeShareResult=result=>{if(result.action==='open-global'){$('global-result').textContent=result.message||'';return}$('share-status').textContent=result.message||text('sharePrivacy');if(result.action==='copy-image')$('copy-image').textContent=text('copied');if(result.action==='copy-caption')$('copy-share').textContent=text('copied')};$('download-share').addEventListener('click',async()=>{const png=await dataUrl();if(!png)return;if(nativeAction('save',{png}))return;const value=await blob(),url=URL.createObjectURL(value),anchor=document.createElement('a');anchor.href=url;anchor.download='my-forkit-ai-footprint.png';anchor.click();setTimeout(()=>URL.revokeObjectURL(url),1000)});$('copy-share').addEventListener('click',async()=>{const caption=shareCaption();if(nativeAction('copy-caption',{caption}))return;await navigator.clipboard.writeText(caption);$('copy-share').textContent=text('copied')});$('copy-image').addEventListener('click',async()=>{const png=await dataUrl();if(!png)return;if(nativeAction('copy-image',{png}))return;const value=await blob();try{await navigator.clipboard.write([new ClipboardItem({'image/png':value})]);$('copy-image').textContent=text('copied')}catch{$('share-status').textContent=text('copyUnavailable')}});$('native-share').addEventListener('click',async()=>{const png=await dataUrl();if(!png)return;const caption=shareCaption();if(nativeAction('share',{png,caption}))return;const value=await blob(),file=new File([value],'my-forkit-ai-footprint.png',{type:'image/png'});if(navigator.share&&(!navigator.canShare||navigator.canShare({files:[file]})))await navigator.share({title:text('shareTitle'),text:caption,files:[file]});else await navigator.clipboard.writeText(caption)});
|
|
92
|
+
for(const button of document.querySelectorAll('[data-resource-mode]'))button.addEventListener('click',()=>{explorerMode='resources';syncModeButtons();resourceMode=button.dataset.resourceMode;for(const item of document.querySelectorAll('[data-resource-mode]'))item.classList.toggle('active',item===button);explorer.setResourceMode(resourceMode);renderFocusSummary()});for(const button of document.querySelectorAll('[data-explorer-mode]'))button.addEventListener('click',()=>setExplorerMode(button.dataset.explorerMode));for(const section of document.querySelectorAll('.rail-section[data-view]'))section.addEventListener('click',event=>{if(event.target.closest('button,select'))return;setExplorerMode(section.dataset.view)});$('zoom-in').addEventListener('click',()=>{explorer.zoom(.65,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()});$('zoom-out').addEventListener('click',()=>{explorer.zoom(1.4,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()});$('reset-view').addEventListener('click',()=>{explorer.reset();setExplorerMode('pulse',false);renderMonitor()});$('system-timeline').addEventListener('wheel',event=>{event.preventDefault();explorer.zoom(event.deltaY<0?.78:1.22,explorer.visibleRange().reduce((a,b)=>a+b)/2);renderSystemTimeline()},{passive:false});let timelineResizeFrame=0;new ResizeObserver(()=>{cancelAnimationFrame(timelineResizeFrame);timelineResizeFrame=requestAnimationFrame(renderSystemTimeline)}).observe($('system-timeline'));for(const next of ['en','de'])$('locale-'+next).addEventListener('click',()=>{localStorage.setItem('forkit-footprints-locale',next);const url=new URL(location.href);url.searchParams.set('lang',next);location.href=url.href});const preferred=localStorage.getItem('forkit-footprints-locale');if(preferred&&preferred!==locale){const url=new URL(location.href);url.searchParams.set('lang',preferred);location.replace(url.href)}
|
|
93
|
+
async function auth(endpoint,options={}){return fetch(endpoint,{method:'POST',headers:{'x-forkit-footprints-session':config.session_token,'content-type':'application/json'},...options})}
|
|
94
|
+
if(config){void auth(config.locale_endpoint,{body:JSON.stringify({locale})});$('monitor-button').addEventListener('click',async()=>{const endpoint=monitor.lifecycle==='monitoring'?config.monitor_stop_endpoint:config.monitor_start_endpoint,response=await auth(endpoint);if(response.ok){monitor=await response.json();renderMonitor()}});$('clear-button').addEventListener('click',async()=>{if(!confirm(text('clearConfirm')))return;const response=await auth(config.monitor_clear_endpoint);if(response.ok){monitor=await response.json();renderMonitor()}});$('scan-button').addEventListener('click',async()=>{const button=$('scan-button');button.disabled=true;$('scan-status').textContent=text('scanning');try{const response=await auth(config.endpoint);if(!response.ok)throw new Error();footprint=await response.json();renderHostedLocal();renderDetails();$('scan-status').textContent=text('refreshed')}catch{$('scan-status').textContent=text('scanFailed')}finally{button.disabled=false}});$('review-payload').addEventListener('click',()=>{if(!nativeAction('open-global'))location.assign(globalUrl)});(async()=>{try{const response=await auth(config.monitor_stream_endpoint);if(!response.ok||!response.body)return;const reader=response.body.getReader(),decoder=new TextDecoder();let buffer='';while(true){const part=await reader.read();if(part.done)break;buffer+=decoder.decode(part.value,{stream:true});const lines=buffer.split('\\n');buffer=lines.pop()||'';for(const line of lines)if(line){monitor=JSON.parse(line);renderMonitor()}}}catch{}})()}
|
|
95
|
+
function appendSystemComparison(){const view=viewForDate(monitor.activity_view,selectedDateKey),selected=(view?.systems||[]).find(system=>system.signature===selectedSystemSignature),others=(view?.systems||[]).filter(system=>system.signature!==selectedSystemSignature&&system.active_seconds>0);if(!selected||!others.length)return;const container=document.createElement('div'),label=document.createElement('label'),select=document.createElement('select'),comparison=document.createElement('div');container.className='inspector';label.className='eyebrow';label.textContent=text('compareSystems');select.className='button';for(const system of others){const option=document.createElement('option');option.value=system.signature;option.textContent=system.name;select.append(option)}comparison.className='inspector-grid';const draw=()=>{comparison.replaceChildren();const other=(view.systems||[]).find(system=>system.signature===select.value);if(!other)return;appendInspectorStat(comparison,selected.name+' · '+text('activeDuration'),seconds(selected.active_seconds));appendInspectorStat(comparison,other.name+' · '+text('activeDuration'),seconds(other.active_seconds));appendInspectorStat(comparison,selected.name+' · '+text('contribution'),Math.round(selected.share*100)+'%');appendInspectorStat(comparison,other.name+' · '+text('contribution'),Math.round(other.share*100)+'%');appendInspectorStat(comparison,selected.name+' · '+text('longestActive'),seconds(selected.longest_active_seconds));appendInspectorStat(comparison,other.name+' · '+text('longestActive'),seconds(other.longest_active_seconds))};select.addEventListener('change',draw);container.append(label,select,comparison);$('app-inspector').append(container);draw()}const activeToolNamesBase=activeToolNames;activeToolNames=function(){return selectedDateKey?(currentView()?.systems||[]).filter(system=>system.active_seconds>0).map(system=>system.name):activeToolNamesBase()};const renderInsightsBase=renderInsights;renderInsights=function(){const source=monitor.activity_view?.insights;if(!source)return renderInsightsBase();monitor.activity_view.insights=source.filter(insight=>insight.kind!=='activity-share');try{return renderInsightsBase()}finally{monitor.activity_view.insights=source}};const renderInspectorBase=renderInspector;renderInspector=function(){renderInspectorBase();appendSystemComparison()};
|
|
96
|
+
const renderInspectorLifecycleBase=renderInspector;renderInspector=function(){renderInspectorLifecycleBase();const stateNode=document.querySelector('.inspector-state'),evidence=$('selected-evidence'),previous=monitor.last_observation;if(stateNode&&monitor.lifecycle!=='monitoring')stateNode.textContent=text('previousObservationSaved');if(evidence&&monitor.lifecycle==='monitoring'&&!monitor.presence?.observation_eligible&&!monitor.observed_seconds&&previous)evidence.textContent=text('lastObservation')+' · '+pct(previous.activity_ratio)+' '+text('aiActive')+' · '+(previous.active_tool||text('noApp'))+' · '+format.format(previous.local_models_found||0)+' '+text('models')+' · '+format.format(previous.local_models_running||0)+' '+text('runningShort')};
|
|
97
|
+
const renderInspectorResourceBase=renderInspector;renderInspector=function(){renderInspectorResourceBase();if(!selectedSystemSignature)return;const container=$('app-inspector'),view=viewForDate(monitor.activity_view,selectedDateKey)||monitor.activity_view,system=(view?.systems||[]).find(item=>item.signature===selectedSystemSignature);if(!container||container.hidden||!system)return;const title=document.createElement('p'),grid=document.createElement('div');title.className='eyebrow';title.textContent=text('resourceHistory');grid.className='inspector-grid';appendInspectorStat(grid,text('resourceMeasuredTime'),system.resource_observed_seconds?seconds(system.resource_observed_seconds):'—');appendInspectorStat(grid,text('resourceAvgCpu'),Number.isFinite(system.avg_cpu_percent)?format.format(Number(system.avg_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(grid,text('resourcePeakCpu'),Number.isFinite(system.peak_cpu_percent)?format.format(Number(system.peak_cpu_percent.toFixed(1)))+'%':'—');appendInspectorStat(grid,text('resourceAvgMemory'),Number.isFinite(system.avg_memory_bytes)?bytes(system.avg_memory_bytes):'—');appendInspectorStat(grid,text('resourcePeakMemory'),Number.isFinite(system.peak_memory_bytes)?bytes(system.peak_memory_bytes):'—');appendInspectorStat(grid,text('resourceSamples'),system.resource_sample_count?format.format(system.resource_sample_count):'—');container.append(title,grid)};
|
|
98
|
+
function renderCenterApps(){const container=$('center-apps-list');if(!container)return;container.replaceChildren();const view=viewForDate(monitor.activity_view,selectedDateKey)||{},systems=new Map((view.systems||[]).map(system=>[system.signature,system])),live=monitor.lifecycle==='monitoring'&&(!selectedDateKey||selectedDateKey===localDateKey(monitor.activity_view?.extent?.end_ms||Date.now()));for(const product of listedProducts()){const system=systems.get(product.signature),row=document.createElement('button'),name=document.createElement('strong'),runtime=document.createElement('span'),processes=document.createElement('span'),resources=document.createElement('span'),parts=[];row.type='button';row.className='center-app-row'+(selectedSystemSignature===product.signature?' is-selected':'');row.style.setProperty('--system-color',systemColor(product.signature));name.textContent=product.name;runtime.textContent=text('activeDuration')+': '+seconds(system?.active_seconds||product.active_seconds||0);processes.textContent=format.format(product.process_count||0)+' '+text((product.process_count||0)===1?'measuredProcess':'measuredProcesses');if(live&&Number.isFinite(product.cpu_percent))parts.push(format.format(Number(product.cpu_percent.toFixed(1)))+'% '+text('cpu'));if(live&&Number.isFinite(product.memory_bytes))parts.push(bytes(product.memory_bytes)+' '+text('memory'));if(Number.isFinite(system?.avg_cpu_percent))parts.push(text('resourceAvgCpu')+' '+format.format(Number(system.avg_cpu_percent.toFixed(1)))+'%');if(Number.isFinite(system?.avg_memory_bytes))parts.push(text('resourceAvgMemory')+' '+bytes(system.avg_memory_bytes));resources.textContent=parts.join(' · ')||text('measuredCurrentOnly');row.append(name,runtime,processes,resources);row.addEventListener('click',()=>explorer.selectSystem(product.signature));container.append(row)}if(!container.children.length){const empty=document.createElement('div');empty.className='early';empty.textContent=text('noMeasuredContribution');container.append(empty)}}
|
|
99
|
+
function renderResourceFootprint(){const container=$('center-resource-history');if(!container)return;const view=currentView()||{},state=view.resource_history_state||monitor.activity_view?.resource_history_state||'not-retained',visibleSignatures=new Set((view.systems||[]).map(item=>item.signature)),systems=(view.resource_history?.systems||[]).filter(item=>!visibleSignatures.size||visibleSignatures.has(item.signature));const label=resourceStatusText(state);$('resource-history-label').textContent=label;$('resource-history-note').textContent=label;container.replaceChildren();if(!systems.length){const empty=document.createElement('div');empty.className='early';empty.textContent=state==='collecting'?text('resourceCollecting'):text('resourceNotRetained');container.append(empty);return}for(const item of systems){const row=document.createElement('button'),name=document.createElement('strong'),observed=document.createElement('span'),cpu=document.createElement('span'),memory=document.createElement('span'),samples=document.createElement('span');row.type='button';row.className='resource-history-row'+(selectedSystemSignature===item.signature?' is-selected':'');row.style.setProperty('--system-color',systemColor(item.signature));name.textContent=item.name;observed.textContent=text('resourceMeasuredTime')+': '+seconds(item.observed_seconds);cpu.textContent=text('resourceAvgCpu')+': '+(Number.isFinite(item.avg_cpu_percent)?format.format(Number(item.avg_cpu_percent.toFixed(1)))+'%':'—')+' · '+text('resourcePeakCpu')+': '+(Number.isFinite(item.peak_cpu_percent)?format.format(Number(item.peak_cpu_percent.toFixed(1)))+'%':'—');memory.textContent=text('resourceAvgMemory')+': '+(Number.isFinite(item.avg_memory_bytes)?bytes(item.avg_memory_bytes):'—')+' · '+text('resourcePeakMemory')+': '+(Number.isFinite(item.peak_memory_bytes)?bytes(item.peak_memory_bytes):'—');samples.textContent=text('resourceSamples')+': '+format.format(item.sample_count||0);row.append(name,observed,cpu,memory,samples);row.addEventListener('click',()=>explorer.selectSystem(item.signature));container.append(row)}}
|
|
100
|
+
const renderDatesResourceBase=renderDates;renderDates=function(){renderDatesResourceBase();const scoped=viewForDate(monitor.activity_view,selectedDateKey)||monitor.activity_view;$('resource-history-state').textContent=resourceStatusText(scoped?.resource_history_state||monitor.activity_view?.resource_history_state)};
|
|
101
|
+
const renderBelowSummaryModeBase=renderBelowSummary;renderBelowSummary=function(){renderBelowSummaryModeBase();renderCenterApps();renderResourceFootprint()};
|
|
102
|
+
renderDetails();renderMonitor();
|
|
103
|
+
</script></body></html>`;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=activity-page.js.map
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { ActivityTimelineSegment, AiActivityProduct, MonitorSnapshot, ResourceHistoryBucket } from './monitor';
|
|
2
|
+
import type { LocalInsight, LocalInsightKind } from './insights';
|
|
3
|
+
export type ActivityVisualState = 'active' | 'idle' | 'excluded';
|
|
4
|
+
export interface ActivityVisualSegment {
|
|
5
|
+
id: string;
|
|
6
|
+
start_ms: number;
|
|
7
|
+
end_ms: number;
|
|
8
|
+
duration_seconds: number;
|
|
9
|
+
state: ActivityVisualState;
|
|
10
|
+
valid: boolean;
|
|
11
|
+
system_signatures: string[];
|
|
12
|
+
observation_id: number | null;
|
|
13
|
+
continuity_id: number | null;
|
|
14
|
+
excluded_reason: null;
|
|
15
|
+
is_longest_active: boolean;
|
|
16
|
+
active_block_id: number | null;
|
|
17
|
+
}
|
|
18
|
+
export interface SystemContribution {
|
|
19
|
+
signature: string;
|
|
20
|
+
name: string;
|
|
21
|
+
kind: string;
|
|
22
|
+
active_seconds: number;
|
|
23
|
+
share: number;
|
|
24
|
+
}
|
|
25
|
+
export interface SystemActivitySummary extends SystemContribution {
|
|
26
|
+
state: AiActivityProduct['state'];
|
|
27
|
+
period_count: number;
|
|
28
|
+
longest_active_seconds: number;
|
|
29
|
+
first_observed_ms: number | null;
|
|
30
|
+
last_observed_ms: number | null;
|
|
31
|
+
current_cpu_percent: number | null;
|
|
32
|
+
current_memory_bytes: number | null;
|
|
33
|
+
current_process_count: number;
|
|
34
|
+
resource_observed_seconds: number;
|
|
35
|
+
resource_active_seconds: number;
|
|
36
|
+
avg_cpu_percent: number | null;
|
|
37
|
+
peak_cpu_percent: number | null;
|
|
38
|
+
avg_memory_bytes: number | null;
|
|
39
|
+
peak_memory_bytes: number | null;
|
|
40
|
+
peak_process_count: number;
|
|
41
|
+
resource_sample_count: number;
|
|
42
|
+
}
|
|
43
|
+
export interface CurrentAiResources {
|
|
44
|
+
cpu_percent: number | null;
|
|
45
|
+
memory_bytes: number | null;
|
|
46
|
+
process_count: number;
|
|
47
|
+
contributing_system_count: number;
|
|
48
|
+
measurement: 'current-detected-process-trees';
|
|
49
|
+
}
|
|
50
|
+
export type ResourceHistoryState = 'retained-local-buckets' | 'collecting' | 'not-retained';
|
|
51
|
+
export interface ResourceHistoryBucketView {
|
|
52
|
+
start_ms: number;
|
|
53
|
+
end_ms: number;
|
|
54
|
+
system_signature: string;
|
|
55
|
+
system_name: string;
|
|
56
|
+
kind: string;
|
|
57
|
+
observed_seconds: number;
|
|
58
|
+
active_seconds: number;
|
|
59
|
+
avg_cpu_percent: number | null;
|
|
60
|
+
peak_cpu_percent: number | null;
|
|
61
|
+
avg_memory_bytes: number | null;
|
|
62
|
+
peak_memory_bytes: number | null;
|
|
63
|
+
peak_process_count: number;
|
|
64
|
+
sample_count: number;
|
|
65
|
+
}
|
|
66
|
+
export interface SystemResourceHistorySummary {
|
|
67
|
+
signature: string;
|
|
68
|
+
name: string;
|
|
69
|
+
kind: string;
|
|
70
|
+
observed_seconds: number;
|
|
71
|
+
active_seconds: number;
|
|
72
|
+
avg_cpu_percent: number | null;
|
|
73
|
+
peak_cpu_percent: number | null;
|
|
74
|
+
avg_memory_bytes: number | null;
|
|
75
|
+
peak_memory_bytes: number | null;
|
|
76
|
+
peak_process_count: number;
|
|
77
|
+
sample_count: number;
|
|
78
|
+
}
|
|
79
|
+
export interface ResourceHistoryView {
|
|
80
|
+
buckets: ResourceHistoryBucketView[];
|
|
81
|
+
systems: SystemResourceHistorySummary[];
|
|
82
|
+
}
|
|
83
|
+
export type InsightEvidenceTarget = {
|
|
84
|
+
type: 'segment';
|
|
85
|
+
segment_id: string;
|
|
86
|
+
} | {
|
|
87
|
+
type: 'range';
|
|
88
|
+
start_ms: number;
|
|
89
|
+
end_ms: number;
|
|
90
|
+
} | {
|
|
91
|
+
type: 'system';
|
|
92
|
+
signature: string;
|
|
93
|
+
} | {
|
|
94
|
+
type: 'observation';
|
|
95
|
+
};
|
|
96
|
+
export interface ActivityInsightView extends LocalInsight {
|
|
97
|
+
evidence: InsightEvidenceTarget;
|
|
98
|
+
}
|
|
99
|
+
export interface ActivityExplorerViewModel {
|
|
100
|
+
segments: ActivityVisualSegment[];
|
|
101
|
+
contributions: SystemContribution[];
|
|
102
|
+
insights: ActivityInsightView[];
|
|
103
|
+
extent: {
|
|
104
|
+
start_ms: number;
|
|
105
|
+
end_ms: number;
|
|
106
|
+
} | null;
|
|
107
|
+
active_block_count: number;
|
|
108
|
+
longest_active_seconds: number;
|
|
109
|
+
longest_active_range: {
|
|
110
|
+
start_ms: number;
|
|
111
|
+
end_ms: number;
|
|
112
|
+
} | null;
|
|
113
|
+
idle_seconds: number;
|
|
114
|
+
excluded_seconds: number;
|
|
115
|
+
simultaneous_systems_max: number;
|
|
116
|
+
active_tool_count: number;
|
|
117
|
+
observation_ids: number[];
|
|
118
|
+
continuity_ids: number[];
|
|
119
|
+
available_date_keys: string[];
|
|
120
|
+
systems: SystemActivitySummary[];
|
|
121
|
+
current_resources: CurrentAiResources;
|
|
122
|
+
resource_history: ResourceHistoryView;
|
|
123
|
+
resource_history_state: ResourceHistoryState;
|
|
124
|
+
}
|
|
125
|
+
interface NormalizedSegment {
|
|
126
|
+
start_ms: number;
|
|
127
|
+
end_ms: number;
|
|
128
|
+
state: ActivityVisualState;
|
|
129
|
+
valid: boolean;
|
|
130
|
+
system_signatures: string[];
|
|
131
|
+
observation_id: number | null;
|
|
132
|
+
continuity_id: number | null;
|
|
133
|
+
excluded_reason: null;
|
|
134
|
+
}
|
|
135
|
+
export declare function mergeActivitySegments(segments: NormalizedSegment[], toleranceMs: number): NormalizedSegment[];
|
|
136
|
+
export declare function normalizeActivitySegments(timeline: ActivityTimelineSegment[], sampleIntervalMs: number): ActivityVisualSegment[];
|
|
137
|
+
export declare function calculateSystemContributions(products: AiActivityProduct[]): SystemContribution[];
|
|
138
|
+
export declare function buildResourceHistoryView(history?: ResourceHistoryBucket[]): ResourceHistoryView;
|
|
139
|
+
export declare function aggregateCurrentAiResources(products: AiActivityProduct[]): CurrentAiResources;
|
|
140
|
+
export declare function availableLocalDateKeys(segments: ActivityVisualSegment[], timeZone?: string): string[];
|
|
141
|
+
export declare function formatObservationDateRange(extent: {
|
|
142
|
+
start_ms: number;
|
|
143
|
+
end_ms: number;
|
|
144
|
+
} | null, locale: 'en' | 'de', timeZone?: string): string | null;
|
|
145
|
+
export declare function selectedTimeRange(segment: ActivityVisualSegment): {
|
|
146
|
+
start_ms: number;
|
|
147
|
+
end_ms: number;
|
|
148
|
+
duration_seconds: number;
|
|
149
|
+
};
|
|
150
|
+
export declare function resolveSelectedSystemSignature(view: Pick<ActivityExplorerViewModel, 'systems'>, selectedSignature: string | null): string | null;
|
|
151
|
+
export declare function insightEvidenceTarget(kind: LocalInsightKind, segments: ActivityVisualSegment[], contributions: SystemContribution[]): InsightEvidenceTarget;
|
|
152
|
+
export declare function buildActivityExplorerViewModel(snapshot: MonitorSnapshot, insights?: LocalInsight[]): ActivityExplorerViewModel;
|
|
153
|
+
export {};
|
|
154
|
+
//# sourceMappingURL=activity-view-model.d.ts.map
|