sessiongraph 1.0.1 → 1.0.3
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/README.md +5 -3
- package/dist/assets/gif-worker-CghHEBpp.js +1 -0
- package/dist/assets/index-Ca1o8F2F.js +167 -0
- package/dist/assets/index-DZ3QjOks.js +1 -0
- package/dist/assets/index-DmhroAg3.js +1 -0
- package/dist/assets/index-Oz3Ov7Mv.css +1 -0
- package/dist/assets/{index-Bn0u7W0k.js → index-ngj67_1P.js} +1 -1
- package/dist/assets/mp4-worker-HFPra5JP.js +1 -0
- package/dist/assets/scene-DpPyjrii.js +139 -0
- package/dist/assets/share-BDMRLovI.js +8 -0
- package/dist/assets/{three-B4kj4iLH.js → three-D_1Qt16u.js} +70 -70
- package/dist/index.html +2 -2
- package/dist-server/server.mjs +2298 -935
- package/docs/guide.md +19 -11
- package/docs/import-coverage.md +74 -0
- package/package.json +11 -7
- package/dist/assets/index-C9rv5Uuu.js +0 -163
- package/dist/assets/index-To7WPdy6.css +0 -1
- package/dist/assets/scene-DHluV79M.js +0 -49
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Geist Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/geist-latin-wght-normal-BgDaEnEv.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2) format("woff2"),url(/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff) format("woff");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2) format("woff2"),url(/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff) format("woff");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2) format("woff2"),url(/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff) format("woff");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2) format("woff2"),url(/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff) format("woff");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:IBM Plex Mono;font-style:normal;font-display:swap;font-weight:400;src:url(/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2) format("woff2"),url(/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff) format("woff");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{font-family:Geist Variable,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;color:#dbe7e3;background:#080e13;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;color-scheme:dark;--line: #c9e3db14;--muted: #82978f;--mint: #b0e9d6;--mono: "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;--control-bg: #122321;--control-border: #b0e9d626;--control-hover: #b0e9d610;--control-radius: 8px;--popover-bg: #0e1c20}*{box-sizing:border-box}html,body,#app{width:100%;height:100%;margin:0;overflow:hidden}#app{height:100dvh;isolation:isolate}button,input,select{font:inherit}button,a,input,select,summary{-webkit-tap-highlight-color:transparent}button{cursor:pointer;color:inherit;border:0;background:none;transition:background .18s,color .18s,border-color .18s}button:disabled{cursor:default;opacity:.45}a{color:inherit;text-decoration:none}button:focus-visible,a:focus-visible,select:focus-visible,input:focus-visible,summary:focus-visible{outline:2px solid #b0e9d6aa;outline-offset:3px}svg{width:16px;height:16px;flex-shrink:0}[hidden]{display:none!important}::selection{background:#b0e9d632;color:#f0fff8}::-webkit-scrollbar{width:4px;height:4px}::-webkit-scrollbar-thumb{background:#3a5149;border-radius:4px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.muted{color:var(--muted)}.map,#scene{position:absolute;inset:0}#scene canvas{display:block;width:100%;height:100%;touch-action:none}.canvas-vignette{position:absolute;inset:0;pointer-events:none;box-shadow:inset 0 0 150px 20px #04090d55}.glass{background:color-mix(in srgb,#0c161b var(--panel-opacity, 90%),transparent);border:1px solid #d6eee119;box-shadow:0 12px 48px #0003,inset 0 1px #ffffff04;backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px)}.app-header,.map-controls{position:fixed;top:24px;display:flex;align-items:center;gap:5px;height:48px;border-radius:14px;padding:5px 7px;z-index:40}.app-header{left:24px;padding-left:13px;gap:10px}.brand{display:flex;align-items:center;gap:8px}.brand img{width:24px;height:24px}.brand>span{font-size:21px;font-weight:510;letter-spacing:-1px;line-height:1;white-space:nowrap}.brand-dot{color:var(--mint)}.connection{display:flex;align-items:center}.status-dot{width:5px;height:5px;border-radius:50%;background:#d6b578}.connected .status-dot{background:#a9d9c5;box-shadow:0 0 8px #b0e9d630}.toolbar-divider{width:1px;height:18px;background:var(--line);margin:0 3px}.toolbar-button{display:flex;align-items:center;gap:7px;padding:9px 10px;border-radius:8px;font-size:12px;color:#9eafa9}.toolbar-button:hover,.icon-button:hover{background:#c2e9d90c;color:#e9fff4}.toolbar-button[aria-expanded=true],.map-controls .icon-button[aria-expanded=true]{background:#b0e9d60c;color:var(--mint)}.icon-button{width:34px;height:34px;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center;border-radius:8px;color:#8ba198}.map-controls{right:24px}.view-switch{display:flex;gap:2px}.view-switch button{min-width:37px;padding:9px 8px;border-radius:8px;font-size:12px;color:#7d9489}.view-switch .active{color:#d4f6e7;background:#b0e9d614}.floating-panel{position:fixed;z-index:10;border-radius:16px;animation:panel-in .2s ease-out}.floating-panel.front{z-index:20}.panel-heading{display:flex;align-items:center;padding:10px 10px 8px 16px;gap:3px;flex-shrink:0}.panel-handle{display:flex;align-items:center;gap:8px;flex:1;min-width:0;padding:8px 0;text-align:left;cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none;font-size:13px;font-weight:480;color:#bdcec6}.panel-handle>svg{width:13px;height:13px;color:#597368}.panel-handle:hover>svg{color:#b0e9d6}.dragging{-webkit-user-select:none;user-select:none;box-shadow:0 20px 80px #0006}.dragging .panel-handle{cursor:grabbing}.small-badge{font:10px var(--mono);font-weight:400;color:#879f93;margin-left:2px}.sidebar{top:86px;left:24px;width:330px;height:min(580px,calc(100dvh - 230px));max-height:calc(100dvh - 100px);display:flex;flex-direction:column;overflow:hidden}.search-box{display:flex;align-items:center;gap:9px;margin:3px 16px 0;padding:10px 11px;background:#d5f6e703;border:1px solid #d1e9dc16;border-radius:9px;color:#7c9588}.search-box:focus-within{border-color:#b0e9d650}.search-box svg{width:14px;height:14px}.search-trigger{text-align:left;font-size:12px}.search-trigger span{flex:1}.search-trigger:hover{border-color:#b0e9d644;color:#d1ecdf}.search-box input{width:100%;min-width:0;background:none;border:0;outline:none;color:#e3ece9;font-size:12px}.search-box input::placeholder{color:#7f948a}kbd{border:1px solid #c4e1d71c;border-radius:4px;padding:2px 5px;font:11px var(--mono);color:#8fa69a}.filters{padding:16px;border-bottom:1px solid var(--line)}.filter-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}.select-wrap{display:flex;align-items:center;position:relative;min-width:0;margin-bottom:8px;color:#8ea99b}.filter-row>.select-wrap{flex:1;margin-bottom:0}.select-wrap>svg,.select-wrap>#source-filter-icon{pointer-events:none;position:absolute;left:9px;width:14px;height:14px}.select-wrap>svg:last-child{left:auto;right:9px;width:12px}.select-wrap select{appearance:none;width:100%;min-width:0;height:34px;padding:7px 29px 7px 32px;background:transparent;color:#bdcfc6;border:1px solid transparent;border-radius:8px;font-size:12px;cursor:pointer;text-overflow:ellipsis}.select-wrap:hover select{background:#b0e9d606}.select-wrap select:focus-visible{outline:2px solid #b0e9d680;outline-offset:0;background:#b0e9d609}#source-filter-icon .source-icon{width:14px;height:14px;flex-basis:14px}select option{background:#14211e;color:#e1e8ea}.filter-toggles{display:flex;gap:18px;margin-top:16px}.filter-toggles label{display:flex;align-items:center;gap:6px;font-size:11px;color:#91a99b;cursor:pointer}.filter-toggles input{width:12px;height:12px;margin:0;accent-color:#a0c9ba}.session-list{padding:0 8px 10px;flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain}.list-date{display:flex;gap:7px;padding:17px 12px 8px;font-size:11px;color:#8ca196}.list-date span{color:#647e70}.session-card{width:100%;display:flex;text-align:left;gap:10px;padding:11px 12px;border:1px solid transparent;border-radius:9px;margin-bottom:2px}.session-card:hover{background:#dbf5e805}.session-card.selected{background:#b0e9d60b;border-color:#b0e9d61a}.session-dot{width:5px;height:5px;margin-top:6px;flex-shrink:0;border-radius:50%;background:var(--node-color, #b0e9d6);box-shadow:0 0 7px color-mix(in srgb,var(--node-color, #b0e9d6) 25%,transparent)}.session-card-body{flex:1;min-width:0}.session-title{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:12px;font-weight:420;line-height:1.55;color:#bccfc5}.selected .session-title{color:#e1f2eb}.session-meta{display:flex;align-items:center;gap:5px;margin-top:6px;font-size:10px;color:#748e7f}.session-meta svg{width:11px;height:11px}.session-meta span:first-of-type{max-width:125px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.session-meta span:last-child{margin-left:auto;white-space:nowrap}.timeline-panel{bottom:24px;left:50%;transform:translate(-50%);width:min(620px,calc(100% - 48px));padding:9px 14px 18px}.timeline-top{display:flex;align-items:center;gap:4px;margin-bottom:14px}.timeline-top .panel-handle{font-size:12px;font-weight:400;white-space:nowrap}.range-buttons{display:flex;gap:2px;margin-left:8px}.range-buttons button{font-size:11px;color:#859d8e;border-radius:6px;padding:6px 8px}.range-buttons button:hover{color:var(--mint)}.range-buttons button.active{color:var(--mint);background:#b0e9d613}.timeline-track{display:flex;align-items:center;gap:15px}.play-button{width:32px;height:32px;flex-shrink:0;display:flex;align-items:center;justify-content:center;border:1px solid #b0e9d62b;border-radius:50%;color:var(--mint);background:#b0e9d604}.play-button:hover{background:#b0e9d613}.play-button svg{width:13px;height:13px}.histogram-wrap{flex:1;position:relative;height:30px;border-bottom:1px solid #b0e9d620}.histogram{display:flex;align-items:flex-end;height:100%;gap:3px;-webkit-mask-image:linear-gradient(to right,black var(--progress, 100%),#ffffff30 var(--progress, 100%));mask-image:linear-gradient(to right,black var(--progress, 100%),#ffffff30 var(--progress, 100%))}.histogram span{flex:1;min-width:0;background:linear-gradient(#a6d5c7ba,#61887d35);border-radius:2px 2px 0 0}#scrubber{appearance:none;position:absolute;inset:-6px -7px;margin:0;width:calc(100% + 14px);height:calc(100% + 12px);background:transparent;cursor:ew-resize}#scrubber::-webkit-slider-thumb{appearance:none;width:12px;height:40px;opacity:0}#scrubber::-moz-range-thumb{width:12px;height:40px;opacity:0}.timeline-cursor{pointer-events:none;position:absolute;top:-3px;bottom:-2px;width:1px;background:#d3eee0;box-shadow:0 0 8px #b0e9d640}.timeline-cursor:before{content:"";position:absolute;top:-2px;left:-2px;width:5px;height:5px;background:var(--mint);border-radius:50%}.playback-date{width:43px;text-align:right;white-space:nowrap;font-size:11px;color:#9ab1a3}.custom-dates{position:relative}summary{cursor:pointer;list-style:none}summary::-webkit-details-marker{display:none}.date-positioner,.ui-select-positioner{margin:0;padding:0;border:0;background:transparent;color:inherit;overflow:visible;z-index:150}.date-popover{width:min(344px,calc(100vw - 24px));max-height:min(570px,calc(100dvh - 24px));overflow:auto;padding:18px;border:1px solid var(--control-border);border-radius:16px;background:var(--popover-bg);box-shadow:0 20px 70px #0008,inset 0 1px #ffffff05}.date-heading{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px}.date-heading .eyebrow{font:8px var(--mono);letter-spacing:.14em;color:#789e8d}.date-heading h2{margin:5px 0 0;font-size:18px;font-weight:500;letter-spacing:-.5px}.date-close{font-size:23px}.date-fields{display:flex;align-items:center;gap:10px}.date-fields>span{padding-top:16px;color:#5f8072}.date-fields label{flex:1;min-width:0;color:#8aa79a;font-size:10px}.date-fields input{display:block;width:100%;margin-top:6px;padding:10px;border:1px solid var(--control-border);border-radius:var(--control-radius);background:#070f1380;color:#d4e8df;font:11px var(--mono)}.date-fields input:focus{border-color:#b0e9d670}.date-fields input[aria-invalid=true]{border-color:#eab894}.date-presets{display:flex;gap:6px;margin:12px 0 16px}.date-presets button{flex:1;padding:7px 4px;border:1px solid var(--control-border);border-radius:6px;color:#9ebcae;font-size:10px}.date-presets button:hover{background:var(--control-hover);color:var(--mint)}.date-calendar{padding-top:10px;border-top:1px solid var(--line)}.date-navigation{display:flex;align-items:center;gap:8px;margin-bottom:9px}.date-view{flex:1;padding:8px;border-radius:var(--control-radius);font-size:13px;font-weight:500}.date-view:hover{background:var(--control-hover)}.date-calendar table{width:100%;table-layout:fixed;border-spacing:0 3px;font-size:12px}.date-calendar th{padding-bottom:10px;color:#729183;font-size:10px;font-weight:400}.date-calendar td{padding:0;text-align:center}.date-calendar td button{width:100%;height:34px;border-radius:7px;font-size:11px;color:#c6dacf;position:relative}.date-calendar td button:hover{background:#b0e9d61c}.date-calendar td button[data-outside-range]{color:#50675e}.date-calendar td button[data-in-range],.date-calendar td button[data-in-hover-range]{background:#b0e9d610;border-radius:0;color:#c8e7d9}.date-calendar td button[data-range-start],.date-calendar td button[data-range-end]{border-radius:7px;color:#10251e;background:var(--mint);font-weight:600}.date-calendar td button[data-today]:after{content:"";position:absolute;width:3px;height:3px;bottom:4px;left:calc(50% - 1.5px);border-radius:50%;background:currentColor}.date-calendar td button:focus-visible{outline-offset:-2px;z-index:1}.date-calendar table:not([data-calendar-view=day]) td{padding:3px}.date-calendar table:not([data-calendar-view=day]) button{height:47px}.date-footer{display:flex;align-items:center;gap:12px;border-top:1px solid var(--line);margin-top:12px;padding-top:14px}.date-status{flex:1;color:#7f9d8f;font-size:10px;line-height:1.6}.date-footer .primary-button{flex:0 0 auto;font-size:11px}.ui-select{display:inline-flex;min-width:0;position:relative}.ui-select-trigger{display:inline-flex;align-items:center;justify-content:space-between;gap:10px;width:100%;min-width:0;min-height:34px;padding:8px 10px;border:1px solid var(--control-border);border-radius:var(--control-radius);background:var(--control-bg);color:#c7dfd2;font-size:12px;text-align:left}.ui-select-trigger>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-select-trigger>svg{width:12px;height:12px;color:#7f9d90}.ui-select-trigger:hover,.ui-select-trigger[data-state=open]{background:var(--control-hover);border-color:#b0e9d645}.ui-select-menu{min-width:max(150px,var(--reference-width));max-width:min(400px,calc(100vw - 24px));max-height:min(300px,var(--available-height, 300px));overflow:auto;padding:5px;border:1px solid var(--control-border);border-radius:10px;background:var(--popover-bg);box-shadow:0 12px 40px #0007;outline:none}.ui-select-option{position:relative;padding:9px 30px 9px 10px;border-radius:6px;color:#a8c3b5;font-size:12px;line-height:1.5;cursor:pointer;overflow-wrap:anywhere}.ui-select-option[data-highlighted]{color:#e0f4e9;background:var(--control-hover)}.ui-select-option[data-state=checked]{color:var(--mint)}.ui-select-option[data-state=checked]:after{content:"✓";position:absolute;right:10px}.ui-select-option[data-disabled]{opacity:.4;cursor:default}.select-wrap .ui-select{width:100%}.select-wrap>svg,.select-wrap>#source-filter-icon{z-index:1}.select-wrap>svg:last-child{display:none}.select-wrap .ui-select-trigger{padding-left:32px;background:transparent;border-color:transparent}.select-wrap .ui-select-trigger:hover,.select-wrap .ui-select-trigger[data-state=open]{background:#b0e9d609}.setting-row>.ui-select{min-width:120px;max-width:180px}.setting-row .ui-select-trigger{font-size:11px}.search-options .ui-select-trigger{background:transparent;border-color:transparent;padding-left:0;min-height:28px}.launch-destination .ui-select{max-width:77%}.inspector-stack{top:86px;right:24px;width:360px;max-height:calc(100dvh - 230px);display:flex;flex-direction:column;gap:12px;pointer-events:none}.inspector-stack>aside{pointer-events:auto;border-radius:16px}.inspector-stack.has-events{height:calc(100dvh - 110px);max-height:calc(100dvh - 110px)}.inspector{min-height:0;display:flex;flex-direction:column;overflow:hidden}.has-events .inspector{flex:0 1 220px;max-height:32%}.has-events .detail-title h2{font-size:17px}.detail-scroll{overflow-y:auto;min-height:0;overscroll-behavior:contain}.detail-title{padding:3px 20px 0}.detail-title h2{font-size:20px;line-height:1.4;letter-spacing:-.45px;font-weight:460;color:#e2ede9;margin:0 0 10px;overflow-wrap:anywhere}.detail-date{font-size:11px;color:#8ba699}.detail-actions{display:flex;align-items:center;gap:9px;padding:17px 20px}.secondary-button,.primary-button{display:flex;align-items:center;justify-content:center;gap:7px;padding:9px 12px;border:1px solid #b0e9d625;border-radius:8px;font-size:12px;color:#b8d9c7;background:#b0e9d606;flex:1}.secondary-button:hover{background:#b0e9d610}.secondary-button svg{width:14px;height:14px}.primary-button{flex:0;background:#b0e9d6;color:#182e29}.text-button{display:inline-flex;align-items:center;gap:7px;padding:8px;font-size:12px;color:#a6c9b6}.detail-section{border-top:1px solid var(--line);padding:17px 20px}.section-label{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-size:12px;font-weight:450;color:#b3c8bc}.section-label>span{margin-left:auto;font:11px var(--mono);color:#8ca896}.file-list{list-style:none;margin:0;padding:0}.file-list li{display:flex;align-items:center;gap:9px;padding:9px 0;border-bottom:1px solid #d1f1df07}.file-list li>svg{width:14px;height:14px;color:#c2b08f}.file-list li>div{flex:1;min-width:0}.file-list strong{display:block;font:11px var(--mono);color:#c7dbcf;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-list li span{display:block;margin-top:4px;font-size:11px;color:#7d9988;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.file-list small{font:10px var(--mono);color:#89a994}.coverage-note{font-size:11px;line-height:1.7;color:#8ba597;margin:14px 0 0}.no-files p{font-size:12px;color:#8ca698;margin:0}.detail-loading{display:flex;align-items:center;gap:8px;font-size:12px;color:#97b6a4}.detail-loading svg{width:14px;height:14px}.load-more{display:flex;align-items:center;justify-content:center;gap:7px;width:100%;margin-top:14px;padding:10px;border:1px solid #b0e9d61c;border-radius:8px;font-size:11px;color:#a2cbb3}.load-more:hover{background:#b0e9d609}.load-more svg{width:13px;height:13px}.relation{display:flex;align-items:center;gap:10px;width:100%;padding:10px 0;text-align:left;border-bottom:1px solid #d1f1df07}.relation>svg{width:14px;height:14px;color:#b6a3d9}.relation>svg:last-child{width:12px;color:#7c9788;margin-left:auto}.relation>span{min-width:0}.relation small{display:block;font-size:11px;color:#8fa598;margin-bottom:4px}.relation strong{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:12px;line-height:1.5;font-weight:400;color:#bdd1c7}.relation:hover strong{color:#e2f6e9}.more-details summary{display:flex;align-items:center;gap:8px;font-size:12px;color:#9ab4a3}.more-details summary>span{margin-left:auto;font:11px var(--mono)}.more-details summary svg{width:13px;height:13px;margin-left:auto}.more-details[open] summary{margin-bottom:14px;color:#c6e0ce}.more-details[open] summary svg{transform:rotate(180deg)}.metadata{margin:0;font-size:12px}.metadata>div{display:flex;justify-content:space-between;gap:15px;padding:7px 0}.metadata dt{color:#829e8d;flex-shrink:0}.metadata dd{margin:0;text-align:right;overflow-wrap:anywhere;font:11px var(--mono);color:#c1d7cc}.directory-card{margin-top:13px;padding:12px;border:1px solid var(--line);border-radius:8px}.directory-card>span{font-size:11px;color:#93b19e}.directory-card code,.location-entry code{display:block;margin-top:6px;font:11px/1.7 var(--mono);color:#8eaa9a;overflow-wrap:anywhere}.location-entry{margin-top:14px}.location-entry>span{font-size:11px;color:#afc9b8}.tools-list>div{display:flex;justify-content:space-between;gap:12px;padding:6px 0;font:11px var(--mono)}.tools-list span{overflow-wrap:anywhere;color:#91af9b}.tools-list strong{font-weight:400;color:#b4cebe}.scene-labels{position:absolute;inset:0;pointer-events:none;overflow:hidden}.scene-label{position:absolute;left:0;top:0;max-width:155px;padding:5px 8px;font:10px var(--mono);color:var(--label-color);opacity:0;filter:blur(3px);transition:opacity .45s ease,filter .45s ease;background:#080f1266;border-radius:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.scene-label.visible{opacity:.55;filter:blur(0)}.selected-label{width:260px;max-width:calc(100% - 24px);padding:7px 10px;font-size:11px;background:#0d1c22ed;border:1px solid #b0e9d62b;border-radius:6px;box-shadow:0 3px 15px #0005;z-index:1}.selected-label.visible{opacity:1}.event-marker-icon{position:absolute;top:0;left:0;width:12px;height:12px;color:#d7e5df;opacity:0;pointer-events:none}.event-marker-icon.visible{opacity:.38}.event-marker-icon svg{display:block;width:12px;height:12px}.scene-labels[data-motion=false] .scene-label{transition:none}.node-tooltip{position:absolute;z-index:30;width:260px;padding:14px;background:#101e1cf2;border:1px solid #b0e9d62b;border-radius:10px;box-shadow:0 12px 32px #0006;pointer-events:none;-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px)}.node-tooltip strong{display:block;font-size:13px;font-weight:450;line-height:1.5;color:#e1efec;margin-bottom:7px}.node-tooltip>span{font-size:11px;color:#91af9d}.message-tooltip{width:min(390px,calc(100vw - 24px));border-color:color-mix(in srgb,var(--event-color) 35%,transparent)}.message-tooltip pre{margin:10px 0;white-space:pre-wrap;overflow-wrap:anywhere;font:12px/1.7 var(--mono);color:#d9e9e0;max-height:min(280px,38dvh);overflow:hidden}.message-tooltip>span{display:block;font-size:10px;line-height:1.6}.graph-message{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;background:#080e1333;padding:32px;text-align:center}.graph-message>svg{width:28px;height:28px;color:var(--mint)}.graph-message h3{font-size:18px;font-weight:450;margin:18px 0;color:#cde1d7}.graph-message p{max-width:350px;font-size:13px;line-height:1.8;color:#91b09f}.loading-orbit{position:relative;width:64px;height:64px}.loading-orbit span{position:absolute;inset:0;border:1px solid #b0e9d629;border-radius:50%;transform:rotateX(55deg) rotateY(20deg);animation:orbit 3s linear infinite}.loading-orbit span:nth-child(2){animation-delay:-.8s}.loading-orbit span:nth-child(3){animation-delay:-1.6s}.empty-list{padding:20px 12px;font-size:12px;line-height:1.8;color:#86a593}.list-loading{padding:22px 8px}.skeleton{height:48px;margin-bottom:20px;border-radius:8px;background:linear-gradient(100deg,#ffffff02,#ffffff05,#ffffff02);background-size:200%;animation:shimmer 2s infinite}.spinning>svg,svg.spinning{animation:spin 2s linear infinite}dialog{max-width:420px;width:calc(100% - 32px);max-height:calc(100dvh - 40px);background:#101d1cf7;color:#d1e2dc;border:1px solid #b0e9d62b;border-radius:18px;padding:28px;box-shadow:0 25px 100px #0009}dialog::backdrop{background:#02070c88;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.dialog-close{position:absolute;top:12px;right:12px}dialog h2{font-size:22px;font-weight:450;letter-spacing:-.5px;margin:0 0 18px}dialog p{font-size:12px;line-height:1.8;color:#92ad9e;margin:18px 0}.help-rows>div{display:flex;justify-content:space-between;align-items:center;padding:9px 0;font-size:12px;border-bottom:1px solid var(--line)}.graph-legend{display:flex;flex-wrap:wrap;gap:13px 18px;margin-top:22px;font-size:12px;color:#a5c2b0}.graph-legend>span{display:flex;align-items:center;gap:7px}.legend-node{width:5px;height:5px;border-radius:50%;background:var(--mint)}.legend-node.message{width:3px;height:3px;background:#dcfff0}.legend-file{width:5px;height:5px;background:#edc899;transform:rotate(45deg)}.legend-line{width:14px;height:1px}.legend-line.fork{background:#edbc8d}.legend-line.child{background:#bda6ef}.legend-line.lane{background:#849d95}.motion-button{width:100%}.motion-button[aria-pressed=false]{color:#728b7e;background:transparent}html[data-density=compact] .session-card{padding-block:6px}html[data-density=compact] .session-title{-webkit-line-clamp:1}html[data-density=compact] .list-date{padding-top:12px}html[data-motion=false] *,html[data-motion=false] *:before,html[data-motion=false] *:after{animation-duration:.01ms!important;transition-duration:.01ms!important}.event-panel{flex:1;min-height:0;display:flex;flex-direction:column;overflow:hidden}.event-heading{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 10px 2px 18px}.event-heading h2{margin:0;font-size:13px;font-weight:480;color:#bdcec6}.event-close{font-size:22px}.event-toolbar{display:flex;align-items:center;gap:12px;padding:12px 0;font-size:11px}.event-toolbar label{display:flex;align-items:center;gap:10px}.event-toolbar select{padding:8px;border:1px solid #b0e9d630;border-radius:6px;background:#142620;color:#d0e6da;max-width:180px}.event-count{color:#adc6b8;font:9px var(--mono);margin-left:8px}.event-scroll{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain}.event-browser{margin:0 16px 16px;border-top:1px solid var(--line);padding-top:12px}.event-browser summary,.event-footer summary{cursor:pointer;font-size:11px;color:#9ab4a3}.event-browser>summary,.event-footer summary,.event-provenance>summary{display:flex;align-items:center;gap:8px}.event-browser>summary:after,.event-footer summary:after,.event-provenance>summary:after{content:"";width:6px;height:6px;flex-shrink:0;margin-left:auto;margin-right:3px;border-right:1px solid currentColor;border-bottom:1px solid currentColor;transform:translateY(-2px) rotate(45deg)}.event-browser[open]>summary:after,.event-footer details[open]>summary:after,.event-provenance[open]>summary:after{transform:translateY(2px) rotate(225deg)}.event-list{max-height:230px;overflow:auto;overscroll-behavior:contain}.event-row{display:block;width:100%;padding:10px;margin-bottom:5px;border:1px solid transparent;border-radius:9px;text-align:left}.event-row:hover{background:#b0e9d608}.event-row[aria-current=true]{background:#b0e9d610;border-color:#b0e9d635}.event-row-top{display:flex;align-items:center;justify-content:space-between;gap:5px;margin-bottom:8px}.event-row-top small{color:#7e9c8a;font:9px var(--mono)}.event-badge{font:10px var(--mono);color:var(--event-color);display:inline-flex;align-items:center;gap:7px}.event-badge:before{content:"";width:7px;height:7px;border-radius:50%;background:var(--event-color);flex-shrink:0}.event-row strong{display:block;font-size:12px;font-weight:480;color:#d2e4da;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.event-preview{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:11px;color:#8aa798;line-height:1.6;margin:6px 0;overflow-wrap:anywhere}.event-row time{font:9px var(--mono);color:#6f9380}.event-pagination{display:flex;justify-content:space-between;gap:10px;padding-top:10px;border-top:1px solid var(--line)}.event-pagination button{font-size:10px}.event-content{padding:16px;min-width:0}.event-detail-nav{display:flex;align-items:center;gap:8px;padding:8px 16px 12px;border-bottom:1px solid var(--line)}.event-detail-nav>span{font:9px var(--mono);color:#92ad9e;text-align:center}.event-detail-nav button{font-size:11px;padding:7px 9px}.event-detail-heading h3{font-size:18px;font-weight:450;letter-spacing:-.4px;overflow-wrap:anywhere;margin:10px 0}.event-detail-heading p{color:#7f9f8c;font:10px var(--mono);line-height:1.6}.event-status{display:inline-block;margin-left:12px;color:#9ab7a6;font:9px var(--mono);border:1px solid #b0e9d629;padding:4px 7px;border-radius:4px}.event-status.failed{color:#eeaa9d;border-color:#eeaa9d40}.event-payload{margin-top:18px}.event-content h4{font:10px var(--mono);text-transform:uppercase;letter-spacing:.1em;color:#8aa997;margin:0 0 12px}.event-payload pre{margin:0;white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.8 var(--mono);color:#d4e6db;padding:12px;border:1px solid #b0e9d619;border-radius:9px;background:#050e123d;tab-size:2}.event-warning{padding:12px;background:#eac5940a;border:1px solid #eac59430;border-radius:7px;font-size:11px;color:#d6bc97}.event-correlations{margin-top:20px}.event-correlations p{font-size:11px;color:#91a999}.event-link{display:flex;align-items:center;gap:9px;padding:10px;width:100%;border:1px solid var(--line);border-radius:7px;margin-bottom:6px;text-align:left}.event-link>span:nth-child(2){flex:1;overflow-wrap:anywhere;font-size:12px}.event-link small{font:9px var(--mono);color:#8ca594}.event-provenance{margin-top:18px;font-size:11px;color:#7e9d8b}.event-provenance summary{cursor:pointer;padding-block:10px}.event-provenance dl{display:grid;grid-template-columns:90px minmax(0,1fr);gap:10px}.event-provenance dd{margin:0;overflow-wrap:anywhere;font-family:var(--mono);font-size:10px}.event-footer{display:flex;align-items:center;gap:12px;padding:8px 16px;border-top:1px solid var(--line);background:#081216}.event-footer>details{flex:1}.event-coverage{font-size:10px;line-height:1.6;color:#7d9c8b;max-height:70px;overflow:auto}.event-reload{font-size:11px;white-space:nowrap}.event-empty{padding:24px 12px;color:#90aa9c;font-size:12px;line-height:1.7}.event-panel button:disabled{opacity:.4;cursor:default}.event-panel[aria-busy=true] .event-scroll{opacity:.65}.event-key{display:flex;flex-wrap:wrap;gap:12px;margin:14px 0}.event-key span{font:9px var(--mono)}.event-key i{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;background:var(--event-color)}.explore-events{width:100%;justify-content:center;margin-top:10px}.history-coverage{margin-top:16px;padding-top:12px;border-top:1px solid var(--line)}.history-coverage>summary{min-height:24px;border-radius:4px}.settings-dialog{width:min(850px,calc(100% - 32px));max-width:none;height:min(710px,calc(100dvh - 48px));padding:0;overflow:hidden;background:#0c191e}.settings-dialog[open]{display:flex;flex-direction:column}.settings-heading{display:flex;align-items:flex-start;justify-content:space-between;padding:30px 30px 24px;border-bottom:1px solid var(--line);background:radial-gradient(ellipse at top left,#28534a44,transparent 70%)}.settings-heading h2{margin:0 0 4px;font-size:27px;letter-spacing:-.8px}.settings-heading p{margin:0;font-size:12px;color:#87a69a}.settings-close{font-size:25px;margin:-10px -12px 0 0}.settings-layout{display:grid;grid-template-columns:175px minmax(0,1fr);flex:1;min-height:0}.settings-tabs{padding:20px 12px;border-right:1px solid var(--line);background:#040b0e33}.settings-tabs button{display:flex;align-items:center;gap:10px;width:100%;padding:12px;margin-bottom:5px;text-align:left;font-size:12px;border-radius:8px;color:#8aa79a}.settings-tabs button>svg{width:16px;height:16px;color:#6b9582}.settings-tabs button[aria-selected=true]{color:#d5eee2;background:#b0e9d610}.settings-tabs button[aria-selected=true]>svg{color:#b0e9d6}.settings-tabs button:hover{background:#b0e9d609}.settings-content{min-width:0;overflow-y:auto;overscroll-behavior:contain;padding:26px 30px}.settings-content h3{font-size:18px;font-weight:450;margin:0 0 7px;letter-spacing:-.4px}.settings-description{margin:0 0 20px;font-size:12px}.settings-sources-list{margin-top:20px;color:var(--muted);font-size:12px}.settings-import-progress{color:var(--muted);font-size:11px;line-height:1.6;margin-top:16px}.setting-row{display:flex;align-items:center;justify-content:space-between;gap:22px;padding:16px 0;border-bottom:1px solid var(--line)}.setting-row>span:first-child{flex:1;min-width:0}.setting-row strong{display:block;font-size:12px;font-weight:470;color:#d1e3d9}.setting-row small{display:block;margin-top:5px;font-size:11px;line-height:1.55;color:#83a090}.setting-row select{max-width:165px;min-width:120px;padding:9px;border:1px solid #b0e9d621;border-radius:7px;background:#142620;color:#c7dfd2;font-size:11px}.setting-row input[type=checkbox]{appearance:none;flex-shrink:0;position:relative;width:34px;height:20px;margin:0;border-radius:20px;border:1px solid #779c8b40;background:#1c2e28;cursor:pointer}.setting-row input[type=checkbox]:before{content:"";position:absolute;width:12px;height:12px;top:3px;left:3px;border-radius:50%;background:#718f80;transition:transform .18s,background .18s}.setting-row input[type=checkbox]:checked{background:#b0e9d625;border-color:#b0e9d64a}.setting-row input[type=checkbox]:checked:before{transform:translate(14px);background:#b0e9d6}.setting-slider{display:flex;align-items:center;width:160px;gap:10px;flex-shrink:0}.setting-slider input{accent-color:#b0e9d6;width:108px;min-width:0;cursor:pointer}.setting-slider output{min-width:36px;font:10px var(--mono);color:#bddaca;text-align:right}.setting-row:has(:disabled){opacity:.45}.settings-note{display:flex;align-items:center;gap:14px;margin-top:22px}.settings-note>span{flex:1;font-size:11px;color:#85a495;line-height:1.6}.settings-note button{flex:0 0 auto;font-size:11px}.settings-footnote{font-size:10px;color:#6f9280;margin-bottom:0}.settings-footer{display:flex;align-items:center;gap:12px;padding:15px 22px;border-top:1px solid var(--line);background:#081216}.settings-save-status{flex:1;font-size:10px;color:#7d9c8b;line-height:1.5}.settings-footer .text-button{font-size:11px}.settings-footer .primary-button{padding-inline:20px}@media(max-width:650px){.settings-dialog{width:calc(100% - 20px);height:calc(100dvh - 24px);max-height:none}.settings-heading{padding:23px 20px 18px}.settings-heading h2{font-size:23px}.settings-layout{display:flex;flex-direction:column}.settings-tabs{display:flex;padding:9px;border-right:0;border-bottom:1px solid var(--line);overflow-x:auto;flex-shrink:0}.settings-tabs button{width:auto;flex:1 0 auto;margin:0;padding:9px 11px;font-size:11px;justify-content:center}.settings-tabs button>svg{width:14px;height:14px}.settings-content{padding:22px 18px}.setting-row{gap:12px}.setting-slider{width:128px}.setting-slider input{width:78px}.setting-row select{min-width:100px;max-width:135px}.settings-footer{flex-wrap:wrap;padding:12px 18px}.settings-save-status{flex-basis:100%}.settings-footer .text-button{margin-right:auto}}.toast{position:fixed;left:50%;bottom:155px;transform:translate(-50%);max-width:min(440px,calc(100% - 32px));padding:12px 18px;background:#15251ff5;color:#c8e5d4;border:1px solid #9fbfad44;border-radius:10px;box-shadow:0 10px 30px #0005;font-size:12px;line-height:1.7;z-index:100}.desktop-update{position:fixed;left:24px;bottom:24px;z-index:45;display:inline-flex;align-items:center;justify-content:center;gap:7px;min-height:32px;min-width:86px;padding:6px 12px;border-radius:10px;color:var(--mint);font-size:11px;font-weight:450;line-height:18px;white-space:nowrap}.desktop-update svg{width:13px;height:13px}.desktop-update:hover{background:#172c29;border-color:#b0e9d633;color:#e9fff4}.desktop-update:disabled{opacity:1;color:#8ba198}.desktop-update[data-phase=downloading] svg,.desktop-update[data-phase=installing] svg{opacity:.65}.shortcut-hints{position:fixed;left:24px;bottom:24px;z-index:10;display:grid;gap:7px;color:#82938f;font-size:10px;pointer-events:none}.shortcut-hints span{display:flex;align-items:center;gap:8px}.shortcut-hints kbd{min-width:22px;padding:2px 4px;border:1px solid #a3bdb523;border-radius:4px;color:#a3b5ae;background:#0b141b66;font:9px var(--mono);text-align:center}#app:has(.desktop-update:not([hidden])) .shortcut-hints{bottom:66px}@media(min-width:760px)and (max-width:1000px){.shortcut-hints{bottom:165px}#app:has(.desktop-update:not([hidden])) .shortcut-hints{bottom:165px}}@keyframes panel-in{0%{opacity:0}to{opacity:1}}@keyframes orbit{to{transform:rotateX(55deg) rotateY(20deg) rotate(360deg)}}@keyframes shimmer{to{background-position:-200% 0}}@keyframes spin{to{transform:rotate(360deg)}}@media(max-width:1000px){.sidebar{width:300px}.inspector-stack{width:320px}}@media(max-width:759px){.shortcut-hints{display:none}.app-header{top:12px;left:12px;height:44px}.brand>span{font-size:19px}.app-header .toolbar-button{padding-inline:7px}.map-controls{top:auto;right:auto;left:50%;bottom:max(12px,env(safe-area-inset-bottom));transform:translate(-50%);height:46px}.floating-panel{border-radius:14px}.sidebar,.inspector-stack{top:70px;left:12px;right:auto;width:min(330px,calc(100% - 24px));max-height:calc(100dvh - 280px)}.sidebar{height:min(500px,calc(100dvh - 280px))}.inspector-stack{width:min(350px,calc(100% - 24px));left:auto;right:12px}.inspector-stack.has-events{top:auto;bottom:230px;height:min(420px,50dvh);max-height:calc(100dvh - 310px);gap:8px}.has-events .inspector{flex-basis:135px;max-height:26%}.event-content{padding:12px}.event-detail-heading h3{font-size:16px}.timeline-panel{bottom:max(72px,calc(env(safe-area-inset-bottom) + 60px));width:calc(100% - 24px);padding:9px 12px 15px}.timeline-top{flex-wrap:wrap;gap:0;margin-bottom:13px}.timeline-top .panel-handle{flex-basis:calc(100% - 72px);font-size:12px}.timeline-top .range-buttons{order:4;width:100%;margin:4px 0 0;gap:5px}.range-buttons button{padding:5px 12px}.timeline-top .icon-button{width:32px;height:32px}.timeline-track{gap:12px}.histogram{gap:2px}.toast{bottom:230px}.desktop-update{left:12px;bottom:max(72px,calc(env(safe-area-inset-bottom) + 60px))}#app:has(.desktop-update:not([hidden])) .timeline-panel{bottom:max(112px,calc(env(safe-area-inset-bottom) + 100px))}#app:has(.desktop-update:not([hidden])) .inspector-stack.has-events{bottom:270px}}@media(min-width:760px)and (max-height:600px){.sidebar,.inspector-stack,.inspector-stack.has-events{max-height:calc(100dvh - 100px)}.sidebar{height:calc(100dvh - 100px)}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;transition-duration:.01ms!important}}.search-dialog{width:min(960px,calc(100% - 48px));max-width:none;height:min(680px,calc(100dvh - 100px));max-height:none;padding:0;overflow:hidden;border-radius:18px;background:#0b171bf5;-webkit-backdrop-filter:blur(28px);backdrop-filter:blur(28px);box-shadow:0 30px 120px #0009}.search-dialog[open]{display:flex;flex-direction:column}.search-dialog::backdrop{background:#02070c88;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.search-command{display:flex;align-items:center;gap:13px;padding:17px 20px;border-bottom:1px solid var(--line)}.search-command-icon{font-size:26px;color:#9dcab7}.search-command input{min-width:0;flex:1;border:0;outline:0;background:none;color:#e0f1e8;font-size:17px}.search-command input::placeholder{color:#6c8b7b}.search-close{font-size:23px}.search-options{display:flex;align-items:center;gap:10px;padding:12px 20px;border-bottom:1px solid var(--line)}.search-options select{font-size:12px;color:#bcdbcb;padding:5px 20px 5px 0;border:0;background:none}.search-chip{padding:5px 9px;border:1px solid #bddfd21a;border-radius:6px;font-size:11px;color:#8fa99b}.search-chip[aria-pressed=true]{color:#b7e2cd;background:#b0e9d60a;border-color:#b0e9d629}#search-index-state{margin-left:auto;font-size:11px;color:#7d9c8c}.search-body{display:grid;grid-template-columns:minmax(0,1.12fr) minmax(0,1fr);flex:1;min-height:0}.search-results{overflow-y:auto;overscroll-behavior:contain;min-height:0}.search-results-inner{position:relative}.search-result{position:absolute;left:7px;right:7px;height:86px;border-radius:8px;padding:11px 13px;cursor:pointer;border:1px solid transparent}.search-result.active{border-color:#b0e9d626;background:#b0e9d60e}.search-result:hover{background:#b0e9d60a}.search-result-title{font-size:13px;font-weight:440;color:#d2e5d9;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.search-result-meta{display:flex;justify-content:space-between;gap:10px;font-size:10px;color:#8ca996;margin-top:7px}.search-result-meta>span:first-child{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.match-kind{flex-shrink:0;color:#a0c7b0}.search-result-excerpt{font-size:11px;color:#759586;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-top:6px}.search-dialog mark{color:#dbffe7;background:#b6f4d111;border-radius:2px}.search-preview{border-left:1px solid var(--line);min-height:0;overflow-y:auto;overscroll-behavior:contain}.search-preview-heading{padding:22px}.search-preview-heading>span{color:#8ba898;font-size:11px}.search-preview-heading h2{margin:10px 0;font-size:20px;line-height:1.4;overflow-wrap:anywhere}.search-preview-heading p{margin:0 0 18px;font-size:11px}.search-open{width:100%}.search-open span{margin-left:auto}.search-launch{width:100%;justify-content:center;margin-top:7px}.search-preview-section{padding:19px 22px;border-top:1px solid var(--line)}.search-preview-section h3{color:#a9c6b4;font-size:12px;font-weight:450;margin:0 0 14px}.search-preview-section p{margin:8px 0 15px;font-size:12px;line-height:1.75;overflow-wrap:anywhere;white-space:pre-line}.search-preview-section article{margin:15px 0}.search-preview-section article>span{color:#b5d1bd;font-size:11px}.search-preview-section .preview-coverage{color:#718f7e;font-size:11px;margin-bottom:0}.search-footer{position:relative;display:flex;align-items:center;gap:14px;padding:12px 18px;border-top:1px solid var(--line);color:#87a592;font-size:11px}.search-footer button{color:#b0e9d6;font-size:11px}.search-keys{margin-left:auto;white-space:nowrap}.search-keys kbd{padding:1px 4px;margin-right:3px;font-size:10px}.search-keys kbd:not(:first-child){margin-left:10px}.search-syntax>div{position:absolute;bottom:45px;right:18px;display:flex;flex-direction:column;gap:10px;padding:18px;background:#132722;border:1px solid #b0e9d629;border-radius:10px;box-shadow:0 10px 30px #0006}.search-syntax code{color:#b4d7c2;font:11px var(--mono)}#search-clear-cache{margin-top:4px;padding:12px 0 0;border-top:1px solid var(--line);text-align:left}.source-badge{display:inline-flex;align-items:center;gap:6px;font:10px var(--mono);letter-spacing:.02em;color:#b5c8d9}.source-icon{display:inline-block;width:16px;height:16px;flex:0 0 16px;vertical-align:-3px;background:currentColor;mask:var(--source-icon) center / contain no-repeat;-webkit-mask:var(--source-icon) center / contain no-repeat}.source-icon-claude{color:#d9a387}.source-icon-openai{color:#b4d9c6}.source-icon-opencode{color:#c7d0d7}.source-icon-gemini,.source-icon-cline{color:#9cbcf6}.source-icon-qwen{color:#b8a6ec}.source-icon-pi{color:#e9a89c}.source-icon-copilot{color:#c7d0d7}.source-icon-roo{color:#d9b59a}.source-icon-kilo{color:#e6ce83}.source-icon-continue{color:#abd9bb}.source-symbol .source-icon{width:20px;height:20px;flex-basis:20px}.source-badge .source-icon,.search-result-meta .source-icon{width:12px;height:12px;flex-basis:12px;vertical-align:-2px}.search-result-meta .source-icon{margin-right:5px}.search-launch{display:inline-flex;gap:8px;align-items:center}#source-filter-icon{display:flex;align-items:center}.source-badge[data-source=claude-code]{color:#d8b297}.source-badge[data-source=codex]{color:#a5d1ba}.detail-title>.source-badge{margin-bottom:10px}.imports-dialog{width:min(680px,calc(100vw - 28px));max-width:680px;padding:32px}.imports-dialog[open]{display:flex;flex-direction:column;overflow-y:auto}.imports-dialog>*{flex-shrink:0}.imports-dialog>.import-sources{flex:1 1 auto;min-height:100px;overflow-y:auto;overscroll-behavior:contain;padding-right:4px}.imports-dialog .primary-button{flex:0 0 auto;white-space:nowrap}.imports-dialog .eyebrow{font:10px var(--mono);letter-spacing:.18em;color:#83b9a3}.imports-dialog h2{margin:16px 0 12px;font-size:clamp(24px,4vw,32px);font-weight:450;letter-spacing:-.04em}.imports-intro{color:#91a99d;font-size:13px;line-height:1.6;margin-bottom:14px}.privacy-disclosure{color:#91a99d;font-size:11px;line-height:1.65;margin-bottom:24px}.privacy-disclosure summary{cursor:pointer;color:#aec9bb}.privacy-disclosure p{font-size:inherit;line-height:inherit;margin:10px 0 0}.import-sources{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));align-content:start;gap:6px}.import-source{display:flex;align-items:center;min-width:0;min-height:52px;gap:9px;padding:8px 10px;border:1px solid #b0e9d61c;border-radius:8px;cursor:pointer;background:#b0e9d603}.import-source:has(input:checked){border-color:#b0e9d658;background:#b0e9d608}.import-source:hover{background:#b0e9d60e}.import-source:focus-within{outline:1px solid #b0e9d6;outline-offset:1px}.import-source:has(input:disabled){opacity:.6;cursor:wait}.import-source input{accent-color:#a4d8bf;flex:0 0 auto;margin:0}.source-symbol{display:grid;place-items:center;width:22px;height:22px;color:#bed3c7;flex:0 0 auto}.source-copy{flex:1;min-width:0}.import-source strong{display:block;font-size:12px;font-weight:500}.import-source .source-meta{display:flex;flex-wrap:wrap;gap:4px 8px;color:#879d90;font-size:10px;line-height:1.35;margin-top:3px}.import-source .source-error{display:block;color:#e4ba96;font-size:10px;line-height:1.4;margin-top:3px;overflow-wrap:anywhere}.source-detected{color:#789083;white-space:nowrap}.source-detected.detected{color:#aedbc4}.imports-progress{font:11px var(--mono);color:#9fc2af;margin-top:20px;line-height:1.8;min-height:20px}.imports-dialog footer{display:flex;align-items:center;justify-content:space-between;gap:18px;margin-top:18px}.imports-dialog footer>span{color:#789083;font-size:11px}.imports-notes{color:#91a99d;font-size:11px;line-height:1.6;margin-top:12px}.imports-notes>div{max-height:150px;overflow-y:auto}@media(max-width:600px){.imports-dialog{padding:26px 20px}.import-sources{grid-template-columns:minmax(0,1fr);gap:4px}.import-source{min-height:44px;padding:6px 9px}.imports-dialog footer{flex-wrap:wrap}}.search-empty{padding:30px 22px;color:#98b4a4;font-size:13px}.launch-dialog{width:min(520px,calc(100% - 32px));max-height:calc(100dvh - 48px);padding:28px;border-radius:16px}.launch-dialog h2{font-size:20px;margin:0 35px 10px 0}.launch-title{margin:0 0 24px;font-size:12px;line-height:1.6;overflow-wrap:anywhere}.launch-destination{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:20px;font-size:12px;color:#a9c6b4}.launch-destination select{min-width:0;max-width:77%;border:1px solid var(--line);border-radius:7px;padding:9px;background:#132321;color:#d1e5d9;font-size:12px}.launch-web-link{width:100%}.launch-pairing{margin-top:19px;font-size:11px;color:#8fa99b}.launch-pairing p,.launch-hint{font-size:11px;line-height:1.7}.launch-directory-label{display:grid;gap:9px;margin-bottom:18px;color:#a9c6b4;font-size:12px}.launch-directory{min-width:0;width:100%;padding:10px;background:#071114;color:#c8e5d5;border:1px solid var(--line);border-radius:7px;font:11px var(--mono)}.launch-summary{margin-bottom:18px;padding:13px;border:1px solid #b0e9d625;border-radius:9px;background:#b0e9d608}.launch-mode{color:#b8ddc9;font-size:12px;font-weight:500}.launch-hint{margin:7px 0 0;color:#9eb6a8}.launch-context{margin-top:12px;color:#a1b9ac;font-size:11px}.launch-context summary{cursor:pointer}.launch-coverage{line-height:1.7}.launch-context-path{display:block;overflow-wrap:anywhere;font:10px/1.7 var(--mono);color:#7e9e8e}.launch-availability{color:#c4b89b;font-size:11px;line-height:1.7;margin-bottom:0}.launch-availability:empty{display:none}.launch-command{display:block;width:100%;background:#071114;border:1px solid var(--line);border-radius:7px;padding:11px;color:#c8e5d5;font:11px var(--mono)}.launch-actions{display:flex;flex-wrap:wrap;gap:9px;margin-top:14px}.launch-actions>button{flex:1;white-space:nowrap}.launch-status{margin:14px 0 0;font-size:12px;line-height:1.6}.launch-status:empty{display:none}@media(max-width:759px){.search-dialog{width:calc(100% - 24px);height:calc(100dvh - 48px);border-radius:14px}.search-command{padding:12px;gap:8px}.search-command input{font-size:16px}.search-options{flex-wrap:wrap;padding:9px 14px;gap:7px 12px}#search-index-state{flex-basis:100%;margin-left:0}.search-body{grid-template-columns:1fr;grid-template-rows:minmax(150px,1fr) minmax(130px,.7fr)}.search-preview{border-left:0;border-top:1px solid var(--line)}.search-preview-heading{padding:16px}.search-preview-heading h2{font-size:17px}.search-preview-section{padding:16px}.search-footer{padding:10px 14px}.search-keys{display:none}.search-syntax{margin-left:auto}}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import{M as $,C as F,S as W,a as M,W as se,A as oe,O as ne,b as re,H as ae,E as he,R as le,U as ce,V as G,c as de,d as fe,e as pe,P as me,G as D,f as ue,g as T,h as ge,i as m,j as ve,k as O,B as R,F as A,l as H,m as ye,n as we,I as Me,o as L,D as U,p as q,q as Y,r as N,s as X,t as j,u as V,v as be,L as xe,w as K,x as ke,y as Pe,z as Se,J as Ee}from"./three-B4kj4iLH.js";import{d as te,h as B,c as Ae,D as Ce,m as Ie,a as J,p as E,b as C,i as _,t as Z,e as Q}from"./index-C9rv5Uuu.js";const Be=["svg",te,[["path",{d:"M12 8V4H8"}],["rect",{width:"16",height:"12",x:"4",y:"8",rx:"2"}],["path",{d:"M2 14h2"}],["path",{d:"M20 14h2"}],["path",{d:"M15 13v2"}],["path",{d:"M9 13v2"}]]];const Ge=["svg",te,[["circle",{cx:"12",cy:"8",r:"5"}],["path",{d:"M20 21a8 8 0 0 0-16 0"}]]],ie=`
|
|
2
|
-
attribute float nodeIndex;
|
|
3
|
-
uniform float uSelected;
|
|
4
|
-
uniform float uHovered;
|
|
5
|
-
uniform float uFocus;
|
|
6
|
-
varying float vNodeEmphasis;
|
|
7
|
-
float nodeEmphasis() {
|
|
8
|
-
if (abs(nodeIndex - uSelected) < .5) return 1.12;
|
|
9
|
-
if (abs(nodeIndex - uHovered) < .5) return 1.2;
|
|
10
|
-
return mix(1.0, .12, uFocus);
|
|
11
|
-
}
|
|
12
|
-
`;function z(k){const e=new F(k.color),t=e.getHSL({h:0,s:0,l:0},W),i=k.session.id;return e.setHSL(t.h+(B(`${i}:hue`)-.5)*.09,M.clamp(t.s+B(`${i}:saturation`)*.12,.4,.72),.63+B(`${i}:lightness`)*.11,W)}function Re(k){const e=new $;return e.onBeforeCompile=t=>{Object.assign(t.uniforms,k),t.vertexShader=`${ie}
|
|
13
|
-
varying vec3 vSphereNormal; varying vec3 vSphereView;
|
|
14
|
-
${t.vertexShader}`.replace("#include <project_vertex>",`
|
|
15
|
-
#include <project_vertex>
|
|
16
|
-
// Instances only translate/uniformly scale. Keep the original sphere
|
|
17
|
-
// normals when the graph's depth is flattened, retaining depth cues in 2D.
|
|
18
|
-
vSphereNormal = mat3(viewMatrix) * normal;
|
|
19
|
-
vSphereView = -mvPosition.xyz;
|
|
20
|
-
vNodeEmphasis = nodeEmphasis();
|
|
21
|
-
`),t.fragmentShader=`varying vec3 vSphereNormal; varying vec3 vSphereView; varying float vNodeEmphasis;
|
|
22
|
-
${t.fragmentShader}`.replace("#include <color_fragment>",`
|
|
23
|
-
#include <color_fragment>
|
|
24
|
-
vec3 n = normalize(vSphereNormal);
|
|
25
|
-
float facing = max(dot(n, normalize(vSphereView)), 0.0);
|
|
26
|
-
float light = .8 + .4 * max(dot(n, normalize(vec3(-.5, .65, 1.0))), 0.0);
|
|
27
|
-
// Luminous colored centers bloom; a soft rim still separates overlaps.
|
|
28
|
-
float rim = mix(.35, 1.0, smoothstep(0.0, .28, facing));
|
|
29
|
-
diffuseColor.rgb = mix(diffuseColor.rgb, vec3(1.0), .07 * facing);
|
|
30
|
-
diffuseColor.rgb *= 1.4 * light * rim * vNodeEmphasis;
|
|
31
|
-
`)},e}class ee{constructor(e=48){this.cellSize=e}cellSize;cells=new Map;clear(){this.cells.clear()}add(e,t,i,s,o,n){if(![t,i,s].every(Number.isFinite)||t+s<0||i+s<0||t-s>o||i-s>n)return;const r=Math.floor(Math.max(0,t-s)/this.cellSize),a=Math.floor(Math.min(o,t+s)/this.cellSize),h=Math.floor(Math.max(0,i-s)/this.cellSize),f=Math.floor(Math.min(n,i+s)/this.cellSize);for(let d=h;d<=f;d++)for(let u=r;u<=a;u++){const p=`${u}:${d}`,l=this.cells.get(p);l?l.push(e):this.cells.set(p,[e])}}at(e,t){return this.cells.get(`${Math.floor(e/this.cellSize)}:${Math.floor(t/this.cellSize)}`)||[]}}function ze(k){const e=k.role==="user"?Ge:Be;return Ae([e[0],{...e[1],"aria-hidden":"true","stroke-width":1.4},e[2]])}function I(k){k.traverse(e=>{const t=e;e instanceof L&&e.dispose(),t.geometry?.dispose(),t.material&&(Array.isArray(t.material)?t.material:[t.material]).forEach(s=>s.dispose())}),k.clear()}class Te{constructor(e,t){this.container=e,this.onSelect=t.onSelect,this.onHover=t.onHover,this.onEvent=t.onEvent,this.onEventHover=t.onEventHover,this.renderer=new se({antialias:!0,alpha:!0,powerPreference:"high-performance"}),this.renderer.setPixelRatio(Math.min(Math.max(devicePixelRatio,1.5),2)),this.renderer.localClippingEnabled=!0,this.renderer.setClearColor(new F().setRGB(.001,.0017,.0024),1),this.renderer.toneMapping=oe,this.renderer.toneMappingExposure=1.05,this.renderer.domElement.setAttribute("aria-label","Interactive 3D session timeline. Drag to orbit, scroll to zoom. Sessions are also available in the list."),this.renderer.domElement.tabIndex=0,e.append(this.renderer.domElement),this.labelLayer=document.createElement("div"),this.labelLayer.className="scene-labels",this.labelLayer.dataset.motion=String(this.motion),e.append(this.labelLayer),this.controls=new ne(this.camera,this.renderer.domElement),this.controls.enableDamping=!0,this.controls.dampingFactor=.065,this.controls.rotateSpeed=.5,this.controls.zoomSpeed=.8,this.controls.minDistance=15,this.controls.maxDistance=1200,this.controls.addEventListener("start",()=>{this.targetPosition=void 0,this.targetLook=void 0,this.focusedSession=null,this.playing&&t.onPlaybackInterrupt()}),this.camera.position.set(20,70,320),this.scene.add(this.graphGroup,this.selectionGroup,this.filesGroup);const i=new re(1,1,{type:ae,samples:Math.min(4,this.renderer.capabilities.maxSamples)});this.composer=new he(this.renderer,i),this.composer.addPass(new le(this.scene,this.camera)),this.bloom=new ce(new G(1,1),.23,.4,.9),this.composer.addPass(this.bloom),this.smaa=new de,this.composer.addPass(this.smaa),this.composer.addPass(new fe);const s=this.smaa;for(const o of[s._areaTexture??s.areaTexture,s._searchTexture??s.searchTexture])o?.image?.addEventListener("load",()=>{this.dirty=!0},{once:!0});this.addStars(),this.resizeObserver=new ResizeObserver(()=>this.resize()),this.resizeObserver.observe(e),this.renderer.domElement.addEventListener("pointermove",this.pointerMove),this.renderer.domElement.addEventListener("pointerdown",this.pointerStart),this.renderer.domElement.addEventListener("pointerup",this.pointerEnd),this.renderer.domElement.addEventListener("pointercancel",()=>{this.pointerID=null}),this.renderer.domElement.addEventListener("pointerleave",this.pointerLeave),this.renderer.domElement.addEventListener("webglcontextlost",this.contextLost),this.resize(),this.animate()}container;renderer;scene=new pe;camera=new me(45,1,.1,2500);controls;composer;bloom;smaa;dirty=!0;graphGroup=new D;selectionGroup=new D;filesGroup=new D;labels=[];labelLayer;graph={nodes:[],edges:[],lanes:[],start:0,end:0};nodeMesh;nodeByID=new Map;nodeIndices=new Map;focusUniforms={uSelected:{value:-1},uHovered:{value:-1},uFocus:{value:0}};raycaster=new ue;nodeGrid=new ee;markerGrid=new ee;pickingDirty=!0;pickingView=new T;pickingProjection=new T;pickMesh;pickMatrix=new T;pickHits=[];width=1;height=1;pointer=new G;pointerDown=new G;pointerID=null;pointerDragged=!1;selected=null;hovered=null;cutoff=1;clipPlane=new ge(new m(-1,0,0),151);flat=!1;motion=!matchMedia("(prefers-reduced-motion: reduce)").matches;suspended=!1;frame=0;resizeObserver;targetPosition;targetLook;playing=!1;playbackPath;playbackRadii=[];playbackSphere=new ve;playbackFocus=new m;playbackOffset=new m;glowMaterial;glowPositions;time=0;previousFrame=performance.now();nodeReveal=new Float32Array;revealAttribute;revealsActive=!1;graphBorn=0;fileMesh;eventMarkers=[];selectedEvent=null;focusedEvent;focusedSession=null;eventIcons=[];iconPoint=new m;markerUniforms={uPixelRatio:{value:1},uSelected:{value:-1},uHovered:{value:-1}};fileOffsets=[];fileOrigin=new m;fileBorn=0;fileUniforms={uTime:{value:0},uBorn:{value:0},uMotion:{value:1},uOrigin:{value:new m}};lineUniforms={uCutoff:{value:160},uReveal:{value:1}};preferences={...Ce};trailUniforms={uTrailTime:{value:0},uTrailFlow:{value:0},uTrailSpeed:{value:.5},uTrailOpacity:{value:1}};stars;transform=new O;onSelect;onHover;onEvent;onEventHover;contextLost=e=>{e.preventDefault(),this.container.dispatchEvent(new CustomEvent("scene-error",{detail:"The graphics context was lost. Reload to restore the 3D view; the session list is still available."}))};addStars(){const e=[];for(let i=0;i<280;i++)e.push((B(`sx${i}`)-.5)*1100,(B(`sy${i}`)-.5)*700,-120-B(`sz${i}`)*500);const t=new R;t.setAttribute("position",new A(e,3)),this.stars=new H(t,new ye({color:"#7b9fa9",size:.4,transparent:!0,opacity:.18,sizeAttenuation:!0})),this.scene.add(this.stars)}applyPreferences(e){const t=this.preferences;this.preferences={...e};const i=Ie(e,matchMedia("(prefers-reduced-motion: reduce)").matches);if(i!==this.motion&&this.setMotion(i),e.view==="2d"!==this.flat&&this.setFlat(e.view==="2d"),e.quality!==t.quality){const o=e.quality==="performance"?1:e.quality==="high"?Math.min(Math.max(devicePixelRatio,2),2.5):Math.min(Math.max(devicePixelRatio,1.5),2),n=e.quality==="performance"?0:Math.min(4,this.renderer.capabilities.maxSamples);for(const r of[this.composer.renderTarget1,this.composer.renderTarget2])r.samples=n,r.dispose();this.smaa.enabled=e.quality!=="performance",this.renderer.setPixelRatio(o),this.composer.setPixelRatio(o),this.resize()}this.bloom.strength=e.bloom/100,this.bloom.enabled=e.quality!=="performance"&&e.bloom>0,this.stars&&(this.stars.visible=e.stars),this.labelLayer.hidden=!e.labels,this.trailUniforms.uTrailOpacity.value=e.trailOpacity/42,this.trailUniforms.uTrailSpeed.value=e.trailSpeed/100;for(const o of[this.graphGroup,this.selectionGroup])for(const n of o.children)n.userData.kind==="lifetime"&&(n.visible=e.trails==="all"||e.trails==="selected"&&o===this.selectionGroup),n.userData.kind==="relationship"&&(n.visible=e.relationships);const s=this.selectionGroup.getObjectByName("event-markers");s&&(s.visible=e.messageDots),this.nodeMesh&&t.nodeScale!==e.nodeScale&&(this.nodeMesh.boundingSphere=null,this.revealsActive=!0),this.dirty=!0}setGraph(e,t=!1,i=!1){const s=i?new Map(this.graph.nodes.map((c,w)=>[c.session.id,this.nodeReveal[w]])):void 0;if(this.pickingDirty=!0,this.dirty=!0,I(this.graphGroup),I(this.selectionGroup),I(this.filesGroup),this.eventMarkers=[],this.eventIcons=[],this.fileMesh=void 0,this.fileOffsets=[],this.labels=[],this.labelLayer.replaceChildren(),this.graph=e,(!i||!this.playing)&&(this.playbackPath=void 0,this.playbackRadii=[]),this.nodeByID=new Map(e.nodes.map(c=>[c.session.id,c])),this.nodeIndices=new Map(e.nodes.map((c,w)=>[c.session.id,w])),this.focusUniforms.uSelected.value=this.selected?this.nodeIndices.get(this.selected)??-1:-1,this.focusUniforms.uHovered.value=-1,this.hovered=null,this.nodeMesh=void 0,this.pickMesh=void 0,this.glowMaterial=void 0,this.glowPositions=void 0,this.graphBorn=i?this.time-1:this.time,this.nodeReveal=Float32Array.from(e.nodes,c=>s?.get(c.session.id)??(this.motion?0:1)),this.revealsActive=this.motion&&e.nodes.length>0,!e.nodes.length)return;const o=new we(1,32,20),n=Float32Array.from(e.nodes,(c,w)=>w);o.setAttribute("nodeIndex",new Me(n,1));const r=new L(o,Re(this.focusUniforms),e.nodes.length);r.scale.z=this.flat?1e3:1,r.instanceMatrix.setUsage(U),r.frustumCulled=!1;const a=new O,h=[],f=[],d=[];e.nodes.forEach((c,w)=>{a.position.fromArray(c.position),this.flat&&(a.position.z*=.001),a.scale.setScalar(c.radius*this.preferences.nodeScale/100),a.updateMatrix(),r.setMatrixAt(w,a.matrix);const S=z(c);r.setColorAt(w,S),h.push(...c.position),f.push(...S.toArray()),d.push(c.radius*11)}),r.instanceMatrix.needsUpdate=!0,r.computeBoundingSphere(),this.nodeMesh=r,this.pickMesh=new q(o,r.material),this.graphGroup.add(r);const u=new R;this.glowPositions=new A(h,3).setUsage(U),u.setAttribute("position",this.glowPositions),u.setAttribute("color",new A(f,3)),u.setAttribute("size",new A(d,1)),u.setAttribute("nodeIndex",new Y(n,1)),this.revealAttribute=new Y(this.nodeReveal,1).setUsage(U),u.setAttribute("reveal",this.revealAttribute),this.glowMaterial=new N({uniforms:{...this.focusUniforms,uCutoff:{value:151},uScale:{value:this.container.clientHeight*this.renderer.getPixelRatio()*.9}},vertexShader:`${ie}
|
|
32
|
-
attribute float size; attribute float reveal; varying vec3 vColor; varying float vVisible; uniform float uScale; uniform float uCutoff;
|
|
33
|
-
void main() { vColor = color; vVisible = reveal; vNodeEmphasis = nodeEmphasis(); vec4 mv = modelViewMatrix * vec4(position, 1.0);
|
|
34
|
-
gl_PointSize = clamp(size * (1.0 + sin(reveal * 3.14159) * .45) * uScale / -mv.z, 2.0, 100.0); gl_Position = projectionMatrix * mv; }`,fragmentShader:`varying vec3 vColor; varying float vVisible; varying float vNodeEmphasis;
|
|
35
|
-
void main() { float d = length(gl_PointCoord - .5) * 2.0; if (d > 1.0) discard;
|
|
36
|
-
float a = pow(1.0 - d, 3.1) * .34 * vVisible * vNodeEmphasis; gl_FragColor = vec4(vColor * 1.15, a); }`,vertexColors:!0,transparent:!0,depthWrite:!1,blending:X});const p=new H(u,this.glowMaterial);p.frustumCulled=!1,this.graphGroup.add(p);const l=[],v=[];for(const c of e.nodes)this.appendSegments([new m(...c.startPosition),new m(...c.position)],z(c),l,v);this.addLines(l,v,.42,this.graphGroup,"lifetime"),e.lanes.forEach((c,w)=>{const S=Math.min(...c.nodes.map(x=>x.startPosition[0]));w<12&&this.addLabel(c.label,new m(S-4,c.y+8,c.z),c.color)});const g=[],y=[];for(const c of e.edges){const w=this.nodeByID.get(c.from),S=this.nodeByID.get(c.to),x=this.edgeCurve(...J(w,S));this.appendSegments(x.getPoints(22),new F(c.kind==="fork"?"#edbc8d":"#bda6ef"),g,y)}this.addLines(g,y,.7,this.graphGroup,"relationship");const P=[],b=[];for(let c=0;c<=8;c++){const w=E(c/8,e);this.appendSegments([new m(w,-105,-70),new m(w,-105,70)],new F("#314149"),P,b)}this.addLines(P,b,.23),this.setCutoff(this.cutoff),this.selected&&this.select(this.selected),t&&this.reset()}appendSegments(e,t,i,s){for(let o=1;o<e.length;o++)i.push(...e[o-1].toArray(),...e[o].toArray()),s.push(t.r,t.g,t.b,t.r,t.g,t.b)}buildPlaybackPath(){if(this.playbackPath=void 0,this.playbackRadii=[],!this.graph.nodes.length)return;const e=this.graph.nodes.map(o=>new m(...o.position)),t=new j().setFromPoints(e).getBoundingSphere(new V),i=[],s=Math.max(1,E(1,this.graph)-E(0,this.graph));for(let o=0;o<=100;o++){const n=o/100,r=E(n,this.graph),a=new m,h=new j;let f=0;for(const l of this.graph.nodes){if(l.startPosition[0]>r)continue;const v=new m(...C(l,r)),g=(v.x-r)*300/s,y=Math.exp(-(((g+6)/24)**2));a.addScaledVector(v,y),f+=y,g>=-38&&g<=12&&h.expandByPoint(v)}a.divideScalar(f);const d=h.isEmpty()?new V(a,0):h.getBoundingSphere(new V),u=Math.max(65,d.radius+d.center.distanceTo(a)),p=M.smoothstep(n,.86,1);a.lerp(t.center,p*.65),i.push(a),this.playbackRadii.push(M.lerp(u,t.radius+20,p))}this.playbackPath=new be(i)}setPlaying(e){this.playing!==e&&(this.playing=e,e||(this.playbackPath=void 0,this.playbackRadii=[]),e&&(this.focusedSession=null,this.camera.clearViewOffset()),e&&this.motion&&(this.playbackPath||this.buildPlaybackPath(),this.targetPosition=void 0,this.targetLook=void 0,this.playbackSphere.setFromVector3(this.camera.position.clone().sub(this.controls.target))),this.dirty=!0)}animatePlaybackCamera(e){if(!this.playing||!this.motion||!this.playbackPath)return!1;this.playbackPath.getPoint(this.cutoff,this.playbackFocus),this.flat&&(this.playbackFocus.z=0);const t=this.cutoff*(this.playbackRadii.length-1),i=Math.floor(t),s=Math.min(i+1,this.playbackRadii.length-1),o=M.lerp(this.playbackRadii[i],this.playbackRadii[s],t-i),n=M.degToRad(this.camera.fov)/2,r=Math.min(n,Math.atan(Math.tan(n)*this.camera.aspect)),a=M.clamp(o/Math.sin(r)*1.08,160,1100),h=this.flat?0:-.3+this.cutoff*Math.PI,f=this.flat?0:.16+Math.sin(this.cutoff*Math.PI)*.12,d=Math.atan2(Math.sin(h-this.playbackSphere.theta),Math.cos(h-this.playbackSphere.theta));return this.playbackSphere.theta+=d*(1-Math.exp(-3*e)),this.playbackSphere.phi=M.damp(this.playbackSphere.phi,Math.PI/2-f,1.5,e),this.playbackSphere.radius=M.damp(this.playbackSphere.radius,a,1.25,e),this.controls.target.lerp(this.playbackFocus,1-Math.exp(-2.1*e)),this.camera.position.copy(this.controls.target).add(this.playbackOffset.setFromSpherical(this.playbackSphere)),!0}addLines(e,t,i,s=this.graphGroup,o="grid"){if(!e.length)return;const n=new R;n.setAttribute("position",new A(e,3)),n.setAttribute("color",new A(t,3));const r=new xe({vertexColors:!0,transparent:!0,opacity:i,depthWrite:!1,blending:X,clippingPlanes:s!==this.filesGroup?[this.clipPlane]:[]});s!==this.filesGroup&&(r.onBeforeCompile=h=>{h.uniforms.uTimelineCutoff=this.lineUniforms.uCutoff,h.uniforms.uGraphReveal=this.lineUniforms.uReveal,h.uniforms.uContextFocus=s===this.graphGroup?this.focusUniforms.uFocus:{value:0},Object.assign(h.uniforms,this.trailUniforms),h.vertexShader=`varying float vTimelineX;
|
|
37
|
-
${h.vertexShader}`.replace("#include <begin_vertex>",`#include <begin_vertex>
|
|
38
|
-
vTimelineX = position.x;`),h.fragmentShader=`varying float vTimelineX; uniform float uTimelineCutoff; uniform float uGraphReveal; uniform float uContextFocus;
|
|
39
|
-
${h.fragmentShader}`.replace("#include <color_fragment>",`#include <color_fragment>
|
|
40
|
-
diffuseColor.a *= smoothstep(0.0, .6, uTimelineCutoff - vTimelineX) * uGraphReveal * mix(1.0, .16, uContextFocus);`),o==="lifetime"&&(h.fragmentShader=`uniform float uTrailTime; uniform float uTrailFlow; uniform float uTrailSpeed; uniform float uTrailOpacity;
|
|
41
|
-
${h.fragmentShader}`.replace("#include <color_fragment>",`#include <color_fragment>
|
|
42
|
-
diffuseColor.a *= uTrailOpacity * mix(1.0, .84 + .16 * pow(.5 + .5 * sin(vTimelineX * .28 - uTrailTime * uTrailSpeed * 2.2), 4.0), uTrailFlow);`))}),r.customProgramCacheKey=()=>o;const a=new K(n,r);a.userData.kind=o,a.visible=o==="lifetime"?this.preferences.trails==="all"||this.preferences.trails==="selected"&&s===this.selectionGroup:o!=="relationship"||this.preferences.relationships,s.add(a)}edgeCurve(e,t){const i=new m(...e),s=new m(...t),o=(e[0]+t[0])/2,n=Math.abs(e[1]-t[1])<8?9:0;return new ke(i,new m(o,e[1]+n,e[2]),new m(o,t[1]+n,t[2]),s)}addLabel(e,t,i,s=!1){const o=document.createElement("div");o.className=s?"scene-label selected-label":"scene-label",o.textContent=e,o.style.setProperty("--label-color",i),this.labelLayer.append(o);const n={element:o,point:t,priority:s};s?this.labels.unshift(n):this.labels.push(n)}select(e){this.pickingDirty=!0,this.dirty=!0,this.selected!==e&&(this.selectedEvent=null,this.focusedEvent=void 0),this.selected=e,this.focusUniforms.uSelected.value=e?this.nodeIndices.get(e)??-1:-1,I(this.selectionGroup),I(this.filesGroup),this.eventMarkers=[],this.clearEventIcons(),this.fileMesh=void 0,this.fileOffsets=[],this.labels=this.labels.filter(a=>(a.priority&&a.element.remove(),!a.priority));const t=e?this.nodeByID.get(e):void 0;if(!t)return;const i=new q(new Pe(t.radius*2.1,t.radius*2.35,96),new $({color:"#e1fff4",side:Se,transparent:!0,opacity:.9,depthTest:!1}));i.position.fromArray(t.position),i.name="selection-ring",this.selectionGroup.add(i);const s=[],o=[],n=[],r=[];this.appendSegments([new m(...t.startPosition),new m(...t.position)],z(t).multiplyScalar(1.4),n,r),this.addLines(n,r,1,this.selectionGroup,"lifetime");for(const a of this.graph.edges.filter(h=>h.from===e||h.to===e)){const h=this.nodeByID.get(a.from),f=this.nodeByID.get(a.to);this.appendSegments(this.edgeCurve(...J(h,f)).getPoints(30),new F("#f3dfbd").multiplyScalar(1.8),s,o)}this.addLines(s,o,1,this.selectionGroup,"relationship"),this.addLabel(t.session.title.slice(0,52),new m(...t.position).add(new m(0,6,0)),"#e6f3ef",!0),this.setCutoff(this.cutoff)}setEvents(e,t=!1){this.pickingDirty=!0;const i=this.selectionGroup.getObjectByName("event-markers");i&&(I(i),i.removeFromParent()),this.eventMarkers=[],this.clearEventIcons(),this.dirty=!0;const s=this.selected?this.nodeByID.get(this.selected):void 0;if(!s)return;const o=[],n=e.filter(_).slice(-2e3);this.focusedEvent&&_(this.focusedEvent)&&!n.some(p=>p.id===this.focusedEvent.id)&&n.push(this.focusedEvent);for(const p of n){if(p.time===null||p.kind==="message"&&p.time===s.session.activity?.lastMessageAt)continue;const l=Z(p.time,this.graph);if(!Number.isFinite(l)||l<s.startPosition[0]||l>s.position[0])continue;const v=new m(...Q(s,l));this.eventMarkers.push({item:p,position:v}),o.push(...v.toArray())}if(!o.length)return;const r=new R;r.setAttribute("position",new A(o,3)),r.setAttribute("markerIndex",new A(this.eventMarkers.map((p,l)=>l),1)),this.markerUniforms.uPixelRatio.value=this.renderer.getPixelRatio(),this.markerUniforms.uHovered.value=-1,this.selectEvent(this.selectedEvent);const a=new N({uniforms:{uCutoff:this.lineUniforms.uCutoff,uColor:{value:z(s)},...this.markerUniforms},transparent:!0,depthWrite:!1,depthTest:!1,vertexShader:`uniform float uPixelRatio; uniform float uSelected; uniform float uHovered; attribute float markerIndex; varying float vTimeX; varying float vActive;
|
|
43
|
-
void main() { vTimeX = position.x; vActive = float(abs(markerIndex-uSelected)<.1 || abs(markerIndex-uHovered)<.1); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); gl_PointSize = mix(6.5,10.0,vActive) * uPixelRatio; }`,fragmentShader:`uniform float uCutoff; uniform vec3 uColor; varying float vTimeX; varying float vActive;
|
|
44
|
-
void main() { float d = length(gl_PointCoord - .5) * 2.0; if (d > 1.0 || vTimeX > uCutoff) discard;
|
|
45
|
-
gl_FragColor = vec4(mix(uColor * 1.3, vec3(1.4), vActive * .25), 1.0 - smoothstep(.5, 1.0, d)); }`}),h=new D;h.name="event-markers",h.visible=this.preferences.messageDots;const f=new H(r,a);f.renderOrder=10,h.add(f),this.selectionGroup.add(h);const d=this.eventMarkers.length-1,u=new Set;for(let p=d;p>=Math.max(0,d-31);p--)u.add(p);for(let p=0;p<32&&d>31;p++)u.add(Math.floor(p*(d-32)/31));for(const p of[...u].sort((l,v)=>v-l)){const l=document.createElement("div");l.className="event-marker-icon",l.setAttribute("aria-hidden","true"),l.style.color=`#${z(s).getHexString()}`,l.append(ze(this.eventMarkers[p].item)),this.labelLayer.append(l),this.eventIcons.push({element:l,marker:p,visible:!1,transform:""})}t&&this.focusedSession===this.selected&&this.selected&&this.focus(this.selected)}clearEventIcons(){for(const e of this.eventIcons)e.element.remove();this.eventIcons=[]}selectEvent(e){this.selectedEvent=e,e||(this.focusedEvent=void 0),this.markerUniforms.uSelected.value=this.eventMarkers.findIndex(t=>t.item.id===e),this.dirty=!0}focusEvent(e){this.focusedSession=null;const t=this.selected?this.nodeByID.get(this.selected):void 0;if(!t||e.time===null||!_(e))return;const i=Z(e.time,this.graph);!Number.isFinite(i)||i<t.startPosition[0]||i>t.position[0]||(this.focusedEvent={...e,preview:"preview"in e?e.preview:(e.text||e.input||e.output||"").slice(0,180)},this.eventMarkers.some(s=>s.item.id===e.id)||this.setEvents(this.eventMarkers.map(s=>s.item)),this.selectEvent(e.id),this.focusPoint(new m(...Q(t,i)),100))}setFiles(e){this.dirty=!0,I(this.filesGroup),this.fileMesh=void 0,this.fileOffsets=[];const t=this.selected?this.nodeByID.get(this.selected):void 0;if(!t)return;const i=[],s=[],o=e.slice(0,80);if(!o.length)return;const n=new Ee(.55),r=new $({color:"#edc899"}),a=new L(n,r,o.length);a.instanceMatrix.setUsage(U),a.frustumCulled=!1,this.fileMesh=a,this.fileBorn=this.time,this.fileOrigin.fromArray(t.position),this.fileUniforms.uOrigin.value.copy(this.fileOrigin),this.fileUniforms.uBorn.value=this.fileBorn;const h=new O;if(o.forEach((f,d)=>{const u=d*2.399963,p=9+Math.sqrt(d)*2.5,l=[t.position[0]+Math.cos(u)*p,t.position[1]+Math.sin(u)*p,t.position[2]+6+B(f.path)*8];this.fileOffsets.push(new m(...l).sub(this.fileOrigin)),h.position.fromArray(l),h.scale.setScalar(this.motion?0:1),h.updateMatrix(),a.setMatrixAt(d,h.matrix);const v=this.edgeCurve(t.position,l).getPoints(24);for(let g=1;g<v.length;g++)i.push(...v[g-1].toArray(),...v[g].toArray()),s.push(d*.018,d*.018)}),a.instanceMatrix.needsUpdate=!0,this.filesGroup.add(a),i.length){const f=new R;f.setAttribute("position",new A(i,3)),f.setAttribute("delay",new A(s,1));const d=new N({uniforms:this.fileUniforms,transparent:!0,depthWrite:!1,blending:X,vertexShader:`attribute float delay; uniform vec3 uOrigin; uniform float uTime; uniform float uBorn; uniform float uMotion; varying float vAlpha;
|
|
46
|
-
void main() { float t = uMotion > .5 ? clamp((uTime-uBorn-delay)/.85,0.0,1.0) : 1.0; float p = 1.0-pow(1.0-t,3.0);
|
|
47
|
-
vec3 offset = (position-uOrigin)*p; float a = uMotion > .5 ? sin(uTime*.22)*.035 : 0.0;
|
|
48
|
-
offset.xy = mat2(cos(a),sin(a),-sin(a),cos(a))*offset.xy;
|
|
49
|
-
vAlpha = smoothstep(0.0,.3,t)*.34; gl_Position = projectionMatrix*modelViewMatrix*vec4(uOrigin+offset,1.0); }`,fragmentShader:"varying float vAlpha; void main(){gl_FragColor=vec4(.78,.57,.32,vAlpha);}"});this.filesGroup.add(new K(f,d))}}focus(e){const t=this.nodeByID.get(e);if(!t)return;this.selected!==e&&this.select(e),this.focusedSession=e;const i=this.eventMarkers.filter(h=>h.item.kind==="message").slice(-12),s=t.position[0]-t.startPosition[0],o=Math.min(s,60,Math.max(8,i.length?t.position[0]-i[0].position.x:Math.min(40,s*.3))),n=new m(...t.position);n.x-=o/2;const r=this.focusArea(),a=Math.max(85,(o+18)*this.height/Math.max(160,r.width)/(2*Math.tan(Math.PI/8)));this.focusPoint(n,Math.min(a,220))}focusPoint(e,t){this.flat&&(e.z=0),this.frameFocus(),this.targetLook=e,this.targetPosition=e.clone().add(new m(0,this.flat?0:20,t)),this.dirty=!0}focusArea(){const e=this.container.clientWidth,t=this.container.clientHeight;let i=16,s=e-16,o=e>=760?92:72,n=t-24;const r=document.getElementById("inspector"),a=document.getElementById("explorer");if(e>=760)i=a&&!a.hidden?a.getBoundingClientRect().right+24:i,s=r&&!r.hidden?r.getBoundingClientRect().left-24:s,s-i<160&&(i=16,s=e-16);else if(r&&!r.hidden){const f=r.getBoundingClientRect();f.top>160&&(n=Math.min(n,f.top-20))}const h=document.getElementById("timeline");if(h&&!h.hidden){const f=h.getBoundingClientRect();f.top>o+160&&(n=Math.min(n,f.top-24))}return{x:(i+s)/2,y:(o+n)/2,width:s-i,height:n-o}}frameFocus(){const e=this.container.clientWidth,t=this.container.clientHeight,{x:i,y:s}=this.focusArea();this.camera.setViewOffset(e,t,e/2-i,t/2-s,e,t)}reset(){if(this.focusedSession=null,this.camera.clearViewOffset(),!this.graph.nodes.length)return;const e=new j().setFromPoints(this.graph.nodes.flatMap(a=>[new m(...a.startPosition),new m(...a.position)])),t=e.getSize(new m),i=e.getCenter(new m);this.flat&&(i.z=0);const s=2*Math.tan(M.degToRad(22.5)),o=(t.y+30)/s,n=(t.x+50)/(s*this.camera.aspect),r=Math.max(o,n,100)+(this.flat?0:t.z/2+20);this.targetLook=i,this.targetPosition=i.clone().add(new m(this.flat?0:18,this.flat?0:45,r))}setFlat(e){this.dirty=!0,this.flat=e,this.controls.enableRotate=!e;for(const t of[this.graphGroup,this.selectionGroup,this.filesGroup])t.scale.z=e?.001:1;this.nodeMesh&&(this.nodeMesh.scale.z=e?1e3:1,this.nodeMesh.boundingSphere=null),this.revealsActive=!0,(!this.playing||!this.motion)&&this.reset()}setMotion(e){this.motion=e,e&&this.playing&&!this.playbackPath&&this.buildPlaybackPath(),e&&this.playing&&this.playbackSphere.setFromVector3(this.camera.position.clone().sub(this.controls.target)),this.labelLayer.dataset.motion=String(e),this.revealsActive=this.graph.nodes.length>0,this.dirty=!0}setSuspended(e){this.suspended=e,this.previousFrame=performance.now(),this.dirty=!0}diagnostics(){return{camera:this.camera.position.toArray(),target:this.controls.target.toArray(),cameraZoom:this.camera.zoom,cameraMoving:!!(this.targetPosition||this.targetLook),timeFrame:this.graph.timeFrame,timeRange:[this.graph.start,this.graph.end],cutoffX:this.clipPlane.constant,nodes:this.graph.nodes.length,edges:this.graph.edges.length,xRange:[Math.min(...this.graph.nodes.map(e=>e.position[0])),Math.max(...this.graph.nodes.map(e=>e.position[0]))],yRange:[Math.min(...this.graph.nodes.map(e=>e.position[1])),Math.max(...this.graph.nodes.map(e=>e.position[1]))],calls:this.renderer.info.render.calls,geometries:this.renderer.info.memory.geometries,msaaSamples:this.composer.renderTarget1.samples,smaa:this.smaa.enabled,pixelRatio:this.renderer.getPixelRatio(),cutoff:this.cutoff,selectedVisible:this.selectionGroup.visible,selectedNode:this.selected,selectedPosition:this.selected&&this.nodeByID.has(this.selected)?C(this.nodeByID.get(this.selected),E(this.cutoff,this.graph)):void 0,headSamples:this.graph.nodes.slice(0,32).map((e,t)=>{const i=new T;return this.nodeMesh?.getMatrixAt(t,i),{id:e.session.id,start:e.startPosition[0],end:e.position[0],x:i.elements[12],glowX:this.glowPositions?.getX(t),reveal:this.nodeReveal[t]}}),focusDimming:this.focusUniforms.uFocus.value,nodeSegments:this.nodeMesh?.geometry.parameters.widthSegments,eventMarkers:this.eventMarkers.length,eventIcons:this.eventIcons.filter(e=>e.visible).length,focusArea:this.focusArea(),selectedScreen:this.selected&&this.nodeByID.has(this.selected)?(()=>{const e=new m(...C(this.nodeByID.get(this.selected),E(this.cutoff,this.graph)));return this.flat&&(e.z=0),e.project(this.camera),[(e.x+1)/2*this.width,(1-e.y)/2*this.height]})():void 0,selectedEvent:this.selectedEvent,selectedEventPosition:this.eventMarkers.find(e=>e.item.id===this.selectedEvent)?.position.toArray(),markerSamples:this.eventMarkers.slice(0,30).map(({item:e,position:t})=>{const i=t.clone();return this.flat&&(i.z*=.001),i.project(this.camera),{id:e.id,kind:e.kind,x:(i.x+1)/2*this.container.clientWidth,y:(1-i.y)/2*this.container.clientHeight}}),sessionTrails:this.graph.nodes.filter(e=>e.position[0]>e.startPosition[0]).length,renderedFrames:this.renderer.info.render.frame,revealingNodes:this.revealsActive,revealedNodes:this.nodeReveal.filter(e=>e>.95).length,fileSatellites:this.fileOffsets.length,fileRevealProgress:this.motion?Math.min(1,(this.time-this.fileBorn)/(.85+this.fileOffsets.length*.018)):1,motion:this.motion,suspended:this.suspended,playbackFollowing:this.playing&&this.motion&&!!this.playbackPath,playbackFocus:this.playbackFocus.toArray(),flat:this.flat,preferences:{...this.preferences}}}setCutoff(e){if(this.dirty=!0,this.cutoff=M.clamp(e,0,1),!this.nodeMesh)return;const t=E(this.cutoff,this.graph)+.001;this.clipPlane.constant=t,this.lineUniforms.uCutoff.value=this.cutoff>=1?t+10:t,this.revealsActive=!0;const i=this.selected?this.nodeByID.get(this.selected):void 0;i&&i.position[0]<=t&&!this.filesGroup.visible&&(this.fileBorn=this.time,this.fileUniforms.uBorn.value=this.fileBorn),this.selectionGroup.visible=!i||i.startPosition[0]<=t,this.filesGroup.visible=!i||i.position[0]<=t;const s=this.selectionGroup.getObjectByName("selection-ring");if(s&&i&&(s.position.fromArray(C(i,E(this.cutoff,this.graph))),s.visible=i.startPosition[0]<=t),i)for(const o of this.labels)o.priority&&(o.point.x=C(i,E(this.cutoff,this.graph))[0]);this.glowMaterial&&(this.glowMaterial.uniforms.uCutoff.value=t)}animateNodes(){if(!this.nodeMesh||!this.revealsActive)return;this.pickingDirty=!0;const e=this.motion?M.smoothstep(this.time-this.graphBorn,0,.9):1,t=E(this.cutoff,this.graph);for(let i=0;i<this.graph.nodes.length;i++){const s=this.graph.nodes[i],o=s.startPosition[0]<=t?e:0;this.nodeReveal[i]=o;const n=C(s,t);this.transform.position.fromArray(n),this.glowPositions?.setX(i,n[0]),this.flat&&(this.transform.position.z*=.001),this.transform.scale.setScalar(s.radius*this.preferences.nodeScale/100*o*(1+Math.sin(o*Math.PI)*.12)),this.transform.updateMatrix(),this.nodeMesh.setMatrixAt(i,this.transform.matrix)}this.nodeMesh.instanceMatrix.needsUpdate=!0,this.revealAttribute&&(this.revealAttribute.needsUpdate=!0),this.glowPositions&&(this.glowPositions.needsUpdate=!0),this.revealsActive=e<1}animateFiles(){if(this.fileUniforms.uTime.value=this.time,this.fileUniforms.uMotion.value=Number(this.motion),!this.fileMesh)return;const e=this.motion?Math.sin(this.time*.22)*.035:0,t=Math.cos(e),i=Math.sin(e);this.fileOffsets.forEach((s,o)=>{const r=1-(1-(this.motion?M.clamp((this.time-this.fileBorn-o*.018)/.85,0,1):1))**3;this.transform.position.set((s.x*t-s.y*i)*r,(s.x*i+s.y*t)*r,s.z*r).add(this.fileOrigin),this.transform.scale.setScalar(r),this.transform.rotation.set(this.motion?this.time*.18+o:0,this.motion?this.time*.24+o:0,Math.PI/4),this.transform.updateMatrix(),this.fileMesh.setMatrixAt(o,this.transform.matrix)}),this.fileMesh.instanceMatrix.needsUpdate=!0,this.transform.rotation.set(0,0,0)}updatePicking(){if(!this.pickingDirty&&this.pickingView.equals(this.camera.matrixWorldInverse)&&this.pickingProjection.equals(this.camera.projectionMatrix))return;this.pickingView.copy(this.camera.matrixWorldInverse),this.pickingProjection.copy(this.camera.projectionMatrix),this.nodeGrid.clear(),this.markerGrid.clear();const e=new m,t=new m;this.graph.nodes.forEach((i,s)=>{if(e.fromArray(C(i,E(this.cutoff,this.graph))),this.flat&&(e.z*=.001),t.copy(e).applyMatrix4(this.camera.matrixWorldInverse),e.project(this.camera),e.z<-1||e.z>1)return;const o=this.nodeReveal[s],n=i.radius*this.preferences.nodeScale/100*o*(1+Math.sin(o*Math.PI)*.12),r=-t.z,a=Math.max(.001,r-n),h=this.width/2*Math.abs(this.camera.projectionMatrix.elements[0])*n*(1+Math.abs(t.x)/r)/a,f=this.height/2*Math.abs(this.camera.projectionMatrix.elements[5])*n*(1+Math.abs(t.y)/r)/a,d=(e.x+1)/2*this.width,u=(1-e.y)/2*this.height;this.nodeGrid.add({index:s,x:d,y:u},d,u,Math.max(12,h,f),this.width,this.height)}),this.eventMarkers.forEach(({position:i},s)=>{if(e.copy(i),this.flat&&(e.z*=.001),e.project(this.camera),e.z<-1||e.z>1)return;const o=(e.x+1)/2*this.width,n=(1-e.y)/2*this.height;this.markerGrid.add({index:s,x:o,y:n},o,n,22,this.width,this.height)}),this.pickingDirty=!1}pick(e){if(!this.nodeMesh||!this.pickMesh)return null;this.updatePicking();const t=this.renderer.domElement.getBoundingClientRect(),i=e.clientX-t.left,s=e.clientY-t.top;this.pointer.set(i/this.width*2-1,-s/this.height*2+1),this.raycaster.setFromCamera(this.pointer,this.camera);let o=null,n=1/0,r=null,a=e.pointerType==="touch"?12:6;for(const h of this.nodeGrid.at(i,s)){const f=this.graph.nodes[h.index];if(f.startPosition[0]>this.clipPlane.constant||this.nodeReveal[h.index]<.05)continue;this.nodeMesh.getMatrixAt(h.index,this.pickMatrix),this.pickMesh.matrixWorld.multiplyMatrices(this.nodeMesh.matrixWorld,this.pickMatrix),this.pickHits.length=0,this.pickMesh.raycast(this.raycaster,this.pickHits);for(const u of this.pickHits)u.distance<n&&(n=u.distance,o=f);const d=Math.hypot(h.x-i,h.y-s);d<a&&(r=f,a=d)}return o||r}pointerStart=e=>{this.pointerID=e.isPrimary&&e.button===0?e.pointerId:null,this.pointerDragged=!1,this.pointerDown.set(e.clientX,e.clientY),this.onHover(null,0,0)};pickEvent(e){if(!this.preferences.messageDots||!this.selectionGroup.visible)return null;this.updatePicking();const t=this.renderer.domElement.getBoundingClientRect(),i=e.clientX-t.left,s=e.clientY-t.top;let o=1/0,n=-1,r=0;for(const a of this.markerGrid.at(i,s)){if(this.eventMarkers[a.index].position.x>this.lineUniforms.uCutoff.value)continue;const h=Math.hypot(a.x-i,a.y-s);h>(e.pointerType==="touch"?22:10)||(r++,h<o&&(o=h,n=a.index))}return n>=0?{index:n,item:this.eventMarkers[n].item,count:r}:null}pointerEnd=e=>{const t=e.button===0&&this.pointerID===e.pointerId&&!this.pointerDragged;if(this.pointerID=null,!t||this.pointerDown.distanceTo(new G(e.clientX,e.clientY))>5)return;const i=this.pickEvent(e);if(i){this.selectEvent(i.item.id),this.onEvent(i.item.id),this.focusEvent(i.item);return}const s=this.pick(e);this.onSelect(s?.session.id||null)};pointerMove=e=>{if(this.pointerID===e.pointerId&&this.pointerDown.distanceTo(new G(e.clientX,e.clientY))>5&&(this.pointerDragged=!0),e.buttons)return;const t=this.pickEvent(e);this.markerUniforms.uHovered.value!==(t?.index??-1)&&(this.markerUniforms.uHovered.value=t?.index??-1,this.dirty=!0);const i=t?null:this.pick(e),s=i?.session.id||null;s!==this.hovered&&(this.hovered=s,this.focusUniforms.uHovered.value=s?this.nodeIndices.get(s)??-1:-1,this.dirty=!0),this.renderer.domElement.style.cursor=i||t?"pointer":"grab";const o=this.container.getBoundingClientRect();t?this.onEventHover(t.item,t.count,e.clientX-o.left,e.clientY-o.top):this.onHover(i,e.clientX-o.left,e.clientY-o.top)};pointerLeave=()=>{this.hovered=null,this.focusUniforms.uHovered.value=-1,this.markerUniforms.uHovered.value=-1,this.dirty=!0,this.onHover(null,0,0)};resize(){this.dirty=!0,this.pickingDirty=!0;const e=this.container.clientWidth,t=this.container.clientHeight;!e||!t||(this.width=e,this.height=t,this.camera.aspect=e/t,this.camera.view?.enabled&&this.frameFocus(),this.camera.updateProjectionMatrix(),this.renderer.setSize(e,t),this.composer.setSize(e,t),this.markerUniforms.uPixelRatio.value=this.renderer.getPixelRatio(),this.glowMaterial&&(this.glowMaterial.uniforms.uScale.value=t*this.renderer.getPixelRatio()*.9))}animate=()=>{this.frame=requestAnimationFrame(this.animate);const e=performance.now(),t=this.suspended?0:Math.min(.05,(e-this.previousFrame)/1e3);if(this.previousFrame=e,document.hidden||this.suspended&&!this.dirty)return;this.time+=t;const s=this.animatePlaybackCamera(t)||!!this.targetPosition;if(this.targetPosition&&this.targetLook){const l=this.motion&&!this.suspended?1-Math.exp(-4.7*t):1;this.camera.position.lerp(this.targetPosition,l),this.controls.target.lerp(this.targetLook,l),this.camera.position.distanceTo(this.targetPosition)<.05&&(this.targetPosition=void 0,this.targetLook=void 0)}const o=this.controls.update();this.camera.updateMatrixWorld();const n=this.selected?this.nodeByID.get(this.selected):void 0,r=this.preferences.focusDimming&&n&&n.startPosition[0]<=this.clipPlane.constant?1:0,a=Math.abs(this.focusUniforms.uFocus.value-r)>.001;this.focusUniforms.uFocus.value=a&&this.motion&&!this.suspended?M.damp(this.focusUniforms.uFocus.value,r,10,t):r;const h=this.motion&&this.preferences.trailFlow&&this.preferences.trails!=="off";if(this.trailUniforms.uTrailTime.value=this.time,this.trailUniforms.uTrailFlow.value=Number(h),!this.dirty&&!o&&!s&&!a&&!this.revealsActive&&!h&&!(this.motion&&this.selected&&this.selectionGroup.visible))return;this.animateNodes(),this.animateFiles(),this.lineUniforms.uReveal.value=this.motion?M.smoothstep(this.time-this.graphBorn,0,.9):1;const f=this.selectionGroup.getObjectByName("selection-ring");f&&(f.quaternion.copy(this.camera.quaternion),f.scale.setScalar(this.preferences.nodeScale/100*(this.motion?1+Math.sin(this.time*2)*.07:1)));const d=this.width,u=this.height,p=[];for(const l of this.labels){const v=l.point.clone();this.flat&&(v.z=0);const g=v.project(this.camera),y=l.priority?Math.min(260,d-24):155,P=(g.x*.5+.5)*d,b=l.priority?M.clamp(P-y/2,12,d-y-12):P,c=(-g.y*.5+.5)*u-(l.priority?24:0),w=p.some(x=>b<x.x+x.width+8&&b+y+8>x.x&&Math.abs(c-x.y)<26),S=(d>600||l.priority)&&!w&&b+y<=d-12&&l.point.x<=this.clipPlane.constant&&g.z<1&&g.z>-1&&Math.abs(g.x)<.95&&Math.abs(g.y)<.9;if(l.visible!==S&&(l.element.classList.toggle("visible",S),l.visible=S),S){const x=`translate(${b}px, ${c}px)`;l.transform!==x&&(l.element.style.transform=x,l.transform=x),p.push({x:b,y:c,width:y})}}for(const l of this.eventIcons){const v=this.eventMarkers[l.marker],g=this.iconPoint.copy(v.position);this.flat&&(g.z=0),g.project(this.camera);const y=(g.x+1)/2*d-6,P=(1-g.y)/2*u-25,b=this.preferences.messageDots&&this.selectionGroup.visible&&v.position.x<=this.clipPlane.constant&&g.z>-1&&g.z<1&&y>12&&y<d-24&&P>12&&P<u-30&&!p.some(c=>y<c.x+c.width+12&&y+24>c.x&&Math.abs(P-c.y)<24);if(b!==l.visible&&(l.element.classList.toggle("visible",b),l.visible=b),b){const c=`translate(${Math.round(y)}px, ${Math.round(P)}px)`;c!==l.transform&&(l.element.style.transform=c,l.transform=c),p.push({x:y,y:P,width:12})}}this.composer.render(),this.dirty=!1};dispose(){cancelAnimationFrame(this.frame),this.resizeObserver.disconnect(),this.controls.dispose(),this.scene.traverse(e=>{const t=e;e instanceof L&&e.dispose(),t.geometry?.dispose(),t.material&&(Array.isArray(t.material)?t.material:[t.material]).forEach(i=>i.dispose())});for(const e of this.composer.passes)e.dispose();this.composer.dispose(),this.renderer.dispose(),this.renderer.domElement.remove(),this.labelLayer.remove()}}export{Te as TimelineScene};
|