@wafertools/wafermap 0.30.3 → 0.31.0

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 (85) hide show
  1. package/AGENTS.md +9 -19
  2. package/CHANGELOG.md +140 -0
  3. package/README.md +2 -2
  4. package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
  5. package/dist/packages/canvas-adapter/charts/capability.js +1 -1
  6. package/dist/packages/canvas-adapter/charts/chartShell.d.ts +89 -6
  7. package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
  8. package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
  9. package/dist/packages/canvas-adapter/charts/scatter.d.ts +16 -2
  10. package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
  11. package/dist/packages/canvas-adapter/charts/sweep.js +1 -1
  12. package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
  13. package/dist/packages/canvas-adapter/charts/trend.js +1 -1
  14. package/dist/packages/canvas-adapter/dieList.d.ts +1 -1
  15. package/dist/packages/canvas-adapter/exportName.d.ts +1 -12
  16. package/dist/packages/canvas-adapter/exportName.js +1 -1
  17. package/dist/packages/canvas-adapter/index.d.ts +2 -3
  18. package/dist/packages/canvas-adapter/index.js +1 -1
  19. package/dist/packages/canvas-adapter/insightsTab.d.ts +11 -1
  20. package/dist/packages/canvas-adapter/insightsTab.js +1 -1
  21. package/dist/packages/canvas-adapter/maplessSummary.js +1 -1
  22. package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +4 -7
  23. package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
  24. package/dist/packages/canvas-adapter/renderWaferMap.d.ts +15 -30
  25. package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
  26. package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
  27. package/dist/packages/canvas-adapter/toCanvas.js +1 -1
  28. package/dist/packages/canvas-adapter/toolbar.js +1 -1
  29. package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
  30. package/dist/packages/canvas-adapter/userGuideHtml.js +49 -43
  31. package/dist/packages/canvas-adapter/version.d.ts +2 -2
  32. package/dist/packages/canvas-adapter/version.js +1 -1
  33. package/dist/packages/canvas-adapter/warnings.js +1 -1
  34. package/dist/packages/core/aggregates.d.ts +0 -6
  35. package/dist/packages/core/aggregates.js +1 -1
  36. package/dist/packages/core/dies.d.ts +1 -3
  37. package/dist/packages/core/dies.js +1 -1
  38. package/dist/packages/core/index.d.ts +8 -10
  39. package/dist/packages/core/index.js +1 -1
  40. package/dist/packages/core/stdf.d.ts +9 -0
  41. package/dist/packages/core/stdf.js +1 -0
  42. package/dist/packages/core/transforms.d.ts +0 -23
  43. package/dist/packages/core/transforms.js +1 -1
  44. package/dist/packages/renderer/binColors.js +1 -1
  45. package/dist/packages/renderer/buildView.d.ts +1 -9
  46. package/dist/packages/renderer/buildView.js +1 -1
  47. package/dist/packages/renderer/buildWaferMap.d.ts +54 -34
  48. package/dist/packages/renderer/buildWaferMap.js +1 -1
  49. package/dist/packages/renderer/colorMap.d.ts +0 -2
  50. package/dist/packages/renderer/colorMap.js +1 -1
  51. package/dist/packages/renderer/deprecate.d.ts +1 -1
  52. package/dist/packages/renderer/deprecate.js +1 -1
  53. package/dist/packages/renderer/derivedTests/apply.js +1 -1
  54. package/dist/packages/renderer/derivedTests/parser.js +1 -1
  55. package/dist/packages/renderer/index.d.ts +6 -5
  56. package/dist/packages/renderer/index.js +1 -1
  57. package/dist/packages/renderer/spec.d.ts +17 -0
  58. package/dist/packages/renderer/spec.js +1 -1
  59. package/dist/packages/stats/analyzeWaferMap.js +1 -1
  60. package/dist/packages/stats/capability.d.ts +4 -2
  61. package/dist/packages/stats/capability.js +1 -1
  62. package/dist/packages/stats/clusterDetection.d.ts +2 -1
  63. package/dist/packages/stats/correlation.d.ts +1 -1
  64. package/dist/packages/stats/facets.d.ts +1 -1
  65. package/dist/packages/stats/index.d.ts +6 -16
  66. package/dist/packages/stats/index.js +1 -1
  67. package/dist/packages/stats/mergeTestDefs.d.ts +1 -1
  68. package/dist/packages/stats/mergeTestDefs.js +1 -1
  69. package/dist/packages/stats/patternClassification.d.ts +2 -1
  70. package/dist/packages/stats/regions.d.ts +2 -1
  71. package/dist/packages/stats/renderFindingsReport.d.ts +0 -4
  72. package/dist/packages/stats/renderFindingsReport.js +1 -21
  73. package/dist/packages/stats/renderSummaryReport.js +11 -11
  74. package/dist/packages/stats/sweep.d.ts +8 -0
  75. package/dist/packages/stats/sweep.js +1 -1
  76. package/dist/packages/stats/types.d.ts +9 -3
  77. package/package.json +2 -2
  78. package/dist/packages/canvas-adapter/deprecated.d.ts +0 -7
  79. package/dist/packages/canvas-adapter/deprecated.js +0 -1
  80. package/dist/packages/core/deprecated.d.ts +0 -60
  81. package/dist/packages/core/deprecated.js +0 -1
  82. package/dist/packages/renderer/deprecated.d.ts +0 -45
  83. package/dist/packages/renderer/deprecated.js +0 -1
  84. package/dist/packages/stats/deprecated.d.ts +0 -85
  85. package/dist/packages/stats/deprecated.js +0 -1
