@wafertools/wafermap 0.31.0 → 0.33.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 (100) hide show
  1. package/AGENTS.md +13 -13
  2. package/CHANGELOG.md +334 -1
  3. package/README.md +3 -3
  4. package/dist/packages/canvas-adapter/charts/chartShell.d.ts +2 -12
  5. package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
  6. package/dist/packages/canvas-adapter/dieList.js +7 -7
  7. package/dist/packages/canvas-adapter/drilldown.js +1 -1
  8. package/dist/packages/canvas-adapter/insightsTab.js +1 -1
  9. package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
  10. package/dist/packages/canvas-adapter/renderWaferMap.d.ts +47 -4
  11. package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
  12. package/dist/packages/canvas-adapter/summaryPanel.d.ts +22 -3
  13. package/dist/packages/canvas-adapter/summaryPanel.js +4 -3
  14. package/dist/packages/canvas-adapter/toCanvas.d.ts +23 -2
  15. package/dist/packages/canvas-adapter/toCanvas.js +1 -1
  16. package/dist/packages/canvas-adapter/toolbar.d.ts +54 -1
  17. package/dist/packages/canvas-adapter/toolbar.js +2 -2
  18. package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
  19. package/dist/packages/canvas-adapter/userGuideHtml.js +100 -27
  20. package/dist/packages/canvas-adapter/version.d.ts +2 -2
  21. package/dist/packages/canvas-adapter/version.js +1 -1
  22. package/dist/packages/core/aggregates.d.ts +6 -0
  23. package/dist/packages/core/aggregates.js +1 -1
  24. package/dist/packages/core/compact.d.ts +205 -0
  25. package/dist/packages/core/compact.js +3 -0
  26. package/dist/packages/core/dieTable.d.ts +137 -0
  27. package/dist/packages/core/dieTable.js +1 -0
  28. package/dist/packages/core/dies.d.ts +22 -0
  29. package/dist/packages/core/dies.js +1 -1
  30. package/dist/packages/core/passBins.d.ts +6 -0
  31. package/dist/packages/core/passBins.js +1 -1
  32. package/dist/packages/core/utils.d.ts +14 -0
  33. package/dist/packages/core/utils.js +1 -1
  34. package/dist/packages/renderer/axisTicks.d.ts +14 -0
  35. package/dist/packages/renderer/axisTicks.js +1 -1
  36. package/dist/packages/renderer/buildView.d.ts +29 -4
  37. package/dist/packages/renderer/buildView.js +1 -1
  38. package/dist/packages/renderer/buildWaferMap.d.ts +29 -11
  39. package/dist/packages/renderer/buildWaferMap.js +1 -1
  40. package/dist/packages/renderer/columnarInput.d.ts +87 -0
  41. package/dist/packages/renderer/columnarInput.js +1 -0
  42. package/dist/packages/renderer/compactView.d.ts +22 -0
  43. package/dist/packages/renderer/compactView.js +1 -0
  44. package/dist/packages/renderer/derivedTests/apply.d.ts +8 -6
  45. package/dist/packages/renderer/derivedTests/apply.js +1 -1
  46. package/dist/packages/renderer/index.d.ts +1 -0
  47. package/dist/packages/renderer/spec.d.ts +3 -7
  48. package/dist/packages/renderer/spec.js +1 -1
  49. package/dist/packages/renderer/xyIndicator.d.ts +27 -0
  50. package/dist/packages/renderer/xyIndicator.js +1 -0
  51. package/dist/packages/stats/analyzeWaferLot.d.ts +28 -0
  52. package/dist/packages/stats/analyzeWaferLot.js +1 -1
  53. package/dist/packages/stats/analyzeWaferMap.d.ts +169 -2
  54. package/dist/packages/stats/analyzeWaferMap.js +1 -1
  55. package/dist/packages/stats/binRows.d.ts +38 -0
  56. package/dist/packages/stats/binRows.js +1 -0
  57. package/dist/packages/stats/boxplot.js +1 -1
  58. package/dist/packages/stats/capability.d.ts +7 -7
  59. package/dist/packages/stats/capability.js +1 -1
  60. package/dist/packages/stats/clusterDetection.js +1 -1
  61. package/dist/packages/stats/connectedComponents.js +1 -1
  62. package/dist/packages/stats/correlation.js +1 -1
  63. package/dist/packages/stats/filterFindings.d.ts +30 -0
  64. package/dist/packages/stats/filterFindings.js +1 -1
  65. package/dist/packages/stats/findingText.d.ts +9 -0
  66. package/dist/packages/stats/findingText.js +2 -0
  67. package/dist/packages/stats/histogram.js +1 -1
  68. package/dist/packages/stats/lotDrift.d.ts +16 -0
  69. package/dist/packages/stats/lotDrift.js +1 -0
  70. package/dist/packages/stats/lotPattern.d.ts +33 -0
  71. package/dist/packages/stats/lotPattern.js +1 -0
  72. package/dist/packages/stats/math.d.ts +73 -6
  73. package/dist/packages/stats/math.js +1 -1
  74. package/dist/packages/stats/normalizeInput.js +1 -1
  75. package/dist/packages/stats/patternClassification.d.ts +34 -3
  76. package/dist/packages/stats/patternClassification.js +1 -1
  77. package/dist/packages/stats/presentation.d.ts +42 -0
  78. package/dist/packages/stats/presentation.js +1 -0
  79. package/dist/packages/stats/regions.d.ts +16 -0
  80. package/dist/packages/stats/regions.js +1 -1
  81. package/dist/packages/stats/renderSummaryReport.d.ts +15 -2
  82. package/dist/packages/stats/renderSummaryReport.js +32 -27
  83. package/dist/packages/stats/reportHtml.d.ts +54 -9
  84. package/dist/packages/stats/reportHtml.js +130 -47
  85. package/dist/packages/stats/scatter.js +1 -1
  86. package/dist/packages/stats/sweep.js +1 -1
  87. package/dist/packages/stats/synthesis.d.ts +66 -0
  88. package/dist/packages/stats/synthesis.js +2 -0
  89. package/dist/packages/stats/testPassRate.js +1 -1
  90. package/dist/packages/stats/trend.js +1 -1
  91. package/dist/packages/stats/types.d.ts +6 -1
  92. package/dist/packages/stats/yieldRows.d.ts +31 -0
  93. package/dist/packages/stats/yieldRows.js +1 -0
  94. package/dist/packages/worker/index.js +1 -1
  95. package/dist/packages/worker/wafermap.worker.d.ts +3 -0
  96. package/dist/packages/worker/wafermap.worker.js +1 -1
  97. package/llms.txt +1 -1
  98. package/package.json +1 -1
  99. package/dist/packages/stats/findingsNarrative.d.ts +0 -3
  100. package/dist/packages/stats/findingsNarrative.js +0 -1
