1window.initCgClerpList = function({visState, renderAll, data, cgSel}){ 2 let itemSel, weightValSel; 3 let clerpListSel = cgSel.select('.clerp-list'); 4 5 const tokenValues = data.metadata.prompt_tokens; 6 const featureById = d3.group(data.features, d => d.featureId); 7 8 function render() { 9 let nodesByTokenByLayer = d3.group(data.nodes, d => d.ctx_idx, d => d.streamIdx); 10 11 const finalData = Array.from(nodesByTokenByLayer.entries()) 12 .sort((a, b) => a[0] - b[0]) 13 .map(d => { 14 const layers = Array.from(d[1]) 15 return { 16 token: tokenValues[d[0]], 17 values: layers.sort((a, b) => a[0] - b[0]), 18 } 19 }) 20 21 clerpListSel.html('') 22 .st({ padding: '2px' }); 23 24 const featuresSel = clerpListSel.append('div.features') 25 .st({columns: '220px', columnFill: 'auto', height: '100%'}); 26 27 const tokenSel = featuresSel.appendMany('div.token', finalData) 28 .st({ 29 position: 'relative', 30 borderTop: 'solid 1px hsl(0 0 0 / 0.4)', 31 }) 32 .at({ title: d => d.token }); 33 34 const tokenLabelSel = tokenSel.append('div') 35 .st({ 36 fontSize: 11, 37 color: 'hsl(0 0 0 /0.4)', 38 fontWeight: '400', 39 pointerEvents: 'none', 40 padding: '2px', 41 zIndex: 1e6, 42 textWrap: 'nowrap', 43 overflow: 'hidden', 44 textOverflow: 'ellipsis', 45 textAlign: 'center', 46 marginTop: 5, 47 }); 48 49 tokenLabelSel.append('span').text('â'); 50 tokenLabelSel.append('span') 51 .text(d => util.ppToken(d.token)) 52 .st({ 53 background: 'hsl(55deg 0% 85% / 0.6)', 54 borderRadius: 4, 55 padding: '0 2px', 56 color: 'black', 57 fontWeight: '700', 58 }); 59 tokenLabelSel.append('span').text('â'); 60 61 const layerSel = tokenSel 62 .appendMany('div.layer', d => d.values) 63 .st({ position: 'relative' }); 64 65 const nodeSel = layerSel.appendMany('div.node', d => d[1].entries().map(d => d[1])); 66 67 itemSel = nodeSel.append('div.feature-row') 68 .classed('clicked', e => e.nodeId == visState.clickedId) 69 .classed('pinned', d => visState.pinnedIds.includes(d.nodeId)); 70 71 utilCg.renderFeatureRow(itemSel, visState, renderAll); 72 73 } 74 renderAll.hClerpUpdate.fns.push(render); 75 renderAll.clickedId.fns.push(render); 76 renderAll.hoveredId.fns.push(() => itemSel?.classed('hovered', e => e.featureId == visState.hoveredId)); 77 renderAll.pinnedIds.fns.push(() => itemSel?.classed('pinned', d => visState.pinnedIds.includes(d.nodeId))); 78 79 renderAll.clickedId.fns.push(() => { 80 if (!itemSel || visState.isDev) return 81 82 var hNode = itemSel.filter(d => d.featureId == visState.clickedId).node() 83 if (!hNode) return 84 var cNode = clerpListSel.node() 85 86 var scrollTop = hNode.offsetTop - cNode.offsetTop - cNode.clientHeight / 2 + hNode.clientHeight / 2 87 scrollTop = d3.clamp(0, scrollTop, cNode.scrollHeight - cNode.clientHeight) 88 if (scrollTop < cNode.scrollTop - cNode.clientHeight / 2 || scrollTop > cNode.scrollTop + cNode.clientHeight / 2) { 89 cNode.scrollTop = scrollTop; 90 } 91 }); 92 93} 94 95window.init?.()
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.