@wafertools/wafermap 0.30.1 → 0.30.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/AGENTS.md +71 -11
  2. package/CHANGELOG.md +464 -8
  3. package/README.md +6 -3
  4. package/dist/packages/canvas-adapter/chartPopulation.d.ts +48 -0
  5. package/dist/packages/canvas-adapter/chartPopulation.js +1 -0
  6. package/dist/packages/canvas-adapter/charts/barPanel.d.ts +4 -1
  7. package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
  8. package/dist/packages/canvas-adapter/charts/boxplot.d.ts +4 -1
  9. package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
  10. package/dist/packages/canvas-adapter/charts/capability.js +1 -1
  11. package/dist/packages/canvas-adapter/charts/chartShell.d.ts +81 -7
  12. package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
  13. package/dist/packages/canvas-adapter/charts/correlation.js +2 -2
  14. package/dist/packages/canvas-adapter/charts/groupedBarPlot.js +1 -1
  15. package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
  16. package/dist/packages/canvas-adapter/charts/regionYieldDiagram.js +1 -1
  17. package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
  18. package/dist/packages/canvas-adapter/charts/sweep.d.ts +31 -0
  19. package/dist/packages/canvas-adapter/charts/sweep.js +1 -0
  20. package/dist/packages/canvas-adapter/charts/trend.d.ts +3 -1
  21. package/dist/packages/canvas-adapter/charts/trend.js +1 -1
  22. package/dist/packages/canvas-adapter/chunked.d.ts +45 -0
  23. package/dist/packages/canvas-adapter/chunked.js +1 -0
  24. package/dist/packages/canvas-adapter/dieList.js +2 -2
  25. package/dist/packages/canvas-adapter/drilldown.d.ts +23 -0
  26. package/dist/packages/canvas-adapter/drilldown.js +1 -0
  27. package/dist/packages/canvas-adapter/icons.js +1 -1
  28. package/dist/packages/canvas-adapter/insightsTab.d.ts +55 -3
  29. package/dist/packages/canvas-adapter/insightsTab.js +1 -1
  30. package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +55 -0
  31. package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
  32. package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
  33. package/dist/packages/canvas-adapter/summaryPanel.d.ts +55 -9
  34. package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
  35. package/dist/packages/canvas-adapter/toCanvas.js +1 -1
  36. package/dist/packages/canvas-adapter/toolbar.d.ts +30 -2
  37. package/dist/packages/canvas-adapter/toolbar.js +2 -2
  38. package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
  39. package/dist/packages/canvas-adapter/userGuideHtml.js +126 -3
  40. package/dist/packages/canvas-adapter/version.d.ts +2 -2
  41. package/dist/packages/canvas-adapter/version.js +1 -1
  42. package/dist/packages/canvas-adapter/warnings.js +1 -1
  43. package/dist/packages/core/aggregates.js +1 -1
  44. package/dist/packages/core/utils.d.ts +55 -0
  45. package/dist/packages/core/utils.js +1 -1
  46. package/dist/packages/renderer/axisTicks.d.ts +32 -0
  47. package/dist/packages/renderer/axisTicks.js +1 -0
  48. package/dist/packages/renderer/binColors.d.ts +14 -0
  49. package/dist/packages/renderer/binColors.js +1 -1
  50. package/dist/packages/renderer/buildView.d.ts +11 -37
  51. package/dist/packages/renderer/buildView.js +1 -1
  52. package/dist/packages/renderer/buildWaferMap.d.ts +58 -1
  53. package/dist/packages/renderer/buildWaferMap.js +1 -1
  54. package/dist/packages/renderer/deprecate.d.ts +13 -5
  55. package/dist/packages/renderer/deprecate.js +1 -1
  56. package/dist/packages/renderer/derivedTests/apply.d.ts +85 -0
  57. package/dist/packages/renderer/derivedTests/apply.js +1 -0
  58. package/dist/packages/renderer/derivedTests/evaluate.d.ts +48 -0
  59. package/dist/packages/renderer/derivedTests/evaluate.js +1 -0
  60. package/dist/packages/renderer/derivedTests/parser.d.ts +148 -0
  61. package/dist/packages/renderer/derivedTests/parser.js +2 -0
  62. package/dist/packages/renderer/fmt.d.ts +24 -2
  63. package/dist/packages/renderer/fmt.js +1 -1
  64. package/dist/packages/renderer/index.d.ts +1 -0
  65. package/dist/packages/renderer/index.js +1 -1
  66. package/dist/packages/renderer/spec.d.ts +49 -0
  67. package/dist/packages/renderer/spec.js +1 -0
  68. package/dist/packages/renderer/testLabel.d.ts +154 -0
  69. package/dist/packages/renderer/testLabel.js +1 -0
  70. package/dist/packages/stats/analyzeWaferMap.js +1 -1
  71. package/dist/packages/stats/capability.d.ts +60 -0
  72. package/dist/packages/stats/capability.js +1 -1
  73. package/dist/packages/stats/correlation.d.ts +33 -0
  74. package/dist/packages/stats/correlation.js +1 -1
  75. package/dist/packages/stats/deprecated.d.ts +3 -0
  76. package/dist/packages/stats/deprecated.js +1 -1
  77. package/dist/packages/stats/findingsNarrative.js +1 -1
  78. package/dist/packages/stats/index.d.ts +2 -2
  79. package/dist/packages/stats/index.js +1 -1
  80. package/dist/packages/stats/math.d.ts +27 -2
  81. package/dist/packages/stats/math.js +1 -1
  82. package/dist/packages/stats/mergeTestDefs.js +1 -1
  83. package/dist/packages/stats/renderFindingsReport.js +8 -28
  84. package/dist/packages/stats/renderSummaryReport.js +22 -31
  85. package/dist/packages/stats/reportHtml.d.ts +27 -0
  86. package/dist/packages/stats/reportHtml.js +35 -14
  87. package/dist/packages/stats/sweep.d.ts +178 -0
  88. package/dist/packages/stats/sweep.js +1 -0
  89. package/dist/packages/stats/sweepXFromName.d.ts +27 -0
  90. package/dist/packages/stats/sweepXFromName.js +1 -0
  91. package/dist/packages/stats/testPassRate.js +1 -1
  92. package/dist/packages/stats/types.d.ts +28 -1
  93. package/llms.txt +14 -8
  94. package/package.json +2 -2