@@ -1 +1 @@
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
+ import{buildView as Xi,buildHoverText as Ni,findTestDef as Ct,resolveTestNumber as tn,buildMapTitle as _i}from"../renderer/buildView.js";import{drawMapCanvas as ji,BIN_LEGEND_W as ti,BIN_LEGEND_W_COMPACT as Ki,BIN_LEGEND_ADAPT_COMPACT as $i,BIN_LEGEND_ADAPT_FLOATING as Gi,PATH_SHAPES as Ui}from"./toCanvas.js";import{buildWaferMap as Zi,getTestPassStatus as Qi,isParametricTest as nn}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as qi}from"../stats/analyzeWaferMap.js";import{SHADOW as Ji,LEADING as ni,wireControlHover as ii,SPACE as Y,EDGE_GUTTER as eo,RADIUS as oi,FONT as St,CLR as E,applyOverlayZ as to,getTooltip as si,hideTooltip as Mt,positionTooltip as li,createToolbarHelpers as no,buildModeMenuEl as io,openReparentedModal as oo,openUserGuideWindow as so,makePaletteBtn as lo,makeLogScaleBtn as ao,makeLegendStyleBtn as ro,makeOverlaysBtn as co,makeOrientationBtn as fo,menuLayerFor as ai,saveImageBlob as po,markMenuTrigger as nt,wireMenuA11y as ri,wireExpandToggle as uo,nextFrame as on,requestedPassFailDisplay as go,overlayMenuRows as ho,anyOverlayActive as mo,openCompactDiagnostics as yo,roomForPanel as bo,logWmapVersionOnce as vo,buildDataModeEntries as xo,metadataKeyHasData as wo,metadataModeEntry as Co}from"./toolbar.js";import{waferIdentityLabel as So}from"../core/waferLabel.js";import{metadataDisplayValue as Mo}from"../core/metadata.js";import{withExportContext as Eo}from"./exportName.js";import{createSummaryPanelEl as sn,wrapWithSummaryPanel as ln,renderWaferSummaryContentSteps as Do}from"./summaryPanel.js";import{runChunked as Bo}from"./chunked.js";import{collectWarnings as ko,buildWarningsMenuEl as Lo,severityOf as To}from"./warnings.js";import{ICONS as di}from"./icons.js";import{hasDrilldownTargets as Po,selectionPopulation as Oo,waferPopulation as Ro}from"./chartPopulation.js";import{createIdentityHeader as Io,collapsedLabel as an}from"./identityHeader.js";import{getDieKey as ye,hasPosition as ci,isPositionedDie as Ao}from"../core/dies.js";import{buildDieListSection as Wo}from"./dieList.js";import{buildMaplessSummary as Fo}from"./maplessSummary.js";import{resolveBinColors as zo,binColorWarning as Ho}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as Vo}from"../core/passBins.js";import{toggleHighlight as fi}from"../core/utils.js";import{buildCompactMap as Yo,compactLayoutOffered as Xo}from"../core/compact.js";const pi=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","compact","showAxes","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(k){const m=k.some(p=>pi.has(p)),S=k.some(p=>!pi.has(p));return m&&S?"mixed":m?"preference":"state"}export function findingBin(k){const{kind:m,bin:S}=k.variable;return m==="hardBin"||m==="softBin"?S:void 0}export function toPublicViewOptions(k){const{metadataValueOrder:m,binColors:S,lotSize:p,compactMap:L,...it}=k;return it}export function renderWaferMap(k,m,S={}){return renderWaferMapCard(k,m,S)}export function renderWaferMapCard(k,m,S={}){vo();const p=k.ownerDocument,L=p.defaultView??window,it=()=>ie.label,rn=()=>So({label:it(),wafer:K}),ue=Eo(()=>{const e=Mo(K.metadata?.lot);return{prefix:S.downloadFilename,lots:e!==void 0?[e]:[],...ie.isLotStack?{stackedWafers:h?.lotSize??!0}:{wafer:rn()}}},S.onSaveImage,S.onSaveText);function dn(){const e=h.plotMode==="softBin"||h.plotMode==="stackedSoftBins"?ee:J,{primary:t,secondary:n}=_i(h,d.fallbackFormat,e);return[t,ie.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}L.getComputedStyle(k).position==="static"&&(k.style.position="relative");const ui=k.clientHeight;S.height!=null&&(k.style.height=typeof S.height=="number"?`${S.height}px`:S.height);const Et=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!ci(e)).length,Fe=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-Et)===0&&Et>0,ze=p.createElement("div");Object.assign(ze.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),k.appendChild(ze);const ke=p.createElement("div");Object.assign(ke.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const be=S.chromeInset??eo,q=p.createElement("div");Object.assign(q.style,{display:"flex",alignItems:"stretch",gap:Y.sm,background:E.canvasBg,paddingBottom:Y.lg,paddingTop:be,paddingLeft:be,paddingRight:be,flexShrink:"0",minWidth:"0"}),ze.appendChild(q),ze.appendChild(ke);function He(){const e=[...q.children].some(t=>t.style.display!=="none");q.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),ke.appendChild(M);let ot=null;if(Et>0){let n=function(){if(t){const r=Wo(e,m.testDefs,{...S.dieList,onSaveText:ue.onSaveText,waferMetadata:K.metadata,metadataFields:xe,ownerDocument:p});if(r)return r}const o=Ct(m.testDefs,d.activeTest??0),l=nn(o)?d.logScale??o?.logScale??!1:!1;return Fo(e,m.testDefs,{plotMode:d.plotMode??"hardBin",activeTest:d.activeTest,hbinDefs:J,sbinDefs:ee,binColors:h.binColors,valueColorScheme:d.valueColorScheme,reverseValueScheme:d.reverseValueScheme,logScale:l,colorbarRangeMode:d.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const l=p.createElement("button");return l.type="button",ii(l),Object.assign(l.style,{fontSize:St.body,padding:`${Y.xxs} ${Y.sm}`,borderRadius:oi.control,flexShrink:"0",border:`1px solid ${E.menuBorder}`,background:E.menuBg,color:E.text,cursor:"pointer"}),l.textContent=t?"View chart":"View die list",l.addEventListener("click",r=>{r.stopPropagation(),t=!t,l.textContent=t?"View chart":"View die list",o()}),l};const e=m.dies.filter(o=>!ci(o));let t=!1;if(Fe){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:E.panelBg,padding:Y.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:Y.md,zIndex:"1"});const l=p.createElement("div");Object.assign(l.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:Y.md});const r=p.createElement("span");Object.assign(r.style,{fontSize:St.body,color:E.label,lineHeight:ni.base}),r.textContent="No die position data for this wafer.",l.appendChild(r);const a=p.createElement("div");Object.assign(a.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),l.appendChild(i(()=>a.replaceChildren(n()))),o.appendChild(l),o.appendChild(a),M.appendChild(o),ot=()=>{t||a.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:E.panelBg,borderTop:`1px solid ${E.menuBorder}`,fontSize:St.body,color:E.text,cursor:"pointer",padding:`${Y.xs} ${Y.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:Y.md}),ii(o,"bare");const l=p.createElement("span");l.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(l);const r=p.createElement("span");r.textContent="\u25BE",Object.assign(r.style,{fontSize:St.body,lineHeight:ni.none,color:E.label,flexShrink:"0"}),o.appendChild(r),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let a=null,c=null;uo(o,f=>{if(r.textContent=f?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(f)),f){a=p.createElement("div");const g=o.getBoundingClientRect().height||28;Object.assign(a.style,{position:"absolute",left:"0",right:"0",bottom:`${g}px`,top:"20%",zIndex:"2",background:E.panelBg,borderTop:`1px solid ${E.menuBorder}`,padding:Y.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:Y.md}),a.addEventListener("click",N=>N.stopPropagation());const v=p.createElement("div");Object.assign(v.style,{display:"flex",justifyContent:"flex-end"}),v.appendChild(i(()=>{c&&c.replaceChildren(n())})),a.appendChild(v),c=p.createElement("div"),Object.assign(c.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),c.appendChild(n()),a.appendChild(c),M.appendChild(a)}else a&&(a.remove(),a=null,c=null)}),M.appendChild(o),ot=()=>{c&&!t&&c.replaceChildren(n())}}}const{onHover:st,onClick:gi,onSelect:ae,onViewOptionsChange:hi,showTooltip:mi=!0,showToolbar:Ve=!0,showIdentity:cn=!0,summaryPanel:Ye,showHelpButton:fn=!1,userGuideExtension:yi,onExpand:pn,showExpandButton:un=!0,zIndex:bi,insights:ve,warnings:gn,viewOptions:vi={},...Le}=S,Xe=ve?.enabled??!1,xi=.4,wi=20,lt=[...m.passBins??Vo],hn=gn?.display??!0,Ci=to(bi);let ge=S.statsSummary,he=[],mn=!1,at=null,yn=!1;function Dt(){const e=ko({result:m,statsSummary:ge,extra:at?[at]:[]}),t=e.length!==he.length||e.some((n,i)=>n.code!==he[i]?.code||n.message!==he[i]?.message);he=e,(t||!mn)&&(mn=!0,gn?.onWarning?.(e))}Dt();let ie=m,K=m.wafer,re=m.dies,x=new Set;const Si={sweeps:ve?.sweeps,onSaveImage:ue.onSaveImage},Bt=()=>!Fe&&Po(te,ve?.sweeps);let bn=null,rt=null,dt=!1,vn=!1,J=m.hbinDefs,ee=m.sbinDefs,te=m.testDefs,xe=m.metadataFields,xn=m.reticles?.length?m.reticles:void 0,ct=m.reticleConfig,wn=m.dataAxisFlip,kt=m.isLotStack??!1,Lt=m.aggrMethod,Tt=m.lotSize;const Mi=Ve&&Xe;let $=null,oe=null,se=null;cn&&($=Io(an(K.metadata??{},Ne())??"",K.metadata,{lotStack:Ne(),ownerDocument:p}),M.appendChild($.metaPanel),$.metaPanel.style.visibility="visible",$.isEmpty()||(oe=Cn($.wrap),q.insertBefore(oe,q.firstChild),He()));function Cn(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${Y.sm} ${Y.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:Y.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function Ne(){return kt?{lotSize:Tt??1,aggrMethod:Lt}:void 0}function Ei(){if(!$)return;$.update(an(K.metadata??{},Ne())??"",K.metadata,Ne());const e=oe?.isConnected??!1,t=!$.isEmpty();!t&&e?(oe.remove(),oe=null):t&&!e&&(oe=Cn($.wrap),oe.style.display="",q.insertBefore(oe,q.firstChild),He())}const Di=[...J??[],...ee??[]].some(e=>e.color);let d={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,compact:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...vi},G=null,le=!1,Sn=null;function Bi(){return Xe?G?Promise.resolve(G):(Sn??=import("./insightsTab.js").then(({createInsightsTab:e})=>(G=e({getItems:()=>[{wafer:K,dies:re,hbinDefs:J,sbinDefs:ee,testDefs:te,label:it(),passBins:lt,statsSummary:ge}],getBinColors:()=>h.binColors,getRingCount:()=>ie.ringCount??4,onSaveImage:ue.onSaveImage,onSaveText:ue.onSaveText,defaultView:ve?.defaultView,sweeps:ve?.sweeps,onRemoveSweeps:ve?.onRemoveSweeps,showMetadataStrip:!1,contentInset:be,backTab:Mi?void 0:{label:"Map",onBack:()=>_e(!1)},onOpenGuide:fn&&!Ve?()=>Qt():void 0,focusTest:t=>{P({plotMode:"value",activeTest:t,highlightBin:void 0}),_e(!1)},ownerDocument:p}),Object.assign(G.el.style,{position:"absolute",inset:"0",background:E.canvasBg,overflowY:"auto",paddingTop:"0"}),G.el.style.display="none",ke.appendChild(G.el),G)),Sn):Promise.resolve(null)}let Mn=0;const Pt=["wheel","touchstart","pointerdown","keydown"];function ki(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const r of i)L.clearTimeout(r);i.length=0;for(const r of Pt)e.removeEventListener(r,o)},l=()=>n||!le?!0:(e.scrollTop=t,e.scrollTop>=t);if(!l()){for(const r of Pt)e.addEventListener(r,o,{passive:!0,once:!0});for(const r of[0,50,150,300,600])i.push(L.setTimeout(()=>{l()},r));i.push(L.setTimeout(()=>{for(const r of Pt)e.removeEventListener(r,o)},700))}}function _e(e){if(!Xe)return;const t=le;le=e,G&&!e&&t&&(Mn=G.el.scrollTop),G&&(G.el.style.display=e?"flex":"none"),M.style.visibility=e?"hidden":"",H&&(H.style.display=e||Fe?"none":"flex"),I&&(I.style.display=e?"none":"flex"),se&&(se.style.display=Ee?"none":"flex"),ce&&(ce.style.display="flex"),oe&&(oe.style.display=""),He(),$&&e&&$.collapse(),gt(),X&&(X.innerHTML=e?di.wafer:di.analysis,X.ariaLabel=e?"Back to wafer view":"Insights"),e&&Bi().then(n=>{!n||!le||(n.el.style.display="flex",n.render(),ki(n.el,Mn))})}Xe&&ve?.defaultOpen&&queueMicrotask(()=>_e(!0));let h,je,_=null,T=null,Ot=[],Rt;function En(e){Rt!==e&&(Rt=e,C())}let we=null,It=Le.legendOffset??{x:0,y:0},Ke=!1,Te=!1,$e={x:0,y:0},At={x:0,y:0},Ce=!1,Pe=!1,j="select",Oe={x:0,y:0},ft={x:0,y:0},W={x:0,y:0},F={x:0,y:0},Ge=!1,Re=!1;function Wt(){const e=d,t=re.filter(Ao);h=Xi(K,t,{compact:d.compact?d.compactMap??Yo(t):void 0,plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??zo(re,{passBins:lt,binColorScheme:e.binColorScheme,hbinDefs:J,sbinDefs:ee,useDefinedBinColors:e.useDefinedBinColors}),passBins:lt,showDieLabels:e.showDieLabels,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:xn,ringCount:ie.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:te,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:kt,aggregationMethod:Lt??e.aggregationMethod,lotSize:Tt??e.lotSize,dataAxisFlip:wn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:J,sbinDefs:ee,metadataFields:xe}),je=void 0;const n=e.binColors?null:Ho(h.binColors,h.plotMode);n?.message!==at?.message&&(at=n,Dt(),yn&&Ht())}Wt();function Dn(){return d.showAxes??Le.showAxes??T!==null}function Li(){return Xo(re,[ct])}let U=null,Se=null,Ie=null,Bn=S.findingsNotice,Ti={},O=null,de=null;function Pi(e){const{kind:t,index:n}=e.variable;P(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:{plotMode:t==="softBin"?"softBin":"hardBin",highlightBin:findingBin(e)});const i=e.highlight;(i.kind==="bin"||i.kind==="region"||i.kind==="dies")&&Tn(i.dieKeys)}const Ue=new Map,Ft=new WeakSet;function zt(e){if(Ue.get(e)?.cancel(),Ue.delete(e),e.style.display==="none"){Ft.add(e);return}Ft.delete(e);const t=Bo(Do(e,{wafer:K,dies:re,yieldSummary:ie.yield,dataCoverage:ie.dataCoverage,hbinDefs:J,sbinDefs:ee,testDefs:te,statsSummary:ge,warnings:hn?he:[],passBins:lt,ringCount:ie.ringCount??4,binColors:h.binColors,plotMode:d.plotMode??"hardBin",metadataShownElsewhere:cn,fallbackFormat:d.fallbackFormat,activeFindingId:Ie,findingsFilter:Ti,findingsNotice:Bn,onFindingsFilterChange:me,onSaveText:ue.onSaveText,metadataFields:xe,dieListOptions:S.dieList,onFindingClick:(n,i)=>{Ie===n.id?(Ie=null,Tn([]),P({highlightBin:void 0})):(Ie=n.id,Pi(n)),me()}}));t.done||Ue.set(e,t)}function me(){U&&zt(U)}function Ze(){O&&zt(O)}if(Ye?.placement){const e=Ye.placement;U=sn(e,be,p);const t=M.parentElement,n=M.nextSibling;Se=ln(M,U,e),t?.insertBefore(Se,n),me()}else if(ge){const e=Ye?.defaultOpen??!Ve;O=sn("right",be,p),O.style.display=e?"block":"none";const t=M.parentElement,n=M.nextSibling;de=ln(M,O,"right"),t?.insertBefore(de,n),Ze()}const z=mi?si(p):null;let ce=null,R=null,H=null,I=null,pt=null,Z=null,kn=null,X=null,fe=null,ut=null;yn=!0;function Ht(){if(!fe||!ut)return;const e=he.length,t=e>0;if(fe.style.display=t?"flex":"none",ut.style.display=t?"":"none",!t)return;const n=To(he[0]),i=`${e} data ${e===1?"warning":"warnings"}`;fe.style.color=n==="error"?E.errText:E.warnText,fe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Vt=null,Ln=null,Yt=null,Xt=null,Nt=null,_t=null;function Me(e="selection"){Ie!==null&&(Ie=null,e==="selection"?P({highlightBin:void 0}):(x=new Set,ae?.([])),me())}function Tn(e){x=new Set(e??[]),ae&&ae(Qe()),C()}function gt(){if(!Z)return;const e=!!(U??O);Z.style.display=ge&&e&&!le?"flex":"none";const t=U??O,n=t?t.style.display!=="none":!1;ge?.hasNotableFindings&&!n?Z.style.color=E.findingIndicator:Z.dataset.active||(Z.style.color=E.icon)}let Pn=null;function On(e){const t=U??O;if(!t)return;const n=t.style.display!=="none",i=M.getBoundingClientRect().width;if(t.style.display=e?"block":"none",e!==n){const o=i-M.getBoundingClientRect().width;(S.onSummaryPanelChange??ht)?.(e,e?o:0)}e&&Ft.has(t)&&zt(t),Z&&Pn?.(Z,e),gt()}if(Ve){let g=function(y){j=y,i(N,y==="zoom"),i(w,y==="pan"),pt&&i(pt,y==="select"),s.style.cursor=y==="pan"?"grab":"crosshair"};ce=p.createElement("div"),ce.dataset.wmapToolbar="single",Object.assign(ce.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:E.menuBg,border:`1px solid ${E.menuBorder}`,borderRadius:oi.control,boxShadow:Ji.panel,pointerEvents:"auto"});const e=si(p),t=no(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:l,makeMenuSection:r,closeOpenMenu:a,getOpenMenu:c,setOpenMenu:f}=t;Pn=i,Vt=a,Ln=c,p.addEventListener("click",a,!0),H=p.createElement("div"),Object.assign(H.style,{display:Fe?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ce.appendChild(H);const v=n("download","Download PNG",Ai);H.appendChild(v),H.appendChild(o());const N=n("zoomMode","Zoom (drag to zoom region)",()=>g("zoom")),ne=n("zoomIn","Zoom in",()=>We(s.clientWidth/2,s.clientHeight/2,1.2)),b=n("zoomOut","Zoom out",()=>We(s.clientWidth/2,s.clientHeight/2,1/1.2)),D=n("reset","Reset zoom (double-click)",()=>bt());H.appendChild(N),H.appendChild(ne),H.appendChild(b),H.appendChild(D),H.appendChild(o());const w=n("pan","Pan (drag to move)",()=>g("pan"));H.appendChild(w),pt=n("boxSelect","Select (drag to select dies)",()=>g("select")),H.appendChild(pt);{const y=n("drilldown","Chart this wafer",()=>{const V=y.getBoundingClientRect();Xn({x:V.left,y:V.bottom+4},y)});y.setAttribute("aria-haspopup","menu"),rt=y,Yn(),H.appendChild(y)}g(j);{let y=function(u){return u.plotMode!==(d.plotMode??"hardBin")?!1:u.plotMode==="value"?(d.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?d.activeMetadataKey===u.activeMetadataKey:!0},V=function(u,B){u.activeTest!==void 0?P({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?P({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):P({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),B.remove(),f(null),nt(A,!1)};R=p.createElement("div"),Object.assign(R.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ce.appendChild(R),I=p.createElement("div"),Object.assign(I.style,{display:"flex",alignItems:"center",gap:"0"}),R.appendChild(I),I.appendChild(o());const pe=()=>{const u=c();u&&(u.remove(),f(null)),nt(A,!1)},A=n("mode","Plot mode",()=>{if(c()){pe();return}const u=re,B=h.testDefs,{testEntries:wt,binEntries:De,stackedEntries:et}=xo(u,B,{includeStacked:h.isLotStack}),en=(xe??[]).filter(Be=>wo(u,Be.key)).map(Co),tt=io(A.getBoundingClientRect(),wt,De,et,y,V,{makeMenuRow:l,makeMenuSection:r},d.plotMode??"hardBin",A.ownerDocument.defaultView??window,en);ai(A).appendChild(tt),f(tt),nt(A,!0),ri(tt,A,pe)});nt(A,!1);const{btn:vt,sync:Je}=lo(t,()=>({...d,plotMode:d.plotMode??"hardBin"}),()=>Di,P);Xt=Je,Xt();const qt=co(t,()=>{const u=!!h.hasReticle,B=(d.plotMode??"hardBin")==="value",{testNumber:wt}=tn(d.activeTest??0,h.testDefs),De=Ct(h.testDefs,wt),et=B&&De!==void 0&&!nn(De),en=B&&!et&&(De?.limitLow!==void 0||De?.limitHigh!==void 0),tt=B&&!et&&h.dies.some(Be=>Qi(Be,wt,De)!==void 0);return ho({...d,showAxes:Dn()},u,{functionalActive:et,hasLimits:en,hasRecorded:tt,binMode:(d.plotMode??"hardBin")==="hardBin"||(d.plotMode??"hardBin")==="softBin"},Be=>P(Be),{on:!!d.compact,offered:Li(),onChange:Be=>P({compact:Be}),onDiagnostics:()=>yo(re,[ct],{anchor:s,onSaveText:ue.onSaveText})})},()=>mo(d)),{btn:Jt,sync:Fi}=ro(t,()=>d,u=>P({legendPosition:u}));Yt=Fi,Yt();const ei=()=>{const{testNumber:u}=tn(d.activeTest??0,te),B=Ct(te,u);return B!==void 0&&!nn(B)},{btn:zi,sync:Hi}=ao(t,()=>({...d,functionalActive:ei()}),u=>P(u));Nt=Hi,Nt();const Vi=()=>{const{testNumber:u}=tn(d.activeTest??0,te),B=Ct(te,u);return B!==void 0&&(B.limitLow!==void 0||B.limitHigh!==void 0)},xt=n("specRange","Colorbar range: test limits",()=>{const u=d.colorbarRangeMode==="data"?"spec":"data";P({colorbarRangeMode:u})});_t=()=>{const u=d.plotMode==="value"&&Vi()&&go(d)==="off"&&!ei();xt.style.display=u?"":"none";const B=(d.colorbarRangeMode??"spec")==="spec";i(xt,B),xt.ariaLabel=B?"Colorbar range: test limits (click for data range)":"Colorbar range: data range (click for test limits)"},_t();const Yi=fo(t,()=>d,u=>P(u));I.appendChild(A),I.appendChild(vt),I.appendChild(zi),I.appendChild(xt),Fe||(I.appendChild(o()),I.appendChild(qt),I.appendChild(o()),I.appendChild(Jt),I.appendChild(o()),I.appendChild(Yi)),ge&&(Z=n("findings","Summary panel",()=>{const u=U??O;u&&On(u.style.display==="none")}),R.appendChild(o()),R.appendChild(Z),O?.style.display!=="none"&&i(Z,!0),gt()),hn&&(ut=o(),fe=n("warning","Data warnings",()=>{const u=c();if(a(new MouseEvent("click")),u)return;const B=Lo(fe.getBoundingClientRect(),he,L);ai(ke).appendChild(B),f(B),ri(B,fe,()=>a(new MouseEvent("click")))}),nt(fe,!1),R.appendChild(ut),R.appendChild(fe),Ht()),Xe&&(R.appendChild(o()),X=n("analysis","Insights",()=>{_e(!le),i(X,le)}),X.dataset.wmapInsightsBtn="1",R.appendChild(X)),un&&(R.appendChild(o()),se=n("expand","Expand (E)",pn??Rn),R.appendChild(se)),fn&&(R.appendChild(o()),kn=n("help","User guide",()=>Qt()),R.appendChild(kn))}q.appendChild(ce),He()}let Ee=null,ht=null;function Rn(){Ee&&(Ee.close(),Ee=null);const e=ke;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=an(K.metadata??{},Ne()),n=q.childElementCount>0?[q,e]:[e],i=oo(n,{ownerDocument:p,boxSize:le?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{Ee=null,ht=null,se&&(se.style.display="flex"),le||s.focus({preventScroll:!0})}});if(!i)return;i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),Ee=i,ht=bo(i);const o=U??O,l=Se??de;if(o&&l&&o.style.display!=="none"){const r=parseFloat(p.defaultView?.getComputedStyle(l).columnGap??"")||0,a=o.getBoundingClientRect().width+r;a>0&&ht(!0,a)}se&&(se.style.display="none")}function In(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&d.binColors!==void 0&&(e={...e,binColors:void 0});const t=d.plotMode;d={...d,...e},("compact"in e||"compactMap"in e)&&(_=null,T=null),e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(l=>l==="legendPosition"||l==="showLegend"||l==="markFailingDies"||l==="showAxes")||Wt(),Yt?.(),Xt?.(),Nt?.(),_t?.(),C();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(l=>l in e);(o||i)&&(me(),Ze()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&ot?.()}function P(e){In(e);const t=Object.keys(e);hi?.(d,t,classifyChanged(t))}let jt=!1;const Kt=S.drawWhenVisible&&L.IntersectionObserver?new L.IntersectionObserver(e=>{Ae=e[e.length-1].isIntersecting,Ae&&mt&&C()},{rootMargin:"25%"}):null;let Ae=Kt===null,mt=!1;Kt?.observe(s);function $t(){jt||(jt=!0,on(()=>{jt=!1,C()},L))}function C(){if(!Ae){mt=!0;return}mt=!1;const e=T??void 0,t=h.dies[0],n=t?{x:t.width,y:t.height}:Le.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!(J?.length||ee?.length||h.dies.some(v=>v.hbin!=null||v.sbin!=null)),l=d.legendPosition??"default",r=d.showLegend??!0,a=l==="default"||l==="compact",c=(Le.colorbarWidth??16)+28,f=o&&a?l!=="default"?Math.max(ti,c):i<Gi?0:i<$i?Math.max(Ki,c):Math.max(ti,c):void 0,g=ji(s,h,{...Le,minRightReserve:r?f:0,showColorbar:r&&(Le.showColorbar??!0),markFailingDies:d.markFailingDies??!1,legendPosition:l,legendOffset:It,diePitchMm:n,fallbackFormat:d.fallbackFormat,showAxes:Dn(),viewport:e,activeBin:d.plotMode==="metadata"?d.highlightMetadataValue:d.highlightBin,hoverBin:Rt,afterDies:x.size>0?Oi:void 0,hbinDefs:J,sbinDefs:ee,metadataFields:xe});Ot=g.binLegendRows,we=g.legendBox??null,T===null&&(_=g.viewport),Pe&&Ii(),Yn()}function Oi(e,t,n){const i=h.hoverPoints,o=h.rectangles[0],l=o?o.width/2*t.ppm:t.ppm*.5,r=o?o.height/2*t.ppm:t.ppm*.5,a=new Set;x.size>0&&(je??=new Map(h.dies.map((b,D)=>[ye(b),D])));for(const b of x){const D=je.get(b);D!==void 0&&a.add(D)}if(!a.size)return;e.save(),e.setLineDash([]),e.fillStyle=n.background,e.globalAlpha=.7;let c=0;e.beginPath();for(let b=0;b<i.length;b++)a.has(b)||(e.rect(t.originX+i[b].x*t.ppm-l,t.originY-i[b].y*t.ppm-r,l*2,r*2),++c===Ui&&(e.fill(),e.beginPath(),c=0));c&&e.fill(),e.globalAlpha=1;const{cw:f,ch:g}=Ri(t,l,r),v=new Map,N=b=>Math.round(b*100),ne=(b,D,w,y)=>{const V=`${N(b)},${N(D)},${N(w)},${N(y)}`;v.has(V)?v.delete(V):v.set(V,[b,D,w,y])};for(const b of a){const D=t.originX+i[b].x*t.ppm,w=t.originY-i[b].y*t.ppm,y=D-f,V=D+f,pe=w-g,A=w+g;ne(y,pe,V,pe),ne(y,A,V,A),ne(y,pe,y,A),ne(V,pe,V,A)}e.strokeStyle=n.text,e.lineWidth=2,e.lineCap="square",e.beginPath();for(const[b,D,w,y]of v.values())e.moveTo(b,D),e.lineTo(w,y);e.stroke(),e.restore()}function Ri(e,t,n){const i=h.hoverPoints,o=h.dies;let l=0,r=0;for(let a=0;a<o.length&&(!l||!r);a++){const c=o[a];if(!(c.x==null||c.y==null))for(const f of[je.get(`${c.x+1},${c.y}`),je.get(`${c.x},${c.y+1}`)]){if(f===void 0)continue;const g=Math.abs(i[f].x-i[a].x)*e.ppm,v=Math.abs(i[f].y-i[a].y)*e.ppm;g>v?l||=g/2:r||=v/2}}return{cw:l||t,ch:r||n}}function Ii(){const e=s.getContext("2d"),t=Math.min(W.x,F.x),n=Math.min(W.y,F.y),i=Math.abs(F.x-W.x),o=Math.abs(F.y-W.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 An(){if(!mt)return;const e=Ae;Ae=!0,C(),Ae=e}function Ai(){An(),s.toBlob(e=>{e&&po(e,dn(),ue.onSaveImage)})}function Wn(e){return _?Math.max(_.ppm*xi,Math.min(_.ppm*wi,e)):e}function We(e,t,n){const i=T??_;if(!i)return;const o=Wn(i.ppm*n),l=o/i.ppm,r=e-(e-i.originX)*l,a=t-(t-i.originY)*l,c=(_?.snapDist??1)/(o/(_?.ppm??o));T={originX:r,originY:a,ppm:o,snapDist:c},C()}function Q(){return T??_}function Fn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;We(e.clientX-t.left,e.clientY-t.top,n)}else if(T!==null){e.preventDefault();const t=Q(),n=T.snapDist;T={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},C()}}function Gt(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function zn(e){if(dt=!1,e.button!==0||!Q())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(we&&d.legendPosition==="floating"&&Gt(n,i,we)){Te=!0,$e={x:n,y:i},At={...It};return}if(Ge&&j!=="pan"){Re=!0,Ce=!0,Oe={x:n,y:i},ft={x:Q().originX,y:Q().originY},s.style.cursor="grabbing";return}if(j==="zoom"||j==="select"){Pe=!0,W=F={x:n,y:i};return}Ce=!0,Oe={x:n,y:i},ft={x:Q().originX,y:Q().originY},s.style.cursor="grabbing"}function Hn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Pe){F={x:n,y:i},$t();return}if(Te){const g=n-$e.x,v=i-$e.y;g*g+v*v>16&&(Te=!1,Ke=!0,s.style.cursor="grabbing")}if(Ke){It={x:At.x+(n-$e.x),y:At.y+(i-$e.y)},$t();return}if(Ce){const g=Q(),v=T?.snapDist??_?.snapDist??1;T={originX:ft.x+(n-Oe.x),originY:ft.y+(i-Oe.y),ppm:g.ppm,snapDist:v},$t();return}const o=Q();if(!o)return;const l=(n-o.originX)/o.ppm,r=(o.originY-i)/o.ppm,c=Zt(l,r,o.snapDist)?.die??null,f=Ot.find(g=>n>=g.x&&n<g.x+g.w&&i>=g.y&&i<g.y+g.h);if(En(f?f.bin:void 0),f){s.style.cursor="pointer",z&&(z.textContent=f.label??`Bin ${f.bin}`,z.style.display="block",li(z,s,e.clientX,e.clientY,{followPointer:!0})),st?.(null,e);return}j==="pan"&&(s.style.cursor=c?"crosshair":"grab"),z&&(c?(z.innerHTML=Ni(c,h.plotMode,{testDefs:te,hbinDefs:J,sbinDefs:ee,fallbackFormat:d.fallbackFormat,aggrMethod:h.aggrMethod,lotSize:h.lotSize,metadataFields:xe,activeTest:h.activeTest,reticleConfig:ct}),z.style.display="block",li(z,s,e.clientX,e.clientY,{followPointer:!0})):z.style.display="none"),st?.(c,e)}function Vn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(z&&(n<0||i<0||n>t.width||i>t.height)&&(z.style.display="none"),Pe){Pe=!1,F={x:n,y:i};const a=n-W.x,c=i-W.y,f=Q();if(j==="zoom"){if(a*a+c*c<25)We(n,i,2);else if(f){const g=Math.min(W.x,F.x),v=Math.max(W.x,F.x),N=Math.min(W.y,F.y),ne=Math.max(W.y,F.y),b=v-g,D=ne-N;if(b>4&&D>4){const w=s.clientWidth,y=s.clientHeight,V=w/b,pe=y/D,A=Math.min(V,pe),vt=Wn(f.ppm*A),Je=vt/f.ppm,qt=(g+v)/2,Jt=(N+ne)/2;T={originX:w/2-(qt-f.originX)*Je,originY:y/2-(Jt-f.originY)*Je,ppm:vt,snapDist:f.snapDist/Je}}}C(),s.style.cursor="crosshair";return}if(a*a+c*c<25)Ut(n,i,o,e);else if(f){const g=(Math.min(W.x,F.x)-f.originX)/f.ppm,v=(Math.max(W.x,F.x)-f.originX)/f.ppm,N=(f.originY-Math.max(W.y,F.y))/f.ppm,ne=(f.originY-Math.min(W.y,F.y))/f.ppm,b=h.hoverPoints,D=[];for(let w=0;w<b.length;w++)if(b[w].x>=g&&b[w].x<=v&&b[w].y>=N&&b[w].y<=ne){const y=h.dies[w];y&&D.push(y)}if(o)for(const w of D){const y=ye(w);x.has(y)?x.delete(y):x.add(y)}else x=new Set(D.map(w=>ye(w)));Me(),ae?.(Qe())}C(),s.style.cursor="crosshair";return}if(Te){Te=!1,Ut(n,i,o,e);return}if(Ke){Ke=!1,s.style.cursor="grab";return}if(!Ce)return;if(Ce=!1,Re){Re=!1,s.style.cursor=Ge||j==="pan"?"grab":"crosshair";return}s.style.cursor=j==="pan"?"grab":"crosshair";const l=n-Oe.x,r=i-Oe.y;l*l+r*r<25&&Ut(n,i,o,e)}function Ut(e,t,n,i){for(const a of Ot)if(e>=a.x&&e<a.x+a.w&&t>=a.y&&t<a.y+a.h){Me("legend"),typeof a.bin=="number"?P({highlightBin:fi(d.highlightBin,a.bin,n)}):P({highlightMetadataValue:fi(d.highlightMetadataValue,a.bin,n)});return}if(we&&Gt(e,t,we))return;const o=Q();if(!o)return;const r=Zt((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(r){gi?.(r,i);const a=ye(r);n?x.has(a)?x.delete(a):x.add(a):x.size===1&&x.has(a)?x=new Set:x=new Set([a]),Me(),ae?.(Qe()),C()}else n||(x=new Set,Me(),ae?.([]),C())}function Qe(){const e=[],t=h.hoverPoints;for(let n=0;n<t.length;n++){const i=h.dies[n];i&&x.has(ye(i))&&e.push(i)}return e}function Yn(){rt&&(rt.style.display=Bt()?"flex":"none",rt.ariaLabel=x.size>0?"Chart the selected dies (or right-click)":"Chart this wafer (or right-click)")}function Wi(){const e={waferLabel:rn(),testDefs:te,isLotStack:ie.isLotStack,activeTest:d.plotMode==="value"?d.activeTest:void 0};return x.size>0?Oo(Qe(),e):Ro(re,e)}function Xn(e,t){if(!Bt())return;const n=Wi();import("./drilldown.js").then(({openDrilldownMenu:i})=>{vn||(bn=i(e,t,n,Si))})}function Nn(e){e.stopPropagation();const t=dt;if(dt=!1,!Bt()||le)return;const n=s.getBoundingClientRect();if(!t){const o=e.clientX-n.left,l=e.clientY-n.top;if(we&&Gt(o,l,we))return;const r=Q(),a=r?Zt((o-r.originX)/r.ppm,(r.originY-l)/r.ppm,r.snapDist)?.die:void 0;a&&!x.has(ye(a))&&(x=new Set([ye(a)]),Me(),ae?.(Qe()),C())}e.preventDefault();const i=t?{x:n.left+n.width/2,y:n.top+n.height/2}:{x:e.clientX,y:e.clientY};Xn(i,s)}function _n(){En(void 0),z&&Mt(p),st?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair"}function jn(){Ce=!1,Re=!1,Pe=!1,Te=!1,Ke=!1,z&&Mt(p),st?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair",C()}function Zt(e,t,n){const i=h.hoverPoints,o=h.rectangles;for(let c=0;c<o.length;c++){const f=o[c];if(Math.abs(e-f.x)<=f.width/2&&Math.abs(t-f.y)<=f.height/2){const g=h.dies[c];return g?{die:g,index:c}:null}}let l=null,r=-1,a=n*n;for(let c=0;c<i.length;c++){const f=i[c].x-e,g=i[c].y-t,v=f*f+g*g;v<a&&(a=v,l=h.dies[c]??null,r=c)}return l?{die:l,index:r}:null}const Kn=new L.ResizeObserver(()=>{_=null,T=null,C()});Kn.observe(s),S.height==null&&ui<=0&&on(()=>on(()=>{k.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 qe=L.matchMedia(`(resolution: ${L.devicePixelRatio}dppx)`);const yt=()=>{qe.removeEventListener("change",yt),qe=L.matchMedia(`(resolution: ${L.devicePixelRatio}dppx)`),qe.addEventListener("change",yt),C()};qe.addEventListener("change",yt);const $n=L.matchMedia("(prefers-color-scheme: dark)"),Gn=()=>C();$n.addEventListener("change",Gn);const Un=()=>{z&&Mt(p)};L.addEventListener("blur",Un);function Zn(e){if((e.key==="ContextMenu"||e.shiftKey&&e.key==="F10")&&(dt=!0),e.key==="Escape"&&x.size>0&&(x=new Set,Me(),ae?.([]),C()),(e.key==="e"||e.key==="E")&&un&&(e.stopPropagation(),(pn??Rn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),We(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),We(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),bt())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=Q();if(n){const i=T?.snapDist??_?.snapDist??1;let o=0,l=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(l=20,e.preventDefault()),e.key==="ArrowDown"&&(l=-20,e.preventDefault()),(o||l)&&(T={originX:n.originX+o,originY:n.originY+l,ppm:n.ppm,snapDist:i},C())}e.key===" "&&!Ge&&(e.preventDefault(),Ge=!0,j!=="pan"&&(s.style.cursor="grab"))}}function Qn(e){e.key===" "&&(Ge=!1,Re&&(Ce=!1,Re=!1),s.style.cursor=j==="pan"?"grab":"crosshair")}s.style.cursor="crosshair",s.setAttribute("tabindex","0"),s.addEventListener("wheel",Fn,{passive:!1}),s.addEventListener("pointerdown",zn),s.addEventListener("pointermove",Hn),s.addEventListener("pointerup",Vn),s.addEventListener("pointerleave",_n),s.addEventListener("pointercancel",jn);const qn=()=>bt();s.addEventListener("dblclick",qn),s.addEventListener("keydown",Zn),s.addEventListener("keyup",Qn),s.addEventListener("contextmenu",Nn);const Jn=e=>{e.stopPropagation()};s.addEventListener("click",Jn),s.clientWidth,C(),ot?.();function bt(){_=null,T=null,C()}function Qt(){import("./userGuideHtml.js").then(e=>so({buildWaferMap:Zi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:qi},e.USER_GUIDE_HTML,yi,k))}return He(),{setResult(e){ie=e,K=e.wafer,re=e.dies,J=e.hbinDefs,ee=e.sbinDefs,te=e.testDefs,xe=e.metadataFields,xn=e.reticles?.length?e.reticles:void 0,ct=e.reticleConfig,wn=e.dataAxisFlip,kt=e.isLotStack,Lt=e.aggrMethod,Tt=e.lotSize,Ei(),Wt(),C(),U&&me()},setOptions(e){In(e)},getOptions(){return{...d}},resetZoom:bt,setSelection(e){x=new Set(e.map(t=>ye(t))),C()},clearSelection(){x=new Set,Me(),ae?.([]),C()},setFindingsNotice(e){Bn=e,U?me():O&&Ze()},setStatsSummary(e){if(ge=e,Dt(),Ht(),U)me();else if(O)Ze();else if(e&&!Ye?.placement){const t=Ye?.defaultOpen??!Ve;O=sn("right",be,p),O.style.display=t?"block":"none";const n=M.parentElement,i=M.nextSibling;de=ln(M,O,"right"),n?.insertBefore(de,i),Ze()}gt()},closeSummaryPanel(){On(!1)},getExportTitle(){return dn()},getSaveImageHook(){return ue.onSaveImage},drawPendingNow:An,getBinColors(){return h.binColors},setSummaryVisible(e){Z&&(Z.style.display=e?"flex":"none")},setViewControlsVisible(e){R&&(R.style.display=e?"flex":"none")},setExpandVisible(e){se&&(se.style.display=e?"flex":"none")},openUserGuide:Qt,setInsightsOpen(e){_e(e),X&&(e?(X.dataset.active="1",X.style.background=E.bgActive,X.style.color=E.iconActive):(delete X.dataset.active,X.style.background="transparent",X.style.color=E.icon))},destroy(){vn=!0;for(const e of Ue.values())e.cancel();Ue.clear(),Ee?.close(),Ln?.()?.remove(),Vt&&p.removeEventListener("click",Vt,!0),s.removeEventListener("wheel",Fn),s.removeEventListener("pointerdown",zn),s.removeEventListener("pointermove",Hn),s.removeEventListener("pointerup",Vn),s.removeEventListener("pointerleave",_n),s.removeEventListener("pointercancel",jn),s.removeEventListener("dblclick",qn),s.removeEventListener("keydown",Zn),s.removeEventListener("keyup",Qn),s.removeEventListener("contextmenu",Nn),bn?.(),s.removeEventListener("click",Jn),Kn.disconnect(),Kt?.disconnect(),qe.removeEventListener("change",yt),$n.removeEventListener("change",Gn),L.removeEventListener("blur",Un),Ci(),z&&Mt(p),ce?.remove(),Se&&(Se.parentElement?.insertBefore(M,Se),Se.remove()),de&&(de.parentElement?.insertBefore(M,de),de.remove()),M.remove(),s.style.cursor="",G?.destroy(),$?.destroy(),ze.remove()}}}
@@ -2,7 +2,7 @@ import type { Wafer } from '../core/wafer.js';
2
2
  import type { Die } from '../core/dies.js';
3
3
  import { type BinDef, type TestDef, type YieldSummary, type MetadataFieldDef } from '../renderer/buildWaferMap.js';
4
4
  import type { StatsFinding, StatsSummary, LotStatsSummary } from '../stats/types.js';
5
- import { type ReportMap } from '../stats/renderSummaryReport.js';
5
+ import type { ReportMap } from '../stats/renderSummaryReport.js';
6
6
  import { type FindingsFilter } from '../stats/filterFindings.js';
7
7
  import { type BinColors } from '../renderer/binColors.js';
8
8
  import { buildWarningsBanner, type WaferWarning } from './warnings.js';
@@ -336,7 +336,24 @@ export declare function buildFindingsSection(findings: StatsFinding[], statsSumm
336
336
  * thread a `panel` through and give it a `stateKey`, or it will be the one
337
337
  * section that forgets whether the reader collapsed it.
338
338
  */
339
- standalone?: boolean): HTMLDivElement | null;
339
+ standalone?: boolean,
340
+ /** The pass bins every wafer was judged by, for the synthesis the Detail modal opens with; omitted when they differ. */
341
+ passBins?: readonly number[]): HTMLDivElement | null;
342
+ /**
343
+ * The first section of both panels: what the wafer or lot did and what stands out, from the same
344
+ * `buildSynthesis` the HTML reports open with. A clean one says so ("Nothing stands out"), which a
345
+ * list of findings cannot, so this is its own section and not a part of the Findings one — that
346
+ * section is absent when there are no findings.
347
+ *
348
+ * Linked names (a region, a bin) select that finding, exactly as its row in the list below does.
349
+ */
350
+ export declare function buildSynthesisSection(source: StatsSummary | LotStatsSummary,
351
+ /** The pass bins every wafer was judged by; omitted when they differ, and the items then rest on yield alone. */
352
+ passBins: readonly number[] | undefined, onFindingClick: ((finding: StatsFinding, row: HTMLButtonElement) => void) | undefined, activeFindingId: string | null,
353
+ /** Panel element owning the collapsed state. Omit for a stateless render. */
354
+ panel?: HTMLElement,
355
+ /** Opens the full report, which begins with this same section. Omitted ⇒ no link. */
356
+ onOpenReport?: () => void): HTMLDivElement;
340
357
  /**
341
358
  * Findings section with severity/kind/region filter controls — the
342
359
  * panel-level entry point (wraps `buildFindingsSection(..., standalone:
@@ -371,7 +388,9 @@ export declare function buildFindingsSectionWithFilter(source: StatsSummary | Lo
371
388
  /** Panel element owning the collapsed state. Omit for a stateless render. */
372
389
  panel?: HTMLElement,
373
390
  /** See {@link FindingsNotice}. Rendered above the filter row. */
374
- notice?: FindingsNotice): HTMLDivElement | null;
391
+ notice?: FindingsNotice,
392
+ /** The pass bins every wafer was judged by; omitted when they differ. See {@link buildSynthesisSection}. */
393
+ passBins?: readonly number[]): HTMLDivElement | null;
375
394
  /**
376
395
  * Aggregate test value stats across all wafers in the lot. When every
377
396
  * wafer's `StatsSummary.stats.perTestStats`/`.testSpecYield` is available
@@ -1,3 +1,4 @@
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
+ import{testValue as Be}from"../core/dieTable.js";import{waferDisplayLabel as ve}from"../core/waferLabel.js";import{commonPassBins as gt,itemPassBins as me,passBinsLabel as ht}from"../core/passBins.js";import{isParametricTest as bt}from"../renderer/buildWaferMap.js";import{testLabel as xt,markedTestLabel as yt,unmarkedLabel as Ct,derivedFields as we,derivedKeyText as vt,derivedCsvCell as Ee,isDerivedTest as Te,DERIVED_CSV_HEADER as De}from"../renderer/testLabel.js";import{buildRingRegions as wt,buildQuadrantRegions as St,buildRegionYieldData as Lt}from"../stats/regions.js";import{computeFunctionalYield as $t}from"../stats/analyzeWaferMap.js";import{buildSynthesis as Re,synthesisText as kt}from"../stats/synthesis.js";import{MEAN_WAFER_YIELD_LABEL as Bt,METER_DOTS as Ne,SEVERITY_MARK as Et,filledDots as Fe,impactWord as Tt,formatPoints as Dt,shortfallColor as Rt}from"../stats/presentation.js";import{regionYieldRows as Nt,waferYieldRows as Ft}from"../stats/yieldRows.js";import{formatFindingTooltip as Ae}from"../stats/findingText.js";import{arrangeFindings as At,filterFindings as Mt}from"../stats/filterFindings.js";import{buildFacetTable as Wt,prettyKey as Me}from"../stats/facets.js";import{commonMetadata as We}from"../stats/facets.js";import{resolveMetadataColumns as It}from"../stats/metadataColumns.js";import{resolveBinColors as Ie,resolveBinColorsByWafer as Pt}from"../renderer/binColors.js";import{NO_DATA_FILL as zt}from"../renderer/colorMap.js";import{classifySpec as Ht,isOutOfSpec as Yt}from"../renderer/spec.js";import{describeWaferPopulation as Pe,populationLabel as Ot}from"../stats/population.js";import{buildWarningsBanner as Se,collectWarnings as ze}from"./warnings.js";export{Se as buildWarningsBanner};import{fmt as He,fmtAggregationMethod as _t,plainBinTerms as ae}from"../renderer/fmt.js";import{getUniqueTestNumbers as jt}from"../renderer/buildView.js";import{describeValues as Vt}from"../stats/math.js";import{pooledTestStatsSteps as Kt}from"../stats/capability.js";import{binBreakdownRows as qt,binBreakdownTitle as Ye,binCountsFrom as Oe,totalOf as _e}from"../stats/binRows.js";import{poolFunctionalYield as Gt}from"../stats/testPassRate.js";import{makeLabeledSelect as je,makeSegmented as Le}from"./charts/chartShell.js";import{SHADOW as Ve,MOTION as Ke,LEADING as Q,TRACKING as le,wireControlHover as U,controlStyle as ge,SPACE as g,RADIUS as G,FONT as T,CLR as C,sevColor as de,openModal as qe,openReportModal as Ge,saveTextFile as Ue,wireTooltip as re}from"./toolbar.js";import{buildDieListSection as Ut}from"./dieList.js";export{csvField}from"../core/utils.js";import{csvField as he,drain as be,maxOf as Qt,minOf as Xt}from"../core/utils.js";import{metadataDisplayValue as Zt}from"../core/metadata.js";const Jt=C.panelBg,Qe=`1px solid ${C.menuBorder}`,en="12px",z=C.label,X=C.value,Xe="10px";function a(e,n,i,t=document){const o=t.createElement(e);return n&&Object.assign(o.style,n),i!==void 0&&(o.textContent=i),o}function pe(e){return a("div",{fontSize:Xe,fontWeight:"700",letterSpacing:le,textTransform:"uppercase",color:z,marginBottom:g.sm},e)}const Ze=new WeakMap,Je=["regionYield","testValues","functionalTests"];function xe(e){if(!e)return{collapsed:new Set(Je),regionMode:"ring",waferSort:"slot"};let n=Ze.get(e);return n||(n={collapsed:new Set(Je),regionMode:"ring",waferSort:"slot"},Ze.set(e,n)),n}function ne(e,n=!0,i,t){const o=a("div"),c=xe(t?.panel);t?.stateKey&&t.panel&&(n=!c.collapsed.has(t.stateKey));const s=document.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",gap:g.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const h=a("span",{fontSize:T.meta,color:z,transition:`transform ${Ke.base}`,transform:n?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:Q.none,marginRight:"1px"},"\u25B6"),f=a("span",{fontSize:Xe,fontWeight:"700",letterSpacing:le,textTransform:"uppercase",color:z,flex:"1"},e);if(U(s,"bare"),s.setAttribute("aria-expanded",n?"true":"false"),s.appendChild(h),s.appendChild(f),i){const x=a("span",{fontSize:T.meta,fontWeight:"700",background:C.warnBg,color:C.warnText,borderRadius:G.pill,padding:"1px 5px"},i);s.appendChild(x)}const l=a("div");l.style.display=n?"block":"none";let p=n;if(s.addEventListener("click",()=>{p=!p,l.style.display=p?"block":"none",h.style.transform=p?"rotate(90deg)":"rotate(0deg)",s.setAttribute("aria-expanded",p?"true":"false"),t?.stateKey&&t.panel&&(p?c.collapsed.delete(t.stateKey):c.collapsed.add(t.stateKey))}),t?.control){const x=a("div",{display:"flex",alignItems:"center",gap:g.sm});s.style.width="auto",s.style.flex="1",x.appendChild(s);const r=()=>{l.innerHTML="",t.render?.(l)},m=t.control(r);m&&(m.style.marginBottom="6px",m.addEventListener("click",v=>v.stopPropagation()),x.appendChild(m)),o.appendChild(x)}else o.appendChild(s);return o.appendChild(l),t?.render?.(l),{outer:o,content:l}}function et(){return a("div",{height:"1px",background:C.separator,margin:`${en} 0`,flexShrink:"0"})}function $e(e,n,i=C.barFill,t,o,c){const s=a("div",{marginBottom:"5px"});c&&c.step>0&&Object.assign(s.style,{background:Rt(c.step),borderRadius:G.container,padding:"2px 4px",marginLeft:"-4px",marginRight:"-4px"});const h=a("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,color:X,marginBottom:g.xxs}),f=a("span",{color:z},e),l=a("span",{fontWeight:"600",fontVariantNumeric:"tabular-nums"},`${n.toFixed(1)}%`);c&&(l.appendChild(a("span",{fontWeight:"400",marginLeft:g.sm,color:c.step>0?X:z},Dt(c.delta))),c.step>0&&(f.style.color=X)),h.appendChild(f),h.appendChild(l);const p=t!==void 0?t:Math.min(100,Math.max(0,n)),x=i,r=a("div",{position:"relative",height:"9px",background:C.bgActive,borderRadius:G.control,overflow:"hidden"}),m=a("div",{height:"100%",width:`${p}%`,background:x,borderRadius:G.control,transition:`width ${Ke.base}`});if(r.appendChild(m),o!==void 0){const v=a("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"2px",marginLeft:"-1px",background:C.value,opacity:"0.8"});r.appendChild(v)}return s.appendChild(h),s.appendChild(r),s}function tt(){const e=a("div",{display:"flex",gap:g.sm,marginBottom:g.md});return e.finish=()=>{const n=e.lastElementChild;n&&Object.assign(n.style,{borderRight:"none",paddingRight:"0"})},e}function ue(e,n,i){const t=a("div",{padding:`${g.xxs} ${g.md} ${g.xxs} 0`,borderRight:Qe,textAlign:"center",flex:"1"}),o=a("div",{fontSize:T.heading,fontWeight:"700",color:X,lineHeight:Q.tight},e),c=a("div",{fontSize:T.body,color:z,marginTop:g.xxs},n);return t.appendChild(o),t.appendChild(c),i&&t.appendChild(a("div",{fontSize:T.body,color:z,opacity:"0.85"},i)),t}function nt(e,n){const i=a("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,gap:g.md,marginBottom:"3px"}),t=a("span",{color:z,flexShrink:"0"},e),o=a("span",{color:X,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},n);return i.appendChild(t),i.appendChild(o),i}function tn(e,n){const i=a("div",{display:"flex",fontSize:T.body,gap:g.sm,marginBottom:"3px"}),t=a("span",{color:z,flexShrink:"0"},`${e}:`),o=a("span",{color:X,fontWeight:"500",wordBreak:"break-all"},n);return i.appendChild(t),i.appendChild(o),i}export function metadataEntries(e){const n=[];for(const[i,t]of Object.entries(e)){const o=Zt(t);o!==void 0&&n.push([i,o])}return n}const nn=["lot","product","testprogram","split"],ye=e=>{const n=nn.indexOf(e.toLowerCase().replace(/[^a-z]/g,""));return n===-1?Number.MAX_SAFE_INTEGER:n};export function buildFacetSummaryChips(e,n=3){if(!e.length)return null;const i=a("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${g.xs} ${g.lg}`}),t=[...e].sort((h,f)=>ye(h.key)-ye(f.key)),o=t.filter(h=>ye(h.key)!==Number.MAX_SAFE_INTEGER),c=t.filter(h=>ye(h.key)===Number.MAX_SAFE_INTEGER),s=h=>{const f=a("span",{whiteSpace:"nowrap"}),l=a("span",{color:z},`${Me(h.key)}: `);f.appendChild(l);const p=h.values.slice(0,n),x=h.values.length-p.length;let r=p.map(m=>m.value).join(", ");return x>0&&(r+=` +${x} more`),f.appendChild(document.createTextNode(r)),f};for(const h of o)i.appendChild(s(h));if(c.length){const h=a("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${g.xs} ${g.lg}`});for(const p of c)h.appendChild(s(p));const f=a("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:C.iconActive,fontSize:T.body,whiteSpace:"nowrap"});f.type="button",U(f,"bare");const l=p=>{h.style.display=p?"contents":"none",f.textContent=p?"less":`+${c.length} more`,f.setAttribute("aria-expanded",String(p))};l(!1),f.addEventListener("click",()=>l(f.getAttribute("aria-expanded")!=="true")),i.appendChild(h),i.appendChild(f)}return i}export function buildMetadataStripRow(e,n,i){const t=Wt(e,i),o=buildFacetSummaryChips(t);if(!o&&!n)return null;const c=a("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(n){const s=a("span",{fontWeight:"500",whiteSpace:"nowrap"},n.aggrMethod?`${n.lotSize} wafers stacked \xB7 ${n.aggrMethod}`:`${n.lotSize} wafers stacked`);c.appendChild(s)}return o&&c.appendChild(o),c}const on={display:"flex",flexDirection:"column",gap:g.sm,background:C.menuBg,border:`1px solid ${C.menuBorder}`,borderRadius:G.container,padding:`${g.sm} ${g.lg}`,boxShadow:Ve.panel,fontSize:T.body,lineHeight:Q.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(e,n,i){const t=buildMetadataStripRow(e,n,i);if(!t)return null;const o=a("div",on);return o.appendChild(t),o}export function buildCompactMetadataRows(e){const n=metadataEntries(e);if(!n.length)return null;const i=a("div");for(const[t,o]of n)i.appendChild(tn(Me(t),o));return i}export function buildMetadataInfoSection(e,n){const i=buildMetadataStripRow(e,n,{facetableOnly:e.length>1});if(!i)return null;const t=a("div");return t.appendChild(pe("Wafer Info")),t.appendChild(i),t}export function buildYieldSection(e,n,i=[1]){const t=a("div");t.appendChild(pe("Summary"));const o=tt();if(o.appendChild(ue(String(e.totalDies),"Total dies")),e.partialDies>0&&o.appendChild(ue(String(e.partialDies),"Partial")),e.yieldPercent!==null){const c=ht([i]);o.appendChild(ue(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${c}`))}return o.finish(),t.appendChild(o),e.edgeExcludedDies>0&&t.appendChild(nt("Edge excluded (outer zone)",String(e.edgeExcludedDies))),t}export function buildBinSection(e,n,i,t,o,c){const s=Oe(e,i,o);if(!s.size)return null;const h=t??Ie(e,{passBins:c,...i==="hard"?{hbinDefs:n}:{sbinDefs:n}}),f=a("div");f.appendChild(pe(Ye(i,_e(s))));for(const l of it(s,n,h[i],h.pass[i]))f.appendChild(l);return f}function it(e,n,i,t){return qt(e,n,t).map(o=>$e(`${o.label} (${o.count})`,o.percent,i.get(o.bin)??zt))}export function buildBinBreakdownSection(e){const{dies:n,hbinDefs:i,sbinDefs:t,hardCounts:o,softCounts:c,plotMode:s,passBins:h=[1],panel:f}=e,l=e.binColors??Ie(n,{passBins:h,hbinDefs:i,sbinDefs:t}),p=D=>Oe(n,D,D==="hard"?o:c),x=p("hard"),r=p("soft"),m=x.size>0,v=r.size>0;if(!m&&!v)return null;const L=xe(f),A=s==="softBin"||s==="stackedSoftBins"?"soft":s==="hardBin"||s==="stackedBins"?"hard":void 0;let u=L.binMode??A??(m?"hard":"soft");u==="hard"&&!m&&(u="soft"),u==="soft"&&!v&&(u="hard");const E=u==="hard"?x:r,W=u==="hard"?i:t,b=_e(E),{outer:S}=ne(Ye(u,b),!0,void 0,{stateKey:"bins",panel:f,render:D=>{const y=u==="hard"?l.hard:l.soft;for(const $ of it(E,W,y,l.pass[u]))D.appendChild($)},control:m&&v&&f?()=>Le([["hard","Hard"],["soft","Soft"]],u,D=>{L.binMode=D;const y=buildBinBreakdownSection(e);y&&S.replaceWith(y)},f.ownerDocument,!0):void 0});return S}export function buildLotBinSection(e,n,i,t){return buildBinSection(e,n,i,t)}export function buildRegionYieldPanelSection(e){const{diesByWafer:n,allWafers:i,ringCount:t,passBins:o,panel:c}=e,s=xe(c),h=p=>Lt(n,i,t,o,p==="ring"?wt:St);if(!h("ring").length&&!h("quadrant").length)return null;const f=s.regionMode,{outer:l}=ne(f==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:c,render:p=>{const x=h(f);if(!x.length){p.appendChild(a("div",{fontSize:T.body,color:z},"No positioned dies for this breakdown."));return}for(const{label:r,n:m,yieldPercent:v,delta:L,step:A}of Nt(x).rows)p.appendChild($e(`${r} (N=${m})`,v,void 0,void 0,void 0,{delta:L,step:A}))},control:c?()=>Le([["ring","Ring"],["quadrant","Quadrant"]],f,p=>{s.regionMode=p;const x=buildRegionYieldPanelSection(e);x&&l.replaceWith(x)},c.ownerDocument,!0):void 0});return l}export function buildLotOverviewSection(e,n=[]){const i=a("div"),t=Pe(e.perWafer.map(s=>s.summary.wafer));i.appendChild(pe(t.lotId!==void 0?"Lot Summary":"Summary"));const o=tt();o.appendChild(ue(String(e.stats.waferCount),"Wafers"));const c=e.perWafer.map(s=>s.summary.stats.yieldPercent).filter(s=>s!==null);if(c.length){const s=c.reduce((h,f)=>h+f,0)/c.length;o.appendChild(ue(`${s.toFixed(1)}%`,Bt))}if(o.finish(),i.appendChild(o),n.length){const s=n.reduce((f,l)=>f+l.stats.analyzedDies,0),h=n.reduce((f,l)=>f+l.stats.excludedDies,0);(s||h)&&i.appendChild(nt("Dies analysed",h?`${s.toLocaleString()} (${h.toLocaleString()} excluded)`:s.toLocaleString()))}return i}export function buildPerWaferYieldSection(e,n,i,t,o){const c=e.perWafer.map(u=>({waferIndex:u.waferIndex,label:ve(n[u.waferIndex],u.waferIndex).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:u.summary.stats.yieldPercent})).filter(u=>u.yieldPct!==null);if(!c.length)return null;const s=Xt(c.map(u=>u.yieldPct)),h=Qt(c.map(u=>u.yieldPct)),f=s===h?"":` (${s.toFixed(1)}\u2013${h.toFixed(1)}%)`,{rows:l,median:p}=Ft(c.map(u=>({...u,yieldPercent:u.yieldPct}))),x=xe(t),r=u=>{const E=x.waferSort==="yield"?[...l].sort((W,b)=>W.yieldPct-b.yieldPct):l;for(const W of E){const{waferIndex:b,label:S,yieldPct:D,delta:y,step:$}=W,N=W.outlier?`${S} \xB7 ${W.outlier} outlier`:S,k=$e(N,D,void 0,void 0,p,{delta:y,step:$}),w=o?.(b);w?.total&&L(k,w),A(k,b,S,D,w),u.appendChild(k)}},m=` \xB7 median ${p.toFixed(1)}%`,{outer:v}=ne("Wafer Yield"+f+m,!0,void 0,{stateKey:"waferYield",panel:t,render:r,control:t?u=>Le([["slot","Slot"],["yield","Yield"]],x.waferSort,E=>{x.waferSort=E,u()},t.ownerDocument,!0):void 0});return v;function L(u,E){const W=E.unusual?"unusual":E.notable?"notable":"info",b=a("span",{marginLeft:g.sm,flexShrink:"0",background:de(W),color:"#fff",borderRadius:G.container,padding:"0 5px",fontSize:T.body,fontWeight:"600"},`${E.total}`);b.setAttribute("aria-hidden","true"),re(b,`${E.total} finding${E.total===1?"":"s"}`+(E.unusual?`, ${E.unusual} unusual`:"")+(E.notable?`, ${E.notable} notable`:"")),u.firstElementChild?.firstElementChild?.appendChild(b)}function A(u,E,W,b,S){i&&(u.style.cursor="pointer",u.style.borderRadius="4px",u.style.padding="2px 3px",u.style.marginLeft="-3px",u.style.marginRight="-3px",u.setAttribute("role","button"),u.setAttribute("aria-label",`${W}, ${b.toFixed(1)}% yield`+(S?.total?`, ${S.total} finding${S.total===1?"":"s"}${S.unusual?`, ${S.unusual} unusual`:""}`:"")+" \u2014 open wafer"),u.tabIndex=0,u.addEventListener("mouseenter",()=>{u.style.background=C.bgHover}),u.addEventListener("mouseleave",()=>{u.style.background=""}),u.addEventListener("focus",()=>{u.style.background=C.bgHover}),u.addEventListener("blur",()=>{u.style.background=""}),u.addEventListener("click",()=>i(E)),u.addEventListener("keydown",D=>{(D.key==="Enter"||D.key===" ")&&(D.preventDefault(),i(E))}))}}function sn(e){return Vt(Float64Array.from(e))}function ot(e,n){if(!e)return[];const i=e.waferMetadata??(e.perWaferMetadata?We(e.perWaferMetadata.map(t=>({metadata:t}))):void 0);return!i||!Object.keys(i).length?[]:It({waferMetadata:i,waferKeys:"identity",waferPlacement:"csv",reservedLabels:n}).columns}function st(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,n,i,t,o,c,s,h,f="full"){const l=e.filter(d=>!d.partial&&!d.edgeExcluded),p=new Map((t?.perTestStats??[]).map(d=>[d.testNumber,d])),x=new Map((t?.testSpecYield??[]).map(d=>[d.testNumber,d]));let r;if(n?.length?r=n.filter(bt).map(d=>({testNumber:d.testNumber,name:d.name,unit:d.unit,limitLow:d.limitLow,limitHigh:d.limitHigh,limitLowInclusive:d.limitLowInclusive,limitHighInclusive:d.limitHighInclusive,...we(d)})):r=jt(l).map(P=>({testNumber:P,name:xt(void 0,P)})),!r.length)return null;const m=r.filter(d=>l.some(P=>{const _=Be(P,d.testNumber);return _!==void 0&&isFinite(_)}));if(!m.length)return null;const v=m.some(d=>d.limitLow!==void 0||d.limitHigh!==void 0),L=[],A=d=>!!d&&d.stddev!==void 0&&d.median!==void 0&&d.q1!==void 0&&d.q3!==void 0,u=d=>d.limitLow!==void 0||d.limitHigh!==void 0,E=!!(s?.length&&n?.length),b=(E||m.some(d=>!A(p.get(d.testNumber))||u(d)&&!x.has(d.testNumber)))&&n?.length?yield*Kt(s??[{dies:e}],n):void 0;for(const d of m){yield;const P=p.get(d.testNumber),_=b?.specTally.get(d.testNumber),K=b?.stats.get(d.testNumber),q=()=>l.map(M=>Be(M,d.testNumber)).filter(M=>M!==void 0&&isFinite(M));let J;if(A(P)){const M=P;J={testNumber:d.testNumber,min:M.min,max:M.max,mean:M.mean,count:M.count,stddev:M.stddev,median:M.median,q1:M.q1,q3:M.q3}}else if(K)J={testNumber:d.testNumber,...K};else{const M=q();if(!M.length)continue;J={testNumber:d.testNumber,...sn(M)}}let I=null,R=0;if(u(d)){const M=x.get(d.testNumber);if(M)({yieldPercent:I,totalDies:R}=M);else if(_)R=_.n,I=R>0?(R-_.fail)/R*100:null;else{const ee=q();let fe=0;for(const se of ee)Yt(Ht(se,d))&&fe++;R=ee.length,I=ee.length>0?(ee.length-fe)/ee.length*100:null}}L.push({entry:d,stats:J,specYieldPct:I,specN:R})}if(!L.length)return null;const S=new Map;for(const d of(E?b?.capability:void 0)??[])d.hasSpec&&S.set(d.testNumber,d.ppk);const D=S.size>0,$=new Set(L.map(d=>d.stats.count)).size===1?L[0].stats.count:null,N=a("div"),k=a("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:g.sm}),w=$!==null?` \xB7 N=${$.toLocaleString()}`:"",F=c?.populationLabel?`Test Values (${L.length}) \u2014 ${c.populationLabel}${w}`:`Test Values (${L.length})${w}`,j=pe(F);j.style.marginBottom="0",k.appendChild(j);const H=document.createElement("button");H.type="button",H.textContent="Test values CSV",Object.assign(H.style,{...ge("outlined")}),U(H),H.addEventListener("click",()=>{const d=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];D&&d.push("Ppk");const P=L.some(R=>R.specYieldPct!==null&&R.specN!==R.stats.count);v&&(d.push("Lo limit","Hi limit","Limit Yield %"),P&&d.push("Limit Yield N"));const _=L.some(R=>Te(R.entry));_&&d.push(De);const K=[...ot(c,d),...st(c)],J=[[...K.map(R=>R.label),...d].map(he).join(",")],I=R=>He(R,void 0,"engineering");for(const{entry:R,stats:M,specYieldPct:ee,specN:fe}of L){const se=[...K.map(ce=>ce.constant??""),R.name,R.unit??"",String(M.count),I(M.min),I(M.q1),I(M.median),I(M.mean),I(M.q3),I(M.max),I(M.stddev)];if(D){const ce=S.get(R.testNumber);se.push(ce==null?"":ce.toFixed(3))}v&&(se.push(R.limitLow!==void 0?I(R.limitLow):"",R.limitHigh!==void 0?I(R.limitHigh):"",ee!==null?ee.toFixed(1):""),P&&se.push(R.limitLow!==void 0||R.limitHigh!==void 0?String(fe):"")),_&&se.push(Ee(R)),J.push(se.map(he).join(","))}Ue(J.join(`
2
+ `),"test-values.csv","text/csv",o)}),k.appendChild(H),N.appendChild(k);const Y=a("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),te=document.createElement("thead"),ie=document.createElement("tr"),O=["Test"];$===null&&O.push("N"),f==="full"&&O.push("Min","Q1","Median"),O.push("Mean"),f==="full"&&O.push("Q3","Max","StdDev"),D&&O.push("Ppk"),f==="full"&&v&&O.push("Lo limit","Hi limit"),v&&O.push("Limit yield");for(const d of O){const P=a("th",{textAlign:d==="Test"?"left":"right",fontWeight:"600",fontSize:T.meta,letterSpacing:le,textTransform:"uppercase",color:z,padding:"3px 8px 5px",borderBottom:`1px solid ${C.menuBorder}`,whiteSpace:"nowrap"},d);ie.appendChild(P)}te.appendChild(ie),Y.appendChild(te);const Z=document.createElement("tbody");for(const{entry:d,stats:P,specYieldPct:_,specN:K}of L){const q=R=>He(R,d.unit,i),J=document.createElement("tr"),I=(R,M="right")=>{const ee=a("td",{textAlign:M,padding:`${g.xs} ${g.md}`,borderBottom:`1px solid ${C.menuBorder}`,color:C.text,whiteSpace:"nowrap"},R);J.appendChild(ee)};if(I(yt(d,d.testNumber),"left"),$===null&&I(`${P.count}`),f==="full"&&(I(q(P.min)),I(q(P.q1)),I(q(P.median))),I(q(P.mean)),f==="full"&&(I(q(P.q3)),I(q(P.max)),I(q(P.stddev))),D){const R=S.get(d.testNumber);I(R==null?"\u2014":R.toFixed(2))}f==="full"&&v&&(I(d.limitLow!==void 0?q(d.limitLow):"\u2014"),I(d.limitHigh!==void 0?q(d.limitHigh):"\u2014")),v&&I(_!==null?$!==null&&K===$?`${_.toFixed(1)}%`:`${_.toFixed(1)}% (N=${K})`:"\u2014"),Z.appendChild(J)}Y.appendChild(Z);const V=a("div",{overflowX:"auto"});V.appendChild(Y);const oe=dt(V,L.map(d=>({label:d.entry.name,...we(d.entry)})));if(!h)return N.appendChild(oe),N;k.remove();const{outer:B}=ne(F,!0,void 0,{stateKey:"testValues",panel:h,render:d=>d.appendChild(oe),control:()=>H});return B}export function buildFunctionalTestSection(e,n,i,t,o,c){const s=i??$t(e,n);if(!s?.length)return null;const f=new Set(s.map(y=>y.totalDies)).size===1?s[0].totalDies:null,l=f!==null?` \xB7 N=${f.toLocaleString()}`:"",p=a("div"),x=a("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:g.sm}),r=o?.populationLabel?`Functional Tests (${s.length}) \u2014 ${o.populationLabel}${l}`:`Functional Tests (${s.length})${l}`,m=pe(r);m.style.marginBottom="0",x.appendChild(m);const v=document.createElement("button");v.type="button",v.textContent="Functional CSV",Object.assign(v.style,{...ge("outlined")}),U(v),v.addEventListener("click",()=>{const y=["Test","N","Pass","Fail","Pass Rate %"],$=s.some(w=>Te(w));$&&y.push(De);const N=[...ot(o,y),...st(o)],k=[[...N.map(w=>w.label),...y].map(he).join(",")];for(const w of s)k.push([...N.map(F=>F.constant??""),Ct(w.label),String(w.totalDies),String(w.passDies),String(w.failDies),w.passRatePercent!==null?w.passRatePercent.toFixed(1):"",...$?[Ee(w)]:[]].map(he).join(","));Ue(k.join(`
3
+ `),"functional-tests.csv","text/csv",t)}),x.appendChild(v),p.appendChild(x);const L=a("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),A=document.createElement("thead"),u=document.createElement("tr"),E=f===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const y of E)u.appendChild(a("th",{textAlign:y==="Test"?"left":"right",fontWeight:"700",fontSize:T.body,letterSpacing:le,textTransform:"uppercase",color:z,padding:"3px 8px 5px",borderBottom:`1px solid ${C.menuBorder}`,whiteSpace:"nowrap"},y));A.appendChild(u),L.appendChild(A);const W=document.createElement("tbody");for(const y of s){const $=document.createElement("tr"),N=(k,w="right")=>{$.appendChild(a("td",{textAlign:w,padding:`${g.xs} ${g.md}`,borderBottom:`1px solid ${C.menuBorder}`,color:X,whiteSpace:"nowrap"},k))};N(y.label,"left"),f===null&&N(String(y.totalDies)),N(String(y.passDies)),N(String(y.failDies)),N(y.passRatePercent!==null?`${y.passRatePercent.toFixed(1)}%`:"\u2014"),W.appendChild($)}L.appendChild(W);const b=a("div",{overflowX:"auto"});b.appendChild(L);const S=dt(b,s);if(!c)return p.appendChild(S),p;x.remove();const{outer:D}=ne(r,!0,void 0,{stateKey:"functionalTests",panel:c,render:y=>y.appendChild(S),control:()=>v});return D}export function buildLotFunctionalSection(e,n,i,t,o){const c=i?.length?{perWaferMetadata:i.map(h=>h.wafer??{}),populationLabel:`${i.length} wafer${i.length===1?"":"s"} pooled`}:void 0,s=Gt(i);return s?buildFunctionalTestSection(e,n,s,t,c,o):buildFunctionalTestSection(e,n,void 0,t,c,o)}function ke(e){const{tier:n,word:i}=Et[e],t=Fe(n),o=a("span",{flexShrink:"0",letterSpacing:"1px",lineHeight:Q.none,color:de(e)},"\u25CF".repeat(t)+"\u25CB".repeat(Ne-t));return o.setAttribute("role","img"),o.setAttribute("aria-label",i),re(o,i),o}function at(e,n){let i=e.summary;if(n){const t=[" has "," have "].find(o=>i.startsWith(`${n}${o}`));t?i=i.slice(n.length+t.length):i.startsWith(`${n} `)&&(i=i.slice(n.length+1))}return i=ae(i),i.length?i[0].toUpperCase()+i.slice(1):i}function rt(e){return lt(e.map(n=>({label:n.variable.label,...we(n.variable)})))}function lt(e){const n=vt(e);return n?a("div",{fontSize:T.body,color:z,marginTop:g.sm,lineHeight:Q.base},n):null}function dt(e,n){const i=lt(n);if(!i)return e;const t=a("div",{});return t.append(e,i),t}export function buildFindingsSection(e,n,i,t,o=!1,c){if(!e.length)return null;const s=e.some(b=>b.severity==="unusual"||b.severity==="notable"),h=s?e.filter(b=>b.severity!=="info").length.toString():void 0,{outer:f,content:l}=o?(()=>{const b=a("div");return{outer:b,content:b}})():ne(`Findings (${e.length})`,s,h);function p(b,S){const y={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[b]??b;return S.toLowerCase().startsWith(y.toLowerCase())?S:`${y}: ${S}`}const x=At(e),r=x.patterns.map(b=>b.finding),m=x.groups.map(b=>({...b,key:`${b.family}\0${b.left}`})),v=()=>[...m.flatMap(b=>b.findings),...r.flatMap(b=>e.filter(S=>b.relatedIds?.includes(S.id)))];function L(b,S=!1,D){const y=t===b.id,$=document.createElement("button");return $.type="button",$.dataset.wmapFinding=b.id,$.textContent=at(b,D),re($,Ae(b)),$.setAttribute("aria-current",y?"true":"false"),Object.assign($.style,{border:`1px solid ${C.menuBorder}`,borderLeft:`3px solid ${de(b.severity)}`,background:y?C.bgActive:C.menuBg,borderRadius:G.container,padding:S?"6px 10px":"8px 10px",textAlign:"left",fontSize:S?"10px":"11px",fontWeight:y?"600":"400",color:C.text,cursor:"pointer",width:"100%",marginBottom:g.xs}),U($,"bare"),$.addEventListener("click",()=>i(b,$)),$}const A=a("button",{flexShrink:"0",border:"none",background:"none",fontSize:T.body,color:C.icon,cursor:"pointer",padding:"0",lineHeight:Q.base,whiteSpace:"nowrap"},"Detail \u25B8");A.type="button",U(A,"bare"),A.addEventListener("click",()=>{const b=qe({title:"Findings Summary",onClose:()=>{},anchor:A}),S=Re(n,{passBins:c}),D=a("div",{fontSize:"16px",lineHeight:Q.base,color:C.text,padding:`${g.xxl} ${g.xxxl} ${g.xxl}`,margin:"0",borderBottom:`1px solid ${C.menuBorder}`,flexShrink:"0",display:"flex",flexDirection:"column",gap:g.md});for(const k of kt(S).split(`
4
+ `))D.appendChild(a("p",{margin:"0"},ae(k)));b.contentWrap.appendChild(D);const y=a("div",{overflowY:"auto",padding:`${g.xxl} ${g.xxxl}`,flex:"1"}),$=(k,w)=>{const F=a("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:T.sub,fontWeight:"600",color:X,marginTop:g.lg,marginBottom:g.xs});return F.appendChild(ke(k)),F.appendChild(a("span",{},w)),F};for(const k of r){y.appendChild($(k.severity,k.comparison.left)),y.appendChild(a("div",{fontSize:T.body,color:C.text,padding:"4px 0 4px 15px",marginBottom:g.xxs},ae(k.summary)));const w=e.filter(F=>k.relatedIds?.includes(F.id));for(const F of w)y.appendChild(a("div",{fontSize:T.body,color:z,padding:"2px 0 2px 23px",marginBottom:g.xxs},ae(F.summary)))}for(const k of m){const[w,F]=k.key.split("\0");y.appendChild($(k.worst,p(w,F)));for(const j of k.findings)y.appendChild(a("div",{fontSize:T.body,color:C.text,padding:"4px 0 4px 15px",marginBottom:g.xxs},at(j,F)))}const N=rt(v());N&&y.appendChild(N),b.contentWrap.appendChild(y),Object.assign(b.contentWrap.style,{flexDirection:"column",overflow:"hidden"})});const u=a("div",{display:"flex",justifyContent:"flex-end",marginBottom:g.xs});u.appendChild(A),l.appendChild(u);let E=!0;for(const b of r){E||l.appendChild(a("div",{height:"1px",background:C.separator,margin:"4px 0"})),E=!1;const S=e.filter(k=>b.relatedIds?.includes(k.id)),D=S.length>0,y=a("div",{position:"relative",marginBottom:D?"2px":"4px"}),$=t===b.id,N=document.createElement("button");if(N.type="button",N.dataset.wmapFinding=b.id,Object.assign(N.style,{border:`1px solid ${C.menuBorder}`,borderLeft:`3px solid ${de(b.severity)}`,background:$?C.bgActive:C.menuBg,borderRadius:G.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:T.body,fontWeight:$?"600":"500",color:C.text,cursor:"pointer",width:"100%"}),N.textContent=ae(b.summary),re(N,b.summary),N.setAttribute("aria-current",$?"true":"false"),U(N,"bare"),N.addEventListener("click",()=>i(b,N)),y.appendChild(N),D){const k=a("div",{display:"none",paddingLeft:"12px",marginBottom:g.xs});for(const j of S)k.appendChild(L(j,!0));y.appendChild(k);let w=!1;const F=a("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:T.body,color:C.icon,cursor:"pointer",padding:`${g.xxs} ${g.xs}`,lineHeight:Q.none},"\u25B8");U(F,"bare"),F.type="button",re(F),F.setAttribute("aria-label","Show supporting findings"),F.setAttribute("aria-expanded","false"),F.addEventListener("click",j=>{j.stopPropagation(),w=!w,k.style.display=w?"block":"none",F.textContent=w?"\u25BE":"\u25B8";const H=w?"Hide supporting findings":"Show supporting findings";F.setAttribute("aria-label",H),F.setAttribute("aria-expanded",String(w))}),y.appendChild(F)}l.appendChild(y)}for(const b of m){E||l.appendChild(a("div",{height:"1px",background:C.separator,margin:"4px 0"})),E=!1;const[S,D]=b.key.split("\0"),y=a("div",{display:"flex",alignItems:"center",gap:g.sm,fontSize:T.body,fontWeight:"600",color:X,margin:"2px 0 4px"});y.appendChild(ke(b.worst)),y.appendChild(a("span",{},p(S,D))),l.appendChild(y);for(const $ of b.findings)l.appendChild(L($,!1,D))}const W=rt(v());return W&&l.appendChild(W),f}const an={high:"rgba(168, 65, 18, 0.10)",medium:"rgba(138, 101, 0, 0.10)",low:""},pt={high:"unusual",medium:"notable",low:"info"};function rn(e,n){const i=Fe(e),t=a("span",{display:"inline-flex",alignItems:"baseline",gap:g.xs,whiteSpace:"nowrap"}),o=a("span",{letterSpacing:"1px",color:de(pt[e])},"\u25CF".repeat(i)+"\u25CB".repeat(Ne-i));return o.setAttribute("aria-hidden","true"),t.appendChild(o),t.appendChild(a("span",{fontSize:T.meta,fontWeight:"600",letterSpacing:le,textTransform:"uppercase",color:X},n)),t}export function buildSynthesisSection(e,n,i,t,o,c){const s=Re(e,{passBins:n}),h=new Map(e.findings.map(r=>[r.id,r])),{outer:f,content:l}=ne("What stands out",!0,void 0,{stateKey:"synthesis",panel:o}),p=(r,m)=>{for(const v of m){const L=v.target?h.get(v.target.id):void 0,A=ae(v.text);if(!L||!i||!A){r.appendChild(document.createTextNode(A));continue}const u=document.createElement("button");u.type="button",u.textContent=A,u.dataset.wmapFinding=L.id,u.setAttribute("aria-current",t===L.id?"true":"false"),Object.assign(u.style,{border:"none",background:"none",padding:"0",margin:"0",font:"inherit",color:"inherit",textDecoration:"underline dotted",textUnderlineOffset:"2px",cursor:"pointer",textAlign:"inherit",fontWeight:t===L.id?"600":"inherit"}),re(u,Ae(L));const E=W=>{u.style.textDecoration=W?"underline solid":"underline dotted",u.style.color=W?C.iconActive:"inherit"};u.addEventListener("mouseenter",()=>E(!0)),u.addEventListener("mouseleave",()=>E(!1)),u.addEventListener("focus",()=>E(!0)),u.addEventListener("blur",()=>E(!1)),u.addEventListener("click",()=>i(L,u)),r.appendChild(u)}},x=(r,m)=>{const v=a("div",{fontSize:T.body,lineHeight:Q.base,color:C.text,...m});return p(v,r),v};l.appendChild(x(s.headline,{fontWeight:"600",marginBottom:g.sm})),s.nothing&&l.appendChild(a("div",{fontSize:T.body,lineHeight:Q.base,color:C.text,marginBottom:g.sm},s.nothing));for(const r of s.items){const m=a("div",{borderLeft:`3px solid ${de(pt[r.impact])}`,background:an[r.impact]||C.bgActive,borderRadius:`0 ${G.container} ${G.container} 0`,padding:`${g.sm} ${g.md}`,marginBottom:g.sm});m.appendChild(rn(r.impact,Tt(r.impact))),m.appendChild(x(r.parts,{marginTop:g.xxs})),l.appendChild(m)}s.also&&l.appendChild(x(s.also,{marginBottom:g.sm}));for(const r of s.watch??[]){const m=x(r.parts,{marginBottom:g.xs});m.insertBefore(a("span",{fontSize:T.meta,fontWeight:"600",letterSpacing:le,textTransform:"uppercase",color:z,marginRight:g.sm},"Watch"),m.firstChild),l.appendChild(m)}if(l.appendChild(a("div",{fontSize:T.body,lineHeight:Q.base,color:z},ae(s.checked))),c){const r=a("button",{border:"none",background:"none",padding:"0",marginTop:g.sm,fontSize:T.body,color:C.icon,cursor:"pointer",textDecoration:"underline",textUnderlineOffset:"2px"},"Full report \u25B8");r.type="button",U(r,"bare"),r.addEventListener("click",c),l.appendChild(r)}return f}const ln=[{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"}],dn=[{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"}],pn=["unusual","notable","info"],cn={unusual:"Unusual",notable:"Notable",info:"Minor"};function un(e,n,i){const t=a("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:g.lg,marginBottom:g.lg,paddingBottom:"10px",borderBottom:`1px solid ${C.separator}`}),o={unusual:0,notable:0,info:0};for(const l of e)o[l.severity]++;const c=pn.filter(l=>o[l]>0),s=new Set(n.severity===void 0?c:Array.isArray(n.severity)?n.severity:[n.severity]),h=a("div",{display:"flex",gap:g.xs,flexWrap:"wrap"});for(const l of c){const p=document.createElement("button");p.type="button";const x=()=>{const m=s.has(l);p.setAttribute("aria-pressed",m?"true":"false"),Object.assign(p.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${C.menuBorder}`,borderRadius:G.pill,background:m?C.bgActive:"none",opacity:m?"1":"0.5",color:C.text,fontSize:T.body,padding:`${g.xxs} ${g.md}`,cursor:"pointer"}),p.dataset.on=m?"true":"false"},r=ke(l);r.removeAttribute("role"),r.removeAttribute("aria-label"),r.setAttribute("aria-hidden","true"),p.appendChild(r),p.appendChild(a("span",{},`${cn[l]} ${o[l]}`)),re(p,()=>s.has(l)?"Click to hide these findings":"Click to show these findings"),x(),U(p,"bare"),p.addEventListener("click",()=>{s.has(l)?s.delete(l):s.add(l),n.severity=s.size===c.length?void 0:[...s],i()}),h.appendChild(p)}t.appendChild(h);const f=n.kind!==void 0||n.family!==void 0;return(e.length>=fn||f)&&(t.appendChild(je("Kind:",ln,n.kind??"",l=>{n.kind=l||void 0,i()},{maxWidth:"130px"})),t.appendChild(je("Region:",dn,n.family??"",l=>{n.family=l||void 0,i()},{maxWidth:"150px"}))),t}const fn=8;function mn(e,n){const i=a("div",{display:"flex",flexDirection:"column",gap:g.xs,padding:g.md,marginBottom:g.md,background:C.bgHover,borderRadius:G.control},void 0,n);if(i.appendChild(a("div",{fontSize:T.body,color:C.value},e.message,n)),e.detail&&i.appendChild(a("div",{fontSize:T.meta,color:z},e.detail,n)),e.actionLabel&&e.onAction){const t=a("button",ge("outlined"),e.actionLabel,n);t.type="button",t.style.alignSelf="flex-start",t.style.marginTop=g.xs,U(t),t.addEventListener("click",e.onAction),i.appendChild(t)}return i}export function buildFindingsSectionWithFilter(e,n,i,t,o,c,s,h){if(!e.findings.length&&!s)return null;const f=e.findings.some(L=>L.severity==="unusual"||L.severity==="notable"),l=f?e.findings.filter(L=>L.severity!=="info").length.toString():void 0,p=c?.ownerDocument??document,{outer:x,content:r}=ne(`Findings (${e.findings.length})`,f||!!s,l,{stateKey:"findings",panel:c});if(s&&r.appendChild(mn(s,p)),!e.findings.length)return x;r.appendChild(un(e.findings,t,o));const m=Mt(e,t);if(!m.length)return r.appendChild(a("div",{color:z,fontSize:T.body,textAlign:"center",padding:`${g.xxl} ${g.md}`},"No findings match the current filter.")),x;const v=buildFindingsSection(m,e,n,i,!0,h);return v&&r.appendChild(v),x}export function buildLotTestSection(...e){return be(buildLotTestSectionSteps(...e))}export function*buildLotTestSectionSteps(e,n,i,t,o,c,s,h="full"){const f=t?.length?{perWaferMetadata:t.map(p=>p.wafer??{}),populationLabel:`${t.length} wafer${t.length===1?"":"s"} pooled`}:void 0;let l;if(t?.length&&t.every(p=>p.stats.perTestStats!==void 0)){const p=new Map;for(const x of t)for(const r of x.stats.perTestStats??[]){const m=p.get(r.testNumber);m?(m.n+=r.count,m.sum+=r.mean*r.count,m.min=Math.min(m.min,r.min),m.max=Math.max(m.max,r.max)):p.set(r.testNumber,{n:r.count,sum:r.mean*r.count,min:r.min,max:r.max})}l={perTestStats:[...p.entries()].map(([x,r])=>({testNumber:x,count:r.n,min:r.min,max:r.max,mean:r.sum/r.n}))}}if(t?.length&&t.every(p=>p.stats.testSpecYield!==void 0)){const p=new Map;for(const x of t)for(const r of x.stats.testSpecYield??[]){const m=p.get(r.testNumber);m?(m.passDies+=r.passDies,m.totalDies+=r.totalDies):p.set(r.testNumber,{passDies:r.passDies,totalDies:r.totalDies})}l={...l,testSpecYield:[...p.entries()].map(([x,r])=>({testNumber:x,totalDies:r.totalDies,yieldPercent:r.totalDies>0?r.passDies/r.totalDies*100:null}))}}return yield*buildTestSectionSteps(e,n,i,l,o,f,c,s,h)}export function createSummaryPanelEl(e,n,i=document){const t=e==="top"||e==="bottom",o=a("div",{background:Jt,color:C.text,fontVariantNumeric:"tabular-nums",border:Qe,borderRadius:G.container,padding:g.xl,overflowY:"auto",overflowX:t?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:T.family,fontSize:T.sub,boxShadow:Ve.panel},void 0,i);return e==="right"&&(o.style.marginRight=n),e==="left"&&(o.style.marginLeft=n),e==="bottom"&&(o.style.marginBottom=n),t?(o.style.height="180px",o.style.width="100%"):(o.style.width="300px",o.style.maxHeight="100%"),o}export function wrapWithSummaryPanel(e,n,i){const t=i==="top"||i==="bottom",o=a("div",{display:"flex",flexDirection:t?"column":"row",gap:g.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:t?"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(n)):(o.appendChild(n),o.appendChild(e)),o}function ct(e,n,i,t,o){const c=n.find(h=>h.id===i);if(!c||!o)return;t.close();const s=[...e.querySelectorAll("button[data-wmap-finding]")].find(h=>h.dataset.wmapFinding===i)??e.ownerDocument.createElement("button");o(c,s)}function ut(e){return a("div",{fontSize:T.heading,fontWeight:"600",color:X,marginBottom:g.lg},e)}function Ce(e,n){const i=a("button",ge("outlined"),e);return i.type="button",U(i),i.addEventListener("click",n),i}function ft(...e){const n=e.filter(t=>!!t);if(!n.length)return null;const i=a("div",{display:"flex",flexWrap:"wrap",gap:g.sm,marginBottom:g.lg});for(const t of n)i.appendChild(t);return i}function mt(e,n,i,t,o,c,s,h,f,l,p){const x=e.ownerDocument,r=qe({title:"Die list",onClose:()=>{},anchor:e,ownerDocument:x});r.contentWrap.style.padding="14px 16px";const m=Ut(n,i,{...s,title:t,onSaveText:h,waferMetadata:o,metadataFields:c,extraColumn:f,getWafer:l,ringCount:p,ownerDocument:x});m&&r.contentWrap.appendChild(m)}export function renderWaferSummaryContent(...e){be(renderWaferSummaryContentSteps(...e))}export function*renderWaferSummaryContentSteps(e,n){const i=e.scrollTop;e.innerHTML="";const{wafer:t,dies:o,yieldSummary:c,dataCoverage:s,hbinDefs:h,sbinDefs:f,testDefs:l,statsSummary:p,passBins:x=[1],ringCount:r=4,binColors:m,plotMode:v,fallbackFormat:L,onFindingClick:A,activeFindingId:u=null,findingsFilter:E,onFindingsFilterChange:W,findingsNotice:b,onSaveText:S,metadataFields:D,dieListOptions:y,metadataShownElsewhere:$}=n;e.appendChild(ut("Wafer Summary"));const N=n.warnings??ze({statsSummary:p});N.length&&e.appendChild(Se(N,e.ownerDocument));const k=c&&s?()=>{import("../stats/renderSummaryReport.js").then(({renderWaferReportHtml:Z})=>{Ge(Z({wafer:t,dies:o,yield:c,dataCoverage:s,hbinDefs:h,sbinDefs:f,testDefs:l,passBins:x,ringCount:r},p,{binColors:m,live:!!A}),{anchor:e,onFinding:(V,oe)=>ct(e,p?.findings??[],V,oe,A)})})}:null,w=k?Ce("Summary report",k):null,F=(y?.enabled??!0)&&o.length?Ce("View die list",()=>{mt(e,o,l,`Die list \u2014 ${o.length} dies`,t.metadata,D,y,S,void 0,()=>t,r)}):null,j=ft(w,F);j&&e.appendChild(j);let H=!0;const Y=Z=>{Z&&(H||e.appendChild(et()),H=!1,e.appendChild(Z))},te=p?.stats.isLotStack?p.stats:void 0,ie=te?.lotSize!==void 0?{lotSize:te.lotSize,aggrMethod:_t(te.aggregationMethod)}:void 0;$||Y(buildMetadataInfoSection([{metadata:t.metadata??void 0}],ie)),c&&s&&Y(buildYieldSection(c,s,x)),yield,p&&(Y(buildSynthesisSection(p,x,A,u,e,k??void 0)),yield),p&&A&&E&&W&&(Y(buildFindingsSectionWithFilter(p,A,u,E,W,e,b,x)),yield),Y(buildBinBreakdownSection({dies:o,hbinDefs:h,sbinDefs:f,binColors:m,hardCounts:p?.stats.hardBinCounts,softCounts:p?.stats.softBinCounts,plotMode:v,passBins:x,panel:e})),yield,Y(buildRegionYieldPanelSection({diesByWafer:[o],allWafers:[t],ringCount:r,passBins:x,panel:e})),yield;const O=t.metadata?{waferMetadata:t.metadata}:void 0;Y(yield*buildTestSectionSteps(o,l,L,p?.stats,S,O,[{dies:o}],e,"compact")),yield,Y(buildFunctionalTestSection(o,l,p?.stats.functionalYield,S,O,e)),e.appendChild(a("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}export function reportMapsFromItems(e,n,i){const t=[];return e.forEach((o,c)=>{!o?.wafer||!o.dies||t.push({...o,wafer:o.wafer,dies:o.dies,label:ve(o,c),passBins:[...me(o,n)],ringCount:o.ringCount??i})}),t}export function renderLotSummaryContent(...e){be(renderLotSummaryContentSteps(...e))}export function*renderLotSummaryContentSteps(e,n){const i=e.scrollTop;e.innerHTML="";const{lotSummary:t,items:o,hbinDefs:c,sbinDefs:s,testDefs:h,passBins:f=[1],ringCount:l=4,binColors:p,plotMode:x,fallbackFormat:r,onFindingClick:m,activeFindingId:v=null,onWaferClick:L,findingsFilter:A,onFindingsFilterChange:u,findingsNotice:E,onSaveText:W,dieListOptions:b,findingsFor:S}=n;e.appendChild(ut(`Summary \u2014 ${Ot(Pe(t.perWafer.map(B=>B.summary.wafer)))}`));const D=n.warnings??ze({lotStatsSummary:t});D.length&&e.appendChild(Se(D,e.ownerDocument));const y=()=>{import("../stats/renderSummaryReport.js").then(({renderLotReportHtml:B})=>{Ge(B(reportMapsFromItems(o,f,l),{binColors:p,live:!!m}),{anchor:e,onFinding:(d,P)=>ct(e,t.findings,d,P,m)})})},$=Ce("Summary report",y),N=[],k=[],w=[],F=[],j=[],H=new WeakMap,Y=new WeakMap;for(let B=0;B<o.length;B++){yield;const d=o[B];if(!d){k.push([]);continue}d.wafer&&(N.push(d.wafer),F.push(d.dies??[]),j.push(me(d,f)));const P=d.dies??[],_=ve(d,B);for(const K of P)H.set(K,_),d.wafer&&Y.set(K,d.wafer);k.push(P);for(const K of P)w.push(K)}const te=b?.enabled??!0?Ce("View die list",()=>{w.length&&mt(e,w,h,`Die list \u2014 ${w.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,We(o.filter(B=>!!B).map(B=>({metadata:B.wafer?.metadata}))),o.find(B=>B?.metadataFields?.length)?.metadataFields,b,W,{label:"Wafer",get:B=>H.get(B)},B=>Y.get(B),l)}):null,ie=ft($,te);ie&&e.appendChild(ie);const O=o.map(B=>B?.statsSummary).filter(B=>!!B);let Z=!0;const V=B=>{B&&(Z||e.appendChild(et()),Z=!1,e.appendChild(B))};V(buildLotOverviewSection(t,O)),yield;const oe=gt(o.map(B=>B?me(B,f):void 0).filter(B=>B!==void 0));V(buildSynthesisSection(t,oe,m,v,e,y)),yield,m&&A&&u&&(V(buildFindingsSectionWithFilter(t,m,v,A,u,e,E,oe)),yield),V(buildPerWaferYieldSection(t,o,L,e,S)),yield,V(buildBinBreakdownSection({dies:w,hbinDefs:c,sbinDefs:s,plotMode:x,passBins:f,panel:e,binColors:p??Pt(o.flatMap(B=>B?[{dies:B.dies??[],passBins:me(B,f)}]:[]),{hbinDefs:c,sbinDefs:s}).colors})),yield,V(buildRegionYieldPanelSection({diesByWafer:F,allWafers:N,ringCount:l,passBins:B=>j[B],panel:e})),yield,h?.length&&(V(yield*buildLotTestSectionSteps(w,h,r,O,W,k.map(B=>({dies:B})),e,"compact")),yield,V(buildLotFunctionalSection(w,h,O,W,e))),e.appendChild(a("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}
@@ -69,8 +69,8 @@ export interface ToCanvasOptions {
69
69
  * or mode-switch state to pass, so these are not on `ToCanvasOptions`.
70
70
  */
71
71
  export interface MapCanvasOptions extends ToCanvasOptions {
72
- /** Currently highlighted bin (or metadata value) — drawn with an active indicator in the bin legend. */
73
- activeBin?: number | string;
72
+ /** Currently highlighted bins (or metadata values) — drawn with an active indicator in the bin legend. */
73
+ activeBin?: number | string | readonly (number | string)[];
74
74
  /** Bin legend row under the pointer — drawn with a background fill, which is
75
75
  * deliberately a different channel from `activeBin`'s accent border and bold
76
76
  * label so "selected" and "pointed at" never look the same. The legend is
@@ -79,6 +79,12 @@ export interface MapCanvasOptions extends ToCanvasOptions {
79
79
  hoverBin?: number | string;
80
80
  /** Minimum right-side reserve in CSS pixels. Ensures the wafer draw width stays stable across plot mode switches. */
81
81
  minRightReserve?: number;
82
+ /** Drawn over the dies and their labels, under the axes and legend, in CSS
83
+ * pixels with this draw's own geometry — the selection highlight. */
84
+ afterDies?: (ctx: CanvasRenderingContext2D, vp: Pick<ViewportTransform, 'originX' | 'originY' | 'ppm'>, colours: {
85
+ background: string;
86
+ text: string;
87
+ }) => void;
82
88
  }
83
89
  /** Internal viewport state shared between toCanvas and renderWaferMap. */
84
90
  export interface ViewportTransform {
@@ -128,4 +134,19 @@ export declare function toCanvas(canvas: HTMLCanvasElement, view: View, options?
128
134
  /** @internal `toCanvas` plus the interaction state `renderWaferMap` draws with. */
129
135
  export declare function drawMapCanvas(canvas: HTMLCanvasElement, view: View, options?: MapCanvasOptions): ToCanvasResult;
130
136
  export { fmt, fmtColorbarAxis } from '../renderer/fmt.js';
137
+ /** Die rectangles, or outline edges, per canvas path — see the fill and outline loops in `drawMapCanvas`. */
138
+ export declare const PATH_SHAPES = 256;
139
+ /**
140
+ * The union of the rectangles' edges as the fewest straight segments, four
141
+ * numbers each (`x0, y0, x1, y1`): each rectangle contributes its four edges, edges on the
142
+ * same line are sorted, and overlapping or touching ones merge. A die grid's
143
+ * outline becomes a few long lines per row and column instead of four sides per
144
+ * die. Works for any axis-aligned rectangles, gridded or not.
145
+ */
146
+ export declare function outlineSegments(rects: readonly {
147
+ x: number;
148
+ y: number;
149
+ width: number;
150
+ height: number;
151
+ }[]): Float64Array;
131
152
  //# sourceMappingURL=toCanvas.d.ts.map