@divami-artefacts/ai-design-system 1.0.23 → 1.0.25

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.
@@ -1,2 +1,2 @@
1
1
  import { RadialFanTreeChartProps } from './types';
2
- export declare function RadialFanTreeChart({ total, items: rawByContractor, 'data-testid': testId }: RadialFanTreeChartProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function RadialFanTreeChart({ total, totalLabel, items: rawByContractor, 'data-testid': testId }: RadialFanTreeChartProps): import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,7 @@
1
1
  import { NCEContractorRow } from '../../types';
2
2
  export interface RadialFanTreeChartProps {
3
3
  total: number;
4
+ totalLabel?: string;
4
5
  items: NCEContractorRow[];
5
6
  'data-testid'?: string;
6
7
  }
@@ -1,2 +1,2 @@
1
1
  import { RankedCardLeaderboardProps } from './types';
2
- export declare function RankedCardLeaderboard({ items: rawItems, 'data-testid': testId }: RankedCardLeaderboardProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function RankedCardLeaderboard({ items: rawItems, "data-testid": testId, }: RankedCardLeaderboardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
1
  import { WeeklyFlowProps } from './types';
2
- export declare function WeeklyFlow({ items: items, 'data-testid': testId }: WeeklyFlowProps): import("react/jsx-runtime").JSX.Element;
2
+ export declare function WeeklyFlow({ items: items, "data-testid": testId, }: WeeklyFlowProps): import("react/jsx-runtime").JSX.Element;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`react-dom/client`),t=require(`react`),n=require(`react/jsx-runtime`);function r({children:e,className:t=``}){return(0,n.jsx)(`div`,{className:`d3-chart ${t}`.trim(),children:e})}var i={bg:`#0C0E12`,bgL:`#0C1420`,sf:`#13161B`,bd:`#22262F`,blue:`#4C93D9`,cyan:`#36BFFA`,orange:`#EC772A`,red:`#EC772A`,green:`#5DA537`,purple:`#818FF8`,amber:`#EEBF3B`,t1:`#F7F9FA`,t2:`#B3B5B6`,t3:`#94979C`,t4:`#334155`},a=[i.blue,i.amber,i.purple,i.green,i.red],o={font:`400 16px 'Satoshi Variable', 'DM Sans', sans-serif`,color:`#F7F7F7`,letterSpacing:`0px`},s={font:`500 16px 'Satoshi Variable', 'DM Sans', sans-serif`,color:`#F7F7F7`},c={font:`400 18px 'Satoshi Variable', 'DM Sans', sans-serif`,color:`#B3B5B6`,letterSpacing:`0px`};function l(e,t=1){let n=e.replace(`#`,``);return`rgba(${parseInt(n.substring(0,2),16)},${parseInt(n.substring(2,4),16)},${parseInt(n.substring(4,6),16)},${t})`}function u(e,t,n){return e+(t-e)*n}function d(e,t,n){let r=e=>{let t=e.replace(`#`,``);return[parseInt(t.substring(0,2),16),parseInt(t.substring(2,4),16),parseInt(t.substring(4,6),16)]},[i,a,o]=r(e),[s,c,l]=r(t),d=e=>Math.max(0,Math.min(255,Math.round(e)));return[d(u(i,s,n)),d(u(a,c,n)),d(u(o,l,n))].map(e=>e.toString(16).padStart(2,`0`)).join(``).replace(/^/,`#`)}function f(e,t,n,r=2){e.width=t*r,e.height=n*r;let i=e.getContext(`2d`);return i.scale(r,r),i}function p(e,t,n,r,i,a=.3){let o=e.createRadialGradient(t,n,0,t,n,r);o.addColorStop(0,l(i,a)),o.addColorStop(1,l(i,0)),e.fillStyle=o,e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fill()}function m(e,t,n,r,a=50,o=l(i.blue,.05)){for(let i=0;i<a;i++)e.beginPath(),e.arc((Math.sin(r*.001+i*23)*.5+.5)*t,(Math.cos(r*8e-4+i*37)*.5+.5)*n,.6,0,Math.PI*2),e.fillStyle=o,e.fill()}function h(e,t,n,r,i=.015){e.fillStyle=`rgba(0,0,0,${i})`;let a=r*.5%6;for(let r=a;r<n;r+=3)e.fillRect(0,r,t,1)}function g(e,t,n,r,a=l(i.t1,.08)){e.strokeStyle=a,e.lineWidth=1,e.setLineDash([3,3]),e.beginPath(),e.moveTo(t,n),e.lineTo(t,r),e.stroke(),e.setLineDash([])}function _({visible:e,x:r,y:a,content:o,parentW:s}){let c=(0,t.useRef)(null);if((0,t.useLayoutEffect)(()=>{let t=c.current;if(!t)return;let n=t.offsetWidth,l=r-n/2,u=a-58;l<4&&(l=4),l+n>(s??400)-4&&(l=(s??400)-n-4),u<4&&(u=a+16),t.style.transform=`translate(${l}px, ${u}px)`,t.style.opacity=e?`1`:`0`;let d=o&&typeof o==`object`&&o.color?o.color:i.blue;t.style.setProperty(`--tooltip-accent`,d??i.blue)},[e,r,a,s,o]),!o)return null;let l=typeof o==`object`,u=l?o.label:null,d=l?o.value:o,f=l?o.sublabel:null;return(0,n.jsxs)(`div`,{ref:c,style:{position:`absolute`,top:0,left:0,minWidth:80,pointerEvents:`none`,background:i.sf,border:`1px solid ${i.bd}`,borderLeft:`2px solid var(--tooltip-accent)`,borderRadius:6,padding:`8px 12px`,opacity:0,transition:`opacity 0.15s ease`,zIndex:20,fontFamily:`'Satoshi Variable', 'DM Sans', sans-serif`},children:[u&&(0,n.jsx)(`div`,{style:{fontSize:14,fontWeight:400,color:i.t2,marginBottom:3,whiteSpace:`nowrap`,lineHeight:`20px`},children:u}),(0,n.jsx)(`div`,{style:{fontSize:16,fontWeight:500,color:i.t1,whiteSpace:`nowrap`,lineHeight:`22px`},children:d}),f&&(0,n.jsx)(`div`,{style:{fontSize:14,fontWeight:400,color:`var(--tooltip-accent)`,marginTop:3,whiteSpace:`nowrap`,lineHeight:`20px`},children:f})]})}function v(e,{width:n,height:r,onClick:i,enabled:a=!0}){let o=(0,t.useRef)({x:-1,y:-1,over:!1}),s=(0,t.useRef)(null),c=(0,t.useRef)([]),l=(0,t.useRef)(null),[u,d]=(0,t.useState)({visible:!1,x:0,y:0,content:null}),f=(0,t.useCallback)((e,t,n)=>{l.current&&clearTimeout(l.current),l.current=setTimeout(()=>{d({visible:!0,x:e,y:t,content:n})},30)},[]),p=(0,t.useCallback)(()=>{l.current&&clearTimeout(l.current),d(e=>e.visible?{visible:!1,x:e.x,y:e.y,content:e.content}:e)},[]);return(0,t.useEffect)(()=>{let t=e.current;if(!t||!a)return;let u=e=>{let i=t.getBoundingClientRect(),a=n/i.width,l=r/i.height;o.current.x=(e.clientX-i.left)*a,o.current.y=(e.clientY-i.top)*l,o.current.over=!0;let u=null,d=c.current;for(let e=d.length-1;e>=0;e--)if(d[e].test(o.current.x,o.current.y)){u=d[e];break}let m=s.current;s.current=u?u.id:null,t.style.cursor=u?`pointer`:`default`,u?f((e.clientX-i.left)*a,(e.clientY-i.top)*l,u.data):m&&p()},d=()=>{o.current={x:-1,y:-1,over:!1},s.current&&(s.current=null,t.style.cursor=`default`,p())},m=()=>{if(s.current&&i){let e=c.current.find(e=>e.id===s.current);e&&i(e.id,e.data)}};return t.addEventListener(`mousemove`,u),t.addEventListener(`mouseleave`,d),t.addEventListener(`click`,m),()=>{t.removeEventListener(`mousemove`,u),t.removeEventListener(`mouseleave`,d),t.removeEventListener(`click`,m),l.current&&clearTimeout(l.current)}},[e,n,r,a,i,f,p]),{mouseRef:o,hoveredRef:s,tooltip:u,showTooltip:f,hideTooltip:p,hitZonesRef:c}}function y(e,t,n,r,i,a){e.push({id:t,data:a,test:(e,t)=>(e-n)**2+(t-r)**2<=i*i})}function b(e,t,n,r,i,a,o){e.push({id:t,data:o,test:(e,t)=>e>=n&&e<=n+i&&t>=r&&t<=r+a})}var x=e=>1-(1-e)**3,S=e=>1-(1-e)**4,C=e=>e===1?1:1-2**(-10*e),w=e=>{let t=1.70158;return 1+(t+1)*(e-1)**3+t*(e-1)**2},T=(e,t=.04,n=.001)=>Math.sin(e*t)*Math.exp(-Math.min(e*n,4)),E=(e,t,n,r=x)=>{let i=Math.min(.06,.5/n),a=t*i,o=1-(n-1)*i;return r(Math.max(0,Math.min((e-a)/o,1)))};function D(e,t,n=.12){e.forEach((r,i)=>{let a=i===t?1:0,o=r+(a-r)*n;Math.abs(o-a)<.005?a===0?e.delete(i):e.set(i,1):e.set(i,o)}),t&&!e.has(t)&&e.set(t,0)}var O=760,k=250;function A({rows:e=[],variant:a,className:o,colors:s}){let c=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),{mouseRef:m,hoveredRef:h,tooltip:b,hitZonesRef:x}=v(c,{width:O,height:k});return(0,t.useEffect)(()=>{let t=c.current;if(!t)return;let n=f(t,O,k);d.current=0;let r=s?.line??i.blue,o=s?.point??i.blue,_=s?.axisLine??i.bd,v=s?.areaFill??i.blue,b={top:24,right:24,bottom:44,left:24},S=O-b.left-b.right,w=k-b.top-b.bottom,E,A=()=>{d.current++;let t=d.current;if(n.clearRect(0,0,O,k),e.length<2){E=requestAnimationFrame(A);return}let s=e.map(e=>e.pricing??0),c=Math.max(100,...s),f=t=>b.left+t/(e.length-1)*S,j=e=>b.top+(1-e/c)*w,M=C(Math.min(t/48,1)),N=Math.max(2,Math.floor(M*e.length));D(u.current,h.current),x.current=[],n.strokeStyle=l(i.bd,.2),n.lineWidth=.5;for(let e=0;e<=4;e++){let t=b.top+e/4*w;n.beginPath(),n.moveTo(b.left,t),n.lineTo(b.left+S,t),n.stroke()}if(n.strokeStyle=l(_,.4),n.lineWidth=1,n.setLineDash([]),n.beginPath(),n.moveTo(b.left,j(0)),n.lineTo(b.left+S,j(0)),n.stroke(),m.current.over&&h.current){let e=parseInt(h.current.split(`-`)[1]);isNaN(e)||g(n,f(e),b.top,b.top+w)}if(a===`area`&&N>1){let t=n.createLinearGradient(0,b.top,0,b.top+w);t.addColorStop(0,l(v,.12)),t.addColorStop(1,l(v,0)),n.fillStyle=t,n.beginPath(),n.moveTo(f(0),b.top+w);for(let t=0;t<N;t++)n.lineTo(f(t),j(e[t].pricing??0));n.lineTo(f(N-1),b.top+w),n.closePath(),n.fill()}if(N>1){n.strokeStyle=l(r,.85),n.lineWidth=2,n.setLineDash([]),n.beginPath();for(let t=0;t<N;t++){let r=f(t),i=j(e[t].pricing??0);t===0?n.moveTo(r,i):n.lineTo(r,i)}n.stroke()}for(let r=0;r<N;r++){let s=f(r),c=j(e[r].pricing??0),d=`sc-${r}`,m=u.current.get(d)??0,h=r===e.length-1;y(x.current,d,s,c,12,{label:e[r].vendor,value:String(e[r].pricing??0),color:h?i.red:o}),m>0&&p(n,s,c,16*m,o,.2*m);let g=h?T(t,.05,5e-4):0,_=a===`area`?5:6;h?(n.shadowColor=l(i.red,.5),n.shadowBlur=(8+g*4)*(1+m*.5),n.fillStyle=i.red,n.beginPath(),n.arc(s,c,(_+g*1.5)*(1+m*.3),0,Math.PI*2),n.fill(),n.shadowBlur=0):(n.fillStyle=l(o,.7+m*.3),n.beginPath(),n.arc(s,c,_+m*2,0,Math.PI*2),n.fill()),n.font=`10px 'JetBrains Mono', monospace`,n.fillStyle=l(i.t3,.6+m*.3),n.textAlign=`center`,n.fillText(e[r].vendor,s,k-14)}E=requestAnimationFrame(A)};return A(),()=>cancelAnimationFrame(E)},[e,a,s]),(0,n.jsx)(r,{className:o,children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:O,height:k},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`${a} chart`,style:{width:O,height:k,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...b,parentW:O,parentH:k})]})})}function j({rows:e=[],className:t,colors:r}){return(0,n.jsx)(A,{rows:e,variant:`area`,className:t,colors:r})}var M=760,N=280;function ee({rows:e=[],className:o,colors:s}){let c=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),{hoveredRef:m,tooltip:h,hitZonesRef:g}=v(c,{width:M,height:N});return(0,t.useEffect)(()=>{let t=c.current;if(!t)return;let n=f(t,M,N);d.current=0;let r=s?.bars??a,o=s?.axisLine??i.bd,h=s?.valueLabel??i.t2,_={top:24,right:24,bottom:56,left:24},v=N-_.top-_.bottom,y=(M-_.left-_.right)/Math.max(e.length,1),x=Math.max(100,...e.map(e=>e.pricing??0)),C=_.top+v,w,T=()=>{d.current++;let t=d.current;n.clearRect(0,0,M,N);let a=S(Math.min(t/48,1));D(u.current,m.current),g.current=[],n.strokeStyle=l(o,.4),n.lineWidth=1,n.setLineDash([]),n.beginPath(),n.moveTo(_.left,C),n.lineTo(M-_.right,C),n.stroke(),e.forEach((t,o)=>{let s=_.left+o*y,c=E(a,o,e.length,S),d=x>0?(t.pricing??0)/x*v:0,f=Math.max(d>0?4:0,d*c),m=r[o%r.length],w=u.current.get(t.id??`bar-${o}`)??0;b(g.current,t.id??`bar-${o}`,s+4,C-f,y-8,f,{label:t.vendor,value:String(t.pricing??0),color:m}),f>0&&(w>0&&p(n,s+y/2,C-f/2,y*.8,m,.12*w),n.shadowColor=l(m,.2*(w>0?w:0)),n.shadowBlur=w>0?6:0,n.fillStyle=l(m,.5+w*.25),n.beginPath(),n.roundRect(s+4,C-f,y-8,f,[4,4,0,0]),n.fill(),n.shadowBlur=0,w>0&&(n.strokeStyle=l(m,.4*w),n.lineWidth=1,n.beginPath(),n.roundRect(s+4,C-f,y-8,f,[4,4,0,0]),n.stroke())),c>.5&&f>0&&(n.globalAlpha=Math.min(1,(c-.5)*2),n.font=`bold 10px 'JetBrains Mono', monospace`,n.fillStyle=w>0?m:l(h,.7),n.textAlign=`center`,n.fillText(String(t.pricing??``),s+y/2,C-f-6),n.globalAlpha=1),n.font=`${w>0?`bold `:``}9px 'JetBrains Mono', monospace`,n.fillStyle=w>0?m:l(i.t3,.6),n.textAlign=`center`,n.fillText(t.vendor,s+y/2,N-14)}),w=requestAnimationFrame(T)};return T(),()=>cancelAnimationFrame(w)},[e,s]),(0,n.jsx)(r,{className:o,children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:M,height:N},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`bar chart`,style:{width:M,height:N,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...h,parentW:M,parentH:N})]})})}function P({width:e,height:t,message:r=`No data available`,"data-testid":i}){return(0,n.jsx)(`div`,{"data-testid":i,style:{width:e,height:t,display:`flex`,alignItems:`center`,justifyContent:`center`,borderRadius:8,background:`rgba(255,255,255,0.03)`,color:`rgba(255,255,255,0.35)`,fontSize:14,fontFamily:`'Satoshi Variable', 'DM Sans', sans-serif`},children:r})}function te({expanded:e,onToggle:t,labelExpanded:r=`View Less`,labelCollapsed:i=`View More`,"data-testid":a}){return(0,n.jsxs)(`button`,{type:`button`,"data-testid":a,onClick:t,style:{display:`flex`,width:90,height:20,justifyContent:`center`,alignItems:`center`,gap:4,boxSizing:`border-box`,border:`none`,borderRadius:6,color:`#71B941`,fontSize:14,fontFamily:`'Satoshi Variable', 'DM Sans', sans-serif`,fontStyle:`normal`,fontWeight:400,lineHeight:`19.5px`,textAlign:`center`,cursor:`pointer`,userSelect:`none`},children:[e?r:i,(0,n.jsx)(`svg`,{width:`10`,height:`10`,viewBox:`0 0 10 10`,fill:`none`,style:{transform:e?`rotate(180deg)`:`rotate(0deg)`},children:(0,n.jsx)(`path`,{d:`M2 3.5L5 6.5L8 3.5`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]})}var F=680,I=42,ne=10,re=24,ie=24,ae=8,oe=[i.green,i.blue,i.amber,i.red];function se(e){let t=Math.abs(e),n=e<0?`-`:``;return t>=1e6?`${n}£${(t/1e6).toFixed(1)}M`:t>=1e3?`${n}£${(t/1e3).toFixed(1)}K`:`${n}£${t.toFixed(0)}`}function ce({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),c=(0,t.useRef)(0),u=(0,t.useRef)(new Map),[d,g]=(0,t.useState)(!1),b=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),S=(0,t.useMemo)(()=>[...b].sort((e,t)=>(t.percentage??0)-(e.percentage??0)),[b]),C=(0,t.useMemo)(()=>d?S:S.slice(0,ae),[S,d]),w=C.length,T=re+ie+w*I+Math.max(0,w-1)*ne,{hoveredRef:E,tooltip:D,hitZonesRef:O}=v(a,{width:F,height:T});return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,F,T);c.current=0;let n=F*.13,r=F*.08,d=F-n-r,g,_=()=>{c.current++;let e=c.current;t.clearRect(0,0,F,T),t.letterSpacing=o.letterSpacing,O.current=[],u.current.forEach((e,t)=>{let n=t===E.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?u.current.delete(t):u.current.set(t,1):u.current.set(t,r)}),E.current&&!u.current.has(E.current)&&u.current.set(E.current,0),m(t,F,T,e,40,l(i.blue,.04)),C.forEach((r,i)=>{let a=oe[i%oe.length],c=u.current.get(r.id)??0,f=re+i*(I+ne);t.fillStyle=l(a,.04+c*.04),t.beginPath(),t.roundRect(n,f,d,I,3),t.fill(),t.strokeStyle=l(a,.08),t.lineWidth=1,t.setLineDash([4,4]),t.beginPath(),t.moveTo(n,f+I/2),t.lineTo(n+d,f+I/2),t.stroke(),t.setLineDash([]);let m=(r.percentage??0)/100,h=n+d*Math.min(m,m*x(Math.min(1,e*.005)));if(h>n+4){let e=t.createLinearGradient(n,0,h,0);e.addColorStop(0,l(a,.02)),e.addColorStop(1,l(a,.25+c*.15)),t.fillStyle=e,t.beginPath(),t.roundRect(n,f+2,h-n,I-4,2),t.fill()}p(t,h,f+I/2,18+c*8,a,.3+c*.2),t.beginPath(),t.arc(h,f+I/2,5+c*2,0,Math.PI*2),t.fillStyle=l(a,.9),t.fill();let g={label:r.name,value:`${r.percentage??0}% commitment`,sublabel:`Base: ${se(r.base??0)} · Variations: ${se(r.variation??0)}`,color:a};y(O.current,r.id,h,f+I/2,14,g),t.font=s.font,t.fillStyle=l(a,.9+c*.1),t.textAlign=`left`,t.textBaseline=`middle`,t.fillText(`${r.percentage??0}%`,h+10,f+I/2),t.font=`${c>0?`bold `:``}`+o.font,t.fillStyle=c>0?a:o.color,t.textAlign=`right`,t.fillText(r.abbreviation??r.name.slice(0,6),n-8,f+I/2)}),t.strokeStyle=l(i.t3,.3),t.lineWidth=1,t.setLineDash([]),t.beginPath(),t.moveTo(n+d,re),t.lineTo(n+d,re+(w-1)*(I+ne)+I),t.stroke(),h(t,F,T,e,.015),g=requestAnimationFrame(_)};return _(),()=>cancelAnimationFrame(g)},[C,T]),S.length===0?(0,n.jsx)(P,{width:F,height:160,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{width:F},children:[(0,n.jsxs)(`div`,{style:{position:`relative`},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Commitment race — contractors ranked by commitment percentage`,style:{width:F,height:T,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...D,parentW:F,parentH:T})]}),b.length>ae&&(0,n.jsx)(`div`,{style:{marginTop:8},children:(0,n.jsx)(te,{expanded:d,onToggle:()=>g(e=>!e)})})]})}var le=480,ue=340;function de({value:e,confirmed:r,total:a,"data-testid":s}){let u=(0,t.useRef)(null),d=(0,t.useRef)(0);return(0,t.useEffect)(()=>{let t=u.current;if(!t)return;let n=f(t,le,ue);d.current=0;let s=le/2,m=Math.PI,h=2*Math.PI,g=Math.PI,_,v=()=>{d.current++;let t=d.current;n.clearRect(0,0,le,ue),n.letterSpacing=o.letterSpacing;let u=x(Math.min(t/80,1)),f=w(Math.min(t/72,1));n.beginPath(),n.arc(s,220,120,m,h),n.strokeStyle=l(i.bd,.35),n.lineWidth=46,n.stroke(),[{start:0,end:.33,color:i.red},{start:.33,end:.66,color:i.amber},{start:.66,end:1,color:i.green}].forEach(e=>{let t=m+e.start*g,r=m+e.end*g;n.beginPath(),n.arc(s,220,194/2,t,r),n.strokeStyle=l(e.color,.12),n.lineWidth=42,n.stroke()}),[{label:`Low`,angle:m+.16*g},{label:`Mid`,angle:m+.5*g},{label:`High`,angle:m+.84*g}].forEach(({label:e,angle:t})=>{let r=s+Math.cos(t)*166,i=220+Math.sin(t)*166;n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(e,r,i+3)});let y=m+e/100*g*u,b=e>=66?i.green:e>=33?i.amber:i.red;p(n,s+Math.cos(y)*194/2,220+Math.sin(y)*194/2,18,b,.35*u),n.beginPath(),n.arc(s,220,194/2,m,y),n.strokeStyle=l(b,.7*u),n.lineWidth=38,n.lineCap=`round`,n.stroke(),n.lineCap=`butt`;let S=m+e/100*g*f,C=s+Math.cos(S)*82,T=220+Math.sin(S)*82,E=s-Math.cos(S)*14,D=220-Math.sin(S)*14;n.strokeStyle=l(b,.18*f),n.lineWidth=6,n.lineCap=`round`,n.beginPath(),n.moveTo(E,D),n.lineTo(C,T),n.stroke(),n.strokeStyle=l(i.t1,.92*f),n.lineWidth=2,n.lineCap=`round`,n.beginPath(),n.moveTo(E,D),n.lineTo(C,T),n.stroke(),n.beginPath(),n.arc(C,T,3,0,Math.PI*2),n.fillStyle=l(b,.9*f),n.fill(),p(n,s,220,20,b,.25*f),n.beginPath(),n.arc(s,220,9,0,Math.PI*2),n.strokeStyle=l(b,.5*f),n.lineWidth=1.5,n.stroke(),n.beginPath(),n.arc(s,220,5,0,Math.PI*2),n.fillStyle=i.t1,n.fill(),u>.5&&(n.globalAlpha=Math.min(1,(u-.5)/.5),n.font=`500 24px 'Satoshi Variable', 'DM Sans', sans-serif`,n.fillStyle=b,n.textAlign=`center`,n.fillText(`${Math.round(e*f)}%`,s,182),n.globalAlpha=1),u>.7&&(n.globalAlpha=Math.min(1,(u-.7)/.3),n.font=c.font,n.fillStyle=c.color,n.textAlign=`center`,n.fillText(`NCEs confirmed`,s,252),n.font=c.font,n.fillStyle=c.color,n.fillText(`${r} of ${a} NCEs are confirmed compensation events`,s,272),n.globalAlpha=1);for(let e=0;e<=10;e++){let t=m+e/10*g;if(n.strokeStyle=l(i.bd,.5),n.lineWidth=e%5==0?1.5:.8,n.beginPath(),n.moveTo(s+Math.cos(t)*122,220+Math.sin(t)*122),n.lineTo(s+Math.cos(t)*128,220+Math.sin(t)*128),n.stroke(),e%5==0){let r=s+Math.cos(t)*138,i=220+Math.sin(t)*138;n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(`${e*10}%`,r,i+3)}}_=requestAnimationFrame(v)};return v(),()=>cancelAnimationFrame(_)},[e,r,a]),(0,n.jsx)(`div`,{"data-testid":s,style:{position:`relative`,width:le,height:ue},children:(0,n.jsx)(`canvas`,{ref:u,role:`img`,"aria-label":`Compensation event gauge — ${e}% of NCEs confirmed as compensation events`,style:{width:le,height:ue,display:`block`}})})}function fe(e,n,r,i,a=!0,o={}){let s=(0,t.useRef)(0),{easing:c=x,durationFrames:l=48}=o;(0,t.useEffect)(()=>{let t=e.current;if(!t||!n||!r)return;let o=t.getContext(`2d`);if(!o)return;t.width=n*2,t.height=r*2,o.scale(2,2);let u;s.current=0;let d=()=>{s.current++;let e=s.current;o.clearRect(0,0,n,r);let t=a?Math.min(e/l,1):1;if(i(o,c(t),e),t<1)u=requestAnimationFrame(d);else{let e=()=>{s.current++,o.clearRect(0,0,n,r),i(o,1,s.current),u=requestAnimationFrame(e)};u=requestAnimationFrame(e)}};return d(),()=>cancelAnimationFrame(u)},[n,r,a])}var L=780,pe=234,me=130,he=52,ge=[i.blue,i.amber,i.purple,i.green],_e=[`Base Value`,`Variations`,`Commitment`],ve=[`Base`,`Var`,`Commit`];function ye({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(new Map),{hoveredRef:u,tooltip:d,hitZonesRef:f}=v(a,{width:L,height:pe}),g=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),b=(0,t.useMemo)(()=>{let e=Math.max(...g.map(e=>e.base??0)),t=Math.max(...g.map(e=>e.variation??0));return g.map((n,r)=>{let i=L*(.12+r*.19),a=me,o=Math.min(L*.075,he),s=ge[r%ge.length],c=[(n.base??0)/(e||1)*100,(n.variation??0)/(t||1)*100,n.percentage??0],l=[`£${n.base??0}M`,`£${n.variation??0}M`,`${n.percentage??0}%`],u=c.map((e,t)=>{let n=-Math.PI/2+t/_e.length*Math.PI*2,r=e/100,s=o*Math.max(.08,r);return{name:_e[t],short:ve[t],label:l[t],val:Math.round(e),x:i+Math.cos(n)*s,y:a+Math.sin(n)*s,angle:n,norm:r}}),d=u.reduce((e,t)=>e+t.x,0)/u.length,f=u.reduce((e,t)=>e+t.y,0)/u.length,p=Math.sqrt(u.reduce((e,t)=>e+(t.x-d)**2+(t.y-f)**2,0)/u.length);return{...n,cx:i,cy:a,baseR:o,stars:u,scatter:p,color:s}})},[g]);return fe(a,L,pe,(e,t,n)=>{D(s.current,u.current),f.current=[],m(e,L,pe,n,30),b.forEach((t,r)=>{let a=t.color,c=`constellation-${r}`,u=s.current.get(c)??0;e.beginPath(),e.arc(t.cx,t.cy,t.baseR+5,0,Math.PI*2),e.strokeStyle=l(i.bd,.08+.08*u),e.lineWidth=.5,e.stroke(),e.beginPath(),t.stars.forEach((t,n)=>{n===0?e.moveTo(t.x,t.y):e.lineTo(t.x,t.y)}),e.closePath(),e.fillStyle=l(a,.04+.03*u),e.fill(),e.strokeStyle=l(a,.15+.1*u),e.lineWidth=.8,e.stroke(),t.stars.forEach((i,c)=>{let u=T(n,.05,5e-4)*.3+.7,d=3.5*u,p=`star-${r}-${c}`,m=s.current.get(p)??0,h=e.createRadialGradient(i.x,i.y,0,i.x,i.y,d*4);h.addColorStop(0,l(a,(.2+.1*m)*u)),h.addColorStop(1,l(a,0)),e.fillStyle=h,e.beginPath(),e.arc(i.x,i.y,d*4,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(i.x,i.y,d+m*2,0,Math.PI*2),e.fillStyle=l(a,(.8+.2*m)*u),e.fill();let g=Math.sin(i.angle)<-.3;e.textAlign=`center`,e.textBaseline=`middle`,g?(e.font=o.font,e.fillStyle=l(a,.5+.15*m),e.fillText(i.short,i.x,i.y-24),e.font=o.font,e.fillStyle=l(a,.8+.15*m),e.fillText(i.label,i.x,i.y-11)):(e.font=o.font,e.fillStyle=l(a,.5+.15*m),e.fillText(i.short,i.x,i.y+11),e.font=o.font,e.fillStyle=l(a,.8+.15*m),e.fillText(i.label,i.x,i.y+24)),y(f.current,p,i.x,i.y,d*4+2,{label:i.name,value:i.label,sublabel:t.abbreviation??t.name.slice(0,6),color:a})}),u>0&&p(e,t.cx,t.cy,16*u,a,.15*u),e.beginPath(),e.arc(t.cx,t.cy,t.baseR+12,0,Math.PI*2),e.strokeStyle=l(a,.1+T(n,.03,5e-4)*.05),e.lineWidth=1,e.stroke(),e.font=o.font,e.textAlign=`center`,e.textBaseline=`alphabetic`,e.fillStyle=u>0?t.color:o.color,e.fillText(t.abbreviation??t.name.slice(0,6),t.cx,t.cy+t.baseR+26),y(f.current,c,t.cx,t.cy,t.baseR+5,{label:t.name,value:`£${t.total??0}M total`,sublabel:`${t.percentage??0}% committed · scatter ${t.scatter.toFixed(1)}`,color:a})}),e.font=c.font,e.textAlign=`center`,e.textBaseline=`middle`,e.fillStyle=c.color,e.fillText(`▲ top = Base value · ▼▸ lower-right = Variations · ◂▼ lower-left = Commitment % · hover stars for details`,L/2,pe-14),h(e,L,pe,n,.012)},!0),b.length===0?(0,n.jsx)(P,{width:L,height:pe,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:L,height:pe},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Contract value breakdown per contractor — multi-KPI constellation chart`,style:{width:L,height:pe,display:`block`}}),(0,n.jsx)(_,{...d,parentW:L,parentH:pe})]})}var be=680,xe=220,Se=8,Ce=[i.blue,i.amber,i.purple,i.green],R={left:8,right:80,top:16,bottom:38},we=88,z=18;function Te(e){let t=Math.abs(e),n=e<0?`-`:``;return t>=1e6?`${n}£${(t/1e6).toFixed(1)}M`:t>=1e3?`${n}£${(t/1e3).toFixed(1)}K`:`${n}£${t.toFixed(0)}`}function Ee({data:e,"data-testid":r}){let a=(0,t.useRef)(null),u=(0,t.useRef)(new Map),[d,f]=(0,t.useState)(!1),{items:m=[],totals:h}=e,g=m.filter(e=>typeof e==`object`&&!!e),y=[...g].sort((e,t)=>(t.total??0)-(e.total??0)),x=d?y:y.slice(0,Se),C=x.length,w=Math.max(...y.map(e=>Math.abs(e.total??0)),1),T=Math.max(xe,R.top+R.bottom+C*z+Math.max(0,C-1)*8),O=be-R.left-we-R.right,k=C>1?(T-R.top-R.bottom-C*z)/(C-1):0,A=g.length===0,{hoveredRef:j,tooltip:M,hitZonesRef:N}=v(a,{width:be,height:T});return fe(a,be,T,(e,t)=>{D(u.current,j.current),N.current=[],x.forEach((n,r)=>{let a=Ce[r%Ce.length],c=E(t,r,C,S),d=R.top+r*(z+k),f=R.left+we,m=u.current.get(n.id)??0,h=Math.max(n.base??0,0),g=Math.max(n.total??0,0),_=h/w*O*c,v=g/w*O*c,y=v-_;e.font=o.font,e.fillStyle=m>0?a:o.color,e.textAlign=`right`,e.textBaseline=`middle`,e.fillText(n.abbreviation??n.name.slice(0,6),f-8,d+z/2),e.fillStyle=l(i.bd,.25),e.beginPath(),e.roundRect(f,d,O,z,4),e.fill(),_>0&&(m>0&&p(e,f+_/2,d+z/2,_*.3,a,.1*m),e.fillStyle=l(a,.5+m*.15),e.beginPath(),e.roundRect(f,d,_,z,4),e.fill()),y>2&&(e.fillStyle=l(a,.22+m*.08),e.beginPath(),e.roundRect(f+_,d,y,z,[0,4,4,0]),e.fill(),e.setLineDash([2,3]),e.strokeStyle=l(a,.55),e.lineWidth=1,e.beginPath(),e.moveTo(f+_,d+3),e.lineTo(f+_,d+z-3),e.stroke(),e.setLineDash([])),m>0&&v>0&&(e.strokeStyle=l(a,.5*m),e.lineWidth=1,e.setLineDash([]),e.beginPath(),e.roundRect(f,d,v,z,4),e.stroke()),c>.35&&(e.globalAlpha=Math.min(1,(c-.35)/.4),e.font=s.font,e.fillStyle=m>0?a:s.color,e.textAlign=`left`,e.textBaseline=`middle`,e.fillText(Te(n.total??0),f+v+6,d+z/2),e.globalAlpha=1),b(N.current,n.id,f,d,Math.max(v,1),z,{label:n.name,value:`${Te(n.total??0)} total`,sublabel:`Base ${Te(n.base??0)} + Var ${Te(n.variation??0)} · ${n.percentage??0}% committed`,color:a})});let n=T-14;e.textBaseline=`middle`,e.font=c.font,e.textAlign=`left`,e.fillStyle=l(i.blue,.5),e.beginPath(),e.roundRect(R.left+we,n-3,14,6,2),e.fill(),e.fillStyle=c.color,e.fillText(`base value`,R.left+we+18,n),e.fillStyle=l(i.blue,.22),e.beginPath(),e.roundRect(R.left+we+94,n-3,14,6,2),e.fill(),e.setLineDash([2,3]),e.strokeStyle=l(i.blue,.5),e.lineWidth=.5,e.beginPath(),e.moveTo(R.left+we+101,n-3),e.lineTo(R.left+we+101,n+3),e.stroke(),e.setLineDash([]),e.fillStyle=c.color,e.fillText(`approved variations`,R.left+we+112,n),e.font=c.font,e.textAlign=`right`,e.fillStyle=c.color,e.fillText(`Portfolio: ${Te(h?.total??0)}`,be-8,n)},!0,{easing:S}),A?(0,n.jsx)(P,{width:be,height:xe,message:`No contract data available`,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{width:be,transition:`all 0.25s ease`},children:[(0,n.jsxs)(`div`,{style:{position:`relative`},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Total contract value per contractor — horizontal bar chart`,style:{width:be,height:T,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...M,parentW:be,parentH:T})]}),g.length>Se&&(0,n.jsx)(`div`,{style:{marginTop:8},children:(0,n.jsx)(te,{expanded:d,onToggle:()=>f(e=>!e)})})]})}var B=780,V=240,De=12,Oe=10,ke=[`Highest exposure`,`Elevated risk`,`Moderate exposure`,`Moderate exposure`,`Low exposure`];function Ae({items:e=[],"data-testid":r}){let c=(0,t.useRef)(null),u=(0,t.useRef)(0),d=(0,t.useRef)(new Map),{hoveredRef:m,tooltip:g,hitZonesRef:y}=v(c,{width:B,height:V}),x=[...(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e])].sort((e,t)=>(t.count??0)-(e.count??0)).slice(0,5),S=x.reduce((e,t)=>e+(t.count??0),0);return(0,t.useEffect)(()=>{let e=c.current;if(!e)return;let t=f(e,B,V);u.current=0;let n=Math.min(5,x.length),r=(B-2*De-4*Oe)/5,g=V*.84,_=V*.08,v=n*r+(n-1)*Oe,C=Math.round((B-v)/2),w,E=()=>{u.current++;let e=u.current;t.clearRect(0,0,B,V),t.letterSpacing=o.letterSpacing,y.current=[],d.current.forEach((e,t)=>{let n=t===m.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?d.current.delete(t):d.current.set(t,1):d.current.set(t,r)}),m.current&&!d.current.has(m.current)&&d.current.set(m.current,0),x.forEach((n,o)=>{let c=o===0,u=o===0?i.red:o===1?i.amber:a[o%a.length],f=C+o*(r+Oe),m=d.current.get(n.id)??0,h=m*8,v=f-h/2,x=r+h,w=c?T(e,.04,3e-4)*.06+.06:0;t.fillStyle=l(u,.08+m*.07),t.beginPath(),t.roundRect(v,_,x,g,6),t.fill(),t.strokeStyle=l(u,.2+m*.4+w),t.lineWidth=c?1.5:1,t.stroke(),(m>.01||c)&&p(t,v+x/2,_+g/2,x*.55,u,w+m*.14),t.font=s.font,t.textAlign=`left`,t.textBaseline=`top`,t.fillStyle=l(u,.5+m*.35),t.fillText(`#${o+1}`,v+7,_+6);let E=Math.min(r*.28,g*.32,72),D=v+x/2,O=_+g*.38,k=t.createRadialGradient(D,O-E*.2,0,D,O,E);k.addColorStop(0,l(u,.5+m*.2)),k.addColorStop(1,l(u,.2+m*.1)),t.beginPath(),t.arc(D,O,E,0,Math.PI*2),t.fillStyle=k,t.fill(),t.strokeStyle=l(u,.4+m*.3),t.lineWidth=1,t.stroke(),t.font=s.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(i.t1,.9),t.fillText(n.abbreviation??n.name.slice(0,6),D,O),t.font=s.font,t.textBaseline=`alphabetic`,t.fillStyle=l(u,.9+m*.1),t.fillText(String(n.count??0),D,_+g*.76);let A=Math.round((n.count??0)/(S||1)*100),j=ke[o]??`Low exposure`;b(y.current,n.id,f,_,r,g,{label:n.name,value:`${n.count??0} · ${A}% of total`,sublabel:`Rank #${o+1} · ${j}`,color:u})}),h(t,B,V,e,.015),w=requestAnimationFrame(E)};return E(),()=>cancelAnimationFrame(w)},[x,S]),x.length===0?(0,n.jsx)(P,{width:B,height:V,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:B,height:V},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`Contractor rank — count per contractor`,style:{width:B,height:V,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...g,parentW:B,parentH:V})]})}var H=680,U=260;function je({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(0),c=(0,t.useRef)(new Map),{hoveredRef:u,tooltip:d,hitZonesRef:g}=v(a,{width:H,height:U}),b=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,H,U);s.current=0;let n=b.length,r=Math.max(...b.map(e=>e.count),1),d=r,_=H*.05,v=U*.1,x=H*.9/n,S=U*.7/d,C=b.reduce((e,t)=>e+t.count,0),w,E=()=>{s.current++;let e=s.current;t.clearRect(0,0,H,U),g.current=[],c.current.forEach((e,t)=>{let n=t===u.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?c.current.delete(t):c.current.set(t,1):c.current.set(t,r)}),u.current&&!c.current.has(u.current)&&c.current.set(u.current,0),m(t,H,U,e,40,l(i.blue,.04)),b.forEach((n,a)=>{let s=n.count===r,u=i.blue,f=c.current.get(`${n.category}-col`)??0;for(let i=0;i<d;i++){let o=_+a*x+x/2,d=v+i*S+S/2,m=Math.min(x,S)*.38;if(i>=r-n.count){let r=m*(1+(T(e,.04,5e-4)+Math.sin(a*.6+i*1.2)*.3)*.12);(s||f>.01)&&p(t,o,d,r*3,u,(s?.2:.1)+f*.1),t.beginPath(),t.arc(o,d,r,0,Math.PI*2),t.fillStyle=l(u,s?.8:.5+f*.2),t.fill();let h=`${n.category}-${i}`;y(g.current,h,o,d,m+4,{label:n.fullName,value:`${n.count} Early Warnings`,sublabel:`${Math.round(n.count/C*100)}% of total`,color:u}),c.current.get(`${n.category}-col`)}else t.beginPath(),t.arc(o,d,1,0,Math.PI*2),t.fillStyle=l(u,.08),t.fill()}let m=v+d*S+16;t.font=o.font,t.textAlign=`center`,t.textBaseline=`alphabetic`,t.fillStyle=s?i.blue:l(i.t2,.65),t.fillText(n.category,_+a*x+x/2,m)}),h(t,H,U,e,.015),w=requestAnimationFrame(E)};return E(),()=>cancelAnimationFrame(w)},[b]),b.length===0?(0,n.jsx)(P,{width:H,height:U,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:H,height:U},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Early Warning count by category — breathing dot grid`,style:{width:H,height:U,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...d,parentW:H,parentH:U})]})}function Me({rows:e=[],className:t,colors:r}){return(0,n.jsx)(A,{rows:e,variant:`line`,className:t,colors:r})}var Ne=[`#4C93D9`,`#5DA537`,`#F3862C`,`#4F72C6`,`#A0B724`,`#EEBF3B`,`#3C45D1`],Pe={nodes:[{id:`supplier-x`,name:`Supplier X`,valueLabel:`Si +0.12%`},{id:`bf3-superheat`,name:`BF-3 Superheat`,valueLabel:`22°C (target 34)`},{id:`ccm3-solidification`,name:`CCM-3 Solidification`,valueLabel:`Rate deviation`},{id:`grade-risk`,name:`Grade Risk`,valueLabel:`Automotive 74%`}],links:[{source:`supplier-x`,target:`bf3-superheat`,value:92},{source:`bf3-superheat`,target:`ccm3-solidification`,value:87},{source:`ccm3-solidification`,target:`grade-risk`,value:74}]};function Fe({rows:e=[],className:t,colors:r}){let i=r?.slices??Ne;return(0,n.jsx)(`div`,{className:[`d3-mini-bars`,t].filter(Boolean).join(` `),children:e.map(([e,t,r],a)=>(0,n.jsxs)(`div`,{className:`d3-mini-row`,children:[(0,n.jsx)(`span`,{children:e}),(0,n.jsx)(`div`,{className:`d3-mini-track`,children:(0,n.jsxs)(`svg`,{viewBox:`0 0 100 12`,className:`d3-mini-svg`,"aria-hidden":`true`,children:[(0,n.jsx)(`rect`,{x:`0`,y:`0`,width:`100`,height:`12`,rx:`6`,className:`d3-mini-track-fill`}),(0,n.jsx)(`rect`,{x:`0`,y:`0`,width:Math.max(0,Math.min(100,t)),height:`12`,rx:`6`,className:`d3-mini-fill tone-${a%Ne.length}`,fill:i[a%i.length]})]})}),(0,n.jsx)(`span`,{children:r})]},`${e}-${a}`))})}var Ie=680,Le=320,Re=60,ze=28;function Be({total:e=0,items:r=[],"data-testid":c}){let u=(0,t.useRef)(null),d=(0,t.useRef)(new Map),m=(0,t.useRef)(0),h=(0,t.useMemo)(()=>r.filter(e=>typeof e==`object`&&!!e),[r]),g=(0,t.useMemo)(()=>Math.max(Le,Re+Math.max(0,h.length-1)*ze),[h.length]),{hoveredRef:b,tooltip:S,hitZonesRef:C}=v(u,{width:Ie,height:g});return(0,t.useEffect)(()=>{let t=u.current;if(!t)return;let n=f(t,Ie,g);m.current=0;let r=g/2,c=Ie-80,_=Math.max(...h.map(e=>e.count??0)),v=(g-60)/(h.length-1),S=h.map((e,t)=>({x:c,y:30+t*v})),w,T=()=>{m.current++;let t=m.current;n.clearRect(0,0,Ie,g),n.letterSpacing=o.letterSpacing;let u=x(Math.min(t/72,1));D(d.current,b.current),C.current=[],p(n,88,r,48*u,i.blue,.15*u),h.forEach((t,f)=>{let m=a[f%a.length],g=E(u,f,h.length,x),v=S[f],b=d.current.get(t.id)??0,w=Math.max(1.5,(t.count??0)/_*6);if(g<.01)return;let T=88+(c-88)*.4,D=r,O=88+(c-88)*.6,k=v.y,A=g;n.beginPath();for(let e=0;e<=40;e++){let t=e/40*A,i=(1-t)**3*88+3*(1-t)**2*t*T+3*(1-t)*t**2*O+t**3*v.x,a=(1-t)**3*r+3*(1-t)**2*t*D+3*(1-t)*t**2*k+t**3*v.y;e===0?n.moveTo(i,a):n.lineTo(i,a)}if(n.strokeStyle=l(m,b>0?.8:.45),n.lineWidth=w*(b>0?1.3:1),n.stroke(),g>.85){let r=Math.min(1,(g-.85)/.15),a=4+(t.count??0)/_*12;p(n,v.x,v.y,a*2.5,m,(.25+b*.2)*r),n.beginPath(),n.arc(v.x,v.y,a*r,0,Math.PI*2),n.fillStyle=l(m,(.7+b*.2)*r),n.fill(),y(C.current,t.id,v.x,v.y,a+8,{label:t.name,value:`${t.count??0} NCEs raised`,sublabel:`${Math.round((t.count??0)/e*100)}% of all NCEs`,color:m}),n.globalAlpha=r,n.font=o.font,n.textAlign=`left`;let c=t.abbreviation??t.name.slice(0,6),u=` ${t.count??0}`,d=v.x+a+6,f=v.y+4;n.fillStyle=b>0?m:l(i.t2,.85),n.fillText(c,d,f);let h=n.measureText(c).width;n.font=s.font,n.fillStyle=b>0?m:i.t1,n.fillText(u,d+h,f),n.globalAlpha=1}}),n.beginPath(),n.arc(88,r,32*u,0,Math.PI*2),n.fillStyle=i.bgL,n.fill(),n.strokeStyle=l(i.blue,.6*u),n.lineWidth=2,n.stroke(),u>.4&&(n.globalAlpha=Math.min(1,(u-.4)/.4),n.font=`500 24px 'Satoshi Variable', 'DM Sans', sans-serif`,n.fillStyle=i.t1,n.textAlign=`center`,n.fillText(String(e),88,r+5),n.font=o.font,n.fillStyle=o.color,n.fillText(`NCEs`,88,r+18),n.globalAlpha=1),w=requestAnimationFrame(T)};return T(),()=>cancelAnimationFrame(w)},[e,h,g]),h.length===0?(0,n.jsx)(P,{width:Ie,height:Le,"data-testid":c}):(0,n.jsxs)(`div`,{"data-testid":c,style:{position:`relative`,width:Ie,height:g},children:[(0,n.jsx)(`canvas`,{ref:u,role:`img`,"aria-label":`NCE fault tree — NCEs per contractor as branching tree`,style:{width:Ie,height:g,display:`block`}}),(0,n.jsx)(_,{...S,parentW:Ie,parentH:g})]})}var Ve=192,He=Ve,Ue=Ve+80;function We({rows:e=[],variant:o,className:s,colors:c}){let u=(0,t.useRef)(null),m=(0,t.useRef)(new Map),h=(0,t.useRef)(0),g=c?.slices??a,{hoveredRef:b,tooltip:x,hitZonesRef:S}=v(u,{width:He,height:Ue});return(0,t.useEffect)(()=>{let t=u.current;if(!t)return;let n=f(t,He,Ue);h.current=0;let r=He/2,a=Ve/2,s=Ve*.4,c=o===`donut`?Ve*.21:0,_=e.reduce((e,t)=>e+(t.pricing??0),0)||1,v,x=()=>{h.current++;let t=h.current;n.clearRect(0,0,He,Ue);let u=1-(1-Math.min(t/48,1))**3;D(m.current,b.current),S.current=[];let f=-Math.PI/2;e.forEach((e,o)=>{let d=(e.pricing??0)/_,h=d*Math.PI*2*u,v=f+h,b=g[o%g.length],x=m.current.get(e.id??`sl-${o}`)??0,C=f+h/2,w=(s+c)/2,E=r+Math.cos(C)*w,D=a+Math.sin(C)*w,O=(s-c)/2+8;y(S.current,e.id??`sl-${o}`,E,D,O,{label:e.vendor,value:`${e.pricing??0} (${Math.round(d*100)}%)`,color:b}),x>0&&p(n,E,D,O*2*x,b,.2*x);let k=T(t,.03,3e-4),A=s+x*6+(x>0?k*2:0);n.beginPath(),n.moveTo(r+Math.cos(f)*c,a+Math.sin(f)*c),n.arc(r,a,A,f,v),c>0?n.arc(r,a,c,v,f,!0):n.lineTo(r,a),n.closePath(),n.fillStyle=l(b,.7+x*.2),n.fill(),n.strokeStyle=l(i.bg,.8),n.lineWidth=1.5,n.stroke(),f=v}),o===`donut`&&e.length>0&&p(n,r,a,c*.8,i.blue,.06);let C=Ve+12;e.forEach((e,t)=>{let r=g[t%g.length],a=(e.pricing??0)/_,o=m.current.get(e.id??`sl-${t}`)??0,s=C+t*18;n.beginPath(),n.arc(8,s,4,0,Math.PI*2),n.fillStyle=l(r,.8+o*.2),n.fill(),n.font=`9px 'JetBrains Mono', monospace`,n.fillStyle=l(i.t2,.7+o*.2),n.textAlign=`left`,n.fillText(e.vendor,18,s+3.5),n.font=`bold 9px 'JetBrains Mono', monospace`,n.fillStyle=d(i.t3,r,o),n.textAlign=`right`,n.fillText(`${e.pricing??0} (${Math.round(a*100)}%)`,He-4,s+3.5)}),v=requestAnimationFrame(x)};return x(),()=>cancelAnimationFrame(v)},[e,o,c,g]),(0,n.jsx)(r,{className:[`canvas-pie-frame`,s].filter(Boolean).join(` `),children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:He,height:Ue},children:[(0,n.jsx)(`canvas`,{ref:u,role:`img`,"aria-label":`${o} chart`,style:{width:He,height:Ue,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...x,parentW:He,parentH:Ue})]})})}function Ge(e,t,n,r){let i=new Set(t.map(e=>e.source)),a=new Set(t.map(e=>e.target)),o=new Map,s=[];for(e.forEach(e=>{i.has(e.id)&&!a.has(e.id)&&s.push({id:e.id,depth:0})});s.length>0;){let e=s.shift();if(!e)break;let{id:n,depth:r}=e;o.has(n)||(o.set(n,r),t.filter(e=>e.source===n).forEach(e=>{o.has(e.target)||s.push({id:e.target,depth:r+1})}))}let c=o.size>0?Math.max(...Array.from(o.values())):0;e.forEach(e=>{o.has(e.id)||o.set(e.id,c+1)});let l=new Map;e.forEach(e=>{let t=o.get(e.id)??0;l.has(t)||l.set(t,[]),l.get(t).push(e.id)});let u=Math.max(...Array.from(l.keys()))+1,d={left:100,right:80,top:40,bottom:40},f=new Map;return l.forEach((e,t)=>{let i=d.left+t/Math.max(u-1,1)*(n-d.left-d.right),a=r-d.top-d.bottom,o=Math.max(24,(a-(e.length-1)*12)/e.length),s=e.length*o+(e.length-1)*12,c=d.top+(a-s)/2;e.forEach((e,t)=>{f.set(e,{x:i-20/2,y:c+t*(o+12),w:20,h:o})})}),f}function Ke({nodes:e,links:o,width:s=960,height:c=280,ariaLabel:u,selectedEntity:d,className:m,colors:g}){let x=(0,t.useRef)(null),S=(0,t.useRef)(new Map),C=(0,t.useRef)(0),w=(0,t.useRef)([]),E=g?.nodes??a,O=g?.links??i.bd,k=g?.activeLinks??i.blue,A=g?.activeNodes??i.blue,j=(0,t.useMemo)(()=>Ge(e,o,s,c),[e,o,s,c]),{hoveredRef:M,tooltip:N,hitZonesRef:ee}=v(x,{width:s,height:c});return(0,t.useEffect)(()=>{let t=x.current;if(!t)return;let n=f(t,s,c);C.current=0,w.current=[];let r=o.length>0?Math.max(...o.map(e=>e.value)):1,a,u=()=>{C.current++;let t=C.current;n.clearRect(0,0,s,c);let f=1-(1-Math.min(t/56,1))**3;D(S.current,M.current),ee.current=[],o.forEach((e,a)=>{let o=j.get(e.source),s=j.get(e.target);if(!o||!s)return;let c=!!d&&(e.source===d||e.target===d),u=c?k:O,p=c?.5:.2,m=Math.max(3,e.value/r*36*f),h=m/2,g=o.x+o.w,_=o.y+o.h/2,v=s.x,b=s.y+s.h/2,x=(g+v)/2;for(let e=0;e<30;e++){let r=e/30,i=(e+1)/30,o=1-r,s=1-i,c=o*o*g+2*o*r*x+r*r*v,d=o*o*_+2*o*r*_+r*r*b,f=s*s*g+2*s*i*x+i*i*v,m=s*s*_+2*s*i*_+i*i*b,y=T(t+r*120+a*40,.025,3e-4)*1.2;n.beginPath(),n.moveTo(c,d-h+y),n.lineTo(f,m-h+y),n.lineTo(f,m+h+y),n.lineTo(c,d+h+y),n.closePath(),n.fillStyle=l(u,p*(.5+r*.5)),n.fill()}y(ee.current,`link-${a}`,x,(_+b)/2,m+6,{label:`${e.source} → ${e.target}`,value:String(e.value),color:c?k:i.blue}),Math.random()<.08&&w.current.push({linkIdx:a,prog:0,speed:.006+Math.random()*.006,off:(Math.random()-.5)*m*.5,sz:1+Math.random()})}),e.forEach((e,r)=>{let a=j.get(e.id);if(!a)return;let o=d===e.id,s=M.current===`node-${r}`,c=S.current.get(`node-${r}`)??0,u=o?A:E[r%E.length];b(ee.current,`node-${r}`,a.x,a.y,a.w,a.h,{label:e.name,value:e.valueLabel??e.id,color:u}),(c>0||o)&&p(n,a.x+a.w/2,a.y+a.h/2,a.w*2,u,.2*Math.max(c,o?.6:0));let f=o?T(t,.03,3e-4)*.15:0;n.fillStyle=l(u,.6+c*.25+f),n.beginPath(),n.roundRect(a.x,a.y,a.w,a.h,4),n.fill(),(o||c>0)&&(n.strokeStyle=l(u,.5*Math.max(c,o?1:0)),n.lineWidth=1,n.beginPath(),n.roundRect(a.x,a.y,a.w,a.h,4),n.stroke());let m=a.x+a.w+8;n.font=`${o||s?`bold `:``}10px 'JetBrains Mono', monospace`,n.fillStyle=l(o?u:i.t2,.7+c*.2),n.textAlign=`left`,n.fillText(e.name,m,a.y+a.h/2+4),e.valueLabel&&(n.font=`9px 'JetBrains Mono', monospace`,n.fillStyle=l(u,.5+c*.2),n.fillText(e.valueLabel,m,a.y+a.h/2+17))}),w.current=w.current.filter(e=>{if(e.prog+=e.speed,e.prog>1)return!1;let t=o[e.linkIdx];if(!t)return!1;let r=j.get(t.source),a=j.get(t.target);if(!r||!a)return!1;let s=r.x+r.w,c=r.y+r.h/2,u=a.x,d=a.y+a.h/2,f=(s+u)/2,p=1-e.prog,m=p*p*s+2*p*e.prog*f+e.prog*e.prog*u,h=p*p*c+2*p*e.prog*c+e.prog*e.prog*d+e.off,_=Math.sin(e.prog*Math.PI)*.5,v=g?.links??i.blue;return n.beginPath(),n.arc(m,h,e.sz,0,Math.PI*2),n.fillStyle=l(v,_),n.fill(),!0}),w.current.length>150&&(w.current=w.current.slice(-150)),h(n,s,c,t,.01),a=requestAnimationFrame(u)};return u(),()=>{cancelAnimationFrame(a),w.current=[]}},[e,o,s,c,d,g,j]),(0,n.jsx)(r,{className:[`canvas-sankey-frame`,m].filter(Boolean).join(` `),children:(0,n.jsxs)(`div`,{role:`img`,"aria-label":u,style:{position:`relative`,width:s,height:c},children:[(0,n.jsx)(`canvas`,{ref:x,style:{width:s,height:c,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...N,parentW:s,parentH:c})]})})}var qe=[{x:.13,y:.48},{x:.37,y:.28},{x:.63,y:.62},{x:.87,y:.38},{x:.25,y:.72},{x:.5,y:.18},{x:.75,y:.7},{x:.92,y:.22}],Je=[i.blue,i.orange,i.red,i.purple,i.green,i.amber,i.t2],Ye=[26,24,24,26,22,22,22,22];function Xe(e,t){let n=1-t;return{x:n*n*n*e.p0.x+3*n*n*t*e.p1.x+3*n*t*t*e.p2.x+t*t*t*e.p3.x,y:n*n*n*e.p0.y+3*n*n*t*e.p1.y+3*n*t*t*e.p2.y+t*t*t*e.p3.y}}function Ze(e,t){let n=1-t,r=3*n*n*(e.p1.x-e.p0.x)+6*n*t*(e.p2.x-e.p1.x)+3*t*t*(e.p3.x-e.p2.x),i=3*n*n*(e.p1.y-e.p0.y)+6*n*t*(e.p2.y-e.p1.y)+3*t*t*(e.p3.y-e.p2.y),a=Math.sqrt(r*r+i*i)||1;return{x:-i/a,y:r/a}}function Qe(e,t){let n=t.x-e.x,r=t.y-e.y;return{p0:{x:e.x,y:e.y},p1:{x:e.x+n*.3+r*.15,y:e.y+r*.3-n*.15},p2:{x:t.x-n*.3+r*.08,y:t.y-r*.3-n*.08},p3:{x:t.x,y:t.y}}}function $e({nodes:e,links:r,width:a=960,height:o=280,selectedEntity:s}){let c=(0,t.useRef)(null),u=(0,t.useRef)(0),g=(0,t.useRef)([]),{hoveredRef:b,tooltip:S,hitZonesRef:C}=v(c,{width:a,height:o}),w=(0,t.useMemo)(()=>{let t=new Map;return e.forEach((e,n)=>t.set(e.id,n)),t},[e]),E=(0,t.useMemo)(()=>r.length>0?Math.max(...r.map(e=>e.value)):100,[r]),D=e=>E>1?e/100:e,O=(0,t.useMemo)(()=>e.map((e,t)=>{let n=qe[t%qe.length];return{id:e.id,label:e.name,sub:e.valueLabel??``,x:n.x*a,y:n.y*o,r:Ye[t%Ye.length],color:Je[t%Je.length]}}),[e,a,o]),k=(0,t.useMemo)(()=>r.map(e=>({fromIdx:w.get(e.source)??-1,toIdx:w.get(e.target)??-1,conf:D(e.value)})).filter(e=>e.fromIdx>=0&&e.toIdx>=0),[r,w]);return(0,t.useEffect)(()=>{let e=c.current;if(!e)return;let t=f(e,a,o);u.current=0,g.current=[];let n,r=()=>{u.current++;let e=u.current;if(t.clearRect(0,0,a,o),C.current=[],m(t,a,o,e,50,l(i.blue,.05)),k.forEach((e,n)=>{let r=O[e.fromIdx],a=O[e.toIdx];if(!r||!a)return;let o=!!s&&(r.id===s||a.id===s),c=d(r.color,a.color,.5),u=o?.18:.05,f=o?.25:.1,p=Qe(r,a);t.beginPath(),t.moveTo(p.p0.x,p.p0.y),t.bezierCurveTo(p.p1.x,p.p1.y,p.p2.x,p.p2.y,p.p3.x,p.p3.y),t.strokeStyle=l(c,u),t.lineWidth=16,t.lineCap=`round`,t.stroke(),t.strokeStyle=l(c,f),t.lineWidth=1.5,t.stroke();for(let t=0;t<e.conf*2.5;t++)Math.random()<.45&&g.current.push({edgeIdx:n,t:0,speed:.003+Math.random()*.004,off:(Math.random()-.5)*13,sz:.7+Math.random()*2});let m=Xe(p,.5),h=`${Math.round(e.conf*100)}%`;t.font=`bold 12px 'JetBrains Mono', monospace`,t.textBaseline=`middle`;let _=t.measureText(h).width+14;t.fillStyle=`rgba(10,16,24,0.88)`,t.beginPath(),t.roundRect(m.x-_/2,m.y-11,_,22,6),t.fill(),t.strokeStyle=l(i.blue,.25),t.lineWidth=1,t.stroke(),t.fillStyle=l(i.blue,.9),t.textAlign=`center`,t.fillText(h,m.x,m.y)}),g.current=g.current.filter(e=>{if(e.t+=e.speed,e.t>1)return!1;let n=k[e.edgeIdx];if(!n)return!1;let r=O[n.fromIdx],i=O[n.toIdx];if(!r||!i)return!1;let a=Qe(r,i),o=Xe(a,e.t),s=Ze(a,e.t),c=o.x+s.x*e.off,u=o.y+s.y*e.off,f=Math.sin(e.t*Math.PI)*.7,m=d(r.color,i.color,e.t);return p(t,c,u,e.sz*3,m,f*.1),t.beginPath(),t.arc(c,u,e.sz,0,Math.PI*2),t.fillStyle=l(m,f),t.fill(),!0}),g.current.length>350&&(g.current=g.current.slice(-350)),O.forEach((n,r)=>{let a=s===n.id,o=b.current===`node-${r}`,c=T(e,.03,3e-4)*.1+1,u=n.r*c*(a?1.15:1);t.beginPath(),t.arc(n.x,n.y,u+6,0,Math.PI*2),t.strokeStyle=l(n.color,a?.3:.1),t.lineWidth=a?1.5:.7,t.stroke(),p(t,n.x,n.y,u*3,n.color,a?.22:.12);let d=t.createRadialGradient(n.x,n.y-u*.2,0,n.x,n.y,u);if(d.addColorStop(0,l(n.color,a?1:.85)),d.addColorStop(1,l(n.color,a?.65:.45)),t.fillStyle=d,t.beginPath(),t.arc(n.x,n.y,u,0,Math.PI*2),t.fill(),a||r===O.length-1){let r=u+16,i=e*.04,a=n.x+Math.cos(i)*r,o=n.y+Math.sin(i)*r;p(t,a,o,6,n.color,.3),t.beginPath(),t.arc(a,o,2,0,Math.PI*2),t.fillStyle=l(n.color,.75),t.fill()}y(C.current,`node-${r}`,n.x,n.y,u+8,{label:n.label,value:n.sub||n.id,color:n.color}),t.font=`${a||o?`bold `:``}12px 'DM Sans', sans-serif`,t.textAlign=`center`,t.textBaseline=`alphabetic`,t.fillStyle=l(n.color,a?1:.9),t.fillText(n.label,n.x,n.y+u+18),n.sub&&(t.font=`10px 'JetBrains Mono', monospace`,t.fillStyle=l(i.t3,.65),t.fillText(n.sub,n.x,n.y+u+32))}),k.length>=2){let n=k.reduce((e,t)=>e*t.conf,1),r=o*.92,s=a*.12,c=a*.76,u=x(Math.min(e*.008,1));t.fillStyle=l(i.bd,.35),t.beginPath(),t.roundRect(s,r,c,5,3),t.fill(),t.fillStyle=l(i.orange,.6),t.beginPath(),t.roundRect(s,r,c*n*u,5,3),t.fill(),t.font=`bold 12px 'JetBrains Mono', monospace`,t.textAlign=`left`,t.textBaseline=`middle`,t.fillStyle=l(i.orange,.85),t.fillText(`${Math.round(n*100)}% compound confidence`,s+c*n*u+10,r+2);let d=k.map(e=>e.conf.toFixed(2)).join(` × `);t.textAlign=`right`,t.font=`9px 'JetBrains Mono', monospace`,t.fillStyle=l(i.t4,.6),t.fillText(d,s-6,r+2)}h(t,a,o,e,.012),n=requestAnimationFrame(r)};return r(),()=>{cancelAnimationFrame(n),g.current=[]}},[O,k,a,o,s]),(0,n.jsxs)(`div`,{style:{position:`relative`,width:a,height:o},children:[(0,n.jsx)(`canvas`,{ref:c,style:{width:a,height:o,display:`block`,borderRadius:8},role:`img`,"aria-label":`causal flow diagram`}),(0,n.jsx)(_,{...S,parentW:a,parentH:o})]})}function et({selectedEntity:e,colors:t}){return(0,n.jsx)($e,{nodes:Pe.nodes,links:Pe.links,width:960,height:280,selectedEntity:e})}function tt({rows:e=[],className:r,colors:i}){let{nodes:a,links:o}=(0,t.useMemo)(()=>{let t=e.slice(0,5);return{nodes:[{id:`score`,name:`Portfolio Score`},...t.map(e=>({id:e.id??e.vendor,name:e.vendor}))],links:t.map(e=>({source:e.id??e.vendor,target:`score`,value:Math.max(8,e.pricing??0)}))}},[e]);return(0,n.jsx)(Ke,{nodes:a,links:o,width:760,height:280,ariaLabel:`sankey chart`,className:r,colors:i})}var nt=500,rt=320;function it({left:e,right:r,"data-testid":a}){let u=(0,t.useRef)(null),d=(0,t.useRef)(0);return(0,t.useEffect)(()=>{let t=u.current;if(!t)return;let n=f(t,nt,rt);d.current=0;let a=nt/2,m=Math.max(e.value,r.value),h=(e.value-r.value)/m*14,g,_=()=>{d.current++;let t=d.current;n.clearRect(0,0,nt,rt),n.letterSpacing=o.letterSpacing;let u=x(Math.min(t/80,1)),f=h*w(Math.min(t/80,1))*Math.PI/180;n.strokeStyle=l(i.bd,.5*u),n.lineWidth=2,n.beginPath(),n.moveTo(a,100),n.lineTo(a,rt-80),n.stroke(),n.beginPath(),n.arc(a,100,5*u,0,Math.PI*2),n.fillStyle=i.t2,n.fill();let v={x:a-Math.cos(f)*160,y:100+Math.sin(-f)*160},y={x:a+Math.cos(f)*160,y:100+Math.sin(f)*160};n.strokeStyle=l(i.t2,.5*u),n.lineWidth=2,n.beginPath(),n.moveTo(v.x,v.y),n.lineTo(y.x,y.y),n.stroke();let b=Math.max(20,e.value/m*100*u),S=v.y+18;p(n,v.x,S+b/2,90*.5,i.green,.18*u),n.fillStyle=l(i.green,.5*u),n.beginPath(),n.roundRect(v.x-90/2,S,90,b,[0,0,6,6]),n.fill(),n.strokeStyle=l(i.green,.7*u),n.lineWidth=1.5,n.stroke(),n.strokeStyle=l(i.t2,.35*u),n.lineWidth=1,[-90/3,90/3].forEach(e=>{n.beginPath(),n.moveTo(v.x+e,v.y+4),n.lineTo(v.x+e,S),n.stroke()}),u>.5&&(n.globalAlpha=Math.min(1,(u-.5)/.5),n.font=s.font,n.fillStyle=i.green,n.textAlign=`center`,n.fillText(e.label,v.x,S+b+18),n.font=o.font,n.fillStyle=o.color,n.fillText(`Accepted`,v.x,S+b+32),n.fillText(`${e.count} quotations`,v.x,S+b+44),n.globalAlpha=1);let C=Math.max(20,r.value/m*100*u),T=y.y+18;n.fillStyle=l(i.amber,.3*u),n.strokeStyle=l(i.amber,.5*u),n.lineWidth=1.5,n.beginPath(),n.roundRect(y.x-90/2,T,90,C,[0,0,6,6]),n.fill(),n.stroke(),n.strokeStyle=l(i.t2,.35*u),n.lineWidth=1,[-90/3,90/3].forEach(e=>{n.beginPath(),n.moveTo(y.x+e,y.y+4),n.lineTo(y.x+e,T),n.stroke()}),u>.5&&(n.globalAlpha=Math.min(1,(u-.5)/.5),n.font=s.font,n.fillStyle=i.amber,n.textAlign=`center`,n.fillText(r.label,y.x,T+C+18),n.font=o.font,n.fillStyle=o.color,n.fillText(`Submitted`,y.x,T+C+32),n.fillText(`${r.count} quotations`,y.x,T+C+44),n.globalAlpha=1),u>.85&&Math.abs(h)>1&&(n.globalAlpha=Math.min(1,(u-.85)/.15)*.6,n.font=c.font,n.fillStyle=c.color,n.textAlign=`center`,n.fillText(`${Math.abs(h).toFixed(1)}° tilt toward accepted`,a,rt-12),n.globalAlpha=1),g=requestAnimationFrame(_)};return _(),()=>cancelAnimationFrame(g)},[e,r]),(0,n.jsx)(`div`,{"data-testid":a,style:{position:`relative`,width:nt,height:rt},children:(0,n.jsx)(`canvas`,{ref:u,role:`img`,"aria-label":`Quotation balance — accepted vs submitted quotation value`,style:{width:nt,height:rt,display:`block`}})})}var at=680,W=280;function ot({points:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(new Map),c=(0,t.useRef)(0),{hoveredRef:u,tooltip:d,hitZonesRef:m}=v(a,{width:at,height:W}),h=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,at,W);c.current=0;let n=at-54-28,r=W-30-54,d=Math.max(...h.map(e=>e.count),1),_=h.length,v=_>1?n/(_-1):n,b=h.map((e,t)=>({x:54+t*v,y:30+r-e.count/d*r,point:e})),S,C=()=>{c.current++;let e=c.current;t.clearRect(0,0,at,W),t.letterSpacing=o.letterSpacing;let a=x(Math.min(e/72,1));D(s.current,u.current),m.current=[],[.25,.5,.75,1].forEach(e=>{let a=30+r-e*r;t.strokeStyle=l(i.bd,.18),t.lineWidth=1,t.setLineDash([3,5]),t.beginPath(),t.moveTo(54,a),t.lineTo(54+n,a),t.stroke(),t.setLineDash([]),t.font=o.font,t.fillStyle=o.color,t.textAlign=`right`,t.fillText(String(Math.round(d*e)),48,a+3)}),t.save(),t.translate(12,30+r/2),t.rotate(-Math.PI/2),t.font=o.font,t.fillStyle=o.color,t.textAlign=`center`,t.fillText(`Submissions`,0,0),t.restore(),t.font=o.font,t.fillStyle=o.color,t.textAlign=`center`,t.fillText(`Week`,54+n/2,W-6),t.strokeStyle=l(i.bd,.3),t.lineWidth=1,t.setLineDash([]),t.beginPath(),t.moveTo(54,30+r),t.lineTo(54+n,30+r),t.stroke();let f=a*(_-1),h=Math.floor(f)+1;if(h>=2){t.beginPath(),t.moveTo(b[0].x,30+r),t.lineTo(b[0].x,b[0].y);for(let e=1;e<h;e++){let n=f-Math.floor(f),r=e<h-1?b[e].x:b[e-1].x+(b[e].x-b[e-1].x)*(e===Math.ceil(f)?n:1),i=e<h-1?b[e].y:b[e-1].y+(b[e].y-b[e-1].y)*(e===Math.ceil(f)?n:1);t.lineTo(r,i)}let e=b[Math.min(h-1,_-1)];t.lineTo(e.x,30+r),t.closePath();let n=t.createLinearGradient(0,30,0,30+r);n.addColorStop(0,l(i.blue,.22)),n.addColorStop(1,l(i.blue,.02)),t.fillStyle=n,t.fill()}t.beginPath();for(let e=0;e<h;e++){let n=f-Math.floor(f),r=e===h-1&&e>0&&e===Math.ceil(f),i=e===0||e<h-1?b[e].x:b[e-1].x+(b[e].x-b[e-1].x)*(r?n:1),a=e===0||e<h-1?b[e].y:b[e-1].y+(b[e].y-b[e-1].y)*(r?n:1);e===0?t.moveTo(i,a):t.lineTo(i,a)}t.strokeStyle=l(i.blue,.85),t.lineWidth=2,t.stroke(),b.forEach((e,n)=>{if(n>=h)return;let a=`pt-${n}`,c=s.current.get(a)??0;y(m.current,a,e.x,e.y,10,{label:e.point.week,value:`${e.point.count} quotations submitted`,sublabel:`£${e.point.value}M value`,color:i.blue}),c>0&&g(t,e.x,30,30+r,l(i.blue,.15*c));let u=e.point.count===d;(c>0||u)&&p(t,e.x,e.y,14,i.blue,(u?.3:0)+c*.25),t.beginPath(),t.arc(e.x,e.y,c>0?5:3.5,0,Math.PI*2),t.fillStyle=l(i.blue,c>0?1:.8),t.fill(),(c>0||u)&&(t.font=o.font,t.fillStyle=i.blue,t.textAlign=`center`,t.fillText(String(e.point.count),e.x,e.y-10)),t.font=o.font,t.fillStyle=c>0?i.blue:o.color,t.textAlign=`center`,t.fillText(e.point.week,e.x,W-54+14)}),S=requestAnimationFrame(C)};return C(),()=>cancelAnimationFrame(S)},[h]),h.length<2?(0,n.jsx)(P,{width:at,height:W,"data-testid":r}):(0,n.jsx)(`div`,{"data-testid":r,className:`trend-scroll`,style:{width:`100%`,overflowX:`auto`},children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:at,height:W},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Trend chart — count over time`,style:{width:at,height:W,display:`block`}}),(0,n.jsx)(_,{...d,parentW:at,parentH:W})]})})}var st=680,G=280,ct=54,lt=28,ut=64,dt=o.font,ft=12,pt=Math.PI*2,mt=72,ht=20,gt=5e3;function _t({points:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(null),c=(0,t.useRef)(0),u=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),d=(0,t.useMemo)(()=>{if(u.length<=1)return ut;let e=document.createElement(`canvas`).getContext(`2d`);if(!e)return ut;e.font=dt;let t=Math.max(1,Math.ceil(u.length/ht)),n=Math.max(...u.filter((e,n)=>n%t===0).map(t=>e.measureText(t.week).width));return Math.max(ut,n+ft)},[u]),p=Math.round(d/2),m=lt+p+Math.max(0,u.length-1)*d,h=Math.max(st-ct,Math.min(m,gt)),{tooltip:g,hitZonesRef:b}=v(a,{width:h,height:G});return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,h,G),n=s.current?f(s.current,ct,G):null;c.current=0;let r=u.length<=mt?mt:Math.max(24,Math.round(mt*(mt/u.length))),m=h-lt,g=G-30-54,_=Math.max(...u.map(e=>e.count),1),v=u.length,S=v>1?(m-p)/(v-1):m-p,C=Math.max(1,Math.ceil(d/S)),w=u.map((e,t)=>({x:p+t*S,y:30+g-e.count/_*g,point:e}));n&&(n.clearRect(0,0,ct,G),n.letterSpacing=o.letterSpacing,[.25,.5,.75,1].forEach(e=>{let t=30+g-e*g;n.font=o.font,n.fillStyle=o.color,n.textAlign=`right`,n.fillText(String(Math.round(_*e)),ct-6,t+3)}),n.save(),n.translate(12,30+g/2),n.rotate(-Math.PI/2),n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(`Count`,0,0),n.restore());let T=t.createLinearGradient(0,30,0,30+g);T.addColorStop(0,l(i.blue,.22)),T.addColorStop(1,l(i.blue,.02));let E=0,D,O=e=>{t.font=dt,t.fillStyle=o.color,t.textAlign=`center`;for(let n=0;n<e;n++)n%C===0&&t.fillText(w[n].point.week,w[n].x,G-54+14)},k=()=>{c.current++;let e=Math.min(c.current/r,1),n=x(e),a=e>=1;t.clearRect(0,0,h,G),t.letterSpacing=o.letterSpacing,[.25,.5,.75,1].forEach(e=>{let n=30+g-e*g;t.strokeStyle=l(i.bd,.18),t.lineWidth=1,t.setLineDash([3,5]),t.beginPath(),t.moveTo(0,n),t.lineTo(m,n),t.stroke(),t.setLineDash([])}),t.font=o.font,t.fillStyle=o.color,t.textAlign=`center`,t.fillText(`Period`,p+(m-p)/2,G-6),t.strokeStyle=l(i.bd,.3),t.lineWidth=1,t.beginPath(),t.moveTo(p,30+g),t.lineTo(m,30+g),t.stroke();let s=n*(v-1),u=Math.floor(s)+1;if(u>=2){t.beginPath(),t.moveTo(w[0].x,30+g),t.lineTo(w[0].x,w[0].y);for(let e=1;e<u;e++){let n=s-Math.floor(s),r=e===u-1&&e===Math.ceil(s)&&n>0,i=r?w[e-1].x+(w[e].x-w[e-1].x)*n:w[e].x,a=r?w[e-1].y+(w[e].y-w[e-1].y)*n:w[e].y;t.lineTo(i,a)}t.lineTo(w[u-1].x,30+g),t.closePath(),t.fillStyle=T,t.fill()}t.beginPath();for(let e=0;e<u;e++){let n=s-Math.floor(s),r=e===u-1&&e>0&&e===Math.ceil(s)&&n>0,i=r?w[e-1].x+(w[e].x-w[e-1].x)*n:w[e].x,a=r?w[e-1].y+(w[e].y-w[e-1].y)*n:w[e].y;e===0?t.moveTo(i,a):t.lineTo(i,a)}t.strokeStyle=l(i.blue,.85),t.lineWidth=2,t.stroke(),t.fillStyle=l(i.blue,.8),t.beginPath();for(let e=0;e<u;e++)t.moveTo(w[e].x+3.5,w[e].y),t.arc(w[e].x,w[e].y,3.5,0,pt);if(t.fill(),u>E){b.current=[];for(let e=0;e<u;e++)y(b.current,`pt-${e}`,w[e].x,w[e].y,10,{label:w[e].point.week,value:`${w[e].point.count} submissions`,sublabel:`£${w[e].point.value}M value`,color:i.blue});E=u}a&&O(v),a||(D=requestAnimationFrame(k))};return k(),()=>cancelAnimationFrame(D)},[u,h,d,b]),u.length<2?(0,n.jsx)(P,{width:st,height:G,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:`100%`,display:`flex`},children:[(0,n.jsx)(`canvas`,{ref:s,"aria-hidden":`true`,style:{width:ct,height:G,display:`block`,flexShrink:0}}),(0,n.jsx)(`div`,{className:`trend-scroll`,style:{flex:1,overflowX:`auto`},children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:h,height:G},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Trend chart — count over time`,style:{width:h,height:G,display:`block`}}),(0,n.jsx)(_,{...g,parentW:h,parentH:G})]})})]})}var K=680,vt=240;function yt(e,t,n){if(e.measureText(t).width<=n)return t;let r=t;for(;r.length>0&&e.measureText(`${r}…`).width>n;)r=r.slice(0,-1);return`${r}…`}var bt={Critical:i.red,High:i.orange,Medium:i.amber,Low:i.green};function xt({severities:e=[],"data-testid":r}){let a=(0,t.useRef)(null),c=(0,t.useRef)(new Map),u=(0,t.useRef)(0),{hoveredRef:d,tooltip:m,hitZonesRef:h}=v(a,{width:K,height:vt}),g=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,K,vt);u.current=0;let n=g.reduce((e,t)=>e+t.count,0),r=K-28-28,m=vt-50-52,_=g.map(e=>e.count/n*r),v,y=()=>{u.current++;let e=u.current;t.clearRect(0,0,K,vt),t.letterSpacing=o.letterSpacing;let a=S(Math.min(e/60,1));D(c.current,d.current),h.current=[],t.strokeStyle=l(i.bd,.2),t.lineWidth=1,t.beginPath(),t.rect(28,50,r,m),t.stroke(),t.strokeStyle=l(i.t2,.15),t.lineWidth=1,t.setLineDash([4,4]),t.beginPath(),t.moveTo(K/2,50),t.lineTo(K/2,50+m),t.stroke(),t.setLineDash([]);let f=28;g.forEach((e,r)=>{let u=bt[e.severity]??i.blue,d=_[r];d*a;let g=c.current.get(e.severity)??0,v=f+d/2,y=d*.85;v-y/2;let x=d*a,S=y*a,C=v-S/2;if(x>0&&(g>0&&p(t,f+x/2,50+m/2,x*.4,u,.15*g),t.beginPath(),t.moveTo(C,50),t.lineTo(C+S,50),t.lineTo(f+x,50+m),t.lineTo(f,50+m),t.closePath(),t.fillStyle=l(u,.45+g*.25),t.fill(),t.strokeStyle=l(u,(.5+g*.3)*a),t.lineWidth=g>0?2:1,t.beginPath(),t.moveTo(C,50),t.lineTo(C+S,50),t.stroke(),t.strokeStyle=l(u,(.3+g*.3)*a),t.lineWidth=g>0?2:1,t.beginPath(),t.moveTo(f,50+m),t.lineTo(f+x,50+m),t.stroke()),b(h.current,e.severity,f,50,d,m,{label:e.severity,value:`${e.count} Early Warnings`,sublabel:`${Math.round(e.count/n*100)}% of all EWs`,color:u}),a>.5){let r=Math.min(1,(a-.5)/.5),c=f+d/2;t.globalAlpha=r,t.font=o.font,t.fillStyle=g>0?u:l(u,.9),t.textAlign=`center`,t.fillText(yt(t,e.severity,d-12),c,38),t.font=s.font,t.fillStyle=g>0?i.t1:l(i.t1,.85),t.fillText(String(e.count),c,50+m/2+6),t.font=o.font,t.fillStyle=g>0?u:o.color,t.fillText(`${Math.round(e.count/n*100)}%`,c,50+m+18),t.globalAlpha=1}f+=d});let x=t.createLinearGradient(28,0,28+r,0);x.addColorStop(0,l(i.red,.03)),x.addColorStop(.33,l(i.orange,.03)),x.addColorStop(.66,l(i.amber,.03)),x.addColorStop(1,l(i.green,.03)),t.fillStyle=x,t.fillRect(28,50,r*a,m),v=requestAnimationFrame(y)};return y(),()=>cancelAnimationFrame(v)},[g]),g.length===0?(0,n.jsx)(P,{width:K,height:vt,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:K,height:vt},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Early Warning severity distribution — prism spectrum bands`,style:{width:K,height:vt,display:`block`}}),(0,n.jsx)(_,{...m,parentW:K,parentH:vt})]})}var q=460,J=300,St={Open:i.red,Submitted:i.amber,Closed:i.green};function Ct({segments:e=[],title:r,"data-testid":a}){let c=(0,t.useRef)(null),u=(0,t.useRef)(0),d=(0,t.useRef)(new Map),{hoveredRef:g,tooltip:b,hitZonesRef:x}=v(c,{width:q,height:J}),S=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=c.current;if(!e)return;let t=f(e,q,J);u.current=0;let n=q*.5,r=J*.54,a=q*.22,_=S.reduce((e,t)=>e+t.count,0),v=Math.max(...S.map(e=>e.count),1),b,C=()=>{u.current++;let e=u.current;t.clearRect(0,0,q,J),t.letterSpacing=o.letterSpacing,x.current=[],d.current.forEach((e,t)=>{let n=t===g.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?d.current.delete(t):d.current.set(t,1):d.current.set(t,r)}),g.current&&!d.current.has(g.current)&&d.current.set(g.current,0),m(t,q,J,e,40,l(i.blue,.04)),S.forEach((o,c)=>{let u=c/3*Math.PI*2-Math.PI/2,d=n+Math.cos(u)*a,f=r+Math.sin(u)*a,m=St[o.status]??i.blue,h=2+o.count/v*8;t.beginPath(),t.moveTo(n,r),t.lineTo(d,f),t.strokeStyle=l(m,.08),t.lineWidth=h*2,t.stroke(),t.beginPath(),t.moveTo(n,r),t.lineTo(d,f),t.strokeStyle=l(m,.25),t.lineWidth=1,t.stroke();let g=(e*.005+c*.33)%1,_=n+(d-n)*g,y=r+(f-r)*g;p(t,_,y,6,m,.4),t.beginPath(),t.arc(_,y,2,0,Math.PI*2),t.fillStyle=l(m,.8),t.fill();let b=(n+d)/2,x=(r+f)/2;t.font=s.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(m,.85),t.fillText(String(o.count),b,x)}),S.forEach((e,s)=>{let c=s/3*Math.PI*2-Math.PI/2,u=n+Math.cos(c)*a,f=r+Math.sin(c)*a,m=St[e.status]??i.blue,h=10+e.count/v*18,g=d.current.get(e.status)??0;p(t,u,f,h*2.5,m,.2+g*.15);let b=t.createRadialGradient(u,f-h*.2,0,u,f,h);b.addColorStop(0,l(m,.8+g*.2)),b.addColorStop(1,l(m,.4+g*.1)),t.beginPath(),t.arc(u,f,h,0,Math.PI*2),t.fillStyle=b,t.fill(),t.font=`bold `+o.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(i.t1,.9),t.fillText(e.status,u,f),y(x.current,e.status,u,f,h+6,{label:e.status,value:`${e.count} Early Warnings`,sublabel:`${Math.round(e.count/_*100)}%`,color:m})});let c=d.current.get(`center`)??0;p(t,n,r,36,i.t2,.2+c*.15);let f=t.createRadialGradient(n,r-4,0,n,r,22);f.addColorStop(0,l(i.t2,.9)),f.addColorStop(1,l(i.t2,.5)),t.beginPath(),t.arc(n,r,22,0,Math.PI*2),t.fillStyle=f,t.fill(),t.font=s.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(i.t1,.9),t.fillText(`EW Status`,n,r-4),t.font=`bold `+o.font,t.fillStyle=i.t1,t.fillText(String(_),n,r+8),y(x.current,`center`,n,r,28,{label:`Total EW Status`,value:`${_} Early Warnings`,color:i.t2}),h(t,q,J,e,.015),b=requestAnimationFrame(C)};return C(),()=>cancelAnimationFrame(b)},[S,r]),S.length===0?(0,n.jsx)(P,{width:q,height:J,"data-testid":a}):(0,n.jsxs)(`div`,{"data-testid":a,style:{position:`relative`,width:q,height:J},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":r??`EW status arc visualization`,style:{width:q,height:J,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...b,parentW:q,parentH:J})]})}var wt=280,Y=96;function Tt({points:e=[],className:a,colors:o}){let s=(0,t.useRef)(null),c=(0,t.useRef)(new Map),u=(0,t.useRef)(0),d=(0,t.useMemo)(()=>e.map(([e,t])=>{let n=String(t).match(/-?\d+(\.\d+)?/);return{label:e,value:n?Number(n[0]):0}}),[e]),{mouseRef:m,hoveredRef:h,tooltip:b,hitZonesRef:x}=v(s,{width:wt,height:Y});return(0,t.useEffect)(()=>{let e=s.current;if(!e)return;let t=f(e,wt,Y);u.current=0;let n=o?.line??i.blue,r=o?.point??i.blue,a=o?.axisLine??i.bd,_,v=()=>{u.current++;let e=u.current;if(t.clearRect(0,0,wt,Y),d.length<2){_=requestAnimationFrame(v);return}let o={left:12,right:12,top:16,bottom:20},s=wt-o.left-o.right,f=Y-o.top-o.bottom,b=d.map(e=>e.value),S=Math.min(...b),C=Math.max(...b)-S||1,w=e=>o.left+e/(d.length-1)*s,E=e=>o.top+(1-(e-S)/C)*f,O=1-(1-Math.min(e/48,1))**3,k=Math.max(2,Math.floor(O*d.length));if(D(c.current,h.current),x.current=[],t.strokeStyle=l(a,.3),t.lineWidth=.5,t.setLineDash([]),t.beginPath(),t.moveTo(o.left,Y-o.bottom),t.lineTo(wt-o.right,Y-o.bottom),t.stroke(),t.font=`9px 'JetBrains Mono', monospace`,t.fillStyle=l(i.t4,.9),t.textAlign=`center`,d.forEach((e,n)=>{t.fillText(e.label.replace(`Day `,`D`),w(n),Y-4)}),m.current.over&&h.current){let e=parseInt(h.current.split(`-`)[1]);isNaN(e)||g(t,w(e),o.top,o.top+f)}if(k>1){let e=t.createLinearGradient(0,o.top,0,o.top+f);e.addColorStop(0,l(n,.15)),e.addColorStop(1,l(n,0)),t.fillStyle=e,t.beginPath(),t.moveTo(w(0),o.top+f);for(let e=0;e<k;e++)t.lineTo(w(e),E(d[e].value));t.lineTo(w(k-1),o.top+f),t.closePath(),t.fill(),t.strokeStyle=l(n,.8),t.lineWidth=1.5,t.setLineDash([]),t.beginPath();for(let e=0;e<k;e++){let n=w(e),r=E(d[e].value);e===0?t.moveTo(n,r):t.lineTo(n,r)}t.stroke()}for(let e=0;e<k;e++){let n=w(e),a=E(d[e].value),o=`tp-${e}`,s=c.current.get(o)??0,u=e===d.length-1;y(x.current,o,n,a,10,{label:d[e].label,value:String(d[e].value),color:u?i.red:r}),s>0&&!u&&(p(t,n,a,12*s,r,.2*s),t.fillStyle=l(r,.8),t.beginPath(),t.arc(n,a,3+s*2,0,Math.PI*2),t.fill())}if(k>=d.length){let n=d.length-1,r=w(n),a=E(d[n].value),o=c.current.get(`tp-${n}`)??0,s=T(e,.05,5e-4),u=1+o*.5;t.shadowColor=l(i.red,.5),t.shadowBlur=(8+s*4)*u,t.fillStyle=i.red,t.beginPath(),t.arc(r,a,(3.5+s*1.5)*u,0,Math.PI*2),t.fill(),t.shadowBlur=0}_=requestAnimationFrame(v)};return v(),()=>cancelAnimationFrame(_)},[d,o]),(0,n.jsx)(r,{className:[`canvas-trend-frame`,a].filter(Boolean).join(` `),children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:wt,height:Y},children:[(0,n.jsx)(`canvas`,{ref:s,role:`img`,"aria-label":`trend chart`,style:{width:wt,height:Y,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...b,parentW:wt,parentH:Y})]})})}var X=680,Et=8,Dt=26,Ot=14,kt=16,At=32;function jt({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),[m,h]=(0,t.useState)(!1),g=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),y=(0,t.useMemo)(()=>m?g:g.slice(0,Et),[g,m]),x=kt+At+y.length*(Dt+Ot)-Ot,{hoveredRef:C,tooltip:w,hitZonesRef:T}=v(a,{width:X,height:x});return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,X,x);d.current=0;let n=kt,r=At,m=Dt,h=Ot,g=X-60-28,_=Math.max(...y.map(e=>(e.implemented??0)+(e.unimplemented??0))),v=y.length*(m+h)-h,w=n+(x-n-r-v)/2,O,k=()=>{d.current++;let e=d.current;t.clearRect(0,0,X,x);let n=S(Math.min(e/60,1));D(u.current,C.current),T.current=[],y.forEach((e,r)=>{let a=E(n,r,y.length,S),c=w+r*(m+h),d=(e.implemented??0)+(e.unimplemented??0),f=(e.implemented??0)/_*g*a,v=(e.unimplemented??0)/_*g*a,x=`${e.id}-impl`,C=`${e.id}-un`,D=u.current.get(x)??0,O=u.current.get(C)??0;b(T.current,x,60,c,f||1,m,{label:`${e.name} — Implemented`,value:`${e.implemented??0} variations`,sublabel:`${Math.round((e.implemented??0)/(d||1)*100)}% complete`,color:i.green}),b(T.current,C,60+f,c,v||1,m,{label:`${e.name} — Unimplemented`,value:`${e.unimplemented??0} variations`,sublabel:`${Math.round((e.unimplemented??0)/(d||1)*100)}% pending`,color:i.amber}),t.font=o.font,t.fillStyle=i.t2,t.textAlign=`right`,t.fillText(e.abbreviation??e.name.slice(0,6),52,c+m/2+4),t.fillStyle=l(i.bd,.15),t.beginPath(),t.roundRect(60,c,d/_*g,m,4),t.fill(),f>0&&(D>0&&p(t,60+f/2,c+m/2,f*.3,i.green,.12*D),t.fillStyle=l(i.green,.6+D*.2),t.beginPath(),t.roundRect(60,c,f,m,[4,0,0,4]),t.fill(),f>28&&a>.5&&(t.font=s.font,t.fillStyle=D>0?i.green:i.t2,t.textAlign=`center`,t.fillText(String(e.implemented??0),60+f/2,c+m/2+4))),v>0&&(O>0&&p(t,60+f+v/2,c+m/2,v*.3,i.amber,.12*O),t.fillStyle=l(i.amber,.18+O*.18),t.strokeStyle=l(i.amber,.3+O*.3),t.lineWidth=1,t.beginPath(),t.roundRect(60+f,c,v,m,[0,4,4,0]),t.fill(),t.stroke(),v>28&&a>.5&&(t.font=s.font,t.fillStyle=O>0?i.amber:i.t2,t.textAlign=`center`,t.fillText(String(e.unimplemented??0),60+f+v/2,c+m/2+4))),f>0&&v>0&&(t.strokeStyle=l(i.bg,.7),t.lineWidth=2,t.beginPath(),t.moveTo(60+f,c),t.lineTo(60+f,c+m),t.stroke())});let r=w+v+24,a=60+g/2;t.font=c.font,t.textAlign=`right`,t.fillStyle=i.green,t.fillText(`■ Implemented`,a-10,r),t.textAlign=`left`,t.fillStyle=c.color,t.fillText(`■ Unimplemented`,a+10,r),O=requestAnimationFrame(k)};return k(),()=>cancelAnimationFrame(O)},[y,x]),g.length===0?(0,n.jsx)(P,{width:X,height:160,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{width:X},children:[(0,n.jsxs)(`div`,{style:{position:`relative`,width:X,height:x},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Implemented vs unimplemented variations per contractor — split bar`,style:{width:X,height:x,display:`block`}}),(0,n.jsx)(_,{...w,parentW:X,parentH:x})]}),g.length>Et&&(0,n.jsx)(`div`,{style:{marginTop:8},children:(0,n.jsx)(te,{expanded:m,onToggle:()=>h(e=>!e)})})]})}var Mt=800,Nt=360;function Pt({items:e=[],"data-testid":r}){let c=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),{hoveredRef:m,tooltip:h,hitZonesRef:g}=v(c,{width:Mt,height:Nt});return(0,t.useEffect)(()=>{let t=c.current;if(!t)return;let n=f(t,Mt,Nt);d.current=0;let r=e.reduce((e,t)=>e+(t.base??0),0),h=e.reduce((e,t)=>e+(t.variation??0),0),_=e.reduce((e,t)=>e+(t.total??0),0),v=Nt-20-26,y=v-6*(e.length-1),S=20,C=e.map((e,t)=>{let n=Math.max(24,(e.total??0)/(_||1)*y),r={x:100-110/2,y:S,h:n,cy:S+n/2,c:e,color:a[t%a.length]};return S+=n+6,r}),w=y-14,T=Math.max(28,r/_*w),O=Math.max(18,h/_*w),k=20+(v-(T+O+14))/2,A={x:420-110/2,y:k,h:T,cy:k+T/2},j={x:420-110/2,y:k+T+14,h:O,cy:k+T+14+O/2},M={x:720-110/2,y:20,h:v,cy:20+v/2},N,ee=()=>{d.current++;let t=d.current;n.clearRect(0,0,Mt,Nt),n.letterSpacing=o.letterSpacing;let a=x(Math.min(t/80,1));if(D(u.current,m.current),g.current=[],e.forEach((t,i)=>{let o=C[i],s=E(a,i,e.length,x),c=u.current.get(t.id)??0;if(s<.01)return;let l=(t.base??0)/(t.total||1),d=(t.variation??0)/(t.total||1),f=o.h*l,p=o.h*d,m=o.y+f/2,g=o.y+f+p/2,_=Math.max(2,(t.base??0)/r*T),v=Math.max(2,(t.variation??0)/h*O),y=A.y+e.slice(0,i).reduce((e,t)=>e+(t.base??0)/r*T,0)+_/2,b=j.y+e.slice(0,i).reduce((e,t)=>e+(t.variation??0)/h*O,0)+v/2,S=c*.2+.18;Ft(n,o.x+110,m,420-110/2,y,_*s,o.color,S),Ft(n,o.x+110,g,420-110/2,b,v*s,o.color,S*.75)}),a>.3){let e=Math.min(1,(a-.3)/.7),t=M.y+r/_*v/2,o=M.y+v-h/_*v/2;Ft(n,475,A.cy,720-110/2,t,T*e,i.blue,.25*e),Ft(n,475,j.cy,720-110/2,o,O*e,i.amber,.22*e)}if([`Contractors`,`Components`,`Total`].forEach((e,t)=>{let r=[100,420,720][t];n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(e,r,Nt-8)}),e.forEach((t,r)=>{let s=C[r],c=E(a,r,e.length,x),d=u.current.get(t.id)??0;b(g.current,t.id,s.x,s.y,110,s.h,{label:t.name,value:`£${t.total??0}M total commitment`,sublabel:`Base £${t.base??0}M + Variations £${t.variation??0}M`,color:s.color}),d>0&&p(n,s.x+110/2,s.cy,110*.6,s.color,.12*d),n.fillStyle=l(s.color,(.3+d*.15)*c),n.strokeStyle=l(s.color,(.55+d*.25)*c),n.lineWidth=1,n.beginPath(),n.roundRect(s.x,s.y,110*c,s.h,4),n.fill(),n.stroke(),c>.6&&s.h>=24&&(n.globalAlpha=Math.min(1,(c-.6)/.4),n.font=o.font,n.fillStyle=d>0?s.color:l(i.t2,.9),n.textAlign=`center`,n.textBaseline=`middle`,n.fillText(t.abbreviation??t.name.slice(0,6),s.x+110/2,s.h>=36?s.cy-5:s.cy),s.h>=36&&(n.font=`400 12px 'Satoshi Variable', 'DM Sans', sans-serif`,n.fillStyle=l(i.t3,.8),n.fillText(`£${t.total??0}M`,s.x+110/2,s.cy+7)),n.globalAlpha=1,n.textBaseline=`alphabetic`)}),a>.2){let e=Math.min(1,(a-.2)/.4);p(n,420,A.cy,30,i.blue,.1*e),n.fillStyle=l(i.blue,.3*e),n.strokeStyle=l(i.blue,.5*e),n.lineWidth=1,n.beginPath(),n.roundRect(A.x,A.y,110,A.h*e,4),n.fill(),n.stroke(),n.globalAlpha=e,n.textBaseline=`middle`,n.font=o.font,n.fillStyle=i.blue,n.textAlign=`center`,n.fillText(`Base Value`,420,A.cy-6),n.font=s.font,n.fillStyle=s.color,n.fillText(`£${r}M`,420,A.cy+8),n.globalAlpha=1,n.textBaseline=`alphabetic`,p(n,420,j.cy,24,i.amber,.1*e),n.fillStyle=l(i.amber,.22*e),n.strokeStyle=l(i.amber,.4*e),n.beginPath(),n.roundRect(j.x,j.y,110,j.h*e,4),n.fill(),n.stroke(),n.globalAlpha=e,n.textBaseline=`middle`,n.font=o.font,n.fillStyle=i.amber,n.textAlign=`center`,n.fillText(`Variations`,420,j.cy-4),n.font=s.font,n.fillStyle=s.color,n.fillText(`£${h}M`,420,j.cy+8),n.globalAlpha=1,n.textBaseline=`alphabetic`}if(a>.5){let e=Math.min(1,(a-.5)/.5);p(n,720,M.cy,44,i.blue,.2*e),n.fillStyle=l(i.blue,.25*e),n.strokeStyle=l(i.blue,.6*e),n.lineWidth=1.5,n.beginPath(),n.roundRect(M.x,M.y,110,M.h*e,6),n.fill(),n.stroke(),n.globalAlpha=e,n.textBaseline=`middle`,n.font=o.font,n.fillStyle=i.t2,n.textAlign=`center`,n.fillText(`Total Commitment`,720,M.cy-12),n.font=s.font,n.fillStyle=i.blue,n.fillText(`£${_}M`,720,M.cy+6),n.globalAlpha=1,n.textBaseline=`alphabetic`}N=requestAnimationFrame(ee)};return ee(),()=>cancelAnimationFrame(N)},[e]),(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:Mt,height:Nt},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`Weekly report flow — base value and variations per contractor flowing to total commitment`,style:{width:Mt,height:Nt,display:`block`}}),(0,n.jsx)(_,{...h,parentW:Mt,parentH:Nt})]})}function Ft(e,t,n,r,i,a,o,s){let c=(t+r)/2;e.beginPath(),e.moveTo(t,n-a/2),e.bezierCurveTo(c,n-a/2,c,i-a/2,r,i-a/2),e.lineTo(r,i+a/2),e.bezierCurveTo(c,i+a/2,c,n+a/2,t,n+a/2),e.closePath(),e.fillStyle=l(o,s),e.fill()}function It({config:e,className:t}){return e.type===`line`?(0,n.jsx)(Me,{rows:e.rows,className:t}):e.type===`area`?(0,n.jsx)(j,{rows:e.rows,className:t}):e.type===`bar`?(0,n.jsx)(ee,{rows:e.rows,className:t}):e.type===`pie`?(0,n.jsx)(We,{rows:e.rows,variant:`pie`,className:t}):e.type===`donut`?(0,n.jsx)(We,{rows:e.rows,variant:`donut`,className:t}):e.type===`sankey`?(0,n.jsx)(tt,{rows:e.rows,className:t}):e.type===`flow`?(0,n.jsx)(et,{selectedEntity:e.selectedEntity,className:t}):e.type===`trend`?(0,n.jsx)(Tt,{points:e.points,className:t}):e.type===`mini-bars`?(0,n.jsx)(Fe,{rows:e.rows,className:t}):e.type===`stacked-horizontal-bar-chart`?(0,n.jsx)(Ee,{data:e.data}):e.type===`multi-metric-constellation-chart`?(0,n.jsx)(ye,{items:e.items}):e.type===`progress-race-chart`?(0,n.jsx)(ce,{items:e.items}):e.type===`hub-and-spoke-radial-chart`?(0,n.jsx)(Ct,{segments:e.segments,title:e.title}):e.type===`dot-matrix-chart`?(0,n.jsx)(je,{items:e.items}):e.type===`ranked-card-leaderboard`?(0,n.jsx)(Ae,{items:e.items}):e.type===`proportional-band-chart`?(0,n.jsx)(xt,{severities:e.severities}):e.type===`radial-fan-tree-chart`?(0,n.jsx)(Be,{total:e.total,items:e.items}):e.type===`semi-circular-gauge-chart`?(0,n.jsx)(de,{value:e.value,confirmed:e.confirmed,total:e.total}):e.type===`segmented-split-bar-chart`?(0,n.jsx)(jt,{items:e.items}):e.type===`balance-scale-chart`?(0,n.jsx)(it,{left:e.left,right:e.right}):e.type===`area-line-chart`?(0,n.jsx)(ot,{points:e.points}):e.type===`trend-view`?(0,n.jsx)(_t,{points:e.points}):e.type===`weekly-flow`?(0,n.jsx)(Pt,{items:e.items}):(0,n.jsx)(`div`,{className:`viz-empty`,children:`Visualization unavailable`})}var Lt=[];function Rt(e){try{return JSON.parse(decodeURIComponent(e))}catch{return null}}function zt(){for(;Lt.length;){let e=Lt.pop();e&&e.unmount()}}function Bt(){zt(),document.querySelectorAll(`[data-d3-viz]`).forEach(t=>{let r=t.dataset.d3Viz;if(!r)return;let i=Rt(r);if(!i)return;let a=(0,e.createRoot)(t);Lt.push(a),a.render((0,n.jsx)(It,{config:i}))})}function Vt(e){return encodeURIComponent(JSON.stringify(e))}function Ht({rows:e=[],className:t,colors:r}){return(0,n.jsx)(We,{rows:e,variant:`donut`,className:t,colors:r})}var Z={bg:`transparent`,border:`transparent`,t1:i.t1,t2:i.t2,t3:i.t3,t4:i.t4,red:i.red,amber:i.amber,green:i.green},Q=`'Satoshi Variable', 'DM Sans', sans-serif`,Ut={color:`#F7F7F7`,fontFamily:Q,fontSize:24,fontWeight:500,lineHeight:`32px`},$={color:`#C2C2C2`,fontFamily:Q,fontSize:18,fontWeight:400,lineHeight:`20px`};function Wt({chips:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,gap:6,marginTop:10},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{width:260,height:120,display:`flex`,alignItems:`baseline`,gap:8,padding:`8px 12px`,background:Z.bg,border:`1px solid ${Z.border}`,borderRadius:5,boxSizing:`border-box`},children:[(0,n.jsx)(`span`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`span`,{style:{...$,flex:1},children:e.label})]},t))})}function Gt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,gap:8},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,justifyContent:`center`,alignItems:`flex-start`,width:260,height:120,padding:24,gap:8,flexShrink:0,border:`1px solid ${Z.border}`,background:Z.bg,boxSizing:`border-box`},children:[(0,n.jsx)(`div`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`div`,{style:{...$},children:e.label})]},t))})}function Kt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:12,padding:`9px 14px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:e.color??Z.t2,background:(e.color??Z.t2)+`22`,padding:`2px 8px`,borderRadius:4,fontFamily:Q,flexShrink:0},children:e.name}),(0,n.jsx)(`span`,{style:{...Ut,fontSize:18,color:e.color??Z.t1,minWidth:70,flexShrink:0},children:e.value}),(0,n.jsx)(`span`,{style:{...$,flex:1},children:e.kpiLabel})]},t))})}function qt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,gap:8},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,justifyContent:`center`,alignItems:`flex-start`,width:260,height:120,padding:24,gap:8,flexShrink:0,background:Z.bg,boxSizing:`border-box`},children:[(0,n.jsx)(`div`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`div`,{style:{...$},children:e.label})]},t))})}var Jt={red:Z.red,amber:Z.amber,green:Z.green};function Yt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>{let r=Jt[e.severity];return(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:10,padding:`10px 14px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{width:7,height:7,borderRadius:`50%`,background:r,flexShrink:0,marginTop:5}}),(0,n.jsx)(`span`,{style:{...$},children:e.text})]},t)})})}function Xt({min:e,max:t,unit:r,dots:a=[],chips:o=[]}){let s=t-e;return(0,n.jsxs)(`div`,{children:[(0,n.jsxs)(`div`,{style:{position:`relative`,height:90,marginTop:4},children:[(0,n.jsx)(`div`,{style:{position:`absolute`,top:38,left:8,right:8,height:2,background:`rgba(255,255,255,0.08)`,borderRadius:1}}),(0,n.jsxs)(`div`,{style:{position:`absolute`,top:43,left:0,fontSize:16,color:Z.t4,fontFamily:Q},children:[e,r]}),(0,n.jsxs)(`div`,{style:{position:`absolute`,top:43,right:0,fontSize:16,color:Z.t4,fontFamily:Q},children:[t,r]}),a.map((t,a)=>{let o=(t.val-e)/s*100,c=t.color??i.blue,l=a%2==0;return(0,n.jsxs)(`div`,{style:{position:`absolute`,left:`${o}%`,top:0,transform:`translateX(-50%)`},children:[l&&(0,n.jsxs)(`div`,{style:{textAlign:`center`,marginBottom:2},children:[(0,n.jsx)(`div`,{style:{fontSize:18,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:t.name}),(0,n.jsxs)(`div`,{style:{fontSize:18,fontWeight:500,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:[t.val,r]})]}),(0,n.jsx)(`div`,{style:{width:10,height:10,borderRadius:`50%`,background:c,boxShadow:`0 0 8px ${c}70`,margin:l?`0 auto`:`26px auto 0`}}),!l&&(0,n.jsxs)(`div`,{style:{textAlign:`center`,marginTop:4},children:[(0,n.jsx)(`div`,{style:{fontSize:18,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:t.name}),(0,n.jsxs)(`div`,{style:{fontSize:18,fontWeight:500,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:[t.val,r]})]})]},a)})]}),o&&o.length>0&&(0,n.jsx)(Wt,{chips:o})]})}function Zt({leftPct:e,leftLabel:t,leftValue:r,leftColor:a,rightPct:o,rightLabel:s,rightValue:c,rightColor:l,chips:u}){let d=a??i.blue,f=l??i.blue;return(0,n.jsxs)(`div`,{children:[(0,n.jsxs)(`div`,{style:{display:`flex`,borderRadius:6,overflow:`hidden`,height:36,marginBottom:8},children:[(0,n.jsx)(`div`,{style:{width:`${e}%`,background:d+`38`,display:`flex`,alignItems:`center`,justifyContent:`flex-end`,paddingRight:12},children:(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:d,fontFamily:Q},children:r})}),(0,n.jsx)(`div`,{style:{width:1,background:`rgba(255,255,255,0.12)`,flexShrink:0}}),(0,n.jsx)(`div`,{style:{width:`${o}%`,background:f+`2A`,display:`flex`,alignItems:`center`,paddingLeft:12},children:(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:f,fontFamily:Q},children:c})})]}),(0,n.jsxs)(`div`,{style:{display:`flex`,marginBottom:u?4:0},children:[(0,n.jsx)(`div`,{style:{width:`${e}%`},children:(0,n.jsxs)(`span`,{style:{fontSize:18,color:d,fontFamily:Q},children:[e,`% `,t]})}),(0,n.jsx)(`div`,{style:{width:`${o}%`,paddingLeft:10},children:(0,n.jsxs)(`span`,{style:{fontSize:18,color:f,fontFamily:Q},children:[o,`% `,s]})})]}),u&&u.length>0&&(0,n.jsx)(Wt,{chips:u})]})}function Qt({pct:e,label:t,color:r,chips:a}){let o=r??i.blue,s=2*Math.PI*30,c=s*(1-e/100);return(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:20},children:[(0,n.jsxs)(`div`,{style:{position:`relative`,flexShrink:0,width:80,height:80},children:[(0,n.jsxs)(`svg`,{width:80,height:80,style:{transform:`rotate(-90deg)`},children:[(0,n.jsx)(`circle`,{cx:40,cy:40,r:30,fill:`none`,stroke:`rgba(255,255,255,0.07)`,strokeWidth:8}),(0,n.jsx)(`circle`,{cx:40,cy:40,r:30,fill:`none`,stroke:o,strokeWidth:8,strokeDasharray:s,strokeDashoffset:c,strokeLinecap:`round`})]}),(0,n.jsx)(`div`,{style:{position:`absolute`,top:`50%`,left:`50%`,transform:`translate(-50%, -50%)`,textAlign:`center`},children:(0,n.jsxs)(`div`,{style:{fontSize:18,fontWeight:500,color:o,fontFamily:Q},children:[e,`%`]})})]}),(0,n.jsxs)(`div`,{style:{flex:1},children:[(0,n.jsx)(`div`,{style:{...$,marginBottom:10},children:t}),a&&(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:a.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,gap:8,padding:`7px 10px`,background:Z.bg,border:`1px solid ${Z.border}`,borderRadius:5},children:[(0,n.jsx)(`span`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`span`,{style:{...$},children:e.label})]},t))})]})]})}var $t={green:`#34D39918`,amber:`#FBBF2418`,red:`#F0606018`},en={green:`#34D399`,amber:`#FBBF24`,red:`#F06060`};function tn({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`8px 12px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:e.color??Z.t2,background:(e.color??Z.t2)+`1A`,padding:`2px 7px`,borderRadius:4,fontFamily:Q,flexShrink:0,minWidth:62,textAlign:`center`},children:e.name}),(0,n.jsx)(`div`,{style:{flex:1,height:4,background:`rgba(255,255,255,0.07)`,borderRadius:2,overflow:`hidden`},children:(0,n.jsx)(`div`,{style:{height:`100%`,width:`${e.pct}%`,background:e.color??Z.t2,borderRadius:2,opacity:.75}})}),(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:e.color??Z.t1,fontFamily:Q,flexShrink:0,minWidth:52,textAlign:`right`},children:e.value}),e.badge&&e.badgeSeverity&&(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:en[e.badgeSeverity],background:$t[e.badgeSeverity],padding:`2px 7px`,borderRadius:4,fontFamily:Q,flexShrink:0,minWidth:72,textAlign:`center`},children:e.badge}),e.sublabel&&(0,n.jsx)(`span`,{style:{...$,flexShrink:0,minWidth:80,textAlign:`right`},children:e.sublabel})]},t))})}var nn={red:Z.red,amber:Z.amber,green:Z.green};function rn({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>{let r=nn[e.severity];return(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:10,padding:`9px 12px`,background:r+`0A`,border:`1px solid ${r}25`},children:[(0,n.jsx)(`span`,{style:{width:7,height:7,borderRadius:`50%`,background:r,flexShrink:0,marginTop:5}}),(0,n.jsx)(`span`,{style:{flex:1,...$},children:e.text}),(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:r,background:r+`20`,padding:`2px 7px`,borderRadius:4,fontFamily:Q,flexShrink:0},children:e.tag}),(0,n.jsx)(`span`,{style:{...$,flexShrink:0,marginTop:1},children:e.date})]},t)})})}function an({columns:e=[],rows:t=[]}){return(0,n.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:[(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`0 12px 6px`,borderBottom:`1px solid ${Z.border}`},children:[(0,n.jsx)(`div`,{style:{minWidth:64}}),e.map((e,t)=>(0,n.jsx)(`div`,{style:{flex:1,fontSize:18,fontWeight:500,color:Z.t2,fontFamily:Q,textTransform:`uppercase`,letterSpacing:.6},children:e},t))]}),t.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`8px 12px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:600,color:Z.t2,background:(e.color??Z.t4)+`1A`,padding:`2px 8px`,borderRadius:4,fontFamily:Q,flexShrink:0,minWidth:64,textAlign:`center`},children:e.label}),e.cells.map((t,r)=>(0,n.jsx)(`span`,{style:{flex:1,fontSize:18,fontWeight:500,color:e.color??Z.t1,fontFamily:Q},children:t},r))]},t))]})}function on({block:e}){if(!e)return null;switch(e.type){case`stats`:return(0,n.jsx)(Gt,{items:e.items});case`ranked`:return(0,n.jsx)(Kt,{items:e.items});case`chips`:return(0,n.jsx)(qt,{items:e.items});case`badges`:return(0,n.jsx)(Yt,{items:e.items});case`dot-strip`:return(0,n.jsx)(Xt,{min:e.min,max:e.max,unit:e.unit,dots:e.dots,chips:e.chips});case`proportion`:return(0,n.jsx)(Zt,{leftPct:e.leftPct,leftLabel:e.leftLabel,leftValue:e.leftValue,leftColor:e.leftColor,rightPct:e.rightPct,rightLabel:e.rightLabel,rightValue:e.rightValue,rightColor:e.rightColor,chips:e.chips});case`ring`:return(0,n.jsx)(Qt,{pct:e.pct,label:e.label,color:e.color,chips:e.chips});case`scorecard-rows`:return(0,n.jsx)(tn,{items:e.items});case`flags-list`:return(0,n.jsx)(rn,{items:e.items});case`comparison-rows`:return(0,n.jsx)(an,{columns:e.columns,rows:e.rows});default:return null}}var sn=`'Satoshi Variable', 'DM Sans', sans-serif`,cn={color:`#C2C2C2`,fontFamily:sn,fontSize:18,fontWeight:400,lineHeight:`20px`};function ln({text:e}){return(0,n.jsxs)(`div`,{style:{padding:`8px 0px`,border:`transparent`,borderRadius:5,background:`transparent`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:i.t1,fontFamily:sn,lineHeight:`20px`,marginRight:8},children:`Takeaway`}),(0,n.jsx)(`span`,{style:{...cn},children:e})]})}exports.AreaChart=j,exports.BarChart=ee,exports.ChartFrame=r,exports.DonutChart=Ht,exports.KeyHighlights=on,exports.LineChart=Me,exports.MiniBars=Fe,exports.PieChart=We,exports.ProcessSankey=et,exports.RankingSankey=tt,exports.SankeySvg=Ke,exports.SeriesChart=A,exports.Takeaway=ln,exports.Trend=_t,exports.TrendChart=Tt,exports.VisualizationRenderer=It,exports.cleanupVisualizationMounts=zt,exports.hydrateVisualizationMounts=Bt,exports.serializeVisualizationConfig=Vt;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`react-dom/client`),t=require(`react`),n=require(`react/jsx-runtime`);function r({children:e,className:t=``}){return(0,n.jsx)(`div`,{className:`d3-chart ${t}`.trim(),children:e})}var i={bg:`#0C0E12`,bgL:`#0C1420`,sf:`#13161B`,bd:`#22262F`,blue:`#4C93D9`,cyan:`#36BFFA`,orange:`#EC772A`,red:`#EC772A`,green:`#5DA537`,purple:`#818FF8`,amber:`#EEBF3B`,t1:`#F7F9FA`,t2:`#B3B5B6`,t3:`#94979C`,t4:`#334155`},a=[i.blue,i.amber,i.purple,i.green,i.red],o={font:`400 16px 'Satoshi Variable', 'DM Sans', sans-serif`,color:`#F7F7F7`,letterSpacing:`0px`},s={font:`500 16px 'Satoshi Variable', 'DM Sans', sans-serif`,color:`#F7F7F7`},c={font:`400 18px 'Satoshi Variable', 'DM Sans', sans-serif`,color:`#B3B5B6`,letterSpacing:`0px`};function l(e,t=1){let n=e.replace(`#`,``);return`rgba(${parseInt(n.substring(0,2),16)},${parseInt(n.substring(2,4),16)},${parseInt(n.substring(4,6),16)},${t})`}function u(e,t,n){return e+(t-e)*n}function d(e,t,n){let r=e=>{let t=e.replace(`#`,``);return[parseInt(t.substring(0,2),16),parseInt(t.substring(2,4),16),parseInt(t.substring(4,6),16)]},[i,a,o]=r(e),[s,c,l]=r(t),d=e=>Math.max(0,Math.min(255,Math.round(e)));return[d(u(i,s,n)),d(u(a,c,n)),d(u(o,l,n))].map(e=>e.toString(16).padStart(2,`0`)).join(``).replace(/^/,`#`)}function f(e,t,n,r=2){e.width=t*r,e.height=n*r;let i=e.getContext(`2d`);return i.scale(r,r),i}function p(e,t,n,r,i,a=.3){let o=e.createRadialGradient(t,n,0,t,n,r);o.addColorStop(0,l(i,a)),o.addColorStop(1,l(i,0)),e.fillStyle=o,e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fill()}function m(e,t,n,r,a=50,o=l(i.blue,.05)){for(let i=0;i<a;i++)e.beginPath(),e.arc((Math.sin(r*.001+i*23)*.5+.5)*t,(Math.cos(r*8e-4+i*37)*.5+.5)*n,.6,0,Math.PI*2),e.fillStyle=o,e.fill()}function h(e,t,n,r,i=.015){e.fillStyle=`rgba(0,0,0,${i})`;let a=r*.5%6;for(let r=a;r<n;r+=3)e.fillRect(0,r,t,1)}function g(e,t,n,r,a=l(i.t1,.08)){e.strokeStyle=a,e.lineWidth=1,e.setLineDash([3,3]),e.beginPath(),e.moveTo(t,n),e.lineTo(t,r),e.stroke(),e.setLineDash([])}function _({visible:e,x:r,y:a,content:o,parentW:s}){let c=(0,t.useRef)(null);if((0,t.useLayoutEffect)(()=>{let t=c.current;if(!t)return;let n=t.offsetWidth,l=r-n/2,u=a-58;l<4&&(l=4),l+n>(s??400)-4&&(l=(s??400)-n-4),u<4&&(u=a+16),t.style.transform=`translate(${l}px, ${u}px)`,t.style.opacity=e?`1`:`0`;let d=o&&typeof o==`object`&&o.color?o.color:i.blue;t.style.setProperty(`--tooltip-accent`,d??i.blue)},[e,r,a,s,o]),!o)return null;let l=typeof o==`object`,u=l?o.label:null,d=l?o.value:o,f=l?o.sublabel:null;return(0,n.jsxs)(`div`,{ref:c,style:{position:`absolute`,top:0,left:0,minWidth:80,pointerEvents:`none`,background:i.sf,border:`1px solid ${i.bd}`,borderLeft:`2px solid var(--tooltip-accent)`,borderRadius:6,padding:`8px 12px`,opacity:0,transition:`opacity 0.15s ease`,zIndex:20,fontFamily:`'Satoshi Variable', 'DM Sans', sans-serif`},children:[u&&(0,n.jsx)(`div`,{style:{fontSize:14,fontWeight:400,color:i.t2,marginBottom:3,whiteSpace:`nowrap`,lineHeight:`20px`},children:u}),(0,n.jsx)(`div`,{style:{fontSize:16,fontWeight:500,color:i.t1,whiteSpace:`nowrap`,lineHeight:`22px`},children:d}),f&&(0,n.jsx)(`div`,{style:{fontSize:14,fontWeight:400,color:`var(--tooltip-accent)`,marginTop:3,whiteSpace:`nowrap`,lineHeight:`20px`},children:f})]})}function v(e,{width:n,height:r,onClick:i,enabled:a=!0}){let o=(0,t.useRef)({x:-1,y:-1,over:!1}),s=(0,t.useRef)(null),c=(0,t.useRef)([]),l=(0,t.useRef)(null),[u,d]=(0,t.useState)({visible:!1,x:0,y:0,content:null}),f=(0,t.useCallback)((e,t,n)=>{l.current&&clearTimeout(l.current),l.current=setTimeout(()=>{d({visible:!0,x:e,y:t,content:n})},30)},[]),p=(0,t.useCallback)(()=>{l.current&&clearTimeout(l.current),d(e=>e.visible?{visible:!1,x:e.x,y:e.y,content:e.content}:e)},[]);return(0,t.useEffect)(()=>{let t=e.current;if(!t||!a)return;let u=e=>{let i=t.getBoundingClientRect(),a=n/i.width,l=r/i.height;o.current.x=(e.clientX-i.left)*a,o.current.y=(e.clientY-i.top)*l,o.current.over=!0;let u=null,d=c.current;for(let e=d.length-1;e>=0;e--)if(d[e].test(o.current.x,o.current.y)){u=d[e];break}let m=s.current;s.current=u?u.id:null,t.style.cursor=u?`pointer`:`default`,u?f((e.clientX-i.left)*a,(e.clientY-i.top)*l,u.data):m&&p()},d=()=>{o.current={x:-1,y:-1,over:!1},s.current&&(s.current=null,t.style.cursor=`default`,p())},m=()=>{if(s.current&&i){let e=c.current.find(e=>e.id===s.current);e&&i(e.id,e.data)}};return t.addEventListener(`mousemove`,u),t.addEventListener(`mouseleave`,d),t.addEventListener(`click`,m),()=>{t.removeEventListener(`mousemove`,u),t.removeEventListener(`mouseleave`,d),t.removeEventListener(`click`,m),l.current&&clearTimeout(l.current)}},[e,n,r,a,i,f,p]),{mouseRef:o,hoveredRef:s,tooltip:u,showTooltip:f,hideTooltip:p,hitZonesRef:c}}function y(e,t,n,r,i,a){e.push({id:t,data:a,test:(e,t)=>(e-n)**2+(t-r)**2<=i*i})}function b(e,t,n,r,i,a,o){e.push({id:t,data:o,test:(e,t)=>e>=n&&e<=n+i&&t>=r&&t<=r+a})}var x=e=>1-(1-e)**3,S=e=>1-(1-e)**4,C=e=>e===1?1:1-2**(-10*e),w=e=>{let t=1.70158;return 1+(t+1)*(e-1)**3+t*(e-1)**2},T=(e,t=.04,n=.001)=>Math.sin(e*t)*Math.exp(-Math.min(e*n,4)),E=(e,t,n,r=x)=>{let i=Math.min(.06,.5/n),a=t*i,o=1-(n-1)*i;return r(Math.max(0,Math.min((e-a)/o,1)))};function D(e,t,n=.12){e.forEach((r,i)=>{let a=i===t?1:0,o=r+(a-r)*n;Math.abs(o-a)<.005?a===0?e.delete(i):e.set(i,1):e.set(i,o)}),t&&!e.has(t)&&e.set(t,0)}var O=760,k=250;function A({rows:e=[],variant:a,className:o,colors:s}){let c=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),{mouseRef:m,hoveredRef:h,tooltip:b,hitZonesRef:x}=v(c,{width:O,height:k});return(0,t.useEffect)(()=>{let t=c.current;if(!t)return;let n=f(t,O,k);d.current=0;let r=s?.line??i.blue,o=s?.point??i.blue,_=s?.axisLine??i.bd,v=s?.areaFill??i.blue,b={top:24,right:24,bottom:44,left:24},S=O-b.left-b.right,w=k-b.top-b.bottom,E,A=()=>{d.current++;let t=d.current;if(n.clearRect(0,0,O,k),e.length<2){E=requestAnimationFrame(A);return}let s=e.map(e=>e.pricing??0),c=Math.max(100,...s),f=t=>b.left+t/(e.length-1)*S,j=e=>b.top+(1-e/c)*w,M=C(Math.min(t/48,1)),N=Math.max(2,Math.floor(M*e.length));D(u.current,h.current),x.current=[],n.strokeStyle=l(i.bd,.2),n.lineWidth=.5;for(let e=0;e<=4;e++){let t=b.top+e/4*w;n.beginPath(),n.moveTo(b.left,t),n.lineTo(b.left+S,t),n.stroke()}if(n.strokeStyle=l(_,.4),n.lineWidth=1,n.setLineDash([]),n.beginPath(),n.moveTo(b.left,j(0)),n.lineTo(b.left+S,j(0)),n.stroke(),m.current.over&&h.current){let e=parseInt(h.current.split(`-`)[1]);isNaN(e)||g(n,f(e),b.top,b.top+w)}if(a===`area`&&N>1){let t=n.createLinearGradient(0,b.top,0,b.top+w);t.addColorStop(0,l(v,.12)),t.addColorStop(1,l(v,0)),n.fillStyle=t,n.beginPath(),n.moveTo(f(0),b.top+w);for(let t=0;t<N;t++)n.lineTo(f(t),j(e[t].pricing??0));n.lineTo(f(N-1),b.top+w),n.closePath(),n.fill()}if(N>1){n.strokeStyle=l(r,.85),n.lineWidth=2,n.setLineDash([]),n.beginPath();for(let t=0;t<N;t++){let r=f(t),i=j(e[t].pricing??0);t===0?n.moveTo(r,i):n.lineTo(r,i)}n.stroke()}for(let r=0;r<N;r++){let s=f(r),c=j(e[r].pricing??0),d=`sc-${r}`,m=u.current.get(d)??0,h=r===e.length-1;y(x.current,d,s,c,12,{label:e[r].vendor,value:String(e[r].pricing??0),color:h?i.red:o}),m>0&&p(n,s,c,16*m,o,.2*m);let g=h?T(t,.05,5e-4):0,_=a===`area`?5:6;h?(n.shadowColor=l(i.red,.5),n.shadowBlur=(8+g*4)*(1+m*.5),n.fillStyle=i.red,n.beginPath(),n.arc(s,c,(_+g*1.5)*(1+m*.3),0,Math.PI*2),n.fill(),n.shadowBlur=0):(n.fillStyle=l(o,.7+m*.3),n.beginPath(),n.arc(s,c,_+m*2,0,Math.PI*2),n.fill()),n.font=`10px 'JetBrains Mono', monospace`,n.fillStyle=l(i.t3,.6+m*.3),n.textAlign=`center`,n.fillText(e[r].vendor,s,k-14)}E=requestAnimationFrame(A)};return A(),()=>cancelAnimationFrame(E)},[e,a,s]),(0,n.jsx)(r,{className:o,children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:O,height:k},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`${a} chart`,style:{width:O,height:k,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...b,parentW:O,parentH:k})]})})}function j({rows:e=[],className:t,colors:r}){return(0,n.jsx)(A,{rows:e,variant:`area`,className:t,colors:r})}var M=760,N=280;function ee({rows:e=[],className:o,colors:s}){let c=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),{hoveredRef:m,tooltip:h,hitZonesRef:g}=v(c,{width:M,height:N});return(0,t.useEffect)(()=>{let t=c.current;if(!t)return;let n=f(t,M,N);d.current=0;let r=s?.bars??a,o=s?.axisLine??i.bd,h=s?.valueLabel??i.t2,_={top:24,right:24,bottom:56,left:24},v=N-_.top-_.bottom,y=(M-_.left-_.right)/Math.max(e.length,1),x=Math.max(100,...e.map(e=>e.pricing??0)),C=_.top+v,w,T=()=>{d.current++;let t=d.current;n.clearRect(0,0,M,N);let a=S(Math.min(t/48,1));D(u.current,m.current),g.current=[],n.strokeStyle=l(o,.4),n.lineWidth=1,n.setLineDash([]),n.beginPath(),n.moveTo(_.left,C),n.lineTo(M-_.right,C),n.stroke(),e.forEach((t,o)=>{let s=_.left+o*y,c=E(a,o,e.length,S),d=x>0?(t.pricing??0)/x*v:0,f=Math.max(d>0?4:0,d*c),m=r[o%r.length],w=u.current.get(t.id??`bar-${o}`)??0;b(g.current,t.id??`bar-${o}`,s+4,C-f,y-8,f,{label:t.vendor,value:String(t.pricing??0),color:m}),f>0&&(w>0&&p(n,s+y/2,C-f/2,y*.8,m,.12*w),n.shadowColor=l(m,.2*(w>0?w:0)),n.shadowBlur=w>0?6:0,n.fillStyle=l(m,.5+w*.25),n.beginPath(),n.roundRect(s+4,C-f,y-8,f,[4,4,0,0]),n.fill(),n.shadowBlur=0,w>0&&(n.strokeStyle=l(m,.4*w),n.lineWidth=1,n.beginPath(),n.roundRect(s+4,C-f,y-8,f,[4,4,0,0]),n.stroke())),c>.5&&f>0&&(n.globalAlpha=Math.min(1,(c-.5)*2),n.font=`bold 10px 'JetBrains Mono', monospace`,n.fillStyle=w>0?m:l(h,.7),n.textAlign=`center`,n.fillText(String(t.pricing??``),s+y/2,C-f-6),n.globalAlpha=1),n.font=`${w>0?`bold `:``}9px 'JetBrains Mono', monospace`,n.fillStyle=w>0?m:l(i.t3,.6),n.textAlign=`center`,n.fillText(t.vendor,s+y/2,N-14)}),w=requestAnimationFrame(T)};return T(),()=>cancelAnimationFrame(w)},[e,s]),(0,n.jsx)(r,{className:o,children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:M,height:N},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`bar chart`,style:{width:M,height:N,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...h,parentW:M,parentH:N})]})})}function P({width:e,height:t,message:r=`No data available`,"data-testid":i}){return(0,n.jsx)(`div`,{"data-testid":i,style:{width:e,height:t,display:`flex`,alignItems:`center`,justifyContent:`center`,borderRadius:8,background:`rgba(255,255,255,0.03)`,color:`rgba(255,255,255,0.35)`,fontSize:14,fontFamily:`'Satoshi Variable', 'DM Sans', sans-serif`},children:r})}function te({expanded:e,onToggle:t,labelExpanded:r=`View Less`,labelCollapsed:i=`View More`,"data-testid":a}){return(0,n.jsxs)(`button`,{type:`button`,"data-testid":a,onClick:t,style:{display:`flex`,width:90,height:20,justifyContent:`center`,alignItems:`center`,gap:4,boxSizing:`border-box`,border:`none`,borderRadius:6,color:`#71B941`,fontSize:14,fontFamily:`'Satoshi Variable', 'DM Sans', sans-serif`,fontStyle:`normal`,fontWeight:400,lineHeight:`19.5px`,textAlign:`center`,cursor:`pointer`,userSelect:`none`},children:[e?r:i,(0,n.jsx)(`svg`,{width:`10`,height:`10`,viewBox:`0 0 10 10`,fill:`none`,style:{transform:e?`rotate(180deg)`:`rotate(0deg)`},children:(0,n.jsx)(`path`,{d:`M2 3.5L5 6.5L8 3.5`,stroke:`currentColor`,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]})}var F=680,I=42,ne=10,re=24,ie=24,ae=8,oe=[i.green,i.blue,i.amber,i.red];function se({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),c=(0,t.useRef)(0),u=(0,t.useRef)(new Map),[d,g]=(0,t.useState)(!1),b=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),S=(0,t.useMemo)(()=>[...b].sort((e,t)=>(t.percentage??0)-(e.percentage??0)),[b]),C=(0,t.useMemo)(()=>d?S:S.slice(0,ae),[S,d]),w=C.length,T=re+ie+w*I+Math.max(0,w-1)*ne,{hoveredRef:E,tooltip:D,hitZonesRef:O}=v(a,{width:F,height:T});return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,F,T);c.current=0;let n=F*.13,r=F*.08,d=F-n-r,g,_=()=>{c.current++;let e=c.current;t.clearRect(0,0,F,T),t.letterSpacing=o.letterSpacing,O.current=[],u.current.forEach((e,t)=>{let n=t===E.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?u.current.delete(t):u.current.set(t,1):u.current.set(t,r)}),E.current&&!u.current.has(E.current)&&u.current.set(E.current,0),m(t,F,T,e,40,l(i.blue,.04)),C.forEach((r,i)=>{let a=oe[i%oe.length],c=u.current.get(r.id)??0,f=re+i*(I+ne);t.fillStyle=l(a,.04+c*.04),t.beginPath(),t.roundRect(n,f,d,I,3),t.fill(),t.strokeStyle=l(a,.08),t.lineWidth=1,t.setLineDash([4,4]),t.beginPath(),t.moveTo(n,f+I/2),t.lineTo(n+d,f+I/2),t.stroke(),t.setLineDash([]);let m=(r.percentage??0)/100,h=n+d*Math.min(m,m*x(Math.min(1,e*.005)));if(h>n+4){let e=t.createLinearGradient(n,0,h,0);e.addColorStop(0,l(a,.02)),e.addColorStop(1,l(a,.25+c*.15)),t.fillStyle=e,t.beginPath(),t.roundRect(n,f+2,h-n,I-4,2),t.fill()}p(t,h,f+I/2,18+c*8,a,.3+c*.2),t.beginPath(),t.arc(h,f+I/2,5+c*2,0,Math.PI*2),t.fillStyle=l(a,.9),t.fill();let g={label:r.name,value:`${r.percentage??0}% commitment`,sublabel:`Base: ${r.baseLabel??String(r.base??0)} · Variations: ${r.variationLabel??String(r.variation??0)}`,color:a};y(O.current,r.id,h,f+I/2,14,g),t.font=s.font,t.fillStyle=l(a,.9+c*.1),t.textAlign=`left`,t.textBaseline=`middle`,t.fillText(`${r.percentage??0}%`,h+10,f+I/2),t.font=`${c>0?`bold `:``}`+o.font,t.fillStyle=c>0?a:o.color,t.textAlign=`right`,t.fillText(r.abbreviation??r.name?.slice(0,6)??``,n-8,f+I/2)}),t.strokeStyle=l(i.t3,.3),t.lineWidth=1,t.setLineDash([]),t.beginPath(),t.moveTo(n+d,re),t.lineTo(n+d,re+(w-1)*(I+ne)+I),t.stroke(),h(t,F,T,e,.015),g=requestAnimationFrame(_)};return _(),()=>cancelAnimationFrame(g)},[C,T]),S.length===0?(0,n.jsx)(P,{width:F,height:160,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{width:F},children:[(0,n.jsxs)(`div`,{style:{position:`relative`},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Commitment race — contractors ranked by commitment percentage`,style:{width:F,height:T,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...D,parentW:F,parentH:T})]}),b.length>ae&&(0,n.jsx)(`div`,{style:{marginTop:8},children:(0,n.jsx)(te,{expanded:d,onToggle:()=>g(e=>!e)})})]})}var ce=480,le=340;function ue({value:e,confirmed:r,total:a,"data-testid":s}){let u=(0,t.useRef)(null),d=(0,t.useRef)(0);return(0,t.useEffect)(()=>{let t=u.current;if(!t)return;let n=f(t,ce,le);d.current=0;let s=ce/2,m=Math.PI,h=2*Math.PI,g=Math.PI,_,v=()=>{d.current++;let t=d.current;n.clearRect(0,0,ce,le),n.letterSpacing=o.letterSpacing;let u=x(Math.min(t/80,1)),f=w(Math.min(t/72,1));n.beginPath(),n.arc(s,220,120,m,h),n.strokeStyle=l(i.bd,.35),n.lineWidth=46,n.stroke(),[{start:0,end:.33,color:i.red},{start:.33,end:.66,color:i.amber},{start:.66,end:1,color:i.green}].forEach(e=>{let t=m+e.start*g,r=m+e.end*g;n.beginPath(),n.arc(s,220,194/2,t,r),n.strokeStyle=l(e.color,.12),n.lineWidth=42,n.stroke()}),[{label:`Low`,angle:m+.16*g},{label:`Mid`,angle:m+.5*g},{label:`High`,angle:m+.84*g}].forEach(({label:e,angle:t})=>{let r=s+Math.cos(t)*166,i=220+Math.sin(t)*166;n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(e,r,i+3)});let y=e??0,b=m+y/100*g*u,S=y>=66?i.green:y>=33?i.amber:i.red;p(n,s+Math.cos(b)*194/2,220+Math.sin(b)*194/2,18,S,.35*u),n.beginPath(),n.arc(s,220,194/2,m,b),n.strokeStyle=l(S,.7*u),n.lineWidth=38,n.lineCap=`round`,n.stroke(),n.lineCap=`butt`;let C=m+y/100*g*f,T=s+Math.cos(C)*82,E=220+Math.sin(C)*82,D=s-Math.cos(C)*14,O=220-Math.sin(C)*14;n.strokeStyle=l(S,.18*f),n.lineWidth=6,n.lineCap=`round`,n.beginPath(),n.moveTo(D,O),n.lineTo(T,E),n.stroke(),n.strokeStyle=l(i.t1,.92*f),n.lineWidth=2,n.lineCap=`round`,n.beginPath(),n.moveTo(D,O),n.lineTo(T,E),n.stroke(),n.beginPath(),n.arc(T,E,3,0,Math.PI*2),n.fillStyle=l(S,.9*f),n.fill(),p(n,s,220,20,S,.25*f),n.beginPath(),n.arc(s,220,9,0,Math.PI*2),n.strokeStyle=l(S,.5*f),n.lineWidth=1.5,n.stroke(),n.beginPath(),n.arc(s,220,5,0,Math.PI*2),n.fillStyle=i.t1,n.fill(),u>.5&&(n.globalAlpha=Math.min(1,(u-.5)/.5),n.font=`500 24px 'Satoshi Variable', 'DM Sans', sans-serif`,n.fillStyle=S,n.textAlign=`center`,n.fillText(`${Math.round(y*f)}%`,s,182),n.globalAlpha=1),u>.7&&(n.globalAlpha=Math.min(1,(u-.7)/.3),n.font=c.font,n.fillStyle=c.color,n.textAlign=`center`,n.fillText(`NCEs confirmed`,s,252),n.font=c.font,n.fillStyle=c.color,n.fillText(`${r??0} of ${a??0} NCEs are confirmed compensation events`,s,272),n.globalAlpha=1);for(let e=0;e<=10;e++){let t=m+e/10*g;if(n.strokeStyle=l(i.bd,.5),n.lineWidth=e%5==0?1.5:.8,n.beginPath(),n.moveTo(s+Math.cos(t)*122,220+Math.sin(t)*122),n.lineTo(s+Math.cos(t)*128,220+Math.sin(t)*128),n.stroke(),e%5==0){let r=s+Math.cos(t)*138,i=220+Math.sin(t)*138;n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(`${e*10}%`,r,i+3)}}_=requestAnimationFrame(v)};return v(),()=>cancelAnimationFrame(_)},[e,r,a]),(0,n.jsx)(`div`,{"data-testid":s,style:{position:`relative`,width:ce,height:le},children:(0,n.jsx)(`canvas`,{ref:u,role:`img`,"aria-label":`Compensation event gauge — ${e}% of NCEs confirmed as compensation events`,style:{width:ce,height:le,display:`block`}})})}function de(e,n,r,i,a=!0,o={}){let s=(0,t.useRef)(0),{easing:c=x,durationFrames:l=48}=o;(0,t.useEffect)(()=>{let t=e.current;if(!t||!n||!r)return;let o=t.getContext(`2d`);if(!o)return;t.width=n*2,t.height=r*2,o.scale(2,2);let u;s.current=0;let d=()=>{s.current++;let e=s.current;o.clearRect(0,0,n,r);let t=a?Math.min(e/l,1):1;if(i(o,c(t),e),t<1)u=requestAnimationFrame(d);else{let e=()=>{s.current++,o.clearRect(0,0,n,r),i(o,1,s.current),u=requestAnimationFrame(e)};u=requestAnimationFrame(e)}};return d(),()=>cancelAnimationFrame(u)},[n,r,a])}var L=780,fe=234,pe=130,me=52,he=[i.blue,i.amber,i.purple,i.green],ge=[`Base Value`,`Variations`,`Commitment`],_e=[`Base`,`Var`,`Commit`];function ve({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(new Map),{hoveredRef:u,tooltip:d,hitZonesRef:f}=v(a,{width:L,height:fe}),g=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),b=(0,t.useMemo)(()=>{let e=Math.max(...g.map(e=>e.base??0)),t=Math.max(...g.map(e=>e.variation??0));return g.map((n,r)=>{let i=L*(.12+r*.19),a=pe,o=Math.min(L*.075,me),s=he[r%he.length],c=[(n.base??0)/(e||1)*100,(n.variation??0)/(t||1)*100,n.percentage??0],l=[n.baseLabel??String(n.base??0),n.variationLabel??String(n.variation??0),`${n.percentage??0}%`],u=c.map((e,t)=>{let n=-Math.PI/2+t/ge.length*Math.PI*2,r=e/100,s=o*Math.max(.08,r);return{name:ge[t],short:_e[t],label:l[t],val:Math.round(e),x:i+Math.cos(n)*s,y:a+Math.sin(n)*s,angle:n,norm:r}}),d=u.reduce((e,t)=>e+t.x,0)/u.length,f=u.reduce((e,t)=>e+t.y,0)/u.length,p=Math.sqrt(u.reduce((e,t)=>e+(t.x-d)**2+(t.y-f)**2,0)/u.length);return{...n,cx:i,cy:a,baseR:o,stars:u,scatter:p,color:s}})},[g]);return de(a,L,fe,(e,t,n)=>{D(s.current,u.current),f.current=[],m(e,L,fe,n,30),b.forEach((t,r)=>{let a=t.color,c=`constellation-${r}`,u=s.current.get(c)??0;e.beginPath(),e.arc(t.cx,t.cy,t.baseR+5,0,Math.PI*2),e.strokeStyle=l(i.bd,.08+.08*u),e.lineWidth=.5,e.stroke(),e.beginPath(),t.stars.forEach((t,n)=>{n===0?e.moveTo(t.x,t.y):e.lineTo(t.x,t.y)}),e.closePath(),e.fillStyle=l(a,.04+.03*u),e.fill(),e.strokeStyle=l(a,.15+.1*u),e.lineWidth=.8,e.stroke(),t.stars.forEach((i,c)=>{let u=T(n,.05,5e-4)*.3+.7,d=3.5*u,p=`star-${r}-${c}`,m=s.current.get(p)??0,h=e.createRadialGradient(i.x,i.y,0,i.x,i.y,d*4);h.addColorStop(0,l(a,(.2+.1*m)*u)),h.addColorStop(1,l(a,0)),e.fillStyle=h,e.beginPath(),e.arc(i.x,i.y,d*4,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(i.x,i.y,d+m*2,0,Math.PI*2),e.fillStyle=l(a,(.8+.2*m)*u),e.fill();let g=Math.sin(i.angle)<-.3;e.textAlign=`center`,e.textBaseline=`middle`,g?(e.font=o.font,e.fillStyle=l(a,.5+.15*m),e.fillText(i.short,i.x,i.y-24),e.font=o.font,e.fillStyle=l(a,.8+.15*m),e.fillText(i.label,i.x,i.y-11)):(e.font=o.font,e.fillStyle=l(a,.5+.15*m),e.fillText(i.short,i.x,i.y+11),e.font=o.font,e.fillStyle=l(a,.8+.15*m),e.fillText(i.label,i.x,i.y+24)),y(f.current,p,i.x,i.y,d*4+2,{label:i.name,value:i.label,sublabel:t.abbreviation??t.name.slice(0,6),color:a})}),u>0&&p(e,t.cx,t.cy,16*u,a,.15*u),e.beginPath(),e.arc(t.cx,t.cy,t.baseR+12,0,Math.PI*2),e.strokeStyle=l(a,.1+T(n,.03,5e-4)*.05),e.lineWidth=1,e.stroke(),e.font=o.font,e.textAlign=`center`,e.textBaseline=`alphabetic`,e.fillStyle=u>0?t.color:o.color,e.fillText(t.abbreviation??t.name.slice(0,6),t.cx,t.cy+t.baseR+26),y(f.current,c,t.cx,t.cy,t.baseR+5,{label:t.name,value:`${t.totalLabel??String(t.total??0)} total`,sublabel:`${t.percentage??0}% committed · scatter ${t.scatter.toFixed(1)}`,color:a})}),e.font=c.font,e.textAlign=`center`,e.textBaseline=`middle`,e.fillStyle=c.color,e.fillText(`▲ top = Base value · ▼▸ lower-right = Variations · ◂▼ lower-left = Commitment % · hover stars for details`,L/2,fe-14),h(e,L,fe,n,.012)},!0),b.length===0?(0,n.jsx)(P,{width:L,height:fe,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:L,height:fe},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Contract value breakdown per contractor — multi-KPI constellation chart`,style:{width:L,height:fe,display:`block`}}),(0,n.jsx)(_,{...d,parentW:L,parentH:fe})]})}var ye=680,be=220,xe=8,Se=[i.blue,i.amber,i.purple,i.green],R={left:8,right:80,top:16,bottom:38},Ce=150,z=18;function we(e,t,n){if(e.measureText(t).width<=n)return t;let r=t;for(;r.length>0&&e.measureText(r+`…`).width>n;)r=r.slice(0,-1);return r+`…`}function Te(e){let t=Math.abs(e),n=e<0?`-`:``;return t>=1e6?`${n}£${(t/1e6).toFixed(1)}M`:t>=1e3?`${n}£${(t/1e3).toFixed(1)}K`:`${n}£${t.toFixed(0)}`}function Ee({data:e,"data-testid":r}){let a=(0,t.useRef)(null),u=(0,t.useRef)(new Map),[d,f]=(0,t.useState)(!1),{items:m=[],totals:h}=e,g=m.filter(e=>typeof e==`object`&&!!e),y=[...g].sort((e,t)=>(t.total??0)-(e.total??0)),x=d?y:y.slice(0,xe),C=x.length,w=Math.max(...y.map(e=>Math.abs(e.total??0)),1),T=Math.max(be,R.top+R.bottom+C*z+Math.max(0,C-1)*8),O=ye-R.left-Ce-R.right,k=C>1?(T-R.top-R.bottom-C*z)/(C-1):0,A=g.length===0,{hoveredRef:j,tooltip:M,hitZonesRef:N}=v(a,{width:ye,height:T});return de(a,ye,T,(e,t)=>{D(u.current,j.current),N.current=[],x.forEach((n,r)=>{let a=Se[r%Se.length],c=E(t,r,C,S),d=R.top+r*(z+k),f=R.left+Ce,m=u.current.get(n.id)??0,h=Math.max(n.base??0,0),g=Math.max(n.total??0,0),_=h/w*O*c,v=g/w*O*c,y=v-_;e.font=o.font,e.fillStyle=m>0?a:o.color,e.textAlign=`right`,e.textBaseline=`middle`,e.fillText(we(e,n.name??``,Ce-16),f-8,d+z/2),e.fillStyle=l(i.bd,.25),e.beginPath(),e.roundRect(f,d,O,z,4),e.fill(),_>0&&(m>0&&p(e,f+_/2,d+z/2,_*.3,a,.1*m),e.fillStyle=l(a,.5+m*.15),e.beginPath(),e.roundRect(f,d,_,z,4),e.fill()),y>2&&(e.fillStyle=l(a,.22+m*.08),e.beginPath(),e.roundRect(f+_,d,y,z,[0,4,4,0]),e.fill(),e.setLineDash([2,3]),e.strokeStyle=l(a,.55),e.lineWidth=1,e.beginPath(),e.moveTo(f+_,d+3),e.lineTo(f+_,d+z-3),e.stroke(),e.setLineDash([])),m>0&&v>0&&(e.strokeStyle=l(a,.5*m),e.lineWidth=1,e.setLineDash([]),e.beginPath(),e.roundRect(f,d,v,z,4),e.stroke()),c>.35&&(e.globalAlpha=Math.min(1,(c-.35)/.4),e.font=s.font,e.fillStyle=m>0?a:s.color,e.textAlign=`left`,e.textBaseline=`middle`,e.fillText(n.totalLabel??Te(n.total??0),f+v+6,d+z/2),e.globalAlpha=1),b(N.current,n.id,f,d,Math.max(v,1),z,{label:n.name,value:`${n.totalLabel??Te(n.total??0)} total`,sublabel:`Base ${n.baseLabel??Te(n.base??0)} + Var ${n.variationLabel??Te(n.variation??0)} · ${n.percentage??0}% committed`,color:a})});let n=T-14;e.textBaseline=`middle`,e.font=c.font,e.textAlign=`left`,e.fillStyle=l(i.blue,.5),e.beginPath(),e.roundRect(R.left+Ce,n-3,14,6,2),e.fill(),e.fillStyle=c.color,e.fillText(`base value`,R.left+Ce+18,n),e.fillStyle=l(i.blue,.22),e.beginPath(),e.roundRect(R.left+Ce+94,n-3,14,6,2),e.fill(),e.setLineDash([2,3]),e.strokeStyle=l(i.blue,.5),e.lineWidth=.5,e.beginPath(),e.moveTo(R.left+Ce+101,n-3),e.lineTo(R.left+Ce+101,n+3),e.stroke(),e.setLineDash([]),e.fillStyle=c.color,e.fillText(`approved variations`,R.left+Ce+112,n),e.font=c.font,e.textAlign=`right`,e.fillStyle=c.color,e.fillText(`Portfolio: ${Te(h?.total??0)}`,ye-8,n)},!0,{easing:S}),A?(0,n.jsx)(P,{width:ye,height:be,message:`No contract data available`,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{width:ye,transition:`all 0.25s ease`},children:[(0,n.jsxs)(`div`,{style:{position:`relative`},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Total contract value per contractor — horizontal bar chart`,style:{width:ye,height:T,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...M,parentW:ye,parentH:T})]}),g.length>xe&&(0,n.jsx)(`div`,{style:{marginTop:8},children:(0,n.jsx)(te,{expanded:d,onToggle:()=>f(e=>!e)})})]})}var B=780,V=240,De=12,Oe=10,ke=[`Highest exposure`,`Elevated risk`,`Moderate exposure`,`Moderate exposure`,`Low exposure`];function Ae({items:e=[],"data-testid":r}){let c=(0,t.useRef)(null),u=(0,t.useRef)(0),d=(0,t.useRef)(new Map),{hoveredRef:m,tooltip:g,hitZonesRef:y}=v(c,{width:B,height:V}),x=[...(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e])].sort((e,t)=>(t.count??0)-(e.count??0)).slice(0,5),S=x.reduce((e,t)=>e+(t.count??0),0);return(0,t.useEffect)(()=>{let e=c.current;if(!e)return;let t=f(e,B,V);u.current=0;let n=Math.min(5,x.length),r=(B-2*De-4*Oe)/5,g=V*.84,_=V*.08,v=n*r+(n-1)*Oe,C=Math.round((B-v)/2),w,E=()=>{u.current++;let e=u.current;t.clearRect(0,0,B,V),t.letterSpacing=o.letterSpacing,y.current=[],d.current.forEach((e,t)=>{let n=t===m.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?d.current.delete(t):d.current.set(t,1):d.current.set(t,r)}),m.current&&!d.current.has(m.current)&&d.current.set(m.current,0),x.forEach((n,c)=>{let u=c===0,f=c===0?i.red:c===1?i.amber:a[c%a.length],m=C+c*(r+Oe),h=d.current.get(n.id)??0,v=h*8,x=m-v/2,w=r+v,E=u?T(e,.04,3e-4)*.06+.06:0;t.fillStyle=l(f,.08+h*.07),t.beginPath(),t.roundRect(x,_,w,g,6),t.fill(),t.strokeStyle=l(f,.2+h*.4+E),t.lineWidth=u?1.5:1,t.stroke(),(h>.01||u)&&p(t,x+w/2,_+g/2,w*.55,f,E+h*.14),t.font=s.font,t.textAlign=`left`,t.textBaseline=`top`,t.fillStyle=l(f,.5+h*.35),t.fillText(`#${c+1}`,x+7,_+6);let D=Math.min(r*.28,g*.32,72),O=x+w/2,k=_+g*.38,A=t.createRadialGradient(O,k-D*.2,0,O,k,D);A.addColorStop(0,l(f,.5+h*.2)),A.addColorStop(1,l(f,.2+h*.1)),t.beginPath(),t.arc(O,k,D,0,Math.PI*2),t.fillStyle=A,t.fill(),t.strokeStyle=l(f,.4+h*.3),t.lineWidth=1,t.stroke(),t.font=s.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(i.t1,.9),t.fillText(n.abbreviation??n.name?.slice(0,6)??``,O,k);let j=n.label??String(n.count??0);t.font=s.font,t.textBaseline=`alphabetic`,t.fillStyle=l(f,.9+h*.1),t.fillText(j,O,_+g*.76),n.label||(t.font=o.font,t.fillStyle=o.color,t.fillText(`open EWs`,O,_+g*.88));let M=Math.round((n.count??0)/(S||1)*100),N=ke[c]??`Low exposure`;b(y.current,n.id,m,_,r,g,{label:n.name,value:`${j??0} open · ${M}% of total`,sublabel:`Rank #${c+1} · ${N}`,color:f})}),h(t,B,V,e,.015),w=requestAnimationFrame(E)};return E(),()=>cancelAnimationFrame(w)},[x,S]),x.length===0?(0,n.jsx)(P,{width:B,height:V,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:B,height:V},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`Contractor rank — open EW count per contractor`,style:{width:B,height:V,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...g,parentW:B,parentH:V})]})}var H=680,U=260;function je({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(0),c=(0,t.useRef)(new Map),{hoveredRef:u,tooltip:d,hitZonesRef:g}=v(a,{width:H,height:U}),b=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,H,U);s.current=0;let n=b.length,r=Math.max(...b.map(e=>e.count),1),d=r,_=H*.05,v=U*.1,x=H*.9/n,S=U*.7/d,C=b.reduce((e,t)=>e+t.count,0),w,E=()=>{s.current++;let e=s.current;t.clearRect(0,0,H,U),g.current=[],c.current.forEach((e,t)=>{let n=t===u.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?c.current.delete(t):c.current.set(t,1):c.current.set(t,r)}),u.current&&!c.current.has(u.current)&&c.current.set(u.current,0),m(t,H,U,e,40,l(i.blue,.04)),b.forEach((n,a)=>{let s=n.count===r,u=i.blue,f=c.current.get(`${n.category}-col`)??0;for(let i=0;i<d;i++){let o=_+a*x+x/2,d=v+i*S+S/2,m=Math.min(x,S)*.38;if(i>=r-n.count){let r=m*(1+(T(e,.04,5e-4)+Math.sin(a*.6+i*1.2)*.3)*.12);(s||f>.01)&&p(t,o,d,r*3,u,(s?.2:.1)+f*.1),t.beginPath(),t.arc(o,d,r,0,Math.PI*2),t.fillStyle=l(u,s?.8:.5+f*.2),t.fill();let h=`${n.category}-${i}`;y(g.current,h,o,d,m+4,{label:n.fullName,value:`${n.count} Early Warnings`,sublabel:`${Math.round(n.count/C*100)}% of total`,color:u}),c.current.get(`${n.category}-col`)}else t.beginPath(),t.arc(o,d,1,0,Math.PI*2),t.fillStyle=l(u,.08),t.fill()}let m=v+d*S+16;t.font=o.font,t.textAlign=`center`,t.textBaseline=`alphabetic`,t.fillStyle=s?i.blue:l(i.t2,.65),t.fillText(n.category,_+a*x+x/2,m)}),h(t,H,U,e,.015),w=requestAnimationFrame(E)};return E(),()=>cancelAnimationFrame(w)},[b]),b.length===0?(0,n.jsx)(P,{width:H,height:U,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:H,height:U},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Early Warning count by category — breathing dot grid`,style:{width:H,height:U,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...d,parentW:H,parentH:U})]})}function Me({rows:e=[],className:t,colors:r}){return(0,n.jsx)(A,{rows:e,variant:`line`,className:t,colors:r})}var Ne=[`#4C93D9`,`#5DA537`,`#F3862C`,`#4F72C6`,`#A0B724`,`#EEBF3B`,`#3C45D1`],Pe={nodes:[{id:`supplier-x`,name:`Supplier X`,valueLabel:`Si +0.12%`},{id:`bf3-superheat`,name:`BF-3 Superheat`,valueLabel:`22°C (target 34)`},{id:`ccm3-solidification`,name:`CCM-3 Solidification`,valueLabel:`Rate deviation`},{id:`grade-risk`,name:`Grade Risk`,valueLabel:`Automotive 74%`}],links:[{source:`supplier-x`,target:`bf3-superheat`,value:92},{source:`bf3-superheat`,target:`ccm3-solidification`,value:87},{source:`ccm3-solidification`,target:`grade-risk`,value:74}]};function Fe({rows:e=[],className:t,colors:r}){let i=r?.slices??Ne;return(0,n.jsx)(`div`,{className:[`d3-mini-bars`,t].filter(Boolean).join(` `),children:e.map(([e,t,r],a)=>(0,n.jsxs)(`div`,{className:`d3-mini-row`,children:[(0,n.jsx)(`span`,{children:e}),(0,n.jsx)(`div`,{className:`d3-mini-track`,children:(0,n.jsxs)(`svg`,{viewBox:`0 0 100 12`,className:`d3-mini-svg`,"aria-hidden":`true`,children:[(0,n.jsx)(`rect`,{x:`0`,y:`0`,width:`100`,height:`12`,rx:`6`,className:`d3-mini-track-fill`}),(0,n.jsx)(`rect`,{x:`0`,y:`0`,width:Math.max(0,Math.min(100,t)),height:`12`,rx:`6`,className:`d3-mini-fill tone-${a%Ne.length}`,fill:i[a%i.length]})]})}),(0,n.jsx)(`span`,{children:r})]},`${e}-${a}`))})}var Ie=680,Le=320,Re=60,ze=28;function Be({total:e=0,totalLabel:r,items:c=[],"data-testid":u}){let d=(0,t.useRef)(null),m=(0,t.useRef)(new Map),h=(0,t.useRef)(0),g=(0,t.useMemo)(()=>c.filter(e=>typeof e==`object`&&!!e),[c]),b=(0,t.useMemo)(()=>Math.max(Le,Re+Math.max(0,g.length-1)*ze),[g.length]),{hoveredRef:S,tooltip:C,hitZonesRef:w}=v(d,{width:Ie,height:b});return(0,t.useEffect)(()=>{let t=d.current;if(!t)return;let n=f(t,Ie,b);h.current=0;let c=b/2,u=Ie-80,_=Math.max(...g.map(e=>e.count??0),1),v=g.length>1?(b-60)/(g.length-1):0,C=g.map((e,t)=>({x:u,y:30+t*v})),T,O=()=>{h.current++;let t=h.current;n.clearRect(0,0,Ie,b),n.letterSpacing=o.letterSpacing;let d=x(Math.min(t/72,1));D(m.current,S.current),w.current=[],p(n,88,c,48*d,i.blue,.15*d),g.forEach((t,r)=>{let f=a[r%a.length],h=E(d,r,g.length,x),v=C[r],b=m.current.get(t.id)??0,S=Math.max(1.5,(t.count??0)/_*6);if(h<.01)return;let T=88+(u-88)*.4,D=c,O=88+(u-88)*.6,k=v.y,A=h;n.beginPath();for(let e=0;e<=40;e++){let t=e/40*A,r=(1-t)**3*88+3*(1-t)**2*t*T+3*(1-t)*t**2*O+t**3*v.x,i=(1-t)**3*c+3*(1-t)**2*t*D+3*(1-t)*t**2*k+t**3*v.y;e===0?n.moveTo(r,i):n.lineTo(r,i)}if(n.strokeStyle=l(f,b>0?.8:.45),n.lineWidth=S*(b>0?1.3:1),n.stroke(),h>.85){let r=Math.min(1,(h-.85)/.15),a=4+(t.count??0)/_*12;p(n,v.x,v.y,a*2.5,f,(.25+b*.2)*r),n.beginPath(),n.arc(v.x,v.y,a*r,0,Math.PI*2),n.fillStyle=l(f,(.7+b*.2)*r),n.fill();let c=t.label??String(t.count??0);y(w.current,t.id,v.x,v.y,a+8,{label:t.name,value:`${c} NCEs raised`,sublabel:`${Math.round((t.count??0)/(e||1)*100)}% of all NCEs`,color:f}),n.globalAlpha=r,n.font=o.font,n.textAlign=`left`;let u=t.abbreviation??t.name?.slice(0,6)??``,d=` ${c}`,m=v.x+a+6,g=v.y+4;n.fillStyle=b>0?f:l(i.t2,.85),n.fillText(u,m,g);let x=n.measureText(u).width;n.font=s.font,n.fillStyle=b>0?f:i.t1,n.fillText(d,m+x,g),n.globalAlpha=1}}),n.beginPath(),n.arc(88,c,32*d,0,Math.PI*2),n.fillStyle=i.bgL,n.fill(),n.strokeStyle=l(i.blue,.6*d),n.lineWidth=2,n.stroke(),d>.4&&(n.globalAlpha=Math.min(1,(d-.4)/.4),n.font=`500 24px 'Satoshi Variable', 'DM Sans', sans-serif`,n.fillStyle=i.t1,n.textAlign=`center`,n.fillText(r??String(e),88,c+5),n.font=o.font,n.fillStyle=o.color,n.fillText(`NCEs`,88,c+18),n.globalAlpha=1),T=requestAnimationFrame(O)};return O(),()=>cancelAnimationFrame(T)},[e,r,g,b]),g.length===0?(0,n.jsx)(P,{width:Ie,height:Le,"data-testid":u}):(0,n.jsxs)(`div`,{"data-testid":u,style:{position:`relative`,width:Ie,height:b},children:[(0,n.jsx)(`canvas`,{ref:d,role:`img`,"aria-label":`NCE fault tree — NCEs per contractor as branching tree`,style:{width:Ie,height:b,display:`block`}}),(0,n.jsx)(_,{...C,parentW:Ie,parentH:b})]})}var Ve=192,He=Ve,Ue=Ve+80;function We({rows:e=[],variant:o,className:s,colors:c}){let u=(0,t.useRef)(null),m=(0,t.useRef)(new Map),h=(0,t.useRef)(0),g=c?.slices??a,{hoveredRef:b,tooltip:x,hitZonesRef:S}=v(u,{width:He,height:Ue});return(0,t.useEffect)(()=>{let t=u.current;if(!t)return;let n=f(t,He,Ue);h.current=0;let r=He/2,a=Ve/2,s=Ve*.4,c=o===`donut`?Ve*.21:0,_=e.reduce((e,t)=>e+(t.pricing??0),0)||1,v,x=()=>{h.current++;let t=h.current;n.clearRect(0,0,He,Ue);let u=1-(1-Math.min(t/48,1))**3;D(m.current,b.current),S.current=[];let f=-Math.PI/2;e.forEach((e,o)=>{let d=(e.pricing??0)/_,h=d*Math.PI*2*u,v=f+h,b=g[o%g.length],x=m.current.get(e.id??`sl-${o}`)??0,C=f+h/2,w=(s+c)/2,E=r+Math.cos(C)*w,D=a+Math.sin(C)*w,O=(s-c)/2+8;y(S.current,e.id??`sl-${o}`,E,D,O,{label:e.vendor,value:`${e.pricing??0} (${Math.round(d*100)}%)`,color:b}),x>0&&p(n,E,D,O*2*x,b,.2*x);let k=T(t,.03,3e-4),A=s+x*6+(x>0?k*2:0);n.beginPath(),n.moveTo(r+Math.cos(f)*c,a+Math.sin(f)*c),n.arc(r,a,A,f,v),c>0?n.arc(r,a,c,v,f,!0):n.lineTo(r,a),n.closePath(),n.fillStyle=l(b,.7+x*.2),n.fill(),n.strokeStyle=l(i.bg,.8),n.lineWidth=1.5,n.stroke(),f=v}),o===`donut`&&e.length>0&&p(n,r,a,c*.8,i.blue,.06);let C=Ve+12;e.forEach((e,t)=>{let r=g[t%g.length],a=(e.pricing??0)/_,o=m.current.get(e.id??`sl-${t}`)??0,s=C+t*18;n.beginPath(),n.arc(8,s,4,0,Math.PI*2),n.fillStyle=l(r,.8+o*.2),n.fill(),n.font=`9px 'JetBrains Mono', monospace`,n.fillStyle=l(i.t2,.7+o*.2),n.textAlign=`left`,n.fillText(e.vendor,18,s+3.5),n.font=`bold 9px 'JetBrains Mono', monospace`,n.fillStyle=d(i.t3,r,o),n.textAlign=`right`,n.fillText(`${e.pricing??0} (${Math.round(a*100)}%)`,He-4,s+3.5)}),v=requestAnimationFrame(x)};return x(),()=>cancelAnimationFrame(v)},[e,o,c,g]),(0,n.jsx)(r,{className:[`canvas-pie-frame`,s].filter(Boolean).join(` `),children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:He,height:Ue},children:[(0,n.jsx)(`canvas`,{ref:u,role:`img`,"aria-label":`${o} chart`,style:{width:He,height:Ue,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...x,parentW:He,parentH:Ue})]})})}function Ge(e,t,n,r){let i=new Set(t.map(e=>e.source)),a=new Set(t.map(e=>e.target)),o=new Map,s=[];for(e.forEach(e=>{i.has(e.id)&&!a.has(e.id)&&s.push({id:e.id,depth:0})});s.length>0;){let e=s.shift();if(!e)break;let{id:n,depth:r}=e;o.has(n)||(o.set(n,r),t.filter(e=>e.source===n).forEach(e=>{o.has(e.target)||s.push({id:e.target,depth:r+1})}))}let c=o.size>0?Math.max(...Array.from(o.values())):0;e.forEach(e=>{o.has(e.id)||o.set(e.id,c+1)});let l=new Map;e.forEach(e=>{let t=o.get(e.id)??0;l.has(t)||l.set(t,[]),l.get(t).push(e.id)});let u=Math.max(...Array.from(l.keys()))+1,d={left:100,right:80,top:40,bottom:40},f=new Map;return l.forEach((e,t)=>{let i=d.left+t/Math.max(u-1,1)*(n-d.left-d.right),a=r-d.top-d.bottom,o=Math.max(24,(a-(e.length-1)*12)/e.length),s=e.length*o+(e.length-1)*12,c=d.top+(a-s)/2;e.forEach((e,t)=>{f.set(e,{x:i-20/2,y:c+t*(o+12),w:20,h:o})})}),f}function Ke({nodes:e,links:o,width:s=960,height:c=280,ariaLabel:u,selectedEntity:d,className:m,colors:g}){let x=(0,t.useRef)(null),S=(0,t.useRef)(new Map),C=(0,t.useRef)(0),w=(0,t.useRef)([]),E=g?.nodes??a,O=g?.links??i.bd,k=g?.activeLinks??i.blue,A=g?.activeNodes??i.blue,j=(0,t.useMemo)(()=>Ge(e,o,s,c),[e,o,s,c]),{hoveredRef:M,tooltip:N,hitZonesRef:ee}=v(x,{width:s,height:c});return(0,t.useEffect)(()=>{let t=x.current;if(!t)return;let n=f(t,s,c);C.current=0,w.current=[];let r=o.length>0?Math.max(...o.map(e=>e.value)):1,a,u=()=>{C.current++;let t=C.current;n.clearRect(0,0,s,c);let f=1-(1-Math.min(t/56,1))**3;D(S.current,M.current),ee.current=[],o.forEach((e,a)=>{let o=j.get(e.source),s=j.get(e.target);if(!o||!s)return;let c=!!d&&(e.source===d||e.target===d),u=c?k:O,p=c?.5:.2,m=Math.max(3,e.value/r*36*f),h=m/2,g=o.x+o.w,_=o.y+o.h/2,v=s.x,b=s.y+s.h/2,x=(g+v)/2;for(let e=0;e<30;e++){let r=e/30,i=(e+1)/30,o=1-r,s=1-i,c=o*o*g+2*o*r*x+r*r*v,d=o*o*_+2*o*r*_+r*r*b,f=s*s*g+2*s*i*x+i*i*v,m=s*s*_+2*s*i*_+i*i*b,y=T(t+r*120+a*40,.025,3e-4)*1.2;n.beginPath(),n.moveTo(c,d-h+y),n.lineTo(f,m-h+y),n.lineTo(f,m+h+y),n.lineTo(c,d+h+y),n.closePath(),n.fillStyle=l(u,p*(.5+r*.5)),n.fill()}y(ee.current,`link-${a}`,x,(_+b)/2,m+6,{label:`${e.source} → ${e.target}`,value:String(e.value),color:c?k:i.blue}),Math.random()<.08&&w.current.push({linkIdx:a,prog:0,speed:.006+Math.random()*.006,off:(Math.random()-.5)*m*.5,sz:1+Math.random()})}),e.forEach((e,r)=>{let a=j.get(e.id);if(!a)return;let o=d===e.id,s=M.current===`node-${r}`,c=S.current.get(`node-${r}`)??0,u=o?A:E[r%E.length];b(ee.current,`node-${r}`,a.x,a.y,a.w,a.h,{label:e.name,value:e.valueLabel??e.id,color:u}),(c>0||o)&&p(n,a.x+a.w/2,a.y+a.h/2,a.w*2,u,.2*Math.max(c,o?.6:0));let f=o?T(t,.03,3e-4)*.15:0;n.fillStyle=l(u,.6+c*.25+f),n.beginPath(),n.roundRect(a.x,a.y,a.w,a.h,4),n.fill(),(o||c>0)&&(n.strokeStyle=l(u,.5*Math.max(c,o?1:0)),n.lineWidth=1,n.beginPath(),n.roundRect(a.x,a.y,a.w,a.h,4),n.stroke());let m=a.x+a.w+8;n.font=`${o||s?`bold `:``}10px 'JetBrains Mono', monospace`,n.fillStyle=l(o?u:i.t2,.7+c*.2),n.textAlign=`left`,n.fillText(e.name,m,a.y+a.h/2+4),e.valueLabel&&(n.font=`9px 'JetBrains Mono', monospace`,n.fillStyle=l(u,.5+c*.2),n.fillText(e.valueLabel,m,a.y+a.h/2+17))}),w.current=w.current.filter(e=>{if(e.prog+=e.speed,e.prog>1)return!1;let t=o[e.linkIdx];if(!t)return!1;let r=j.get(t.source),a=j.get(t.target);if(!r||!a)return!1;let s=r.x+r.w,c=r.y+r.h/2,u=a.x,d=a.y+a.h/2,f=(s+u)/2,p=1-e.prog,m=p*p*s+2*p*e.prog*f+e.prog*e.prog*u,h=p*p*c+2*p*e.prog*c+e.prog*e.prog*d+e.off,_=Math.sin(e.prog*Math.PI)*.5,v=g?.links??i.blue;return n.beginPath(),n.arc(m,h,e.sz,0,Math.PI*2),n.fillStyle=l(v,_),n.fill(),!0}),w.current.length>150&&(w.current=w.current.slice(-150)),h(n,s,c,t,.01),a=requestAnimationFrame(u)};return u(),()=>{cancelAnimationFrame(a),w.current=[]}},[e,o,s,c,d,g,j]),(0,n.jsx)(r,{className:[`canvas-sankey-frame`,m].filter(Boolean).join(` `),children:(0,n.jsxs)(`div`,{role:`img`,"aria-label":u,style:{position:`relative`,width:s,height:c},children:[(0,n.jsx)(`canvas`,{ref:x,style:{width:s,height:c,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...N,parentW:s,parentH:c})]})})}var qe=[{x:.13,y:.48},{x:.37,y:.28},{x:.63,y:.62},{x:.87,y:.38},{x:.25,y:.72},{x:.5,y:.18},{x:.75,y:.7},{x:.92,y:.22}],Je=[i.blue,i.orange,i.red,i.purple,i.green,i.amber,i.t2],Ye=[26,24,24,26,22,22,22,22];function Xe(e,t){let n=1-t;return{x:n*n*n*e.p0.x+3*n*n*t*e.p1.x+3*n*t*t*e.p2.x+t*t*t*e.p3.x,y:n*n*n*e.p0.y+3*n*n*t*e.p1.y+3*n*t*t*e.p2.y+t*t*t*e.p3.y}}function Ze(e,t){let n=1-t,r=3*n*n*(e.p1.x-e.p0.x)+6*n*t*(e.p2.x-e.p1.x)+3*t*t*(e.p3.x-e.p2.x),i=3*n*n*(e.p1.y-e.p0.y)+6*n*t*(e.p2.y-e.p1.y)+3*t*t*(e.p3.y-e.p2.y),a=Math.sqrt(r*r+i*i)||1;return{x:-i/a,y:r/a}}function Qe(e,t){let n=t.x-e.x,r=t.y-e.y;return{p0:{x:e.x,y:e.y},p1:{x:e.x+n*.3+r*.15,y:e.y+r*.3-n*.15},p2:{x:t.x-n*.3+r*.08,y:t.y-r*.3-n*.08},p3:{x:t.x,y:t.y}}}function $e({nodes:e,links:r,width:a=960,height:o=280,selectedEntity:s}){let c=(0,t.useRef)(null),u=(0,t.useRef)(0),g=(0,t.useRef)([]),{hoveredRef:b,tooltip:S,hitZonesRef:C}=v(c,{width:a,height:o}),w=(0,t.useMemo)(()=>{let t=new Map;return e.forEach((e,n)=>t.set(e.id,n)),t},[e]),E=(0,t.useMemo)(()=>r.length>0?Math.max(...r.map(e=>e.value)):100,[r]),D=e=>E>1?e/100:e,O=(0,t.useMemo)(()=>e.map((e,t)=>{let n=qe[t%qe.length];return{id:e.id,label:e.name,sub:e.valueLabel??``,x:n.x*a,y:n.y*o,r:Ye[t%Ye.length],color:Je[t%Je.length]}}),[e,a,o]),k=(0,t.useMemo)(()=>r.map(e=>({fromIdx:w.get(e.source)??-1,toIdx:w.get(e.target)??-1,conf:D(e.value)})).filter(e=>e.fromIdx>=0&&e.toIdx>=0),[r,w]);return(0,t.useEffect)(()=>{let e=c.current;if(!e)return;let t=f(e,a,o);u.current=0,g.current=[];let n,r=()=>{u.current++;let e=u.current;if(t.clearRect(0,0,a,o),C.current=[],m(t,a,o,e,50,l(i.blue,.05)),k.forEach((e,n)=>{let r=O[e.fromIdx],a=O[e.toIdx];if(!r||!a)return;let o=!!s&&(r.id===s||a.id===s),c=d(r.color,a.color,.5),u=o?.18:.05,f=o?.25:.1,p=Qe(r,a);t.beginPath(),t.moveTo(p.p0.x,p.p0.y),t.bezierCurveTo(p.p1.x,p.p1.y,p.p2.x,p.p2.y,p.p3.x,p.p3.y),t.strokeStyle=l(c,u),t.lineWidth=16,t.lineCap=`round`,t.stroke(),t.strokeStyle=l(c,f),t.lineWidth=1.5,t.stroke();for(let t=0;t<e.conf*2.5;t++)Math.random()<.45&&g.current.push({edgeIdx:n,t:0,speed:.003+Math.random()*.004,off:(Math.random()-.5)*13,sz:.7+Math.random()*2});let m=Xe(p,.5),h=`${Math.round(e.conf*100)}%`;t.font=`bold 12px 'JetBrains Mono', monospace`,t.textBaseline=`middle`;let _=t.measureText(h).width+14;t.fillStyle=`rgba(10,16,24,0.88)`,t.beginPath(),t.roundRect(m.x-_/2,m.y-11,_,22,6),t.fill(),t.strokeStyle=l(i.blue,.25),t.lineWidth=1,t.stroke(),t.fillStyle=l(i.blue,.9),t.textAlign=`center`,t.fillText(h,m.x,m.y)}),g.current=g.current.filter(e=>{if(e.t+=e.speed,e.t>1)return!1;let n=k[e.edgeIdx];if(!n)return!1;let r=O[n.fromIdx],i=O[n.toIdx];if(!r||!i)return!1;let a=Qe(r,i),o=Xe(a,e.t),s=Ze(a,e.t),c=o.x+s.x*e.off,u=o.y+s.y*e.off,f=Math.sin(e.t*Math.PI)*.7,m=d(r.color,i.color,e.t);return p(t,c,u,e.sz*3,m,f*.1),t.beginPath(),t.arc(c,u,e.sz,0,Math.PI*2),t.fillStyle=l(m,f),t.fill(),!0}),g.current.length>350&&(g.current=g.current.slice(-350)),O.forEach((n,r)=>{let a=s===n.id,o=b.current===`node-${r}`,c=T(e,.03,3e-4)*.1+1,u=n.r*c*(a?1.15:1);t.beginPath(),t.arc(n.x,n.y,u+6,0,Math.PI*2),t.strokeStyle=l(n.color,a?.3:.1),t.lineWidth=a?1.5:.7,t.stroke(),p(t,n.x,n.y,u*3,n.color,a?.22:.12);let d=t.createRadialGradient(n.x,n.y-u*.2,0,n.x,n.y,u);if(d.addColorStop(0,l(n.color,a?1:.85)),d.addColorStop(1,l(n.color,a?.65:.45)),t.fillStyle=d,t.beginPath(),t.arc(n.x,n.y,u,0,Math.PI*2),t.fill(),a||r===O.length-1){let r=u+16,i=e*.04,a=n.x+Math.cos(i)*r,o=n.y+Math.sin(i)*r;p(t,a,o,6,n.color,.3),t.beginPath(),t.arc(a,o,2,0,Math.PI*2),t.fillStyle=l(n.color,.75),t.fill()}y(C.current,`node-${r}`,n.x,n.y,u+8,{label:n.label,value:n.sub||n.id,color:n.color}),t.font=`${a||o?`bold `:``}12px 'DM Sans', sans-serif`,t.textAlign=`center`,t.textBaseline=`alphabetic`,t.fillStyle=l(n.color,a?1:.9),t.fillText(n.label,n.x,n.y+u+18),n.sub&&(t.font=`10px 'JetBrains Mono', monospace`,t.fillStyle=l(i.t3,.65),t.fillText(n.sub,n.x,n.y+u+32))}),k.length>=2){let n=k.reduce((e,t)=>e*t.conf,1),r=o*.92,s=a*.12,c=a*.76,u=x(Math.min(e*.008,1));t.fillStyle=l(i.bd,.35),t.beginPath(),t.roundRect(s,r,c,5,3),t.fill(),t.fillStyle=l(i.orange,.6),t.beginPath(),t.roundRect(s,r,c*n*u,5,3),t.fill(),t.font=`bold 12px 'JetBrains Mono', monospace`,t.textAlign=`left`,t.textBaseline=`middle`,t.fillStyle=l(i.orange,.85),t.fillText(`${Math.round(n*100)}% compound confidence`,s+c*n*u+10,r+2);let d=k.map(e=>e.conf.toFixed(2)).join(` × `);t.textAlign=`right`,t.font=`9px 'JetBrains Mono', monospace`,t.fillStyle=l(i.t4,.6),t.fillText(d,s-6,r+2)}h(t,a,o,e,.012),n=requestAnimationFrame(r)};return r(),()=>{cancelAnimationFrame(n),g.current=[]}},[O,k,a,o,s]),(0,n.jsxs)(`div`,{style:{position:`relative`,width:a,height:o},children:[(0,n.jsx)(`canvas`,{ref:c,style:{width:a,height:o,display:`block`,borderRadius:8},role:`img`,"aria-label":`causal flow diagram`}),(0,n.jsx)(_,{...S,parentW:a,parentH:o})]})}function et({selectedEntity:e,colors:t}){return(0,n.jsx)($e,{nodes:Pe.nodes,links:Pe.links,width:960,height:280,selectedEntity:e})}function tt({rows:e=[],className:r,colors:i}){let{nodes:a,links:o}=(0,t.useMemo)(()=>{let t=e.slice(0,5);return{nodes:[{id:`score`,name:`Portfolio Score`},...t.map(e=>({id:e.id??e.vendor,name:e.vendor}))],links:t.map(e=>({source:e.id??e.vendor,target:`score`,value:Math.max(8,e.pricing??0)}))}},[e]);return(0,n.jsx)(Ke,{nodes:a,links:o,width:760,height:280,ariaLabel:`sankey chart`,className:r,colors:i})}var nt=500,rt=320;function it({left:e,right:r,"data-testid":a}){let u=(0,t.useRef)(null),d=(0,t.useRef)(0);return(0,t.useEffect)(()=>{let t=u.current;if(!t)return;let n=f(t,nt,rt);d.current=0;let a=nt/2,m=Math.max(e.value,r.value),h=(e.value-r.value)/m*14,g,_=()=>{d.current++;let t=d.current;n.clearRect(0,0,nt,rt),n.letterSpacing=o.letterSpacing;let u=x(Math.min(t/80,1)),f=h*w(Math.min(t/80,1))*Math.PI/180;n.strokeStyle=l(i.bd,.5*u),n.lineWidth=2,n.beginPath(),n.moveTo(a,100),n.lineTo(a,rt-80),n.stroke(),n.beginPath(),n.arc(a,100,5*u,0,Math.PI*2),n.fillStyle=i.t2,n.fill();let v={x:a-Math.cos(f)*160,y:100+Math.sin(-f)*160},y={x:a+Math.cos(f)*160,y:100+Math.sin(f)*160};n.strokeStyle=l(i.t2,.5*u),n.lineWidth=2,n.beginPath(),n.moveTo(v.x,v.y),n.lineTo(y.x,y.y),n.stroke();let b=Math.max(20,e.value/m*100*u),S=v.y+18;p(n,v.x,S+b/2,90*.5,i.green,.18*u),n.fillStyle=l(i.green,.5*u),n.beginPath(),n.roundRect(v.x-90/2,S,90,b,[0,0,6,6]),n.fill(),n.strokeStyle=l(i.green,.7*u),n.lineWidth=1.5,n.stroke(),n.strokeStyle=l(i.t2,.35*u),n.lineWidth=1,[-90/3,90/3].forEach(e=>{n.beginPath(),n.moveTo(v.x+e,v.y+4),n.lineTo(v.x+e,S),n.stroke()}),u>.5&&(n.globalAlpha=Math.min(1,(u-.5)/.5),n.font=s.font,n.fillStyle=i.green,n.textAlign=`center`,n.fillText(e.label,v.x,S+b+18),n.font=o.font,n.fillStyle=o.color,n.fillText(`Accepted`,v.x,S+b+32),n.fillText(`${e.count} quotations`,v.x,S+b+44),n.globalAlpha=1);let C=Math.max(20,r.value/m*100*u),T=y.y+18;n.fillStyle=l(i.amber,.3*u),n.strokeStyle=l(i.amber,.5*u),n.lineWidth=1.5,n.beginPath(),n.roundRect(y.x-90/2,T,90,C,[0,0,6,6]),n.fill(),n.stroke(),n.strokeStyle=l(i.t2,.35*u),n.lineWidth=1,[-90/3,90/3].forEach(e=>{n.beginPath(),n.moveTo(y.x+e,y.y+4),n.lineTo(y.x+e,T),n.stroke()}),u>.5&&(n.globalAlpha=Math.min(1,(u-.5)/.5),n.font=s.font,n.fillStyle=i.amber,n.textAlign=`center`,n.fillText(r.label,y.x,T+C+18),n.font=o.font,n.fillStyle=o.color,n.fillText(`Submitted`,y.x,T+C+32),n.fillText(`${r.count} quotations`,y.x,T+C+44),n.globalAlpha=1),u>.85&&Math.abs(h)>1&&(n.globalAlpha=Math.min(1,(u-.85)/.15)*.6,n.font=c.font,n.fillStyle=c.color,n.textAlign=`center`,n.fillText(`${Math.abs(h).toFixed(1)}° tilt toward accepted`,a,rt-12),n.globalAlpha=1),g=requestAnimationFrame(_)};return _(),()=>cancelAnimationFrame(g)},[e,r]),(0,n.jsx)(`div`,{"data-testid":a,style:{position:`relative`,width:nt,height:rt},children:(0,n.jsx)(`canvas`,{ref:u,role:`img`,"aria-label":`Quotation balance — accepted vs submitted quotation value`,style:{width:nt,height:rt,display:`block`}})})}var at=680,W=280;function ot({points:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(new Map),c=(0,t.useRef)(0),{hoveredRef:u,tooltip:d,hitZonesRef:m}=v(a,{width:at,height:W}),h=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,at,W);c.current=0;let n=at-54-28,r=W-30-54,d=Math.max(...h.map(e=>e.count),1),_=h.length,v=_>1?n/(_-1):n,b=h.map((e,t)=>({x:54+t*v,y:30+r-e.count/d*r,point:e})),S,C=()=>{c.current++;let e=c.current;t.clearRect(0,0,at,W),t.letterSpacing=o.letterSpacing;let a=x(Math.min(e/72,1));D(s.current,u.current),m.current=[],[.25,.5,.75,1].forEach(e=>{let a=30+r-e*r;t.strokeStyle=l(i.bd,.18),t.lineWidth=1,t.setLineDash([3,5]),t.beginPath(),t.moveTo(54,a),t.lineTo(54+n,a),t.stroke(),t.setLineDash([]),t.font=o.font,t.fillStyle=o.color,t.textAlign=`right`,t.fillText(String(Math.round(d*e)),48,a+3)}),t.save(),t.translate(12,30+r/2),t.rotate(-Math.PI/2),t.font=o.font,t.fillStyle=o.color,t.textAlign=`center`,t.fillText(`Submissions`,0,0),t.restore(),t.font=o.font,t.fillStyle=o.color,t.textAlign=`center`,t.fillText(`Week`,54+n/2,W-6),t.strokeStyle=l(i.bd,.3),t.lineWidth=1,t.setLineDash([]),t.beginPath(),t.moveTo(54,30+r),t.lineTo(54+n,30+r),t.stroke();let f=a*(_-1),h=Math.floor(f)+1;if(h>=2){t.beginPath(),t.moveTo(b[0].x,30+r),t.lineTo(b[0].x,b[0].y);for(let e=1;e<h;e++){let n=f-Math.floor(f),r=e<h-1?b[e].x:b[e-1].x+(b[e].x-b[e-1].x)*(e===Math.ceil(f)?n:1),i=e<h-1?b[e].y:b[e-1].y+(b[e].y-b[e-1].y)*(e===Math.ceil(f)?n:1);t.lineTo(r,i)}let e=b[Math.min(h-1,_-1)];t.lineTo(e.x,30+r),t.closePath();let n=t.createLinearGradient(0,30,0,30+r);n.addColorStop(0,l(i.blue,.22)),n.addColorStop(1,l(i.blue,.02)),t.fillStyle=n,t.fill()}t.beginPath();for(let e=0;e<h;e++){let n=f-Math.floor(f),r=e===h-1&&e>0&&e===Math.ceil(f),i=e===0||e<h-1?b[e].x:b[e-1].x+(b[e].x-b[e-1].x)*(r?n:1),a=e===0||e<h-1?b[e].y:b[e-1].y+(b[e].y-b[e-1].y)*(r?n:1);e===0?t.moveTo(i,a):t.lineTo(i,a)}t.strokeStyle=l(i.blue,.85),t.lineWidth=2,t.stroke(),b.forEach((e,n)=>{if(n>=h)return;let a=`pt-${n}`,c=s.current.get(a)??0;y(m.current,a,e.x,e.y,10,{label:e.point.week,value:`${e.point.count} quotations submitted`,sublabel:`£${e.point.value}M value`,color:i.blue}),c>0&&g(t,e.x,30,30+r,l(i.blue,.15*c));let u=e.point.count===d;(c>0||u)&&p(t,e.x,e.y,14,i.blue,(u?.3:0)+c*.25),t.beginPath(),t.arc(e.x,e.y,c>0?5:3.5,0,Math.PI*2),t.fillStyle=l(i.blue,c>0?1:.8),t.fill(),(c>0||u)&&(t.font=o.font,t.fillStyle=i.blue,t.textAlign=`center`,t.fillText(String(e.point.count),e.x,e.y-10)),t.font=o.font,t.fillStyle=c>0?i.blue:o.color,t.textAlign=`center`,t.fillText(e.point.week,e.x,W-54+14)}),S=requestAnimationFrame(C)};return C(),()=>cancelAnimationFrame(S)},[h]),h.length<2?(0,n.jsx)(P,{width:at,height:W,"data-testid":r}):(0,n.jsx)(`div`,{"data-testid":r,className:`trend-scroll`,style:{width:`100%`,overflowX:`auto`},children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:at,height:W},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Trend chart — count over time`,style:{width:at,height:W,display:`block`}}),(0,n.jsx)(_,{...d,parentW:at,parentH:W})]})})}var st=680,G=280,ct=54,lt=28,ut=64,dt=o.font,ft=12,pt=Math.PI*2,mt=72,ht=20,gt=5e3;function _t({points:e=[],"data-testid":r}){let a=(0,t.useRef)(null),s=(0,t.useRef)(null),c=(0,t.useRef)(0),u=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),d=(0,t.useMemo)(()=>{if(u.length<=1)return ut;let e=document.createElement(`canvas`).getContext(`2d`);if(!e)return ut;e.font=dt;let t=Math.max(1,Math.ceil(u.length/ht)),n=Math.max(...u.filter((e,n)=>n%t===0).map(t=>e.measureText(t.week).width));return Math.max(ut,n+ft)},[u]),p=Math.round(d/2),m=lt+p+Math.max(0,u.length-1)*d,h=Math.max(st-ct,Math.min(m,gt)),{tooltip:g,hitZonesRef:b}=v(a,{width:h,height:G});return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,h,G),n=s.current?f(s.current,ct,G):null;c.current=0;let r=u.length<=mt?mt:Math.max(24,Math.round(mt*(mt/u.length))),m=h-lt,g=G-30-54,_=Math.max(...u.map(e=>e.count),1),v=u.length,S=v>1?(m-p)/(v-1):m-p,C=Math.max(1,Math.ceil(d/S)),w=u.map((e,t)=>({x:p+t*S,y:30+g-e.count/_*g,point:e}));n&&(n.clearRect(0,0,ct,G),n.letterSpacing=o.letterSpacing,[.25,.5,.75,1].forEach(e=>{let t=30+g-e*g;n.font=o.font,n.fillStyle=o.color,n.textAlign=`right`,n.fillText(String(Math.round(_*e)),ct-6,t+3)}),n.save(),n.translate(12,30+g/2),n.rotate(-Math.PI/2),n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(`Count`,0,0),n.restore());let T=t.createLinearGradient(0,30,0,30+g);T.addColorStop(0,l(i.blue,.22)),T.addColorStop(1,l(i.blue,.02));let E=0,D,O=e=>{t.font=dt,t.fillStyle=o.color,t.textAlign=`center`;for(let n=0;n<e;n++)n%C===0&&t.fillText(w[n].point.week,w[n].x,G-54+14)},k=()=>{c.current++;let e=Math.min(c.current/r,1),n=x(e),a=e>=1;t.clearRect(0,0,h,G),t.letterSpacing=o.letterSpacing,[.25,.5,.75,1].forEach(e=>{let n=30+g-e*g;t.strokeStyle=l(i.bd,.18),t.lineWidth=1,t.setLineDash([3,5]),t.beginPath(),t.moveTo(0,n),t.lineTo(m,n),t.stroke(),t.setLineDash([])}),t.font=o.font,t.fillStyle=o.color,t.textAlign=`center`,t.fillText(`Period`,p+(m-p)/2,G-6),t.strokeStyle=l(i.bd,.3),t.lineWidth=1,t.beginPath(),t.moveTo(p,30+g),t.lineTo(m,30+g),t.stroke();let s=n*(v-1),u=Math.floor(s)+1;if(u>=2){t.beginPath(),t.moveTo(w[0].x,30+g),t.lineTo(w[0].x,w[0].y);for(let e=1;e<u;e++){let n=s-Math.floor(s),r=e===u-1&&e===Math.ceil(s)&&n>0,i=r?w[e-1].x+(w[e].x-w[e-1].x)*n:w[e].x,a=r?w[e-1].y+(w[e].y-w[e-1].y)*n:w[e].y;t.lineTo(i,a)}t.lineTo(w[u-1].x,30+g),t.closePath(),t.fillStyle=T,t.fill()}t.beginPath();for(let e=0;e<u;e++){let n=s-Math.floor(s),r=e===u-1&&e>0&&e===Math.ceil(s)&&n>0,i=r?w[e-1].x+(w[e].x-w[e-1].x)*n:w[e].x,a=r?w[e-1].y+(w[e].y-w[e-1].y)*n:w[e].y;e===0?t.moveTo(i,a):t.lineTo(i,a)}t.strokeStyle=l(i.blue,.85),t.lineWidth=2,t.stroke(),t.fillStyle=l(i.blue,.8),t.beginPath();for(let e=0;e<u;e++)t.moveTo(w[e].x+3.5,w[e].y),t.arc(w[e].x,w[e].y,3.5,0,pt);if(t.fill(),u>E){b.current=[];for(let e=0;e<u;e++)y(b.current,`pt-${e}`,w[e].x,w[e].y,10,{label:w[e].point.week,value:`${w[e].point.count} submissions`,sublabel:`£${w[e].point.value}M value`,color:i.blue});E=u}a&&O(v),a||(D=requestAnimationFrame(k))};return k(),()=>cancelAnimationFrame(D)},[u,h,d,b]),u.length<2?(0,n.jsx)(P,{width:st,height:G,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:`100%`,display:`flex`},children:[(0,n.jsx)(`canvas`,{ref:s,"aria-hidden":`true`,style:{width:ct,height:G,display:`block`,flexShrink:0}}),(0,n.jsx)(`div`,{className:`trend-scroll`,style:{flex:1,overflowX:`auto`},children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:h,height:G},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Trend chart — count over time`,style:{width:h,height:G,display:`block`}}),(0,n.jsx)(_,{...g,parentW:h,parentH:G})]})})]})}var K=680,vt=240;function yt(e,t,n){if(e.measureText(t).width<=n)return t;let r=t;for(;r.length>0&&e.measureText(`${r}…`).width>n;)r=r.slice(0,-1);return`${r}…`}var bt={Critical:i.red,High:i.orange,Medium:i.amber,Low:i.green};function xt({severities:e=[],"data-testid":r}){let a=(0,t.useRef)(null),c=(0,t.useRef)(new Map),u=(0,t.useRef)(0),{hoveredRef:d,tooltip:m,hitZonesRef:h}=v(a,{width:K,height:vt}),g=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,K,vt);u.current=0;let n=g.reduce((e,t)=>e+(t.count??0),0),r=K-28-28,m=vt-50-52,_=g.map(e=>(e.count??0)/(n||1)*r),v,y=()=>{u.current++;let e=u.current;t.clearRect(0,0,K,vt),t.letterSpacing=o.letterSpacing;let a=S(Math.min(e/60,1));D(c.current,d.current),h.current=[],t.strokeStyle=l(i.bd,.2),t.lineWidth=1,t.beginPath(),t.rect(28,50,r,m),t.stroke(),t.strokeStyle=l(i.t2,.15),t.lineWidth=1,t.setLineDash([4,4]),t.beginPath(),t.moveTo(K/2,50),t.lineTo(K/2,50+m),t.stroke(),t.setLineDash([]);let f=28;g.forEach((e,r)=>{let u=bt[e.severity]??i.blue,d=_[r],g=c.current.get(e.severity)??0,v=f+d/2,y=d*.85,x=d*a,S=y*a,C=v-S/2;if(x>0&&(g>0&&p(t,f+x/2,50+m/2,x*.4,u,.15*g),t.beginPath(),t.moveTo(C,50),t.lineTo(C+S,50),t.lineTo(f+x,50+m),t.lineTo(f,50+m),t.closePath(),t.fillStyle=l(u,.45+g*.25),t.fill(),t.strokeStyle=l(u,(.5+g*.3)*a),t.lineWidth=g>0?2:1,t.beginPath(),t.moveTo(C,50),t.lineTo(C+S,50),t.stroke(),t.strokeStyle=l(u,(.3+g*.3)*a),t.lineWidth=g>0?2:1,t.beginPath(),t.moveTo(f,50+m),t.lineTo(f+x,50+m),t.stroke()),b(h.current,e.severity,f,50,d,m,{label:e.severity,value:`${e.count} Early Warnings`,sublabel:`${Math.round((e.count??0)/(n||1)*100)}% of all EWs`,color:u}),a>.5){let r=Math.min(1,(a-.5)/.5),c=f+d/2;t.globalAlpha=r,t.font=o.font,t.fillStyle=g>0?u:l(u,.9),t.textAlign=`center`,t.fillText(yt(t,e.severity,d-12),c,38),t.font=s.font,t.fillStyle=g>0?i.t1:l(i.t1,.85),t.fillText(String(e.count),c,50+m/2+6),t.font=o.font,t.fillStyle=g>0?u:o.color,t.fillText(`${Math.round((e.count??0)/(n||1)*100)}%`,c,50+m+18),t.globalAlpha=1}f+=d});let x=t.createLinearGradient(28,0,28+r,0);x.addColorStop(0,l(i.red,.03)),x.addColorStop(.33,l(i.orange,.03)),x.addColorStop(.66,l(i.amber,.03)),x.addColorStop(1,l(i.green,.03)),t.fillStyle=x,t.fillRect(28,50,r*a,m),v=requestAnimationFrame(y)};return y(),()=>cancelAnimationFrame(v)},[g]),g.length===0?(0,n.jsx)(P,{width:K,height:vt,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:K,height:vt},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Early Warning severity distribution — prism spectrum bands`,style:{width:K,height:vt,display:`block`}}),(0,n.jsx)(_,{...m,parentW:K,parentH:vt})]})}var q=460,J=300,St={Open:i.red,Submitted:i.amber,Closed:i.green};function Ct({segments:e=[],title:r,"data-testid":a}){let c=(0,t.useRef)(null),u=(0,t.useRef)(0),d=(0,t.useRef)(new Map),{hoveredRef:g,tooltip:b,hitZonesRef:x}=v(c,{width:q,height:J}),S=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]);return(0,t.useEffect)(()=>{let e=c.current;if(!e)return;let t=f(e,q,J);u.current=0;let n=q*.5,r=J*.54,a=q*.22,_=S.reduce((e,t)=>e+(t.count??0),0),v=Math.max(...S.map(e=>e.count??0),1),b,C=()=>{u.current++;let e=u.current;t.clearRect(0,0,q,J),t.letterSpacing=o.letterSpacing,x.current=[],d.current.forEach((e,t)=>{let n=t===g.current?1:0,r=e+(n-e)*.12;Math.abs(r-n)<.005?n===0?d.current.delete(t):d.current.set(t,1):d.current.set(t,r)}),g.current&&!d.current.has(g.current)&&d.current.set(g.current,0),m(t,q,J,e,40,l(i.blue,.04)),S.forEach((o,c)=>{let u=c/3*Math.PI*2-Math.PI/2,d=n+Math.cos(u)*a,f=r+Math.sin(u)*a,m=St[o.status]??i.blue,h=2+o.count/v*8;t.beginPath(),t.moveTo(n,r),t.lineTo(d,f),t.strokeStyle=l(m,.08),t.lineWidth=h*2,t.stroke(),t.beginPath(),t.moveTo(n,r),t.lineTo(d,f),t.strokeStyle=l(m,.25),t.lineWidth=1,t.stroke();let g=(e*.005+c*.33)%1,_=n+(d-n)*g,y=r+(f-r)*g;p(t,_,y,6,m,.4),t.beginPath(),t.arc(_,y,2,0,Math.PI*2),t.fillStyle=l(m,.8),t.fill();let b=(n+d)/2,x=(r+f)/2;t.font=s.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(m,.85),t.fillText(String(o.count),b,x)}),S.forEach((e,s)=>{let c=s/3*Math.PI*2-Math.PI/2,u=n+Math.cos(c)*a,f=r+Math.sin(c)*a,m=St[e.status]??i.blue,h=10+e.count/v*18,g=d.current.get(e.status)??0;p(t,u,f,h*2.5,m,.2+g*.15);let b=t.createRadialGradient(u,f-h*.2,0,u,f,h);b.addColorStop(0,l(m,.8+g*.2)),b.addColorStop(1,l(m,.4+g*.1)),t.beginPath(),t.arc(u,f,h,0,Math.PI*2),t.fillStyle=b,t.fill(),t.font=`bold `+o.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(i.t1,.9),t.fillText(e.status,u,f),y(x.current,e.status,u,f,h+6,{label:e.status,value:`${e.count} Early Warnings`,sublabel:`${Math.round((e.count??0)/(_||1)*100)}%`,color:m})});let c=d.current.get(`center`)??0;p(t,n,r,36,i.t2,.2+c*.15);let f=t.createRadialGradient(n,r-4,0,n,r,22);f.addColorStop(0,l(i.t2,.9)),f.addColorStop(1,l(i.t2,.5)),t.beginPath(),t.arc(n,r,22,0,Math.PI*2),t.fillStyle=f,t.fill(),t.font=s.font,t.textAlign=`center`,t.textBaseline=`middle`,t.fillStyle=l(i.t1,.9),t.fillText(`EW Status`,n,r-4),t.font=`bold `+o.font,t.fillStyle=i.t1,t.fillText(String(_),n,r+8),y(x.current,`center`,n,r,28,{label:`Total EW Status`,value:`${_} Early Warnings`,color:i.t2}),h(t,q,J,e,.015),b=requestAnimationFrame(C)};return C(),()=>cancelAnimationFrame(b)},[S,r]),S.length===0?(0,n.jsx)(P,{width:q,height:J,"data-testid":a}):(0,n.jsxs)(`div`,{"data-testid":a,style:{position:`relative`,width:q,height:J},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":r??`EW status arc visualization`,style:{width:q,height:J,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...b,parentW:q,parentH:J})]})}var wt=280,Y=96;function Tt({points:e=[],className:a,colors:o}){let s=(0,t.useRef)(null),c=(0,t.useRef)(new Map),u=(0,t.useRef)(0),d=(0,t.useMemo)(()=>e.filter(Array.isArray).map(([e,t])=>{let n=String(t).match(/-?\d+(\.\d+)?/);return{label:e,value:n?Number(n[0]):0}}),[e]),{mouseRef:m,hoveredRef:h,tooltip:b,hitZonesRef:x}=v(s,{width:wt,height:Y});return(0,t.useEffect)(()=>{let e=s.current;if(!e)return;let t=f(e,wt,Y);u.current=0;let n=o?.line??i.blue,r=o?.point??i.blue,a=o?.axisLine??i.bd,_,v=()=>{u.current++;let e=u.current;if(t.clearRect(0,0,wt,Y),d.length<2){_=requestAnimationFrame(v);return}let o={left:12,right:12,top:16,bottom:20},s=wt-o.left-o.right,f=Y-o.top-o.bottom,b=d.map(e=>e.value),S=Math.min(...b),C=Math.max(...b)-S||1,w=e=>o.left+e/(d.length-1)*s,E=e=>o.top+(1-(e-S)/C)*f,O=1-(1-Math.min(e/48,1))**3,k=Math.max(2,Math.floor(O*d.length));if(D(c.current,h.current),x.current=[],t.strokeStyle=l(a,.3),t.lineWidth=.5,t.setLineDash([]),t.beginPath(),t.moveTo(o.left,Y-o.bottom),t.lineTo(wt-o.right,Y-o.bottom),t.stroke(),t.font=`9px 'JetBrains Mono', monospace`,t.fillStyle=l(i.t4,.9),t.textAlign=`center`,d.forEach((e,n)=>{t.fillText(e.label.replace(`Day `,`D`),w(n),Y-4)}),m.current.over&&h.current){let e=parseInt(h.current.split(`-`)[1]);isNaN(e)||g(t,w(e),o.top,o.top+f)}if(k>1){let e=t.createLinearGradient(0,o.top,0,o.top+f);e.addColorStop(0,l(n,.15)),e.addColorStop(1,l(n,0)),t.fillStyle=e,t.beginPath(),t.moveTo(w(0),o.top+f);for(let e=0;e<k;e++)t.lineTo(w(e),E(d[e].value));t.lineTo(w(k-1),o.top+f),t.closePath(),t.fill(),t.strokeStyle=l(n,.8),t.lineWidth=1.5,t.setLineDash([]),t.beginPath();for(let e=0;e<k;e++){let n=w(e),r=E(d[e].value);e===0?t.moveTo(n,r):t.lineTo(n,r)}t.stroke()}for(let e=0;e<k;e++){let n=w(e),a=E(d[e].value),o=`tp-${e}`,s=c.current.get(o)??0,u=e===d.length-1;y(x.current,o,n,a,10,{label:d[e].label,value:String(d[e].value),color:u?i.red:r}),s>0&&!u&&(p(t,n,a,12*s,r,.2*s),t.fillStyle=l(r,.8),t.beginPath(),t.arc(n,a,3+s*2,0,Math.PI*2),t.fill())}if(k>=d.length){let n=d.length-1,r=w(n),a=E(d[n].value),o=c.current.get(`tp-${n}`)??0,s=T(e,.05,5e-4),u=1+o*.5;t.shadowColor=l(i.red,.5),t.shadowBlur=(8+s*4)*u,t.fillStyle=i.red,t.beginPath(),t.arc(r,a,(3.5+s*1.5)*u,0,Math.PI*2),t.fill(),t.shadowBlur=0}_=requestAnimationFrame(v)};return v(),()=>cancelAnimationFrame(_)},[d,o]),(0,n.jsx)(r,{className:[`canvas-trend-frame`,a].filter(Boolean).join(` `),children:(0,n.jsxs)(`div`,{style:{position:`relative`,width:wt,height:Y},children:[(0,n.jsx)(`canvas`,{ref:s,role:`img`,"aria-label":`trend chart`,style:{width:wt,height:Y,display:`block`,borderRadius:8}}),(0,n.jsx)(_,{...b,parentW:wt,parentH:Y})]})})}var X=680,Et=8,Dt=26,Ot=14,kt=16,At=32;function jt({items:e=[],"data-testid":r}){let a=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),[m,h]=(0,t.useState)(!1),g=(0,t.useMemo)(()=>e.filter(e=>typeof e==`object`&&!!e),[e]),y=(0,t.useMemo)(()=>m?g:g.slice(0,Et),[g,m]),x=kt+At+y.length*(Dt+Ot)-Ot,{hoveredRef:C,tooltip:w,hitZonesRef:T}=v(a,{width:X,height:x});return(0,t.useEffect)(()=>{let e=a.current;if(!e)return;let t=f(e,X,x);d.current=0;let n=kt,r=At,m=Dt,h=Ot,g=X-60-28,_=Math.max(...y.map(e=>(e.implemented??0)+(e.unimplemented??0)),1),v=y.length*(m+h)-h,w=n+(x-n-r-v)/2,O,k=()=>{d.current++;let e=d.current;t.clearRect(0,0,X,x);let n=S(Math.min(e/60,1));D(u.current,C.current),T.current=[],y.forEach((e,r)=>{let a=E(n,r,y.length,S),c=w+r*(m+h),d=(e.implemented??0)+(e.unimplemented??0),f=(e.implemented??0)/_*g*a,v=(e.unimplemented??0)/_*g*a,x=`${e.id}-impl`,C=`${e.id}-un`,D=u.current.get(x)??0,O=u.current.get(C)??0;b(T.current,x,60,c,f||1,m,{label:`${e.name} — Implemented`,value:`${e.implemented??0} variations`,sublabel:`${Math.round((e.implemented??0)/(d||1)*100)}% complete`,color:i.green}),b(T.current,C,60+f,c,v||1,m,{label:`${e.name} — Unimplemented`,value:`${e.unimplemented??0} variations`,sublabel:`${Math.round((e.unimplemented??0)/(d||1)*100)}% pending`,color:i.amber}),t.font=o.font,t.fillStyle=i.t2,t.textAlign=`right`,t.fillText(e.abbreviation??e.name?.slice(0,6)??``,52,c+m/2+4),t.fillStyle=l(i.bd,.15),t.beginPath(),t.roundRect(60,c,d/_*g,m,4),t.fill(),f>0&&(D>0&&p(t,60+f/2,c+m/2,f*.3,i.green,.12*D),t.fillStyle=l(i.green,.6+D*.2),t.beginPath(),t.roundRect(60,c,f,m,[4,0,0,4]),t.fill(),f>28&&a>.5&&(t.font=s.font,t.fillStyle=D>0?i.green:i.t2,t.textAlign=`center`,t.fillText(String(e.implemented??0),60+f/2,c+m/2+4))),v>0&&(O>0&&p(t,60+f+v/2,c+m/2,v*.3,i.amber,.12*O),t.fillStyle=l(i.amber,.18+O*.18),t.strokeStyle=l(i.amber,.3+O*.3),t.lineWidth=1,t.beginPath(),t.roundRect(60+f,c,v,m,[0,4,4,0]),t.fill(),t.stroke(),v>28&&a>.5&&(t.font=s.font,t.fillStyle=O>0?i.amber:i.t2,t.textAlign=`center`,t.fillText(String(e.unimplemented??0),60+f+v/2,c+m/2+4))),f>0&&v>0&&(t.strokeStyle=l(i.bg,.7),t.lineWidth=2,t.beginPath(),t.moveTo(60+f,c),t.lineTo(60+f,c+m),t.stroke())});let r=w+v+24,a=60+g/2;t.font=c.font,t.textAlign=`right`,t.fillStyle=i.green,t.fillText(`■ Implemented`,a-10,r),t.textAlign=`left`,t.fillStyle=c.color,t.fillText(`■ Unimplemented`,a+10,r),O=requestAnimationFrame(k)};return k(),()=>cancelAnimationFrame(O)},[y,x]),g.length===0?(0,n.jsx)(P,{width:X,height:160,"data-testid":r}):(0,n.jsxs)(`div`,{"data-testid":r,style:{width:X},children:[(0,n.jsxs)(`div`,{style:{position:`relative`,width:X,height:x},children:[(0,n.jsx)(`canvas`,{ref:a,role:`img`,"aria-label":`Implemented vs unimplemented variations per contractor — split bar`,style:{width:X,height:x,display:`block`}}),(0,n.jsx)(_,{...w,parentW:X,parentH:x})]}),g.length>Et&&(0,n.jsx)(`div`,{style:{marginTop:8},children:(0,n.jsx)(te,{expanded:m,onToggle:()=>h(e=>!e)})})]})}var Mt=800,Nt=360;function Pt({items:e=[],"data-testid":r}){let c=(0,t.useRef)(null),u=(0,t.useRef)(new Map),d=(0,t.useRef)(0),{hoveredRef:m,tooltip:h,hitZonesRef:g}=v(c,{width:Mt,height:Nt});return(0,t.useEffect)(()=>{let t=c.current;if(!t)return;let n=f(t,Mt,Nt);d.current=0;let r=e.reduce((e,t)=>e+(t.base??0),0),h=e.reduce((e,t)=>e+(t.variation??0),0),_=e.reduce((e,t)=>e+(t.total??0),0),v=Nt-20-26,y=v-6*(e.length-1),S=20,C=e.map((e,t)=>{let n=Math.max(24,(e.total??0)/(_||1)*y),r={x:100-110/2,y:S,h:n,cy:S+n/2,c:e,color:a[t%a.length]};return S+=n+6,r}),w=y-14,T=Math.max(28,r/_*w),O=Math.max(18,h/_*w),k=20+(v-(T+O+14))/2,A={x:420-110/2,y:k,h:T,cy:k+T/2},j={x:420-110/2,y:k+T+14,h:O,cy:k+T+14+O/2},M={x:720-110/2,y:20,h:v,cy:20+v/2},N,ee=()=>{d.current++;let t=d.current;n.clearRect(0,0,Mt,Nt),n.letterSpacing=o.letterSpacing;let a=x(Math.min(t/80,1));if(D(u.current,m.current),g.current=[],e.forEach((t,i)=>{let o=C[i],s=E(a,i,e.length,x),c=u.current.get(t.id)??0;if(s<.01)return;let l=(t.base??0)/(t.total||1),d=(t.variation??0)/(t.total||1),f=o.h*l,p=o.h*d,m=o.y+f/2,g=o.y+f+p/2,_=Math.max(2,(t.base??0)/r*T),v=Math.max(2,(t.variation??0)/h*O),y=A.y+e.slice(0,i).reduce((e,t)=>e+(t.base??0)/r*T,0)+_/2,b=j.y+e.slice(0,i).reduce((e,t)=>e+(t.variation??0)/h*O,0)+v/2,S=c*.2+.18;Ft(n,o.x+110,m,420-110/2,y,_*s,o.color,S),Ft(n,o.x+110,g,420-110/2,b,v*s,o.color,S*.75)}),a>.3){let e=Math.min(1,(a-.3)/.7),t=M.y+r/_*v/2,o=M.y+v-h/_*v/2;Ft(n,475,A.cy,720-110/2,t,T*e,i.blue,.25*e),Ft(n,475,j.cy,720-110/2,o,O*e,i.amber,.22*e)}if([`Contractors`,`Components`,`Total`].forEach((e,t)=>{let r=[100,420,720][t];n.font=o.font,n.fillStyle=o.color,n.textAlign=`center`,n.fillText(e,r,Nt-8)}),e.forEach((t,r)=>{let s=C[r],c=E(a,r,e.length,x),d=u.current.get(t.id)??0;b(g.current,t.id,s.x,s.y,110,s.h,{label:t.name,value:`${t.totalLabel??String(t.total??0)} total commitment`,sublabel:`Base ${t.baseLabel??String(t.base??0)} + Variations ${t.variationLabel??String(t.variation??0)}`,color:s.color}),d>0&&p(n,s.x+110/2,s.cy,110*.6,s.color,.12*d),n.fillStyle=l(s.color,(.3+d*.15)*c),n.strokeStyle=l(s.color,(.55+d*.25)*c),n.lineWidth=1,n.beginPath(),n.roundRect(s.x,s.y,110*c,s.h,4),n.fill(),n.stroke(),c>.6&&s.h>=24&&(n.globalAlpha=Math.min(1,(c-.6)/.4),n.font=o.font,n.fillStyle=d>0?s.color:l(i.t2,.9),n.textAlign=`center`,n.textBaseline=`middle`,n.fillText(t.abbreviation??t.name.slice(0,6),s.x+110/2,s.h>=36?s.cy-5:s.cy),s.h>=36&&(n.font=`400 12px 'Satoshi Variable', 'DM Sans', sans-serif`,n.fillStyle=l(i.t3,.8),n.fillText(t.totalLabel??String(t.total??0),s.x+110/2,s.cy+7)),n.globalAlpha=1,n.textBaseline=`alphabetic`)}),a>.2){let e=Math.min(1,(a-.2)/.4);p(n,420,A.cy,30,i.blue,.1*e),n.fillStyle=l(i.blue,.3*e),n.strokeStyle=l(i.blue,.5*e),n.lineWidth=1,n.beginPath(),n.roundRect(A.x,A.y,110,A.h*e,4),n.fill(),n.stroke(),n.globalAlpha=e,n.textBaseline=`middle`,n.font=o.font,n.fillStyle=i.blue,n.textAlign=`center`,n.fillText(`Base Value`,420,A.cy-6),n.font=s.font,n.fillStyle=s.color,n.fillText(`£${r}M`,420,A.cy+8),n.globalAlpha=1,n.textBaseline=`alphabetic`,p(n,420,j.cy,24,i.amber,.1*e),n.fillStyle=l(i.amber,.22*e),n.strokeStyle=l(i.amber,.4*e),n.beginPath(),n.roundRect(j.x,j.y,110,j.h*e,4),n.fill(),n.stroke(),n.globalAlpha=e,n.textBaseline=`middle`,n.font=o.font,n.fillStyle=i.amber,n.textAlign=`center`,n.fillText(`Variations`,420,j.cy-4),n.font=s.font,n.fillStyle=s.color,n.fillText(`£${h}M`,420,j.cy+8),n.globalAlpha=1,n.textBaseline=`alphabetic`}if(a>.5){let e=Math.min(1,(a-.5)/.5);p(n,720,M.cy,44,i.blue,.2*e),n.fillStyle=l(i.blue,.25*e),n.strokeStyle=l(i.blue,.6*e),n.lineWidth=1.5,n.beginPath(),n.roundRect(M.x,M.y,110,M.h*e,6),n.fill(),n.stroke(),n.globalAlpha=e,n.textBaseline=`middle`,n.font=o.font,n.fillStyle=i.t2,n.textAlign=`center`,n.fillText(`Total Commitment`,720,M.cy-12),n.font=s.font,n.fillStyle=i.blue,n.fillText(`£${_}M`,720,M.cy+6),n.globalAlpha=1,n.textBaseline=`alphabetic`}N=requestAnimationFrame(ee)};return ee(),()=>cancelAnimationFrame(N)},[e]),(0,n.jsxs)(`div`,{"data-testid":r,style:{position:`relative`,width:Mt,height:Nt},children:[(0,n.jsx)(`canvas`,{ref:c,role:`img`,"aria-label":`Weekly report flow — base value and variations per contractor flowing to total commitment`,style:{width:Mt,height:Nt,display:`block`}}),(0,n.jsx)(_,{...h,parentW:Mt,parentH:Nt})]})}function Ft(e,t,n,r,i,a,o,s){let c=(t+r)/2;e.beginPath(),e.moveTo(t,n-a/2),e.bezierCurveTo(c,n-a/2,c,i-a/2,r,i-a/2),e.lineTo(r,i+a/2),e.bezierCurveTo(c,i+a/2,c,n+a/2,t,n+a/2),e.closePath(),e.fillStyle=l(o,s),e.fill()}function It({config:e,className:t}){return e.type===`line`?(0,n.jsx)(Me,{rows:e.rows,className:t}):e.type===`area`?(0,n.jsx)(j,{rows:e.rows,className:t}):e.type===`bar`?(0,n.jsx)(ee,{rows:e.rows,className:t}):e.type===`pie`?(0,n.jsx)(We,{rows:e.rows,variant:`pie`,className:t}):e.type===`donut`?(0,n.jsx)(We,{rows:e.rows,variant:`donut`,className:t}):e.type===`sankey`?(0,n.jsx)(tt,{rows:e.rows,className:t}):e.type===`flow`?(0,n.jsx)(et,{selectedEntity:e.selectedEntity,className:t}):e.type===`trend`?(0,n.jsx)(Tt,{points:e.points,className:t}):e.type===`mini-bars`?(0,n.jsx)(Fe,{rows:e.rows,className:t}):e.type===`stacked-horizontal-bar-chart`?(0,n.jsx)(Ee,{data:e.data}):e.type===`multi-metric-constellation-chart`?(0,n.jsx)(ve,{items:e.items}):e.type===`progress-race-chart`?(0,n.jsx)(se,{items:e.items}):e.type===`hub-and-spoke-radial-chart`?(0,n.jsx)(Ct,{segments:e.segments,title:e.title}):e.type===`dot-matrix-chart`?(0,n.jsx)(je,{items:e.items}):e.type===`ranked-card-leaderboard`?(0,n.jsx)(Ae,{items:e.items}):e.type===`proportional-band-chart`?(0,n.jsx)(xt,{severities:e.severities}):e.type===`radial-fan-tree-chart`?(0,n.jsx)(Be,{total:e.total,totalLabel:e.totalLabel,items:e.items}):e.type===`semi-circular-gauge-chart`?(0,n.jsx)(ue,{value:e.value,confirmed:e.confirmed,total:e.total}):e.type===`segmented-split-bar-chart`?(0,n.jsx)(jt,{items:e.items}):e.type===`balance-scale-chart`?(0,n.jsx)(it,{left:e.left,right:e.right}):e.type===`area-line-chart`?(0,n.jsx)(ot,{points:e.points}):e.type===`trend-view`?(0,n.jsx)(_t,{points:e.points}):e.type===`weekly-flow`?(0,n.jsx)(Pt,{items:e.items}):(0,n.jsx)(`div`,{className:`viz-empty`,children:`Visualization unavailable`})}var Lt=[];function Rt(e){try{return JSON.parse(decodeURIComponent(e))}catch{return null}}function zt(){for(;Lt.length;){let e=Lt.pop();e&&e.unmount()}}function Bt(){zt(),document.querySelectorAll(`[data-d3-viz]`).forEach(t=>{let r=t.dataset.d3Viz;if(!r)return;let i=Rt(r);if(!i)return;let a=(0,e.createRoot)(t);Lt.push(a),a.render((0,n.jsx)(It,{config:i}))})}function Vt(e){return encodeURIComponent(JSON.stringify(e))}function Ht({rows:e=[],className:t,colors:r}){return(0,n.jsx)(We,{rows:e,variant:`donut`,className:t,colors:r})}var Z={bg:`transparent`,border:`transparent`,t1:i.t1,t2:i.t2,t3:i.t3,t4:i.t4,red:i.red,amber:i.amber,green:i.green},Q=`'Satoshi Variable', 'DM Sans', sans-serif`,Ut={color:`#F7F7F7`,fontFamily:Q,fontSize:24,fontWeight:500,lineHeight:`32px`},$={color:`#C2C2C2`,fontFamily:Q,fontSize:18,fontWeight:400,lineHeight:`20px`};function Wt({chips:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,gap:6,marginTop:10},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{width:260,height:120,display:`flex`,alignItems:`baseline`,gap:8,padding:`8px 12px`,background:Z.bg,border:`1px solid ${Z.border}`,borderRadius:5,boxSizing:`border-box`},children:[(0,n.jsx)(`span`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`span`,{style:{...$,flex:1},children:e.label})]},t))})}function Gt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,gap:8},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,justifyContent:`center`,alignItems:`flex-start`,width:260,height:120,padding:24,gap:8,flexShrink:0,border:`1px solid ${Z.border}`,background:Z.bg,boxSizing:`border-box`},children:[(0,n.jsx)(`div`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`div`,{style:{...$},children:e.label})]},t))})}function Kt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:12,padding:`9px 14px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:e.color??Z.t2,background:(e.color??Z.t2)+`22`,padding:`2px 8px`,borderRadius:4,fontFamily:Q,flexShrink:0},children:e.name}),(0,n.jsx)(`span`,{style:{...Ut,fontSize:18,color:e.color??Z.t1,minWidth:70,flexShrink:0},children:e.value}),(0,n.jsx)(`span`,{style:{...$,flex:1},children:e.kpiLabel})]},t))})}function qt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,gap:8},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,justifyContent:`center`,alignItems:`flex-start`,width:260,height:120,padding:24,gap:8,flexShrink:0,background:Z.bg,boxSizing:`border-box`},children:[(0,n.jsx)(`div`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`div`,{style:{...$},children:e.label})]},t))})}var Jt={red:Z.red,amber:Z.amber,green:Z.green};function Yt({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>{let r=Jt[e.severity];return(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:10,padding:`10px 14px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{width:7,height:7,borderRadius:`50%`,background:r,flexShrink:0,marginTop:5}}),(0,n.jsx)(`span`,{style:{...$},children:e.text})]},t)})})}function Xt({min:e,max:t,unit:r,dots:a=[],chips:o=[]}){let s=t-e;return(0,n.jsxs)(`div`,{children:[(0,n.jsxs)(`div`,{style:{position:`relative`,height:90,marginTop:4},children:[(0,n.jsx)(`div`,{style:{position:`absolute`,top:38,left:8,right:8,height:2,background:`rgba(255,255,255,0.08)`,borderRadius:1}}),(0,n.jsxs)(`div`,{style:{position:`absolute`,top:43,left:0,fontSize:16,color:Z.t4,fontFamily:Q},children:[e,r]}),(0,n.jsxs)(`div`,{style:{position:`absolute`,top:43,right:0,fontSize:16,color:Z.t4,fontFamily:Q},children:[t,r]}),a.map((t,a)=>{let o=(t.val-e)/s*100,c=t.color??i.blue,l=a%2==0;return(0,n.jsxs)(`div`,{style:{position:`absolute`,left:`${o}%`,top:0,transform:`translateX(-50%)`},children:[l&&(0,n.jsxs)(`div`,{style:{textAlign:`center`,marginBottom:2},children:[(0,n.jsx)(`div`,{style:{fontSize:18,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:t.name}),(0,n.jsxs)(`div`,{style:{fontSize:18,fontWeight:500,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:[t.val,r]})]}),(0,n.jsx)(`div`,{style:{width:10,height:10,borderRadius:`50%`,background:c,boxShadow:`0 0 8px ${c}70`,margin:l?`0 auto`:`26px auto 0`}}),!l&&(0,n.jsxs)(`div`,{style:{textAlign:`center`,marginTop:4},children:[(0,n.jsx)(`div`,{style:{fontSize:18,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:t.name}),(0,n.jsxs)(`div`,{style:{fontSize:18,fontWeight:500,color:c,fontFamily:Q,whiteSpace:`nowrap`},children:[t.val,r]})]})]},a)})]}),o&&o.length>0&&(0,n.jsx)(Wt,{chips:o})]})}function Zt({leftPct:e,leftLabel:t,leftValue:r,leftColor:a,rightPct:o,rightLabel:s,rightValue:c,rightColor:l,chips:u}){let d=a??i.blue,f=l??i.blue;return(0,n.jsxs)(`div`,{children:[(0,n.jsxs)(`div`,{style:{display:`flex`,borderRadius:6,overflow:`hidden`,height:36,marginBottom:8},children:[(0,n.jsx)(`div`,{style:{width:`${e}%`,background:d+`38`,display:`flex`,alignItems:`center`,justifyContent:`flex-end`,paddingRight:12},children:(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:d,fontFamily:Q},children:r})}),(0,n.jsx)(`div`,{style:{width:1,background:`rgba(255,255,255,0.12)`,flexShrink:0}}),(0,n.jsx)(`div`,{style:{width:`${o}%`,background:f+`2A`,display:`flex`,alignItems:`center`,paddingLeft:12},children:(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:f,fontFamily:Q},children:c})})]}),(0,n.jsxs)(`div`,{style:{display:`flex`,marginBottom:u?4:0},children:[(0,n.jsx)(`div`,{style:{width:`${e}%`},children:(0,n.jsxs)(`span`,{style:{fontSize:18,color:d,fontFamily:Q},children:[e,`% `,t]})}),(0,n.jsx)(`div`,{style:{width:`${o}%`,paddingLeft:10},children:(0,n.jsxs)(`span`,{style:{fontSize:18,color:f,fontFamily:Q},children:[o,`% `,s]})})]}),u&&u.length>0&&(0,n.jsx)(Wt,{chips:u})]})}function Qt({pct:e,label:t,color:r,chips:a}){let o=r??i.blue,s=2*Math.PI*30,c=s*(1-e/100);return(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:20},children:[(0,n.jsxs)(`div`,{style:{position:`relative`,flexShrink:0,width:80,height:80},children:[(0,n.jsxs)(`svg`,{width:80,height:80,style:{transform:`rotate(-90deg)`},children:[(0,n.jsx)(`circle`,{cx:40,cy:40,r:30,fill:`none`,stroke:`rgba(255,255,255,0.07)`,strokeWidth:8}),(0,n.jsx)(`circle`,{cx:40,cy:40,r:30,fill:`none`,stroke:o,strokeWidth:8,strokeDasharray:s,strokeDashoffset:c,strokeLinecap:`round`})]}),(0,n.jsx)(`div`,{style:{position:`absolute`,top:`50%`,left:`50%`,transform:`translate(-50%, -50%)`,textAlign:`center`},children:(0,n.jsxs)(`div`,{style:{fontSize:18,fontWeight:500,color:o,fontFamily:Q},children:[e,`%`]})})]}),(0,n.jsxs)(`div`,{style:{flex:1},children:[(0,n.jsx)(`div`,{style:{...$,marginBottom:10},children:t}),a&&(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:a.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,gap:8,padding:`7px 10px`,background:Z.bg,border:`1px solid ${Z.border}`,borderRadius:5},children:[(0,n.jsx)(`span`,{style:{...Ut,color:e.color??Z.t1},children:e.value}),(0,n.jsx)(`span`,{style:{...$},children:e.label})]},t))})]})]})}var $t={green:`#34D39918`,amber:`#FBBF2418`,red:`#F0606018`},en={green:`#34D399`,amber:`#FBBF24`,red:`#F06060`};function tn({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`8px 12px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:e.color??Z.t2,background:(e.color??Z.t2)+`1A`,padding:`2px 7px`,borderRadius:4,fontFamily:Q,flexShrink:0,minWidth:62,textAlign:`center`},children:e.name}),(0,n.jsx)(`div`,{style:{flex:1,height:4,background:`rgba(255,255,255,0.07)`,borderRadius:2,overflow:`hidden`},children:(0,n.jsx)(`div`,{style:{height:`100%`,width:`${e.pct}%`,background:e.color??Z.t2,borderRadius:2,opacity:.75}})}),(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:e.color??Z.t1,fontFamily:Q,flexShrink:0,minWidth:52,textAlign:`right`},children:e.value}),e.badge&&e.badgeSeverity&&(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:en[e.badgeSeverity],background:$t[e.badgeSeverity],padding:`2px 7px`,borderRadius:4,fontFamily:Q,flexShrink:0,minWidth:72,textAlign:`center`},children:e.badge}),e.sublabel&&(0,n.jsx)(`span`,{style:{...$,flexShrink:0,minWidth:80,textAlign:`right`},children:e.sublabel})]},t))})}var nn={red:Z.red,amber:Z.amber,green:Z.green};function rn({items:e=[]}){return(0,n.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:e.map((e,t)=>{let r=nn[e.severity];return(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`flex-start`,gap:10,padding:`9px 12px`,background:r+`0A`,border:`1px solid ${r}25`},children:[(0,n.jsx)(`span`,{style:{width:7,height:7,borderRadius:`50%`,background:r,flexShrink:0,marginTop:5}}),(0,n.jsx)(`span`,{style:{flex:1,...$},children:e.text}),(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:r,background:r+`20`,padding:`2px 7px`,borderRadius:4,fontFamily:Q,flexShrink:0},children:e.tag}),(0,n.jsx)(`span`,{style:{...$,flexShrink:0,marginTop:1},children:e.date})]},t)})})}function an({columns:e=[],rows:t=[]}){return(0,n.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:5},children:[(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`0 12px 6px`,borderBottom:`1px solid ${Z.border}`},children:[(0,n.jsx)(`div`,{style:{minWidth:64}}),e.map((e,t)=>(0,n.jsx)(`div`,{style:{flex:1,fontSize:18,fontWeight:500,color:Z.t2,fontFamily:Q,textTransform:`uppercase`,letterSpacing:.6},children:e},t))]}),t.map((e,t)=>(0,n.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10,padding:`8px 12px`,background:Z.bg,border:`1px solid ${Z.border}`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:600,color:Z.t2,background:(e.color??Z.t4)+`1A`,padding:`2px 8px`,borderRadius:4,fontFamily:Q,flexShrink:0,minWidth:64,textAlign:`center`},children:e.label}),e.cells.map((t,r)=>(0,n.jsx)(`span`,{style:{flex:1,fontSize:18,fontWeight:500,color:e.color??Z.t1,fontFamily:Q},children:t},r))]},t))]})}function on({block:e}){if(!e)return null;switch(e.type){case`stats`:return(0,n.jsx)(Gt,{items:e.items});case`ranked`:return(0,n.jsx)(Kt,{items:e.items});case`chips`:return(0,n.jsx)(qt,{items:e.items});case`badges`:return(0,n.jsx)(Yt,{items:e.items});case`dot-strip`:return(0,n.jsx)(Xt,{min:e.min,max:e.max,unit:e.unit,dots:e.dots,chips:e.chips});case`proportion`:return(0,n.jsx)(Zt,{leftPct:e.leftPct,leftLabel:e.leftLabel,leftValue:e.leftValue,leftColor:e.leftColor,rightPct:e.rightPct,rightLabel:e.rightLabel,rightValue:e.rightValue,rightColor:e.rightColor,chips:e.chips});case`ring`:return(0,n.jsx)(Qt,{pct:e.pct,label:e.label,color:e.color,chips:e.chips});case`scorecard-rows`:return(0,n.jsx)(tn,{items:e.items});case`flags-list`:return(0,n.jsx)(rn,{items:e.items});case`comparison-rows`:return(0,n.jsx)(an,{columns:e.columns,rows:e.rows});default:return null}}var sn=`'Satoshi Variable', 'DM Sans', sans-serif`,cn={color:`#C2C2C2`,fontFamily:sn,fontSize:18,fontWeight:400,lineHeight:1.65};function ln({text:e}){return(0,n.jsxs)(`div`,{style:{padding:`8px 0px`,border:`transparent`,borderRadius:5,background:`transparent`},children:[(0,n.jsx)(`span`,{style:{fontSize:18,fontWeight:500,color:i.t1,fontFamily:sn,lineHeight:1.65,marginRight:8},children:`Takeaway`}),(0,n.jsx)(`span`,{style:{...cn},children:e})]})}exports.AreaChart=j,exports.BarChart=ee,exports.ChartFrame=r,exports.DonutChart=Ht,exports.KeyHighlights=on,exports.LineChart=Me,exports.MiniBars=Fe,exports.PieChart=We,exports.ProcessSankey=et,exports.RankingSankey=tt,exports.SankeySvg=Ke,exports.SeriesChart=A,exports.Takeaway=ln,exports.Trend=_t,exports.TrendChart=Tt,exports.VisualizationRenderer=It,exports.cleanupVisualizationMounts=zt,exports.hydrateVisualizationMounts=Bt,exports.serializeVisualizationConfig=Vt;
package/dist/index.js CHANGED
@@ -504,11 +504,7 @@ var L = 680, R = 42, oe = 10, se = 24, ce = 24, le = 8, ue = [
504
504
  u.amber,
505
505
  u.red
506
506
  ];
507
- function de(e) {
508
- let t = Math.abs(e), n = e < 0 ? "-" : "";
509
- return t >= 1e6 ? `${n}£${(t / 1e6).toFixed(1)}M` : t >= 1e3 ? `${n}£${(t / 1e3).toFixed(1)}K` : `${n}£${t.toFixed(0)}`;
510
- }
511
- function fe({ items: e = [], "data-testid": t }) {
507
+ function de({ items: e = [], "data-testid": t }) {
512
508
  let r = a(null), l = a(0), d = a(/* @__PURE__ */ new Map()), [m, g] = o(!1), _ = i(() => e.filter((e) => typeof e == "object" && !!e), [e]), S = i(() => [..._].sort((e, t) => (t.percentage ?? 0) - (e.percentage ?? 0)), [_]), E = i(() => m ? S : S.slice(0, le), [S, m]), O = E.length, k = se + ce + O * R + Math.max(0, O - 1) * oe, { hoveredRef: A, tooltip: j, hitZonesRef: M } = w(r, {
513
509
  width: L,
514
510
  height: k
@@ -536,10 +532,10 @@ function fe({ items: e = [], "data-testid": t }) {
536
532
  let m = {
537
533
  label: r.name,
538
534
  value: `${r.percentage ?? 0}% commitment`,
539
- sublabel: `Base: ${de(r.base ?? 0)} · Variations: ${de(r.variation ?? 0)}`,
535
+ sublabel: `Base: ${r.baseLabel ?? String(r.base ?? 0)} · Variations: ${r.variationLabel ?? String(r.variation ?? 0)}`,
540
536
  color: o
541
537
  };
542
- T(M.current, r.id, u, c + R / 2, 14, m), t.font = p.font, t.fillStyle = h(o, .9 + s * .1), t.textAlign = "left", t.textBaseline = "middle", t.fillText(`${r.percentage ?? 0}%`, u + 10, c + R / 2), t.font = `${s > 0 ? "bold " : ""}` + f.font, t.fillStyle = s > 0 ? o : f.color, t.textAlign = "right", t.fillText(r.abbreviation ?? r.name.slice(0, 6), n - 8, c + R / 2);
538
+ T(M.current, r.id, u, c + R / 2, 14, m), t.font = p.font, t.fillStyle = h(o, .9 + s * .1), t.textAlign = "left", t.textBaseline = "middle", t.fillText(`${r.percentage ?? 0}%`, u + 10, c + R / 2), t.font = `${s > 0 ? "bold " : ""}` + f.font, t.fillStyle = s > 0 ? o : f.color, t.textAlign = "right", t.fillText(r.abbreviation ?? r.name?.slice(0, 6) ?? "", n - 8, c + R / 2);
543
539
  }), t.strokeStyle = h(u.t3, .3), t.lineWidth = 1, t.setLineDash([]), t.beginPath(), t.moveTo(n + a, se), t.lineTo(n + a, se + (O - 1) * (R + oe) + R), t.stroke(), x(t, L, k, e, .015), o = requestAnimationFrame(s);
544
540
  };
545
541
  return s(), () => cancelAnimationFrame(o);
@@ -578,18 +574,18 @@ function fe({ items: e = [], "data-testid": t }) {
578
574
  }
579
575
  //#endregion
580
576
  //#region src/components/semiCircularGaugeChart/SemiCircularGaugeChart.tsx
581
- var pe = 480, me = 340;
582
- function he({ value: e, confirmed: t, total: r, "data-testid": i }) {
577
+ var fe = 480, pe = 340;
578
+ function me({ value: e, confirmed: t, total: r, "data-testid": i }) {
583
579
  let o = a(null), c = a(0);
584
580
  return n(() => {
585
581
  let n = o.current;
586
582
  if (!n) return;
587
- let i = v(n, pe, me);
583
+ let i = v(n, fe, pe);
588
584
  c.current = 0;
589
- let a = pe / 2, s = Math.PI, l = 2 * Math.PI, d = Math.PI, p, g = () => {
585
+ let a = fe / 2, s = Math.PI, l = 2 * Math.PI, d = Math.PI, p, g = () => {
590
586
  c.current++;
591
587
  let n = c.current;
592
- i.clearRect(0, 0, pe, me), i.letterSpacing = f.letterSpacing;
588
+ i.clearRect(0, 0, fe, pe), i.letterSpacing = f.letterSpacing;
593
589
  let o = D(Math.min(n / 80, 1)), _ = A(Math.min(n / 72, 1));
594
590
  i.beginPath(), i.arc(a, 220, 120, s, l), i.strokeStyle = h(u.bd, .35), i.lineWidth = 46, i.stroke(), [
595
591
  {
@@ -627,10 +623,10 @@ function he({ value: e, confirmed: t, total: r, "data-testid": i }) {
627
623
  let n = a + Math.cos(t) * 166, r = 220 + Math.sin(t) * 166;
628
624
  i.font = f.font, i.fillStyle = f.color, i.textAlign = "center", i.fillText(e, n, r + 3);
629
625
  });
630
- let v = s + e / 100 * d * o, b = e >= 66 ? u.green : e >= 33 ? u.amber : u.red;
631
- y(i, a + Math.cos(v) * 194 / 2, 220 + Math.sin(v) * 194 / 2, 18, b, .35 * o), i.beginPath(), i.arc(a, 220, 194 / 2, s, v), i.strokeStyle = h(b, .7 * o), i.lineWidth = 38, i.lineCap = "round", i.stroke(), i.lineCap = "butt";
632
- let x = s + e / 100 * d * _, S = a + Math.cos(x) * 82, C = 220 + Math.sin(x) * 82, w = a - Math.cos(x) * 14, T = 220 - Math.sin(x) * 14;
633
- i.strokeStyle = h(b, .18 * _), i.lineWidth = 6, i.lineCap = "round", i.beginPath(), i.moveTo(w, T), i.lineTo(S, C), i.stroke(), i.strokeStyle = h(u.t1, .92 * _), i.lineWidth = 2, i.lineCap = "round", i.beginPath(), i.moveTo(w, T), i.lineTo(S, C), i.stroke(), i.beginPath(), i.arc(S, C, 3, 0, Math.PI * 2), i.fillStyle = h(b, .9 * _), i.fill(), y(i, a, 220, 20, b, .25 * _), i.beginPath(), i.arc(a, 220, 9, 0, Math.PI * 2), i.strokeStyle = h(b, .5 * _), i.lineWidth = 1.5, i.stroke(), i.beginPath(), i.arc(a, 220, 5, 0, Math.PI * 2), i.fillStyle = u.t1, i.fill(), o > .5 && (i.globalAlpha = Math.min(1, (o - .5) / .5), i.font = "500 24px 'Satoshi Variable', 'DM Sans', sans-serif", i.fillStyle = b, i.textAlign = "center", i.fillText(`${Math.round(e * _)}%`, a, 182), i.globalAlpha = 1), o > .7 && (i.globalAlpha = Math.min(1, (o - .7) / .3), i.font = m.font, i.fillStyle = m.color, i.textAlign = "center", i.fillText("NCEs confirmed", a, 252), i.font = m.font, i.fillStyle = m.color, i.fillText(`${t} of ${r} NCEs are confirmed compensation events`, a, 272), i.globalAlpha = 1);
626
+ let v = e ?? 0, b = s + v / 100 * d * o, x = v >= 66 ? u.green : v >= 33 ? u.amber : u.red;
627
+ y(i, a + Math.cos(b) * 194 / 2, 220 + Math.sin(b) * 194 / 2, 18, x, .35 * o), i.beginPath(), i.arc(a, 220, 194 / 2, s, b), i.strokeStyle = h(x, .7 * o), i.lineWidth = 38, i.lineCap = "round", i.stroke(), i.lineCap = "butt";
628
+ let S = s + v / 100 * d * _, C = a + Math.cos(S) * 82, w = 220 + Math.sin(S) * 82, T = a - Math.cos(S) * 14, E = 220 - Math.sin(S) * 14;
629
+ i.strokeStyle = h(x, .18 * _), i.lineWidth = 6, i.lineCap = "round", i.beginPath(), i.moveTo(T, E), i.lineTo(C, w), i.stroke(), i.strokeStyle = h(u.t1, .92 * _), i.lineWidth = 2, i.lineCap = "round", i.beginPath(), i.moveTo(T, E), i.lineTo(C, w), i.stroke(), i.beginPath(), i.arc(C, w, 3, 0, Math.PI * 2), i.fillStyle = h(x, .9 * _), i.fill(), y(i, a, 220, 20, x, .25 * _), i.beginPath(), i.arc(a, 220, 9, 0, Math.PI * 2), i.strokeStyle = h(x, .5 * _), i.lineWidth = 1.5, i.stroke(), i.beginPath(), i.arc(a, 220, 5, 0, Math.PI * 2), i.fillStyle = u.t1, i.fill(), o > .5 && (i.globalAlpha = Math.min(1, (o - .5) / .5), i.font = "500 24px 'Satoshi Variable', 'DM Sans', sans-serif", i.fillStyle = x, i.textAlign = "center", i.fillText(`${Math.round(v * _)}%`, a, 182), i.globalAlpha = 1), o > .7 && (i.globalAlpha = Math.min(1, (o - .7) / .3), i.font = m.font, i.fillStyle = m.color, i.textAlign = "center", i.fillText("NCEs confirmed", a, 252), i.font = m.font, i.fillStyle = m.color, i.fillText(`${t ?? 0} of ${r ?? 0} NCEs are confirmed compensation events`, a, 272), i.globalAlpha = 1);
634
630
  for (let e = 0; e <= 10; e++) {
635
631
  let t = s + e / 10 * d;
636
632
  if (i.strokeStyle = h(u.bd, .5), i.lineWidth = e % 5 == 0 ? 1.5 : .8, i.beginPath(), i.moveTo(a + Math.cos(t) * 122, 220 + Math.sin(t) * 122), i.lineTo(a + Math.cos(t) * 128, 220 + Math.sin(t) * 128), i.stroke(), e % 5 == 0) {
@@ -649,16 +645,16 @@ function he({ value: e, confirmed: t, total: r, "data-testid": i }) {
649
645
  "data-testid": i,
650
646
  style: {
651
647
  position: "relative",
652
- width: pe,
653
- height: me
648
+ width: fe,
649
+ height: pe
654
650
  },
655
651
  children: /* @__PURE__ */ s("canvas", {
656
652
  ref: o,
657
653
  role: "img",
658
654
  "aria-label": `Compensation event gauge — ${e}% of NCEs confirmed as compensation events`,
659
655
  style: {
660
- width: pe,
661
- height: me,
656
+ width: fe,
657
+ height: pe,
662
658
  display: "block"
663
659
  }
664
660
  })
@@ -666,7 +662,7 @@ function he({ value: e, confirmed: t, total: r, "data-testid": i }) {
666
662
  }
667
663
  //#endregion
668
664
  //#region src/canvas/useCanvasLoop.ts
669
- function ge(e, t, r, i, o = !0, s = {}) {
665
+ function he(e, t, r, i, o = !0, s = {}) {
670
666
  let c = a(0), { easing: l = D, durationFrames: u = 48 } = s;
671
667
  n(() => {
672
668
  let n = e.current;
@@ -698,40 +694,40 @@ function ge(e, t, r, i, o = !0, s = {}) {
698
694
  }
699
695
  //#endregion
700
696
  //#region src/components/multiMetricConstellationChart/MultiMetricConstellationChart.tsx
701
- var z = 780, _e = 234, ve = 130, ye = 52, be = [
697
+ var z = 780, ge = 234, _e = 130, ve = 52, ye = [
702
698
  u.blue,
703
699
  u.amber,
704
700
  u.purple,
705
701
  u.green
706
- ], xe = [
702
+ ], be = [
707
703
  "Base Value",
708
704
  "Variations",
709
705
  "Commitment"
710
- ], Se = [
706
+ ], xe = [
711
707
  "Base",
712
708
  "Var",
713
709
  "Commit"
714
710
  ];
715
- function Ce({ items: e = [], "data-testid": t }) {
711
+ function Se({ items: e = [], "data-testid": t }) {
716
712
  let n = a(null), r = a(/* @__PURE__ */ new Map()), { hoveredRef: o, tooltip: l, hitZonesRef: d } = w(n, {
717
713
  width: z,
718
- height: _e
714
+ height: ge
719
715
  }), p = i(() => e.filter((e) => typeof e == "object" && !!e), [e]), g = i(() => {
720
716
  let e = Math.max(...p.map((e) => e.base ?? 0)), t = Math.max(...p.map((e) => e.variation ?? 0));
721
717
  return p.map((n, r) => {
722
- let i = z * (.12 + r * .19), a = ve, o = Math.min(z * .075, ye), s = be[r % be.length], c = [
718
+ let i = z * (.12 + r * .19), a = _e, o = Math.min(z * .075, ve), s = ye[r % ye.length], c = [
723
719
  (n.base ?? 0) / (e || 1) * 100,
724
720
  (n.variation ?? 0) / (t || 1) * 100,
725
721
  n.percentage ?? 0
726
722
  ], l = [
727
- `£${n.base ?? 0}M`,
728
- `£${n.variation ?? 0}M`,
723
+ n.baseLabel ?? String(n.base ?? 0),
724
+ n.variationLabel ?? String(n.variation ?? 0),
729
725
  `${n.percentage ?? 0}%`
730
726
  ], u = c.map((e, t) => {
731
- let n = -Math.PI / 2 + t / xe.length * Math.PI * 2, r = e / 100, s = o * Math.max(.08, r);
727
+ let n = -Math.PI / 2 + t / be.length * Math.PI * 2, r = e / 100, s = o * Math.max(.08, r);
732
728
  return {
733
- name: xe[t],
734
- short: Se[t],
729
+ name: be[t],
730
+ short: xe[t],
735
731
  label: l[t],
736
732
  val: Math.round(e),
737
733
  x: i + Math.cos(n) * s,
@@ -751,8 +747,8 @@ function Ce({ items: e = [], "data-testid": t }) {
751
747
  };
752
748
  });
753
749
  }, [p]);
754
- return ge(n, z, _e, (e, t, n) => {
755
- N(r.current, o.current), d.current = [], b(e, z, _e, n, 30), g.forEach((t, i) => {
750
+ return he(n, z, ge, (e, t, n) => {
751
+ N(r.current, o.current), d.current = [], b(e, z, ge, n, 30), g.forEach((t, i) => {
756
752
  let a = t.color, o = `constellation-${i}`, s = r.current.get(o) ?? 0;
757
753
  e.beginPath(), e.arc(t.cx, t.cy, t.baseR + 5, 0, Math.PI * 2), e.strokeStyle = h(u.bd, .08 + .08 * s), e.lineWidth = .5, e.stroke(), e.beginPath(), t.stars.forEach((t, n) => {
758
754
  n === 0 ? e.moveTo(t.x, t.y) : e.lineTo(t.x, t.y);
@@ -768,21 +764,21 @@ function Ce({ items: e = [], "data-testid": t }) {
768
764
  });
769
765
  }), s > 0 && y(e, t.cx, t.cy, 16 * s, a, .15 * s), e.beginPath(), e.arc(t.cx, t.cy, t.baseR + 12, 0, Math.PI * 2), e.strokeStyle = h(a, .1 + j(n, .03, 5e-4) * .05), e.lineWidth = 1, e.stroke(), e.font = f.font, e.textAlign = "center", e.textBaseline = "alphabetic", e.fillStyle = s > 0 ? t.color : f.color, e.fillText(t.abbreviation ?? t.name.slice(0, 6), t.cx, t.cy + t.baseR + 26), T(d.current, o, t.cx, t.cy, t.baseR + 5, {
770
766
  label: t.name,
771
- value: `£${t.total ?? 0}M total`,
767
+ value: `${t.totalLabel ?? String(t.total ?? 0)} total`,
772
768
  sublabel: `${t.percentage ?? 0}% committed · scatter ${t.scatter.toFixed(1)}`,
773
769
  color: a
774
770
  });
775
- }), e.font = m.font, e.textAlign = "center", e.textBaseline = "middle", e.fillStyle = m.color, e.fillText("▲ top = Base value · ▼▸ lower-right = Variations · ◂▼ lower-left = Commitment % · hover stars for details", z / 2, _e - 14), x(e, z, _e, n, .012);
771
+ }), e.font = m.font, e.textAlign = "center", e.textBaseline = "middle", e.fillStyle = m.color, e.fillText("▲ top = Base value · ▼▸ lower-right = Variations · ◂▼ lower-left = Commitment % · hover stars for details", z / 2, ge - 14), x(e, z, ge, n, .012);
776
772
  }, !0), g.length === 0 ? /* @__PURE__ */ s(I, {
777
773
  width: z,
778
- height: _e,
774
+ height: ge,
779
775
  "data-testid": t
780
776
  }) : /* @__PURE__ */ c("div", {
781
777
  "data-testid": t,
782
778
  style: {
783
779
  position: "relative",
784
780
  width: z,
785
- height: _e
781
+ height: ge
786
782
  },
787
783
  children: [/* @__PURE__ */ s("canvas", {
788
784
  ref: n,
@@ -790,19 +786,19 @@ function Ce({ items: e = [], "data-testid": t }) {
790
786
  "aria-label": "Contract value breakdown per contractor — multi-KPI constellation chart",
791
787
  style: {
792
788
  width: z,
793
- height: _e,
789
+ height: ge,
794
790
  display: "block"
795
791
  }
796
792
  }), /* @__PURE__ */ s(C, {
797
793
  ...l,
798
794
  parentW: z,
799
- parentH: _e
795
+ parentH: ge
800
796
  })]
801
797
  });
802
798
  }
803
799
  //#endregion
804
800
  //#region src/components/stackedHorizontalBarChart/StackedHorizontalBarChart.tsx
805
- var we = 680, Te = 220, Ee = 8, De = [
801
+ var Ce = 680, we = 220, Te = 8, Ee = [
806
802
  u.blue,
807
803
  u.amber,
808
804
  u.purple,
@@ -812,42 +808,48 @@ var we = 680, Te = 220, Ee = 8, De = [
812
808
  right: 80,
813
809
  top: 16,
814
810
  bottom: 38
815
- }, Oe = 88, V = 18;
811
+ }, De = 150, V = 18;
812
+ function Oe(e, t, n) {
813
+ if (e.measureText(t).width <= n) return t;
814
+ let r = t;
815
+ for (; r.length > 0 && e.measureText(r + "…").width > n;) r = r.slice(0, -1);
816
+ return r + "…";
817
+ }
816
818
  function ke(e) {
817
819
  let t = Math.abs(e), n = e < 0 ? "-" : "";
818
820
  return t >= 1e6 ? `${n}£${(t / 1e6).toFixed(1)}M` : t >= 1e3 ? `${n}£${(t / 1e3).toFixed(1)}K` : `${n}£${t.toFixed(0)}`;
819
821
  }
820
822
  function Ae({ data: e, "data-testid": t }) {
821
- let n = a(null), r = a(/* @__PURE__ */ new Map()), [i, l] = o(!1), { items: d = [], totals: g } = e, _ = d.filter((e) => typeof e == "object" && !!e), v = [..._].sort((e, t) => (t.total ?? 0) - (e.total ?? 0)), b = i ? v : v.slice(0, Ee), x = b.length, S = Math.max(...v.map((e) => Math.abs(e.total ?? 0)), 1), T = Math.max(Te, B.top + B.bottom + x * V + Math.max(0, x - 1) * 8), D = we - B.left - Oe - B.right, k = x > 1 ? (T - B.top - B.bottom - x * V) / (x - 1) : 0, A = _.length === 0, { hoveredRef: j, tooltip: P, hitZonesRef: F } = w(n, {
822
- width: we,
823
+ let n = a(null), r = a(/* @__PURE__ */ new Map()), [i, l] = o(!1), { items: d = [], totals: g } = e, _ = d.filter((e) => typeof e == "object" && !!e), v = [..._].sort((e, t) => (t.total ?? 0) - (e.total ?? 0)), b = i ? v : v.slice(0, Te), x = b.length, S = Math.max(...v.map((e) => Math.abs(e.total ?? 0)), 1), T = Math.max(we, B.top + B.bottom + x * V + Math.max(0, x - 1) * 8), D = Ce - B.left - De - B.right, k = x > 1 ? (T - B.top - B.bottom - x * V) / (x - 1) : 0, A = _.length === 0, { hoveredRef: j, tooltip: P, hitZonesRef: F } = w(n, {
824
+ width: Ce,
823
825
  height: T
824
826
  });
825
- return ge(n, we, T, (e, t) => {
827
+ return he(n, Ce, T, (e, t) => {
826
828
  N(r.current, j.current), F.current = [], b.forEach((n, i) => {
827
- let a = De[i % De.length], o = M(t, i, x, O), s = B.top + i * (V + k), c = B.left + Oe, l = r.current.get(n.id) ?? 0, d = Math.max(n.base ?? 0, 0), m = Math.max(n.total ?? 0, 0), g = d / S * D * o, _ = m / S * D * o, v = _ - g;
828
- e.font = f.font, e.fillStyle = l > 0 ? a : f.color, e.textAlign = "right", e.textBaseline = "middle", e.fillText(n.abbreviation ?? n.name.slice(0, 6), c - 8, s + V / 2), e.fillStyle = h(u.bd, .25), e.beginPath(), e.roundRect(c, s, D, V, 4), e.fill(), g > 0 && (l > 0 && y(e, c + g / 2, s + V / 2, g * .3, a, .1 * l), e.fillStyle = h(a, .5 + l * .15), e.beginPath(), e.roundRect(c, s, g, V, 4), e.fill()), v > 2 && (e.fillStyle = h(a, .22 + l * .08), e.beginPath(), e.roundRect(c + g, s, v, V, [
829
+ let a = Ee[i % Ee.length], o = M(t, i, x, O), s = B.top + i * (V + k), c = B.left + De, l = r.current.get(n.id) ?? 0, d = Math.max(n.base ?? 0, 0), m = Math.max(n.total ?? 0, 0), g = d / S * D * o, _ = m / S * D * o, v = _ - g;
830
+ e.font = f.font, e.fillStyle = l > 0 ? a : f.color, e.textAlign = "right", e.textBaseline = "middle", e.fillText(Oe(e, n.name ?? "", De - 16), c - 8, s + V / 2), e.fillStyle = h(u.bd, .25), e.beginPath(), e.roundRect(c, s, D, V, 4), e.fill(), g > 0 && (l > 0 && y(e, c + g / 2, s + V / 2, g * .3, a, .1 * l), e.fillStyle = h(a, .5 + l * .15), e.beginPath(), e.roundRect(c, s, g, V, 4), e.fill()), v > 2 && (e.fillStyle = h(a, .22 + l * .08), e.beginPath(), e.roundRect(c + g, s, v, V, [
829
831
  0,
830
832
  4,
831
833
  4,
832
834
  0
833
- ]), e.fill(), e.setLineDash([2, 3]), e.strokeStyle = h(a, .55), e.lineWidth = 1, e.beginPath(), e.moveTo(c + g, s + 3), e.lineTo(c + g, s + V - 3), e.stroke(), e.setLineDash([])), l > 0 && _ > 0 && (e.strokeStyle = h(a, .5 * l), e.lineWidth = 1, e.setLineDash([]), e.beginPath(), e.roundRect(c, s, _, V, 4), e.stroke()), o > .35 && (e.globalAlpha = Math.min(1, (o - .35) / .4), e.font = p.font, e.fillStyle = l > 0 ? a : p.color, e.textAlign = "left", e.textBaseline = "middle", e.fillText(ke(n.total ?? 0), c + _ + 6, s + V / 2), e.globalAlpha = 1), E(F.current, n.id, c, s, Math.max(_, 1), V, {
835
+ ]), e.fill(), e.setLineDash([2, 3]), e.strokeStyle = h(a, .55), e.lineWidth = 1, e.beginPath(), e.moveTo(c + g, s + 3), e.lineTo(c + g, s + V - 3), e.stroke(), e.setLineDash([])), l > 0 && _ > 0 && (e.strokeStyle = h(a, .5 * l), e.lineWidth = 1, e.setLineDash([]), e.beginPath(), e.roundRect(c, s, _, V, 4), e.stroke()), o > .35 && (e.globalAlpha = Math.min(1, (o - .35) / .4), e.font = p.font, e.fillStyle = l > 0 ? a : p.color, e.textAlign = "left", e.textBaseline = "middle", e.fillText(n.totalLabel ?? ke(n.total ?? 0), c + _ + 6, s + V / 2), e.globalAlpha = 1), E(F.current, n.id, c, s, Math.max(_, 1), V, {
834
836
  label: n.name,
835
- value: `${ke(n.total ?? 0)} total`,
836
- sublabel: `Base ${ke(n.base ?? 0)} + Var ${ke(n.variation ?? 0)} · ${n.percentage ?? 0}% committed`,
837
+ value: `${n.totalLabel ?? ke(n.total ?? 0)} total`,
838
+ sublabel: `Base ${n.baseLabel ?? ke(n.base ?? 0)} + Var ${n.variationLabel ?? ke(n.variation ?? 0)} · ${n.percentage ?? 0}% committed`,
837
839
  color: a
838
840
  });
839
841
  });
840
842
  let n = T - 14;
841
- e.textBaseline = "middle", e.font = m.font, e.textAlign = "left", e.fillStyle = h(u.blue, .5), e.beginPath(), e.roundRect(B.left + Oe, n - 3, 14, 6, 2), e.fill(), e.fillStyle = m.color, e.fillText("base value", B.left + Oe + 18, n), e.fillStyle = h(u.blue, .22), e.beginPath(), e.roundRect(B.left + Oe + 94, n - 3, 14, 6, 2), e.fill(), e.setLineDash([2, 3]), e.strokeStyle = h(u.blue, .5), e.lineWidth = .5, e.beginPath(), e.moveTo(B.left + Oe + 101, n - 3), e.lineTo(B.left + Oe + 101, n + 3), e.stroke(), e.setLineDash([]), e.fillStyle = m.color, e.fillText("approved variations", B.left + Oe + 112, n), e.font = m.font, e.textAlign = "right", e.fillStyle = m.color, e.fillText(`Portfolio: ${ke(g?.total ?? 0)}`, we - 8, n);
843
+ e.textBaseline = "middle", e.font = m.font, e.textAlign = "left", e.fillStyle = h(u.blue, .5), e.beginPath(), e.roundRect(B.left + De, n - 3, 14, 6, 2), e.fill(), e.fillStyle = m.color, e.fillText("base value", B.left + De + 18, n), e.fillStyle = h(u.blue, .22), e.beginPath(), e.roundRect(B.left + De + 94, n - 3, 14, 6, 2), e.fill(), e.setLineDash([2, 3]), e.strokeStyle = h(u.blue, .5), e.lineWidth = .5, e.beginPath(), e.moveTo(B.left + De + 101, n - 3), e.lineTo(B.left + De + 101, n + 3), e.stroke(), e.setLineDash([]), e.fillStyle = m.color, e.fillText("approved variations", B.left + De + 112, n), e.font = m.font, e.textAlign = "right", e.fillStyle = m.color, e.fillText(`Portfolio: ${ke(g?.total ?? 0)}`, Ce - 8, n);
842
844
  }, !0, { easing: O }), A ? /* @__PURE__ */ s(I, {
843
- width: we,
844
- height: Te,
845
+ width: Ce,
846
+ height: we,
845
847
  message: "No contract data available",
846
848
  "data-testid": t
847
849
  }) : /* @__PURE__ */ c("div", {
848
850
  "data-testid": t,
849
851
  style: {
850
- width: we,
852
+ width: Ce,
851
853
  transition: "all 0.25s ease"
852
854
  },
853
855
  children: [/* @__PURE__ */ c("div", {
@@ -857,17 +859,17 @@ function Ae({ data: e, "data-testid": t }) {
857
859
  role: "img",
858
860
  "aria-label": "Total contract value per contractor — horizontal bar chart",
859
861
  style: {
860
- width: we,
862
+ width: Ce,
861
863
  height: T,
862
864
  display: "block",
863
865
  borderRadius: 8
864
866
  }
865
867
  }), /* @__PURE__ */ s(C, {
866
868
  ...P,
867
- parentW: we,
869
+ parentW: Ce,
868
870
  parentH: T
869
871
  })]
870
- }), _.length > Ee && /* @__PURE__ */ s("div", {
872
+ }), _.length > Te && /* @__PURE__ */ s("div", {
871
873
  style: { marginTop: 8 },
872
874
  children: /* @__PURE__ */ s(ae, {
873
875
  expanded: i,
@@ -902,15 +904,17 @@ function Pe({ items: e = [], "data-testid": t }) {
902
904
  let n = t === m.current ? 1 : 0, r = e + (n - e) * .12;
903
905
  Math.abs(r - n) < .005 ? n === 0 ? l.current.delete(t) : l.current.set(t, 1) : l.current.set(t, r);
904
906
  }), m.current && !l.current.has(m.current) && l.current.set(m.current, 0), b.forEach((n, r) => {
905
- let o = r === 0, c = r === 0 ? u.red : r === 1 ? u.amber : d[r % d.length], f = g + r * (i + Me), m = l.current.get(n.id) ?? 0, v = m * 8, b = f - v / 2, x = i + v, C = o ? j(e, .04, 3e-4) * .06 + .06 : 0;
906
- t.fillStyle = h(c, .08 + m * .07), t.beginPath(), t.roundRect(b, s, x, a, 6), t.fill(), t.strokeStyle = h(c, .2 + m * .4 + C), t.lineWidth = o ? 1.5 : 1, t.stroke(), (m > .01 || o) && y(t, b + x / 2, s + a / 2, x * .55, c, C + m * .14), t.font = p.font, t.textAlign = "left", t.textBaseline = "top", t.fillStyle = h(c, .5 + m * .35), t.fillText(`#${r + 1}`, b + 7, s + 6);
907
- let w = Math.min(i * .28, a * .32, 72), T = b + x / 2, D = s + a * .38, O = t.createRadialGradient(T, D - w * .2, 0, T, D, w);
908
- O.addColorStop(0, h(c, .5 + m * .2)), O.addColorStop(1, h(c, .2 + m * .1)), t.beginPath(), t.arc(T, D, w, 0, Math.PI * 2), t.fillStyle = O, t.fill(), t.strokeStyle = h(c, .4 + m * .3), t.lineWidth = 1, t.stroke(), t.font = p.font, t.textAlign = "center", t.textBaseline = "middle", t.fillStyle = h(u.t1, .9), t.fillText(n.abbreviation ?? n.name.slice(0, 6), T, D), t.font = p.font, t.textBaseline = "alphabetic", t.fillStyle = h(c, .9 + m * .1), t.fillText(String(n.count ?? 0), T, s + a * .76);
909
- let k = Math.round((n.count ?? 0) / (S || 1) * 100), A = Ne[r] ?? "Low exposure";
910
- E(_.current, n.id, f, s, i, a, {
907
+ let o = r === 0, c = r === 0 ? u.red : r === 1 ? u.amber : d[r % d.length], m = g + r * (i + Me), v = l.current.get(n.id) ?? 0, b = v * 8, x = m - b / 2, C = i + b, w = o ? j(e, .04, 3e-4) * .06 + .06 : 0;
908
+ t.fillStyle = h(c, .08 + v * .07), t.beginPath(), t.roundRect(x, s, C, a, 6), t.fill(), t.strokeStyle = h(c, .2 + v * .4 + w), t.lineWidth = o ? 1.5 : 1, t.stroke(), (v > .01 || o) && y(t, x + C / 2, s + a / 2, C * .55, c, w + v * .14), t.font = p.font, t.textAlign = "left", t.textBaseline = "top", t.fillStyle = h(c, .5 + v * .35), t.fillText(`#${r + 1}`, x + 7, s + 6);
909
+ let T = Math.min(i * .28, a * .32, 72), D = x + C / 2, O = s + a * .38, k = t.createRadialGradient(D, O - T * .2, 0, D, O, T);
910
+ k.addColorStop(0, h(c, .5 + v * .2)), k.addColorStop(1, h(c, .2 + v * .1)), t.beginPath(), t.arc(D, O, T, 0, Math.PI * 2), t.fillStyle = k, t.fill(), t.strokeStyle = h(c, .4 + v * .3), t.lineWidth = 1, t.stroke(), t.font = p.font, t.textAlign = "center", t.textBaseline = "middle", t.fillStyle = h(u.t1, .9), t.fillText(n.abbreviation ?? n.name?.slice(0, 6) ?? "", D, O);
911
+ let A = n.label ?? String(n.count ?? 0);
912
+ t.font = p.font, t.textBaseline = "alphabetic", t.fillStyle = h(c, .9 + v * .1), t.fillText(A, D, s + a * .76), n.label || (t.font = f.font, t.fillStyle = f.color, t.fillText("open EWs", D, s + a * .88));
913
+ let M = Math.round((n.count ?? 0) / (S || 1) * 100), N = Ne[r] ?? "Low exposure";
914
+ E(_.current, n.id, m, s, i, a, {
911
915
  label: n.name,
912
- value: `${n.count ?? 0} · ${k}% of total`,
913
- sublabel: `Rank #${r + 1} · ${A}`,
916
+ value: `${A ?? 0} open · ${M}% of total`,
917
+ sublabel: `Rank #${r + 1} · ${N}`,
914
918
  color: c
915
919
  });
916
920
  }), x(t, H, U, e, .015), C = requestAnimationFrame(w);
@@ -930,7 +934,7 @@ function Pe({ items: e = [], "data-testid": t }) {
930
934
  children: [/* @__PURE__ */ s("canvas", {
931
935
  ref: r,
932
936
  role: "img",
933
- "aria-label": "Contractor rank — count per contractor",
937
+ "aria-label": "Contractor rank — open EW count per contractor",
934
938
  style: {
935
939
  width: H,
936
940
  height: U,
@@ -1115,77 +1119,80 @@ function ze({ rows: e = [], className: t, colors: n }) {
1115
1119
  //#endregion
1116
1120
  //#region src/components/radialFanTreeChart/RadialFanTreeChart.tsx
1117
1121
  var Be = 680, Ve = 320, He = 60, Ue = 28;
1118
- function We({ total: e = 0, items: t = [], "data-testid": r }) {
1119
- let o = a(null), l = a(/* @__PURE__ */ new Map()), m = a(0), g = i(() => t.filter((e) => typeof e == "object" && !!e), [t]), _ = i(() => Math.max(Ve, He + Math.max(0, g.length - 1) * Ue), [g.length]), { hoveredRef: b, tooltip: x, hitZonesRef: S } = w(o, {
1122
+ function We({ total: e = 0, totalLabel: t, items: r = [], "data-testid": o }) {
1123
+ let l = a(null), m = a(/* @__PURE__ */ new Map()), g = a(0), _ = i(() => r.filter((e) => typeof e == "object" && !!e), [r]), b = i(() => Math.max(Ve, He + Math.max(0, _.length - 1) * Ue), [_.length]), { hoveredRef: x, tooltip: S, hitZonesRef: E } = w(l, {
1120
1124
  width: Be,
1121
- height: _
1125
+ height: b
1122
1126
  });
1123
1127
  return n(() => {
1124
- let t = o.current;
1125
- if (!t) return;
1126
- let n = v(t, Be, _);
1127
- m.current = 0;
1128
- let r = _ / 2, i = Be - 80, a = Math.max(...g.map((e) => e.count ?? 0)), s = (_ - 60) / (g.length - 1), c = g.map((e, t) => ({
1129
- x: i,
1128
+ let n = l.current;
1129
+ if (!n) return;
1130
+ let r = v(n, Be, b);
1131
+ g.current = 0;
1132
+ let i = b / 2, a = Be - 80, o = Math.max(..._.map((e) => e.count ?? 0), 1), s = _.length > 1 ? (b - 60) / (_.length - 1) : 0, c = _.map((e, t) => ({
1133
+ x: a,
1130
1134
  y: 30 + t * s
1131
- })), x, C = () => {
1132
- m.current++;
1133
- let t = m.current;
1134
- n.clearRect(0, 0, Be, _), n.letterSpacing = f.letterSpacing;
1135
- let o = D(Math.min(t / 72, 1));
1136
- N(l.current, b.current), S.current = [], y(n, 88, r, 48 * o, u.blue, .15 * o), g.forEach((t, s) => {
1137
- let m = d[s % d.length], _ = M(o, s, g.length, D), v = c[s], b = l.current.get(t.id) ?? 0, x = Math.max(1.5, (t.count ?? 0) / a * 6);
1138
- if (_ < .01) return;
1139
- let C = 88 + (i - 88) * .4, w = r, E = 88 + (i - 88) * .6, O = v.y, k = _;
1140
- n.beginPath();
1135
+ })), S, C = () => {
1136
+ g.current++;
1137
+ let n = g.current;
1138
+ r.clearRect(0, 0, Be, b), r.letterSpacing = f.letterSpacing;
1139
+ let s = D(Math.min(n / 72, 1));
1140
+ N(m.current, x.current), E.current = [], y(r, 88, i, 48 * s, u.blue, .15 * s), _.forEach((t, n) => {
1141
+ let l = d[n % d.length], g = M(s, n, _.length, D), v = c[n], b = m.current.get(t.id) ?? 0, x = Math.max(1.5, (t.count ?? 0) / o * 6);
1142
+ if (g < .01) return;
1143
+ let S = 88 + (a - 88) * .4, C = i, w = 88 + (a - 88) * .6, O = v.y, k = g;
1144
+ r.beginPath();
1141
1145
  for (let e = 0; e <= 40; e++) {
1142
- let t = e / 40 * k, i = (1 - t) ** 3 * 88 + 3 * (1 - t) ** 2 * t * C + 3 * (1 - t) * t ** 2 * E + t ** 3 * v.x, a = (1 - t) ** 3 * r + 3 * (1 - t) ** 2 * t * w + 3 * (1 - t) * t ** 2 * O + t ** 3 * v.y;
1143
- e === 0 ? n.moveTo(i, a) : n.lineTo(i, a);
1146
+ let t = e / 40 * k, n = (1 - t) ** 3 * 88 + 3 * (1 - t) ** 2 * t * S + 3 * (1 - t) * t ** 2 * w + t ** 3 * v.x, a = (1 - t) ** 3 * i + 3 * (1 - t) ** 2 * t * C + 3 * (1 - t) * t ** 2 * O + t ** 3 * v.y;
1147
+ e === 0 ? r.moveTo(n, a) : r.lineTo(n, a);
1144
1148
  }
1145
- if (n.strokeStyle = h(m, b > 0 ? .8 : .45), n.lineWidth = x * (b > 0 ? 1.3 : 1), n.stroke(), _ > .85) {
1146
- let r = Math.min(1, (_ - .85) / .15), i = 4 + (t.count ?? 0) / a * 12;
1147
- y(n, v.x, v.y, i * 2.5, m, (.25 + b * .2) * r), n.beginPath(), n.arc(v.x, v.y, i * r, 0, Math.PI * 2), n.fillStyle = h(m, (.7 + b * .2) * r), n.fill(), T(S.current, t.id, v.x, v.y, i + 8, {
1149
+ if (r.strokeStyle = h(l, b > 0 ? .8 : .45), r.lineWidth = x * (b > 0 ? 1.3 : 1), r.stroke(), g > .85) {
1150
+ let n = Math.min(1, (g - .85) / .15), i = 4 + (t.count ?? 0) / o * 12;
1151
+ y(r, v.x, v.y, i * 2.5, l, (.25 + b * .2) * n), r.beginPath(), r.arc(v.x, v.y, i * n, 0, Math.PI * 2), r.fillStyle = h(l, (.7 + b * .2) * n), r.fill();
1152
+ let a = t.label ?? String(t.count ?? 0);
1153
+ T(E.current, t.id, v.x, v.y, i + 8, {
1148
1154
  label: t.name,
1149
- value: `${t.count ?? 0} NCEs raised`,
1150
- sublabel: `${Math.round((t.count ?? 0) / e * 100)}% of all NCEs`,
1151
- color: m
1152
- }), n.globalAlpha = r, n.font = f.font, n.textAlign = "left";
1153
- let o = t.abbreviation ?? t.name.slice(0, 6), s = ` ${t.count ?? 0}`, c = v.x + i + 6, l = v.y + 4;
1154
- n.fillStyle = b > 0 ? m : h(u.t2, .85), n.fillText(o, c, l);
1155
- let d = n.measureText(o).width;
1156
- n.font = p.font, n.fillStyle = b > 0 ? m : u.t1, n.fillText(s, c + d, l), n.globalAlpha = 1;
1155
+ value: `${a} NCEs raised`,
1156
+ sublabel: `${Math.round((t.count ?? 0) / (e || 1) * 100)}% of all NCEs`,
1157
+ color: l
1158
+ }), r.globalAlpha = n, r.font = f.font, r.textAlign = "left";
1159
+ let s = t.abbreviation ?? t.name?.slice(0, 6) ?? "", c = ` ${a}`, d = v.x + i + 6, m = v.y + 4;
1160
+ r.fillStyle = b > 0 ? l : h(u.t2, .85), r.fillText(s, d, m);
1161
+ let _ = r.measureText(s).width;
1162
+ r.font = p.font, r.fillStyle = b > 0 ? l : u.t1, r.fillText(c, d + _, m), r.globalAlpha = 1;
1157
1163
  }
1158
- }), n.beginPath(), n.arc(88, r, 32 * o, 0, Math.PI * 2), n.fillStyle = u.bgL, n.fill(), n.strokeStyle = h(u.blue, .6 * o), n.lineWidth = 2, n.stroke(), o > .4 && (n.globalAlpha = Math.min(1, (o - .4) / .4), n.font = "500 24px 'Satoshi Variable', 'DM Sans', sans-serif", n.fillStyle = u.t1, n.textAlign = "center", n.fillText(String(e), 88, r + 5), n.font = f.font, n.fillStyle = f.color, n.fillText("NCEs", 88, r + 18), n.globalAlpha = 1), x = requestAnimationFrame(C);
1164
+ }), r.beginPath(), r.arc(88, i, 32 * s, 0, Math.PI * 2), r.fillStyle = u.bgL, r.fill(), r.strokeStyle = h(u.blue, .6 * s), r.lineWidth = 2, r.stroke(), s > .4 && (r.globalAlpha = Math.min(1, (s - .4) / .4), r.font = "500 24px 'Satoshi Variable', 'DM Sans', sans-serif", r.fillStyle = u.t1, r.textAlign = "center", r.fillText(t ?? String(e), 88, i + 5), r.font = f.font, r.fillStyle = f.color, r.fillText("NCEs", 88, i + 18), r.globalAlpha = 1), S = requestAnimationFrame(C);
1159
1165
  };
1160
- return C(), () => cancelAnimationFrame(x);
1166
+ return C(), () => cancelAnimationFrame(S);
1161
1167
  }, [
1162
1168
  e,
1163
- g,
1164
- _
1165
- ]), g.length === 0 ? /* @__PURE__ */ s(I, {
1169
+ t,
1170
+ _,
1171
+ b
1172
+ ]), _.length === 0 ? /* @__PURE__ */ s(I, {
1166
1173
  width: Be,
1167
1174
  height: Ve,
1168
- "data-testid": r
1175
+ "data-testid": o
1169
1176
  }) : /* @__PURE__ */ c("div", {
1170
- "data-testid": r,
1177
+ "data-testid": o,
1171
1178
  style: {
1172
1179
  position: "relative",
1173
1180
  width: Be,
1174
- height: _
1181
+ height: b
1175
1182
  },
1176
1183
  children: [/* @__PURE__ */ s("canvas", {
1177
- ref: o,
1184
+ ref: l,
1178
1185
  role: "img",
1179
1186
  "aria-label": "NCE fault tree — NCEs per contractor as branching tree",
1180
1187
  style: {
1181
1188
  width: Be,
1182
- height: _,
1189
+ height: b,
1183
1190
  display: "block"
1184
1191
  }
1185
1192
  }), /* @__PURE__ */ s(C, {
1186
- ...x,
1193
+ ...S,
1187
1194
  parentW: Be,
1188
- parentH: _
1195
+ parentH: b
1189
1196
  })]
1190
1197
  });
1191
1198
  }
@@ -1963,7 +1970,7 @@ function Tt({ severities: e = [], "data-testid": t }) {
1963
1970
  if (!e) return;
1964
1971
  let t = v(e, J, St);
1965
1972
  l.current = 0;
1966
- let n = _.reduce((e, t) => e + t.count, 0), i = J - 28 - 28, a = St - 50 - 52, s = _.map((e) => e.count / n * i), c, m = () => {
1973
+ let n = _.reduce((e, t) => e + (t.count ?? 0), 0), i = J - 28 - 28, a = St - 50 - 52, s = _.map((e) => (e.count ?? 0) / (n || 1) * i), c, m = () => {
1967
1974
  l.current++;
1968
1975
  let e = l.current;
1969
1976
  t.clearRect(0, 0, J, St), t.letterSpacing = f.letterSpacing;
@@ -1971,19 +1978,15 @@ function Tt({ severities: e = [], "data-testid": t }) {
1971
1978
  N(o.current, d.current), g.current = [], t.strokeStyle = h(u.bd, .2), t.lineWidth = 1, t.beginPath(), t.rect(28, 50, i, a), t.stroke(), t.strokeStyle = h(u.t2, .15), t.lineWidth = 1, t.setLineDash([4, 4]), t.beginPath(), t.moveTo(J / 2, 50), t.lineTo(J / 2, 50 + a), t.stroke(), t.setLineDash([]);
1972
1979
  let v = 28;
1973
1980
  _.forEach((e, i) => {
1974
- let c = wt[e.severity] ?? u.blue, l = s[i];
1975
- l * r;
1976
- let d = o.current.get(e.severity) ?? 0, m = v + l / 2, _ = l * .85;
1977
- m - _ / 2;
1978
- let b = l * r, x = _ * r, S = m - x / 2;
1981
+ let c = wt[e.severity] ?? u.blue, l = s[i], d = o.current.get(e.severity) ?? 0, m = v + l / 2, _ = l * .85, b = l * r, x = _ * r, S = m - x / 2;
1979
1982
  if (b > 0 && (d > 0 && y(t, v + b / 2, 50 + a / 2, b * .4, c, .15 * d), t.beginPath(), t.moveTo(S, 50), t.lineTo(S + x, 50), t.lineTo(v + b, 50 + a), t.lineTo(v, 50 + a), t.closePath(), t.fillStyle = h(c, .45 + d * .25), t.fill(), t.strokeStyle = h(c, (.5 + d * .3) * r), t.lineWidth = d > 0 ? 2 : 1, t.beginPath(), t.moveTo(S, 50), t.lineTo(S + x, 50), t.stroke(), t.strokeStyle = h(c, (.3 + d * .3) * r), t.lineWidth = d > 0 ? 2 : 1, t.beginPath(), t.moveTo(v, 50 + a), t.lineTo(v + b, 50 + a), t.stroke()), E(g.current, e.severity, v, 50, l, a, {
1980
1983
  label: e.severity,
1981
1984
  value: `${e.count} Early Warnings`,
1982
- sublabel: `${Math.round(e.count / n * 100)}% of all EWs`,
1985
+ sublabel: `${Math.round((e.count ?? 0) / (n || 1) * 100)}% of all EWs`,
1983
1986
  color: c
1984
1987
  }), r > .5) {
1985
1988
  let i = Math.min(1, (r - .5) / .5), o = v + l / 2;
1986
- t.globalAlpha = i, t.font = f.font, t.fillStyle = d > 0 ? c : h(c, .9), t.textAlign = "center", t.fillText(Ct(t, e.severity, l - 12), o, 38), t.font = p.font, t.fillStyle = d > 0 ? u.t1 : h(u.t1, .85), t.fillText(String(e.count), o, 50 + a / 2 + 6), t.font = f.font, t.fillStyle = d > 0 ? c : f.color, t.fillText(`${Math.round(e.count / n * 100)}%`, o, 50 + a + 18), t.globalAlpha = 1;
1989
+ t.globalAlpha = i, t.font = f.font, t.fillStyle = d > 0 ? c : h(c, .9), t.textAlign = "center", t.fillText(Ct(t, e.severity, l - 12), o, 38), t.font = p.font, t.fillStyle = d > 0 ? u.t1 : h(u.t1, .85), t.fillText(String(e.count), o, 50 + a / 2 + 6), t.font = f.font, t.fillStyle = d > 0 ? c : f.color, t.fillText(`${Math.round((e.count ?? 0) / (n || 1) * 100)}%`, o, 50 + a + 18), t.globalAlpha = 1;
1987
1990
  }
1988
1991
  v += l;
1989
1992
  });
@@ -2035,7 +2038,7 @@ function Dt({ segments: e = [], title: t, "data-testid": r }) {
2035
2038
  if (!e) return;
2036
2039
  let t = v(e, Y, X);
2037
2040
  l.current = 0;
2038
- let n = Y * .5, r = X * .54, i = Y * .22, a = S.reduce((e, t) => e + t.count, 0), s = Math.max(...S.map((e) => e.count), 1), c, g = () => {
2041
+ let n = Y * .5, r = X * .54, i = Y * .22, a = S.reduce((e, t) => e + (t.count ?? 0), 0), s = Math.max(...S.map((e) => e.count ?? 0), 1), c, g = () => {
2039
2042
  l.current++;
2040
2043
  let e = l.current;
2041
2044
  t.clearRect(0, 0, Y, X), t.letterSpacing = f.letterSpacing, _.current = [], d.current.forEach((e, t) => {
@@ -2055,7 +2058,7 @@ function Dt({ segments: e = [], title: t, "data-testid": r }) {
2055
2058
  b.addColorStop(0, h(m, .8 + v * .2)), b.addColorStop(1, h(m, .4 + v * .1)), t.beginPath(), t.arc(l, p, g, 0, Math.PI * 2), t.fillStyle = b, t.fill(), t.font = "bold " + f.font, t.textAlign = "center", t.textBaseline = "middle", t.fillStyle = h(u.t1, .9), t.fillText(e.status, l, p), T(_.current, e.status, l, p, g + 6, {
2056
2059
  label: e.status,
2057
2060
  value: `${e.count} Early Warnings`,
2058
- sublabel: `${Math.round(e.count / a * 100)}%`,
2061
+ sublabel: `${Math.round((e.count ?? 0) / (a || 1) * 100)}%`,
2059
2062
  color: m
2060
2063
  });
2061
2064
  });
@@ -2101,7 +2104,7 @@ function Dt({ segments: e = [], title: t, "data-testid": r }) {
2101
2104
  //#region src/components/trendChart/TrendChart.tsx
2102
2105
  var Ot = 280, Z = 96;
2103
2106
  function kt({ points: e = [], className: t, colors: r }) {
2104
- let o = a(null), d = a(/* @__PURE__ */ new Map()), f = a(0), p = i(() => e.map(([e, t]) => {
2107
+ let o = a(null), d = a(/* @__PURE__ */ new Map()), f = a(0), p = i(() => e.filter(Array.isArray).map(([e, t]) => {
2105
2108
  let n = String(t).match(/-?\d+(\.\d+)?/);
2106
2109
  return {
2107
2110
  label: e,
@@ -2200,7 +2203,7 @@ function It({ items: e = [], "data-testid": t }) {
2200
2203
  if (!e) return;
2201
2204
  let t = v(e, At, S);
2202
2205
  d.current = 0;
2203
- let n = Pt, i = Ft, a = Mt, o = Nt, s = At - 60 - 28, c = Math.max(...x.map((e) => (e.implemented ?? 0) + (e.unimplemented ?? 0))), g = x.length * (a + o) - o, _ = n + (S - n - i - g) / 2, b, C = () => {
2206
+ let n = Pt, i = Ft, a = Mt, o = Nt, s = At - 60 - 28, c = Math.max(...x.map((e) => (e.implemented ?? 0) + (e.unimplemented ?? 0)), 1), g = x.length * (a + o) - o, _ = n + (S - n - i - g) / 2, b, C = () => {
2204
2207
  d.current++;
2205
2208
  let e = d.current;
2206
2209
  t.clearRect(0, 0, At, S);
@@ -2217,7 +2220,7 @@ function It({ items: e = [], "data-testid": t }) {
2217
2220
  value: `${e.unimplemented ?? 0} variations`,
2218
2221
  sublabel: `${Math.round((e.unimplemented ?? 0) / (m || 1) * 100)}% pending`,
2219
2222
  color: u.amber
2220
- }), t.font = f.font, t.fillStyle = u.t2, t.textAlign = "right", t.fillText(e.abbreviation ?? e.name.slice(0, 6), 52, d + a / 2 + 4), t.fillStyle = h(u.bd, .15), t.beginPath(), t.roundRect(60, d, m / c * s, a, 4), t.fill(), g > 0 && (C > 0 && y(t, 60 + g / 2, d + a / 2, g * .3, u.green, .12 * C), t.fillStyle = h(u.green, .6 + C * .2), t.beginPath(), t.roundRect(60, d, g, a, [
2223
+ }), t.font = f.font, t.fillStyle = u.t2, t.textAlign = "right", t.fillText(e.abbreviation ?? e.name?.slice(0, 6) ?? "", 52, d + a / 2 + 4), t.fillStyle = h(u.bd, .15), t.beginPath(), t.roundRect(60, d, m / c * s, a, 4), t.fill(), g > 0 && (C > 0 && y(t, 60 + g / 2, d + a / 2, g * .3, u.green, .12 * C), t.fillStyle = h(u.green, .6 + C * .2), t.beginPath(), t.roundRect(60, d, g, a, [
2221
2224
  4,
2222
2225
  0,
2223
2226
  0,
@@ -2336,10 +2339,10 @@ function zt({ items: e = [], "data-testid": t }) {
2336
2339
  let o = x[a], s = M(r, a, e.length, D), c = i.current.get(t.id) ?? 0;
2337
2340
  E(g.current, t.id, o.x, o.y, 110, o.h, {
2338
2341
  label: t.name,
2339
- value: `£${t.total ?? 0}M total commitment`,
2340
- sublabel: `Base £${t.base ?? 0}M + Variations £${t.variation ?? 0}M`,
2342
+ value: `${t.totalLabel ?? String(t.total ?? 0)} total commitment`,
2343
+ sublabel: `Base ${t.baseLabel ?? String(t.base ?? 0)} + Variations ${t.variationLabel ?? String(t.variation ?? 0)}`,
2341
2344
  color: o.color
2342
- }), c > 0 && y(n, o.x + 110 / 2, o.cy, 110 * .6, o.color, .12 * c), n.fillStyle = h(o.color, (.3 + c * .15) * s), n.strokeStyle = h(o.color, (.55 + c * .25) * s), n.lineWidth = 1, n.beginPath(), n.roundRect(o.x, o.y, 110 * s, o.h, 4), n.fill(), n.stroke(), s > .6 && o.h >= 24 && (n.globalAlpha = Math.min(1, (s - .6) / .4), n.font = f.font, n.fillStyle = c > 0 ? o.color : h(u.t2, .9), n.textAlign = "center", n.textBaseline = "middle", n.fillText(t.abbreviation ?? t.name.slice(0, 6), o.x + 110 / 2, o.h >= 36 ? o.cy - 5 : o.cy), o.h >= 36 && (n.font = "400 12px 'Satoshi Variable', 'DM Sans', sans-serif", n.fillStyle = h(u.t3, .8), n.fillText(`£${t.total ?? 0}M`, o.x + 110 / 2, o.cy + 7)), n.globalAlpha = 1, n.textBaseline = "alphabetic");
2345
+ }), c > 0 && y(n, o.x + 110 / 2, o.cy, 110 * .6, o.color, .12 * c), n.fillStyle = h(o.color, (.3 + c * .15) * s), n.strokeStyle = h(o.color, (.55 + c * .25) * s), n.lineWidth = 1, n.beginPath(), n.roundRect(o.x, o.y, 110 * s, o.h, 4), n.fill(), n.stroke(), s > .6 && o.h >= 24 && (n.globalAlpha = Math.min(1, (s - .6) / .4), n.font = f.font, n.fillStyle = c > 0 ? o.color : h(u.t2, .9), n.textAlign = "center", n.textBaseline = "middle", n.fillText(t.abbreviation ?? t.name.slice(0, 6), o.x + 110 / 2, o.h >= 36 ? o.cy - 5 : o.cy), o.h >= 36 && (n.font = "400 12px 'Satoshi Variable', 'DM Sans', sans-serif", n.fillStyle = h(u.t3, .8), n.fillText(t.totalLabel ?? String(t.total ?? 0), o.x + 110 / 2, o.cy + 7)), n.globalAlpha = 1, n.textBaseline = "alphabetic");
2343
2346
  }), r > .2) {
2344
2347
  let e = Math.min(1, (r - .2) / .4);
2345
2348
  y(n, 420, O.cy, 30, u.blue, .1 * e), n.fillStyle = h(u.blue, .3 * e), n.strokeStyle = h(u.blue, .5 * e), n.lineWidth = 1, n.beginPath(), n.roundRect(O.x, O.y, 110, O.h * e, 4), n.fill(), n.stroke(), n.globalAlpha = e, n.textBaseline = "middle", n.font = f.font, n.fillStyle = u.blue, n.textAlign = "center", n.fillText("Base Value", 420, O.cy - 6), n.font = p.font, n.fillStyle = p.color, n.fillText(`£${a}M`, 420, O.cy + 8), n.globalAlpha = 1, n.textBaseline = "alphabetic", y(n, 420, k.cy, 24, u.amber, .1 * e), n.fillStyle = h(u.amber, .22 * e), n.strokeStyle = h(u.amber, .4 * e), n.beginPath(), n.roundRect(k.x, k.y, 110, k.h * e, 4), n.fill(), n.stroke(), n.globalAlpha = e, n.textBaseline = "middle", n.font = f.font, n.fillStyle = u.amber, n.textAlign = "center", n.fillText("Variations", 420, k.cy - 4), n.font = p.font, n.fillStyle = p.color, n.fillText(`£${s}M`, 420, k.cy + 8), n.globalAlpha = 1, n.textBaseline = "alphabetic";
@@ -2410,13 +2413,14 @@ function Vt({ config: e, className: t }) {
2410
2413
  }) : e.type === "mini-bars" ? /* @__PURE__ */ s(ze, {
2411
2414
  rows: e.rows,
2412
2415
  className: t
2413
- }) : e.type === "stacked-horizontal-bar-chart" ? /* @__PURE__ */ s(Ae, { data: e.data }) : e.type === "multi-metric-constellation-chart" ? /* @__PURE__ */ s(Ce, { items: e.items }) : e.type === "progress-race-chart" ? /* @__PURE__ */ s(fe, { items: e.items }) : e.type === "hub-and-spoke-radial-chart" ? /* @__PURE__ */ s(Dt, {
2416
+ }) : e.type === "stacked-horizontal-bar-chart" ? /* @__PURE__ */ s(Ae, { data: e.data }) : e.type === "multi-metric-constellation-chart" ? /* @__PURE__ */ s(Se, { items: e.items }) : e.type === "progress-race-chart" ? /* @__PURE__ */ s(de, { items: e.items }) : e.type === "hub-and-spoke-radial-chart" ? /* @__PURE__ */ s(Dt, {
2414
2417
  segments: e.segments,
2415
2418
  title: e.title
2416
2419
  }) : e.type === "dot-matrix-chart" ? /* @__PURE__ */ s(Fe, { items: e.items }) : e.type === "ranked-card-leaderboard" ? /* @__PURE__ */ s(Pe, { items: e.items }) : e.type === "proportional-band-chart" ? /* @__PURE__ */ s(Tt, { severities: e.severities }) : e.type === "radial-fan-tree-chart" ? /* @__PURE__ */ s(We, {
2417
2420
  total: e.total,
2421
+ totalLabel: e.totalLabel,
2418
2422
  items: e.items
2419
- }) : e.type === "semi-circular-gauge-chart" ? /* @__PURE__ */ s(he, {
2423
+ }) : e.type === "semi-circular-gauge-chart" ? /* @__PURE__ */ s(me, {
2420
2424
  value: e.value,
2421
2425
  confirmed: e.confirmed,
2422
2426
  total: e.total
@@ -3259,7 +3263,7 @@ var pn = "'Satoshi Variable', 'DM Sans', sans-serif", mn = {
3259
3263
  fontFamily: pn,
3260
3264
  fontSize: 18,
3261
3265
  fontWeight: 400,
3262
- lineHeight: "20px"
3266
+ lineHeight: 1.65
3263
3267
  };
3264
3268
  function hn({ text: e }) {
3265
3269
  return /* @__PURE__ */ c("div", {
@@ -3275,7 +3279,7 @@ function hn({ text: e }) {
3275
3279
  fontWeight: 500,
3276
3280
  color: u.t1,
3277
3281
  fontFamily: pn,
3278
- lineHeight: "20px",
3282
+ lineHeight: 1.65,
3279
3283
  marginRight: 8
3280
3284
  },
3281
3285
  children: "Takeaway"
@@ -139,6 +139,7 @@ export type BaseVisualizationConfig = {
139
139
  } | {
140
140
  type: 'radial-fan-tree-chart';
141
141
  total: number;
142
+ totalLabel?: string;
142
143
  items: NCEContractorRow[];
143
144
  } | {
144
145
  type: 'semi-circular-gauge-chart';
@@ -174,6 +175,9 @@ export type ContractorRow = {
174
175
  variation?: number;
175
176
  total?: number;
176
177
  percentage?: number;
178
+ baseLabel?: string;
179
+ variationLabel?: string;
180
+ totalLabel?: string;
177
181
  };
178
182
  export type ContractData = {
179
183
  items: (ContractorRow | number | null)[];
@@ -201,12 +205,14 @@ export type EWOpenContractorRow = {
201
205
  name: string;
202
206
  abbreviation?: string;
203
207
  count?: number;
208
+ label?: string;
204
209
  };
205
210
  export type NCEContractorRow = {
206
211
  id: string;
207
212
  name: string;
208
213
  abbreviation?: string;
209
214
  count?: number;
215
+ label?: string;
210
216
  };
211
217
  export type NCECompensationData = {
212
218
  total: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@divami-artefacts/ai-design-system",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "module": "./dist/index.js",