@@ -1 +1 @@
1
- import{fontPx as Ct}from"./toolbar.js";import{findTestDef as Ce,buildMapTitle as _e}from"../renderer/buildView.js";import{sortBinsForDisplay as ve}from"../stats/binPareto.js";import{affineInvert as to,affineVector as Be}from"../core/transforms.js";import{compareNatural as eo}from"../core/utils.js";import{resolveValueColorFn as oo}from"../renderer/colorSchemes.js";import{NO_DATA_FILL as no}from"../renderer/colorMap.js";import{SPEC_PASS_FILL as Pe,SPEC_FAIL_LOW as so,SPEC_FAIL_HIGH as De,contrastTextColor as We}from"../renderer/colorMap.js";import{fmt as Ie,fmtColorbarAxis as lo}from"../renderer/fmt.js";import{resolveCanvasTheme as io}from"./canvasTheme.js";import{hitGridDims as ao}from"./hitGrid.js";function Fe(g,e,P,b,r){g.moveTo(e,P+r*b),g.lineTo(e-b*.9,P-r*b*.6),g.lineTo(e+b*.9,P-r*b*.6),g.closePath()}const co=new Set(["value","stackedValues","stackedBins","stackedSoftBins"]),ro=new Set(["hardBin","softBin","metadata"]),J=()=>`${Ct(-2)}px system-ui, sans-serif`,Ne=3,Ut=2,fo=6,ho=20,go=()=>`600 ${Ct()}px system-ui, sans-serif`,Kt=()=>`${Ct(-1)}px system-ui, sans-serif`,mo=()=>`600 ${Ct(-1)}px system-ui, sans-serif`,qt=128,uo=()=>`${Ct(-2)}px system-ui, sans-serif`,Oe=4,D=17,H=11;export const BIN_LEGEND_W=110,BIN_LEGEND_W_COMPACT=64,BIN_LEGEND_ADAPT_COMPACT=280,BIN_LEGEND_ADAPT_FLOATING=180,BIN_LEGEND_MIN_CANVAS_W=150,BIN_LEGEND_MIN_CANVAS_H=120;const zt=28,gt=5,ft=8,Ee=15,He=12,Ye=6;export function toCanvas(g,e,P={}){return drawMapCanvas(g,e,P)}export function drawMapCanvas(g,e,P={}){const b=io(g.parentElement??g),{padding:r=16,showColorbar:G=!0,markFailingDies:X=!1,colorbarWidth:B=16,background:mt=b.background,legendPosition:Z="default",legendOffset:ut,showAxes:pt=!1,diePitchMm:w,viewport:K,activeBin:O,hoverBin:q,fallbackFormat:Tt,minRightReserve:_t,hbinDefs:nt,sbinDefs:xt,metadataFields:Mt,showTitle:U=!0}=P,W=Math.floor(g.clientWidth||g.width),Y=Math.floor(g.clientHeight||g.height),yt=W>=BIN_LEGEND_MIN_CANVAS_W&&Y>=BIN_LEGEND_MIN_CANVAS_H,St=G&&yt&&co.has(e.plotMode)&&e.passFailDisplay==="off",Lt=G&&yt&&ro.has(e.plotMode),j=G&&yt&&e.plotMode==="value"&&(e.passFailDisplay==="spec"&&e.specCounts!==void 0||e.passFailDisplay==="test"&&e.passFailCounts!==void 0),Q=Lt||j,Bt=Lt&&e.plotMode!=="metadata"&&e.binCounts?ve(e.binCounts.entries(),e.plotMode==="softBin"?e.binColors.pass.soft:e.binColors.pass.hard):[],Pt=Lt&&e.plotMode==="metadata"&&e.metadataCounts?[...e.metadataColorMap?.keys()??[...e.metadataCounts.keys()].sort(eo)].map(o=>[o,e.metadataCounts.get(o)??0]):[],v=[];if(j&&e.passFailDisplay==="test"){const o=e.passFailCounts;v.push({key:-1,color:Pe,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),v.push({key:-2,color:De,label:"Fail",compactLabel:"Fail",count:o.fail,tooltip:`Fail \xB7 ${o.fail} dies`})}else if(j){const o=e.specCounts,f=Ce(e.testDefs,e.activeTest);v.push({key:-1,color:Pe,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),f?.limitHigh!==void 0&&v.push({key:-2,color:De,label:"Fail high",compactLabel:"Fail hi",count:o.failHigh,tooltip:`Fail high \xB7 ${o.failHigh} dies`}),f?.limitLow!==void 0&&v.push({key:-3,color:so,label:"Fail low",compactLabel:"Fail lo",count:o.failLow,tooltip:`Fail low \xB7 ${o.failLow} dies`})}const Dt=j?v.length:e.plotMode==="metadata"?Pt.length:Bt.length,M=(g.ownerDocument.defaultView??window).devicePixelRatio??1;if(W<=0||Y<=0)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const k=Z!=="default"?Z:W<BIN_LEGEND_ADAPT_FLOATING?"floating":W<BIN_LEGEND_ADAPT_COMPACT?"compact":"default",ht=k==="default"||k==="compact",he=k==="left",Zt=k==="bottom",kt=k==="top",At=k==="floating",Wt=k==="compact"||k==="floating"?BIN_LEGEND_W_COMPACT:BIN_LEGEND_W,de=Math.floor((Y-2*r)/D),ge=Dt>de?de-1:Dt,me=Q&&Zt?ge*D:0,jt=Q&&kt?ge*D:0,Qt=e.plotMode==="stackedBins"||e.plotMode==="stackedSoftBins",vt=Ce(e.testDefs,e.activeTest),Ge=Qt?"Count":vt?.name??(e.activeTest!=null?`Test ${e.activeTest}`:void 0),Xe=Qt?void 0:vt?.unit,[It,Ft]=e.valueRange,{tickFmt:$e}=lo(Ft,Ge,Xe,Tt),Nt=e.allIntegerValues?o=>String(Math.round(o)):$e;let te=0;if(St){const o=g.getContext("2d");o.font=J();const f=[Nt(It),Nt(Ft)];It<0&&f.push(Nt(-Math.max(Math.abs(It),Math.abs(Ft))));for(const s of f)te=Math.max(te,o.measureText(s).width)}const ue=Math.max(ho,Math.ceil(te)+Ne+Ut+fo-r),ee=St?B+ue+8:Q&&ht?Wt:0,oe=Q&&he?Wt:0,ne=pt?32:0,Ot=pt?36:0,we=_t!=null?Math.max(ee,_t):ee,Ve=W-2*r-we-Ot-oe,pe=Y-2*r-ne-me-jt;g.width=Math.round(W*M),g.height=Math.round(Y*M);const t=g.getContext("2d");t.scale(M,M),t.fillStyle=mt,t.fillRect(0,0,W,Y);const $=e.hoverPoints;if(!$.length)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const Et=e.rectangles[0],se=Et?Et.width/2:0,le=Et?Et.height/2:0,Ht=e.dieBounds,xe=(Ht?.minX??0)-se,Ue=(Ht?.maxX??0)+se,Ke=(Ht?.minY??0)-le,Me=(Ht?.maxY??0)+le,ye=Ue-xe,be=Me-Ke;let tt,et,A;if(K)({originX:tt,originY:et,ppm:A}=K);else{const f=e.notchDir,s=f&&f.y>.1?13:0,a=f&&f.y<-.1?13:0,c=f&&f.x<-.1?13:0,h=f&&f.x>.1?13:0,d=Ve-c-h,i=pe-s-a;A=Math.min(d/ye,i/be),tt=r+Ot+oe+c+(d-ye*A)/2-xe*A,et=r+jt+s+(i-be*A)/2+Me*A}const Yt=K?.snapDist??Math.max(se,le,1)*1.5,Gt=tt+e.waferCenter.x*A,qe=et-e.waferCenter.y*A,ie=e.waferRadius*A,st=o=>{const f=Math.abs(o-qe);return f>=ie?0:Math.sqrt(ie*ie-f*f)},lt=(o,f,s,a,c,h,d=go(),i=b.text)=>{if(!o)return;t.save(),t.fillStyle=i,t.font=d,t.textAlign=a,t.textBaseline=c;const y=a==="right"?f-h:h-f;let l=o;if(y>8&&t.measureText(l).width>y){for(;l.length>1&&t.measureText(l+"\u2026").width>y;)l=l.slice(0,-1);l=l+"\u2026"}y>8&&t.fillText(l,f,s),t.restore()};t.save(),t.setTransform(A*M,0,0,-A*M,tt*M,et*M);const dt=1/A,ze=1/(A*M);if(e.rectangles.length>0){const o=new Map;for(const s of e.rectangles){const a=String(s.fill);let c=o.get(a);c||(c=[],o.set(a,c)),c.push(s)}for(const[s,a]of o){t.beginPath();for(const c of a)t.rect(c.x-c.width/2,c.y-c.height/2,c.width,c.height);t.fillStyle=s,t.fill()}t.strokeStyle="rgba(0,0,0,0.18)",t.lineWidth=.5*ze,t.beginPath();for(const s of e.rectangles)t.rect(s.x-s.width/2,s.y-s.height/2,s.width,s.height);if(t.stroke(),X){const s=e.rectangles.filter(a=>a.binFail);if(s.length>0){const a=new Map;for(const c of s){const h=We(String(c.fill));let d=a.get(h);d||(d=[],a.set(h,d)),d.push(c)}t.save(),t.lineCap="butt";for(const[c,h]of a){t.strokeStyle=c,t.globalAlpha=.55,t.lineWidth=Math.max(.6*dt,Math.min(h[0].width,h[0].height)*.1);for(const d of h){const i=d.width/2,y=d.height/2,l=Math.max(1.6*dt,Math.min(d.width,d.height)/3);t.save(),t.beginPath(),t.rect(d.x-i,d.y-y,d.width,d.height),t.clip(),t.beginPath();for(let T=-(i+y);T<=i+y;T+=l)t.moveTo(d.x-i+T,d.y-y),t.lineTo(d.x-i+T+d.height,d.y+y);t.stroke(),t.restore()}}t.restore()}}const f=e.rectangles.filter(s=>s.specMark);if(f.length>0){const s=new Map;for(const c of f){const h=We(String(c.fill)),d=`${c.specMark}|${h}`;let i=s.get(d);i||(i=[],s.set(d,i)),i.push(c)}const a=2.5*dt;t.lineJoin="round";for(const[c,h]of s){const[d,i]=c.split("|"),y=i==="#000000"?"#ffffff":"#000000",l=d==="failHigh"?1:-1,T=Math.min(h[0].width,h[0].height),I=Math.max(2.5*dt,T*.3);t.beginPath();for(const R of h)Fe(t,R.x,R.y,I,l);t.strokeStyle=y,t.lineWidth=a,t.stroke(),t.fillStyle=i,t.fill()}}}for(const o of e.overlays){t.beginPath();for(const f of o.points){for(let s=0;s<f.length;s++)s===0?t.moveTo(f[s].x,f[s].y):t.lineTo(f[s].x,f[s].y);o.closed&&t.closePath()}o.fill&&!o.fill.startsWith("rgba(0,0,0,0)")&&(t.fillStyle=o.fill,t.fill()),o.kind==="ring-boundary"||o.kind==="quadrant-boundary"||o.kind==="reticle"?(t.strokeStyle="rgba(0,0,0,0.45)",t.lineWidth=3*dt,t.stroke(),t.strokeStyle="rgba(255,255,255,0.8)",t.lineWidth=1*dt,t.stroke()):(t.strokeStyle=o.lineColor,t.lineWidth=o.lineWidth*dt,t.stroke())}if(t.restore(),e.notchDir){const o=tt+e.waferCenter.x*A,f=et-e.waferCenter.y*A,s=e.notchDir.x,a=-e.notchDir.y,c=e.waferRadius*A,h=4,d=9,i=5,y=o+s*(c+h),l=f+a*(c+h),T=y+s*d,I=l+a*d,R={x:-a,y:s},F=r+Ot+oe,E=W-r-ee,V=r+jt,at=Y-r-me-ne;t.save(),t.beginPath(),t.rect(F,V,E-F,at-V),t.clip(),t.beginPath(),t.moveTo(y,l),t.lineTo(T+R.x*i,I+R.y*i),t.lineTo(T-R.x*i,I-R.y*i),t.closePath(),t.fillStyle=b.text,t.fill(),t.restore()}t.save(),t.textAlign="center",t.textBaseline="middle";let Te=0;if(e.rectangles.length>0){let o=1;for(const h of e.texts)h.role!=="indicator"&&h.text.length>o&&(o=h.text.length);const f=e.rectangles[0].width*A,s=e.rectangles[0].height*A,a=Math.min(f,s),c=f/o;Te=Math.max(8,Math.min(64,Math.round(Math.min(a*.55,c*1.8))))}for(const o of e.texts){const f=tt+o.x*A,s=et-o.y*A;t.font=`${o.role==="indicator"?o.fontSize:Te}px system-ui, sans-serif`,t.fillStyle=o.color,t.fillText(o.text,f,s)}if(t.restore(),pt&&po(t,W,Y,tt,et,A,r,ne,Ot,w,e.gridToScreen,e.rotation,b),St){const o=oo(e.valueColorScheme,e.reverseValueScheme),f=ue,s=pe,a=Math.round(s*.75),c=r+Math.round((s-a)/2),h=W-r-B-f,d=It,i=Ft,y=i-d,l=e.plotMode==="stackedSoftBins"?xt:nt,{primary:T,secondary:I}=U?_e(e,Tt,l):{primary:"",secondary:""};if(U){const n=Math.max(c-6,r+11),m=Gt+Math.max(st(n),st(n-12))+8;lt(T,W-r,n,"right","bottom",m)}let R=c+a+4;const F=n=>Gt+Math.max(st(n),st(n+12))+8,E=e.logScale&&d>0?Math.log10(d):0,V=e.logScale&&i>0?Math.log10(i)-E:1,at=n=>e.logScale?(1-(Math.log10(n)-E)/V)*a:(1-(n-d)/y)*a;for(let n=0;n<qt;n++){const m=1-n/(qt-1),S=c+n/qt*a,p=a/qt+1;t.fillStyle=o(m),t.fillRect(h,S,B,p)}t.strokeStyle="rgba(0,0,0,0.25)",t.lineWidth=.5,t.strokeRect(h,c,B,a),t.fillStyle=b.text,t.font=J(),t.textAlign="left",t.strokeStyle="rgba(0,0,0,0.35)",t.lineWidth=.5;const L=Ne,N=36,ot=14,wt=e.logScale&&V>0?xo(d,i,a,N,ot,E,V):e.allIntegerValues?(()=>{const n=Math.max(1,Jt(y*N/a)),m=[],S=Math.ceil(d/n)*n;for(let p=S;p<=i+n*1e-6;p+=n){const u=(1-(p-d)/y)*a;u>ot&&u<a-ot&&m.push(Math.round(p))}return m})():(()=>{const n=y>0?Jt(y*N/a):0,m=[];if(n>0){const S=Math.ceil(d/n)*n;for(let p=S;p<=i+n*1e-6;p+=n){const u=(1-(p-d)/y)*a;u>ot&&u<a-ot&&m.push(p)}}return m})(),C=vt,_=Qt,x=Nt;t.textBaseline="middle";for(const n of wt){const m=c+at(n);t.beginPath(),t.moveTo(h+B,m),t.lineTo(h+B+L,m),t.stroke(),t.fillText(x(n),h+B+L+Ut,m)}if(t.beginPath(),t.moveTo(h+B,c),t.lineTo(h+B+L,c),t.stroke(),t.textBaseline="top",t.fillText(x(i),h+B+L+Ut,c),t.beginPath(),t.moveTo(h+B,c+a),t.lineTo(h+B+L,c+a),t.stroke(),t.textBaseline="bottom",t.fillText(x(d),h+B+L+Ut,c+a),!_&&C&&(C.limitLow!==void 0||C.limitHigh!==void 0)){const n=[],m=e.colorbarRangeMode==="spec";for(const[S,p]of[[C.limitLow,"LSL"],[C.limitHigh,"USL"]]){if(S===void 0||e.logScale&&S<=0)continue;const u=at(S);!m&&(u<-ot||u>a+ot)||n.push({value:S,label:p,py:Math.max(0,Math.min(a,u))})}if(n.length>0){t.save(),t.font=J(),t.textAlign="right",t.textBaseline="middle";for(const{py:S,label:p}of n){const u=c+S;m||(t.strokeStyle="rgba(255,255,255,0.85)",t.lineWidth=3,t.beginPath(),t.moveTo(h,u),t.lineTo(h+B,u),t.stroke(),t.strokeStyle="rgba(0,0,0,0.7)",t.lineWidth=1,t.beginPath(),t.moveTo(h,u),t.lineTo(h+B,u),t.stroke()),t.fillStyle=b.text,t.fillText(p,h-3,u);const ct=p==="USL"?-1:1,rt=4,bt=h-3-t.measureText(p).width-rt-4;t.beginPath(),Fe(t,bt,u,rt,ct),t.strokeStyle="#fff",t.lineWidth=2,t.lineJoin="round",t.stroke(),t.fillStyle=b.text,t.fill()}t.restore()}}if(!_){const n=e.logScale?"log\u2081\u2080":e.logScaleRequested?"linear \u2014 log n/a":null;n&&(t.save(),t.fillStyle=b.text,t.font=mo(),t.textAlign="right",t.textBaseline="top",t.fillText(n,W-r,R),t.restore(),R+=15)}U&&I&&lt(I,W-r,R,"right","top",F(R),Kt(),b.text)}const ae=[];let z;if(Q){const o=k==="compact",f=e.plotMode==="softBin"?xt:nt,s=f?new Map(f.map(l=>[l.bin,l])):null,a=e.plotMode==="softBin"?e.binColors.soft:e.binColors.hard,c=l=>a.get(l)??no,h=(l,T)=>{const I=t.measureText(l).width,R=o?0:t.measureText(String(T)).width,F=H+gt+I+(R?zt:0);return{labelWidth:I,countWidth:R,totalWidth:F}},d=Mt?.find(l=>l.key===e.activeMetadataKey),i=j?v.map(l=>{const T=o?l.compactLabel:l.label;return{key:l.key,color:l.color,count:l.count,label:T,tooltipLabel:l.tooltip,...h(T,l.count)}}):e.plotMode==="metadata"?Pt.map(([l,T])=>{const R=d?.values?.find(V=>V.value===l)?.label??l,F=o?l:R,E=e.metadataColorMap?.get(l)??"#d6d9dd";return{key:l,color:E,count:T,label:F,tooltipLabel:`${R} \xB7 ${T} dies`,...h(F,T)}}):Bt.map(([l,T])=>{const I=s?.get(l),R=I?.name?`${l} \xB7 ${I.name}`:`Bin ${l}`,F=o?String(l):R;return{key:l,color:c(l),count:T,label:F,tooltipLabel:`${R} \xB7 ${T} dies`,...h(F,T)}}),y=W-r*2;if(i.length>0){const l=At?ft*2+(U?Ee:0):U&&!kt?He+Ye:0,T=Math.max(1,Math.floor((Y-2*r-l)/D));let I=i.length,R=1,F=I*D,E=[],V=0;const at=Zt||kt;if(at){const C=Math.max(...i.map(x=>x.totalWidth)),_=Math.max(1,Math.min(i.length,Math.floor((y+8)/(C+8))));for(let x=_;x>=1;x--){const n=Math.ceil(i.length/x);if(n>T)continue;const m=new Array(x).fill(0);for(let p=0;p<i.length;p++){const u=p%x;m[u]=Math.max(m[u],i[p].totalWidth)}if(m.reduce((p,u)=>p+u,0)+(x-1)*8<=y||x===1){R=x,E=m,I=n,F=n*D;break}}}else I=Math.min(i.length,T),F=I*D,i.length>T&&(V=i.length-(T-1)),E=[Wt];let L,N;if(At){const C=Math.max(...i.map(u=>H+gt+t.measureText(u.label).width+zt)),_=Math.ceil(C);E=[_];const x=U?Ee:0,n=_+ft*2,m=F+x+ft*2,S=ut?.x??0,p=ut?.y??0;L=Math.min(Math.max(W-r-n+S,r),W-r-n),N=Math.min(Math.max(Y-r-m+p,r),Y-r-m),z={x:L,y:N,w:n,h:m},t.save(),t.globalAlpha=.92,t.fillStyle=b.surface,t.fillRect(L,N,n,m),t.globalAlpha=1,t.strokeStyle=b.axisLine,t.lineWidth=1,t.strokeRect(L,N,n,m),t.restore(),L+=ft,N+=ft+x}else Zt?(L=r,N=Y-r-F):kt?(L=r,N=r):he?(L=r+4,N=Math.max(r+Math.round((Y-2*r-F)/2),r+l)):(L=W-r-Wt+4,N=Math.max(r+Math.round((Y-2*r-F)/2),r+l));if(U){const C=e.plotMode==="softBin"?xt:nt,{primary:_,secondary:x}=_e(e,Tt,C),n=Ye,m=u=>Gt-Math.max(st(u),st(u-12))-8,S=u=>ht?W-r:m(u),p=At?z.y+z.h:N+F;if(kt){const u=p+n;lt(_,L,u,"left","top",Gt-Math.max(st(u),st(u+12))-8),x&&lt(x,L,u+16,"left","top",m(u+16),Kt(),b.text)}else if(At)lt(_,z.x+ft,z.y+ft,"left","top",z.x+z.w-ft),x&&lt(x,z.x,p+n,"left","top",z.x+z.w,Kt(),b.text);else{const u=Math.max(N-n,r+He);if(lt(_,L,u,"left","bottom",S(u)),x){const ct=p+n;lt(x,L,ct,"left","top",S(ct),Kt(),b.text)}}}t.save(),t.font=J();const ot=at?8:0,wt=(C,_)=>{if(t.measureText(C).width<=_)return C;let x=0,n=C.length;const m="\u2026",S=t.measureText(m).width;for(;x<n;){const p=x+n+1>>1;t.measureText(C.slice(0,p)).width+S<=_?x=p:n=p-1}return x===0?m:C.slice(0,x)+m};if(at){let C=0;for(let _=0;_<I;_++){let x=L;for(let n=0;n<R;n++){const m=i[C++];if(!m)break;const S=m.key===O,p=!S&&m.key===q,u=x,ct=x+H+gt,rt=N+_*D+D/2,bt=N+_*D+Math.round((D-H)/2),Vt=E[n]-H-gt-zt;p&&(t.fillStyle=b.hoverRow,t.fillRect(x,N+_*D,E[n],D)),t.fillStyle=m.color,t.fillRect(u,bt,H,H),t.strokeStyle=S?b.accent:"rgba(0,0,0,0.25)",t.lineWidth=S?2:.75,t.strokeRect(u,bt,H,H),t.fillStyle=S?b.accent:b.text,t.font=S?`bold ${J()}`:J(),t.textAlign="left",t.textBaseline="middle",t.fillText(wt(m.label,Vt),ct,rt),t.fillStyle=b.textMuted,t.font=J(),t.textAlign="right",t.fillText(String(m.count),x+E[n]-2,rt),ae.push({bin:m.key,x,y:N+_*D,w:E[n],h:D,label:m.tooltipLabel}),x+=E[n]+ot}}}else{const C=E[0],_=k!=="compact",x=C-H-gt-(_?zt:0),n=L+C-2;let m=i;V>0&&(m=i.slice(0,T-1));let S=N;for(const p of m){const u=p.key===O,ct=!u&&p.key===q,rt=L,bt=L+H+gt,Vt=S+D/2,Re=S+Math.round((D-H)/2),Qe=p.label;ct&&(t.fillStyle=b.hoverRow,t.fillRect(L-3,S,C+3,D)),t.fillStyle=p.color,t.fillRect(rt,Re,H,H),t.strokeStyle=u?b.accent:"rgba(0,0,0,0.25)",t.lineWidth=u?2:.75,t.strokeRect(rt,Re,H,H),t.fillStyle=u?b.accent:b.text,t.font=u?`bold ${J()}`:J(),t.textAlign="left",t.textBaseline="middle",t.fillText(wt(Qe,x),bt,Vt),(_||At)&&(t.fillStyle=b.textMuted,t.font=J(),t.textAlign="right",t.fillText(String(p.count),n,Vt)),ae.push({bin:p.key,x:L,y:S,w:C,h:D,label:p.tooltipLabel}),S+=D}V>0&&(t.fillStyle=b.textMuted,t.font=J(),t.textAlign="left",t.textBaseline="middle",t.fillText(`+ ${V} more`,L+H+gt,S+D/2))}}i.length>0&&t.restore()}const Je={originX:tt,originY:et,ppm:A,snapDist:Yt},Se=e.rectangles[0]?.width??1,Le=e.rectangles[0]?.height??1,it=e.dieBounds,Xt=it?it.minX:$.length?Math.min(...$.map(o=>o.x)):0,$t=it?it.minY:$.length?Math.min(...$.map(o=>o.y)):0,Ze=it?it.maxX:$.length?Math.max(...$.map(o=>o.x)):1,je=it?it.maxY:$.length?Math.max(...$.map(o=>o.y)):1,{cellW:ce,cellH:re,nCols:Rt,nRows:fe}=ao(Ze-Xt,je-$t,Se*1.5,Le*1.5,$.length),ke=Array.from({length:Rt*fe},()=>[]);for(let o=0;o<$.length;o++){const f=Math.floor(($[o].x-Xt)/ce),s=Math.floor(($[o].y-$t)/re),a=Number.isFinite(f)?Math.max(0,Math.min(Rt-1,f)):0,c=Number.isFinite(s)?Math.max(0,Math.min(fe-1,s)):0;ke[c*Rt+a].push(o)}function Ae(o,f,s){const a=Math.max(0,Math.floor((o-s-Xt)/ce)),c=Math.min(Rt-1,Math.floor((o+s-Xt)/ce)),h=Math.max(0,Math.floor((f-s-$t)/re)),d=Math.min(fe-1,Math.floor((f+s-$t)/re)),i=[];for(let y=h;y<=d;y++)for(let l=a;l<=c;l++)for(const T of ke[y*Rt+l])i.push(T);return i}return{hitTarget:{getDieAtPoint(o,f){const s=(o-tt)/A,a=(et-f)/A,c=Math.max(Se,Le);for(const i of Ae(s,a,c)){const y=e.rectangles[i];if(y&&Math.abs(s-y.x)<=y.width/2&&Math.abs(a-y.y)<=y.height/2)return e.dies[i]??null}let h=null,d=Yt*Yt;for(const i of Ae(s,a,Yt)){const y=$[i].x-s,l=$[i].y-a,T=y*y+l*l;T<d&&(d=T,h=e.dies[i]??null)}return h}},viewport:Je,binLegendRows:ae,legendBox:z}}function po(g,e,P,b,r,G,X,B,mt,Z,ut,pt,w){g.save(),g.font=uo(),g.fillStyle=w.text,g.strokeStyle=w.axisLine,g.lineWidth=.5;const K=P-B+4,O=X+mt-4,q=to(ut),Tt=Be(q,1,0),_t=Be(q,0,1),nt=1e-9;function xt(M){return Z?Math.abs(M.y)<nt&&Math.abs(M.x)>nt?{pitch:Z.x,sign:Math.sign(M.x)}:Math.abs(M.x)<nt&&Math.abs(M.y)>nt?{pitch:Z.y,sign:Math.sign(M.y)}:null:null}const Mt=xt(Tt),U=xt(_t);function W(M){return Mt?Math.round(M*Mt.sign/Mt.pitch):M}function Y(M){return U?Math.round(M*U.sign/U.pitch):M}function yt(M){if(!M)return Jt(50/G);const k=50/(M*G);return Math.max(1,Math.round(k))*M}const St=Mt?.pitch,Lt=U?.pitch,j=yt(St),Q=yt(Lt);g.textAlign="center",g.textBaseline="top";const Bt=Math.ceil((X-b)/G/j)*j,Pt=(e-X-b)/G;for(let M=Bt;M<=Pt;M+=j){const k=b+M*G;if(k<X||k>e-X)continue;g.beginPath(),g.moveTo(k,K-Oe),g.lineTo(k,K),g.stroke();const ht=Z?String(W(M)):Ie(M);g.fillText(ht,k,K+2)}g.textAlign="right",g.textBaseline="middle";const v=Math.ceil((r-(P-X))/G/Q)*Q,Dt=(r-X)/G;for(let M=v;M<=Dt;M+=Q){const k=r-M*G;if(k<X||k>P-X)continue;g.beginPath(),g.moveTo(O,k),g.lineTo(O+Oe,k),g.stroke();const ht=Z?String(Y(M)):Ie(M);g.fillText(ht,O-2,k)}g.restore()}function Jt(g){const e=Math.pow(10,Math.floor(Math.log10(g))),P=g/e;return(P<1.5?1:P<3.5?2:P<7.5?5:10)*e}function xo(g,e,P,b,r,G,X){const B=[],mt=X;if(mt<1){const w=Jt((e-g)*b/P);if(w>0){const K=Math.ceil(g/w)*w;for(let O=K;O<=e+w*1e-6;O+=w){if(O<=g||O>=e)continue;const q=(1-(Math.log10(O)-G)/X)*P;q>r&&q<P-r&&B.push(O)}}return B}const Z=mt<3?[1,2,5]:[1],ut=Math.floor(Math.log10(g)),pt=Math.ceil(Math.log10(e));for(let w=ut;w<=pt;w++)for(const K of Z){const O=K*Math.pow(10,w);if(O<=g||O>=e)continue;const q=(1-(Math.log10(O)-G)/X)*P;q>r&&q<P-r&&B.push(O)}return B}export{fmt,fmtColorbarAxis}from"../renderer/fmt.js";
1
+ import{fontPx as Wt}from"./toolbar.js";import{findTestDef as We,buildMapTitle as Fe}from"../renderer/buildView.js";import{niceStep as Ft}from"../renderer/axisTicks.js";import{sortBinsForDisplay as lo}from"../stats/binPareto.js";import{affineInvert as io,affineVector as Oe}from"../core/transforms.js";import{compareNatural as ao,maxOf as zt,minOf as Ne}from"../core/utils.js";import{resolveValueColorFn as co}from"../renderer/colorSchemes.js";import{NO_DATA_FILL as ro}from"../renderer/colorMap.js";import{SPEC_PASS_FILL as Ee,SPEC_FAIL_LOW as fo,SPEC_FAIL_HIGH as He,contrastTextColor as Ye}from"../renderer/colorMap.js";import{fmt as Xe,fmtColorbarAxis as Ge}from"../renderer/fmt.js";import{resolveCanvasTheme as ho}from"./canvasTheme.js";import{hitGridDims as go}from"./hitGrid.js";function $e(g,e,X,x,c){g.moveTo(e,X+c*x),g.lineTo(e-x*.9,X-c*x*.6),g.lineTo(e+x*.9,X-c*x*.6),g.closePath()}const mo=new Set(["value","stackedValues","stackedBins","stackedSoftBins"]),uo=new Set(["hardBin","softBin","metadata"]),v=()=>`${Wt(-2)}px system-ui, sans-serif`,we=3,Jt=2,po=6,xo=20,bo=()=>`600 ${Wt()}px system-ui, sans-serif`,Ve=36,ue=()=>`${Wt(-1)}px system-ui, sans-serif`,Mo=()=>`600 ${Wt(-1)}px system-ui, sans-serif`,Zt=128,yo=()=>`${Wt(-2)}px system-ui, sans-serif`,Ue=4,E=17,$=11;export const BIN_LEGEND_W=110,BIN_LEGEND_W_COMPACT=64,BIN_LEGEND_ADAPT_COMPACT=280,BIN_LEGEND_ADAPT_FLOATING=180,BIN_LEGEND_MIN_CANVAS_W=150,BIN_LEGEND_MIN_CANVAS_H=120;const jt=28,ut=5,ht=8,Ke=15,qe=12,ze=6;export function toCanvas(g,e,X={}){return drawMapCanvas(g,e,X)}export function drawMapCanvas(g,e,X={}){const x=ho(g.parentElement??g),{padding:c=16,showColorbar:V=!0,markFailingDies:U=!1,colorbarWidth:D=16,background:pt=x.background,legendPosition:tt="default",legendOffset:xt,showAxes:bt=!1,diePitchMm:q,viewport:Z,activeBin:Y,hoverBin:j,fallbackFormat:Mt,minRightReserve:Ot,hbinDefs:ct,sbinDefs:yt,metadataFields:Tt,showTitle:z=!0}=X,F=Math.floor(g.clientWidth||g.width),G=Math.floor(g.clientHeight||g.height),St=F>=BIN_LEGEND_MIN_CANVAS_W&&G>=BIN_LEGEND_MIN_CANVAS_H,At=V&&St&&mo.has(e.plotMode)&&e.passFailDisplay==="off",Rt=V&&St&&uo.has(e.plotMode),ot=V&&St&&e.plotMode==="value"&&(e.passFailDisplay==="spec"&&e.specCounts!==void 0||e.passFailDisplay==="test"&&e.passFailCounts!==void 0),nt=Rt||ot,Nt=Rt&&e.plotMode!=="metadata"&&e.binCounts?lo(e.binCounts.entries(),e.plotMode==="softBin"?e.binColors.pass.soft:e.binColors.pass.hard):[],Et=Rt&&e.plotMode==="metadata"&&e.metadataCounts?[...e.metadataColorMap?.keys()??[...e.metadataCounts.keys()].sort(ao)].map(o=>[o,e.metadataCounts.get(o)??0]):[],st=[];if(ot&&e.passFailDisplay==="test"){const o=e.passFailCounts;st.push({key:-1,color:Ee,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),st.push({key:-2,color:He,label:"Fail",compactLabel:"Fail",count:o.fail,tooltip:`Fail \xB7 ${o.fail} dies`})}else if(ot){const o=e.specCounts,f=We(e.testDefs,e.activeTest);st.push({key:-1,color:Ee,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),f?.limitHigh!==void 0&&st.push({key:-2,color:He,label:"Fail high",compactLabel:"Fail hi",count:o.failHigh,tooltip:`Fail high \xB7 ${o.failHigh} dies`}),f?.limitLow!==void 0&&st.push({key:-3,color:fo,label:"Fail low",compactLabel:"Fail lo",count:o.failLow,tooltip:`Fail low \xB7 ${o.failLow} dies`})}const Ht=ot?st.length:e.plotMode==="metadata"?Et.length:Nt.length,u=(g.ownerDocument.defaultView??window).devicePixelRatio??1;if(F<=0||G<=0)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const k=tt!=="default"?tt:F<BIN_LEGEND_ADAPT_FLOATING?"floating":F<BIN_LEGEND_ADAPT_COMPACT?"compact":"default",dt=k==="default"||k==="compact",pe=k==="left",Qt=k==="bottom",_t=k==="top",Ct=k==="floating",Yt=k==="compact"||k==="floating"?BIN_LEGEND_W_COMPACT:BIN_LEGEND_W,xe=Math.floor((G-2*c)/E),be=Ht>xe?xe-1:Ht,Me=nt&&Qt?be*E:0,vt=nt&&_t?be*E:0,te=e.plotMode==="stackedBins"||e.plotMode==="stackedSoftBins",ee=We(e.testDefs,e.activeTest),ye=te?"Count":ee?.name??(e.activeTest!=null?`Test ${e.activeTest}`:void 0),Te=te?void 0:ee?.unit,[Bt,Pt]=e.valueRange,oe=o=>String(Math.round(o)),Je=e.logScale||e.allIntegerValues?void 0:Ft(Math.max(0,Pt-Bt)*Ve/Math.max(1,G))||void 0,ne=e.allIntegerValues?oe:Ge(Pt,ye,Te,Mt,Je).edgeFmt;let se=0;if(At){const o=g.getContext("2d");o.font=v();const f=[ne(Bt),ne(Pt)];Bt<0&&f.push(ne(-Math.max(Math.abs(Bt),Math.abs(Pt))));for(const n of f)se=Math.max(se,o.measureText(n).width)}const Se=Math.max(xo,Math.ceil(se)+we+Jt+po-c),le=At?D+Se+8:nt&&dt?Yt:0,ie=nt&&pe?Yt:0,ae=bt?32:0,Xt=bt?36:0,Ze=Ot!=null?Math.max(le,Ot):le,je=F-2*c-Ze-Xt-ie,Le=G-2*c-ae-Me-vt;g.width=Math.round(F*u),g.height=Math.round(G*u);const t=g.getContext("2d");t.scale(u,u),t.fillStyle=pt,t.fillRect(0,0,F,G);const K=e.hoverPoints;if(!K.length)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const Gt=e.rectangles[0],ce=Gt?Gt.width/2:0,re=Gt?Gt.height/2:0,$t=e.dieBounds,ke=($t?.minX??0)-ce,Qe=($t?.maxX??0)+ce,ve=($t?.minY??0)-re,Ae=($t?.maxY??0)+re,Re=Qe-ke,_e=Ae-ve;let lt,it,A;if(Z)({originX:lt,originY:it,ppm:A}=Z);else{const f=e.notchDir,n=f&&f.y>.1?13:0,a=f&&f.y<-.1?13:0,r=f&&f.x<-.1?13:0,h=f&&f.x>.1?13:0,d=je-r-h,s=Le-n-a;A=Math.min(d/Re,s/_e),lt=c+Xt+ie+r+(d-Re*A)/2-ke*A,it=c+vt+n+(s-_e*A)/2+Ae*A}const wt=Z?.snapDist??Math.max(ce,re,1)*1.5,Vt=lt+e.waferCenter.x*A,to=it-e.waferCenter.y*A,fe=e.waferRadius*A,rt=o=>{const f=Math.abs(o-to);return f>=fe?0:Math.sqrt(fe*fe-f*f)},gt=(o,f,n,a,r,h,d=bo(),s=x.text)=>{if(!o)return;t.save(),t.fillStyle=s,t.font=d,t.textAlign=a,t.textBaseline=r;const p=a==="right"?f-h:h-f;let l=o;if(p>8&&t.measureText(l).width>p){for(;l.length>1&&t.measureText(l+"\u2026").width>p;)l=l.slice(0,-1);l=l+"\u2026"}p>8&&t.fillText(l,f,n),t.restore()};t.save(),t.setTransform(A*u,0,0,-A*u,lt*u,it*u);const mt=1/A,eo=1/(A*u);if(e.rectangles.length>0){const o=new Map;for(const n of e.rectangles){const a=String(n.fill);let r=o.get(a);r||(r=[],o.set(a,r)),r.push(n)}for(const[n,a]of o){t.beginPath();for(const r of a)t.rect(r.x-r.width/2,r.y-r.height/2,r.width,r.height);t.fillStyle=n,t.fill()}t.strokeStyle="rgba(0,0,0,0.18)",t.lineWidth=.5*eo,t.beginPath();for(const n of e.rectangles)t.rect(n.x-n.width/2,n.y-n.height/2,n.width,n.height);if(t.stroke(),U){const n=e.rectangles.filter(a=>a.binFail);if(n.length>0){const a=new Map;for(const r of n){const h=Ye(String(r.fill));let d=a.get(h);d||(d=[],a.set(h,d)),d.push(r)}t.save(),t.lineCap="butt";for(const[r,h]of a){t.strokeStyle=r,t.globalAlpha=.55,t.lineWidth=Math.max(.6*mt,Math.min(h[0].width,h[0].height)*.1);for(const d of h){const s=d.width/2,p=d.height/2,l=Math.max(1.6*mt,Math.min(d.width,d.height)/3);t.save(),t.beginPath(),t.rect(d.x-s,d.y-p,d.width,d.height),t.clip(),t.beginPath();for(let M=-(s+p);M<=s+p;M+=l)t.moveTo(d.x-s+M,d.y-p),t.lineTo(d.x-s+M+d.height,d.y+p);t.stroke(),t.restore()}}t.restore()}}const f=e.rectangles.filter(n=>n.specMark);if(f.length>0){const n=new Map;for(const r of f){const h=Ye(String(r.fill)),d=`${r.specMark}|${h}`;let s=n.get(d);s||(s=[],n.set(d,s)),s.push(r)}const a=2.5*mt;t.lineJoin="round";for(const[r,h]of n){const[d,s]=r.split("|"),p=s==="#000000"?"#ffffff":"#000000",l=d==="failHigh"?1:-1,M=Math.min(h[0].width,h[0].height),H=Math.max(2.5*mt,M*.3);t.beginPath();for(const I of h)$e(t,I.x,I.y,H,l);t.strokeStyle=p,t.lineWidth=a,t.stroke(),t.fillStyle=s,t.fill()}}}for(const o of e.overlays){t.beginPath();for(const f of o.points){for(let n=0;n<f.length;n++)n===0?t.moveTo(f[n].x,f[n].y):t.lineTo(f[n].x,f[n].y);o.closed&&t.closePath()}o.fill&&!o.fill.startsWith("rgba(0,0,0,0)")&&(t.fillStyle=o.fill,t.fill()),o.kind==="ring-boundary"||o.kind==="quadrant-boundary"||o.kind==="reticle"?(t.strokeStyle="rgba(0,0,0,0.45)",t.lineWidth=3*mt,t.stroke(),t.strokeStyle="rgba(255,255,255,0.8)",t.lineWidth=1*mt,t.stroke()):(t.strokeStyle=o.lineColor,t.lineWidth=o.lineWidth*mt,t.stroke())}if(t.restore(),e.notchDir){const o=lt+e.waferCenter.x*A,f=it-e.waferCenter.y*A,n=e.notchDir.x,a=-e.notchDir.y,r=e.waferRadius*A,h=4,d=9,s=5,p=o+n*(r+h),l=f+a*(r+h),M=p+n*d,H=l+a*d,I={x:-a,y:n},L=c+Xt+ie,w=F-c-le,J=c+vt,at=G-c-Me-ae;t.save(),t.beginPath(),t.rect(L,J,w-L,at-J),t.clip(),t.beginPath(),t.moveTo(p,l),t.lineTo(M+I.x*s,H+I.y*s),t.lineTo(M-I.x*s,H-I.y*s),t.closePath(),t.fillStyle=x.text,t.fill(),t.restore()}t.save(),t.textAlign="center",t.textBaseline="middle";let Ce=0;if(e.rectangles.length>0){let o=1;for(const h of e.texts)h.role!=="indicator"&&h.text.length>o&&(o=h.text.length);const f=e.rectangles[0].width*A,n=e.rectangles[0].height*A,a=Math.min(f,n),r=f/o;Ce=Math.max(8,Math.min(64,Math.round(Math.min(a*.55,r*1.8))))}for(const o of e.texts){const f=lt+o.x*A,n=it-o.y*A;t.font=`${o.role==="indicator"?o.fontSize:Ce}px system-ui, sans-serif`,t.fillStyle=o.color,t.fillText(o.text,f,n)}if(t.restore(),bt&&To(t,F,G,lt,it,A,c,ae,Xt,q,e.gridToScreen,e.rotation,x),At){const o=co(e.valueColorScheme,e.reverseValueScheme),f=Se,n=Le,a=Math.round(n*.75),r=c+Math.round((n-a)/2),h=F-c-D-f,d=Bt,s=Pt,p=s-d,l=e.plotMode==="stackedSoftBins"?yt:ct,{primary:M,secondary:H,note:I}=z?Fe(e,Mt,l):{primary:"",secondary:"",note:void 0};if(z){const i=Math.max(r-6,c+11),P=Vt+Math.max(rt(i),rt(i-12))+8;gt(M,F-c,i,"right","bottom",P)}let L=r+a+4;const w=i=>Vt+Math.max(rt(i),rt(i+12))+8,J=e.logScale&&d>0?Math.log10(d):0,at=e.logScale&&s>0?Math.log10(s)-J:1,_=i=>e.logScale?(1-(Math.log10(i)-J)/at)*a:(1-(i-d)/p)*a;for(let i=0;i<Zt;i++){const P=1-i/(Zt-1),W=r+i/Zt*a,m=a/Zt+1;t.fillStyle=o(P),t.fillRect(h,W,D,m)}t.strokeStyle="rgba(0,0,0,0.25)",t.lineWidth=.5,t.strokeRect(h,r,D,a),t.fillStyle=x.text,t.font=v(),t.textAlign="left",t.strokeStyle="rgba(0,0,0,0.35)",t.lineWidth=.5;const C=we,It=Ve,et=14;let O;const B=e.logScale&&at>0?So(d,s,a,It,et,J,at):e.allIntegerValues?(()=>{const i=Math.max(1,Ft(p*It/a)),P=[],W=Math.ceil(d/i)*i;for(let m=W;m<=s+i*1e-6;m+=i){const R=(1-(m-d)/p)*a;R>et&&R<a-et&&P.push(Math.round(m))}return P})():(()=>{const i=p>0?Ft(p*It/a):0,P=[];if(i>0){O=i;const W=Math.ceil(d/i)*i;for(let m=W;m<=s+i*1e-6;m+=i){const R=(1-(m-d)/p)*a;R>et&&R<a-et&&P.push(m)}}return P})(),b=ee,S=te,y=Ge(s,ye,Te,Mt,O),N=e.allIntegerValues?oe:y.tickFmt,T=e.allIntegerValues?oe:y.edgeFmt;t.textBaseline="middle";for(const i of B){const P=r+_(i);t.beginPath(),t.moveTo(h+D,P),t.lineTo(h+D+C,P),t.stroke(),t.fillText(N(i),h+D+C+Jt,P)}if(t.beginPath(),t.moveTo(h+D,r),t.lineTo(h+D+C,r),t.stroke(),t.textBaseline="top",t.fillText(T(s),h+D+C+Jt,r),t.beginPath(),t.moveTo(h+D,r+a),t.lineTo(h+D+C,r+a),t.stroke(),t.textBaseline="bottom",t.fillText(T(d),h+D+C+Jt,r+a),!S&&b&&(b.limitLow!==void 0||b.limitHigh!==void 0)){const i=[],P=e.colorbarRangeMode==="spec";for(const[W,m]of[[b.limitLow,"LSL"],[b.limitHigh,"USL"]]){if(W===void 0||e.logScale&&W<=0)continue;const R=_(W);!P&&(R<-et||R>a+et)||i.push({value:W,label:m,py:Math.max(0,Math.min(a,R))})}if(i.length>0){t.save(),t.font=v(),t.textAlign="right",t.textBaseline="middle";for(const{py:W,label:m}of i){const R=r+W;P||(t.strokeStyle="rgba(255,255,255,0.85)",t.lineWidth=3,t.beginPath(),t.moveTo(h,R),t.lineTo(h+D,R),t.stroke(),t.strokeStyle="rgba(0,0,0,0.7)",t.lineWidth=1,t.beginPath(),t.moveTo(h,R),t.lineTo(h+D,R),t.stroke()),t.fillStyle=x.text,t.fillText(m,h-3,R);const Lt=m==="USL"?-1:1,kt=4,qt=h-3-t.measureText(m).width-kt-4;t.beginPath(),$e(t,qt,R,kt,Lt),t.strokeStyle="#fff",t.lineWidth=2,t.lineJoin="round",t.stroke(),t.fillStyle=x.text,t.fill()}t.restore()}}if(!S){const i=e.logScale?"log\u2081\u2080":e.logScaleRequested?"linear \u2014 log n/a":null;i&&(t.save(),t.fillStyle=x.text,t.font=Mo(),t.textAlign="right",t.textBaseline="top",t.fillText(i,F-c,L),t.restore(),L+=15)}z&&H&&(gt(H,F-c,L,"right","top",w(L),ue(),x.text),L+=15),z&&I&&gt(I,F-c,L,"right","top",w(L),ue(),x.text)}const he=[];let Q;if(nt){const o=k==="compact",f=e.plotMode==="softBin"?yt:ct,n=f?new Map(f.map(l=>[l.bin,l])):null,a=e.plotMode==="softBin"?e.binColors.soft:e.binColors.hard,r=l=>a.get(l)??ro,h=(l,M)=>{const H=t.measureText(l).width,I=o?0:t.measureText(String(M)).width,L=$+ut+H+(I?jt:0);return{labelWidth:H,countWidth:I,totalWidth:L}},d=Tt?.find(l=>l.key===e.activeMetadataKey),s=ot?st.map(l=>{const M=o?l.compactLabel:l.label;return{key:l.key,color:l.color,count:l.count,label:M,tooltipLabel:l.tooltip,...h(M,l.count)}}):e.plotMode==="metadata"?Et.map(([l,M])=>{const I=d?.values?.find(J=>J.value===l)?.label??l,L=o?l:I,w=e.metadataColorMap?.get(l)??"#d6d9dd";return{key:l,color:w,count:M,label:L,tooltipLabel:`${I} \xB7 ${M} dies`,...h(L,M)}}):Nt.map(([l,M])=>{const H=n?.get(l),I=H?.name?`${l} \xB7 ${H.name}`:`Bin ${l}`,L=o?String(l):I;return{key:l,color:r(l),count:M,label:L,tooltipLabel:`${I} \xB7 ${M} dies`,...h(L,M)}}),p=F-c*2;if(s.length>0){const l=Ct?ht*2+(z?Ke:0):z&&!_t?qe+ze:0,M=Math.max(1,Math.floor((G-2*c-l)/E));let H=s.length,I=1,L=H*E,w=[],J=0;const at=Qt||_t;if(at){const O=zt(s.map(b=>b.totalWidth)),B=Math.max(1,Math.min(s.length,Math.floor((p+8)/(O+8))));for(let b=B;b>=1;b--){const S=Math.ceil(s.length/b);if(S>M)continue;const y=new Array(b).fill(0);for(let T=0;T<s.length;T++){const i=T%b;y[i]=Math.max(y[i],s[T].totalWidth)}if(y.reduce((T,i)=>T+i,0)+(b-1)*8<=p||b===1){I=b,w=y,H=S,L=S*E;break}}}else H=Math.min(s.length,M),L=H*E,s.length>M&&(J=s.length-(M-1)),w=[Yt];let _,C;if(Ct){const O=zt(s.map(i=>$+ut+t.measureText(i.label).width+jt)),B=Math.ceil(O);w=[B];const b=z?Ke:0,S=B+ht*2,y=L+b+ht*2,N=xt?.x??0,T=xt?.y??0;_=Math.min(Math.max(F-c-S+N,c),F-c-S),C=Math.min(Math.max(G-c-y+T,c),G-c-y),Q={x:_,y:C,w:S,h:y},t.save(),t.globalAlpha=.92,t.fillStyle=x.surface,t.fillRect(_,C,S,y),t.globalAlpha=1,t.strokeStyle=x.axisLine,t.lineWidth=1,t.strokeRect(_,C,S,y),t.restore(),_+=ht,C+=ht+b}else Qt?(_=c,C=G-c-L):_t?(_=c,C=c):pe?(_=c+4,C=Math.max(c+Math.round((G-2*c-L)/2),c+l)):(_=F-c-Yt+4,C=Math.max(c+Math.round((G-2*c-L)/2),c+l));if(z){const O=e.plotMode==="softBin"?yt:ct,{primary:B,secondary:b,note:S}=Fe(e,Mt,O),y=ze,N=[b,S].filter(m=>!!m),T=(m,R,Lt)=>N.forEach((kt,qt)=>gt(kt,m,R+qt*16,"left","top",Lt(R+qt*16),ue(),x.text)),i=m=>Vt-Math.max(rt(m),rt(m-12))-8,P=m=>dt?F-c:i(m),W=Ct?Q.y+Q.h:C+L;if(_t){const m=W+y;gt(B,_,m,"left","top",Vt-Math.max(rt(m),rt(m+12))-8),T(_,m+16,i)}else if(Ct)gt(B,Q.x+ht,Q.y+ht,"left","top",Q.x+Q.w-ht),T(Q.x,W+y,()=>Q.x+Q.w);else{const m=Math.max(C-y,c+qe);gt(B,_,m,"left","bottom",P(m)),T(_,W+y,P)}}t.save(),t.font=v();const It=at?8:0,et=(O,B)=>{if(t.measureText(O).width<=B)return O;let b=0,S=O.length;const y="\u2026",N=t.measureText(y).width;for(;b<S;){const T=b+S+1>>1;t.measureText(O.slice(0,T)).width+N<=B?b=T:S=T-1}return b===0?y:O.slice(0,b)+y};if(at){let O=0;for(let B=0;B<H;B++){let b=_;for(let S=0;S<I;S++){const y=s[O++];if(!y)break;const N=y.key===Y,T=!N&&y.key===j,i=b,P=b+$+ut,W=C+B*E+E/2,m=C+B*E+Math.round((E-$)/2),R=w[S]-$-ut-jt;T&&(t.fillStyle=x.hoverRow,t.fillRect(b,C+B*E,w[S],E)),t.fillStyle=y.color,t.fillRect(i,m,$,$),t.strokeStyle=N?x.accent:"rgba(0,0,0,0.25)",t.lineWidth=N?2:.75,t.strokeRect(i,m,$,$),t.fillStyle=N?x.accent:x.text,t.font=N?`bold ${v()}`:v(),t.textAlign="left",t.textBaseline="middle",t.fillText(et(y.label,R),P,W),t.fillStyle=x.textMuted,t.font=v(),t.textAlign="right",t.fillText(String(y.count),b+w[S]-2,W),he.push({bin:y.key,x:b,y:C+B*E,w:w[S],h:E,label:y.tooltipLabel}),b+=w[S]+It}}}else{const O=w[0],B=k!=="compact",b=O-$-ut-(B?jt:0),S=_+O-2;let y=s;J>0&&(y=s.slice(0,M-1));let N=C;for(const T of y){const i=T.key===Y,P=!i&&T.key===j,W=_,m=_+$+ut,R=N+E/2,Lt=N+Math.round((E-$)/2),kt=T.label;P&&(t.fillStyle=x.hoverRow,t.fillRect(_-3,N,O+3,E)),t.fillStyle=T.color,t.fillRect(W,Lt,$,$),t.strokeStyle=i?x.accent:"rgba(0,0,0,0.25)",t.lineWidth=i?2:.75,t.strokeRect(W,Lt,$,$),t.fillStyle=i?x.accent:x.text,t.font=i?`bold ${v()}`:v(),t.textAlign="left",t.textBaseline="middle",t.fillText(et(kt,b),m,R),(B||Ct)&&(t.fillStyle=x.textMuted,t.font=v(),t.textAlign="right",t.fillText(String(T.count),S,R)),he.push({bin:T.key,x:_,y:N,w:O,h:E,label:T.tooltipLabel}),N+=E}J>0&&(t.fillStyle=x.textMuted,t.font=v(),t.textAlign="left",t.textBaseline="middle",t.fillText(`+ ${J} more`,_+$+ut,N+E/2))}}s.length>0&&t.restore()}const oo={originX:lt,originY:it,ppm:A,snapDist:wt},Be=e.rectangles[0]?.width??1,Pe=e.rectangles[0]?.height??1,ft=e.dieBounds,Ut=ft?ft.minX:K.length?Ne(K.map(o=>o.x)):0,Kt=ft?ft.minY:K.length?Ne(K.map(o=>o.y)):0,no=ft?ft.maxX:K.length?zt(K.map(o=>o.x)):1,so=ft?ft.maxY:K.length?zt(K.map(o=>o.y)):1,{cellW:de,cellH:ge,nCols:Dt,nRows:me}=go(no-Ut,so-Kt,Be*1.5,Pe*1.5,K.length),De=Array.from({length:Dt*me},()=>[]);for(let o=0;o<K.length;o++){const f=Math.floor((K[o].x-Ut)/de),n=Math.floor((K[o].y-Kt)/ge),a=Number.isFinite(f)?Math.max(0,Math.min(Dt-1,f)):0,r=Number.isFinite(n)?Math.max(0,Math.min(me-1,n)):0;De[r*Dt+a].push(o)}function Ie(o,f,n){const a=Math.max(0,Math.floor((o-n-Ut)/de)),r=Math.min(Dt-1,Math.floor((o+n-Ut)/de)),h=Math.max(0,Math.floor((f-n-Kt)/ge)),d=Math.min(me-1,Math.floor((f+n-Kt)/ge)),s=[];for(let p=h;p<=d;p++)for(let l=a;l<=r;l++)for(const M of De[p*Dt+l])s.push(M);return s}return{hitTarget:{getDieAtPoint(o,f){const n=(o-lt)/A,a=(it-f)/A,r=Math.max(Be,Pe);for(const s of Ie(n,a,r)){const p=e.rectangles[s];if(p&&Math.abs(n-p.x)<=p.width/2&&Math.abs(a-p.y)<=p.height/2)return e.dies[s]??null}let h=null,d=wt*wt;for(const s of Ie(n,a,wt)){const p=K[s].x-n,l=K[s].y-a,M=p*p+l*l;M<d&&(d=M,h=e.dies[s]??null)}return h}},viewport:oo,binLegendRows:he,legendBox:Q}}function To(g,e,X,x,c,V,U,D,pt,tt,xt,bt,q){g.save(),g.font=yo(),g.fillStyle=q.text,g.strokeStyle=q.axisLine,g.lineWidth=.5;const Z=X-D+4,Y=U+pt-4,j=io(xt),Mt=Oe(j,1,0),Ot=Oe(j,0,1),ct=1e-9;function yt(u){return tt?Math.abs(u.y)<ct&&Math.abs(u.x)>ct?{pitch:tt.x,sign:Math.sign(u.x)}:Math.abs(u.x)<ct&&Math.abs(u.y)>ct?{pitch:tt.y,sign:Math.sign(u.y)}:null:null}const Tt=yt(Mt),z=yt(Ot);function F(u){return Tt?Math.round(u*Tt.sign/Tt.pitch):u}function G(u){return z?Math.round(u*z.sign/z.pitch):u}function St(u){if(!u)return Ft(50/V);const k=50/(u*V);return Math.max(1,Math.round(k))*u}const At=Tt?.pitch,Rt=z?.pitch,ot=St(At),nt=St(Rt);g.textAlign="center",g.textBaseline="top";const Nt=Math.ceil((U-x)/V/ot)*ot,Et=(e-U-x)/V;for(let u=Nt;u<=Et;u+=ot){const k=x+u*V;if(k<U||k>e-U)continue;g.beginPath(),g.moveTo(k,Z-Ue),g.lineTo(k,Z),g.stroke();const dt=tt?String(F(u)):Xe(u);g.fillText(dt,k,Z+2)}g.textAlign="right",g.textBaseline="middle";const st=Math.ceil((c-(X-U))/V/nt)*nt,Ht=(c-U)/V;for(let u=st;u<=Ht;u+=nt){const k=c-u*V;if(k<U||k>X-U)continue;g.beginPath(),g.moveTo(Y,k),g.lineTo(Y+Ue,k),g.stroke();const dt=tt?String(G(u)):Xe(u);g.fillText(dt,Y-2,k)}g.restore()}function So(g,e,X,x,c,V,U){const D=[],pt=U;if(pt<1){const q=Ft((e-g)*x/X);if(q>0){const Z=Math.ceil(g/q)*q;for(let Y=Z;Y<=e+q*1e-6;Y+=q){if(Y<=g||Y>=e)continue;const j=(1-(Math.log10(Y)-V)/U)*X;j>c&&j<X-c&&D.push(Y)}}return D}const tt=pt<3?[1,2,5]:[1],xt=Math.floor(Math.log10(g)),bt=Math.ceil(Math.log10(e));for(let q=xt;q<=bt;q++)for(const Z of tt){const Y=Z*Math.pow(10,q);if(Y<=g||Y>=e)continue;const j=(1-(Math.log10(Y)-V)/U)*X;j>c&&j<X-c&&D.push(Y)}return D}export{fmt,fmtColorbarAxis}from"../renderer/fmt.js";
@@ -433,7 +433,19 @@ export declare function reparentTooltip(parent?: HTMLElement): void;
433
433
  * be feasible: flip to just below it, else just above it. A large anchor keeps
434
434
  * exactly the previous cursor-following behaviour.
435
435
  */
436
- export declare function positionTooltip(tooltip: HTMLDivElement, anchor: Element, clientX: number, clientY: number): void;
436
+ /**
437
+ * Place the shared tooltip beside the pointer, inside the viewport.
438
+ *
439
+ * By default it also keeps off `anchor` when that is small enough to step
440
+ * around — a toolbar button's tip must not cover the button. Pass
441
+ * `followPointer` when the pointer is on the very content the tip describes (a
442
+ * die on the map): there is nothing to step around, and stepping clear of the
443
+ * whole canvas threw the tip hundreds of pixels from the die whenever the map
444
+ * was under 40% of the window tall — every gallery card.
445
+ */
446
+ export declare function positionTooltip(tooltip: HTMLDivElement, anchor: Element, clientX: number, clientY: number, opts?: {
447
+ followPointer?: boolean;
448
+ }): void;
437
449
  /**
438
450
  * Wire the shared themed tooltip onto a plain DOM element.
439
451
  *
@@ -464,7 +476,9 @@ export interface ToolbarHelpers {
464
476
  makeBtn(iconKey: string, label: string, onClick: () => void): HTMLButtonElement;
465
477
  setActive(btn: HTMLButtonElement, active: boolean): void;
466
478
  makeSep(): HTMLDivElement;
467
- makeMenuRow(label: string, active: boolean, indent: boolean, onClick: (e: MouseEvent) => void): HTMLDivElement;
479
+ makeMenuRow(label: string, active: boolean, indent: boolean, onClick: (e: MouseEvent) => void, mark?: {
480
+ derived: boolean;
481
+ }): HTMLDivElement;
468
482
  makeMenuSection(label: string): HTMLDivElement;
469
483
  makeDropdown<T extends string>(iconKey: string, title: string, getItems: () => Array<{
470
484
  value: T;
@@ -481,12 +495,15 @@ export interface ToolbarHelpers {
481
495
  getOpenMenu(): HTMLDivElement | null;
482
496
  setOpenMenu(menu: HTMLDivElement | null): void;
483
497
  }
498
+ /** `label` is the plain name (with unit); `derived` puts the † in front of it
499
+ * when the menu draws the row — kept apart so the menu can align it in a slot. */
484
500
  export type ModeEntry = {
485
501
  plotMode: PlotMode;
486
502
  activeTest?: number;
487
503
  activeMetadataKey?: string;
488
504
  label: string;
489
505
  logScale?: boolean;
506
+ derived?: true;
490
507
  };
491
508
  /**
492
509
  * Which plot modes the data actually supports — the single derivation shared by
@@ -681,6 +698,9 @@ export interface OverlayHandle {
681
698
  close: () => void;
682
699
  /** Raise this window above other open windows. No-op in 'modal' mode. */
683
700
  bringToFront: () => void;
701
+ /** Replace the box's natural height (see `OverlayOptions.boxSize`) — applied
702
+ * now unless maximized or minimized, and restored to from either. */
703
+ setNaturalHeight: (height: string) => void;
684
704
  }
685
705
  /** Create and open a resizable, maximizable, exclusive expand modal — dims and
686
706
  * blocks the rest of the page. See `openFloatingWindow` for the non-modal form. */
@@ -699,6 +719,14 @@ export interface ReparentModalOptions {
699
719
  };
700
720
  /** Called after the modal has closed and every element has been restored to its original position (or appended back, if its original spot is no longer available — see the stale-reference note above). Runs once, even if nothing was actually moved (the re-entrancy guard tripped). */
701
721
  onClosed?: () => void;
722
+ /**
723
+ * Where to resolve the modal's root from — see `OverlayOptions.anchor`.
724
+ * Defaults to `elements[0]`, which is right whenever that element is already
725
+ * on the page. Pass one explicitly when it is not: an element built only to
726
+ * be shown in the modal (a drilldown chart card) has no parent, so resolving
727
+ * from it lands on bare `doc.body`, behind a host's own `<dialog>`.
728
+ */
729
+ anchor?: Element;
702
730
  }
703
731
  /**
704
732
  * Reparent one or more elements (moved together, in the given order) into a
@@ -1,4 +1,4 @@
1
- import{getUniqueTestNumbers as ve}from"../renderer/buildView.js";import{dieHasTestData as ge}from"../renderer/buildWaferMap.js";import{prettyKey as ye}from"../core/utils.js";import{listBinColorSchemes as we,listValueColorSchemes as ke}from"../renderer/colorSchemes.js";import{ICONS as $}from"./icons.js";import{WMAP_VERSION as Ee,WMAP_BUILD_TIME as Ce}from"./version.js";import{openHtmlReport as Le}from"../stats/renderFindingsReport.js";import{buildWaferMap as Ae}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Me}from"../stats/analyzeWaferMap.js";let le=!1;export function logWmapVersionOnce(){le||(le=!0,console.log(`[wmap] v${Ee} (built ${Ce})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","control-border","menu-hover","menu-active","font-family","font-size","density","panel-bg","text-muted","text","text-strong","warn-bg","warn-border","warn-text","err-bg","err-border","err-text","info-bg","info-text","selected","finding-indicator","canvas-bg","bar-fill"];const E=(e,n)=>`var(--wmap-${e}, ${n})`,q="var(--wmap-font-size, 12px)",Se="var(--wmap-density, 1)",N=e=>`calc(${e}px * ${Se})`;export function wireControlHover(e,n="outlined"){let t=null;const o=()=>{t&&(e.style.background=t.background,e.style.color=t.color)};e.addEventListener("mouseenter",()=>{e.dataset.on==="true"||e.disabled||(t||(t={background:e.style.background,color:e.style.color}),e.style.background=CLR.bgHover,e.style.color=CLR.iconHover)}),e.addEventListener("mouseleave",o),e.addEventListener("blur",o)}export function controlStyle(e,n=!1){const t={fontSize:FONT.body,cursor:"pointer",borderRadius:RADIUS.control};return e==="bare"?{...t,border:"none",background:"none",padding:"0",color:CLR.icon}:{...t,border:`1px solid ${CLR.controlBorder}`,background:e==="toggle"&&n?CLR.menuActive:"none",color:e==="toggle"&&n?CLR.iconActive:CLR.text,padding:`${SPACE.xxs} ${SPACE.lg}`}}export const SPACE={xxs:N(2),xs:N(4),sm:N(6),md:N(8),lg:N(10),xl:N(12),xxl:N(16),xxxl:N(24)},SHADOW={panel:"0 1px 4px rgba(0,0,0,0.10)",menu:"0 4px 12px rgba(0,0,0,0.15)",modal:"0 20px 60px rgba(0,0,0,0.40)"},MOTION={fast:"0.12s ease",base:"0.2s ease"},LEADING={none:"1",tight:"1.2",base:"1.45"},ALPHA={muted:"0.85",disabled:"0.4"},TRACKING="0.05em",EDGE_GUTTER=SPACE.xl,MAP_CHROME_INSET=SPACE.xs,RADIUS={control:"4px",container:"6px",pill:"999px"},FONT={family:"var(--wmap-font-family, inherit)",meta:`calc(${q} - 1px)`,body:q,sub:`calc(${q} + 1px)`,heading:`calc(${q} + 3px)`,stat:`calc(${q} + 8px)`};export function fontPx(e=0,n){const t=n?.ownerDocument??(typeof document<"u"?document:null);if(!t)return 12+e;const o=getComputedStyle(n??t.documentElement).getPropertyValue("--wmap-font-size").trim(),r=o?parseFloat(o):NaN;return(Number.isFinite(r)?r:12)+e}export const CLR={icon:E("icon","#506784"),iconHover:E("icon-hover","#2a3f5f"),iconActive:E("icon-active","#1a65ca"),bgHover:E("bg-hover","#edf0f8"),bgActive:E("bg-active","#dce8f8"),separator:E("separator","rgba(0,0,0,0.12)"),menuBg:E("surface","#fff"),menuBorder:E("border","rgba(0,0,0,0.12)"),controlBorder:E("control-border",E("border","rgba(0,0,0,0.30)")),menuHover:E("menu-hover","#f0f4fc"),menuActive:E("menu-active","#dce8f8"),canvasBg:`var(--wmap-canvas-bg, ${E("surface","#f5f5f5")})`,panelBg:E("panel-bg","#fafbfc"),label:E("text-muted","#647687"),value:E("text-strong","#1f2f43"),text:E("text","#333"),warnBg:E("warn-bg","#fffbe6"),warnBorder:E("warn-border","#f0c040"),warnText:E("warn-text","#7a5800"),errBg:E("err-bg","#fef2f2"),errBorder:E("err-border","#dc8a8a"),errText:E("err-text","#7a1c1c"),infoBg:E("info-bg","#dce8f8"),infoText:E("info-text","#334155"),findingHighlight:E("selected","#e07a20"),findingIndicator:E("finding-indicator","#b7551a"),barFill:E("bar-fill","#2a6fc0")};export function sevColor(e){return e==="unusual"?"#a84112":e==="notable"?"#8a6500":CLR.icon}export const ROTATIONS=[0,90,180,270],INLINE_TEST_LIMIT=6,MENU_SEARCH_THRESHOLD=8,DEFAULT_OVERLAY_Z=6e3,Z_BASE=`var(--wmap-z, ${DEFAULT_OVERLAY_Z})`,Z_ABOVE=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 1)`,Z_MENU=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 2)`,Z_ABOVE2=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 3)`;export function applyOverlayZ(e){if(e==null)return()=>{};const n=document.documentElement,t=n.style.getPropertyValue("--wmap-z");return n.style.setProperty("--wmap-z",String(e)),()=>{t?n.style.setProperty("--wmap-z",t):n.style.removeProperty("--wmap-z")}}export function copyWmapThemeTokens(e,n){const t=getComputedStyle(e);for(const o of WMAP_TOKEN_NAMES){const r=t.getPropertyValue(`--wmap-${o}`).trim();r&&n.style.setProperty(`--wmap-${o}`,r)}}export function syncWmapPopupTheme(e,n,t){const o=()=>{copyWmapThemeTokens(e,n),t?.()},r=new window.MutationObserver(o);r.observe(e,{attributes:!0,attributeFilter:["style","class"]}),r.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const l=window.matchMedia("(prefers-color-scheme: dark)");return l.addEventListener("change",o),()=>{r.disconnect(),l.removeEventListener("change",o)}}let re=null;export function setDetachWindowOpener(e){re=e}export function openDetachWindow(e){return re?re(e):window.open("","_blank","width=560,height=600")}export const MODE_LABELS={value:"Test Value",hardBin:"Hard Bin",softBin:"Soft Bin",stackedValues:"Stacked Test Values",stackedBins:"Stacked Hard Bins",stackedSoftBins:"Stacked Soft Bins",metadata:"Metadata"},BIN_LEGEND_MODES=new Set(["hardBin","softBin","metadata"]),STACKED_MODES=new Set(["stackedValues","stackedBins","stackedSoftBins"]);export function saveImageBlob(e,n,t){const o=`${n}.png`;if(t){t(e,o);return}downloadBlob(e,o)}export function downloadBlob(e,n){const t=URL.createObjectURL(e),o=document.createElement("a");o.href=t,o.download=n,o.click(),URL.revokeObjectURL(t)}export function saveTextFile(e,n,t,o){if(o){o(e,n,t);return}downloadBlob(new Blob([e],{type:t}),n)}const Be='[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';export function nextFrame(e,n=window){const t=n.requestAnimationFrame;typeof t=="function"?t.call(n,e):setTimeout(e,0)}export function wireListNavigation(e,n,t){e.addEventListener("keydown",o=>{const r=n();if(r.length===0)return;const l=e.ownerDocument.activeElement,u=l?r.indexOf(l):-1;switch(o.key){case"ArrowDown":o.preventDefault(),r[u<0||u===r.length-1?0:u+1].focus();break;case"ArrowUp":o.preventDefault(),r[u<=0?r.length-1:u-1].focus();break;case"Home":o.preventDefault(),r[0].focus();break;case"End":o.preventDefault(),r[r.length-1].focus();break;case"Enter":case" ":u>=0&&(o.preventDefault(),r[u].click());break;case"Escape":case"Tab":o.preventDefault(),t();break}})}function J(e,n,t){const o=()=>Array.from(e.querySelectorAll(Be));wireListNavigation(e,o,()=>{t(),n?.focus()});const r=o()[0];r&&nextFrame(()=>r.focus())}export function overlayRootFor(e){let n=e;for(;n;){if(n.classList.contains("wmap-overlay-box")||n.tagName==="DIALOG"&&n.matches(":modal"))return n;n=n.parentElement}return e.ownerDocument.body}const ce=new WeakMap;export function menuLayerFor(e){const n=overlayRootFor(e),t=ce.get(n);if(t&&t.isConnected)return t;const r=e.ownerDocument.createElement("div");return r.dataset.wmapMenuLayer="1",Object.assign(r.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),n.appendChild(r),ce.set(n,r),r}const ae=new WeakMap;export function getTooltip(e=document){const n=ae.get(e);if(n&&n.isConnected)return n;const t=n??e.createElement("div");return n||(Object.assign(t.style,{position:"fixed",pointerEvents:"none",background:"rgba(30, 32, 40, 0.93)",color:"#f0f0f2",border:"1px solid rgba(255,255,255,0.10)",padding:"7px 11px",borderRadius:RADIUS.control,fontSize:FONT.sub,lineHeight:LEADING.base,maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),ae.set(e,t)),e.body.appendChild(t),t}export function hideTooltip(e=document){const n=ae.get(e);n&&(n.style.display="none")}export function reparentTooltip(e){const n=e?.ownerDocument??document,t=getTooltip(n);(e??n.body).appendChild(t)}export function positionTooltip(e,n,t,o){const r=overlayRootFor(n);e.parentElement!==r&&r.appendChild(e);const l=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const u=e.offsetWidth,i=e.offsetHeight,f=8,m=l.innerWidth,s=l.innerHeight;let y=t+14,a=o-8;y+u+f>m&&(y=t-u-6);const p=n.getBoundingClientRect();if(p.height>0&&p.height<=s*.4&&a<p.bottom&&a+i>p.top&&y<p.right&&y+u>p.left){const c=p.bottom+f,b=p.top-i-f;c+i+f<=s?a=c:b>=f&&(a=b)}a+i+f>s&&(a=s-i-f),a<f&&(a=f),e.style.left=`${y}px`,e.style.top=`${a}px`}export function wireTooltip(e,n,t={}){const o=()=>(typeof n=="function"?n():n)??e.getAttribute("aria-label")??"";t.asDataPoint&&(e.tabIndex=0,e.setAttribute("role","img"),typeof n=="string"&&e.setAttribute("aria-label",n));const r=u=>{const i=o();if(!i)return;const f=getTooltip(e.ownerDocument);if(f.textContent=i,f.style.display="block",u)positionTooltip(f,e,u.clientX,u.clientY);else{const m=e.getBoundingClientRect();positionTooltip(f,e,m.left+m.width/2,m.top)}},l=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",r),e.addEventListener("mouseleave",l),e.addEventListener("focus",()=>r()),e.addEventListener("blur",l)}export function buildDataModeEntries(e,n,t){const o=e.some(ge),r=e.some(s=>s.testValues!==void 0&&Object.keys(s.testValues).length>0),l=e.some(s=>s.hbin!=null),u=e.some(s=>s.sbin!=null),i=o?n!==void 0?n.map(s=>({plotMode:"value",activeTest:s.testNumber,label:s.unit?`${s.name} (${s.unit})`:s.name,logScale:s.logScale})):ve(e).map(s=>({plotMode:"value",activeTest:s,label:`Test ${s}`})):[],f=[...l?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...u?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],m=t.includeStacked?[...r?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...l?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...u?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:i,binEntries:f,stackedEntries:m}}export function metadataKeyHasData(e,n){return e.some(t=>t.metadata?.[n]!==void 0&&t.metadata?.[n]!==null)}export function metadataModeEntry(e){return{plotMode:"metadata",activeMetadataKey:e.key,label:e.label??ye(e.key)}}export function makeMenuSearchBox(e,n="Filter\u2026",t=document){const o=t.createElement("input");return o.type="text",o.placeholder=n,o.setAttribute("aria-label",n),Object.assign(o.style,{display:"block",width:"calc(100% - 20px)",margin:"2px 10px 6px",padding:`${SPACE.xs} ${SPACE.md}`,fontSize:FONT.body,boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,outline:"none"}),o.addEventListener("click",r=>r.stopPropagation()),o.addEventListener("mousedown",r=>r.stopPropagation()),o.addEventListener("keydown",r=>r.stopPropagation()),o.addEventListener("input",()=>e(o.value.trim().toLowerCase())),o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder}),queueMicrotask(()=>o.focus()),o}export function buildModeMenuEl(e,n,t,o,r,l,u,i,f=window,m=[]){const{makeMenuRow:s,makeMenuSection:y}=u,a=document.createElement("div"),p=180,d=e.left+p<=(f.innerWidth??1/0)?e.left:Math.max(4,e.right-p);if(Object.assign(a.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${d}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${p}px`,padding:"4px 0",pointerEvents:"auto"}),n.length)if(a.appendChild(y("Test Value")),n.length<=INLINE_TEST_LIMIT)for(const c of n)a.appendChild(s(c.label,r(c),!0,b=>{b.stopPropagation(),l(c,a)}));else{const c=i==="value",b=s(MODE_LABELS.value+" \u25B6",c,!1,g=>{g.stopPropagation(),A(),M(),g.detail===0&&T()});b.setAttribute("aria-haspopup","menu"),b.style.display="flex",b.style.justifyContent="space-between",b.style.alignItems="center";let v=null,w=null;const A=()=>{w!==null&&(clearTimeout(w),w=null)},C=g=>{const S=g.target;S&&(b.contains(S)||v?.contains(S))||L()},L=()=>{A(),v?.remove(),v=null,f.document.removeEventListener("click",C),b.setAttribute("aria-expanded","false")},T=()=>{const g=v?.querySelector('input, [role="menuitemradio"]');g&&nextFrame(()=>g.focus(),f)},B=()=>{A(),w=setTimeout(L,300)},M=()=>{if(v)return;const g=b.getBoundingClientRect(),S=160,F=320,H=g.right+2+S<=(f.innerWidth??1/0)?g.right+2:Math.max(4,g.left-2-S),X=Math.min(g.top-4,Math.max(4,(f.innerHeight??1/0)-F-4));if(v=document.createElement("div"),v.setAttribute("data-wmap-submenu",""),v.setAttribute("role","menu"),Object.assign(v.style,{position:"fixed",top:`${X}px`,left:`${H}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${S}px`,maxHeight:`${F}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),n.length>MENU_SEARCH_THRESHOLD){const k=makeMenuSearchBox(j=>{for(const V of I)V.row.style.display=V.label.includes(j)?"":"none"},"Filter tests\u2026");Object.assign(k.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),v.appendChild(k)}const I=[];for(const k of n){const j=s(k.label,r(k),!1,V=>{V.stopPropagation(),L(),l(k,a)});I.push({row:j,label:k.label.toLowerCase()}),v.appendChild(j)}v.addEventListener("mouseenter",A),v.addEventListener("mouseleave",B),wireListNavigation(v,()=>I.filter(k=>k.row.style.display!=="none").map(k=>k.row),()=>{L(),b.focus()}),(a.parentElement??f.document.body).appendChild(v),f.document.addEventListener("click",C),b.setAttribute("aria-expanded","true")};a.addEventListener("keydown",g=>{g.key==="Escape"&&L()}),b.addEventListener("mouseenter",()=>{A(),M()}),b.addEventListener("mouseleave",B),a.appendChild(b)}if(t.length){a.appendChild(y("Bins"));for(const c of t)a.appendChild(s(c.label,r(c),!1,b=>{b.stopPropagation(),l(c,a)}))}if(m.length){a.appendChild(y("Metadata"));for(const c of m)a.appendChild(s(c.label,r(c),!1,b=>{b.stopPropagation(),l(c,a)}))}if(o.length){a.appendChild(y("Lot Aggregation"));for(const c of o)a.appendChild(s(c.label,r(c),!1,b=>{b.stopPropagation(),l(c,a)}))}return a.setAttribute("role","menu"),a.setAttribute("aria-label","Plot mode"),a}export function markMenuTrigger(e,n){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",n?"true":"false")}export function wireMenuA11y(e,n,t){J(e,n,t)}export function wireExpandToggle(e,n){const t=e.ownerDocument;let o=!1;function r(m){o!==m&&(o=m,n(o))}function l(){r(!1)}function u(){r(!o),o&&t.addEventListener("click",l,{once:!0})}const i=m=>{m.stopPropagation(),u()},f=m=>{m.key==="Enter"||m.key===" "?(m.preventDefault(),u()):m.key==="Escape"&&l()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",i),e.addEventListener("keydown",f),{isOpen:()=>o,close:l,destroy(){e.removeEventListener("click",i),e.removeEventListener("keydown",f),t.removeEventListener("click",l)}}}export function buildCheckMenuEl(e,n,t,o=window){const{makeMenuSection:r}=t,l=o.document,u=l.createElement("div"),i=168,m=e.left+i<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-i);Object.assign(u.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${m}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${i}px`,padding:"4px 0",pointerEvents:"auto"});for(const s of n)if("section"in s)u.appendChild(r(s.section));else{const y=s.enabled!==!1;if(!y&&!s.disabledHint)continue;const a=l.createElement("div");s.action?a.setAttribute("role","menuitem"):(a.setAttribute("role","menuitemcheckbox"),a.setAttribute("aria-checked",s.active?"true":"false")),a.tabIndex=-1,y||(a.setAttribute("aria-disabled","true"),wireTooltip(a,s.disabledHint)),Object.assign(a.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:y?"pointer":"default",color:y?s.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:s.active?"700":"400",background:s.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const p=l.createElement("span");Object.assign(p.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:s.active?"visible":"hidden"}),p.textContent=s.action?"":"\u2713",p.setAttribute("aria-hidden","true");const x=l.createElement("span");x.textContent=s.label,a.appendChild(p),a.appendChild(x),y?(a.addEventListener("mouseenter",()=>{s.active||(a.style.background=CLR.menuHover)}),a.addEventListener("mouseleave",()=>{a.style.background=s.active?CLR.menuActive:"transparent"}),a.addEventListener("focus",()=>{s.active||(a.style.background=CLR.menuHover)}),a.addEventListener("blur",()=>{a.style.background=s.active?CLR.menuActive:"transparent"}),a.addEventListener("click",d=>{d.stopPropagation(),s.onClick(d)})):a.addEventListener("click",d=>{d.stopPropagation()}),u.appendChild(a)}return u}export function createToolbarHelpers(e){const n=e.ownerDocument;let t=null;const o=a=>menuLayerFor(a);function r(a,p,x){const d=n.createElement("button");return d.innerHTML=$[a],d.type="button",d.ariaLabel=p,Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:RADIUS.control,background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:`background ${MOTION.fast}, color ${MOTION.fast}`,flexShrink:"0"}),d.addEventListener("mouseenter",c=>{d.dataset.active||(d.style.background=CLR.bgHover,d.style.color=CLR.iconHover),e.textContent=d.ariaLabel??p,e.style.display="block",positionTooltip(e,d,c.clientX,c.clientY)}),d.addEventListener("mousemove",c=>{e.style.display==="block"&&positionTooltip(e,d,c.clientX,c.clientY)}),d.addEventListener("mouseleave",()=>{d.dataset.active||(d.style.background="transparent",d.style.color=CLR.icon),e.style.display="none"}),d.addEventListener("click",()=>{e.style.display="none",x()}),d}function l(a,p){p?(a.dataset.active="1",a.style.background=CLR.bgActive,a.style.color=CLR.iconActive):(delete a.dataset.active,a.style.background="transparent",a.style.color=CLR.icon)}function u(){const a=n.createElement("div");return Object.assign(a.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),a}function i(a,p,x,d){const c=n.createElement("div");return c.textContent=a,c.setAttribute("role","menuitemradio"),c.setAttribute("aria-checked",p?"true":"false"),c.tabIndex=-1,Object.assign(c.style,{padding:`6px 14px 6px ${x?"26px":"14px"}`,fontSize:FONT.body,cursor:"pointer",color:p?CLR.iconActive:CLR.text,fontWeight:p?"700":"400",background:p?CLR.menuActive:"transparent",whiteSpace:"nowrap"}),c.addEventListener("mouseenter",()=>{p||(c.style.background=CLR.menuHover)}),c.addEventListener("mouseleave",()=>{c.style.background=p?CLR.menuActive:"transparent"}),c.addEventListener("focus",()=>{p||(c.style.background=CLR.menuHover)}),c.addEventListener("blur",()=>{c.style.background=p?CLR.menuActive:"transparent"}),c.addEventListener("click",d),c}function f(a){const p=n.createElement("div");return p.textContent=a,p.setAttribute("role","presentation"),Object.assign(p.style,{padding:"5px 14px 2px",fontSize:FONT.body,fontWeight:"600",letterSpacing:TRACKING,color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),p}function m(a,p,x,d,c){const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=r(a,p,()=>{if(t){b();return}const w=n.createElement("div"),A=v.getBoundingClientRect(),C=v.ownerDocument.defaultView??window,L=148,B=A.left+L<=(C.innerWidth??1/0)?A.left:Math.max(4,A.right-L);Object.assign(w.style,{position:"fixed",top:`${A.bottom+4}px`,left:`${B}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${L}px`,padding:"4px 0",pointerEvents:"auto"});for(const M of x()){const g=n.createElement("div");g.textContent=M.label,g.dataset.wmapDropdownValue=M.value;const S=M.value===d();g.setAttribute("role","menuitemradio"),g.setAttribute("aria-checked",S?"true":"false"),g.tabIndex=-1,Object.assign(g.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:S?CLR.iconActive:CLR.text,fontWeight:S?"700":"400",background:S?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const F=()=>{M.value!==d()&&(g.style.background=CLR.menuHover)},R=()=>{g.style.background=M.value===d()?CLR.menuActive:"transparent"};g.addEventListener("mouseenter",F),g.addEventListener("mouseleave",R),g.addEventListener("focus",F),g.addEventListener("blur",R),g.addEventListener("click",H=>{H.stopPropagation(),c(M.value),b()}),w.appendChild(g)}w.setAttribute("role","menu"),w.setAttribute("aria-label",p),o(v).appendChild(w),t=w,v.setAttribute("aria-expanded","true"),J(w,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),v}function s(a,p,x,d){function c(){return buildCheckMenuEl(v.getBoundingClientRect(),x().map(w=>"section"in w?w:{...w,onClick:A=>{w.onClick(A),d(v);const C=t;if(!C)return;const L=c();L.setAttribute("role","menu"),L.setAttribute("aria-label",p),C.replaceWith(L),t=L,J(L,v,b)}}),{makeMenuSection:f},v.ownerDocument.defaultView??window)}const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=r(a,p,()=>{if(t){b();return}const w=c();w.setAttribute("role","menu"),w.setAttribute("aria-label",p),o(v).appendChild(w),t=w,v.setAttribute("aria-expanded","true"),J(w,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),d(v),v}function y(a){const p=a.target?.closest?.("[data-wmap-submenu]");if(t&&!t.contains(a.target)&&!p&&(t.remove(),t=null,a.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const d of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))d.setAttribute("aria-expanded","false")}return{makeBtn:r,setActive:l,makeSep:u,makeMenuRow:i,makeMenuSection:f,makeDropdown:m,makeCheckMenuBtn:s,closeOpenMenu:y,getOpenMenu:()=>t,setOpenMenu:a=>{t=a}}}const Te=7e3;let De=0;function de(){return Te+ ++De}const He=32,Ie=6;let Oe=0;function $e(){return Oe++%Ie*He}function Re(e,n){if(n===e.body)return()=>{};let t=n;for(;t.parentElement&&t.parentElement!==e.body;)t=t.parentElement;return t===e.body?()=>{}:(t.classList.add("wmap-overlay-ancestor"),()=>t.classList.remove("wmap-overlay-ancestor"))}function ue(e){const n=e.mode==="modal",t=e.ownerDocument??document,o=t.defaultView??window,r=t.body.style.overflow;n&&(t.body.style.overflow="hidden");let l=null;n&&(l=t.createElement("div"),l.id="wmap-modal-backdrop",Object.assign(l.style,{position:"fixed",inset:"0",background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:Z_ABOVE,backdropFilter:"blur(3px)"}));const u=t.activeElement,i=t.createElement("div");i.className=n?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",i.setAttribute("role","dialog"),n&&i.setAttribute("aria-modal","true"),i.setAttribute("aria-label",e.title??"Expanded wafer map"),i.tabIndex=-1;const f=e.boxSize?.width??"min(90vw, 700px)",m=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(i.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:f,height:m,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:n?Z_ABOVE2:String(de())}),!n){const h=$e();Object.assign(i.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+h}px`,left:`${Math.round(o.innerWidth*.08)+h}px`})}const s=t.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const y={border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:LEADING.none,padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const h=t.createElement("span");h.textContent=e.title,h.title=e.title,h.dataset.wmapWindowTitle="1",Object.assign(h.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),s.appendChild(h)}const a=t.createElement("div");a.style.flex="1",s.appendChild(a);let p=null;n||(p=t.createElement("button"),p.type="button",p.innerHTML=$.collapse,p.setAttribute("aria-label","Collapse"),wireTooltip(p),Object.assign(p.style,y),wireControlHover(p),p.addEventListener("click",()=>M(!C)),s.appendChild(p));let x=null;e.printable&&(x=t.createElement("button"),x.type="button",x.innerHTML=$.print,x.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(x),Object.assign(x.style,y),wireControlHover(x),x.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),s.appendChild(x));const d=t.createElement("button");d.type="button",d.innerHTML=$.maximize,d.setAttribute("aria-label","Maximize (F)"),wireTooltip(d),Object.assign(d.style,y),wireControlHover(d),d.addEventListener("click",()=>A(!b));const c=t.createElement("button");c.type="button",c.innerHTML=$.close,c.setAttribute("aria-label","Close (Esc)"),wireTooltip(c),Object.assign(c.style,y),wireControlHover(c),c.addEventListener("click",H),s.appendChild(d),s.appendChild(c);let b=!1,v="",w="";function A(h){b=h,d.innerHTML=b?$.minimize:$.maximize,d.setAttribute("aria-label",b?"Restore (F)":"Maximize (F)"),p&&(p.style.display=b?"none":""),k.style.display=b?"none":"block",b?(i.style.borderRadius="0",i.style.width="100vw",i.style.height="100vh",n||(v=i.style.top,w=i.style.left,i.style.top="0",i.style.left="0")):(i.style.borderRadius="12px",i.style.width=f,i.style.height=m,n||(i.style.top=v,i.style.left=w)),e.onMaximizeChange?.(b,i)}let C=!1,L="",T="";const B=220;function M(h){C=h,p.innerHTML=C?$.uncollapse:$.collapse,p.setAttribute("aria-label",C?"Show contents":"Collapse"),k.style.display=C?"none":"block",C?(L=i.style.height,T=i.style.width,i.style.minHeight="0",i.style.height="auto",i.style.minWidth="0",i.style.width=`${B}px`,d.disabled=!0,d.style.opacity="0.4",d.style.cursor="default",I.style.display="none"):(i.style.minHeight="240px",i.style.height=L||m,i.style.minWidth="320px",i.style.width=T||f,d.disabled=!1,d.style.opacity="1",d.style.cursor="pointer",I.style.display="flex")}function g(){const h=t.body.style.userSelect;return t.body.style.userSelect="none",()=>{t.body.style.userSelect=h}}n||(s.style.cursor="move",s.addEventListener("pointerdown",h=>{if(b||h.target.closest('button, [role="button"]'))return;h.preventDefault();const D=g(),W=h.clientX,z=h.clientY,O=i.offsetTop,_=i.offsetLeft,ne=o.innerHeight-s.offsetHeight,oe=o.innerWidth-40,Q=40-i.offsetWidth;s.setPointerCapture(h.pointerId);const Y=G=>{const ie=Math.min(Math.max(O+(G.clientY-z),0),ne),xe=Math.min(Math.max(_+(G.clientX-W),Q),oe);i.style.top=`${ie}px`,i.style.left=`${xe}px`},U=G=>{D(),s.releasePointerCapture(G.pointerId),s.removeEventListener("pointermove",Y),s.removeEventListener("pointerup",U)};s.addEventListener("pointermove",Y),s.addEventListener("pointerup",U)}));const S='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function F(h){const D=Array.from(i.querySelectorAll(S)).filter(_=>_.offsetParent!==null||_===t.activeElement);if(D.length===0){h.preventDefault(),i.focus();return}const W=D[0],z=D[D.length-1],O=t.activeElement;h.shiftKey&&(O===W||!i.contains(O))?(h.preventDefault(),z.focus()):!h.shiftKey&&O===z&&(h.preventDefault(),W.focus())}const R=h=>{if(h.key==="Escape"){H();return}if(n&&(h.key==="e"||h.key==="E")){H();return}if(n&&h.key==="Tab"){F(h);return}(h.key==="f"||h.key==="F")&&!C&&A(!b)};function H(){n?t.removeEventListener("keydown",R):i.removeEventListener("keydown",R),te.remove(),he(),hideTooltip(t),reparentTooltip(t.body),l?l.remove():i.remove(),n&&(t.body.style.overflow=r),u?.focus?.(),e.onClose()}function X(){n||(i.style.zIndex=String(de()))}const I=t.createElement("div");Object.assign(I.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const k=t.createElement("div");k.tabIndex=0,k.setAttribute("role","separator"),k.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(k.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),k.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16" style="display:block"><path d="M15 15 L15 9 M15 15 L9 15 M15 15 L15 3 M15 15 L3 15" stroke="currentColor" stroke-width="1" opacity="0.35" fill="none"/></svg>',k.style.color=CLR.label;const j=320,V=240,K=20;function Z(h,D){const W=o.innerWidth-i.offsetLeft,z=o.innerHeight-i.offsetTop,O=Math.min(Math.max(i.offsetWidth+h,j),W),_=Math.min(Math.max(i.offsetHeight+D,V),z);i.style.width=`${O}px`,i.style.height=`${_}px`}k.addEventListener("keydown",h=>{if(!(b||C))switch(h.key){case"ArrowRight":h.preventDefault(),Z(K,0);break;case"ArrowLeft":h.preventDefault(),Z(-K,0);break;case"ArrowDown":h.preventDefault(),Z(0,K);break;case"ArrowUp":h.preventDefault(),Z(0,-K);break}}),k.addEventListener("pointerdown",h=>{if(b||C)return;h.preventDefault();const D=g(),W=h.clientX,z=h.clientY,O=i.offsetWidth,_=i.offsetHeight,ne=o.innerWidth-i.offsetLeft,oe=o.innerHeight-i.offsetTop;k.setPointerCapture(h.pointerId);const Q=U=>{const G=Math.min(Math.max(O+(U.clientX-W),j),ne),ie=Math.min(Math.max(_+(U.clientY-z),V),oe);i.style.width=`${G}px`,i.style.height=`${ie}px`},Y=U=>{D(),k.releasePointerCapture(U.pointerId),k.removeEventListener("pointermove",Q),k.removeEventListener("pointerup",Y)};k.addEventListener("pointermove",Q),k.addEventListener("pointerup",Y)}),i.appendChild(s),i.appendChild(I),i.appendChild(k);const ee=e.anchor?overlayRootFor(e.anchor):t.body;l?(l.appendChild(i),ee.appendChild(l)):ee.appendChild(i);const he=Re(t,ee),te=t.createElement("style");return te.textContent=`@media print{
1
+ import{getUniqueTestNumbers as ke}from"../renderer/buildView.js";import{dieHasTestData as Ee}from"../renderer/buildWaferMap.js";import{testLabel as re,isDerivedTest as Ce,DERIVED_MARK as ce,DERIVED_KEY as de}from"../renderer/testLabel.js";import{prettyKey as Le}from"../core/utils.js";import{listBinColorSchemes as Ae,listValueColorSchemes as Me}from"../renderer/colorSchemes.js";import{ICONS as W}from"./icons.js";import{WMAP_VERSION as Se,WMAP_BUILD_TIME as Be}from"./version.js";import{openHtmlReport as De}from"../stats/renderFindingsReport.js";import{buildWaferMap as Te}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as He}from"../stats/analyzeWaferMap.js";let ue=!1;export function logWmapVersionOnce(){ue||(ue=!0,console.log(`[wmap] v${Se} (built ${Be})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","control-border","menu-hover","menu-active","font-family","font-size","density","panel-bg","text-muted","text","text-strong","warn-bg","warn-border","warn-text","err-bg","err-border","err-text","info-bg","info-text","selected","finding-indicator","canvas-bg","bar-fill"];const k=(e,t)=>`var(--wmap-${e}, ${t})`,K="var(--wmap-font-size, 12px)",Ie="var(--wmap-density, 1)",F=e=>`calc(${e}px * ${Ie})`;export function wireControlHover(e,t="outlined"){let n=null;const o=()=>{n&&(e.style.background=n.background,e.style.color=n.color)};e.addEventListener("mouseenter",()=>{e.dataset.on==="true"||e.disabled||(n||(n={background:e.style.background,color:e.style.color}),e.style.background=CLR.bgHover,e.style.color=CLR.iconHover)}),e.addEventListener("mouseleave",o),e.addEventListener("blur",o)}export function controlStyle(e,t=!1){const n={fontSize:FONT.body,cursor:"pointer",borderRadius:RADIUS.control};return e==="bare"?{...n,border:"none",background:"none",padding:"0",color:CLR.icon}:{...n,border:`1px solid ${CLR.controlBorder}`,background:e==="toggle"&&t?CLR.menuActive:"none",color:e==="toggle"&&t?CLR.iconActive:CLR.text,padding:`${SPACE.xxs} ${SPACE.lg}`}}export const SPACE={xxs:F(2),xs:F(4),sm:F(6),md:F(8),lg:F(10),xl:F(12),xxl:F(16),xxxl:F(24)},SHADOW={panel:"0 1px 4px rgba(0,0,0,0.10)",menu:"0 4px 12px rgba(0,0,0,0.15)",modal:"0 20px 60px rgba(0,0,0,0.40)"},MOTION={fast:"0.12s ease",base:"0.2s ease"},LEADING={none:"1",tight:"1.2",base:"1.45"},ALPHA={muted:"0.85",disabled:"0.4"},TRACKING="0.05em",EDGE_GUTTER=SPACE.xl,MAP_CHROME_INSET=SPACE.xs,RADIUS={control:"4px",container:"6px",pill:"999px"},FONT={family:"var(--wmap-font-family, inherit)",meta:`calc(${K} - 1px)`,body:K,sub:`calc(${K} + 1px)`,heading:`calc(${K} + 3px)`,stat:`calc(${K} + 8px)`};export function fontPx(e=0,t){const n=t?.ownerDocument??(typeof document<"u"?document:null);if(!n)return 12+e;const o=getComputedStyle(t??n.documentElement).getPropertyValue("--wmap-font-size").trim(),r=o?parseFloat(o):NaN;return(Number.isFinite(r)?r:12)+e}export const CLR={icon:k("icon","#506784"),iconHover:k("icon-hover","#2a3f5f"),iconActive:k("icon-active","#1a65ca"),bgHover:k("bg-hover","#edf0f8"),bgActive:k("bg-active","#dce8f8"),separator:k("separator","rgba(0,0,0,0.12)"),menuBg:k("surface","#fff"),menuBorder:k("border","rgba(0,0,0,0.12)"),controlBorder:k("control-border",k("border","rgba(0,0,0,0.30)")),menuHover:k("menu-hover","#f0f4fc"),menuActive:k("menu-active","#dce8f8"),canvasBg:`var(--wmap-canvas-bg, ${k("surface","#f5f5f5")})`,panelBg:k("panel-bg","#fafbfc"),label:k("text-muted","#647687"),value:k("text-strong","#1f2f43"),text:k("text","#333"),warnBg:k("warn-bg","#fffbe6"),warnBorder:k("warn-border","#f0c040"),warnText:k("warn-text","#7a5800"),errBg:k("err-bg","#fef2f2"),errBorder:k("err-border","#dc8a8a"),errText:k("err-text","#7a1c1c"),infoBg:k("info-bg","#dce8f8"),infoText:k("info-text","#334155"),findingHighlight:k("selected","#e07a20"),findingIndicator:k("finding-indicator","#b7551a"),barFill:k("bar-fill","#2a6fc0")};export function sevColor(e){return e==="unusual"?"#a84112":e==="notable"?"#8a6500":CLR.icon}export const ROTATIONS=[0,90,180,270],INLINE_TEST_LIMIT=6,MENU_SEARCH_THRESHOLD=8,DEFAULT_OVERLAY_Z=6e3,Z_BASE=`var(--wmap-z, ${DEFAULT_OVERLAY_Z})`,Z_ABOVE=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 1)`,Z_MENU=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 2)`,Z_ABOVE2=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 3)`;export function applyOverlayZ(e){if(e==null)return()=>{};const t=document.documentElement,n=t.style.getPropertyValue("--wmap-z");return t.style.setProperty("--wmap-z",String(e)),()=>{n?t.style.setProperty("--wmap-z",n):t.style.removeProperty("--wmap-z")}}export function copyWmapThemeTokens(e,t){const n=getComputedStyle(e);for(const o of WMAP_TOKEN_NAMES){const r=n.getPropertyValue(`--wmap-${o}`).trim();r&&t.style.setProperty(`--wmap-${o}`,r)}}export function syncWmapPopupTheme(e,t,n){const o=()=>{copyWmapThemeTokens(e,t),n?.()},r=new window.MutationObserver(o);r.observe(e,{attributes:!0,attributeFilter:["style","class"]}),r.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const l=window.matchMedia("(prefers-color-scheme: dark)");return l.addEventListener("change",o),()=>{r.disconnect(),l.removeEventListener("change",o)}}let ae=null;export function setDetachWindowOpener(e){ae=e}export function openDetachWindow(e){return ae?ae(e):window.open("","_blank","width=560,height=600")}export const MODE_LABELS={value:"Test Value",hardBin:"Hard Bin",softBin:"Soft Bin",stackedValues:"Stacked Test Values",stackedBins:"Stacked Hard Bins",stackedSoftBins:"Stacked Soft Bins",metadata:"Metadata"},BIN_LEGEND_MODES=new Set(["hardBin","softBin","metadata"]),STACKED_MODES=new Set(["stackedValues","stackedBins","stackedSoftBins"]);export function saveImageBlob(e,t,n){const o=`${t}.png`;if(n){n(e,o);return}downloadBlob(e,o)}export function downloadBlob(e,t){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=t,o.click(),URL.revokeObjectURL(n)}export function saveTextFile(e,t,n,o){if(o){o(e,t,n);return}downloadBlob(new Blob([e],{type:n}),t)}const $e='[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';export function nextFrame(e,t=window){const n=t.requestAnimationFrame;typeof n=="function"?n.call(t,e):setTimeout(e,0)}export function wireListNavigation(e,t,n){e.addEventListener("keydown",o=>{const r=t();if(r.length===0)return;const l=e.ownerDocument.activeElement,p=l?r.indexOf(l):-1;switch(o.key){case"ArrowDown":o.preventDefault(),r[p<0||p===r.length-1?0:p+1].focus();break;case"ArrowUp":o.preventDefault(),r[p<=0?r.length-1:p-1].focus();break;case"Home":o.preventDefault(),r[0].focus();break;case"End":o.preventDefault(),r[r.length-1].focus();break;case"Enter":case" ":p>=0&&(o.preventDefault(),r[p].click());break;case"Escape":case"Tab":o.preventDefault(),n();break}})}function J(e,t,n){const o=()=>Array.from(e.querySelectorAll($e));wireListNavigation(e,o,()=>{n(),t?.focus()});const r=o()[0];r&&nextFrame(()=>r.focus())}export function overlayRootFor(e){let t=e;for(;t;){if(t.classList.contains("wmap-overlay-box")||t.tagName==="DIALOG"&&t.matches(":modal"))return t;t=t.parentElement}return e.ownerDocument.body}const pe=new WeakMap;export function menuLayerFor(e){const t=overlayRootFor(e),n=pe.get(t);if(n&&n.isConnected)return n;const r=e.ownerDocument.createElement("div");return r.dataset.wmapMenuLayer="1",Object.assign(r.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),t.appendChild(r),pe.set(t,r),r}const se=new WeakMap;export function getTooltip(e=document){const t=se.get(e);if(t&&t.isConnected)return t;const n=t??e.createElement("div");return t||(Object.assign(n.style,{position:"fixed",pointerEvents:"none",background:"rgba(30, 32, 40, 0.93)",color:"#f0f0f2",border:"1px solid rgba(255,255,255,0.10)",padding:"7px 11px",borderRadius:RADIUS.control,fontSize:FONT.sub,lineHeight:LEADING.base,maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE2,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),se.set(e,n)),e.body.appendChild(n),n}export function hideTooltip(e=document){const t=se.get(e);t&&(t.style.display="none")}export function reparentTooltip(e){const t=e?.ownerDocument??document,n=getTooltip(t);(e??t.body).appendChild(n)}export function positionTooltip(e,t,n,o,r={}){const l=menuLayerFor(t);e.parentElement!==l&&l.appendChild(e);const p=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const i=e.offsetWidth,b=e.offsetHeight,d=8,a=p.innerWidth,y=p.innerHeight;let s=n+14,f=o-8;s+i+d>a&&(s=n-i-6);const x=t.getBoundingClientRect();if(!r.followPointer&&x.height>0&&x.height<=y*.4&&f<x.bottom&&f+b>x.top&&s<x.right&&s+i>x.left){const u=x.bottom+d,h=x.top-b-d;u+b+d<=y?f=u:h>=d&&(f=h)}f+b+d>y&&(f=y-b-d),f<d&&(f=d),e.style.left=`${s}px`,e.style.top=`${f}px`}export function wireTooltip(e,t,n={}){const o=()=>(typeof t=="function"?t():t)??e.getAttribute("aria-label")??"";n.asDataPoint&&(e.tabIndex=0,e.setAttribute("role","img"),typeof t=="string"&&e.setAttribute("aria-label",t));const r=p=>{const i=o();if(!i)return;const b=getTooltip(e.ownerDocument);if(b.textContent=i,b.style.display="block",p)positionTooltip(b,e,p.clientX,p.clientY);else{const d=e.getBoundingClientRect();positionTooltip(b,e,d.left+d.width/2,d.top)}},l=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",r),e.addEventListener("mouseleave",l),e.addEventListener("focus",()=>r()),e.addEventListener("blur",l)}export function buildDataModeEntries(e,t,n){const o=e.some(Ee),r=e.some(a=>a.testValues!==void 0&&Object.keys(a.testValues).length>0),l=e.some(a=>a.hbin!=null),p=e.some(a=>a.sbin!=null),i=o?t!==void 0?t.map(a=>({plotMode:"value",activeTest:a.testNumber,label:a.unit?`${re(a,a.testNumber)} (${a.unit})`:re(a,a.testNumber),logScale:a.logScale,...Ce(a)?{derived:!0}:{}})):ke(e).map(a=>({plotMode:"value",activeTest:a,label:re(void 0,a)})):[],b=[...l?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...p?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],d=n.includeStacked?[...r?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...l?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...p?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:i,binEntries:b,stackedEntries:d}}export function metadataKeyHasData(e,t){return e.some(n=>n.metadata?.[t]!==void 0&&n.metadata?.[t]!==null)}export function metadataModeEntry(e){return{plotMode:"metadata",activeMetadataKey:e.key,label:e.label??Le(e.key)}}export function makeMenuSearchBox(e,t="Filter\u2026",n=document){const o=n.createElement("input");return o.type="text",o.placeholder=t,o.setAttribute("aria-label",t),Object.assign(o.style,{display:"block",width:"calc(100% - 20px)",margin:"2px 10px 6px",padding:`${SPACE.xs} ${SPACE.md}`,fontSize:FONT.body,boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,outline:"none"}),o.addEventListener("click",r=>r.stopPropagation()),o.addEventListener("mousedown",r=>r.stopPropagation()),o.addEventListener("keydown",r=>r.stopPropagation()),o.addEventListener("input",()=>e(o.value.trim().toLowerCase())),o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder}),queueMicrotask(()=>o.focus()),o}export function buildModeMenuEl(e,t,n,o,r,l,p,i,b=window,d=[]){const{makeMenuRow:a,makeMenuSection:y}=p,s=document.createElement("div"),f=180,c=e.left+f<=(b.innerWidth??1/0)?e.left:Math.max(4,e.right-f);if(Object.assign(s.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${c}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${f}px`,padding:"4px 0",pointerEvents:"auto"}),t.length)if(s.appendChild(y("Test Value")),t.length<=INLINE_TEST_LIMIT)for(const m of t)s.appendChild(a(m.label,r(m),!0,u=>{u.stopPropagation(),l(m,s)}));else{const m=i==="value",u=a(MODE_LABELS.value+" \u25B6",m,!1,g=>{g.stopPropagation(),A(),S(),g.detail===0&&T()});u.setAttribute("aria-haspopup","menu"),u.style.display="flex",u.style.justifyContent="space-between",u.style.alignItems="center";let h=null,w=null;const A=()=>{w!==null&&(clearTimeout(w),w=null)},E=g=>{const B=g.target;B&&(u.contains(B)||h?.contains(B))||C()},C=()=>{A(),h?.remove(),h=null,b.document.removeEventListener("click",E),u.setAttribute("aria-expanded","false")},T=()=>{const g=h?.querySelector('input, [role="menuitemradio"]');g&&nextFrame(()=>g.focus(),b)},D=()=>{A(),w=setTimeout(C,300)},S=()=>{if(h)return;const g=u.getBoundingClientRect(),B=160,V=320,I=g.right+2+B<=(b.innerWidth??1/0)?g.right+2:Math.max(4,g.left-2-B),Y=Math.min(g.top-4,Math.max(4,(b.innerHeight??1/0)-V-4));if(h=document.createElement("div"),h.setAttribute("data-wmap-submenu",""),h.setAttribute("role","menu"),Object.assign(h.style,{position:"fixed",top:`${Y}px`,left:`${I}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${B}px`,maxHeight:`${V}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),t.length>MENU_SEARCH_THRESHOLD){const L=makeMenuSearchBox(U=>{for(const O of $)O.row.style.display=O.label.includes(U)?"":"none"},"Filter tests\u2026");Object.assign(L.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),h.appendChild(L)}const $=[],M=t.some(L=>L.derived);for(const L of t){const U=a(L.label,r(L),!1,O=>{O.stopPropagation(),C(),l(L,s)},M?{derived:L.derived===!0}:void 0);$.push({row:U,label:L.label.toLowerCase()}),h.appendChild(U)}if(M){const L=b.document.createElement("div");L.setAttribute("role","presentation"),L.textContent=`${ce} ${de}`,Object.assign(L.style,{padding:"6px 14px",fontSize:FONT.meta,color:CLR.label,borderTop:`1px solid ${CLR.menuBorder}`,marginTop:"4px",whiteSpace:"nowrap"}),h.appendChild(L)}h.addEventListener("mouseenter",A),h.addEventListener("mouseleave",D),wireListNavigation(h,()=>$.filter(L=>L.row.style.display!=="none").map(L=>L.row),()=>{C(),u.focus()}),(s.parentElement??b.document.body).appendChild(h),b.document.addEventListener("click",E),u.setAttribute("aria-expanded","true")};s.addEventListener("keydown",g=>{g.key==="Escape"&&C()}),u.addEventListener("mouseenter",()=>{A(),S()}),u.addEventListener("mouseleave",D),s.appendChild(u)}if(n.length){s.appendChild(y("Bins"));for(const m of n)s.appendChild(a(m.label,r(m),!1,u=>{u.stopPropagation(),l(m,s)}))}if(d.length){s.appendChild(y("Metadata"));for(const m of d)s.appendChild(a(m.label,r(m),!1,u=>{u.stopPropagation(),l(m,s)}))}if(o.length){s.appendChild(y("Lot Aggregation"));for(const m of o)s.appendChild(a(m.label,r(m),!1,u=>{u.stopPropagation(),l(m,s)}))}return s.setAttribute("role","menu"),s.setAttribute("aria-label","Plot mode"),s}export function markMenuTrigger(e,t){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",t?"true":"false")}export function wireMenuA11y(e,t,n){J(e,t,n)}export function wireExpandToggle(e,t){const n=e.ownerDocument;let o=!1;function r(d){o!==d&&(o=d,t(o))}function l(){r(!1)}function p(){r(!o),o&&n.addEventListener("click",l,{once:!0})}const i=d=>{d.stopPropagation(),p()},b=d=>{d.key==="Enter"||d.key===" "?(d.preventDefault(),p()):d.key==="Escape"&&l()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",i),e.addEventListener("keydown",b),{isOpen:()=>o,close:l,destroy(){e.removeEventListener("click",i),e.removeEventListener("keydown",b),n.removeEventListener("click",l)}}}export function buildCheckMenuEl(e,t,n,o=window){const{makeMenuSection:r}=n,l=o.document,p=l.createElement("div"),i=168,d=e.left+i<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-i);Object.assign(p.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${d}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${i}px`,padding:"4px 0",pointerEvents:"auto"});for(const a of t)if("section"in a)p.appendChild(r(a.section));else{const y=a.enabled!==!1;if(!y&&!a.disabledHint)continue;const s=l.createElement("div");a.action?s.setAttribute("role","menuitem"):(s.setAttribute("role","menuitemcheckbox"),s.setAttribute("aria-checked",a.active?"true":"false")),s.tabIndex=-1,y||(s.setAttribute("aria-disabled","true"),wireTooltip(s,a.disabledHint)),Object.assign(s.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:y?"pointer":"default",color:y?a.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:a.active?"700":"400",background:a.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const f=l.createElement("span");Object.assign(f.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:a.active?"visible":"hidden"}),f.textContent=a.action?"":"\u2713",f.setAttribute("aria-hidden","true");const x=l.createElement("span");x.textContent=a.label,s.appendChild(f),s.appendChild(x),y?(s.addEventListener("mouseenter",()=>{a.active||(s.style.background=CLR.menuHover)}),s.addEventListener("mouseleave",()=>{s.style.background=a.active?CLR.menuActive:"transparent"}),s.addEventListener("focus",()=>{a.active||(s.style.background=CLR.menuHover)}),s.addEventListener("blur",()=>{s.style.background=a.active?CLR.menuActive:"transparent"}),s.addEventListener("click",c=>{c.stopPropagation(),a.onClick(c)})):s.addEventListener("click",c=>{c.stopPropagation()}),p.appendChild(s)}return p}export function createToolbarHelpers(e){const t=e.ownerDocument;let n=null;const o=s=>menuLayerFor(s);function r(s,f,x){const c=t.createElement("button");return c.innerHTML=W[s],c.type="button",c.ariaLabel=f,Object.assign(c.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:RADIUS.control,background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:`background ${MOTION.fast}, color ${MOTION.fast}`,flexShrink:"0"}),c.addEventListener("mouseenter",m=>{c.dataset.active||(c.style.background=CLR.bgHover,c.style.color=CLR.iconHover),e.textContent=c.ariaLabel??f,e.style.display="block",positionTooltip(e,c,m.clientX,m.clientY)}),c.addEventListener("mousemove",m=>{e.style.display==="block"&&positionTooltip(e,c,m.clientX,m.clientY)}),c.addEventListener("mouseleave",()=>{c.dataset.active||(c.style.background="transparent",c.style.color=CLR.icon),e.style.display="none"}),c.addEventListener("click",()=>{e.style.display="none",x()}),c}function l(s,f){f?(s.dataset.active="1",s.style.background=CLR.bgActive,s.style.color=CLR.iconActive):(delete s.dataset.active,s.style.background="transparent",s.style.color=CLR.icon)}function p(){const s=t.createElement("div");return Object.assign(s.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),s}function i(s,f,x,c,m){const u=t.createElement("div");if(m){const h=t.createElement("span");h.textContent=m.derived?ce:"",h.setAttribute("aria-hidden","true"),Object.assign(h.style,{display:"inline-block",width:"1.1em"}),u.append(h,s),m.derived&&u.setAttribute("aria-label",`${s} \u2014 ${de.toLowerCase()}`)}else u.textContent=s;return u.setAttribute("role","menuitemradio"),u.setAttribute("aria-checked",f?"true":"false"),u.tabIndex=-1,Object.assign(u.style,{padding:`6px 14px 6px ${x?"26px":"14px"}`,fontSize:FONT.body,cursor:"pointer",color:f?CLR.iconActive:CLR.text,fontWeight:f?"700":"400",background:f?CLR.menuActive:"transparent",whiteSpace:"nowrap"}),u.addEventListener("mouseenter",()=>{f||(u.style.background=CLR.menuHover)}),u.addEventListener("mouseleave",()=>{u.style.background=f?CLR.menuActive:"transparent"}),u.addEventListener("focus",()=>{f||(u.style.background=CLR.menuHover)}),u.addEventListener("blur",()=>{u.style.background=f?CLR.menuActive:"transparent"}),u.addEventListener("click",c),u}function b(s){const f=t.createElement("div");return f.textContent=s,f.setAttribute("role","presentation"),Object.assign(f.style,{padding:"5px 14px 2px",fontSize:FONT.body,fontWeight:"600",letterSpacing:TRACKING,color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),f}function d(s,f,x,c,m){const u=()=>{n&&(n.remove(),n=null),h.setAttribute("aria-expanded","false")},h=r(s,f,()=>{if(n){u();return}const w=t.createElement("div"),A=h.getBoundingClientRect(),E=h.ownerDocument.defaultView??window,C=148,D=A.left+C<=(E.innerWidth??1/0)?A.left:Math.max(4,A.right-C);Object.assign(w.style,{position:"fixed",top:`${A.bottom+4}px`,left:`${D}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${C}px`,padding:"4px 0",pointerEvents:"auto"});for(const S of x()){const g=t.createElement("div");g.textContent=S.label,g.dataset.wmapDropdownValue=S.value;const B=S.value===c();g.setAttribute("role","menuitemradio"),g.setAttribute("aria-checked",B?"true":"false"),g.tabIndex=-1,Object.assign(g.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:B?CLR.iconActive:CLR.text,fontWeight:B?"700":"400",background:B?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const V=()=>{S.value!==c()&&(g.style.background=CLR.menuHover)},z=()=>{g.style.background=S.value===c()?CLR.menuActive:"transparent"};g.addEventListener("mouseenter",V),g.addEventListener("mouseleave",z),g.addEventListener("focus",V),g.addEventListener("blur",z),g.addEventListener("click",I=>{I.stopPropagation(),m(S.value),u()}),w.appendChild(g)}w.setAttribute("role","menu"),w.setAttribute("aria-label",f),o(h).appendChild(w),n=w,h.setAttribute("aria-expanded","true"),J(w,h,u)});return h.setAttribute("aria-haspopup","menu"),h.setAttribute("aria-expanded","false"),h}function a(s,f,x,c){function m(){return buildCheckMenuEl(h.getBoundingClientRect(),x().map(w=>"section"in w?w:{...w,onClick:A=>{w.onClick(A),c(h);const E=n;if(!E)return;const C=m();C.setAttribute("role","menu"),C.setAttribute("aria-label",f),E.replaceWith(C),n=C,J(C,h,u)}}),{makeMenuSection:b},h.ownerDocument.defaultView??window)}const u=()=>{n&&(n.remove(),n=null),h.setAttribute("aria-expanded","false")},h=r(s,f,()=>{if(n){u();return}const w=m();w.setAttribute("role","menu"),w.setAttribute("aria-label",f),o(h).appendChild(w),n=w,h.setAttribute("aria-expanded","true"),J(w,h,u)});return h.setAttribute("aria-haspopup","menu"),h.setAttribute("aria-expanded","false"),c(h),h}function y(s){const f=s.target?.closest?.("[data-wmap-submenu]");if(n&&!n.contains(s.target)&&!f&&(n.remove(),n=null,s.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const c of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))c.setAttribute("aria-expanded","false")}return{makeBtn:r,setActive:l,makeSep:p,makeMenuRow:i,makeMenuSection:b,makeDropdown:d,makeCheckMenuBtn:a,closeOpenMenu:y,getOpenMenu:()=>n,setOpenMenu:s=>{n=s}}}const Oe=7e3;let Re=0;function fe(){return Oe+ ++Re}const We=32,ze=6;let _e=0;function Ne(){return _e++%ze*We}function Pe(e,t){if(t===e.body)return()=>{};let n=t;for(;n.parentElement&&n.parentElement!==e.body;)n=n.parentElement;return n===e.body?()=>{}:(n.classList.add("wmap-overlay-ancestor"),()=>n.classList.remove("wmap-overlay-ancestor"))}function me(e){const t=e.mode==="modal",n=e.ownerDocument??document,o=n.defaultView??window,r=n.body.style.overflow;t&&(n.body.style.overflow="hidden");let l=null;t&&(l=n.createElement("div"),l.id="wmap-modal-backdrop",Object.assign(l.style,{position:"fixed",inset:"0",background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:Z_ABOVE,backdropFilter:"blur(3px)"}));const p=n.activeElement,i=n.createElement("div");i.className=t?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",i.setAttribute("role","dialog"),t&&i.setAttribute("aria-modal","true"),i.setAttribute("aria-label",e.title??"Expanded wafer map"),i.tabIndex=-1;const b=e.boxSize?.width??"min(90vw, 700px)";let d=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(i.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:b,height:d,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:t?Z_ABOVE2:String(fe())}),!t){const v=Ne();Object.assign(i.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+v}px`,left:`${Math.round(o.innerWidth*.08)+v}px`})}const a=n.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const y={border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:LEADING.none,padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const v=n.createElement("span");v.textContent=e.title,v.title=e.title,v.dataset.wmapWindowTitle="1",Object.assign(v.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),a.appendChild(v)}const s=n.createElement("div");s.style.flex="1",a.appendChild(s);let f=null;t||(f=n.createElement("button"),f.type="button",f.innerHTML=W.collapse,f.setAttribute("aria-label","Collapse"),wireTooltip(f),Object.assign(f.style,y),wireControlHover(f),f.addEventListener("click",()=>S(!E)),a.appendChild(f));let x=null;e.printable&&(x=n.createElement("button"),x.type="button",x.innerHTML=W.print,x.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(x),Object.assign(x.style,y),wireControlHover(x),x.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),a.appendChild(x));const c=n.createElement("button");c.type="button",c.innerHTML=W.maximize,c.setAttribute("aria-label","Maximize (F)"),wireTooltip(c),Object.assign(c.style,y),wireControlHover(c),c.addEventListener("click",()=>A(!u));const m=n.createElement("button");m.type="button",m.innerHTML=W.close,m.setAttribute("aria-label","Close (Esc)"),wireTooltip(m),Object.assign(m.style,y),wireControlHover(m),m.addEventListener("click",I),a.appendChild(c),a.appendChild(m);let u=!1,h="",w="";function A(v){u=v,c.innerHTML=u?W.minimize:W.maximize,c.setAttribute("aria-label",u?"Restore (F)":"Maximize (F)"),f&&(f.style.display=u?"none":""),M.style.display=u?"none":"block",u?(i.style.borderRadius="0",i.style.width="100vw",i.style.height="100vh",t||(h=i.style.top,w=i.style.left,i.style.top="0",i.style.left="0")):(i.style.borderRadius="12px",i.style.width=b,i.style.height=d,t||(i.style.top=h,i.style.left=w)),e.onMaximizeChange?.(u,i)}let E=!1,C="",T="";const D=220;function S(v){E=v,f.innerHTML=E?W.uncollapse:W.collapse,f.setAttribute("aria-label",E?"Show contents":"Collapse"),M.style.display=E?"none":"block",E?(C=i.style.height,T=i.style.width,i.style.minHeight="0",i.style.height="auto",i.style.minWidth="0",i.style.width=`${D}px`,c.disabled=!0,c.style.opacity="0.4",c.style.cursor="default",$.style.display="none"):(i.style.minHeight="240px",i.style.height=C||d,i.style.minWidth="320px",i.style.width=T||b,c.disabled=!1,c.style.opacity="1",c.style.cursor="pointer",$.style.display="flex")}function g(){const v=n.body.style.userSelect;return n.body.style.userSelect="none",()=>{n.body.style.userSelect=v}}t||(a.style.cursor="move",a.addEventListener("pointerdown",v=>{if(u||v.target.closest('button, [role="button"]'))return;v.preventDefault();const H=g(),_=v.clientX,N=v.clientY,R=i.offsetTop,P=i.offsetLeft,ne=o.innerHeight-a.offsetHeight,oe=o.innerWidth-40,Q=40-i.offsetWidth;a.setPointerCapture(v.pointerId);const q=X=>{const ie=Math.min(Math.max(R+(X.clientY-N),0),ne),we=Math.min(Math.max(P+(X.clientX-_),Q),oe);i.style.top=`${ie}px`,i.style.left=`${we}px`},G=X=>{H(),a.releasePointerCapture(X.pointerId),a.removeEventListener("pointermove",q),a.removeEventListener("pointerup",G)};a.addEventListener("pointermove",q),a.addEventListener("pointerup",G)}));const B='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function V(v){const H=Array.from(i.querySelectorAll(B)).filter(P=>P.offsetParent!==null||P===n.activeElement);if(H.length===0){v.preventDefault(),i.focus();return}const _=H[0],N=H[H.length-1],R=n.activeElement;v.shiftKey&&(R===_||!i.contains(R))?(v.preventDefault(),N.focus()):!v.shiftKey&&R===N&&(v.preventDefault(),_.focus())}const z=v=>{if(v.key==="Escape"){I();return}if(t&&(v.key==="e"||v.key==="E")){I();return}if(t&&v.key==="Tab"){V(v);return}(v.key==="f"||v.key==="F")&&!E&&A(!u)};function I(){t?n.removeEventListener("keydown",z):i.removeEventListener("keydown",z),te.remove(),ge(),hideTooltip(n),reparentTooltip(n.body),l?l.remove():i.remove(),t&&(n.body.style.overflow=r),p?.focus?.(),e.onClose()}function Y(){t||(i.style.zIndex=String(fe()))}const $=n.createElement("div");Object.assign($.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const M=n.createElement("div");M.tabIndex=0,M.setAttribute("role","separator"),M.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(M.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),M.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16" style="display:block"><path d="M15 15 L15 9 M15 15 L9 15 M15 15 L15 3 M15 15 L3 15" stroke="currentColor" stroke-width="1" opacity="0.35" fill="none"/></svg>',M.style.color=CLR.label;const L=320,U=240,O=20;function Z(v,H){const _=o.innerWidth-i.offsetLeft,N=o.innerHeight-i.offsetTop,R=Math.min(Math.max(i.offsetWidth+v,L),_),P=Math.min(Math.max(i.offsetHeight+H,U),N);i.style.width=`${R}px`,i.style.height=`${P}px`}M.addEventListener("keydown",v=>{if(!(u||E))switch(v.key){case"ArrowRight":v.preventDefault(),Z(O,0);break;case"ArrowLeft":v.preventDefault(),Z(-O,0);break;case"ArrowDown":v.preventDefault(),Z(0,O);break;case"ArrowUp":v.preventDefault(),Z(0,-O);break}}),M.addEventListener("pointerdown",v=>{if(u||E)return;v.preventDefault();const H=g(),_=v.clientX,N=v.clientY,R=i.offsetWidth,P=i.offsetHeight,ne=o.innerWidth-i.offsetLeft,oe=o.innerHeight-i.offsetTop;M.setPointerCapture(v.pointerId);const Q=G=>{const X=Math.min(Math.max(R+(G.clientX-_),L),ne),ie=Math.min(Math.max(P+(G.clientY-N),U),oe);i.style.width=`${X}px`,i.style.height=`${ie}px`},q=G=>{H(),M.releasePointerCapture(G.pointerId),M.removeEventListener("pointermove",Q),M.removeEventListener("pointerup",q)};M.addEventListener("pointermove",Q),M.addEventListener("pointerup",q)}),i.appendChild(a),i.appendChild($),i.appendChild(M);const ee=e.anchor?overlayRootFor(e.anchor):n.body;l?(l.appendChild(i),ee.appendChild(l)):ee.appendChild(i);const ge=Pe(n,ee),te=n.createElement("style");te.textContent=`@media print{
2
2
  body{overflow:visible!important;height:auto!important}
3
3
  body>*:not(.wmap-overlay-box):not(#wmap-modal-backdrop):not(.wmap-overlay-ancestor){display:none!important}
4
4
  #wmap-modal-backdrop{position:static!important;background:none!important;backdrop-filter:none!important;display:block!important}
@@ -6,4 +6,4 @@ body>*:not(.wmap-overlay-box):not(#wmap-modal-backdrop):not(.wmap-overlay-ancest
6
6
  .wmap-overlay-box>div:first-child{display:none!important}
7
7
  .wmap-overlay-box>div:nth-child(2){display:block!important;overflow:visible!important;height:auto!important;flex:none!important;min-height:0!important;min-width:0!important}
8
8
  .wmap-overlay-box>div:nth-child(3){display:none!important}
9
- }`,t.head.appendChild(te),reparentTooltip(i),n?(l.addEventListener("click",h=>{h.target===l&&H()}),t.addEventListener("keydown",R)):(i.addEventListener("keydown",R),i.addEventListener("mousedown",X),X()),nextFrame(()=>(c.isConnected?c:i).focus(),o),{backdrop:l,box:i,contentWrap:I,close:H,bringToFront:X}}export function openModal(e){return ue({...e,mode:"modal"})}export function openFloatingWindow(e){return ue({...e,mode:"window"})}const se=new WeakSet;export function openReparentedModal(e,n={}){if(e.length===0||e.some(r=>se.has(r)))return null;const t=e.map(r=>({el:r,parent:r.parentElement,next:r.nextSibling})),o=openModal({ownerDocument:n.ownerDocument,title:n.title,boxSize:n.boxSize,anchor:e[0],onClose:()=>{for(const r of t){if(se.delete(r.el),!r.parent)continue;const l=r.next&&r.next.parentNode===r.parent?r.next:null;r.parent.insertBefore(r.el,l)}n.onClosed?.()}});for(const r of t)se.add(r.el),o.contentWrap.appendChild(r.el);return o}export function makePaletteBtn(e,n,t,o){const r=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const u=n(),i=[];if(u.plotMode==="hardBin"||u.plotMode==="softBin"){const f=u.binColorScheme??"default";i.push({section:"Bin colours"});for(const m of we())i.push({label:m.label,active:f===m.name,onClick:()=>o({binColorScheme:m.name})});if(t()){const m=u.useDefinedBinColors??!0;i.push({section:"Bin definitions"}),i.push({label:"Use colours from bin definitions",active:m,onClick:()=>o({useDefinedBinColors:!m})})}}else{const f=u.valueColorScheme??"default";i.push({section:"Value colours"});for(const s of ke())i.push({label:s.label,active:f===s.name,onClick:()=>o({valueColorScheme:s.name})});const m=u.reverseValueScheme??!1;i.push({section:"Direction"}),i.push({label:"Reverse gradient",active:m,onClick:()=>o({reverseValueScheme:!m})})}return i},()=>{});function l(){r.style.display=n().plotMode==="metadata"?"none":""}return{btn:r,sync:l}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"off"}export function overlayMenuRows(e,n,t,o){return[{label:"Ring boundaries",active:!!e.showRingBoundaries,onClick:()=>o({showRingBoundaries:!e.showRingBoundaries})},{label:"Quadrant lines",active:!!e.showQuadrantBoundaries,onClick:()=>o({showQuadrantBoundaries:!e.showQuadrantBoundaries})},{label:"Die labels",active:!!e.showDieLabels,onClick:()=>o({showDieLabels:!e.showDieLabels})},{label:"Reticle grid",active:!!e.showReticle,enabled:n,onClick:()=>o({showReticle:!e.showReticle})},{label:"XY indicator",active:!!e.showXYIndicator,onClick:()=>o({showXYIndicator:!e.showXYIndicator})},...passFailMenuRows({...t,display:requestedPassFailDisplay(e)},r=>o({passFailDisplay:r})),{label:"Mark failing dies",active:!!e.markFailingDies,enabled:t.binMode,disabledHint:t.binMode?void 0:"Available on hard/soft bin maps",onClick:()=>o({markFailingDies:!e.markFailingDies})},{section:""},{label:"Clear overlays",active:!1,action:!0,enabled:anyOverlayActive(e),disabledHint:"No overlays are active",onClick:()=>o({showRingBoundaries:!1,showQuadrantBoundaries:!1,showDieLabels:!1,showReticle:!1,showXYIndicator:!1,passFailDisplay:"off",markFailingDies:!1})}]}export function anyOverlayActive(e){return!!(e.showRingBoundaries||e.showQuadrantBoundaries||e.showDieLabels||e.showReticle||e.showXYIndicator||e.markFailingDies||requestedPassFailDisplay(e)!=="off")}export function passFailMenuRows(e,n){if(e.functionalActive)return[];const t=[];return e.hasLimits&&t.push({label:"Spec pass/fail",active:e.display==="spec",onClick:()=>n(e.display==="spec"?"off":"spec")}),e.hasRecorded&&t.push({label:"Test pass/fail",active:e.display==="test",onClick:()=>n(e.display==="test"?"off":"test")}),t}export function makeLogScaleBtn(e,n,t){const o=e.makeBtn("logScale","Toggle log scale",()=>{t({logScale:!n().logScale})});function r(){const l=n(),u=l.plotMode,i=u==="value"||u==="stackedValues";o.style.display=i&&requestedPassFailDisplay(l)==="off"&&!l.functionalActive?"":"none",e.setActive(o,!!l.logScale)}return{btn:o,sync:r}}const We=[{value:"default",label:"Default (right)"},{value:"compact",label:"Compact (right)"},{value:"left",label:"Left"},{value:"top",label:"Top"},{value:"bottom",label:"Bottom"},{value:"floating",label:"Floating"}];export function makeLegendStyleBtn(e,n,t,o){const r=e.makeCheckMenuBtn("legend","Legend style",()=>{const u=n().legendPosition??"default",i=[];let f=!0;if(o){const m=o.blockedReason();f=m?!0:o.get(),i.push({label:"Legend on each map",active:f,enabled:!m,disabledHint:m??void 0,onClick:()=>o.set(!o.get())})}if(pe(n().plotMode)){o&&i.push({section:"Position on each map"});for(const m of We)i.push({label:m.label,active:f&&u===m.value,enabled:f,disabledHint:f?void 0:'Turn on "Legend on each map" to position it',onClick:()=>t(m.value)})}return i},()=>{});function l(){r.style.display=o||pe(n().plotMode)?"":"none"}return{btn:r,sync:l}}function pe(e){return e==="hardBin"||e==="softBin"||e==="metadata"}export function makeOverlaysBtn(e,n,t){return e.makeCheckMenuBtn("overlays","Overlays",()=>n(),o=>e.setActive(o,t()))}export function makeOrientationBtn(e,n,t){return e.makeCheckMenuBtn("orient","Orientation",()=>[{section:"Rotate"},{label:"Rotate 90\xB0 clockwise",active:!1,onClick:()=>{const o=n().rotation??0;t({rotation:ROTATIONS[(ROTATIONS.indexOf(o)+1)%4]})}},{section:"Flip"},{label:"Flip horizontal",active:!!n().flipX,onClick:()=>t({flipX:!n().flipX})},{label:"Flip vertical",active:!!n().flipY,onClick:()=>t({flipY:!n().flipY})},{section:""},{label:"Reset orientation",active:!1,action:!0,enabled:!!(n().rotation||n().flipX||n().flipY),disabledHint:"Already in the original orientation",onClick:()=>t({rotation:0,flipX:!1,flipY:!1})}],o=>{const{rotation:r,flipX:l,flipY:u}=n();e.setActive(o,!!(r||l||u))})}let P=null;const fe=40,ze=fe+8;function _e(e,n){const t=e.createElement("div");t.classList.add("wmap-guide-search"),t.style.cssText="display:flex;align-items:center;gap:2px;margin-left:10px;flex:1;min-width:80px;max-width:260px;";const o=e.createElement("input");o.type="text",o.placeholder="Search guide\u2026",o.setAttribute("aria-label","Search guide"),o.style.cssText=`flex:1;min-width:0;padding:4px 8px;font-size:12px;background:${CLR.menuBg};color:${CLR.text};border:1px solid ${CLR.menuBorder};border-radius:${RADIUS.control};outline:none;`,o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder});const r=e.createElement("span");r.setAttribute("role","status"),r.setAttribute("aria-live","polite"),r.style.cssText=`font-size:12px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function l(x,d){const c=e.createElement("button");return c.type="button",c.textContent=x,c.setAttribute("aria-label",d),c.disabled=!0,c.style.cssText=`border:none;background:none;cursor:pointer;padding:4px 6px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};flex-shrink:0;opacity:0.4;`,c.addEventListener("mouseenter",()=>{c.disabled||(c.style.background=CLR.bgHover)}),c.addEventListener("mouseleave",()=>{c.style.background="none"}),c}const u=l("\u25B2","Previous match"),i=l("\u25BC","Next match");let f=[],m=-1;function s(){const x=f.length===0;u.disabled=x,i.disabled=x,u.style.opacity=x?"0.4":"",i.style.opacity=x?"0.4":""}function y(){for(const x of f)x.parentNode?.replaceChild(e.createTextNode(x.textContent??""),x);n.normalize(),f=[],m=-1}function a(x){if(f.length===0)return;m>=0&&(f[m].style.outline="none"),m=(x%f.length+f.length)%f.length;const d=f[m];d.style.outline=`2px solid ${CLR.iconActive}`,d.style.outlineOffset="1px",d.scrollIntoView({behavior:"smooth",block:"center"}),r.textContent=`${m+1}/${f.length}`}function p(x){y();const d=x.trim();if(!d){r.textContent="",s();return}const c=d.toLowerCase(),b=e.createTreeWalker(n,NodeFilter.SHOW_TEXT,{acceptNode(A){const C=A.parentElement;return!C||C.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),v=[];let w;for(;w=b.nextNode();)v.push(w);for(const A of v){const C=A.textContent??"",L=C.toLowerCase();if(!L.includes(c))continue;const T=e.createDocumentFragment();let B=0,M=L.indexOf(c);for(;M!==-1;){M>B&&T.appendChild(e.createTextNode(C.slice(B,M)));const g=e.createElement("mark");g.textContent=C.slice(M,M+d.length),T.appendChild(g),f.push(g),B=M+d.length,M=L.indexOf(c,B)}B<C.length&&T.appendChild(e.createTextNode(C.slice(B))),A.parentNode?.replaceChild(T,A)}s(),f.length===0?r.textContent="No matches":a(0)}return o.addEventListener("input",()=>p(o.value)),o.addEventListener("keydown",x=>{x.key==="Enter"?(x.preventDefault(),a(m+(x.shiftKey?-1:1))):x.key==="Escape"&&(o.value?(o.value="",p("")):o.blur())}),u.addEventListener("click",()=>a(m-1)),i.addEventListener("click",()=>a(m+1)),t.append(o,r,u,i),t}function Ne(e,n,t){const o=[...n.querySelectorAll("h2[id]")];if(o.length<2)return;for(const d of n.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))d.style.scrollMarginTop=`${ze}px`;const r=e.createElement("div");r.classList.add("wmap-guide-toc"),r.style.cssText=`position:sticky;top:0;z-index:2;background:${CLR.menuBg};border-bottom:1px solid ${CLR.menuBorder};font-family:system-ui,-apple-system,"Segoe UI",sans-serif;`;const l=e.createElement("div");l.style.cssText=`display:flex;align-items:center;gap:4px;height:${fe}px;padding:0 12px;box-sizing:border-box;`;const u=e.createElement("span");u.innerHTML='<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',u.style.cssText=`display:inline-flex;transition:transform ${MOTION.base};flex-shrink:0;`;const i=e.createElement("button");i.type="button";const f="wmap-guide-toc-panel";i.setAttribute("aria-expanded","false"),i.setAttribute("aria-controls",f),i.style.cssText=`display:flex;align-items:center;gap:6px;border:none;background:none;cursor:pointer;padding:6px 8px;margin:0 -8px 0 -8px;border-radius:${RADIUS.control};font-size:13px;font-weight:600;color:${CLR.text};`;const m=e.createElement("span");m.textContent=`Contents (${o.length})`,i.append(u,m),i.addEventListener("mouseenter",()=>{i.style.background=CLR.bgHover}),i.addEventListener("mouseleave",()=>{i.style.background="none"});const s=e.createElement("button");s.type="button",s.textContent="\u2191 Top",s.style.cssText=`margin-left:auto;border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};`,s.addEventListener("mouseenter",()=>{s.style.background=CLR.bgHover}),s.addEventListener("mouseleave",()=>{s.style.background="none"}),s.addEventListener("click",()=>{x.close(),n.scrollTo({top:0,behavior:"smooth"})}),t?l.append(i,_e(e,n),s):l.append(i,s);const y=e.createElement("div");y.id=f,y.hidden=!0,y.style.cssText="padding:2px 12px 12px;max-height:min(60vh,440px);overflow-y:auto;";const a=/^\s*\d+(?:\.\d+)*\.\s+/;for(const d of n.querySelectorAll("h2[id],h3[id],h4[id]")){const c=d.firstChild;c?.nodeType===Node.TEXT_NODE&&(c.textContent=(c.textContent??"").replace(a,""))}const p=e.createElement("ul");p.setAttribute("role","list"),p.style.cssText="list-style:none;margin:0;padding:0;columns:200px;column-gap:24px;";for(const d of o){const c=e.createElement("li");c.style.cssText="break-inside:avoid;";const b=e.createElement("a");b.href=`#${d.id}`,b.textContent=d.textContent??"",b.style.cssText=`display:block;padding:4px 6px;margin:0 -6px;border-radius:${RADIUS.control};font-size:12.5px;color:${CLR.iconActive};text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,b.addEventListener("mouseenter",()=>{b.style.background=CLR.bgHover}),b.addEventListener("mouseleave",()=>{b.style.background="none"}),b.addEventListener("click",v=>{v.preventDefault(),x.close(),d.scrollIntoView({behavior:"smooth",block:"start"})}),c.appendChild(b),p.appendChild(c)}y.appendChild(p);const x=wireExpandToggle(i,d=>{y.hidden=!d,i.setAttribute("aria-expanded",String(d)),u.style.transform=d?"rotate(180deg)":"none"});r.append(l,y),n.prepend(r)}function me(e,n,t,o,r){const l=n,u=l.__wmapDemoApi;l.__wmapDemoApi=o;const i=e.createElement("div");return i.classList.add("wmap-guide-content"),i.innerHTML=t,Ne(e,i,r),{content:i,restoreApi:()=>{l.__wmapDemoApi===o&&(l.__wmapDemoApi=u)}}}function be(e,n){const t=n,o=e.querySelector("script");if(o){const r=e.ownerDocument.createElement("script");r.textContent=o.textContent,e.appendChild(r);const l=e.querySelector(".wmap-guide");return l&&t.__wmapPopulateGuideDemos?.(l),t.__wmapDestroyGuideDemos}}function Pe(e,n,t,o){const r=o?.ownerDocument??document,l=r.defaultView??window,{content:u,restoreApi:i}=me(r,l,n,t,!0);Object.assign(u.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let f;const m=openFloatingWindow({title:e,anchor:o,ownerDocument:r,printable:!0,onMaximizeChange:s=>{u.style.setProperty("--wmap-guide-reading-width",s?"1000px":"720px")},onClose:()=>{P===m&&(P=null),f?.(),i()}});return m.contentWrap.appendChild(u),f=be(u,l),m}function Fe(e,n,t,o){const r=e.document;r.title=n,Object.assign(r.documentElement.style,{height:"100%"}),Object.assign(r.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:FONT.family}),copyWmapThemeTokens(document.documentElement,r.documentElement);const l=syncWmapPopupTheme(document.documentElement,r.documentElement),{content:u,restoreApi:i}=me(r,e,t,o,!1);Object.assign(u.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),r.body.appendChild(u);const f=be(u,e);let m=!1;const s=()=>{if(!m){m=!0,clearInterval(y),l();try{f?.()}catch{}i(),P===a&&(P=null)}},y=setInterval(()=>{e.closed&&s()},400);e.addEventListener("pagehide",s);const a={close:()=>{e.closed||e.close(),s()}};return a}export function openUserGuideWindow(e,n,t,o){P&&(P.close(),P=null);const r=t?.title??"Wafer Map \u2014 User Guide",l=(t?.html??"")+n,i=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");P=i?Fe(i,r,l,e):Pe(r,l,e,o)}export function openWaferMapGuide(e,n){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([t,o,r])=>{openUserGuideWindow({buildWaferMap:Ae,renderWaferMap:o.renderWaferMap,renderWaferGallery:r.renderWaferGallery,analyzeWaferMap:Me},t.USER_GUIDE_HTML,e,n)})}export function openReportModal(e,n){const t=n?.ownerDocument??document,o=t.createElement("iframe");o.srcdoc=e,o.title="Summary report",Object.assign(o.style,{border:"0",width:"100%",flex:"1",minHeight:"0",background:"#fff"});const r=t.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"flex-end",padding:"6px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const l=t.createElement("button");l.type="button",wireControlHover(l,"bare"),l.textContent="Open as full page \u2197",Object.assign(l.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:FONT.body,textDecoration:"underline",padding:"0"}),l.addEventListener("click",()=>Le(e)),r.appendChild(l);const u=openModal({title:"Summary report",anchor:n?.anchor,ownerDocument:t,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return u.contentWrap.style.flexDirection="column",u.contentWrap.appendChild(r),u.contentWrap.appendChild(o),u}
9
+ }`,n.head.appendChild(te),reparentTooltip(i),t?(l.addEventListener("click",v=>{v.target===l&&I()}),n.addEventListener("keydown",z)):(i.addEventListener("keydown",z),i.addEventListener("mousedown",Y),Y()),nextFrame(()=>(m.isConnected?m:i).focus(),o);function ye(v){d=v,!u&&!E&&(i.style.height=v)}return{backdrop:l,box:i,contentWrap:$,close:I,bringToFront:Y,setNaturalHeight:ye}}export function openModal(e){return me({...e,mode:"modal"})}export function openFloatingWindow(e){return me({...e,mode:"window"})}const le=new WeakSet;export function openReparentedModal(e,t={}){if(e.length===0||e.some(r=>le.has(r)))return null;const n=e.map(r=>({el:r,parent:r.parentElement,next:r.nextSibling})),o=openModal({ownerDocument:t.ownerDocument,title:t.title,boxSize:t.boxSize,anchor:t.anchor??e[0],onClose:()=>{for(const r of n){if(le.delete(r.el),!r.parent)continue;const l=r.next&&r.next.parentNode===r.parent?r.next:null;r.parent.insertBefore(r.el,l)}t.onClosed?.()}});for(const r of n)le.add(r.el),o.contentWrap.appendChild(r.el);return o}export function makePaletteBtn(e,t,n,o){const r=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const p=t(),i=[];if(p.plotMode==="hardBin"||p.plotMode==="softBin"){const b=p.binColorScheme??"default";i.push({section:"Bin colours"});for(const d of Ae())i.push({label:d.label,active:b===d.name,onClick:()=>o({binColorScheme:d.name})});if(n()){const d=p.useDefinedBinColors??!0;i.push({section:"Bin definitions"}),i.push({label:"Use colours from bin definitions",active:d,onClick:()=>o({useDefinedBinColors:!d})})}}else{const b=p.valueColorScheme??"default";i.push({section:"Value colours"});for(const a of Me())i.push({label:a.label,active:b===a.name,onClick:()=>o({valueColorScheme:a.name})});const d=p.reverseValueScheme??!1;i.push({section:"Direction"}),i.push({label:"Reverse gradient",active:d,onClick:()=>o({reverseValueScheme:!d})})}return i},()=>{});function l(){r.style.display=t().plotMode==="metadata"?"none":""}return{btn:r,sync:l}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"off"}export function overlayMenuRows(e,t,n,o){return[{label:"Ring boundaries",active:!!e.showRingBoundaries,onClick:()=>o({showRingBoundaries:!e.showRingBoundaries})},{label:"Quadrant lines",active:!!e.showQuadrantBoundaries,onClick:()=>o({showQuadrantBoundaries:!e.showQuadrantBoundaries})},{label:"Die labels",active:!!e.showDieLabels,onClick:()=>o({showDieLabels:!e.showDieLabels})},{label:"Reticle grid",active:!!e.showReticle,enabled:t,onClick:()=>o({showReticle:!e.showReticle})},{label:"XY indicator",active:!!e.showXYIndicator,onClick:()=>o({showXYIndicator:!e.showXYIndicator})},...passFailMenuRows({...n,display:requestedPassFailDisplay(e)},r=>o({passFailDisplay:r})),{label:"Mark failing dies",active:!!e.markFailingDies,enabled:n.binMode,disabledHint:n.binMode?void 0:"Available on hard/soft bin maps",onClick:()=>o({markFailingDies:!e.markFailingDies})},{section:""},{label:"Clear overlays",active:!1,action:!0,enabled:anyOverlayActive(e),disabledHint:"No overlays are active",onClick:()=>o({showRingBoundaries:!1,showQuadrantBoundaries:!1,showDieLabels:!1,showReticle:!1,showXYIndicator:!1,passFailDisplay:"off",markFailingDies:!1})}]}export function anyOverlayActive(e){return!!(e.showRingBoundaries||e.showQuadrantBoundaries||e.showDieLabels||e.showReticle||e.showXYIndicator||e.markFailingDies||requestedPassFailDisplay(e)!=="off")}export function passFailMenuRows(e,t){if(e.functionalActive)return[];const n=[];return e.hasLimits&&n.push({label:"Spec pass/fail",active:e.display==="spec",onClick:()=>t(e.display==="spec"?"off":"spec")}),e.hasRecorded&&n.push({label:"Test pass/fail",active:e.display==="test",onClick:()=>t(e.display==="test"?"off":"test")}),n}export function makeLogScaleBtn(e,t,n){const o=e.makeBtn("logScale","Toggle log scale",()=>{n({logScale:!t().logScale})});function r(){const l=t(),p=l.plotMode,i=p==="value"||p==="stackedValues";o.style.display=i&&requestedPassFailDisplay(l)==="off"&&!l.functionalActive?"":"none",e.setActive(o,!!l.logScale)}return{btn:o,sync:r}}const Fe=[{value:"default",label:"Default (right)"},{value:"compact",label:"Compact (right)"},{value:"left",label:"Left"},{value:"top",label:"Top"},{value:"bottom",label:"Bottom"},{value:"floating",label:"Floating"}];export function makeLegendStyleBtn(e,t,n,o){const r=e.makeCheckMenuBtn("legend","Legend style",()=>{const p=t().legendPosition??"default",i=[];let b=!0;if(o){const d=o.blockedReason();b=d?!0:o.get(),i.push({label:"Legend on each map",active:b,enabled:!d,disabledHint:d??void 0,onClick:()=>o.set(!o.get())})}if(be(t().plotMode)){o&&i.push({section:"Position on each map"});for(const d of Fe)i.push({label:d.label,active:b&&p===d.value,enabled:b,disabledHint:b?void 0:'Turn on "Legend on each map" to position it',onClick:()=>n(d.value)})}return i},()=>{});function l(){r.style.display=o||be(t().plotMode)?"":"none"}return{btn:r,sync:l}}function be(e){return e==="hardBin"||e==="softBin"||e==="metadata"}export function makeOverlaysBtn(e,t,n){return e.makeCheckMenuBtn("overlays","Overlays",()=>t(),o=>e.setActive(o,n()))}export function makeOrientationBtn(e,t,n){return e.makeCheckMenuBtn("orient","Orientation",()=>[{section:"Rotate"},{label:"Rotate 90\xB0 clockwise",active:!1,onClick:()=>{const o=t().rotation??0;n({rotation:ROTATIONS[(ROTATIONS.indexOf(o)+1)%4]})}},{section:"Flip"},{label:"Flip horizontal",active:!!t().flipX,onClick:()=>n({flipX:!t().flipX})},{label:"Flip vertical",active:!!t().flipY,onClick:()=>n({flipY:!t().flipY})},{section:""},{label:"Reset orientation",active:!1,action:!0,enabled:!!(t().rotation||t().flipX||t().flipY),disabledHint:"Already in the original orientation",onClick:()=>n({rotation:0,flipX:!1,flipY:!1})}],o=>{const{rotation:r,flipX:l,flipY:p}=t();e.setActive(o,!!(r||l||p))})}let j=null;const he=40,je=he+8;function Ve(e,t){const n=e.createElement("div");n.classList.add("wmap-guide-search"),n.style.cssText="display:flex;align-items:center;gap:2px;margin-left:10px;flex:1;min-width:80px;max-width:260px;";const o=e.createElement("input");o.type="text",o.placeholder="Search guide\u2026",o.setAttribute("aria-label","Search guide"),o.style.cssText=`flex:1;min-width:0;padding:4px 8px;font-size:12px;background:${CLR.menuBg};color:${CLR.text};border:1px solid ${CLR.menuBorder};border-radius:${RADIUS.control};outline:none;`,o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder});const r=e.createElement("span");r.setAttribute("role","status"),r.setAttribute("aria-live","polite"),r.style.cssText=`font-size:12px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function l(x,c){const m=e.createElement("button");return m.type="button",m.textContent=x,m.setAttribute("aria-label",c),m.disabled=!0,m.style.cssText=`border:none;background:none;cursor:pointer;padding:4px 6px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};flex-shrink:0;opacity:0.4;`,m.addEventListener("mouseenter",()=>{m.disabled||(m.style.background=CLR.bgHover)}),m.addEventListener("mouseleave",()=>{m.style.background="none"}),m}const p=l("\u25B2","Previous match"),i=l("\u25BC","Next match");let b=[],d=-1;function a(){const x=b.length===0;p.disabled=x,i.disabled=x,p.style.opacity=x?"0.4":"",i.style.opacity=x?"0.4":""}function y(){for(const x of b)x.parentNode?.replaceChild(e.createTextNode(x.textContent??""),x);t.normalize(),b=[],d=-1}function s(x){if(b.length===0)return;d>=0&&(b[d].style.outline="none"),d=(x%b.length+b.length)%b.length;const c=b[d];c.style.outline=`2px solid ${CLR.iconActive}`,c.style.outlineOffset="1px",c.scrollIntoView({behavior:"smooth",block:"center"}),r.textContent=`${d+1}/${b.length}`}function f(x){y();const c=x.trim();if(!c){r.textContent="",a();return}const m=c.toLowerCase(),u=e.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode(A){const E=A.parentElement;return!E||E.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),h=[];let w;for(;w=u.nextNode();)h.push(w);for(const A of h){const E=A.textContent??"",C=E.toLowerCase();if(!C.includes(m))continue;const T=e.createDocumentFragment();let D=0,S=C.indexOf(m);for(;S!==-1;){S>D&&T.appendChild(e.createTextNode(E.slice(D,S)));const g=e.createElement("mark");g.textContent=E.slice(S,S+c.length),T.appendChild(g),b.push(g),D=S+c.length,S=C.indexOf(m,D)}D<E.length&&T.appendChild(e.createTextNode(E.slice(D))),A.parentNode?.replaceChild(T,A)}a(),b.length===0?r.textContent="No matches":s(0)}return o.addEventListener("input",()=>f(o.value)),o.addEventListener("keydown",x=>{x.key==="Enter"?(x.preventDefault(),s(d+(x.shiftKey?-1:1))):x.key==="Escape"&&(o.value?(o.value="",f("")):o.blur())}),p.addEventListener("click",()=>s(d-1)),i.addEventListener("click",()=>s(d+1)),n.append(o,r,p,i),n}function Ue(e,t,n){const o=[...t.querySelectorAll("h2[id]")];if(o.length<2)return;for(const c of t.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))c.style.scrollMarginTop=`${je}px`;const r=e.createElement("div");r.classList.add("wmap-guide-toc"),r.style.cssText=`position:sticky;top:0;z-index:2;background:${CLR.menuBg};border-bottom:1px solid ${CLR.menuBorder};font-family:system-ui,-apple-system,"Segoe UI",sans-serif;`;const l=e.createElement("div");l.style.cssText=`display:flex;align-items:center;gap:4px;height:${he}px;padding:0 12px;box-sizing:border-box;`;const p=e.createElement("span");p.innerHTML='<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',p.style.cssText=`display:inline-flex;transition:transform ${MOTION.base};flex-shrink:0;`;const i=e.createElement("button");i.type="button";const b="wmap-guide-toc-panel";i.setAttribute("aria-expanded","false"),i.setAttribute("aria-controls",b),i.style.cssText=`display:flex;align-items:center;gap:6px;border:none;background:none;cursor:pointer;padding:6px 8px;margin:0 -8px 0 -8px;border-radius:${RADIUS.control};font-size:13px;font-weight:600;color:${CLR.text};`;const d=e.createElement("span");d.textContent=`Contents (${o.length})`,i.append(p,d),i.addEventListener("mouseenter",()=>{i.style.background=CLR.bgHover}),i.addEventListener("mouseleave",()=>{i.style.background="none"});const a=e.createElement("button");a.type="button",a.textContent="\u2191 Top",a.style.cssText=`margin-left:auto;border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};`,a.addEventListener("mouseenter",()=>{a.style.background=CLR.bgHover}),a.addEventListener("mouseleave",()=>{a.style.background="none"}),a.addEventListener("click",()=>{x.close(),t.scrollTo({top:0,behavior:"smooth"})}),n?l.append(i,Ve(e,t),a):l.append(i,a);const y=e.createElement("div");y.id=b,y.hidden=!0,y.style.cssText="padding:2px 12px 12px;max-height:min(60vh,440px);overflow-y:auto;";const s=/^\s*\d+(?:\.\d+)*\.\s+/;for(const c of t.querySelectorAll("h2[id],h3[id],h4[id]")){const m=c.firstChild;m?.nodeType===Node.TEXT_NODE&&(m.textContent=(m.textContent??"").replace(s,""))}const f=e.createElement("ul");f.setAttribute("role","list"),f.style.cssText="list-style:none;margin:0;padding:0;columns:200px;column-gap:24px;";for(const c of o){const m=e.createElement("li");m.style.cssText="break-inside:avoid;";const u=e.createElement("a");u.href=`#${c.id}`,u.textContent=c.textContent??"",u.style.cssText=`display:block;padding:4px 6px;margin:0 -6px;border-radius:${RADIUS.control};font-size:12.5px;color:${CLR.iconActive};text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,u.addEventListener("mouseenter",()=>{u.style.background=CLR.bgHover}),u.addEventListener("mouseleave",()=>{u.style.background="none"}),u.addEventListener("click",h=>{h.preventDefault(),x.close(),c.scrollIntoView({behavior:"smooth",block:"start"})}),m.appendChild(u),f.appendChild(m)}y.appendChild(f);const x=wireExpandToggle(i,c=>{y.hidden=!c,i.setAttribute("aria-expanded",String(c)),p.style.transform=c?"rotate(180deg)":"none"});r.append(l,y),t.prepend(r)}function xe(e,t,n,o,r){const l=t,p=l.__wmapDemoApi;l.__wmapDemoApi=o;const i=e.createElement("div");return i.classList.add("wmap-guide-content"),i.innerHTML=n,Ue(e,i,r),{content:i,restoreApi:()=>{l.__wmapDemoApi===o&&(l.__wmapDemoApi=p)}}}function ve(e,t){const n=t,o=e.querySelector("script");if(o){const r=e.ownerDocument.createElement("script");r.textContent=o.textContent,e.appendChild(r);const l=e.querySelector(".wmap-guide");return l&&n.__wmapPopulateGuideDemos?.(l),n.__wmapDestroyGuideDemos}}function Ge(e,t,n,o){const r=o?.ownerDocument??document,l=r.defaultView??window,{content:p,restoreApi:i}=xe(r,l,t,n,!0);Object.assign(p.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let b;const d=openFloatingWindow({title:e,anchor:o,ownerDocument:r,printable:!0,onMaximizeChange:a=>{p.style.setProperty("--wmap-guide-reading-width",a?"1000px":"720px")},onClose:()=>{j===d&&(j=null),b?.(),i()}});return d.contentWrap.appendChild(p),b=ve(p,l),d}function Xe(e,t,n,o){const r=e.document;r.title=t,Object.assign(r.documentElement.style,{height:"100%"}),Object.assign(r.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:FONT.family}),copyWmapThemeTokens(document.documentElement,r.documentElement);const l=syncWmapPopupTheme(document.documentElement,r.documentElement),{content:p,restoreApi:i}=xe(r,e,n,o,!1);Object.assign(p.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),r.body.appendChild(p);const b=ve(p,e);let d=!1;const a=()=>{if(!d){d=!0,clearInterval(y),l();try{b?.()}catch{}i(),j===s&&(j=null)}},y=setInterval(()=>{e.closed&&a()},400);e.addEventListener("pagehide",a);const s={close:()=>{e.closed||e.close(),a()}};return s}export function openUserGuideWindow(e,t,n,o){j&&(j.close(),j=null);const r=n?.title??"Wafer Map \u2014 User Guide",l=(n?.html??"")+t,i=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");j=i?Xe(i,r,l,e):Ge(r,l,e,o)}export function openWaferMapGuide(e,t){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([n,o,r])=>{openUserGuideWindow({buildWaferMap:Te,renderWaferMap:o.renderWaferMap,renderWaferGallery:r.renderWaferGallery,analyzeWaferMap:He},n.USER_GUIDE_HTML,e,t)})}export function openReportModal(e,t){const n=t?.ownerDocument??document,o=n.createElement("iframe");o.srcdoc=e,o.title="Summary report",Object.assign(o.style,{border:"0",width:"100%",flex:"1",minHeight:"0",background:"#fff"});const r=n.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"flex-end",padding:"6px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const l=n.createElement("button");l.type="button",wireControlHover(l,"bare"),l.textContent="Open as full page \u2197",Object.assign(l.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:FONT.body,textDecoration:"underline",padding:"0"}),l.addEventListener("click",()=>De(e)),r.appendChild(l);const p=openModal({title:"Summary report",anchor:t?.anchor,ownerDocument:n,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return p.contentWrap.style.flexDirection="column",p.contentWrap.appendChild(r),p.contentWrap.appendChild(o),p}