@@ -1 +1 @@
1
- import{buildView as Oi,buildHoverText as Ri,findTestDef as gt,resolveTestNumber as _t,buildMapTitle as Ii}from"../renderer/buildView.js";import{drawMapCanvas as Wi,BIN_LEGEND_W as $n,BIN_LEGEND_W_COMPACT as Fi,BIN_LEGEND_ADAPT_COMPACT as Ai,BIN_LEGEND_ADAPT_FLOATING as Hi}from"./toCanvas.js";import{buildWaferMap as zi,getTestPassStatus as Vi,isParametricTest as $t}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Yi}from"../stats/analyzeWaferMap.js";import{SHADOW as Xi,LEADING as Gn,wireControlHover as Un,SPACE as A,EDGE_GUTTER as Ni,RADIUS as Zn,FONT as mt,CLR as w,applyOverlayZ as ji,getTooltip as Qn,hideTooltip as yt,positionTooltip as qn,createToolbarHelpers as Ki,buildModeMenuEl as _i,openReparentedModal as $i,openUserGuideWindow as Gi,makePaletteBtn as Ui,makeLogScaleBtn as Zi,makeLegendStyleBtn as Qi,makeOverlaysBtn as qi,makeOrientationBtn as Ji,menuLayerFor as Jn,saveImageBlob as ei,markMenuTrigger as Qe,wireMenuA11y as ti,wireExpandToggle as eo,nextFrame as Gt,requestedPassFailDisplay as to,overlayMenuRows as no,anyOverlayActive as io,logWmapVersionOnce as oo,buildDataModeEntries as so,metadataKeyHasData as lo,metadataModeEntry as ao}from"./toolbar.js";import{waferIdentityLabel as ro}from"../core/waferLabel.js";import{metadataDisplayValue as co}from"../core/metadata.js";import{withExportContext as fo,noticeDownloadFilenameChange as po}from"./exportName.js";import{createSummaryPanelEl as Ut,wrapWithSummaryPanel as Zt,renderWaferSummaryContentSteps as uo}from"./summaryPanel.js";import{runChunked as ho}from"./chunked.js";import{collectWarnings as go,buildWarningsMenuEl as mo,severityOf as yo}from"./warnings.js";import{ICONS as ni}from"./icons.js";import{hasDrilldownTargets as bo,selectionPopulation as vo,waferPopulation as xo}from"./chartPopulation.js";import{createIdentityHeader as wo,collapsedLabel as Qt}from"./identityHeader.js";import{getDieKey as fe,hasPosition as ii,isPositionedDie as Co}from"../core/dies.js";import{buildDieListSection as So}from"./dieList.js";import{buildMaplessSummary as Mo}from"./maplessSummary.js";import{resolveBinColors as Eo,binColorWarning as Do}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as ko}from"../core/passBins.js";const oi=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(P){const m=P.some(p=>oi.has(p)),v=P.some(p=>!oi.has(p));return m&&v?"mixed":m?"preference":"state"}export function toPublicViewOptions(P){const{metadataValueOrder:m,binColors:v,lotSize:p,...k}=P;return k}export function renderWaferMap(P,m,v={}){return renderWaferMapCard(P,m,v)}export function renderWaferMapCard(P,m,v={}){oo();const p=P.ownerDocument,k=p.defaultView??window,qt=()=>q.label,Jt=()=>ro({label:qt(),wafer:V}),xe=fo(()=>{const e=co(V.metadata?.lot);return{lots:e!==void 0?[e]:[],...q.isLotStack?{stackedWafers:g?.lotSize??!0}:{wafer:Jt()}}},v.onSaveImage,v.onSaveText);po(v.downloadFilename);function en(){const e=g.plotMode==="softBin"||g.plotMode==="stackedSoftBins"?G:$,{primary:t,secondary:n}=Ii(g,c.fallbackFormat,e);return[t,q.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}k.getComputedStyle(P).position==="static"&&(P.style.position="relative");const si=P.clientHeight;v.height!=null&&(P.style.height=typeof v.height=="number"?`${v.height}px`:v.height);const bt=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!ii(e)).length,Oe=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-bt)===0&&bt>0,Re=p.createElement("div");Object.assign(Re.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),P.appendChild(Re);const we=p.createElement("div");Object.assign(we.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const pe=v.chromeInset??Ni,_=p.createElement("div");Object.assign(_.style,{display:"flex",alignItems:"stretch",gap:A.sm,background:w.canvasBg,paddingBottom:A.lg,paddingTop:pe,paddingLeft:pe,paddingRight:pe,flexShrink:"0",minWidth:"0"}),Re.appendChild(_),Re.appendChild(we);function Ie(){const e=[..._.children].some(t=>t.style.display!=="none");_.style.display=e?"flex":"none"}const M=p.createElement("div");Object.assign(M.style,{position:"relative",width:"100%",height:"100%"});const s=p.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),M.appendChild(s),we.appendChild(M);let qe=null;if(bt>0){let n=function(){if(t){const d=So(e,m.testDefs,{...v.dieList,onSaveText:xe.onSaveText,waferMetadata:V.metadata,metadataFields:he,ownerDocument:p});if(d)return d}const o=gt(m.testDefs,c.activeTest??0),a=$t(o)?c.logScale??o?.logScale??!1:!1;return Mo(e,m.testDefs,{plotMode:c.plotMode??"hardBin",activeTest:c.activeTest,hbinDefs:$,sbinDefs:G,binColors:g.binColors,valueColorScheme:c.valueColorScheme,reverseValueScheme:c.reverseValueScheme,logScale:a,colorbarRangeMode:c.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const a=p.createElement("button");return a.type="button",Un(a),Object.assign(a.style,{fontSize:mt.body,padding:`${A.xxs} ${A.sm}`,borderRadius:Zn.control,flexShrink:"0",border:`1px solid ${w.menuBorder}`,background:w.menuBg,color:w.text,cursor:"pointer"}),a.textContent=t?"View chart":"View die list",a.addEventListener("click",d=>{d.stopPropagation(),t=!t,a.textContent=t?"View chart":"View die list",o()}),a};const e=m.dies.filter(o=>!ii(o));let t=!1;if(Oe){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:w.panelBg,padding:A.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:A.md,zIndex:"1"});const a=p.createElement("div");Object.assign(a.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:A.md});const d=p.createElement("span");Object.assign(d.style,{fontSize:mt.body,color:w.label,lineHeight:Gn.base}),d.textContent="No die position data for this wafer.",a.appendChild(d);const l=p.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(a),o.appendChild(l),M.appendChild(o),qe=()=>{t||l.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,fontSize:mt.body,color:w.text,cursor:"pointer",padding:`${A.xs} ${A.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:A.md}),Un(o,"bare");const a=p.createElement("span");a.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(a);const d=p.createElement("span");d.textContent="\u25BE",Object.assign(d.style,{fontSize:mt.body,lineHeight:Gn.none,color:w.label,flexShrink:"0"}),o.appendChild(d),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,r=null;eo(o,f=>{if(d.textContent=f?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(f)),f){l=p.createElement("div");const h=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${h}px`,top:"20%",zIndex:"2",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,padding:A.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:A.md}),l.addEventListener("click",se=>se.stopPropagation());const y=p.createElement("div");Object.assign(y.style,{display:"flex",justifyContent:"flex-end"}),y.appendChild(i(()=>{r&&r.replaceChildren(n())})),l.appendChild(y),r=p.createElement("div"),Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(n()),l.appendChild(r),M.appendChild(l)}else l&&(l.remove(),l=null,r=null)}),M.appendChild(o),qe=()=>{r&&!t&&r.replaceChildren(n())}}}const{onHover:Je,onClick:li,onSelect:le,onViewOptionsChange:ai,showTooltip:ri=!0,showToolbar:We=!0,showIdentity:tn=!0,summaryPanel:Fe,showHelpButton:nn=!1,userGuideExtension:di,onExpand:on,showExpandButton:sn=!0,zIndex:ci,insights:Ce,warnings:ln,viewOptions:fi={},...Se}=v,Ae=Ce?.enabled??!1,pi=.4,ui=20,et=[...m.passBins??ko],an=ln?.display??!0,hi=ji(ci);let ae=v.statsSummary,re=[],rn=!1,tt=null,dn=!1;function vt(){const e=go({result:m,statsSummary:ae,extra:tt?[tt]:[]}),t=e.length!==re.length||e.some((n,i)=>n.code!==re[i]?.code||n.message!==re[i]?.message);re=e,(t||!rn)&&(rn=!0,ln?.onWarning?.(e))}vt();let q=m,V=m.wafer,ue=m.dies,C=new Set;const gi={sweeps:Ce?.sweeps,onSaveImage:xe.onSaveImage},xt=()=>!Oe&&bo(U,Ce?.sweeps);let cn=null,nt=null,it=!1,fn=!1,$=m.hbinDefs,G=m.sbinDefs,U=m.testDefs,he=m.metadataFields,pn=m.reticles?.length?m.reticles:void 0,un=m.reticleConfig,hn=m.view?.dataAxisFlip,wt=m.isLotStack??!1,Ct=m.aggrMethod,St=m.lotSize;const mi=We&&Ae;let Y=null,J=null,ee=null;tn&&(Y=wo(Qt(V.metadata??{},He())??"",V.metadata,{lotStack:He(),ownerDocument:p}),M.appendChild(Y.metaPanel),Y.metaPanel.style.visibility="visible",Y.isEmpty()||(J=gn(Y.wrap),_.insertBefore(J,_.firstChild),Ie()));function gn(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${A.sm} ${A.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:A.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function He(){return wt?{lotSize:St??1,aggrMethod:Ct}:void 0}function yi(){if(!Y)return;Y.update(Qt(V.metadata??{},He())??"",V.metadata,He());const e=J?.isConnected??!1,t=!Y.isEmpty();!t&&e?(J.remove(),J=null):t&&!e&&(J=gn(Y.wrap),J.style.display="",_.insertBefore(J,_.firstChild),Ie())}const bi=[...$??[],...G??[]].some(e=>e.color);let c={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...fi},X=null,te=!1,mn=null;function vi(){return Ae?X?Promise.resolve(X):(mn??=import("./insightsTab.js").then(({createInsightsTab:e})=>(X=e({getItems:()=>[{wafer:V,dies:ue,hbinDefs:$,sbinDefs:G,testDefs:U,label:qt(),passBins:et,statsSummary:ae}],getBinColors:()=>g.binColors,getRingCount:()=>q.ringCount??4,onSaveImage:xe.onSaveImage,onSaveText:xe.onSaveText,defaultView:Ce?.defaultView,sweeps:Ce?.sweeps,showMetadataStrip:!1,contentInset:pe,backTab:mi?void 0:{label:"Map",onBack:()=>ze(!1)},onOpenGuide:nn&&!We?()=>Xt():void 0,focusTest:t=>{D({plotMode:"value",activeTest:t,highlightBin:void 0}),ze(!1)},ownerDocument:p}),Object.assign(X.el.style,{position:"absolute",inset:"0",background:w.canvasBg,overflowY:"auto",paddingTop:"0"}),X.el.style.display="none",we.appendChild(X.el),X)),mn):Promise.resolve(null)}let yn=0;const Mt=["wheel","touchstart","pointerdown","keydown"];function xi(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const d of i)k.clearTimeout(d);i.length=0;for(const d of Mt)e.removeEventListener(d,o)},a=()=>n||!te?!0:(e.scrollTop=t,e.scrollTop>=t);if(!a()){for(const d of Mt)e.addEventListener(d,o,{passive:!0,once:!0});for(const d of[0,50,150,300,600])i.push(k.setTimeout(()=>{a()},d));i.push(k.setTimeout(()=>{for(const d of Mt)e.removeEventListener(d,o)},700))}}function ze(e){if(!Ae)return;const t=te;te=e,X&&!e&&t&&(yn=X.el.scrollTop),X&&(X.el.style.display=e?"flex":"none"),M.style.visibility=e?"hidden":"",F&&(F.style.display=e||Oe?"none":"flex"),T&&(T.style.display=e?"none":"flex"),ee&&(ee.style.display=be?"none":"flex"),ie&&(ie.style.display="flex"),J&&(J.style.display=""),Ie(),Y&&e&&Y.collapse(),rt(),H&&(H.innerHTML=e?ni.wafer:ni.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&vi().then(n=>{!n||!te||(n.el.style.display="flex",n.render(),xi(n.el,yn))})}Ae&&Ce?.defaultOpen&&queueMicrotask(()=>ze(!0));let g,bn,N=null,B=null,Et=[],Dt;function vn(e){Dt!==e&&(Dt=e,x())}let ge=null,kt=Se.legendOffset??{x:0,y:0},Ve=!1,Me=!1,Ye={x:0,y:0},Bt={x:0,y:0},me=!1,Ee=!1,j="pan",De={x:0,y:0},ot={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Xe=!1,ke=!1;function Lt(){const e=c;g=Oi(V,ue.filter(Co),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??Eo(ue,{passBins:et,binColorScheme:e.binColorScheme,hbinDefs:$,sbinDefs:G,useDefinedBinColors:e.useDefinedBinColors}),passBins:et,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:pn,ringCount:q.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:U,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:wt,aggregationMethod:Ct??e.aggregationMethod,lotSize:St??e.lotSize,dataAxisFlip:hn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:he}),bn=new Map(g.dies.map((n,i)=>[fe(n),i]));const t=e.binColors?null:Do(g.binColors,g.plotMode);t?.message!==tt?.message&&(tt=t,vt(),dn&&Tt())}Lt();let Z=null,Be=null,st=null,xn=v.findingsNotice,wi={},I=null,de=null;function Ci(e){const{kind:t,index:n}=e.variable;D(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const i=e.highlight;i.kind==="bin"?(Ft(i.dieKeys),D({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Ft(i.dieKeys)}const Ne=new Map;function wn(e){Ne.get(e)?.cancel(),Ne.delete(e);const t=ho(uo(e,{wafer:V,dies:ue,yieldSummary:q.yield,dataCoverage:q.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:U,statsSummary:ae,warnings:an?re:[],passBins:et,ringCount:q.ringCount??4,binColors:g.binColors,plotMode:c.plotMode??"hardBin",metadataShownElsewhere:tn,fallbackFormat:c.fallbackFormat,activeFindingId:st,findingsFilter:wi,findingsNotice:xn,onFindingsFilterChange:ye,onSaveText:xe.onSaveText,metadataFields:he,dieListOptions:v.dieList,onFindingClick:(n,i)=>{st===n.id?(st=null,Ft([]),D({highlightBin:void 0})):(st=n.id,Ci(n)),ye()}}));t.done||Ne.set(e,t)}function ye(){Z&&wn(Z)}function je(){I&&wn(I)}if(Fe?.placement){const e=Fe.placement;Z=Ut(e,pe,p);const t=M.parentElement,n=M.nextSibling;Be=Zt(M,Z,e),t?.insertBefore(Be,n),ye()}else if(ae){const e=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=e?"block":"none";const t=M.parentElement,n=M.nextSibling;de=Zt(M,I,"right"),t?.insertBefore(de,n),je()}const W=ri?Qn(p):null;let ie=null,L=null,F=null,T=null,lt=null,K=null,Cn=null,H=null,oe=null,at=null;dn=!0;function Tt(){if(!oe||!at)return;const e=re.length,t=e>0;if(oe.style.display=t?"flex":"none",at.style.display=t?"":"none",!t)return;const n=yo(re[0]),i=`${e} data ${e===1?"warning":"warnings"}`;oe.style.color=n==="error"?w.errText:w.warnText,oe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Pt=null,Sn=null,Ot=null,Rt=null,It=null,Wt=null;function Ft(e){C=new Set(e??[]),le&&le(Ke()),x()}function rt(){if(!K)return;const e=!!(Z??I);K.style.display=ae&&e&&!te?"flex":"none";const t=Z??I,n=t?t.style.display!=="none":!1;ae?.hasNotableFindings&&!n?K.style.color=w.findingIndicator:K.dataset.active||(K.style.color=w.icon)}let Mn=null;function En(e){const t=Z??I;t&&(t.style.display=e?"block":"none",K&&Mn?.(K,e),rt())}if(We){let h=function(b){j=b,i(se,b==="zoom"),i(E,b==="pan"),lt&&i(lt,b==="select"),s.style.cursor=b==="pan"?"grab":"crosshair"};ie=p.createElement("div"),ie.dataset.wmapToolbar="single",Object.assign(ie.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:w.menuBg,border:`1px solid ${w.menuBorder}`,borderRadius:Zn.control,boxShadow:Xi.panel,pointerEvents:"auto"});const e=Qn(p),t=Ki(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:a,makeMenuSection:d,closeOpenMenu:l,getOpenMenu:r,setOpenMenu:f}=t;Mn=i,Pt=l,Sn=r,p.addEventListener("click",l,!0),F=p.createElement("div"),Object.assign(F.style,{display:Oe?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(F);const y=n("download","Download PNG",Ei);F.appendChild(y),F.appendChild(o());const se=n("zoomMode","Zoom (drag to zoom region)",()=>h("zoom")),Te=n("zoomIn","Zoom in",()=>Le(s.clientWidth/2,s.clientHeight/2,1.2)),ne=n("zoomOut","Zoom out",()=>Le(s.clientWidth/2,s.clientHeight/2,1/1.2)),ce=n("reset","Reset zoom (double-click)",()=>ct());F.appendChild(se),F.appendChild(Te),F.appendChild(ne),F.appendChild(ce),F.appendChild(o());const E=n("pan","Pan (drag to move)",()=>h("pan"));F.appendChild(E),lt=n("boxSelect","Select (drag to select dies)",()=>h("select")),F.appendChild(lt);{const b=n("drilldown","Chart this wafer",()=>{const Pe=b.getBoundingClientRect();In({x:Pe.left,y:Pe.bottom+4},b)});b.setAttribute("aria-haspopup","menu"),nt=b,Rn(),F.appendChild(b)}i(E,!0);{let b=function(u){return u.plotMode!==(c.plotMode??"hardBin")?!1:u.plotMode==="value"?(c.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?c.activeMetadataKey===u.activeMetadataKey:!0},Pe=function(u,S){u.activeTest!==void 0?D({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),S.remove(),f(null),Qe(Q,!1)};L=p.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(L),T=p.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const ft=()=>{const u=r();u&&(u.remove(),f(null)),Qe(Q,!1)},Q=n("mode","Plot mode",()=>{if(r()){ft();return}const u=ue,S=g.testDefs,{testEntries:ht,binEntries:ve,stackedEntries:Ge}=so(u,S,{includeStacked:g.isLotStack}),Kt=(he??[]).filter(Ze=>lo(u,Ze.key)).map(ao),Ue=_i(Q.getBoundingClientRect(),ht,ve,Ge,b,Pe,{makeMenuRow:a,makeMenuSection:d},c.plotMode??"hardBin",Q.ownerDocument.defaultView??window,Kt);Jn(Q).appendChild(Ue),f(Ue),Qe(Q,!0),ti(Ue,Q,ft)});Qe(Q,!1);const{btn:pt,sync:$e}=Ui(t,()=>({...c,plotMode:c.plotMode??"hardBin"}),()=>bi,D);Rt=$e,Rt();const Nt=qi(t,()=>{const u=!!g.hasReticle,S=(c.plotMode??"hardBin")==="value",{testNumber:ht}=_t(c.activeTest??0,g.testDefs),ve=gt(g.testDefs,ht),Ge=S&&ve!==void 0&&!$t(ve),Kt=S&&!Ge&&(ve?.limitLow!==void 0||ve?.limitHigh!==void 0),Ue=S&&!Ge&&g.dies.some(Ze=>Vi(Ze,ht,ve)!==void 0);return no(c,u,{functionalActive:Ge,hasLimits:Kt,hasRecorded:Ue,binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},Ze=>D(Ze))},()=>io(c)),{btn:jt,sync:ki}=Qi(t,()=>c,u=>D({legendPosition:u}));Ot=ki,Ot();const _n=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&!$t(S)},{btn:Bi,sync:Li}=Zi(t,()=>({...c,functionalActive:_n()}),u=>D(u));It=Li,It();const Ti=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&(S.limitLow!==void 0||S.limitHigh!==void 0)},ut=n("specRange","Colorbar range: spec limits",()=>{const u=c.colorbarRangeMode==="data"?"spec":"data";D({colorbarRangeMode:u})});Wt=()=>{const u=c.plotMode==="value"&&Ti()&&to(c)==="off"&&!_n();ut.style.display=u?"":"none";const S=(c.colorbarRangeMode??"spec")==="spec";i(ut,S),ut.ariaLabel=S?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},Wt();const Pi=Ji(t,()=>c,u=>D(u));T.appendChild(Q),T.appendChild(pt),T.appendChild(Bi),T.appendChild(ut),Oe||(T.appendChild(o()),T.appendChild(Nt),T.appendChild(o()),T.appendChild(jt),T.appendChild(o()),T.appendChild(Pi)),ae&&(K=n("findings","Summary panel",()=>{const u=Z??I;u&&En(u.style.display==="none")}),L.appendChild(o()),L.appendChild(K),I?.style.display!=="none"&&i(K,!0),rt()),an&&(at=o(),oe=n("warning","Data warnings",()=>{const u=r();if(l(new MouseEvent("click")),u)return;const S=mo(oe.getBoundingClientRect(),re,k);Jn(we).appendChild(S),f(S),ti(S,oe,()=>l(new MouseEvent("click")))}),Qe(oe,!1),L.appendChild(at),L.appendChild(oe),Tt()),Ae&&(L.appendChild(o()),H=n("analysis","Insights",()=>{ze(!te),i(H,te)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),sn&&(L.appendChild(o()),ee=n("expand","Expand (E)",on??Dn),L.appendChild(ee)),nn&&(L.appendChild(o()),Cn=n("help","User guide",()=>Xt()),L.appendChild(Cn))}_.appendChild(ie),Ie()}let be=null;function Dn(){be&&(be.close(),be=null);const e=we;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=Qt(V.metadata??{},He()),n=_.childElementCount>0?[_,e]:[e],i=$i(n,{ownerDocument:p,boxSize:te?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{be=null,ee&&(ee.style.display="flex"),te||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),be=i,ee&&(ee.style.display="none"))}function kn(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&c.binColors!==void 0&&(e={...e,binColors:void 0});const t=c.plotMode;c={...c,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(a=>a==="legendPosition"||a==="showLegend"||a==="markFailingDies")||Lt(),Ot?.(),Rt?.(),It?.(),Wt?.(),x();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(a=>a in e);(o||i)&&(ye(),je()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&qe?.()}function D(e){kn(e);const t=Object.keys(e);ai?.(c,t,classifyChanged(t))}let At=!1;function Ht(){At||(At=!0,Gt(()=>{At=!1,x()},k))}function x(){const e=B??void 0,t=g.dies[0],n=t?{x:t.width,y:t.height}:Se.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!($?.length||G?.length||g.dies.some(y=>y.hbin!=null||y.sbin!=null)),a=c.legendPosition??"default",d=c.showLegend??!0,l=a==="default"||a==="compact",r=(Se.colorbarWidth??16)+28,f=o&&l?a!=="default"?Math.max($n,r):i<Hi?0:i<Ai?Math.max(Fi,r):Math.max($n,r):void 0,h=Wi(s,g,{...Se,minRightReserve:d?f:0,showColorbar:d&&(Se.showColorbar??!0),markFailingDies:c.markFailingDies??!1,legendPosition:a,legendOffset:kt,diePitchMm:n,fallbackFormat:c.fallbackFormat,showAxes:Se.showAxes??B!==null,viewport:e,activeBin:c.plotMode==="metadata"?c.highlightMetadataValue:c.highlightBin,hoverBin:Dt,hbinDefs:$,sbinDefs:G,metadataFields:he});Et=h.binLegendRows,ge=h.legendBox??null,B===null&&(N=h.viewport),C.size>0&&Si(),Ee&&Mi(),Rn()}function Si(){const e=z();if(!e)return;const t=s.getContext("2d"),n=g.hoverPoints,i=g.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,a=i?i.height/2*e.ppm:e.ppm*.5,d=Math.max(1,Math.min(3,o*.08)),l=o-d,r=a-d,f=[];for(const h of C){const y=bn.get(h);y!==void 0&&f.push({sx:e.originX+n[y].x*e.ppm,sy:e.originY-n[y].y*e.ppm})}if(f.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.restore()}}function Mi(){const e=s.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),i=Math.abs(R.x-O.x),o=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,i,o),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,i,o),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,i,o),e.restore()}function Ei(){s.toBlob(e=>{e&&(v.downloadFilename!=null?ei(e,v.downloadFilename,v.onSaveImage):ei(e,en(),xe.onSaveImage))})}function Bn(e){return N?Math.max(N.ppm*pi,Math.min(N.ppm*ui,e)):e}function Le(e,t,n){const i=B??N;if(!i)return;const o=Bn(i.ppm*n),a=o/i.ppm,d=e-(e-i.originX)*a,l=t-(t-i.originY)*a,r=(N?.snapDist??1)/(o/(N?.ppm??o));B={originX:d,originY:l,ppm:o,snapDist:r},x()}function z(){return B??N}function Ln(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Le(e.clientX-t.left,e.clientY-t.top,n)}else if(B!==null){e.preventDefault();const t=z(),n=B.snapDist;B={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},x()}}function zt(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function Tn(e){if(it=!1,e.button!==0||!z())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(ge&&c.legendPosition==="floating"&&zt(n,i,ge)){Me=!0,Ye={x:n,y:i},Bt={...kt};return}if(Xe&&j!=="pan"){ke=!0,me=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing";return}if(j==="zoom"||j==="select"){Ee=!0,O=R={x:n,y:i};return}me=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing"}function Pn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ee){R={x:n,y:i},Ht();return}if(Me){const h=n-Ye.x,y=i-Ye.y;h*h+y*y>16&&(Me=!1,Ve=!0,s.style.cursor="grabbing")}if(Ve){kt={x:Bt.x+(n-Ye.x),y:Bt.y+(i-Ye.y)},Ht();return}if(me){const h=z(),y=B?.snapDist??N?.snapDist??1;B={originX:ot.x+(n-De.x),originY:ot.y+(i-De.y),ppm:h.ppm,snapDist:y},Ht();return}const o=z();if(!o)return;const a=(n-o.originX)/o.ppm,d=(o.originY-i)/o.ppm,r=Yt(a,d,o.snapDist)?.die??null,f=Et.find(h=>n>=h.x&&n<h.x+h.w&&i>=h.y&&i<h.y+h.h);if(vn(f?f.bin:void 0),f){s.style.cursor="pointer",W&&(W.textContent=f.label??`Bin ${f.bin}`,W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})),Je?.(null,e);return}j==="pan"&&(s.style.cursor=r?"crosshair":"grab"),W&&(r?(W.innerHTML=Ri(r,g.plotMode,{testDefs:U,hbinDefs:$,sbinDefs:G,fallbackFormat:c.fallbackFormat,aggrMethod:g.aggrMethod,lotSize:g.lotSize,metadataFields:he,activeTest:g.activeTest,reticleConfig:un}),W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})):W.style.display="none"),Je?.(r,e)}function On(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(W&&(n<0||i<0||n>t.width||i>t.height)&&(W.style.display="none"),Ee){Ee=!1,R={x:n,y:i};const l=n-O.x,r=i-O.y,f=z();if(j==="zoom"){if(l*l+r*r<25)Le(n,i,2);else if(f){const h=Math.min(O.x,R.x),y=Math.max(O.x,R.x),se=Math.min(O.y,R.y),Te=Math.max(O.y,R.y),ne=y-h,ce=Te-se;if(ne>4&&ce>4){const E=s.clientWidth,b=s.clientHeight,Pe=E/ne,ft=b/ce,Q=Math.min(Pe,ft),pt=Bn(f.ppm*Q),$e=pt/f.ppm,Nt=(h+y)/2,jt=(se+Te)/2;B={originX:E/2-(Nt-f.originX)*$e,originY:b/2-(jt-f.originY)*$e,ppm:pt,snapDist:f.snapDist/$e}}}x(),s.style.cursor="crosshair";return}if(l*l+r*r<25)Vt(n,i,o,e);else if(f){const h=(Math.min(O.x,R.x)-f.originX)/f.ppm,y=(Math.max(O.x,R.x)-f.originX)/f.ppm,se=(f.originY-Math.max(O.y,R.y))/f.ppm,Te=(f.originY-Math.min(O.y,R.y))/f.ppm,ne=g.hoverPoints,ce=[];for(let E=0;E<ne.length;E++)if(ne[E].x>=h&&ne[E].x<=y&&ne[E].y>=se&&ne[E].y<=Te){const b=g.dies[E];b&&ce.push(b)}if(o)for(const E of ce){const b=fe(E);C.has(b)?C.delete(b):C.add(b)}else C=new Set(ce.map(E=>fe(E)));le?.(Ke())}x(),s.style.cursor="crosshair";return}if(Me){Me=!1,Vt(n,i,o,e);return}if(Ve){Ve=!1,s.style.cursor="grab";return}if(!me)return;if(me=!1,ke){ke=!1,s.style.cursor=Xe||j==="pan"?"grab":"crosshair";return}s.style.cursor=j==="pan"?"grab":"crosshair";const a=n-De.x,d=i-De.y;a*a+d*d<25&&Vt(n,i,o,e)}function Vt(e,t,n,i){for(const l of Et)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const r=c.highlightBin===l.bin?void 0:l.bin;D({highlightBin:r})}else{const r=c.highlightMetadataValue===l.bin?void 0:l.bin;D({highlightMetadataValue:r})}return}if(ge&&zt(e,t,ge))return;const o=z();if(!o)return;const d=Yt((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(d){li?.(d,i);const l=fe(d);n?C.has(l)?C.delete(l):C.add(l):C=new Set([l]),le?.(Ke()),x()}else n||(C=new Set,le?.([]),x())}function Ke(){const e=[],t=g.hoverPoints;for(let n=0;n<t.length;n++){const i=g.dies[n];i&&C.has(fe(i))&&e.push(i)}return e}function Rn(){nt&&(nt.style.display=xt()?"flex":"none",nt.ariaLabel=C.size>0?"Chart the selected dies (or right-click)":"Chart this wafer (or right-click)")}function Di(){const e={waferLabel:Jt(),testDefs:U,isLotStack:q.isLotStack,activeTest:c.plotMode==="value"?c.activeTest:void 0};return C.size>0?vo(Ke(),e):xo(ue,e)}function In(e,t){if(!xt())return;const n=Di();import("./drilldown.js").then(({openDrilldownMenu:i})=>{fn||(cn=i(e,t,n,gi))})}function Wn(e){e.stopPropagation();const t=it;if(it=!1,!xt()||te)return;const n=s.getBoundingClientRect();if(!t){const o=e.clientX-n.left,a=e.clientY-n.top;if(ge&&zt(o,a,ge))return;const d=z(),l=d?Yt((o-d.originX)/d.ppm,(d.originY-a)/d.ppm,d.snapDist)?.die:void 0;l&&!C.has(fe(l))&&(C=new Set([fe(l)]),le?.(Ke()),x())}e.preventDefault();const i=t?{x:n.left+n.width/2,y:n.top+n.height/2}:{x:e.clientX,y:e.clientY};In(i,s)}function Fn(){vn(void 0),W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair"}function An(){me=!1,ke=!1,Ee=!1,Me=!1,Ve=!1,W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair",x()}function Yt(e,t,n){const i=g.hoverPoints,o=g.rectangles;for(let r=0;r<o.length;r++){const f=o[r];if(Math.abs(e-f.x)<=f.width/2&&Math.abs(t-f.y)<=f.height/2){const h=g.dies[r];return h?{die:h,index:r}:null}}let a=null,d=-1,l=n*n;for(let r=0;r<i.length;r++){const f=i[r].x-e,h=i[r].y-t,y=f*f+h*h;y<l&&(l=y,a=g.dies[r]??null,d=r)}return a?{die:a,index:d}:null}const Hn=new k.ResizeObserver(()=>{N=null,B=null,x()});Hn.observe(s),v.height==null&&si<=0&&Gt(()=>Gt(()=>{P.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let _e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`);const dt=()=>{_e.removeEventListener("change",dt),_e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`),_e.addEventListener("change",dt),x()};_e.addEventListener("change",dt);const zn=k.matchMedia("(prefers-color-scheme: dark)"),Vn=()=>x();zn.addEventListener("change",Vn);const Yn=()=>{W&&yt(p)};k.addEventListener("blur",Yn);function Xn(e){if((e.key==="ContextMenu"||e.shiftKey&&e.key==="F10")&&(it=!0),e.key==="Escape"&&C.size>0&&(C=new Set,le?.([]),x()),(e.key==="e"||e.key==="E")&&sn&&(e.stopPropagation(),(on??Dn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),ct())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=z();if(n){const i=B?.snapDist??N?.snapDist??1;let o=0,a=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(a=20,e.preventDefault()),e.key==="ArrowDown"&&(a=-20,e.preventDefault()),(o||a)&&(B={originX:n.originX+o,originY:n.originY+a,ppm:n.ppm,snapDist:i},x())}e.key===" "&&!Xe&&(e.preventDefault(),Xe=!0,j!=="pan"&&(s.style.cursor="grab"))}}function Nn(e){e.key===" "&&(Xe=!1,ke&&(me=!1,ke=!1),s.style.cursor=j==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",Ln,{passive:!1}),s.addEventListener("pointerdown",Tn),s.addEventListener("pointermove",Pn),s.addEventListener("pointerup",On),s.addEventListener("pointerleave",Fn),s.addEventListener("pointercancel",An);const jn=()=>ct();s.addEventListener("dblclick",jn),s.addEventListener("keydown",Xn),s.addEventListener("keyup",Nn),s.addEventListener("contextmenu",Wn);const Kn=e=>{e.stopPropagation()};s.addEventListener("click",Kn),s.clientWidth,x(),qe?.();function ct(){N=null,B=null,x()}function Xt(){import("./userGuideHtml.js").then(e=>Gi({buildWaferMap:zi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:Yi},e.USER_GUIDE_HTML,di,P))}return Ie(),{setResult(e){q=e,V=e.wafer,ue=e.dies,$=e.hbinDefs,G=e.sbinDefs,U=e.testDefs,he=e.metadataFields,pn=e.reticles?.length?e.reticles:void 0,un=e.reticleConfig,hn=e.view?.dataAxisFlip,wt=e.isLotStack,Ct=e.aggrMethod,St=e.lotSize,yi(),Lt(),x(),Z&&ye()},setOptions(e){kn(e)},getOptions(){return{...c}},resetZoom:ct,setSelection(e){C=new Set(e.map(t=>fe(t))),x()},clearSelection(){C=new Set,le?.([]),x()},setFindingsNotice(e){xn=e,Z?ye():I&&je()},setStatsSummary(e){if(ae=e,vt(),Tt(),Z)ye();else if(I)je();else if(e&&!Fe?.placement){const t=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=t?"block":"none";const n=M.parentElement,i=M.nextSibling;de=Zt(M,I,"right"),n?.insertBefore(de,i),je()}rt()},closeSummaryPanel(){En(!1)},getExportTitle(){return en()},getBinColors(){return g.binColors},setSummaryVisible(e){K&&(K.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){ee&&(ee.style.display=e?"flex":"none")},openUserGuide:Xt,setInsightsOpen(e){ze(e),H&&(e?(H.dataset.active="1",H.style.background=w.bgActive,H.style.color=w.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=w.icon))},destroy(){fn=!0;for(const e of Ne.values())e.cancel();Ne.clear(),be?.close(),Sn?.()?.remove(),Pt&&p.removeEventListener("click",Pt,!0),s.removeEventListener("wheel",Ln),s.removeEventListener("pointerdown",Tn),s.removeEventListener("pointermove",Pn),s.removeEventListener("pointerup",On),s.removeEventListener("pointerleave",Fn),s.removeEventListener("pointercancel",An),s.removeEventListener("dblclick",jn),s.removeEventListener("keydown",Xn),s.removeEventListener("keyup",Nn),s.removeEventListener("contextmenu",Wn),cn?.(),s.removeEventListener("click",Kn),Hn.disconnect(),_e.removeEventListener("change",dt),zn.removeEventListener("change",Vn),k.removeEventListener("blur",Yn),hi(),W&&yt(p),ie?.remove(),Be&&(Be.parentElement?.insertBefore(M,Be),Be.remove()),de&&(de.parentElement?.insertBefore(M,de),de.remove()),M.remove(),s.style.cursor="",X?.destroy(),Y?.destroy(),Re.remove()}}}
1
+ import{buildView as Pi,buildHoverText as Oi,findTestDef as ht,resolveTestNumber as _t,buildMapTitle as Ri}from"../renderer/buildView.js";import{drawMapCanvas as Ii,BIN_LEGEND_W as $n,BIN_LEGEND_W_COMPACT as Wi,BIN_LEGEND_ADAPT_COMPACT as Fi,BIN_LEGEND_ADAPT_FLOATING as Ai}from"./toCanvas.js";import{buildWaferMap as Hi,getTestPassStatus as zi,isParametricTest as $t}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Vi}from"../stats/analyzeWaferMap.js";import{SHADOW as Yi,LEADING as Gn,wireControlHover as Un,SPACE as A,EDGE_GUTTER as Xi,RADIUS as Zn,FONT as mt,CLR as x,applyOverlayZ as Ni,getTooltip as Qn,hideTooltip as yt,positionTooltip as qn,createToolbarHelpers as ji,buildModeMenuEl as Ki,openReparentedModal as _i,openUserGuideWindow as $i,makePaletteBtn as Gi,makeLogScaleBtn as Ui,makeLegendStyleBtn as Zi,makeOverlaysBtn as Qi,makeOrientationBtn as qi,menuLayerFor as Jn,saveImageBlob as Ji,markMenuTrigger as Qe,wireMenuA11y as ei,wireExpandToggle as eo,nextFrame as Gt,requestedPassFailDisplay as to,overlayMenuRows as no,anyOverlayActive as io,logWmapVersionOnce as oo,buildDataModeEntries as so,metadataKeyHasData as lo,metadataModeEntry as ao}from"./toolbar.js";import{waferIdentityLabel as ro}from"../core/waferLabel.js";import{metadataDisplayValue as co}from"../core/metadata.js";import{withExportContext as fo}from"./exportName.js";import{createSummaryPanelEl as Ut,wrapWithSummaryPanel as Zt,renderWaferSummaryContentSteps as po}from"./summaryPanel.js";import{runChunked as uo}from"./chunked.js";import{collectWarnings as go,buildWarningsMenuEl as ho,severityOf as mo}from"./warnings.js";import{ICONS as ti}from"./icons.js";import{hasDrilldownTargets as yo,selectionPopulation as bo,waferPopulation as vo}from"./chartPopulation.js";import{createIdentityHeader as xo,collapsedLabel as Qt}from"./identityHeader.js";import{getDieKey as fe,hasPosition as ni,isPositionedDie as wo}from"../core/dies.js";import{buildDieListSection as Co}from"./dieList.js";import{buildMaplessSummary as So}from"./maplessSummary.js";import{resolveBinColors as Mo,binColorWarning as Eo}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as Do}from"../core/passBins.js";const ii=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(P){const m=P.some(p=>ii.has(p)),M=P.some(p=>!ii.has(p));return m&&M?"mixed":m?"preference":"state"}export function toPublicViewOptions(P){const{metadataValueOrder:m,binColors:M,lotSize:p,...k}=P;return k}export function renderWaferMap(P,m,M={}){return renderWaferMapCard(P,m,M)}export function renderWaferMapCard(P,m,M={}){oo();const p=P.ownerDocument,k=p.defaultView??window,qt=()=>q.label,Jt=()=>ro({label:qt(),wafer:V}),pe=fo(()=>{const e=co(V.metadata?.lot);return{prefix:M.downloadFilename,lots:e!==void 0?[e]:[],...q.isLotStack?{stackedWafers:h?.lotSize??!0}:{wafer:Jt()}}},M.onSaveImage,M.onSaveText);function en(){const e=h.plotMode==="softBin"||h.plotMode==="stackedSoftBins"?G:$,{primary:t,secondary:n}=Ri(h,c.fallbackFormat,e);return[t,q.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}k.getComputedStyle(P).position==="static"&&(P.style.position="relative");const oi=P.clientHeight;M.height!=null&&(P.style.height=typeof M.height=="number"?`${M.height}px`:M.height);const bt=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!ni(e)).length,Oe=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-bt)===0&&bt>0,Re=p.createElement("div");Object.assign(Re.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),P.appendChild(Re);const Ce=p.createElement("div");Object.assign(Ce.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const ue=M.chromeInset??Xi,_=p.createElement("div");Object.assign(_.style,{display:"flex",alignItems:"stretch",gap:A.sm,background:x.canvasBg,paddingBottom:A.lg,paddingTop:ue,paddingLeft:ue,paddingRight:ue,flexShrink:"0",minWidth:"0"}),Re.appendChild(_),Re.appendChild(Ce);function Ie(){const e=[..._.children].some(t=>t.style.display!=="none");_.style.display=e?"flex":"none"}const S=p.createElement("div");Object.assign(S.style,{position:"relative",width:"100%",height:"100%"});const s=p.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),S.appendChild(s),Ce.appendChild(S);let qe=null;if(bt>0){let n=function(){if(t){const d=Co(e,m.testDefs,{...M.dieList,onSaveText:pe.onSaveText,waferMetadata:V.metadata,metadataFields:me,ownerDocument:p});if(d)return d}const o=ht(m.testDefs,c.activeTest??0),a=$t(o)?c.logScale??o?.logScale??!1:!1;return So(e,m.testDefs,{plotMode:c.plotMode??"hardBin",activeTest:c.activeTest,hbinDefs:$,sbinDefs:G,binColors:h.binColors,valueColorScheme:c.valueColorScheme,reverseValueScheme:c.reverseValueScheme,logScale:a,colorbarRangeMode:c.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const a=p.createElement("button");return a.type="button",Un(a),Object.assign(a.style,{fontSize:mt.body,padding:`${A.xxs} ${A.sm}`,borderRadius:Zn.control,flexShrink:"0",border:`1px solid ${x.menuBorder}`,background:x.menuBg,color:x.text,cursor:"pointer"}),a.textContent=t?"View chart":"View die list",a.addEventListener("click",d=>{d.stopPropagation(),t=!t,a.textContent=t?"View chart":"View die list",o()}),a};const e=m.dies.filter(o=>!ni(o));let t=!1;if(Oe){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:x.panelBg,padding:A.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:A.md,zIndex:"1"});const a=p.createElement("div");Object.assign(a.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:A.md});const d=p.createElement("span");Object.assign(d.style,{fontSize:mt.body,color:x.label,lineHeight:Gn.base}),d.textContent="No die position data for this wafer.",a.appendChild(d);const l=p.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(a),o.appendChild(l),S.appendChild(o),qe=()=>{t||l.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,fontSize:mt.body,color:x.text,cursor:"pointer",padding:`${A.xs} ${A.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:A.md}),Un(o,"bare");const a=p.createElement("span");a.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(a);const d=p.createElement("span");d.textContent="\u25BE",Object.assign(d.style,{fontSize:mt.body,lineHeight:Gn.none,color:x.label,flexShrink:"0"}),o.appendChild(d),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,r=null;eo(o,f=>{if(d.textContent=f?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(f)),f){l=p.createElement("div");const g=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${g}px`,top:"20%",zIndex:"2",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,padding:A.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:A.md}),l.addEventListener("click",se=>se.stopPropagation());const y=p.createElement("div");Object.assign(y.style,{display:"flex",justifyContent:"flex-end"}),y.appendChild(i(()=>{r&&r.replaceChildren(n())})),l.appendChild(y),r=p.createElement("div"),Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(n()),l.appendChild(r),S.appendChild(l)}else l&&(l.remove(),l=null,r=null)}),S.appendChild(o),qe=()=>{r&&!t&&r.replaceChildren(n())}}}const{onHover:Je,onClick:si,onSelect:le,onViewOptionsChange:li,showTooltip:ai=!0,showToolbar:We=!0,showIdentity:tn=!0,summaryPanel:Fe,showHelpButton:nn=!1,userGuideExtension:ri,onExpand:on,showExpandButton:sn=!0,zIndex:di,insights:ge,warnings:ln,viewOptions:ci={},...Se}=M,Ae=ge?.enabled??!1,fi=.4,pi=20,et=[...m.passBins??Do],an=ln?.display??!0,ui=Ni(di);let ae=M.statsSummary,re=[],rn=!1,tt=null,dn=!1;function vt(){const e=go({result:m,statsSummary:ae,extra:tt?[tt]:[]}),t=e.length!==re.length||e.some((n,i)=>n.code!==re[i]?.code||n.message!==re[i]?.message);re=e,(t||!rn)&&(rn=!0,ln?.onWarning?.(e))}vt();let q=m,V=m.wafer,he=m.dies,w=new Set;const gi={sweeps:ge?.sweeps,onSaveImage:pe.onSaveImage},xt=()=>!Oe&&yo(U,ge?.sweeps);let cn=null,nt=null,it=!1,fn=!1,$=m.hbinDefs,G=m.sbinDefs,U=m.testDefs,me=m.metadataFields,pn=m.reticles?.length?m.reticles:void 0,un=m.reticleConfig,gn=m.view?.dataAxisFlip,wt=m.isLotStack??!1,Ct=m.aggrMethod,St=m.lotSize;const hi=We&&Ae;let Y=null,J=null,ee=null;tn&&(Y=xo(Qt(V.metadata??{},He())??"",V.metadata,{lotStack:He(),ownerDocument:p}),S.appendChild(Y.metaPanel),Y.metaPanel.style.visibility="visible",Y.isEmpty()||(J=hn(Y.wrap),_.insertBefore(J,_.firstChild),Ie()));function hn(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${A.sm} ${A.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:A.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function He(){return wt?{lotSize:St??1,aggrMethod:Ct}:void 0}function mi(){if(!Y)return;Y.update(Qt(V.metadata??{},He())??"",V.metadata,He());const e=J?.isConnected??!1,t=!Y.isEmpty();!t&&e?(J.remove(),J=null):t&&!e&&(J=hn(Y.wrap),J.style.display="",_.insertBefore(J,_.firstChild),Ie())}const yi=[...$??[],...G??[]].some(e=>e.color);let c={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...ci},X=null,te=!1,mn=null;function bi(){return Ae?X?Promise.resolve(X):(mn??=import("./insightsTab.js").then(({createInsightsTab:e})=>(X=e({getItems:()=>[{wafer:V,dies:he,hbinDefs:$,sbinDefs:G,testDefs:U,label:qt(),passBins:et,statsSummary:ae}],getBinColors:()=>h.binColors,getRingCount:()=>q.ringCount??4,onSaveImage:pe.onSaveImage,onSaveText:pe.onSaveText,defaultView:ge?.defaultView,sweeps:ge?.sweeps,onRemoveSweeps:ge?.onRemoveSweeps,showMetadataStrip:!1,contentInset:ue,backTab:hi?void 0:{label:"Map",onBack:()=>ze(!1)},onOpenGuide:nn&&!We?()=>Xt():void 0,focusTest:t=>{D({plotMode:"value",activeTest:t,highlightBin:void 0}),ze(!1)},ownerDocument:p}),Object.assign(X.el.style,{position:"absolute",inset:"0",background:x.canvasBg,overflowY:"auto",paddingTop:"0"}),X.el.style.display="none",Ce.appendChild(X.el),X)),mn):Promise.resolve(null)}let yn=0;const Mt=["wheel","touchstart","pointerdown","keydown"];function vi(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const d of i)k.clearTimeout(d);i.length=0;for(const d of Mt)e.removeEventListener(d,o)},a=()=>n||!te?!0:(e.scrollTop=t,e.scrollTop>=t);if(!a()){for(const d of Mt)e.addEventListener(d,o,{passive:!0,once:!0});for(const d of[0,50,150,300,600])i.push(k.setTimeout(()=>{a()},d));i.push(k.setTimeout(()=>{for(const d of Mt)e.removeEventListener(d,o)},700))}}function ze(e){if(!Ae)return;const t=te;te=e,X&&!e&&t&&(yn=X.el.scrollTop),X&&(X.el.style.display=e?"flex":"none"),S.style.visibility=e?"hidden":"",F&&(F.style.display=e||Oe?"none":"flex"),T&&(T.style.display=e?"none":"flex"),ee&&(ee.style.display=xe?"none":"flex"),ie&&(ie.style.display="flex"),J&&(J.style.display=""),Ie(),Y&&e&&Y.collapse(),rt(),H&&(H.innerHTML=e?ti.wafer:ti.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&bi().then(n=>{!n||!te||(n.el.style.display="flex",n.render(),vi(n.el,yn))})}Ae&&ge?.defaultOpen&&queueMicrotask(()=>ze(!0));let h,bn,N=null,B=null,Et=[],Dt;function vn(e){Dt!==e&&(Dt=e,v())}let ye=null,kt=Se.legendOffset??{x:0,y:0},Ve=!1,Me=!1,Ye={x:0,y:0},Bt={x:0,y:0},be=!1,Ee=!1,j="pan",De={x:0,y:0},ot={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Xe=!1,ke=!1;function Lt(){const e=c;h=Pi(V,he.filter(wo),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??Mo(he,{passBins:et,binColorScheme:e.binColorScheme,hbinDefs:$,sbinDefs:G,useDefinedBinColors:e.useDefinedBinColors}),passBins:et,showDieLabels:e.showDieLabels,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:pn,ringCount:q.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:U,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:wt,aggregationMethod:Ct??e.aggregationMethod,lotSize:St??e.lotSize,dataAxisFlip:gn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:me}),bn=new Map(h.dies.map((n,i)=>[fe(n),i]));const t=e.binColors?null:Eo(h.binColors,h.plotMode);t?.message!==tt?.message&&(tt=t,vt(),dn&&Tt())}Lt();let Z=null,Be=null,st=null,xn=M.findingsNotice,xi={},I=null,de=null;function wi(e){const{kind:t,index:n}=e.variable;D(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const i=e.highlight;i.kind==="bin"?(Ft(i.dieKeys),D({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Ft(i.dieKeys)}const Ne=new Map;function wn(e){Ne.get(e)?.cancel(),Ne.delete(e);const t=uo(po(e,{wafer:V,dies:he,yieldSummary:q.yield,dataCoverage:q.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:U,statsSummary:ae,warnings:an?re:[],passBins:et,ringCount:q.ringCount??4,binColors:h.binColors,plotMode:c.plotMode??"hardBin",metadataShownElsewhere:tn,fallbackFormat:c.fallbackFormat,activeFindingId:st,findingsFilter:xi,findingsNotice:xn,onFindingsFilterChange:ve,onSaveText:pe.onSaveText,metadataFields:me,dieListOptions:M.dieList,onFindingClick:(n,i)=>{st===n.id?(st=null,Ft([]),D({highlightBin:void 0})):(st=n.id,wi(n)),ve()}}));t.done||Ne.set(e,t)}function ve(){Z&&wn(Z)}function je(){I&&wn(I)}if(Fe?.placement){const e=Fe.placement;Z=Ut(e,ue,p);const t=S.parentElement,n=S.nextSibling;Be=Zt(S,Z,e),t?.insertBefore(Be,n),ve()}else if(ae){const e=Fe?.defaultOpen??!We;I=Ut("right",ue,p),I.style.display=e?"block":"none";const t=S.parentElement,n=S.nextSibling;de=Zt(S,I,"right"),t?.insertBefore(de,n),je()}const W=ai?Qn(p):null;let ie=null,L=null,F=null,T=null,lt=null,K=null,Cn=null,H=null,oe=null,at=null;dn=!0;function Tt(){if(!oe||!at)return;const e=re.length,t=e>0;if(oe.style.display=t?"flex":"none",at.style.display=t?"":"none",!t)return;const n=mo(re[0]),i=`${e} data ${e===1?"warning":"warnings"}`;oe.style.color=n==="error"?x.errText:x.warnText,oe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Pt=null,Sn=null,Ot=null,Rt=null,It=null,Wt=null;function Ft(e){w=new Set(e??[]),le&&le(Ke()),v()}function rt(){if(!K)return;const e=!!(Z??I);K.style.display=ae&&e&&!te?"flex":"none";const t=Z??I,n=t?t.style.display!=="none":!1;ae?.hasNotableFindings&&!n?K.style.color=x.findingIndicator:K.dataset.active||(K.style.color=x.icon)}let Mn=null;function En(e){const t=Z??I;t&&(t.style.display=e?"block":"none",K&&Mn?.(K,e),rt())}if(We){let g=function(b){j=b,i(se,b==="zoom"),i(E,b==="pan"),lt&&i(lt,b==="select"),s.style.cursor=b==="pan"?"grab":"crosshair"};ie=p.createElement("div"),ie.dataset.wmapToolbar="single",Object.assign(ie.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:x.menuBg,border:`1px solid ${x.menuBorder}`,borderRadius:Zn.control,boxShadow:Yi.panel,pointerEvents:"auto"});const e=Qn(p),t=ji(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:a,makeMenuSection:d,closeOpenMenu:l,getOpenMenu:r,setOpenMenu:f}=t;Mn=i,Pt=l,Sn=r,p.addEventListener("click",l,!0),F=p.createElement("div"),Object.assign(F.style,{display:Oe?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(F);const y=n("download","Download PNG",Mi);F.appendChild(y),F.appendChild(o());const se=n("zoomMode","Zoom (drag to zoom region)",()=>g("zoom")),Te=n("zoomIn","Zoom in",()=>Le(s.clientWidth/2,s.clientHeight/2,1.2)),ne=n("zoomOut","Zoom out",()=>Le(s.clientWidth/2,s.clientHeight/2,1/1.2)),ce=n("reset","Reset zoom (double-click)",()=>ct());F.appendChild(se),F.appendChild(Te),F.appendChild(ne),F.appendChild(ce),F.appendChild(o());const E=n("pan","Pan (drag to move)",()=>g("pan"));F.appendChild(E),lt=n("boxSelect","Select (drag to select dies)",()=>g("select")),F.appendChild(lt);{const b=n("drilldown","Chart this wafer",()=>{const Pe=b.getBoundingClientRect();In({x:Pe.left,y:Pe.bottom+4},b)});b.setAttribute("aria-haspopup","menu"),nt=b,Rn(),F.appendChild(b)}i(E,!0);{let b=function(u){return u.plotMode!==(c.plotMode??"hardBin")?!1:u.plotMode==="value"?(c.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?c.activeMetadataKey===u.activeMetadataKey:!0},Pe=function(u,C){u.activeTest!==void 0?D({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),C.remove(),f(null),Qe(Q,!1)};L=p.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(L),T=p.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const ft=()=>{const u=r();u&&(u.remove(),f(null)),Qe(Q,!1)},Q=n("mode","Plot mode",()=>{if(r()){ft();return}const u=he,C=h.testDefs,{testEntries:gt,binEntries:we,stackedEntries:Ge}=so(u,C,{includeStacked:h.isLotStack}),Kt=(me??[]).filter(Ze=>lo(u,Ze.key)).map(ao),Ue=Ki(Q.getBoundingClientRect(),gt,we,Ge,b,Pe,{makeMenuRow:a,makeMenuSection:d},c.plotMode??"hardBin",Q.ownerDocument.defaultView??window,Kt);Jn(Q).appendChild(Ue),f(Ue),Qe(Q,!0),ei(Ue,Q,ft)});Qe(Q,!1);const{btn:pt,sync:$e}=Gi(t,()=>({...c,plotMode:c.plotMode??"hardBin"}),()=>yi,D);Rt=$e,Rt();const Nt=Qi(t,()=>{const u=!!h.hasReticle,C=(c.plotMode??"hardBin")==="value",{testNumber:gt}=_t(c.activeTest??0,h.testDefs),we=ht(h.testDefs,gt),Ge=C&&we!==void 0&&!$t(we),Kt=C&&!Ge&&(we?.limitLow!==void 0||we?.limitHigh!==void 0),Ue=C&&!Ge&&h.dies.some(Ze=>zi(Ze,gt,we)!==void 0);return no(c,u,{functionalActive:Ge,hasLimits:Kt,hasRecorded:Ue,binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},Ze=>D(Ze))},()=>io(c)),{btn:jt,sync:Di}=Zi(t,()=>c,u=>D({legendPosition:u}));Ot=Di,Ot();const _n=()=>{const{testNumber:u}=_t(c.activeTest??0,U),C=ht(U,u);return C!==void 0&&!$t(C)},{btn:ki,sync:Bi}=Ui(t,()=>({...c,functionalActive:_n()}),u=>D(u));It=Bi,It();const Li=()=>{const{testNumber:u}=_t(c.activeTest??0,U),C=ht(U,u);return C!==void 0&&(C.limitLow!==void 0||C.limitHigh!==void 0)},ut=n("specRange","Colorbar range: test limits",()=>{const u=c.colorbarRangeMode==="data"?"spec":"data";D({colorbarRangeMode:u})});Wt=()=>{const u=c.plotMode==="value"&&Li()&&to(c)==="off"&&!_n();ut.style.display=u?"":"none";const C=(c.colorbarRangeMode??"spec")==="spec";i(ut,C),ut.ariaLabel=C?"Colorbar range: test limits (click for data range)":"Colorbar range: data range (click for test limits)"},Wt();const Ti=qi(t,()=>c,u=>D(u));T.appendChild(Q),T.appendChild(pt),T.appendChild(ki),T.appendChild(ut),Oe||(T.appendChild(o()),T.appendChild(Nt),T.appendChild(o()),T.appendChild(jt),T.appendChild(o()),T.appendChild(Ti)),ae&&(K=n("findings","Summary panel",()=>{const u=Z??I;u&&En(u.style.display==="none")}),L.appendChild(o()),L.appendChild(K),I?.style.display!=="none"&&i(K,!0),rt()),an&&(at=o(),oe=n("warning","Data warnings",()=>{const u=r();if(l(new MouseEvent("click")),u)return;const C=ho(oe.getBoundingClientRect(),re,k);Jn(Ce).appendChild(C),f(C),ei(C,oe,()=>l(new MouseEvent("click")))}),Qe(oe,!1),L.appendChild(at),L.appendChild(oe),Tt()),Ae&&(L.appendChild(o()),H=n("analysis","Insights",()=>{ze(!te),i(H,te)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),sn&&(L.appendChild(o()),ee=n("expand","Expand (E)",on??Dn),L.appendChild(ee)),nn&&(L.appendChild(o()),Cn=n("help","User guide",()=>Xt()),L.appendChild(Cn))}_.appendChild(ie),Ie()}let xe=null;function Dn(){xe&&(xe.close(),xe=null);const e=Ce;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=Qt(V.metadata??{},He()),n=_.childElementCount>0?[_,e]:[e],i=_i(n,{ownerDocument:p,boxSize:te?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{xe=null,ee&&(ee.style.display="flex"),te||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),xe=i,ee&&(ee.style.display="none"))}function kn(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&c.binColors!==void 0&&(e={...e,binColors:void 0});const t=c.plotMode;c={...c,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(a=>a==="legendPosition"||a==="showLegend"||a==="markFailingDies")||Lt(),Ot?.(),Rt?.(),It?.(),Wt?.(),v();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(a=>a in e);(o||i)&&(ve(),je()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&qe?.()}function D(e){kn(e);const t=Object.keys(e);li?.(c,t,classifyChanged(t))}let At=!1;function Ht(){At||(At=!0,Gt(()=>{At=!1,v()},k))}function v(){const e=B??void 0,t=h.dies[0],n=t?{x:t.width,y:t.height}:Se.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!($?.length||G?.length||h.dies.some(y=>y.hbin!=null||y.sbin!=null)),a=c.legendPosition??"default",d=c.showLegend??!0,l=a==="default"||a==="compact",r=(Se.colorbarWidth??16)+28,f=o&&l?a!=="default"?Math.max($n,r):i<Ai?0:i<Fi?Math.max(Wi,r):Math.max($n,r):void 0,g=Ii(s,h,{...Se,minRightReserve:d?f:0,showColorbar:d&&(Se.showColorbar??!0),markFailingDies:c.markFailingDies??!1,legendPosition:a,legendOffset:kt,diePitchMm:n,fallbackFormat:c.fallbackFormat,showAxes:Se.showAxes??B!==null,viewport:e,activeBin:c.plotMode==="metadata"?c.highlightMetadataValue:c.highlightBin,hoverBin:Dt,hbinDefs:$,sbinDefs:G,metadataFields:me});Et=g.binLegendRows,ye=g.legendBox??null,B===null&&(N=g.viewport),w.size>0&&Ci(),Ee&&Si(),Rn()}function Ci(){const e=z();if(!e)return;const t=s.getContext("2d"),n=h.hoverPoints,i=h.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,a=i?i.height/2*e.ppm:e.ppm*.5,d=Math.max(1,Math.min(3,o*.08)),l=o-d,r=a-d,f=[];for(const g of w){const y=bn.get(g);y!==void 0&&f.push({sx:e.originX+n[y].x*e.ppm,sy:e.originY-n[y].y*e.ppm})}if(f.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:g,sy:y}of f)t.rect(g-l,y-r,l*2,r*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:g,sy:y}of f)t.rect(g-l,y-r,l*2,r*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:g,sy:y}of f)t.rect(g-l,y-r,l*2,r*2);t.stroke(),t.restore()}}function Si(){const e=s.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),i=Math.abs(R.x-O.x),o=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,i,o),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,i,o),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,i,o),e.restore()}function Mi(){s.toBlob(e=>{e&&Ji(e,en(),pe.onSaveImage)})}function Bn(e){return N?Math.max(N.ppm*fi,Math.min(N.ppm*pi,e)):e}function Le(e,t,n){const i=B??N;if(!i)return;const o=Bn(i.ppm*n),a=o/i.ppm,d=e-(e-i.originX)*a,l=t-(t-i.originY)*a,r=(N?.snapDist??1)/(o/(N?.ppm??o));B={originX:d,originY:l,ppm:o,snapDist:r},v()}function z(){return B??N}function Ln(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Le(e.clientX-t.left,e.clientY-t.top,n)}else if(B!==null){e.preventDefault();const t=z(),n=B.snapDist;B={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}function zt(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function Tn(e){if(it=!1,e.button!==0||!z())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(ye&&c.legendPosition==="floating"&&zt(n,i,ye)){Me=!0,Ye={x:n,y:i},Bt={...kt};return}if(Xe&&j!=="pan"){ke=!0,be=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing";return}if(j==="zoom"||j==="select"){Ee=!0,O=R={x:n,y:i};return}be=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing"}function Pn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ee){R={x:n,y:i},Ht();return}if(Me){const g=n-Ye.x,y=i-Ye.y;g*g+y*y>16&&(Me=!1,Ve=!0,s.style.cursor="grabbing")}if(Ve){kt={x:Bt.x+(n-Ye.x),y:Bt.y+(i-Ye.y)},Ht();return}if(be){const g=z(),y=B?.snapDist??N?.snapDist??1;B={originX:ot.x+(n-De.x),originY:ot.y+(i-De.y),ppm:g.ppm,snapDist:y},Ht();return}const o=z();if(!o)return;const a=(n-o.originX)/o.ppm,d=(o.originY-i)/o.ppm,r=Yt(a,d,o.snapDist)?.die??null,f=Et.find(g=>n>=g.x&&n<g.x+g.w&&i>=g.y&&i<g.y+g.h);if(vn(f?f.bin:void 0),f){s.style.cursor="pointer",W&&(W.textContent=f.label??`Bin ${f.bin}`,W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})),Je?.(null,e);return}j==="pan"&&(s.style.cursor=r?"crosshair":"grab"),W&&(r?(W.innerHTML=Oi(r,h.plotMode,{testDefs:U,hbinDefs:$,sbinDefs:G,fallbackFormat:c.fallbackFormat,aggrMethod:h.aggrMethod,lotSize:h.lotSize,metadataFields:me,activeTest:h.activeTest,reticleConfig:un}),W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})):W.style.display="none"),Je?.(r,e)}function On(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(W&&(n<0||i<0||n>t.width||i>t.height)&&(W.style.display="none"),Ee){Ee=!1,R={x:n,y:i};const l=n-O.x,r=i-O.y,f=z();if(j==="zoom"){if(l*l+r*r<25)Le(n,i,2);else if(f){const g=Math.min(O.x,R.x),y=Math.max(O.x,R.x),se=Math.min(O.y,R.y),Te=Math.max(O.y,R.y),ne=y-g,ce=Te-se;if(ne>4&&ce>4){const E=s.clientWidth,b=s.clientHeight,Pe=E/ne,ft=b/ce,Q=Math.min(Pe,ft),pt=Bn(f.ppm*Q),$e=pt/f.ppm,Nt=(g+y)/2,jt=(se+Te)/2;B={originX:E/2-(Nt-f.originX)*$e,originY:b/2-(jt-f.originY)*$e,ppm:pt,snapDist:f.snapDist/$e}}}v(),s.style.cursor="crosshair";return}if(l*l+r*r<25)Vt(n,i,o,e);else if(f){const g=(Math.min(O.x,R.x)-f.originX)/f.ppm,y=(Math.max(O.x,R.x)-f.originX)/f.ppm,se=(f.originY-Math.max(O.y,R.y))/f.ppm,Te=(f.originY-Math.min(O.y,R.y))/f.ppm,ne=h.hoverPoints,ce=[];for(let E=0;E<ne.length;E++)if(ne[E].x>=g&&ne[E].x<=y&&ne[E].y>=se&&ne[E].y<=Te){const b=h.dies[E];b&&ce.push(b)}if(o)for(const E of ce){const b=fe(E);w.has(b)?w.delete(b):w.add(b)}else w=new Set(ce.map(E=>fe(E)));le?.(Ke())}v(),s.style.cursor="crosshair";return}if(Me){Me=!1,Vt(n,i,o,e);return}if(Ve){Ve=!1,s.style.cursor="grab";return}if(!be)return;if(be=!1,ke){ke=!1,s.style.cursor=Xe||j==="pan"?"grab":"crosshair";return}s.style.cursor=j==="pan"?"grab":"crosshair";const a=n-De.x,d=i-De.y;a*a+d*d<25&&Vt(n,i,o,e)}function Vt(e,t,n,i){for(const l of Et)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const r=c.highlightBin===l.bin?void 0:l.bin;D({highlightBin:r})}else{const r=c.highlightMetadataValue===l.bin?void 0:l.bin;D({highlightMetadataValue:r})}return}if(ye&&zt(e,t,ye))return;const o=z();if(!o)return;const d=Yt((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(d){si?.(d,i);const l=fe(d);n?w.has(l)?w.delete(l):w.add(l):w=new Set([l]),le?.(Ke()),v()}else n||(w=new Set,le?.([]),v())}function Ke(){const e=[],t=h.hoverPoints;for(let n=0;n<t.length;n++){const i=h.dies[n];i&&w.has(fe(i))&&e.push(i)}return e}function Rn(){nt&&(nt.style.display=xt()?"flex":"none",nt.ariaLabel=w.size>0?"Chart the selected dies (or right-click)":"Chart this wafer (or right-click)")}function Ei(){const e={waferLabel:Jt(),testDefs:U,isLotStack:q.isLotStack,activeTest:c.plotMode==="value"?c.activeTest:void 0};return w.size>0?bo(Ke(),e):vo(he,e)}function In(e,t){if(!xt())return;const n=Ei();import("./drilldown.js").then(({openDrilldownMenu:i})=>{fn||(cn=i(e,t,n,gi))})}function Wn(e){e.stopPropagation();const t=it;if(it=!1,!xt()||te)return;const n=s.getBoundingClientRect();if(!t){const o=e.clientX-n.left,a=e.clientY-n.top;if(ye&&zt(o,a,ye))return;const d=z(),l=d?Yt((o-d.originX)/d.ppm,(d.originY-a)/d.ppm,d.snapDist)?.die:void 0;l&&!w.has(fe(l))&&(w=new Set([fe(l)]),le?.(Ke()),v())}e.preventDefault();const i=t?{x:n.left+n.width/2,y:n.top+n.height/2}:{x:e.clientX,y:e.clientY};In(i,s)}function Fn(){vn(void 0),W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair"}function An(){be=!1,ke=!1,Ee=!1,Me=!1,Ve=!1,W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair",v()}function Yt(e,t,n){const i=h.hoverPoints,o=h.rectangles;for(let r=0;r<o.length;r++){const f=o[r];if(Math.abs(e-f.x)<=f.width/2&&Math.abs(t-f.y)<=f.height/2){const g=h.dies[r];return g?{die:g,index:r}:null}}let a=null,d=-1,l=n*n;for(let r=0;r<i.length;r++){const f=i[r].x-e,g=i[r].y-t,y=f*f+g*g;y<l&&(l=y,a=h.dies[r]??null,d=r)}return a?{die:a,index:d}:null}const Hn=new k.ResizeObserver(()=>{N=null,B=null,v()});Hn.observe(s),M.height==null&&oi<=0&&Gt(()=>Gt(()=>{P.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let _e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`);const dt=()=>{_e.removeEventListener("change",dt),_e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`),_e.addEventListener("change",dt),v()};_e.addEventListener("change",dt);const zn=k.matchMedia("(prefers-color-scheme: dark)"),Vn=()=>v();zn.addEventListener("change",Vn);const Yn=()=>{W&&yt(p)};k.addEventListener("blur",Yn);function Xn(e){if((e.key==="ContextMenu"||e.shiftKey&&e.key==="F10")&&(it=!0),e.key==="Escape"&&w.size>0&&(w=new Set,le?.([]),v()),(e.key==="e"||e.key==="E")&&sn&&(e.stopPropagation(),(on??Dn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),ct())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=z();if(n){const i=B?.snapDist??N?.snapDist??1;let o=0,a=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(a=20,e.preventDefault()),e.key==="ArrowDown"&&(a=-20,e.preventDefault()),(o||a)&&(B={originX:n.originX+o,originY:n.originY+a,ppm:n.ppm,snapDist:i},v())}e.key===" "&&!Xe&&(e.preventDefault(),Xe=!0,j!=="pan"&&(s.style.cursor="grab"))}}function Nn(e){e.key===" "&&(Xe=!1,ke&&(be=!1,ke=!1),s.style.cursor=j==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",Ln,{passive:!1}),s.addEventListener("pointerdown",Tn),s.addEventListener("pointermove",Pn),s.addEventListener("pointerup",On),s.addEventListener("pointerleave",Fn),s.addEventListener("pointercancel",An);const jn=()=>ct();s.addEventListener("dblclick",jn),s.addEventListener("keydown",Xn),s.addEventListener("keyup",Nn),s.addEventListener("contextmenu",Wn);const Kn=e=>{e.stopPropagation()};s.addEventListener("click",Kn),s.clientWidth,v(),qe?.();function ct(){N=null,B=null,v()}function Xt(){import("./userGuideHtml.js").then(e=>$i({buildWaferMap:Hi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:Vi},e.USER_GUIDE_HTML,ri,P))}return Ie(),{setResult(e){q=e,V=e.wafer,he=e.dies,$=e.hbinDefs,G=e.sbinDefs,U=e.testDefs,me=e.metadataFields,pn=e.reticles?.length?e.reticles:void 0,un=e.reticleConfig,gn=e.view?.dataAxisFlip,wt=e.isLotStack,Ct=e.aggrMethod,St=e.lotSize,mi(),Lt(),v(),Z&&ve()},setOptions(e){kn(e)},getOptions(){return{...c}},resetZoom:ct,setSelection(e){w=new Set(e.map(t=>fe(t))),v()},clearSelection(){w=new Set,le?.([]),v()},setFindingsNotice(e){xn=e,Z?ve():I&&je()},setStatsSummary(e){if(ae=e,vt(),Tt(),Z)ve();else if(I)je();else if(e&&!Fe?.placement){const t=Fe?.defaultOpen??!We;I=Ut("right",ue,p),I.style.display=t?"block":"none";const n=S.parentElement,i=S.nextSibling;de=Zt(S,I,"right"),n?.insertBefore(de,i),je()}rt()},closeSummaryPanel(){En(!1)},getExportTitle(){return en()},getSaveImageHook(){return pe.onSaveImage},getBinColors(){return h.binColors},setSummaryVisible(e){K&&(K.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){ee&&(ee.style.display=e?"flex":"none")},openUserGuide:Xt,setInsightsOpen(e){ze(e),H&&(e?(H.dataset.active="1",H.style.background=x.bgActive,H.style.color=x.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=x.icon))},destroy(){fn=!0;for(const e of Ne.values())e.cancel();Ne.clear(),xe?.close(),Sn?.()?.remove(),Pt&&p.removeEventListener("click",Pt,!0),s.removeEventListener("wheel",Ln),s.removeEventListener("pointerdown",Tn),s.removeEventListener("pointermove",Pn),s.removeEventListener("pointerup",On),s.removeEventListener("pointerleave",Fn),s.removeEventListener("pointercancel",An),s.removeEventListener("dblclick",jn),s.removeEventListener("keydown",Xn),s.removeEventListener("keyup",Nn),s.removeEventListener("contextmenu",Wn),cn?.(),s.removeEventListener("click",Kn),Hn.disconnect(),_e.removeEventListener("change",dt),zn.removeEventListener("change",Vn),k.removeEventListener("blur",Yn),ui(),W&&yt(p),ie?.remove(),Be&&(Be.parentElement?.insertBefore(S,Be),Be.remove()),de&&(de.parentElement?.insertBefore(S,de),de.remove()),S.remove(),s.style.cursor="",X?.destroy(),Y?.destroy(),Re.remove()}}}
@@ -1,3 +1,3 @@
1
- import{waferDisplayLabel as ve}from"../core/waferLabel.js";import{itemPassBins as Se,passBinsLabel as lt}from"../core/passBins.js";import{isParametricTest as dt}from"../renderer/buildWaferMap.js";import{testLabel as ct,markedTestLabel as pt,unmarkedLabel as ut,derivedFields as we,derivedKeyText as ft,derivedCsvCell as Ne,isDerivedTest as Te,DERIVED_CSV_HEADER as De}from"../renderer/testLabel.js";import{buildRingRegions as mt,buildQuadrantRegions as gt,buildRegionYieldData as ht}from"../stats/regions.js";import{computeFunctionalYield as bt}from"../stats/analyzeWaferMap.js";import{renderWaferReportHtml as xt,renderLotReportHtml as yt}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as Ct}from"../stats/findingsNarrative.js";import{formatFindingTooltip as vt}from"../stats/reportHtml.js";import{filterFindings as St}from"../stats/filterFindings.js";import{buildFacetTable as wt,prettyKey as Ee}from"../stats/facets.js";import{commonMetadata as Fe}from"../stats/facets.js";import{resolveMetadataColumns as $t}from"../stats/metadataColumns.js";import{resolveBinColors as Re,resolveBinColorsByWafer as kt}from"../renderer/binColors.js";import{NO_DATA_FILL as Lt}from"../renderer/colorMap.js";import{describeWaferPopulation as Me,populationLabel as Bt}from"../stats/population.js";import{buildWarningsBanner as $e,collectWarnings as Ie}from"./warnings.js";export{$e as buildWarningsBanner};import{fmt as Ae,fmtAggregationMethod as Nt,plainBinTerms as de}from"../renderer/fmt.js";import{getUniqueTestNumbers as Tt}from"../renderer/buildView.js";import{describeSorted as Dt,quantile as We}from"../stats/math.js";import{pooledTestStatsSteps as Et}from"../stats/capability.js";import{sortBinsForDisplay as Ft}from"../stats/binPareto.js";import{poolFunctionalYield as Rt}from"../stats/testPassRate.js";import{makeLabeledSelect as Pe,makeSegmented as ke}from"./charts/chartShell.js";import{SHADOW as ze,MOTION as He,LEADING as ne,TRACKING as fe,wireControlHover as G,controlStyle as me,SPACE as x,RADIUS as q,FONT as T,CLR as $,sevColor as ge,openModal as Oe,openReportModal as Ye,saveTextFile as _e,wireTooltip as ce}from"./toolbar.js";import{buildDieListSection as Mt}from"./dieList.js";export{csvField}from"../core/utils.js";import{csvField as he,drain as be,maxOf as It,medianOfSorted as At,minOf as Wt}from"../core/utils.js";import{metadataDisplayValue as Pt}from"../core/metadata.js";const zt=$.panelBg,je=`1px solid ${$.menuBorder}`,Ht="12px",Y=$.label,ie=$.value,Ke="10px";function l(e,t,i,n=document){const o=n.createElement(e);return t&&Object.assign(o.style,t),i!==void 0&&(o.textContent=i),o}function se(e){return l("div",{fontSize:Ke,fontWeight:"700",letterSpacing:fe,textTransform:"uppercase",color:Y,marginBottom:x.sm},e)}const Ve=new WeakMap,qe=["regionYield","testValues","functionalTests"];function xe(e){if(!e)return{collapsed:new Set(qe),regionMode:"ring",waferSort:"slot"};let t=Ve.get(e);return t||(t={collapsed:new Set(qe),regionMode:"ring",waferSort:"slot"},Ve.set(e,t)),t}function oe(e,t=!0,i,n){const o=l("div"),u=xe(n?.panel);n?.stateKey&&n.panel&&(t=!u.collapsed.has(n.stateKey));const s=document.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",gap:x.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const m=l("span",{fontSize:T.meta,color:Y,transition:`transform ${He.base}`,transform:t?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:ne.none,marginRight:"1px"},"\u25B6"),p=l("span",{fontSize:Ke,fontWeight:"700",letterSpacing:fe,textTransform:"uppercase",color:Y,flex:"1"},e);if(G(s,"bare"),s.setAttribute("aria-expanded",t?"true":"false"),s.appendChild(m),s.appendChild(p),i){const b=l("span",{fontSize:T.meta,fontWeight:"700",background:$.warnBg,color:$.warnText,borderRadius:q.pill,padding:"1px 5px"},i);s.appendChild(b)}const r=l("div");r.style.display=t?"block":"none";let a=t;if(s.addEventListener("click",()=>{a=!a,r.style.display=a?"block":"none",m.style.transform=a?"rotate(90deg)":"rotate(0deg)",s.setAttribute("aria-expanded",a?"true":"false"),n?.stateKey&&n.panel&&(a?u.collapsed.delete(n.stateKey):u.collapsed.add(n.stateKey))}),n?.control){const b=l("div",{display:"flex",alignItems:"center",gap:x.sm});s.style.width="auto",s.style.flex="1",b.appendChild(s);const f=()=>{r.innerHTML="",n.render?.(r)},w=n.control(f);w&&(w.style.marginBottom="6px",w.addEventListener("click",k=>k.stopPropagation()),b.appendChild(w)),o.appendChild(b)}else o.appendChild(s);return o.appendChild(r),n?.render?.(r),{outer:o,content:r}}function Ge(){return l("div",{height:"1px",background:$.separator,margin:`${Ht} 0`,flexShrink:"0"})}function Le(e,t,i=$.barFill,n,o){const u=l("div",{marginBottom:"5px"}),s=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,color:ie,marginBottom:x.xxs}),m=l("span",{color:Y},e),p=l("span",{fontWeight:"600"},`${t.toFixed(1)}%`);s.appendChild(m),s.appendChild(p);const r=n!==void 0?n:Math.min(100,Math.max(0,t)),a=i,b=l("div",{position:"relative",height:"9px",background:$.bgActive,borderRadius:q.control,overflow:"hidden"}),f=l("div",{height:"100%",width:`${r}%`,background:a,borderRadius:q.control,transition:`width ${He.base}`});if(b.appendChild(f),o!==void 0){const w=l("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"2px",marginLeft:"-1px",background:$.value,opacity:"0.8"});b.appendChild(w)}return u.appendChild(s),u.appendChild(b),u}function Ue(){const e=l("div",{display:"flex",gap:x.sm,marginBottom:x.md});return e.finish=()=>{const t=e.lastElementChild;t&&Object.assign(t.style,{borderRight:"none",paddingRight:"0"})},e}function pe(e,t,i){const n=l("div",{padding:`${x.xxs} ${x.md} ${x.xxs} 0`,borderRight:je,textAlign:"center",flex:"1"}),o=l("div",{fontSize:T.heading,fontWeight:"700",color:ie,lineHeight:ne.tight},e),u=l("div",{fontSize:T.body,color:Y,marginTop:x.xxs},t);return n.appendChild(o),n.appendChild(u),i&&n.appendChild(l("div",{fontSize:T.body,color:Y,opacity:"0.85"},i)),n}function Qe(e,t){const i=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,gap:x.md,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},e),o=l("span",{color:ie,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}function Ot(e,t){const i=l("div",{display:"flex",fontSize:T.body,gap:x.sm,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},`${e}:`),o=l("span",{color:ie,fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}export function metadataEntries(e){const t=[];for(const[i,n]of Object.entries(e)){const o=Pt(n);o!==void 0&&t.push([i,o])}return t}const Yt=["lot","product","testprogram","split"],ye=e=>{const t=Yt.indexOf(e.toLowerCase().replace(/[^a-z]/g,""));return t===-1?Number.MAX_SAFE_INTEGER:t};export function buildFacetSummaryChips(e,t=3){if(!e.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${x.xs} ${x.lg}`}),n=[...e].sort((m,p)=>ye(m.key)-ye(p.key)),o=n.filter(m=>ye(m.key)!==Number.MAX_SAFE_INTEGER),u=n.filter(m=>ye(m.key)===Number.MAX_SAFE_INTEGER),s=m=>{const p=l("span",{whiteSpace:"nowrap"}),r=l("span",{color:Y},`${Ee(m.key)}: `);p.appendChild(r);const a=m.values.slice(0,t),b=m.values.length-a.length;let f=a.map(w=>w.value).join(", ");return b>0&&(f+=` +${b} more`),p.appendChild(document.createTextNode(f)),p};for(const m of o)i.appendChild(s(m));if(u.length){const m=l("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${x.xs} ${x.lg}`});for(const a of u)m.appendChild(s(a));const p=l("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:$.iconActive,fontSize:T.body,whiteSpace:"nowrap"});p.type="button",G(p,"bare");const r=a=>{m.style.display=a?"contents":"none",p.textContent=a?"less":`+${u.length} more`,p.setAttribute("aria-expanded",String(a))};r(!1),p.addEventListener("click",()=>r(p.getAttribute("aria-expanded")!=="true")),i.appendChild(m),i.appendChild(p)}return i}export function buildMetadataStripRow(e,t,i){const n=wt(e,i),o=buildFacetSummaryChips(n);if(!o&&!t)return null;const u=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(t){const s=l("span",{fontWeight:"500",whiteSpace:"nowrap"},t.aggrMethod?`${t.lotSize} wafers stacked \xB7 ${t.aggrMethod}`:`${t.lotSize} wafers stacked`);u.appendChild(s)}return o&&u.appendChild(o),u}const _t={display:"flex",flexDirection:"column",gap:x.sm,background:$.menuBg,border:`1px solid ${$.menuBorder}`,borderRadius:q.container,padding:`${x.sm} ${x.lg}`,boxShadow:ze.panel,fontSize:T.body,lineHeight:ne.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(e,t,i){const n=buildMetadataStripRow(e,t,i);if(!n)return null;const o=l("div",_t);return o.appendChild(n),o}export function buildCompactMetadataRows(e){const t=metadataEntries(e);if(!t.length)return null;const i=l("div");for(const[n,o]of t)i.appendChild(Ot(Ee(n),o));return i}export function buildMetadataInfoSection(e,t){const i=buildMetadataStripRow(e,t,{facetableOnly:e.length>1});if(!i)return null;const n=l("div");return n.appendChild(se("Wafer Info")),n.appendChild(i),n}export function buildYieldSection(e,t,i=[1]){const n=l("div");n.appendChild(se("Summary"));const o=Ue();if(o.appendChild(pe(String(e.totalDies),"Total dies")),e.partialDies>0&&o.appendChild(pe(String(e.partialDies),"Partial")),e.yieldPercent!==null){const u=lt([i]);o.appendChild(pe(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${u}`))}return o.finish(),n.appendChild(o),e.edgeExcludedDies>0&&n.appendChild(Qe("Edge excluded (outer zone)",String(e.edgeExcludedDies))),n}export function buildBinSection(e,t,i,n,o,u){const s=new Map;if(o)for(const[r,a]of Object.entries(o))s.set(Number(r),a);else for(const r of e){if(r.partial||r.edgeExcluded)continue;const a=i==="hard"?r.hbin:r.sbin;a!=null&&s.set(a,(s.get(a)??0)+1)}if(!s.size)return null;const m=n??Re(e,{passBins:u,...i==="hard"?{hbinDefs:t}:{sbinDefs:t}}),p=l("div");p.appendChild(se(Xe(i,[...s.values()].reduce((r,a)=>r+a,0))));for(const r of Ze(s,t,m[i],m.pass[i]))p.appendChild(r);return p}function Xe(e,t){return`${e==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${t})`}function Ze(e,t,i,n){const o=[...e.values()].reduce((m,p)=>m+p,0),u=t?new Map(t.map(m=>[m.bin,m])):null;return Ft(e.entries(),n).map(([m,p])=>{const r=u?.get(m),a=r?.name?`Bin ${m} \xB7 ${r.name}`:`Bin ${m}`,b=p/o*100,f=i.get(m)??Lt;return Le(`${a} (${p})`,b,f)})}export function buildBinBreakdownSection(e){const{dies:t,hbinDefs:i,sbinDefs:n,hardCounts:o,softCounts:u,plotMode:s,passBins:m=[1],panel:p}=e,r=e.binColors??Re(t,{passBins:m,hbinDefs:i,sbinDefs:n}),a=v=>{const g=v==="hard"?o:u,h=new Map;if(g){for(const[y,S]of Object.entries(g))h.set(Number(y),S);return h}for(const y of t){if(y.partial||y.edgeExcluded)continue;const S=v==="hard"?y.hbin:y.sbin;S!=null&&h.set(S,(h.get(S)??0)+1)}return h},b=a("hard"),f=a("soft"),w=b.size>0,k=f.size>0;if(!w&&!k)return null;const F=xe(p),H=s==="softBin"||s==="stackedSoftBins"?"soft":s==="hardBin"||s==="stackedBins"?"hard":void 0;let I=F.binMode??H??(w?"hard":"soft");I==="hard"&&!w&&(I="soft"),I==="soft"&&!k&&(I="hard");const O=I==="hard"?b:f,z=I==="hard"?i:n,C=[...O.values()].reduce((v,g)=>v+g,0),{outer:d}=oe(Xe(I,C),!0,void 0,{stateKey:"bins",panel:p,render:v=>{const g=I==="hard"?r.hard:r.soft;for(const h of Ze(O,z,g,r.pass[I]))v.appendChild(h)},control:w&&k&&p?()=>ke([["hard","Hard"],["soft","Soft"]],I,v=>{F.binMode=v;const g=buildBinBreakdownSection(e);g&&d.replaceWith(g)},p.ownerDocument,!0):void 0});return d}export function buildLotBinSection(e,t,i,n){return buildBinSection(e,t,i,n)}export function buildRegionYieldPanelSection(e){const{diesByWafer:t,allWafers:i,ringCount:n,passBins:o,panel:u}=e,s=xe(u),m=a=>ht(t,i,n,o,a==="ring"?mt:gt);if(!m("ring").length&&!m("quadrant").length)return null;const p=s.regionMode,{outer:r}=oe(p==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:u,render:a=>{const b=m(p);if(!b.length){a.appendChild(l("div",{fontSize:T.body,color:Y},"No positioned dies for this breakdown."));return}for(const{label:f,n:w,yieldPercent:k}of b)a.appendChild(Le(`${f} (N=${w})`,k))},control:u?()=>ke([["ring","Ring"],["quadrant","Quadrant"]],p,a=>{s.regionMode=a;const b=buildRegionYieldPanelSection(e);b&&r.replaceWith(b)},u.ownerDocument,!0):void 0});return r}export function buildLotOverviewSection(e,t=[]){const i=l("div"),n=Me(e.perWafer.map(s=>s.summary.wafer));i.appendChild(se(n.lotId!==void 0?"Lot Summary":"Summary"));const o=Ue();o.appendChild(pe(String(e.stats.waferCount),"Wafers"));const u=e.perWafer.map(s=>s.summary.stats.yieldPercent).filter(s=>s!==null);if(u.length){const s=u.reduce((m,p)=>m+p,0)/u.length;o.appendChild(pe(`${s.toFixed(1)}%`,"Mean per-wafer yield"))}if(o.finish(),i.appendChild(o),t.length){const s=t.reduce((p,r)=>p+r.stats.analyzedDies,0),m=t.reduce((p,r)=>p+r.stats.excludedDies,0);(s||m)&&i.appendChild(Qe("Dies analysed",m?`${s.toLocaleString()} (${m.toLocaleString()} excluded)`:s.toLocaleString()))}return i}export function buildPerWaferYieldSection(e,t,i,n,o){const u=e.perWafer.map(C=>({waferIndex:C.waferIndex,label:ve(t[C.waferIndex],C.waferIndex).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:C.summary.stats.yieldPercent})).filter(C=>C.yieldPct!==null);if(!u.length)return null;const s=Wt(u.map(C=>C.yieldPct)),m=It(u.map(C=>C.yieldPct)),p=s===m?"":` (${s.toFixed(1)}\u2013${m.toFixed(1)}%)`,r=[...u.map(C=>C.yieldPct)].sort((C,d)=>C-d),a=At(r),b=We(r,.25),f=We(r,.75),w=u.length>=5?b-1.5*(f-b):-1/0,k=xe(n),F=C=>{const d=k.waferSort==="yield"?[...u].sort((v,g)=>v.yieldPct-g.yieldPct):u;for(const{waferIndex:v,label:g,yieldPct:h}of d){const S=h<w?`${g} \xB7 low outlier`:g,L=Le(S,h,void 0,void 0,a),A=o?.(v);A?.total&&O(L,A),z(L,v,g,h,A),C.appendChild(L)}},H=` \xB7 median ${a.toFixed(1)}%`,{outer:I}=oe("Wafer Yield"+p+H,!0,void 0,{stateKey:"waferYield",panel:n,render:F,control:n?C=>ke([["slot","Slot"],["yield","Yield"]],k.waferSort,d=>{k.waferSort=d,C()},n.ownerDocument,!0):void 0});return I;function O(C,d){const v=d.unusual?"unusual":d.notable?"notable":"info",g=l("span",{marginLeft:x.sm,flexShrink:"0",background:ge(v),color:"#fff",borderRadius:q.container,padding:"0 5px",fontSize:T.body,fontWeight:"600"},`${d.total}`);g.setAttribute("aria-hidden","true"),ce(g,`${d.total} finding${d.total===1?"":"s"}`+(d.unusual?`, ${d.unusual} unusual`:"")+(d.notable?`, ${d.notable} notable`:"")),C.firstElementChild?.firstElementChild?.appendChild(g)}function z(C,d,v,g,h){i&&(C.style.cursor="pointer",C.style.borderRadius="4px",C.style.padding="2px 3px",C.style.marginLeft="-3px",C.style.marginRight="-3px",C.setAttribute("role","button"),C.setAttribute("aria-label",`${v}, ${g.toFixed(1)}% yield`+(h?.total?`, ${h.total} finding${h.total===1?"":"s"}${h.unusual?`, ${h.unusual} unusual`:""}`:"")+" \u2014 open wafer"),C.tabIndex=0,C.addEventListener("mouseenter",()=>{C.style.background=$.bgHover}),C.addEventListener("mouseleave",()=>{C.style.background=""}),C.addEventListener("focus",()=>{C.style.background=$.bgHover}),C.addEventListener("blur",()=>{C.style.background=""}),C.addEventListener("click",()=>i(d)),C.addEventListener("keydown",y=>{(y.key==="Enter"||y.key===" ")&&(y.preventDefault(),i(d))}))}}function jt(e){return Dt([...e].sort((t,i)=>t-i))}function Je(e,t){if(!e)return[];const i=e.waferMetadata??(e.perWaferMetadata?Fe(e.perWaferMetadata.map(n=>({metadata:n}))):void 0);return!i||!Object.keys(i).length?[]:$t({waferMetadata:i,waferKeys:"identity",waferPlacement:"csv",reservedLabels:t}).columns}function et(e){return e?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:e.populationLabel,get:()=>e.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(...e){return be(buildTestSectionSteps(...e))}export function*buildTestSectionSteps(e,t,i,n,o,u,s,m,p="full"){const r=e.filter(c=>!c.partial&&!c.edgeExcluded),a=new Map((n?.perTestStats??[]).map(c=>[c.testNumber,c])),b=new Map((n?.testSpecYield??[]).map(c=>[c.testNumber,c]));let f;if(t?.length?f=t.filter(dt).map(c=>({testNumber:c.testNumber,name:c.name,unit:c.unit,limitLow:c.limitLow,limitHigh:c.limitHigh,...we(c)})):f=Tt(r).map(W=>({testNumber:W,name:ct(void 0,W)})),!f.length)return null;const w=f.filter(c=>r.some(W=>{const j=W.testValues?.[c.testNumber];return j!==void 0&&isFinite(j)}));if(!w.length)return null;const k=w.some(c=>c.limitLow!==void 0||c.limitHigh!==void 0),F=[],H=c=>!!c&&c.stddev!==void 0&&c.median!==void 0&&c.q1!==void 0&&c.q3!==void 0,I=c=>c.limitLow!==void 0||c.limitHigh!==void 0,O=!!(s?.length&&t?.length),C=(O||w.some(c=>!H(a.get(c.testNumber))||I(c)&&!b.has(c.testNumber)))&&t?.length?yield*Et(s??[{dies:e}],t):void 0;for(const c of w){yield;const W=a.get(c.testNumber),j=C?.specTally.get(c.testNumber),ee=C?.stats.get(c.testNumber),K=()=>r.map(E=>E.testValues?.[c.testNumber]).filter(E=>E!==void 0&&isFinite(E));let Q;if(H(W)){const E=W;Q={testNumber:c.testNumber,min:E.min,max:E.max,mean:E.mean,count:E.count,stddev:E.stddev,median:E.median,q1:E.q1,q3:E.q3}}else if(ee)Q={testNumber:c.testNumber,...ee};else{const E=K();if(!E.length)continue;Q={testNumber:c.testNumber,...jt(E)}}let M=null,B=0;if(I(c)){const E=b.get(c.testNumber);if(E)({yieldPercent:M,totalDies:B}=E);else if(j)B=j.n,M=B>0?(B-j.fail)/B*100:null;else{const X=K();let ue=0;for(const te of X)(c.limitLow!==void 0&&te<c.limitLow||c.limitHigh!==void 0&&te>c.limitHigh)&&ue++;B=X.length,M=X.length>0?(X.length-ue)/X.length*100:null}}F.push({entry:c,stats:Q,specYieldPct:M,specN:B})}if(!F.length)return null;const d=new Map;for(const c of(O?C?.capability:void 0)??[])c.hasSpec&&d.set(c.testNumber,c.ppk);const v=d.size>0,h=new Set(F.map(c=>c.stats.count)).size===1?F[0].stats.count:null,y=l("div"),S=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:x.sm}),L=h!==null?` \xB7 N=${h.toLocaleString()}`:"",A=u?.populationLabel?`Test Values (${F.length}) \u2014 ${u.populationLabel}${L}`:`Test Values (${F.length})${L}`,D=se(A);D.style.marginBottom="0",S.appendChild(D);const R=document.createElement("button");R.type="button",R.textContent="Test values CSV",Object.assign(R.style,{...me("outlined")}),G(R),R.addEventListener("click",()=>{const c=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];v&&c.push("Ppk");const W=F.some(B=>B.specYieldPct!==null&&B.specN!==B.stats.count);k&&(c.push("LSL","USL","Spec Yield %"),W&&c.push("Spec Yield N"));const j=F.some(B=>Te(B.entry));j&&c.push(De);const ee=[...Je(u,c),...et(u)],Q=[[...ee.map(B=>B.label),...c].map(he).join(",")],M=B=>Ae(B,void 0,"engineering");for(const{entry:B,stats:E,specYieldPct:X,specN:ue}of F){const te=[...ee.map(le=>le.constant??""),B.name,B.unit??"",String(E.count),M(E.min),M(E.q1),M(E.median),M(E.mean),M(E.q3),M(E.max),M(E.stddev)];if(v){const le=d.get(B.testNumber);te.push(le==null?"":le.toFixed(3))}k&&(te.push(B.limitLow!==void 0?M(B.limitLow):"",B.limitHigh!==void 0?M(B.limitHigh):"",X!==null?X.toFixed(1):""),W&&te.push(B.limitLow!==void 0||B.limitHigh!==void 0?String(ue):"")),j&&te.push(Ne(B)),Q.push(te.map(he).join(","))}_e(Q.join(`
2
- `),"test-values.csv","text/csv",o)}),S.appendChild(R),y.appendChild(S);const P=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),Z=document.createElement("thead"),J=document.createElement("tr"),_=["Test"];h===null&&_.push("N"),p==="full"&&_.push("Min","Q1","Median"),_.push("Mean"),p==="full"&&_.push("Q3","Max","StdDev"),v&&_.push("Ppk"),p==="full"&&k&&_.push("LSL","USL"),k&&_.push("Spec yield");for(const c of _){const W=l("th",{textAlign:c==="Test"?"left":"right",fontWeight:"600",fontSize:T.meta,letterSpacing:fe,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},c);J.appendChild(W)}Z.appendChild(J),P.appendChild(Z);const U=document.createElement("tbody");for(const{entry:c,stats:W,specYieldPct:j,specN:ee}of F){const K=B=>Ae(B,c.unit,i),Q=document.createElement("tr"),M=(B,E="right")=>{const X=l("td",{textAlign:E,padding:`${x.xs} ${x.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:$.text,whiteSpace:"nowrap"},B);Q.appendChild(X)};if(M(pt(c,c.testNumber),"left"),h===null&&M(`${W.count}`),p==="full"&&(M(K(W.min)),M(K(W.q1)),M(K(W.median))),M(K(W.mean)),p==="full"&&(M(K(W.q3)),M(K(W.max)),M(K(W.stddev))),v){const B=d.get(c.testNumber);M(B==null?"\u2014":B.toFixed(2))}p==="full"&&k&&(M(c.limitLow!==void 0?K(c.limitLow):"\u2014"),M(c.limitHigh!==void 0?K(c.limitHigh):"\u2014")),k&&M(j!==null?h!==null&&ee===h?`${j.toFixed(1)}%`:`${j.toFixed(1)}% (N=${ee})`:"\u2014"),U.appendChild(Q)}P.appendChild(U);const N=l("div",{overflowX:"auto"});N.appendChild(P);const V=ot(N,F.map(c=>({label:c.entry.name,...we(c.entry)})));if(!m)return y.appendChild(V),y;S.remove();const{outer:re}=oe(A,!0,void 0,{stateKey:"testValues",panel:m,render:c=>c.appendChild(V),control:()=>R});return re}export function buildFunctionalTestSection(e,t,i,n,o,u){const s=i??bt(e,t);if(!s?.length)return null;const p=new Set(s.map(g=>g.totalDies)).size===1?s[0].totalDies:null,r=p!==null?` \xB7 N=${p.toLocaleString()}`:"",a=l("div"),b=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:x.sm}),f=o?.populationLabel?`Functional Tests (${s.length}) \u2014 ${o.populationLabel}${r}`:`Functional Tests (${s.length})${r}`,w=se(f);w.style.marginBottom="0",b.appendChild(w);const k=document.createElement("button");k.type="button",k.textContent="Functional CSV",Object.assign(k.style,{...me("outlined")}),G(k),k.addEventListener("click",()=>{const g=["Test","N","Pass","Fail","Pass Rate %"],h=s.some(L=>Te(L));h&&g.push(De);const y=[...Je(o,g),...et(o)],S=[[...y.map(L=>L.label),...g].map(he).join(",")];for(const L of s)S.push([...y.map(A=>A.constant??""),ut(L.label),String(L.totalDies),String(L.passDies),String(L.failDies),L.passRatePercent!==null?L.passRatePercent.toFixed(1):"",...h?[Ne(L)]:[]].map(he).join(","));_e(S.join(`
3
- `),"functional-tests.csv","text/csv",n)}),b.appendChild(k),a.appendChild(b);const F=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),H=document.createElement("thead"),I=document.createElement("tr"),O=p===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const g of O)I.appendChild(l("th",{textAlign:g==="Test"?"left":"right",fontWeight:"700",fontSize:T.body,letterSpacing:fe,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},g));H.appendChild(I),F.appendChild(H);const z=document.createElement("tbody");for(const g of s){const h=document.createElement("tr"),y=(S,L="right")=>{h.appendChild(l("td",{textAlign:L,padding:`${x.xs} ${x.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:ie,whiteSpace:"nowrap"},S))};y(g.label,"left"),p===null&&y(String(g.totalDies)),y(String(g.passDies)),y(String(g.failDies)),y(g.passRatePercent!==null?`${g.passRatePercent.toFixed(1)}%`:"\u2014"),z.appendChild(h)}F.appendChild(z);const C=l("div",{overflowX:"auto"});C.appendChild(F);const d=ot(C,s);if(!u)return a.appendChild(d),a;b.remove();const{outer:v}=oe(f,!0,void 0,{stateKey:"functionalTests",panel:u,render:g=>g.appendChild(d),control:()=>k});return v}export function buildLotFunctionalSection(e,t,i,n,o){const u=i?.length?{perWaferMetadata:i.map(m=>m.wafer??{}),populationLabel:`${i.length} wafer${i.length===1?"":"s"} pooled`}:void 0,s=Rt(i);return s?buildFunctionalTestSection(e,t,s,n,u,o):buildFunctionalTestSection(e,t,void 0,n,u,o)}const ae={unusual:0,notable:1,info:2};function Be(e){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:q.pill,background:ge(e),flexShrink:"0"})}function tt(e,t){let i=e.summary;if(t){const n=[" has "," have "].find(o=>i.startsWith(`${t}${o}`));n?i=i.slice(t.length+n.length):i.startsWith(`${t} `)&&(i=i.slice(t.length+1))}return i=de(i),i.length?i[0].toUpperCase()+i.slice(1):i}function nt(e){return it(e.map(t=>({label:t.variable.label,...we(t.variable)})))}function it(e){const t=ft(e);return t?l("div",{fontSize:T.body,color:Y,marginTop:x.sm,lineHeight:ne.base},t):null}function ot(e,t){const i=it(t);if(!i)return e;const n=l("div",{});return n.append(e,i),n}export function buildFindingsSection(e,t,i,n,o=!1){if(!e.length)return null;const u=e.some(d=>d.severity==="unusual"||d.severity==="notable"),s=u?e.filter(d=>d.severity!=="info").length.toString():void 0,{outer:m,content:p}=o?(()=>{const d=l("div");return{outer:d,content:d}})():oe(`Findings (${e.length})`,u,s);function r(d){return d.reduce((v,g)=>ae[g.severity]<ae[v]?g.severity:v,"info")}function a(d){const v=new Map;for(const h of d){const y=`${h.comparison.family}\0${h.comparison.left}`,S=v.get(y)??[];S.push(h),v.set(y,S)}const g=[...v.entries()].map(([h,y])=>{const S=[...y].sort((L,A)=>ae[L.severity]-ae[A.severity]);return{key:h,findings:S,worst:r(S)}});return g.sort((h,y)=>ae[h.worst]-ae[y.worst]),g}function b(d,v){const h={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[d]??d;return v.toLowerCase().startsWith(h.toLowerCase())?v:`${h}: ${v}`}const f=e.filter(d=>d.comparison.family==="spatial-pattern"),w=new Set([...f.flatMap(d=>d.relatedIds??[]),...e.flatMap(d=>d.absorbedIds??[])]),k=e.filter(d=>d.comparison.family!=="spatial-pattern"&&!w.has(d.id)),F=a(k),H=()=>[...F.flatMap(d=>d.findings),...f.flatMap(d=>e.filter(v=>d.relatedIds?.includes(v.id)))];function I(d,v=!1,g){const h=n===d.id,y=document.createElement("button");return y.type="button",y.dataset.wmapFinding=d.id,y.textContent=tt(d,g),ce(y,vt(d)),y.setAttribute("aria-current",h?"true":"false"),Object.assign(y.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${ge(d.severity)}`,background:h?$.bgActive:$.menuBg,borderRadius:q.container,padding:v?"6px 10px":"8px 10px",textAlign:"left",fontSize:v?"10px":"11px",fontWeight:h?"600":"400",color:$.text,cursor:"pointer",width:"100%",marginBottom:x.xs}),G(y,"bare"),y.addEventListener("click",()=>i(d,y)),y}const O=de(Ct(e)??"");if(O){const d=l("div",{background:$.bgActive,borderRadius:q.container,padding:`${x.md} ${x.lg}`,marginBottom:x.md,display:"flex",gap:x.md,alignItems:"flex-start"}),v=l("span",{flex:"1",fontSize:T.body,lineHeight:ne.base,color:$.text},O);d.appendChild(v);const g=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:"0",lineHeight:ne.base,whiteSpace:"nowrap"},"Detail \u25B8");g.type="button",G(g,"bare"),g.addEventListener("click",()=>{const h=Oe({title:"Findings Summary",onClose:()=>{},anchor:g}),y=l("p",{fontSize:"16px",lineHeight:ne.base,color:$.text,padding:`${x.xxl} ${x.xxxl} ${x.xxl}`,margin:"0",borderBottom:`1px solid ${$.menuBorder}`,flexShrink:"0"},O);h.contentWrap.appendChild(y);const S=l("div",{overflowY:"auto",padding:`${x.xxl} ${x.xxxl}`,flex:"1"}),L=(D,R)=>{const P=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:T.sub,fontWeight:"600",color:ie,marginTop:x.lg,marginBottom:x.xs});return P.appendChild(Be(D)),P.appendChild(l("span",{},R)),P};for(const D of f){S.appendChild(L(D.severity,D.comparison.left)),S.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:x.xxs},de(D.summary)));const R=e.filter(P=>D.relatedIds?.includes(P.id));for(const P of R)S.appendChild(l("div",{fontSize:T.body,color:Y,padding:"2px 0 2px 23px",marginBottom:x.xxs},de(P.summary)))}for(const D of F){const[R,P]=D.key.split("\0");S.appendChild(L(D.worst,b(R,P)));for(const Z of D.findings)S.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:x.xxs},tt(Z,P)))}const A=nt(H());A&&S.appendChild(A),h.contentWrap.appendChild(S),Object.assign(h.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),d.appendChild(g),p.appendChild(d)}let z=!0;for(const d of f){z||p.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),z=!1;const v=e.filter(L=>d.relatedIds?.includes(L.id)),g=v.length>0,h=l("div",{position:"relative",marginBottom:g?"2px":"4px"}),y=n===d.id,S=document.createElement("button");if(S.type="button",S.dataset.wmapFinding=d.id,Object.assign(S.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${ge(d.severity)}`,background:y?$.bgActive:$.menuBg,borderRadius:q.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:T.body,fontWeight:y?"600":"500",color:$.text,cursor:"pointer",width:"100%"}),S.textContent=de(d.summary),ce(S,d.summary),S.setAttribute("aria-current",y?"true":"false"),G(S,"bare"),S.addEventListener("click",()=>i(d,S)),h.appendChild(S),g){const L=l("div",{display:"none",paddingLeft:"12px",marginBottom:x.xs});for(const R of v)L.appendChild(I(R,!0));h.appendChild(L);let A=!1;const D=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:`${x.xxs} ${x.xs}`,lineHeight:ne.none},"\u25B8");G(D,"bare"),D.type="button",ce(D),D.setAttribute("aria-label","Show supporting findings"),D.setAttribute("aria-expanded","false"),D.addEventListener("click",R=>{R.stopPropagation(),A=!A,L.style.display=A?"block":"none",D.textContent=A?"\u25BE":"\u25B8";const P=A?"Hide supporting findings":"Show supporting findings";D.setAttribute("aria-label",P),D.setAttribute("aria-expanded",String(A))}),h.appendChild(D)}p.appendChild(h)}for(const d of F){z||p.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),z=!1;const[v,g]=d.key.split("\0"),h=l("div",{display:"flex",alignItems:"center",gap:x.sm,fontSize:T.body,fontWeight:"600",color:ie,margin:"2px 0 4px"});h.appendChild(Be(d.worst)),h.appendChild(l("span",{},b(v,g))),p.appendChild(h);for(const y of d.findings)p.appendChild(I(y,!1,g))}const C=nt(H());return C&&p.appendChild(C),m}const Kt=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],Vt=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],qt=["unusual","notable","info"],Gt={unusual:"Unusual",notable:"Notable",info:"Info"};function Ut(e,t,i){const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:x.lg,marginBottom:x.lg,paddingBottom:"10px",borderBottom:`1px solid ${$.separator}`}),o={unusual:0,notable:0,info:0};for(const r of e)o[r.severity]++;const u=qt.filter(r=>o[r]>0),s=new Set(t.severity===void 0?u:Array.isArray(t.severity)?t.severity:[t.severity]),m=l("div",{display:"flex",gap:x.xs,flexWrap:"wrap"});for(const r of u){const a=document.createElement("button");a.type="button";const b=()=>{const f=s.has(r);a.setAttribute("aria-pressed",f?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${$.menuBorder}`,borderRadius:q.pill,background:f?$.bgActive:"none",opacity:f?"1":"0.5",color:$.text,fontSize:T.body,padding:`${x.xxs} ${x.md}`,cursor:"pointer"}),a.dataset.on=f?"true":"false"};a.appendChild(Be(r)),a.appendChild(l("span",{},`${Gt[r]} ${o[r]}`)),ce(a,()=>s.has(r)?"Click to hide these findings":"Click to show these findings"),b(),G(a,"bare"),a.addEventListener("click",()=>{s.has(r)?s.delete(r):s.add(r),t.severity=s.size===u.length?void 0:[...s],i()}),m.appendChild(a)}n.appendChild(m);const p=t.kind!==void 0||t.family!==void 0;return(e.length>=Qt||p)&&(n.appendChild(Pe("Kind:",Kt,t.kind??"",r=>{t.kind=r||void 0,i()},{maxWidth:"130px"})),n.appendChild(Pe("Region:",Vt,t.family??"",r=>{t.family=r||void 0,i()},{maxWidth:"150px"}))),n}const Qt=8;function Xt(e,t){const i=l("div",{display:"flex",flexDirection:"column",gap:x.xs,padding:x.md,marginBottom:x.md,background:$.bgHover,borderRadius:q.control},void 0,t);if(i.appendChild(l("div",{fontSize:T.body,color:$.value},e.message,t)),e.detail&&i.appendChild(l("div",{fontSize:T.meta,color:Y},e.detail,t)),e.actionLabel&&e.onAction){const n=l("button",me("outlined"),e.actionLabel,t);n.type="button",n.style.alignSelf="flex-start",n.style.marginTop=x.xs,G(n),n.addEventListener("click",e.onAction),i.appendChild(n)}return i}export function buildFindingsSectionWithFilter(e,t,i,n,o,u,s){if(!e.findings.length&&!s)return null;const m=e.findings.some(k=>k.severity==="unusual"||k.severity==="notable"),p=m?e.findings.filter(k=>k.severity!=="info").length.toString():void 0,r=u?.ownerDocument??document,{outer:a,content:b}=oe(`Findings (${e.findings.length})`,m||!!s,p,{stateKey:"findings",panel:u});if(s&&b.appendChild(Xt(s,r)),!e.findings.length)return a;b.appendChild(Ut(e.findings,n,o));const f=St(e,n);if(!f.length)return b.appendChild(l("div",{color:Y,fontSize:T.body,textAlign:"center",padding:`${x.xxl} ${x.md}`},"No findings match the current filter.")),a;const w=buildFindingsSection(f,e,t,i,!0);return w&&b.appendChild(w),a}export function buildLotTestSection(...e){return be(buildLotTestSectionSteps(...e))}export function*buildLotTestSectionSteps(e,t,i,n,o,u,s,m="full"){const p=n?.length?{perWaferMetadata:n.map(a=>a.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;let r;if(n?.length&&n.every(a=>a.stats.perTestStats!==void 0)){const a=new Map;for(const b of n)for(const f of b.stats.perTestStats??[]){const w=a.get(f.testNumber);w?(w.n+=f.count,w.sum+=f.mean*f.count,w.min=Math.min(w.min,f.min),w.max=Math.max(w.max,f.max)):a.set(f.testNumber,{n:f.count,sum:f.mean*f.count,min:f.min,max:f.max})}r={perTestStats:[...a.entries()].map(([b,f])=>({testNumber:b,count:f.n,min:f.min,max:f.max,mean:f.sum/f.n}))}}if(n?.length&&n.every(a=>a.stats.testSpecYield!==void 0)){const a=new Map;for(const b of n)for(const f of b.stats.testSpecYield??[]){const w=a.get(f.testNumber);w?(w.passDies+=f.passDies,w.totalDies+=f.totalDies):a.set(f.testNumber,{passDies:f.passDies,totalDies:f.totalDies})}r={...r,testSpecYield:[...a.entries()].map(([b,f])=>({testNumber:b,totalDies:f.totalDies,yieldPercent:f.totalDies>0?f.passDies/f.totalDies*100:null}))}}return yield*buildTestSectionSteps(e,t,i,r,o,p,u,s,m)}export function createSummaryPanelEl(e,t,i=document){const n=e==="top"||e==="bottom",o=l("div",{background:zt,color:$.text,fontVariantNumeric:"tabular-nums",border:je,borderRadius:q.container,padding:x.xl,overflowY:"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:T.family,fontSize:T.sub,boxShadow:ze.panel},void 0,i);return e==="right"&&(o.style.marginRight=t),e==="left"&&(o.style.marginLeft=t),e==="bottom"&&(o.style.marginBottom=t),n?(o.style.height="180px",o.style.width="100%"):(o.style.width="300px",o.style.maxHeight="100%"),o}export function wrapWithSummaryPanel(e,t,i){const n=i==="top"||i==="bottom",o=l("div",{display:"flex",flexDirection:n?"column":"row",gap:x.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:n?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",i==="right"||i==="bottom"?(o.appendChild(e),o.appendChild(t)):(o.appendChild(t),o.appendChild(e)),o}function st(e){return l("div",{fontSize:T.heading,fontWeight:"600",color:ie,marginBottom:x.lg},e)}function Ce(e,t){const i=l("button",me("outlined"),e);return i.type="button",G(i),i.addEventListener("click",t),i}function at(...e){const t=e.filter(n=>!!n);if(!t.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",gap:x.sm,marginBottom:x.lg});for(const n of t)i.appendChild(n);return i}function rt(e,t,i,n,o,u,s,m,p,r,a){const b=e.ownerDocument,f=Oe({title:"Die list",onClose:()=>{},anchor:e,ownerDocument:b});f.contentWrap.style.padding="14px 16px";const w=Mt(t,i,{...s,title:n,onSaveText:m,waferMetadata:o,metadataFields:u,extraColumn:p,getWafer:r,ringCount:a,ownerDocument:b});w&&f.contentWrap.appendChild(w)}export function renderWaferSummaryContent(...e){be(renderWaferSummaryContentSteps(...e))}export function*renderWaferSummaryContentSteps(e,t){const i=e.scrollTop;e.innerHTML="";const{wafer:n,dies:o,yieldSummary:u,dataCoverage:s,hbinDefs:m,sbinDefs:p,testDefs:r,statsSummary:a,passBins:b=[1],ringCount:f=4,binColors:w,plotMode:k,fallbackFormat:F,onFindingClick:H,activeFindingId:I=null,findingsFilter:O,onFindingsFilterChange:z,findingsNotice:C,onSaveText:d,metadataFields:v,dieListOptions:g,metadataShownElsewhere:h}=t;e.appendChild(st("Wafer Summary"));const y=t.warnings??Ie({statsSummary:a});y.length&&e.appendChild($e(y,e.ownerDocument));const S=u&&s?Ce("Summary report",()=>{Ye(xt({wafer:n,dies:o,yield:u,dataCoverage:s,hbinDefs:m,sbinDefs:p,testDefs:r,passBins:b,ringCount:f},a),{anchor:e})}):null,L=(g?.enabled??!0)&&o.length?Ce("View die list",()=>{rt(e,o,r,`Die list \u2014 ${o.length} dies`,n.metadata,v,g,d,void 0,()=>n,f)}):null,A=at(S,L);A&&e.appendChild(A);let D=!0;const R=_=>{_&&(D||e.appendChild(Ge()),D=!1,e.appendChild(_))},P=a?.stats.isLotStack?a.stats:void 0,Z=P?.lotSize!==void 0?{lotSize:P.lotSize,aggrMethod:Nt(P.aggregationMethod)}:void 0;h||R(buildMetadataInfoSection([{metadata:n.metadata??void 0}],Z)),u&&s&&R(buildYieldSection(u,s,b)),yield,a&&H&&O&&z&&(R(buildFindingsSectionWithFilter(a,H,I,O,z,e,C)),yield),R(buildBinBreakdownSection({dies:o,hbinDefs:m,sbinDefs:p,binColors:w,hardCounts:a?.stats.hardBinCounts,softCounts:a?.stats.softBinCounts,plotMode:k,passBins:b,panel:e})),yield,R(buildRegionYieldPanelSection({diesByWafer:[o],allWafers:[n],ringCount:f,passBins:b,panel:e})),yield;const J=n.metadata?{waferMetadata:n.metadata}:void 0;R(yield*buildTestSectionSteps(o,r,F,a?.stats,d,J,[{dies:o}],e,"compact")),yield,R(buildFunctionalTestSection(o,r,a?.stats.functionalYield,d,J,e)),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}export function reportMapsFromItems(e,t,i){const n=[];return e.forEach((o,u)=>{!o?.wafer||!o.dies||n.push({...o,wafer:o.wafer,dies:o.dies,label:ve(o,u),passBins:[...Se(o,t)],ringCount:o.ringCount??i})}),n}export function renderLotSummaryContent(...e){be(renderLotSummaryContentSteps(...e))}export function*renderLotSummaryContentSteps(e,t){const i=e.scrollTop;e.innerHTML="";const{lotSummary:n,items:o,hbinDefs:u,sbinDefs:s,testDefs:m,passBins:p=[1],ringCount:r=4,binColors:a,plotMode:b,fallbackFormat:f,onFindingClick:w,activeFindingId:k=null,onWaferClick:F,findingsFilter:H,onFindingsFilterChange:I,findingsNotice:O,onSaveText:z,dieListOptions:C,findingsFor:d}=t;e.appendChild(st(`Summary \u2014 ${Bt(Me(n.perWafer.map(N=>N.summary.wafer)))}`));const v=t.warnings??Ie({lotStatsSummary:n});v.length&&e.appendChild($e(v,e.ownerDocument));const g=Ce("Summary report",()=>{Ye(yt(reportMapsFromItems(o,p,r)),{anchor:e})}),h=[],y=[],S=[],L=[],A=[],D=new WeakMap,R=new WeakMap;for(let N=0;N<o.length;N++){yield;const V=o[N];if(!V){y.push([]);continue}V.wafer&&(h.push(V.wafer),L.push(V.dies??[]),A.push(Se(V,p)));const re=V.dies??[],c=ve(V,N);for(const W of re)D.set(W,c),V.wafer&&R.set(W,V.wafer);y.push(re);for(const W of re)S.push(W)}const P=C?.enabled??!0?Ce("View die list",()=>{S.length&&rt(e,S,m,`Die list \u2014 ${S.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,Fe(o.filter(N=>!!N).map(N=>({metadata:N.wafer?.metadata}))),o.find(N=>N?.metadataFields?.length)?.metadataFields,C,z,{label:"Wafer",get:N=>D.get(N)},N=>R.get(N),r)}):null,Z=at(g,P);Z&&e.appendChild(Z);const J=o.map(N=>N?.statsSummary).filter(N=>!!N);let _=!0;const U=N=>{N&&(_||e.appendChild(Ge()),_=!1,e.appendChild(N))};U(buildLotOverviewSection(n,J)),yield,w&&H&&I&&(U(buildFindingsSectionWithFilter(n,w,k,H,I,e,O)),yield),U(buildPerWaferYieldSection(n,o,F,e,d)),yield,U(buildBinBreakdownSection({dies:S,hbinDefs:u,sbinDefs:s,plotMode:b,passBins:p,panel:e,binColors:a??kt(o.flatMap(N=>N?[{dies:N.dies??[],passBins:Se(N,p)}]:[]),{hbinDefs:u,sbinDefs:s}).colors})),yield,U(buildRegionYieldPanelSection({diesByWafer:L,allWafers:h,ringCount:r,passBins:N=>A[N],panel:e})),yield,m?.length&&(U(yield*buildLotTestSectionSteps(S,m,f,J,z,y.map(N=>({dies:N})),e,"compact")),yield,U(buildLotFunctionalSection(S,m,J,z,e))),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}
1
+ import{waferDisplayLabel as ve}from"../core/waferLabel.js";import{itemPassBins as Se,passBinsLabel as lt}from"../core/passBins.js";import{isParametricTest as dt}from"../renderer/buildWaferMap.js";import{testLabel as ct,markedTestLabel as pt,unmarkedLabel as ut,derivedFields as we,derivedKeyText as ft,derivedCsvCell as Ne,isDerivedTest as Te,DERIVED_CSV_HEADER as De}from"../renderer/testLabel.js";import{buildRingRegions as mt,buildQuadrantRegions as gt,buildRegionYieldData as ht}from"../stats/regions.js";import{computeFunctionalYield as bt}from"../stats/analyzeWaferMap.js";import{renderWaferReportHtml as xt,renderLotReportHtml as yt}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as Ct}from"../stats/findingsNarrative.js";import{formatFindingTooltip as vt}from"../stats/reportHtml.js";import{filterFindings as St}from"../stats/filterFindings.js";import{buildFacetTable as wt,prettyKey as Ee}from"../stats/facets.js";import{commonMetadata as Fe}from"../stats/facets.js";import{resolveMetadataColumns as $t}from"../stats/metadataColumns.js";import{resolveBinColors as Re,resolveBinColorsByWafer as kt}from"../renderer/binColors.js";import{NO_DATA_FILL as Lt}from"../renderer/colorMap.js";import{classifySpec as Bt,isOutOfSpec as Nt}from"../renderer/spec.js";import{describeWaferPopulation as Me,populationLabel as Tt}from"../stats/population.js";import{buildWarningsBanner as $e,collectWarnings as Ie}from"./warnings.js";export{$e as buildWarningsBanner};import{fmt as Ae,fmtAggregationMethod as Dt,plainBinTerms as de}from"../renderer/fmt.js";import{getUniqueTestNumbers as Et}from"../renderer/buildView.js";import{describeSorted as Ft,quantile as We}from"../stats/math.js";import{pooledTestStatsSteps as Rt}from"../stats/capability.js";import{sortBinsForDisplay as Mt}from"../stats/binPareto.js";import{poolFunctionalYield as It}from"../stats/testPassRate.js";import{makeLabeledSelect as Pe,makeSegmented as ke}from"./charts/chartShell.js";import{SHADOW as ze,MOTION as He,LEADING as te,TRACKING as fe,wireControlHover as G,controlStyle as me,SPACE as x,RADIUS as q,FONT as T,CLR as $,sevColor as ge,openModal as Oe,openReportModal as Ye,saveTextFile as _e,wireTooltip as ce}from"./toolbar.js";import{buildDieListSection as At}from"./dieList.js";export{csvField}from"../core/utils.js";import{csvField as he,drain as be,maxOf as Wt,medianOfSorted as Pt,minOf as zt}from"../core/utils.js";import{metadataDisplayValue as Ht}from"../core/metadata.js";const Ot=$.panelBg,je=`1px solid ${$.menuBorder}`,Yt="12px",Y=$.label,ne=$.value,Ke="10px";function l(e,t,i,n=document){const o=n.createElement(e);return t&&Object.assign(o.style,t),i!==void 0&&(o.textContent=i),o}function se(e){return l("div",{fontSize:Ke,fontWeight:"700",letterSpacing:fe,textTransform:"uppercase",color:Y,marginBottom:x.sm},e)}const Ve=new WeakMap,qe=["regionYield","testValues","functionalTests"];function xe(e){if(!e)return{collapsed:new Set(qe),regionMode:"ring",waferSort:"slot"};let t=Ve.get(e);return t||(t={collapsed:new Set(qe),regionMode:"ring",waferSort:"slot"},Ve.set(e,t)),t}function oe(e,t=!0,i,n){const o=l("div"),u=xe(n?.panel);n?.stateKey&&n.panel&&(t=!u.collapsed.has(n.stateKey));const s=document.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",gap:x.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const m=l("span",{fontSize:T.meta,color:Y,transition:`transform ${He.base}`,transform:t?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:te.none,marginRight:"1px"},"\u25B6"),p=l("span",{fontSize:Ke,fontWeight:"700",letterSpacing:fe,textTransform:"uppercase",color:Y,flex:"1"},e);if(G(s,"bare"),s.setAttribute("aria-expanded",t?"true":"false"),s.appendChild(m),s.appendChild(p),i){const b=l("span",{fontSize:T.meta,fontWeight:"700",background:$.warnBg,color:$.warnText,borderRadius:q.pill,padding:"1px 5px"},i);s.appendChild(b)}const r=l("div");r.style.display=t?"block":"none";let a=t;if(s.addEventListener("click",()=>{a=!a,r.style.display=a?"block":"none",m.style.transform=a?"rotate(90deg)":"rotate(0deg)",s.setAttribute("aria-expanded",a?"true":"false"),n?.stateKey&&n.panel&&(a?u.collapsed.delete(n.stateKey):u.collapsed.add(n.stateKey))}),n?.control){const b=l("div",{display:"flex",alignItems:"center",gap:x.sm});s.style.width="auto",s.style.flex="1",b.appendChild(s);const f=()=>{r.innerHTML="",n.render?.(r)},w=n.control(f);w&&(w.style.marginBottom="6px",w.addEventListener("click",k=>k.stopPropagation()),b.appendChild(w)),o.appendChild(b)}else o.appendChild(s);return o.appendChild(r),n?.render?.(r),{outer:o,content:r}}function Ge(){return l("div",{height:"1px",background:$.separator,margin:`${Yt} 0`,flexShrink:"0"})}function Le(e,t,i=$.barFill,n,o){const u=l("div",{marginBottom:"5px"}),s=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,color:ne,marginBottom:x.xxs}),m=l("span",{color:Y},e),p=l("span",{fontWeight:"600"},`${t.toFixed(1)}%`);s.appendChild(m),s.appendChild(p);const r=n!==void 0?n:Math.min(100,Math.max(0,t)),a=i,b=l("div",{position:"relative",height:"9px",background:$.bgActive,borderRadius:q.control,overflow:"hidden"}),f=l("div",{height:"100%",width:`${r}%`,background:a,borderRadius:q.control,transition:`width ${He.base}`});if(b.appendChild(f),o!==void 0){const w=l("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"2px",marginLeft:"-1px",background:$.value,opacity:"0.8"});b.appendChild(w)}return u.appendChild(s),u.appendChild(b),u}function Ue(){const e=l("div",{display:"flex",gap:x.sm,marginBottom:x.md});return e.finish=()=>{const t=e.lastElementChild;t&&Object.assign(t.style,{borderRight:"none",paddingRight:"0"})},e}function pe(e,t,i){const n=l("div",{padding:`${x.xxs} ${x.md} ${x.xxs} 0`,borderRight:je,textAlign:"center",flex:"1"}),o=l("div",{fontSize:T.heading,fontWeight:"700",color:ne,lineHeight:te.tight},e),u=l("div",{fontSize:T.body,color:Y,marginTop:x.xxs},t);return n.appendChild(o),n.appendChild(u),i&&n.appendChild(l("div",{fontSize:T.body,color:Y,opacity:"0.85"},i)),n}function Qe(e,t){const i=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,gap:x.md,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},e),o=l("span",{color:ne,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}function _t(e,t){const i=l("div",{display:"flex",fontSize:T.body,gap:x.sm,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},`${e}:`),o=l("span",{color:ne,fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}export function metadataEntries(e){const t=[];for(const[i,n]of Object.entries(e)){const o=Ht(n);o!==void 0&&t.push([i,o])}return t}const jt=["lot","product","testprogram","split"],ye=e=>{const t=jt.indexOf(e.toLowerCase().replace(/[^a-z]/g,""));return t===-1?Number.MAX_SAFE_INTEGER:t};export function buildFacetSummaryChips(e,t=3){if(!e.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${x.xs} ${x.lg}`}),n=[...e].sort((m,p)=>ye(m.key)-ye(p.key)),o=n.filter(m=>ye(m.key)!==Number.MAX_SAFE_INTEGER),u=n.filter(m=>ye(m.key)===Number.MAX_SAFE_INTEGER),s=m=>{const p=l("span",{whiteSpace:"nowrap"}),r=l("span",{color:Y},`${Ee(m.key)}: `);p.appendChild(r);const a=m.values.slice(0,t),b=m.values.length-a.length;let f=a.map(w=>w.value).join(", ");return b>0&&(f+=` +${b} more`),p.appendChild(document.createTextNode(f)),p};for(const m of o)i.appendChild(s(m));if(u.length){const m=l("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${x.xs} ${x.lg}`});for(const a of u)m.appendChild(s(a));const p=l("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:$.iconActive,fontSize:T.body,whiteSpace:"nowrap"});p.type="button",G(p,"bare");const r=a=>{m.style.display=a?"contents":"none",p.textContent=a?"less":`+${u.length} more`,p.setAttribute("aria-expanded",String(a))};r(!1),p.addEventListener("click",()=>r(p.getAttribute("aria-expanded")!=="true")),i.appendChild(m),i.appendChild(p)}return i}export function buildMetadataStripRow(e,t,i){const n=wt(e,i),o=buildFacetSummaryChips(n);if(!o&&!t)return null;const u=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(t){const s=l("span",{fontWeight:"500",whiteSpace:"nowrap"},t.aggrMethod?`${t.lotSize} wafers stacked \xB7 ${t.aggrMethod}`:`${t.lotSize} wafers stacked`);u.appendChild(s)}return o&&u.appendChild(o),u}const Kt={display:"flex",flexDirection:"column",gap:x.sm,background:$.menuBg,border:`1px solid ${$.menuBorder}`,borderRadius:q.container,padding:`${x.sm} ${x.lg}`,boxShadow:ze.panel,fontSize:T.body,lineHeight:te.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(e,t,i){const n=buildMetadataStripRow(e,t,i);if(!n)return null;const o=l("div",Kt);return o.appendChild(n),o}export function buildCompactMetadataRows(e){const t=metadataEntries(e);if(!t.length)return null;const i=l("div");for(const[n,o]of t)i.appendChild(_t(Ee(n),o));return i}export function buildMetadataInfoSection(e,t){const i=buildMetadataStripRow(e,t,{facetableOnly:e.length>1});if(!i)return null;const n=l("div");return n.appendChild(se("Wafer Info")),n.appendChild(i),n}export function buildYieldSection(e,t,i=[1]){const n=l("div");n.appendChild(se("Summary"));const o=Ue();if(o.appendChild(pe(String(e.totalDies),"Total dies")),e.partialDies>0&&o.appendChild(pe(String(e.partialDies),"Partial")),e.yieldPercent!==null){const u=lt([i]);o.appendChild(pe(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${u}`))}return o.finish(),n.appendChild(o),e.edgeExcludedDies>0&&n.appendChild(Qe("Edge excluded (outer zone)",String(e.edgeExcludedDies))),n}export function buildBinSection(e,t,i,n,o,u){const s=new Map;if(o)for(const[r,a]of Object.entries(o))s.set(Number(r),a);else for(const r of e){if(r.partial||r.edgeExcluded)continue;const a=i==="hard"?r.hbin:r.sbin;a!=null&&s.set(a,(s.get(a)??0)+1)}if(!s.size)return null;const m=n??Re(e,{passBins:u,...i==="hard"?{hbinDefs:t}:{sbinDefs:t}}),p=l("div");p.appendChild(se(Xe(i,[...s.values()].reduce((r,a)=>r+a,0))));for(const r of Ze(s,t,m[i],m.pass[i]))p.appendChild(r);return p}function Xe(e,t){return`${e==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${t})`}function Ze(e,t,i,n){const o=[...e.values()].reduce((m,p)=>m+p,0),u=t?new Map(t.map(m=>[m.bin,m])):null;return Mt(e.entries(),n).map(([m,p])=>{const r=u?.get(m),a=r?.name?`Bin ${m} \xB7 ${r.name}`:`Bin ${m}`,b=p/o*100,f=i.get(m)??Lt;return Le(`${a} (${p})`,b,f)})}export function buildBinBreakdownSection(e){const{dies:t,hbinDefs:i,sbinDefs:n,hardCounts:o,softCounts:u,plotMode:s,passBins:m=[1],panel:p}=e,r=e.binColors??Re(t,{passBins:m,hbinDefs:i,sbinDefs:n}),a=v=>{const g=v==="hard"?o:u,h=new Map;if(g){for(const[y,S]of Object.entries(g))h.set(Number(y),S);return h}for(const y of t){if(y.partial||y.edgeExcluded)continue;const S=v==="hard"?y.hbin:y.sbin;S!=null&&h.set(S,(h.get(S)??0)+1)}return h},b=a("hard"),f=a("soft"),w=b.size>0,k=f.size>0;if(!w&&!k)return null;const F=xe(p),H=s==="softBin"||s==="stackedSoftBins"?"soft":s==="hardBin"||s==="stackedBins"?"hard":void 0;let I=F.binMode??H??(w?"hard":"soft");I==="hard"&&!w&&(I="soft"),I==="soft"&&!k&&(I="hard");const O=I==="hard"?b:f,z=I==="hard"?i:n,C=[...O.values()].reduce((v,g)=>v+g,0),{outer:d}=oe(Xe(I,C),!0,void 0,{stateKey:"bins",panel:p,render:v=>{const g=I==="hard"?r.hard:r.soft;for(const h of Ze(O,z,g,r.pass[I]))v.appendChild(h)},control:w&&k&&p?()=>ke([["hard","Hard"],["soft","Soft"]],I,v=>{F.binMode=v;const g=buildBinBreakdownSection(e);g&&d.replaceWith(g)},p.ownerDocument,!0):void 0});return d}export function buildLotBinSection(e,t,i,n){return buildBinSection(e,t,i,n)}export function buildRegionYieldPanelSection(e){const{diesByWafer:t,allWafers:i,ringCount:n,passBins:o,panel:u}=e,s=xe(u),m=a=>ht(t,i,n,o,a==="ring"?mt:gt);if(!m("ring").length&&!m("quadrant").length)return null;const p=s.regionMode,{outer:r}=oe(p==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:u,render:a=>{const b=m(p);if(!b.length){a.appendChild(l("div",{fontSize:T.body,color:Y},"No positioned dies for this breakdown."));return}for(const{label:f,n:w,yieldPercent:k}of b)a.appendChild(Le(`${f} (N=${w})`,k))},control:u?()=>ke([["ring","Ring"],["quadrant","Quadrant"]],p,a=>{s.regionMode=a;const b=buildRegionYieldPanelSection(e);b&&r.replaceWith(b)},u.ownerDocument,!0):void 0});return r}export function buildLotOverviewSection(e,t=[]){const i=l("div"),n=Me(e.perWafer.map(s=>s.summary.wafer));i.appendChild(se(n.lotId!==void 0?"Lot Summary":"Summary"));const o=Ue();o.appendChild(pe(String(e.stats.waferCount),"Wafers"));const u=e.perWafer.map(s=>s.summary.stats.yieldPercent).filter(s=>s!==null);if(u.length){const s=u.reduce((m,p)=>m+p,0)/u.length;o.appendChild(pe(`${s.toFixed(1)}%`,"Mean per-wafer yield"))}if(o.finish(),i.appendChild(o),t.length){const s=t.reduce((p,r)=>p+r.stats.analyzedDies,0),m=t.reduce((p,r)=>p+r.stats.excludedDies,0);(s||m)&&i.appendChild(Qe("Dies analysed",m?`${s.toLocaleString()} (${m.toLocaleString()} excluded)`:s.toLocaleString()))}return i}export function buildPerWaferYieldSection(e,t,i,n,o){const u=e.perWafer.map(C=>({waferIndex:C.waferIndex,label:ve(t[C.waferIndex],C.waferIndex).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:C.summary.stats.yieldPercent})).filter(C=>C.yieldPct!==null);if(!u.length)return null;const s=zt(u.map(C=>C.yieldPct)),m=Wt(u.map(C=>C.yieldPct)),p=s===m?"":` (${s.toFixed(1)}\u2013${m.toFixed(1)}%)`,r=[...u.map(C=>C.yieldPct)].sort((C,d)=>C-d),a=Pt(r),b=We(r,.25),f=We(r,.75),w=u.length>=5?b-1.5*(f-b):-1/0,k=xe(n),F=C=>{const d=k.waferSort==="yield"?[...u].sort((v,g)=>v.yieldPct-g.yieldPct):u;for(const{waferIndex:v,label:g,yieldPct:h}of d){const S=h<w?`${g} \xB7 low outlier`:g,L=Le(S,h,void 0,void 0,a),A=o?.(v);A?.total&&O(L,A),z(L,v,g,h,A),C.appendChild(L)}},H=` \xB7 median ${a.toFixed(1)}%`,{outer:I}=oe("Wafer Yield"+p+H,!0,void 0,{stateKey:"waferYield",panel:n,render:F,control:n?C=>ke([["slot","Slot"],["yield","Yield"]],k.waferSort,d=>{k.waferSort=d,C()},n.ownerDocument,!0):void 0});return I;function O(C,d){const v=d.unusual?"unusual":d.notable?"notable":"info",g=l("span",{marginLeft:x.sm,flexShrink:"0",background:ge(v),color:"#fff",borderRadius:q.container,padding:"0 5px",fontSize:T.body,fontWeight:"600"},`${d.total}`);g.setAttribute("aria-hidden","true"),ce(g,`${d.total} finding${d.total===1?"":"s"}`+(d.unusual?`, ${d.unusual} unusual`:"")+(d.notable?`, ${d.notable} notable`:"")),C.firstElementChild?.firstElementChild?.appendChild(g)}function z(C,d,v,g,h){i&&(C.style.cursor="pointer",C.style.borderRadius="4px",C.style.padding="2px 3px",C.style.marginLeft="-3px",C.style.marginRight="-3px",C.setAttribute("role","button"),C.setAttribute("aria-label",`${v}, ${g.toFixed(1)}% yield`+(h?.total?`, ${h.total} finding${h.total===1?"":"s"}${h.unusual?`, ${h.unusual} unusual`:""}`:"")+" \u2014 open wafer"),C.tabIndex=0,C.addEventListener("mouseenter",()=>{C.style.background=$.bgHover}),C.addEventListener("mouseleave",()=>{C.style.background=""}),C.addEventListener("focus",()=>{C.style.background=$.bgHover}),C.addEventListener("blur",()=>{C.style.background=""}),C.addEventListener("click",()=>i(d)),C.addEventListener("keydown",y=>{(y.key==="Enter"||y.key===" ")&&(y.preventDefault(),i(d))}))}}function Vt(e){return Ft([...e].sort((t,i)=>t-i))}function Je(e,t){if(!e)return[];const i=e.waferMetadata??(e.perWaferMetadata?Fe(e.perWaferMetadata.map(n=>({metadata:n}))):void 0);return!i||!Object.keys(i).length?[]:$t({waferMetadata:i,waferKeys:"identity",waferPlacement:"csv",reservedLabels:t}).columns}function et(e){return e?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:e.populationLabel,get:()=>e.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(...e){return be(buildTestSectionSteps(...e))}export function*buildTestSectionSteps(e,t,i,n,o,u,s,m,p="full"){const r=e.filter(c=>!c.partial&&!c.edgeExcluded),a=new Map((n?.perTestStats??[]).map(c=>[c.testNumber,c])),b=new Map((n?.testSpecYield??[]).map(c=>[c.testNumber,c]));let f;if(t?.length?f=t.filter(dt).map(c=>({testNumber:c.testNumber,name:c.name,unit:c.unit,limitLow:c.limitLow,limitHigh:c.limitHigh,limitLowInclusive:c.limitLowInclusive,limitHighInclusive:c.limitHighInclusive,...we(c)})):f=Et(r).map(W=>({testNumber:W,name:ct(void 0,W)})),!f.length)return null;const w=f.filter(c=>r.some(W=>{const j=W.testValues?.[c.testNumber];return j!==void 0&&isFinite(j)}));if(!w.length)return null;const k=w.some(c=>c.limitLow!==void 0||c.limitHigh!==void 0),F=[],H=c=>!!c&&c.stddev!==void 0&&c.median!==void 0&&c.q1!==void 0&&c.q3!==void 0,I=c=>c.limitLow!==void 0||c.limitHigh!==void 0,O=!!(s?.length&&t?.length),C=(O||w.some(c=>!H(a.get(c.testNumber))||I(c)&&!b.has(c.testNumber)))&&t?.length?yield*Rt(s??[{dies:e}],t):void 0;for(const c of w){yield;const W=a.get(c.testNumber),j=C?.specTally.get(c.testNumber),ee=C?.stats.get(c.testNumber),K=()=>r.map(E=>E.testValues?.[c.testNumber]).filter(E=>E!==void 0&&isFinite(E));let Q;if(H(W)){const E=W;Q={testNumber:c.testNumber,min:E.min,max:E.max,mean:E.mean,count:E.count,stddev:E.stddev,median:E.median,q1:E.q1,q3:E.q3}}else if(ee)Q={testNumber:c.testNumber,...ee};else{const E=K();if(!E.length)continue;Q={testNumber:c.testNumber,...Vt(E)}}let M=null,B=0;if(I(c)){const E=b.get(c.testNumber);if(E)({yieldPercent:M,totalDies:B}=E);else if(j)B=j.n,M=B>0?(B-j.fail)/B*100:null;else{const X=K();let ue=0;for(const ie of X)Nt(Bt(ie,c))&&ue++;B=X.length,M=X.length>0?(X.length-ue)/X.length*100:null}}F.push({entry:c,stats:Q,specYieldPct:M,specN:B})}if(!F.length)return null;const d=new Map;for(const c of(O?C?.capability:void 0)??[])c.hasSpec&&d.set(c.testNumber,c.ppk);const v=d.size>0,h=new Set(F.map(c=>c.stats.count)).size===1?F[0].stats.count:null,y=l("div"),S=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:x.sm}),L=h!==null?` \xB7 N=${h.toLocaleString()}`:"",A=u?.populationLabel?`Test Values (${F.length}) \u2014 ${u.populationLabel}${L}`:`Test Values (${F.length})${L}`,D=se(A);D.style.marginBottom="0",S.appendChild(D);const R=document.createElement("button");R.type="button",R.textContent="Test values CSV",Object.assign(R.style,{...me("outlined")}),G(R),R.addEventListener("click",()=>{const c=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];v&&c.push("Ppk");const W=F.some(B=>B.specYieldPct!==null&&B.specN!==B.stats.count);k&&(c.push("Lo limit","Hi limit","Limit Yield %"),W&&c.push("Limit Yield N"));const j=F.some(B=>Te(B.entry));j&&c.push(De);const ee=[...Je(u,c),...et(u)],Q=[[...ee.map(B=>B.label),...c].map(he).join(",")],M=B=>Ae(B,void 0,"engineering");for(const{entry:B,stats:E,specYieldPct:X,specN:ue}of F){const ie=[...ee.map(le=>le.constant??""),B.name,B.unit??"",String(E.count),M(E.min),M(E.q1),M(E.median),M(E.mean),M(E.q3),M(E.max),M(E.stddev)];if(v){const le=d.get(B.testNumber);ie.push(le==null?"":le.toFixed(3))}k&&(ie.push(B.limitLow!==void 0?M(B.limitLow):"",B.limitHigh!==void 0?M(B.limitHigh):"",X!==null?X.toFixed(1):""),W&&ie.push(B.limitLow!==void 0||B.limitHigh!==void 0?String(ue):"")),j&&ie.push(Ne(B)),Q.push(ie.map(he).join(","))}_e(Q.join(`
2
+ `),"test-values.csv","text/csv",o)}),S.appendChild(R),y.appendChild(S);const P=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),Z=document.createElement("thead"),J=document.createElement("tr"),_=["Test"];h===null&&_.push("N"),p==="full"&&_.push("Min","Q1","Median"),_.push("Mean"),p==="full"&&_.push("Q3","Max","StdDev"),v&&_.push("Ppk"),p==="full"&&k&&_.push("Lo limit","Hi limit"),k&&_.push("Limit yield");for(const c of _){const W=l("th",{textAlign:c==="Test"?"left":"right",fontWeight:"600",fontSize:T.meta,letterSpacing:fe,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},c);J.appendChild(W)}Z.appendChild(J),P.appendChild(Z);const U=document.createElement("tbody");for(const{entry:c,stats:W,specYieldPct:j,specN:ee}of F){const K=B=>Ae(B,c.unit,i),Q=document.createElement("tr"),M=(B,E="right")=>{const X=l("td",{textAlign:E,padding:`${x.xs} ${x.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:$.text,whiteSpace:"nowrap"},B);Q.appendChild(X)};if(M(pt(c,c.testNumber),"left"),h===null&&M(`${W.count}`),p==="full"&&(M(K(W.min)),M(K(W.q1)),M(K(W.median))),M(K(W.mean)),p==="full"&&(M(K(W.q3)),M(K(W.max)),M(K(W.stddev))),v){const B=d.get(c.testNumber);M(B==null?"\u2014":B.toFixed(2))}p==="full"&&k&&(M(c.limitLow!==void 0?K(c.limitLow):"\u2014"),M(c.limitHigh!==void 0?K(c.limitHigh):"\u2014")),k&&M(j!==null?h!==null&&ee===h?`${j.toFixed(1)}%`:`${j.toFixed(1)}% (N=${ee})`:"\u2014"),U.appendChild(Q)}P.appendChild(U);const N=l("div",{overflowX:"auto"});N.appendChild(P);const V=ot(N,F.map(c=>({label:c.entry.name,...we(c.entry)})));if(!m)return y.appendChild(V),y;S.remove();const{outer:re}=oe(A,!0,void 0,{stateKey:"testValues",panel:m,render:c=>c.appendChild(V),control:()=>R});return re}export function buildFunctionalTestSection(e,t,i,n,o,u){const s=i??bt(e,t);if(!s?.length)return null;const p=new Set(s.map(g=>g.totalDies)).size===1?s[0].totalDies:null,r=p!==null?` \xB7 N=${p.toLocaleString()}`:"",a=l("div"),b=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:x.sm}),f=o?.populationLabel?`Functional Tests (${s.length}) \u2014 ${o.populationLabel}${r}`:`Functional Tests (${s.length})${r}`,w=se(f);w.style.marginBottom="0",b.appendChild(w);const k=document.createElement("button");k.type="button",k.textContent="Functional CSV",Object.assign(k.style,{...me("outlined")}),G(k),k.addEventListener("click",()=>{const g=["Test","N","Pass","Fail","Pass Rate %"],h=s.some(L=>Te(L));h&&g.push(De);const y=[...Je(o,g),...et(o)],S=[[...y.map(L=>L.label),...g].map(he).join(",")];for(const L of s)S.push([...y.map(A=>A.constant??""),ut(L.label),String(L.totalDies),String(L.passDies),String(L.failDies),L.passRatePercent!==null?L.passRatePercent.toFixed(1):"",...h?[Ne(L)]:[]].map(he).join(","));_e(S.join(`
3
+ `),"functional-tests.csv","text/csv",n)}),b.appendChild(k),a.appendChild(b);const F=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),H=document.createElement("thead"),I=document.createElement("tr"),O=p===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const g of O)I.appendChild(l("th",{textAlign:g==="Test"?"left":"right",fontWeight:"700",fontSize:T.body,letterSpacing:fe,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},g));H.appendChild(I),F.appendChild(H);const z=document.createElement("tbody");for(const g of s){const h=document.createElement("tr"),y=(S,L="right")=>{h.appendChild(l("td",{textAlign:L,padding:`${x.xs} ${x.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:ne,whiteSpace:"nowrap"},S))};y(g.label,"left"),p===null&&y(String(g.totalDies)),y(String(g.passDies)),y(String(g.failDies)),y(g.passRatePercent!==null?`${g.passRatePercent.toFixed(1)}%`:"\u2014"),z.appendChild(h)}F.appendChild(z);const C=l("div",{overflowX:"auto"});C.appendChild(F);const d=ot(C,s);if(!u)return a.appendChild(d),a;b.remove();const{outer:v}=oe(f,!0,void 0,{stateKey:"functionalTests",panel:u,render:g=>g.appendChild(d),control:()=>k});return v}export function buildLotFunctionalSection(e,t,i,n,o){const u=i?.length?{perWaferMetadata:i.map(m=>m.wafer??{}),populationLabel:`${i.length} wafer${i.length===1?"":"s"} pooled`}:void 0,s=It(i);return s?buildFunctionalTestSection(e,t,s,n,u,o):buildFunctionalTestSection(e,t,void 0,n,u,o)}const ae={unusual:0,notable:1,info:2};function Be(e){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:q.pill,background:ge(e),flexShrink:"0"})}function tt(e,t){let i=e.summary;if(t){const n=[" has "," have "].find(o=>i.startsWith(`${t}${o}`));n?i=i.slice(t.length+n.length):i.startsWith(`${t} `)&&(i=i.slice(t.length+1))}return i=de(i),i.length?i[0].toUpperCase()+i.slice(1):i}function nt(e){return it(e.map(t=>({label:t.variable.label,...we(t.variable)})))}function it(e){const t=ft(e);return t?l("div",{fontSize:T.body,color:Y,marginTop:x.sm,lineHeight:te.base},t):null}function ot(e,t){const i=it(t);if(!i)return e;const n=l("div",{});return n.append(e,i),n}export function buildFindingsSection(e,t,i,n,o=!1){if(!e.length)return null;const u=e.some(d=>d.severity==="unusual"||d.severity==="notable"),s=u?e.filter(d=>d.severity!=="info").length.toString():void 0,{outer:m,content:p}=o?(()=>{const d=l("div");return{outer:d,content:d}})():oe(`Findings (${e.length})`,u,s);function r(d){return d.reduce((v,g)=>ae[g.severity]<ae[v]?g.severity:v,"info")}function a(d){const v=new Map;for(const h of d){const y=`${h.comparison.family}\0${h.comparison.left}`,S=v.get(y)??[];S.push(h),v.set(y,S)}const g=[...v.entries()].map(([h,y])=>{const S=[...y].sort((L,A)=>ae[L.severity]-ae[A.severity]);return{key:h,findings:S,worst:r(S)}});return g.sort((h,y)=>ae[h.worst]-ae[y.worst]),g}function b(d,v){const h={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[d]??d;return v.toLowerCase().startsWith(h.toLowerCase())?v:`${h}: ${v}`}const f=e.filter(d=>d.comparison.family==="spatial-pattern"),w=new Set([...f.flatMap(d=>d.relatedIds??[]),...e.flatMap(d=>d.absorbedIds??[])]),k=e.filter(d=>d.comparison.family!=="spatial-pattern"&&!w.has(d.id)),F=a(k),H=()=>[...F.flatMap(d=>d.findings),...f.flatMap(d=>e.filter(v=>d.relatedIds?.includes(v.id)))];function I(d,v=!1,g){const h=n===d.id,y=document.createElement("button");return y.type="button",y.dataset.wmapFinding=d.id,y.textContent=tt(d,g),ce(y,vt(d)),y.setAttribute("aria-current",h?"true":"false"),Object.assign(y.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${ge(d.severity)}`,background:h?$.bgActive:$.menuBg,borderRadius:q.container,padding:v?"6px 10px":"8px 10px",textAlign:"left",fontSize:v?"10px":"11px",fontWeight:h?"600":"400",color:$.text,cursor:"pointer",width:"100%",marginBottom:x.xs}),G(y,"bare"),y.addEventListener("click",()=>i(d,y)),y}const O=de(Ct(e)??"");if(O){const d=l("div",{background:$.bgActive,borderRadius:q.container,padding:`${x.md} ${x.lg}`,marginBottom:x.md,display:"flex",gap:x.md,alignItems:"flex-start"}),v=l("span",{flex:"1",fontSize:T.body,lineHeight:te.base,color:$.text},O);d.appendChild(v);const g=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:"0",lineHeight:te.base,whiteSpace:"nowrap"},"Detail \u25B8");g.type="button",G(g,"bare"),g.addEventListener("click",()=>{const h=Oe({title:"Findings Summary",onClose:()=>{},anchor:g}),y=l("p",{fontSize:"16px",lineHeight:te.base,color:$.text,padding:`${x.xxl} ${x.xxxl} ${x.xxl}`,margin:"0",borderBottom:`1px solid ${$.menuBorder}`,flexShrink:"0"},O);h.contentWrap.appendChild(y);const S=l("div",{overflowY:"auto",padding:`${x.xxl} ${x.xxxl}`,flex:"1"}),L=(D,R)=>{const P=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:T.sub,fontWeight:"600",color:ne,marginTop:x.lg,marginBottom:x.xs});return P.appendChild(Be(D)),P.appendChild(l("span",{},R)),P};for(const D of f){S.appendChild(L(D.severity,D.comparison.left)),S.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:x.xxs},de(D.summary)));const R=e.filter(P=>D.relatedIds?.includes(P.id));for(const P of R)S.appendChild(l("div",{fontSize:T.body,color:Y,padding:"2px 0 2px 23px",marginBottom:x.xxs},de(P.summary)))}for(const D of F){const[R,P]=D.key.split("\0");S.appendChild(L(D.worst,b(R,P)));for(const Z of D.findings)S.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:x.xxs},tt(Z,P)))}const A=nt(H());A&&S.appendChild(A),h.contentWrap.appendChild(S),Object.assign(h.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),d.appendChild(g),p.appendChild(d)}let z=!0;for(const d of f){z||p.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),z=!1;const v=e.filter(L=>d.relatedIds?.includes(L.id)),g=v.length>0,h=l("div",{position:"relative",marginBottom:g?"2px":"4px"}),y=n===d.id,S=document.createElement("button");if(S.type="button",S.dataset.wmapFinding=d.id,Object.assign(S.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${ge(d.severity)}`,background:y?$.bgActive:$.menuBg,borderRadius:q.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:T.body,fontWeight:y?"600":"500",color:$.text,cursor:"pointer",width:"100%"}),S.textContent=de(d.summary),ce(S,d.summary),S.setAttribute("aria-current",y?"true":"false"),G(S,"bare"),S.addEventListener("click",()=>i(d,S)),h.appendChild(S),g){const L=l("div",{display:"none",paddingLeft:"12px",marginBottom:x.xs});for(const R of v)L.appendChild(I(R,!0));h.appendChild(L);let A=!1;const D=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:`${x.xxs} ${x.xs}`,lineHeight:te.none},"\u25B8");G(D,"bare"),D.type="button",ce(D),D.setAttribute("aria-label","Show supporting findings"),D.setAttribute("aria-expanded","false"),D.addEventListener("click",R=>{R.stopPropagation(),A=!A,L.style.display=A?"block":"none",D.textContent=A?"\u25BE":"\u25B8";const P=A?"Hide supporting findings":"Show supporting findings";D.setAttribute("aria-label",P),D.setAttribute("aria-expanded",String(A))}),h.appendChild(D)}p.appendChild(h)}for(const d of F){z||p.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),z=!1;const[v,g]=d.key.split("\0"),h=l("div",{display:"flex",alignItems:"center",gap:x.sm,fontSize:T.body,fontWeight:"600",color:ne,margin:"2px 0 4px"});h.appendChild(Be(d.worst)),h.appendChild(l("span",{},b(v,g))),p.appendChild(h);for(const y of d.findings)p.appendChild(I(y,!1,g))}const C=nt(H());return C&&p.appendChild(C),m}const qt=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],Gt=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],Ut=["unusual","notable","info"],Qt={unusual:"Unusual",notable:"Notable",info:"Info"};function Xt(e,t,i){const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:x.lg,marginBottom:x.lg,paddingBottom:"10px",borderBottom:`1px solid ${$.separator}`}),o={unusual:0,notable:0,info:0};for(const r of e)o[r.severity]++;const u=Ut.filter(r=>o[r]>0),s=new Set(t.severity===void 0?u:Array.isArray(t.severity)?t.severity:[t.severity]),m=l("div",{display:"flex",gap:x.xs,flexWrap:"wrap"});for(const r of u){const a=document.createElement("button");a.type="button";const b=()=>{const f=s.has(r);a.setAttribute("aria-pressed",f?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${$.menuBorder}`,borderRadius:q.pill,background:f?$.bgActive:"none",opacity:f?"1":"0.5",color:$.text,fontSize:T.body,padding:`${x.xxs} ${x.md}`,cursor:"pointer"}),a.dataset.on=f?"true":"false"};a.appendChild(Be(r)),a.appendChild(l("span",{},`${Qt[r]} ${o[r]}`)),ce(a,()=>s.has(r)?"Click to hide these findings":"Click to show these findings"),b(),G(a,"bare"),a.addEventListener("click",()=>{s.has(r)?s.delete(r):s.add(r),t.severity=s.size===u.length?void 0:[...s],i()}),m.appendChild(a)}n.appendChild(m);const p=t.kind!==void 0||t.family!==void 0;return(e.length>=Zt||p)&&(n.appendChild(Pe("Kind:",qt,t.kind??"",r=>{t.kind=r||void 0,i()},{maxWidth:"130px"})),n.appendChild(Pe("Region:",Gt,t.family??"",r=>{t.family=r||void 0,i()},{maxWidth:"150px"}))),n}const Zt=8;function Jt(e,t){const i=l("div",{display:"flex",flexDirection:"column",gap:x.xs,padding:x.md,marginBottom:x.md,background:$.bgHover,borderRadius:q.control},void 0,t);if(i.appendChild(l("div",{fontSize:T.body,color:$.value},e.message,t)),e.detail&&i.appendChild(l("div",{fontSize:T.meta,color:Y},e.detail,t)),e.actionLabel&&e.onAction){const n=l("button",me("outlined"),e.actionLabel,t);n.type="button",n.style.alignSelf="flex-start",n.style.marginTop=x.xs,G(n),n.addEventListener("click",e.onAction),i.appendChild(n)}return i}export function buildFindingsSectionWithFilter(e,t,i,n,o,u,s){if(!e.findings.length&&!s)return null;const m=e.findings.some(k=>k.severity==="unusual"||k.severity==="notable"),p=m?e.findings.filter(k=>k.severity!=="info").length.toString():void 0,r=u?.ownerDocument??document,{outer:a,content:b}=oe(`Findings (${e.findings.length})`,m||!!s,p,{stateKey:"findings",panel:u});if(s&&b.appendChild(Jt(s,r)),!e.findings.length)return a;b.appendChild(Xt(e.findings,n,o));const f=St(e,n);if(!f.length)return b.appendChild(l("div",{color:Y,fontSize:T.body,textAlign:"center",padding:`${x.xxl} ${x.md}`},"No findings match the current filter.")),a;const w=buildFindingsSection(f,e,t,i,!0);return w&&b.appendChild(w),a}export function buildLotTestSection(...e){return be(buildLotTestSectionSteps(...e))}export function*buildLotTestSectionSteps(e,t,i,n,o,u,s,m="full"){const p=n?.length?{perWaferMetadata:n.map(a=>a.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;let r;if(n?.length&&n.every(a=>a.stats.perTestStats!==void 0)){const a=new Map;for(const b of n)for(const f of b.stats.perTestStats??[]){const w=a.get(f.testNumber);w?(w.n+=f.count,w.sum+=f.mean*f.count,w.min=Math.min(w.min,f.min),w.max=Math.max(w.max,f.max)):a.set(f.testNumber,{n:f.count,sum:f.mean*f.count,min:f.min,max:f.max})}r={perTestStats:[...a.entries()].map(([b,f])=>({testNumber:b,count:f.n,min:f.min,max:f.max,mean:f.sum/f.n}))}}if(n?.length&&n.every(a=>a.stats.testSpecYield!==void 0)){const a=new Map;for(const b of n)for(const f of b.stats.testSpecYield??[]){const w=a.get(f.testNumber);w?(w.passDies+=f.passDies,w.totalDies+=f.totalDies):a.set(f.testNumber,{passDies:f.passDies,totalDies:f.totalDies})}r={...r,testSpecYield:[...a.entries()].map(([b,f])=>({testNumber:b,totalDies:f.totalDies,yieldPercent:f.totalDies>0?f.passDies/f.totalDies*100:null}))}}return yield*buildTestSectionSteps(e,t,i,r,o,p,u,s,m)}export function createSummaryPanelEl(e,t,i=document){const n=e==="top"||e==="bottom",o=l("div",{background:Ot,color:$.text,fontVariantNumeric:"tabular-nums",border:je,borderRadius:q.container,padding:x.xl,overflowY:"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:T.family,fontSize:T.sub,boxShadow:ze.panel},void 0,i);return e==="right"&&(o.style.marginRight=t),e==="left"&&(o.style.marginLeft=t),e==="bottom"&&(o.style.marginBottom=t),n?(o.style.height="180px",o.style.width="100%"):(o.style.width="300px",o.style.maxHeight="100%"),o}export function wrapWithSummaryPanel(e,t,i){const n=i==="top"||i==="bottom",o=l("div",{display:"flex",flexDirection:n?"column":"row",gap:x.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:n?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",i==="right"||i==="bottom"?(o.appendChild(e),o.appendChild(t)):(o.appendChild(t),o.appendChild(e)),o}function st(e){return l("div",{fontSize:T.heading,fontWeight:"600",color:ne,marginBottom:x.lg},e)}function Ce(e,t){const i=l("button",me("outlined"),e);return i.type="button",G(i),i.addEventListener("click",t),i}function at(...e){const t=e.filter(n=>!!n);if(!t.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",gap:x.sm,marginBottom:x.lg});for(const n of t)i.appendChild(n);return i}function rt(e,t,i,n,o,u,s,m,p,r,a){const b=e.ownerDocument,f=Oe({title:"Die list",onClose:()=>{},anchor:e,ownerDocument:b});f.contentWrap.style.padding="14px 16px";const w=At(t,i,{...s,title:n,onSaveText:m,waferMetadata:o,metadataFields:u,extraColumn:p,getWafer:r,ringCount:a,ownerDocument:b});w&&f.contentWrap.appendChild(w)}export function renderWaferSummaryContent(...e){be(renderWaferSummaryContentSteps(...e))}export function*renderWaferSummaryContentSteps(e,t){const i=e.scrollTop;e.innerHTML="";const{wafer:n,dies:o,yieldSummary:u,dataCoverage:s,hbinDefs:m,sbinDefs:p,testDefs:r,statsSummary:a,passBins:b=[1],ringCount:f=4,binColors:w,plotMode:k,fallbackFormat:F,onFindingClick:H,activeFindingId:I=null,findingsFilter:O,onFindingsFilterChange:z,findingsNotice:C,onSaveText:d,metadataFields:v,dieListOptions:g,metadataShownElsewhere:h}=t;e.appendChild(st("Wafer Summary"));const y=t.warnings??Ie({statsSummary:a});y.length&&e.appendChild($e(y,e.ownerDocument));const S=u&&s?Ce("Summary report",()=>{Ye(xt({wafer:n,dies:o,yield:u,dataCoverage:s,hbinDefs:m,sbinDefs:p,testDefs:r,passBins:b,ringCount:f},a),{anchor:e})}):null,L=(g?.enabled??!0)&&o.length?Ce("View die list",()=>{rt(e,o,r,`Die list \u2014 ${o.length} dies`,n.metadata,v,g,d,void 0,()=>n,f)}):null,A=at(S,L);A&&e.appendChild(A);let D=!0;const R=_=>{_&&(D||e.appendChild(Ge()),D=!1,e.appendChild(_))},P=a?.stats.isLotStack?a.stats:void 0,Z=P?.lotSize!==void 0?{lotSize:P.lotSize,aggrMethod:Dt(P.aggregationMethod)}:void 0;h||R(buildMetadataInfoSection([{metadata:n.metadata??void 0}],Z)),u&&s&&R(buildYieldSection(u,s,b)),yield,a&&H&&O&&z&&(R(buildFindingsSectionWithFilter(a,H,I,O,z,e,C)),yield),R(buildBinBreakdownSection({dies:o,hbinDefs:m,sbinDefs:p,binColors:w,hardCounts:a?.stats.hardBinCounts,softCounts:a?.stats.softBinCounts,plotMode:k,passBins:b,panel:e})),yield,R(buildRegionYieldPanelSection({diesByWafer:[o],allWafers:[n],ringCount:f,passBins:b,panel:e})),yield;const J=n.metadata?{waferMetadata:n.metadata}:void 0;R(yield*buildTestSectionSteps(o,r,F,a?.stats,d,J,[{dies:o}],e,"compact")),yield,R(buildFunctionalTestSection(o,r,a?.stats.functionalYield,d,J,e)),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}export function reportMapsFromItems(e,t,i){const n=[];return e.forEach((o,u)=>{!o?.wafer||!o.dies||n.push({...o,wafer:o.wafer,dies:o.dies,label:ve(o,u),passBins:[...Se(o,t)],ringCount:o.ringCount??i})}),n}export function renderLotSummaryContent(...e){be(renderLotSummaryContentSteps(...e))}export function*renderLotSummaryContentSteps(e,t){const i=e.scrollTop;e.innerHTML="";const{lotSummary:n,items:o,hbinDefs:u,sbinDefs:s,testDefs:m,passBins:p=[1],ringCount:r=4,binColors:a,plotMode:b,fallbackFormat:f,onFindingClick:w,activeFindingId:k=null,onWaferClick:F,findingsFilter:H,onFindingsFilterChange:I,findingsNotice:O,onSaveText:z,dieListOptions:C,findingsFor:d}=t;e.appendChild(st(`Summary \u2014 ${Tt(Me(n.perWafer.map(N=>N.summary.wafer)))}`));const v=t.warnings??Ie({lotStatsSummary:n});v.length&&e.appendChild($e(v,e.ownerDocument));const g=Ce("Summary report",()=>{Ye(yt(reportMapsFromItems(o,p,r)),{anchor:e})}),h=[],y=[],S=[],L=[],A=[],D=new WeakMap,R=new WeakMap;for(let N=0;N<o.length;N++){yield;const V=o[N];if(!V){y.push([]);continue}V.wafer&&(h.push(V.wafer),L.push(V.dies??[]),A.push(Se(V,p)));const re=V.dies??[],c=ve(V,N);for(const W of re)D.set(W,c),V.wafer&&R.set(W,V.wafer);y.push(re);for(const W of re)S.push(W)}const P=C?.enabled??!0?Ce("View die list",()=>{S.length&&rt(e,S,m,`Die list \u2014 ${S.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,Fe(o.filter(N=>!!N).map(N=>({metadata:N.wafer?.metadata}))),o.find(N=>N?.metadataFields?.length)?.metadataFields,C,z,{label:"Wafer",get:N=>D.get(N)},N=>R.get(N),r)}):null,Z=at(g,P);Z&&e.appendChild(Z);const J=o.map(N=>N?.statsSummary).filter(N=>!!N);let _=!0;const U=N=>{N&&(_||e.appendChild(Ge()),_=!1,e.appendChild(N))};U(buildLotOverviewSection(n,J)),yield,w&&H&&I&&(U(buildFindingsSectionWithFilter(n,w,k,H,I,e,O)),yield),U(buildPerWaferYieldSection(n,o,F,e,d)),yield,U(buildBinBreakdownSection({dies:S,hbinDefs:u,sbinDefs:s,plotMode:b,passBins:p,panel:e,binColors:a??kt(o.flatMap(N=>N?[{dies:N.dies??[],passBins:Se(N,p)}]:[]),{hbinDefs:u,sbinDefs:s}).colors})),yield,U(buildRegionYieldPanelSection({diesByWafer:L,allWafers:h,ringCount:r,passBins:N=>A[N],panel:e})),yield,m?.length&&(U(yield*buildLotTestSectionSteps(S,m,f,J,z,y.map(N=>({dies:N})),e,"compact")),yield,U(buildLotFunctionalSection(S,m,J,z,e))),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}
@@ -1 +1 @@
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";
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`,Ke=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,Ue=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:K=!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 U=e.hoverPoints;if(!U.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(),K){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,"Lo limit"],[b.limitHigh,"Hi limit"]]){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==="Hi limit"?-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?Ue: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?Ue: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,Kt=ft?ft.minX:U.length?Ne(U.map(o=>o.x)):0,Ut=ft?ft.minY:U.length?Ne(U.map(o=>o.y)):0,no=ft?ft.maxX:U.length?zt(U.map(o=>o.x)):1,so=ft?ft.maxY:U.length?zt(U.map(o=>o.y)):1,{cellW:de,cellH:ge,nCols:Dt,nRows:me}=go(no-Kt,so-Ut,Be*1.5,Pe*1.5,U.length),De=Array.from({length:Dt*me},()=>[]);for(let o=0;o<U.length;o++){const f=Math.floor((U[o].x-Kt)/de),n=Math.floor((U[o].y-Ut)/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-Kt)/de)),r=Math.min(Dt-1,Math.floor((o+n-Kt)/de)),h=Math.max(0,Math.floor((f-n-Ut)/ge)),d=Math.min(me-1,Math.floor((f+n-Ut)/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=U[s].x-n,l=U[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,K,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=K+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((K-x)/V/ot)*ot,Et=(e-K-x)/V;for(let u=Nt;u<=Et;u+=ot){const k=x+u*V;if(k<K||k>e-K)continue;g.beginPath(),g.moveTo(k,Z-Ke),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-K))/V/nt)*nt,Ht=(c-K)/V;for(let u=st;u<=Ht;u+=nt){const k=c-u*V;if(k<K||k>X-K)continue;g.beginPath(),g.moveTo(Y,k),g.lineTo(Y+Ke,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,K){const D=[],pt=K;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)/K)*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)/K)*X;j>c&&j<X-c&&D.push(Y)}return D}export{fmt,fmtColorbarAxis}from"../renderer/fmt.js";