@wafertools/wafermap 0.23.0 → 0.24.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 (29) hide show
  1. package/CHANGELOG.md +109 -1
  2. package/README.md +1 -1
  3. package/dist/packages/canvas-adapter/charts/chartShell.d.ts +1 -0
  4. package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
  5. package/dist/packages/canvas-adapter/dieList.d.ts +83 -17
  6. package/dist/packages/canvas-adapter/dieList.js +13 -2
  7. package/dist/packages/canvas-adapter/index.d.ts +1 -1
  8. package/dist/packages/canvas-adapter/insightsTab.js +1 -1
  9. package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +10 -0
  10. package/dist/packages/canvas-adapter/renderWaferGallery.js +2 -2
  11. package/dist/packages/canvas-adapter/renderWaferMap.d.ts +13 -0
  12. package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
  13. package/dist/packages/canvas-adapter/summaryPanel.d.ts +36 -3
  14. package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
  15. package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
  16. package/dist/packages/canvas-adapter/userGuideHtml.js +1 -1
  17. package/dist/packages/canvas-adapter/version.d.ts +2 -2
  18. package/dist/packages/canvas-adapter/version.js +1 -1
  19. package/dist/packages/core/inference/pitch.js +1 -1
  20. package/dist/packages/core/metadata.d.ts +29 -0
  21. package/dist/packages/core/metadata.js +1 -1
  22. package/dist/packages/renderer/buildView.d.ts +8 -0
  23. package/dist/packages/renderer/buildView.js +1 -1
  24. package/dist/packages/stats/facets.js +1 -1
  25. package/dist/packages/stats/index.d.ts +2 -0
  26. package/dist/packages/stats/index.js +1 -1
  27. package/dist/packages/stats/metadataColumns.d.ts +70 -0
  28. package/dist/packages/stats/metadataColumns.js +1 -0
  29. package/package.json +11 -6
@@ -1,4 +1,4 @@
1
- import{getUniqueTestNumbers as yn,resolveTestNumber as xn,findTestDef as wn}from"../renderer/buildView.js";import{getColorScheme as vn}from"../renderer/colorSchemes.js";import{metadataValueColor as Cn}from"../renderer/colorMap.js";import{resolveCanvasTheme as Sn}from"./canvasTheme.js";import{ICONS as pe}from"./icons.js";import{CLR as m,sevColor as Mt,BIN_LEGEND_MODES as Mn,STACKED_MODES as ue,Z_ABOVE as kt,applyOverlayZ as kn,getTooltip as Bn,hideTooltip as Bt,createToolbarHelpers as En,buildModeMenuEl as On,openDetachWindow as Dn,openFloatingWindow as Tn,openModal as Wn,copyWmapThemeTokens as Ln,syncWmapPopupTheme as In,openUserGuideWindow as Rn,makePaletteBtn as Pn,makeLogScaleBtn as An,makeLegendStyleBtn as Fn,makeOverlaysBtn as Hn,makeOrientationBtn as $n,overlayRootFor as Et,saveImageBlob as jn,markMenuTrigger as me,wireMenuA11y as Ot,wireExpandToggle as Dt,passFailMenuRows as zn,requestedPassFailDisplay as Ge,logWmapVersionOnce as Nn,buildDataModeEntries as Vn,metadataKeyHasData as _n,metadataModeEntry as Gn}from"./toolbar.js";import{aggregateValues as Kn,aggregateBinCounts as Tt}from"../core/aggregates.js";import{renderWaferMap as Ke}from"./renderWaferMap.js";import{classifyChanged as qn}from"./renderWaferMap.js";import{buildWaferMap as Xn,getTestPassStatus as Un,isParametricTest as Wt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ee}from"../stats/analyzeWaferMap.js";import{collectWarnings as Yn,buildWarningsMenuEl as Qn,severityOf as Zn}from"./warnings.js";import{compareNatural as Jn}from"../core/utils.js";import{createSummaryPanelEl as qe,buildMetadataStripRow as ei,buildCompactMetadataRows as Lt,metadataEntries as It,renderLotSummaryContent as ti}from"./summaryPanel.js";import"../stats/facets.js";import{openHtmlReport as ni}from"../stats/renderFindingsReport.js";import{escHtml as ge,renderSection as ii,renderSeverityBadge as ai,reportStyles as oi}from"../stats/reportHtml.js";import{createInsightsTab as li}from"./insightsTab.js";import{getDieKey as si,hasPosition as ri}from"../core/dies.js";function Oe(S){const B=new Set;return S.filter(u=>B.has(u.bin)?!1:(B.add(u.bin),!0))}function Rt(S,B){const u=document.createElement("div");Object.assign(u.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:"2px 4px",borderRadius:"3px"});const U=document.createElement("span");Object.assign(U.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:B.color,border:B.isActive?`2px solid ${m.iconActive}`:`1px solid ${m.menuBorder}`,borderRadius:"2px",boxSizing:"border-box"});const te=document.createElement("span");te.textContent=B.label,Object.assign(te.style,{fontWeight:B.isActive?"700":"400",color:B.isActive?m.iconActive:m.text,whiteSpace:"nowrap"}),u.appendChild(U),u.appendChild(te),u.setAttribute("role","button"),u.setAttribute("aria-pressed",B.isActive?"true":"false"),u.tabIndex=0,u.addEventListener("mouseenter",()=>{u.style.background=m.bgHover}),u.addEventListener("mouseleave",()=>{u.style.background="transparent"}),u.addEventListener("focus",()=>{u.style.background=m.bgHover}),u.addEventListener("blur",()=>{u.style.background="transparent"}),u.addEventListener("click",B.onClick),u.addEventListener("keydown",L=>{(L.key==="Enter"||L.key===" ")&&(L.preventDefault(),B.onClick())}),S.appendChild(u)}export function renderWaferGallery(S,B,u={}){Nn();const U=u.cardPadding??6,te=u.downloadFilename??"wafer-gallery";let L=u.columns;const Pt=u.showPlotModeSelector??!0,At=u.showHelpButton??!1,Ft=u.userGuideExtension,Xe=u.insights?.enabled??!1,Ht=kn(u.zIndex),Y=u.summaryPanel,Ue=u.passBins??[1];let he=u.fallbackFormat,D=u.lotStatsSummary,ne=u.legendPosition??"default",d={plotMode:"hardBin",colorScheme:"default",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,...u.viewOptions},w=[],q=[],Q=[],M=[],y=B.map(e=>typeof e=="function"?null:e),De=0,be=0;const R=new Map;let $t=0,T=null,ie=null,Ye=new Set,p=null,ae="lot",jt={};function Qe(e){return y[e]?.statsSummary??D?.perWafer.find(t=>t.waferIndex===e)?.summary}function ye(){return!!(y.some(e=>e?.statsSummary?.findings.length)||D?.perWafer.some(e=>e.summary.findings.length))}const zt=Bn(),Z=En(zt),{makeBtn:V,setActive:oe,makeSep:P,makeMenuRow:Nt,makeMenuSection:Vt,makeDropdown:Ze,makeCheckMenuBtn:di,closeOpenMenu:xe,getOpenMenu:le,setOpenMenu:se}=Z;S.ownerDocument.addEventListener("click",xe,!0);const Je=()=>Bt();window.addEventListener("blur",Je);function Te(e){Ye=new Set(e);const t=[...O.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((i,s)=>{const c=Ye.has(s);i.style.outline=c?`3px solid ${m.findingHighlight}`:"",i.style.outlineOffset=c?"-3px":"",c&&n===void 0&&(n=i)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function We(){Te([])}function Le(){for(const e of w)e&&e.clearSelection()}function Ie(e,t){const n=new Set(e),i=t??w.map((s,c)=>c);for(const s of i){const c=M[s],a=w[s];if(!c||!a)continue;const r=c.dies.filter(o=>n.has(si(o)));a.setSelection(r)}}function et(){const e=document.createElement("div");Object.assign(e.style,{display:"flex",gap:"4px",marginBottom:"10px",borderBottom:`1px solid ${m.menuBorder}`,paddingBottom:"8px"});for(const t of["lot","wafers"]){const n=document.createElement("button");n.type="button",n.textContent=t==="lot"?"Lot":"Wafers";const i=ae===t;Object.assign(n.style,{border:"none",borderRadius:"4px",padding:"2px 8px",fontSize:"11px",cursor:"pointer",fontWeight:i?"600":"400",background:i?m.bgActive:"transparent",color:i?m.iconHover:m.icon}),n.addEventListener("click",()=>{ae=t,We(),Le(),I()}),e.appendChild(n)}return e}function _t(){if(!p)return;p.innerHTML="",D&&p.appendChild(et());const e=[];for(let n=0;n<y.length;n++){const i=y[n];if(!i)continue;const s=Qe(n)?.findings??[];if(!s.length)continue;const c=s.filter(r=>r.severity==="unusual").length,a=s.filter(r=>r.severity==="notable").length;e.push({index:n,item:i,unusualCount:c,notableCount:a,totalCount:s.length})}if(e.length>0){const n=document.createElement("button");n.type="button",n.textContent="Findings report",Object.assign(n.style,{border:`1px solid ${m.menuBorder}`,borderRadius:"4px",padding:"3px 8px",marginBottom:"10px",fontSize:"10px",color:m.iconHover,background:"none",cursor:"pointer",display:"block",width:"100%",textAlign:"left"}),n.addEventListener("click",()=>{const i=`Findings report \u2014 ${e.length} wafer${e.length>1?"s":""}`,s=new Date().toLocaleString(),c=e.map(({item:r,index:o})=>{const l=Qe(o),f=r.label??`W${o+1}`,h=l.findings.map(g=>`<li>${ai(g.severity)} ${ge(g.summary)}</li>`).join("");return ii(ge(f),`<ul style="margin:0;padding-left:18px;list-style:none">${h}</ul>`)}).join(`
1
+ import{getUniqueTestNumbers as yn,resolveTestNumber as xn,findTestDef as wn}from"../renderer/buildView.js";import{getColorScheme as vn}from"../renderer/colorSchemes.js";import{metadataValueColor as Cn}from"../renderer/colorMap.js";import{resolveCanvasTheme as Sn}from"./canvasTheme.js";import{ICONS as pe}from"./icons.js";import{CLR as m,sevColor as Mt,BIN_LEGEND_MODES as Mn,STACKED_MODES as ue,Z_ABOVE as kt,applyOverlayZ as kn,getTooltip as Bn,hideTooltip as Bt,createToolbarHelpers as En,buildModeMenuEl as On,openDetachWindow as Dn,openFloatingWindow as Tn,openModal as Wn,copyWmapThemeTokens as Ln,syncWmapPopupTheme as In,openUserGuideWindow as Rn,makePaletteBtn as Pn,makeLogScaleBtn as An,makeLegendStyleBtn as Fn,makeOverlaysBtn as Hn,makeOrientationBtn as $n,overlayRootFor as Et,saveImageBlob as jn,markMenuTrigger as me,wireMenuA11y as Ot,wireExpandToggle as Dt,passFailMenuRows as zn,requestedPassFailDisplay as Ge,logWmapVersionOnce as Nn,buildDataModeEntries as Vn,metadataKeyHasData as _n,metadataModeEntry as Gn}from"./toolbar.js";import{aggregateValues as Kn,aggregateBinCounts as Tt}from"../core/aggregates.js";import{renderWaferMap as Ke}from"./renderWaferMap.js";import{classifyChanged as qn}from"./renderWaferMap.js";import{buildWaferMap as Xn,getTestPassStatus as Un,isParametricTest as Wt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ee}from"../stats/analyzeWaferMap.js";import{collectWarnings as Yn,buildWarningsMenuEl as Qn,severityOf as Zn}from"./warnings.js";import{compareNatural as Jn}from"../core/utils.js";import{createSummaryPanelEl as qe,buildMetadataStripRow as ei,buildCompactMetadataRows as Lt,metadataEntries as It,renderLotSummaryContent as ti}from"./summaryPanel.js";import"../stats/facets.js";import{openHtmlReport as ni}from"../stats/renderFindingsReport.js";import{escHtml as ge,renderSection as ii,renderSeverityBadge as ai,reportStyles as oi}from"../stats/reportHtml.js";import{createInsightsTab as li}from"./insightsTab.js";import{getDieKey as si,hasPosition as ri}from"../core/dies.js";function Oe(S){const B=new Set;return S.filter(p=>B.has(p.bin)?!1:(B.add(p.bin),!0))}function Rt(S,B){const p=document.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:"2px 4px",borderRadius:"3px"});const Y=document.createElement("span");Object.assign(Y.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:B.color,border:B.isActive?`2px solid ${m.iconActive}`:`1px solid ${m.menuBorder}`,borderRadius:"2px",boxSizing:"border-box"});const te=document.createElement("span");te.textContent=B.label,Object.assign(te.style,{fontWeight:B.isActive?"700":"400",color:B.isActive?m.iconActive:m.text,whiteSpace:"nowrap"}),p.appendChild(Y),p.appendChild(te),p.setAttribute("role","button"),p.setAttribute("aria-pressed",B.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=m.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=m.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",B.onClick),p.addEventListener("keydown",L=>{(L.key==="Enter"||L.key===" ")&&(L.preventDefault(),B.onClick())}),S.appendChild(p)}export function renderWaferGallery(S,B,p={}){Nn();const Y=p.cardPadding??6,te=p.downloadFilename??"wafer-gallery";let L=p.columns;const Pt=p.showPlotModeSelector??!0,At=p.showHelpButton??!1,Ft=p.userGuideExtension,Xe=p.insights?.enabled??!1,Ht=kn(p.zIndex),Q=p.summaryPanel,Ue=p.passBins??[1];let he=p.fallbackFormat,D=p.lotStatsSummary,ne=p.legendPosition??"default",d={plotMode:"hardBin",colorScheme:"default",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},w=[],q=[],Z=[],M=[],y=B.map(e=>typeof e=="function"?null:e),De=0,be=0;const R=new Map;let $t=0,T=null,ie=null,Ye=new Set,u=null,ae="lot",jt={};function Qe(e){return y[e]?.statsSummary??D?.perWafer.find(t=>t.waferIndex===e)?.summary}function ye(){return!!(y.some(e=>e?.statsSummary?.findings.length)||D?.perWafer.some(e=>e.summary.findings.length))}const zt=Bn(),J=En(zt),{makeBtn:V,setActive:oe,makeSep:P,makeMenuRow:Nt,makeMenuSection:Vt,makeDropdown:Ze,makeCheckMenuBtn:di,closeOpenMenu:xe,getOpenMenu:le,setOpenMenu:se}=J;S.ownerDocument.addEventListener("click",xe,!0);const Je=()=>Bt();window.addEventListener("blur",Je);function Te(e){Ye=new Set(e);const t=[...O.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((i,s)=>{const c=Ye.has(s);i.style.outline=c?`3px solid ${m.findingHighlight}`:"",i.style.outlineOffset=c?"-3px":"",c&&n===void 0&&(n=i)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function We(){Te([])}function Le(){for(const e of w)e&&e.clearSelection()}function Ie(e,t){const n=new Set(e),i=t??w.map((s,c)=>c);for(const s of i){const c=M[s],a=w[s];if(!c||!a)continue;const r=c.dies.filter(o=>n.has(si(o)));a.setSelection(r)}}function et(){const e=document.createElement("div");Object.assign(e.style,{display:"flex",gap:"4px",marginBottom:"10px",borderBottom:`1px solid ${m.menuBorder}`,paddingBottom:"8px"});for(const t of["lot","wafers"]){const n=document.createElement("button");n.type="button",n.textContent=t==="lot"?"Lot":"Wafers";const i=ae===t;Object.assign(n.style,{border:"none",borderRadius:"4px",padding:"2px 8px",fontSize:"11px",cursor:"pointer",fontWeight:i?"600":"400",background:i?m.bgActive:"transparent",color:i?m.iconHover:m.icon}),n.addEventListener("click",()=>{ae=t,We(),Le(),I()}),e.appendChild(n)}return e}function _t(){if(!u)return;u.innerHTML="",D&&u.appendChild(et());const e=[];for(let n=0;n<y.length;n++){const i=y[n];if(!i)continue;const s=Qe(n)?.findings??[];if(!s.length)continue;const c=s.filter(r=>r.severity==="unusual").length,a=s.filter(r=>r.severity==="notable").length;e.push({index:n,item:i,unusualCount:c,notableCount:a,totalCount:s.length})}if(e.length>0){const n=document.createElement("button");n.type="button",n.textContent="Findings report",Object.assign(n.style,{border:`1px solid ${m.menuBorder}`,borderRadius:"4px",padding:"3px 8px",marginBottom:"10px",fontSize:"10px",color:m.iconHover,background:"none",cursor:"pointer",display:"block",width:"100%",textAlign:"left"}),n.addEventListener("click",()=>{const i=`Findings report \u2014 ${e.length} wafer${e.length>1?"s":""}`,s=new Date().toLocaleString(),c=e.map(({item:r,index:o})=>{const l=Qe(o),f=r.label??`W${o+1}`,h=l.findings.map(g=>`<li>${ai(g.severity)} ${ge(g.summary)}</li>`).join("");return ii(ge(f),`<ul style="margin:0;padding-left:18px;list-style:none">${h}</ul>`)}).join(`
2
2
  `),a=`<!DOCTYPE html>
3
3
  <html lang="en">
4
4
  <head>
@@ -17,4 +17,4 @@ ${oi()}
17
17
  ${c}
18
18
  </main>
19
19
  </body>
20
- </html>`;ni(a)}),p.appendChild(n)}if(e.length===0){const n=document.createElement("div");Object.assign(n.style,{color:m.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",p.appendChild(n)}else for(const{index:n,item:i,unusualCount:s,notableCount:c,totalCount:a}of e){const r=s?"unusual":c?"notable":"info",o=s+c||a,l=document.createElement("button");l.type="button",Object.assign(l.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:"4px",border:"none",borderLeft:`3px solid ${Mt(r)}`,borderRadius:"3px",background:m.bgHover,cursor:"pointer",fontSize:"11px",textAlign:"left",boxSizing:"border-box"}),l.addEventListener("mouseover",()=>{l.style.background=m.bgActive}),l.addEventListener("mouseout",()=>{l.style.background=m.bgHover});const f=document.createElement("span");f.textContent=i.label??`W${n+1}`,Object.assign(f.style,{color:m.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const h=document.createElement("span");h.textContent=String(o),Object.assign(h.style,{marginLeft:"6px",flexShrink:"0",background:Mt(r),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),l.appendChild(f),l.appendChild(h),l.addEventListener("click",()=>ke(n,i)),p.appendChild(l)}const t=document.createElement("div");t.style.height="12px",p.appendChild(t)}function I(){if(p)if(ae==="lot"&&D){const e=Oe(y.flatMap(n=>n?.hbinDefs??[])),t=Oe(y.flatMap(n=>n?.sbinDefs??[]));ti(p,{lotSummary:D,items:y,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:y.find(n=>n?.testDefs?.length)?.testDefs,passBins:Ue,ringCount:d.ringCount,colorScheme:d.colorScheme,fallbackFormat:he,activeFindingId:ie,warnings:u.warnings?.display??!0?_:[],findingsFilter:jt,onFindingsFilterChange:I,onSaveText:u.onSaveText,onFindingClick:(n,i)=>{ie===n.id?Re():Gt(n,i),I()},onWaferClick:n=>{Te([n])}}),ye()&&p.insertBefore(et(),p.firstChild)}else _t()}function tt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}function Re(){ie=null,We(),Le(),v({highlightBin:void 0},{fireCallback:!1})}function Gt(e,t){if(ie===e.id){Re();return}ie=e.id,t.style.background=m.bgActive,t.style.fontWeight="600";const{kind:n,index:i}=e.variable;n==="test"?v({plotMode:"value",activeTest:i??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?v({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):v({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1}),We(),Le();const s=e.highlight;if(s.kind==="wafer"){Te(s.waferIndices);const c=tt(e);for(const a of s.waferIndices){const l=M[a]?.statsSummary?.findings.find(f=>tt(f)===c)?.highlight?.dieKeys;l?.length&&Ie(l,[a])}}else s.kind==="bin"?s.dieKeys?.length&&Ie(s.dieKeys):(s.kind==="region"||s.kind==="dies")&&s.dieKeys?.length&&Ie(s.dieKeys)}function X(){if(!T)return;const e=!!p;T.style.display=(D||ye())&&e&&!Ae?"flex":"none";const t=p?p.style.display!=="none":!1;(D?.hasNotableFindings||y.some(i=>i?.statsSummary?.hasNotableFindings))&&!t?T.style.color=m.findingIndicator:T.dataset.active||(T.style.color=m.icon)}const E=document.createElement("div");E.dataset.wmapToolbar="gallery",Object.assign(E.style,{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"6px",padding:"3px 4px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const nt=()=>{const e=le();e&&(e.remove(),se(null)),me($,!1)},$=V("mode","Plot mode",()=>{if(le()){nt();return}const e=y.flatMap(g=>g?.dies??[]),t=y.find(g=>g?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:i,stackedEntries:s}=Vn(e,t,{includeStacked:!0}),c=d.plotMode??"hardBin",a=d.activeTest??0;function r(g){return g.plotMode!==c?!1:g.plotMode==="value"?a===(g.activeTest??0):g.plotMode==="metadata"?d.activeMetadataKey===g.activeMetadataKey:!0}function o(g,k){g.activeTest!==void 0?v({plotMode:"value",activeTest:g.activeTest,activeMetadataKey:void 0,logScale:g.logScale}):g.activeMetadataKey!==void 0?v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:g.activeMetadataKey,passFailDisplay:"off"}):v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),k.remove(),se(null),me($,!1)}const l=new Set,f=y.flatMap(g=>g?.metadataFields??[]).filter(g=>!l.has(g.key)&&l.add(g.key)).filter(g=>_n(e,g.key)).map(Gn),h=On($.getBoundingClientRect(),n,i,s,r,o,{makeMenuRow:Nt,makeMenuSection:Vt},c,$.ownerDocument.defaultView??window,f);Et($).appendChild(h),se(h),me($,!0),Ot(h,$,nt)});me($,!1);const Kt=()=>M.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:qt,sync:it}=Pn(Z,()=>d.plotMode??"hardBin",()=>d.colorScheme??"default",Kt,e=>v({colorScheme:e}));it();const Xt=B.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Pe(){const e=y.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=xn(d.activeTest??0,e);return{testNumber:t,td:wn(e,t)}}function at(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function re(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&!Wt(e)}function Ut(){if((d.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Pe();return y.some(n=>n?.dies?.some(i=>Un(i,e,t)!==void 0))}const Yt=Hn(Z,()=>[{label:"Ring boundaries",active:!!d.showRingBoundaries,onClick:()=>v({showRingBoundaries:!d.showRingBoundaries})},{label:"Quadrant lines",active:!!d.showQuadrantBoundaries,onClick:()=>v({showQuadrantBoundaries:!d.showQuadrantBoundaries})},{label:"Die labels",active:!!d.showDieLabels,onClick:()=>v({showDieLabels:!d.showDieLabels})},{label:"Reticle grid",active:!!d.showReticle,enabled:Xt,onClick:()=>v({showReticle:!d.showReticle})},{label:"XY indicator",active:!!d.showXYIndicator,onClick:()=>v({showXYIndicator:!d.showXYIndicator})},...zn({functionalActive:re(),hasLimits:at()&&!re(),hasRecorded:Ut()&&!re(),display:Ge(d)},e=>v({passFailDisplay:e}))],()=>!!(d.showRingBoundaries||d.showQuadrantBoundaries||d.showDieLabels||d.showReticle||d.showXYIndicator||Ge(d)!=="off")),{btn:Qt,sync:ot}=Fn(Z,()=>({plotMode:d.plotMode,legendPosition:ne}),e=>{ne=e;for(const t of w)t&&t.setOptions({legendPosition:ne})});ot();const Zt=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],lt=Ze("aggr","Aggregation method",()=>Zt,()=>d.aggregationMethod??"mean",e=>v({aggregationMethod:e}));function st(){const e=d.plotMode==="stackedValues";lt.style.display=e?"":"none"}st();const{btn:Jt,sync:rt}=An(Z,()=>({...d,functionalActive:re()}),e=>v(e));rt();const we=V("specRange","Colorbar range: spec limits",()=>{const e=d.colorbarRangeMode==="data"?"spec":"data";v({colorbarRangeMode:e})});function dt(){const e=(d.plotMode??"hardBin")==="value"&&at()&&Ge(d)==="off"&&!re();we.style.display=e?"":"none";const t=(d.colorbarRangeMode??"spec")==="spec";oe(we,t),we.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}dt();const en=$n(Z,()=>d,e=>v(e)),tn=V("downloadAll","Download gallery PNG",hn),nn=Ze("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>L!=null?String(L):"auto",e=>xt(e==="auto"?void 0:Number(e))),C=document.createElement("div");Object.assign(C.style,{display:"inline-flex",alignItems:"center",gap:"0"}),E.appendChild(C),Pt&&C.appendChild($),C.appendChild(qt),C.appendChild(lt),C.appendChild(Jt),C.appendChild(we),C.appendChild(P()),C.appendChild(Yt),C.appendChild(P()),C.appendChild(Qt),C.appendChild(P()),C.appendChild(en),C.appendChild(P()),C.appendChild(nn),C.appendChild(P()),C.appendChild(tn),(D||ye())&&(T=V("findings","Summary panel",()=>{if(!p)return;const e=p.style.display!=="none";e||I(),p.style.display=e?"none":"flex",oe(T,!e),X()}),E.appendChild(P()),E.appendChild(T));let j=null,ve=null,_=[],ct=!1;function ft(){const e=Yn({lotStatsSummary:D,result:{warnings:y.flatMap(n=>n?.warnings??[])}}),t=e.length!==_.length||e.some((n,i)=>n.code!==_[i]?.code||n.message!==_[i]?.message);_=e,(t||!ct)&&(ct=!0,u.warnings?.onWarning?.(e)),an()}function an(){if(!j||!ve)return;const e=_.length,t=e>0;if(j.style.display=t?"flex":"none",ve.style.display=t?"":"none",!t)return;const n=Zn(_[0]),i=`${e} data ${e===1?"warning":"warnings"}`;j.style.color=n==="error"?m.errText:m.warnText,j.ariaLabel=n==="error"?`${i} \u2014 wafers in this lot may be positionally wrong`:i}(u.warnings?.display??!0)&&(ve=P(),j=V("warning","Data warnings",()=>{const e=le();if(xe(new MouseEvent("click")),e)return;const t=Qn(j.getBoundingClientRect(),_);Et(S).appendChild(t),se(t),Ot(t,j,()=>xe(new MouseEvent("click")))}),me(j,!1),E.appendChild(ve),E.appendChild(j)),ft();let J=null;Xe&&(J=V("analysis","Insights",()=>{const e=ee?.style.display!=="none";ut(!e)}),E.appendChild(P()),E.appendChild(J));function pt(){import("./userGuideHtml.js").then(e=>Rn({buildWaferMap:Xn,renderWaferMap:Ke,renderWaferGallery,analyzeWaferMap:Ee},e.USER_GUIDE_HTML,Ft,S))}At&&(E.appendChild(P()),E.appendChild(V("help","User guide",()=>pt())));const G=document.createElement("div");Object.assign(G.style,{display:"flex",flexDirection:"column",gap:"6px",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"6px",padding:"6px 10px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"});const A=document.createElement("div");Object.assign(A.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let de=null,ee=null;Xe&&(de=li({getItems:()=>y,getLotStats:()=>D,getColorSchemeName:()=>d.colorScheme??"default",passBins:Ue,getRingCount:()=>d.ringCount??4,defaultView:u.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>ut(!1)},showMetadataStrip:!1,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,openWafer:(e,t,n)=>{const i=y[e];if(!i)return;let s=null;const c=Wn({title:t,onClose:()=>s?.destroy(),anchor:S});vt(c,t,i.wafer.metadata??void 0),s=ze(c.contentWrap,i,n)}}),ee=de.el);let Ae=!1;function ut(e){!de||!ee||(Ae=e,ee.style.display=e?"flex":"none",A.style.display=e?"none":"flex",C.style.display=e?"none":"inline-flex",J&&(oe(J,e),J.innerHTML=e?pe.wafer:pe.analysis,J.ariaLabel=e?"Back to gallery view":"Insights"),X(),Me(),e&&de.render())}const on=4,Fe=240,mt=480,ln=720,sn=1.25,gt=u.maxSize;let z=gt??mt;function ht(e){const t=U*2+110+2;let n=null;for(const i of e){if(i==null||!i.dies?.length)continue;const s=i.dies[0].width;if(!(s>0))continue;const c=i.wafer.radius*2*(on/s),a=Math.ceil(c+t);(n==null||a>n)&&(n=a)}return n}function rn(e){const t=ht(e);return t==null?Fe:Math.min(z,Math.max(Fe,t))}function dn(e){if(gt!=null)return!1;const t=ht(e);if(t==null)return!1;const n=Math.min(ln,Math.max(mt,t));return n<=z?!1:(z=n,!0)}function cn(){for(const e of Array.from(O.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${z}px`,e.style.maxHeight=`${z}px`)}let Ce=Fe,bt=0;function yt(e){const t=dn(e);if(t&&cn(),L!=null){t&&Se();return}const n=rn(e);n>Ce&&(Ce=n),Se()}function xt(e){L=e,Se()}function He(e){return`repeat(${e}, minmax(0, ${z}px))`}function Se(){if(L!=null){O.style.gridTemplateColumns=He(L);return}const e=Math.max(1,bt),t=12,n=O.clientWidth||0,i=c=>(n-t*(c-1))/c;let s=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){for(;s>1&&i(s)<Ce;)s--;const c=Math.min(z,Ce*sn);for(;s<e&&i(s+1)>=c;)s++}O.style.gridTemplateColumns=He(s)}const O=document.createElement("div");if(Object.assign(O.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:He(1),gap:"12px",justifyContent:"start",alignContent:"start"}),ae=D?"lot":"wafers",Y?.placement){const e=Y.placement;p=qe(e),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.display="flex",p.style.flexDirection="column"}else if(D||ye()){const e=!!Y?.defaultOpen;p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display=e?"flex":"none",I()}X(),p?.style.display!=="none"&&T&&oe(T,!0),(Y?.placement??"right")==="left"?(p&&A.appendChild(p),A.appendChild(O)):(A.appendChild(O),p&&A.appendChild(p)),S.appendChild(E),S.appendChild(G),S.appendChild(A),ee&&S.appendChild(ee);function Me(){G.innerHTML="";const e=d.plotMode??"hardBin",t=!Ae&&Mn.has(e),n=M.filter(b=>b!=null),i=n.find(b=>b.isLotStack),s=ei(n.map(b=>({metadata:b.wafer.metadata??void 0})),i?{lotSize:i.lotSize??n.length,aggrMethod:i.aggrMethod}:void 0),c=e==="metadata",a=d.activeMetadataKey,r=new Set;if(t&&!c)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=e==="softBin"?W.sbin:W.hbin;x!=null&&r.add(x)}const o=t&&!c?[...r].sort((b,W)=>b-W):[],l=new Set;if(t&&c&&a)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=W.metadata?.[a];x!=null&&(typeof x=="string"||typeof x=="number"||typeof x=="boolean")&&l.add(String(x))}const f=t&&c?[...l].sort(Jn):[];if(!s&&!o.length&&!f.length){G.style.display="none";return}if(G.style.display="flex",s&&G.appendChild(s),!o.length&&!f.length)return;const h=document.createElement("div");Object.assign(h.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),s&&Object.assign(h.style,{borderTop:`1px solid ${m.separator}`,paddingTop:"6px"}),G.appendChild(h);const g=vn(d.colorScheme),k=d.highlightBin;if(c){const b=d.highlightMetadataValue,W=M.flatMap(x=>x?.metadataFields??[]).find(x=>x.key===a);f.forEach((x,Ne)=>{const Ve=b===x,St=W?.values?.find(_e=>_e.value===x),bn=St?.color??Cn(Ne);Rt(h,{color:bn,isActive:Ve,label:St?.label??x,onClick:()=>{const _e=d.highlightMetadataValue===x?void 0:x;v({highlightMetadataValue:_e})}})});return}const F=e==="softBin"?M.flatMap(b=>b?.sbinDefs??[]):M.flatMap(b=>b?.hbinDefs??[]),H=new Set,K=[];for(const b of F)H.has(b.bin)||(H.add(b.bin),K.push(b));const fe=K.length>0?new Map(K.map(b=>[b.bin,b])):null;for(const b of o){const W=k===b,x=fe?.get(b),Ne=(d.colorScheme==="custom"?x?.color:void 0)??g.forBin(b);Rt(h,{color:Ne,isActive:W,label:x?.name?`${b} \xB7 ${x.name}`:`Bin ${b}`,onClick:()=>{const Ve=d.highlightBin===b?void 0:b;v({highlightBin:Ve})}})}}function ce(e){const t=y.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(ri)),i=t[0].wafer,s=t.length,c=i.metadata?{...i,metadata:(({wafer:r,waferId:o,...l})=>l)(i.metadata)}:i;function a(r,o){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:o,lotSize:s}}}if(e==="stackedValues"){const r=t.find(f=>f.testDefs?.length)?.testDefs;let o=r?.filter(Wt);if(r?.length||(o=yn(t.flatMap(h=>h.dies)).map(h=>({testNumber:h,name:`Test ${h}`}))),!o?.length)return[];const l=d.aggregationMethod??"mean";return o.map(f=>{const h=Kn(n,l,f.testNumber),g={testNumber:0,name:f.name,unit:f.unit};return{wafer:c,dies:h,testDefs:[g],label:`${f.name} \xB7 ${l}`,isLotStack:!0,aggrMethod:l,lotSize:s,statsSummary:a(Ee({wafer:c,dies:h,testDefs:[g]},{testNumbers:[0]}),l)}})}if(e==="stackedBins"){let r=Oe(t.flatMap(o=>o.hbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(o=>{const l=Tt(n,o.bin,"hard"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,hbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let r=Oe(t.flatMap(o=>o.sbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(o=>{const l=Tt(n,o.bin,"soft"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,sbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,sbinDefs:f}),"countBin")}})}return t}function $e(e){const t=y.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:d.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}const fn=new Set(["default","accessible","custom"]);function v(e,{fireCallback:t=!0}={}){const n=d.plotMode;d={...d,...e};const i=d.plotMode,s=ue.has(i),c=n!==void 0&&ue.has(n),a=be>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(i==="hardBin"||i==="softBin")&&!fn.has(d.colorScheme??"")&&(d={...d,colorScheme:"default"}),e.plotMode!==void 0)if(s){const o=$e(i);if(d={...d,...o},a)for(const l of w)l&&l.setOptions(e);else N(ce(i))}else if(c){const{valueRange:o,lotSize:l,aggregationMethod:f,...h}=d;if(d=h,a)for(const g of w)g&&g.setOptions(e);else N(y.filter(g=>g!==null))}else for(const o of w)o&&o.setOptions(e);else if(e.aggregationMethod!==void 0&&i==="stackedValues")if(a)for(const o of w)o&&o.setOptions(e);else N(ce("stackedValues"));else for(const o of w)o&&o.setOptions(e);Me(),st(),ot(),it();const r=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||r)&&I(),rt(),dt(),t){const o=Object.keys(e);u.onViewOptionsChange?.(d,o,qn(o))}}function wt(e,t,n){const i=e.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0"});const s=e.createElement("span");s.textContent=t,Object.assign(s.style,{fontWeight:"700",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),i.appendChild(s);const c=It(n??{});let a=null;if(c.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",i.appendChild(r),Object.assign(i.style,{cursor:"pointer"}),a=e.createElement("div"),a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const o=Lt(n??{});o&&a.appendChild(o),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Dt(i,l=>{r.textContent=l?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(l)),a&&(a.style.display=l?"block":"none")})}return{wrap:i,metaPanel:a}}function vt(e,t,n){const i=e.box.querySelector("[data-wmap-window-title]"),s=It(n??{});if(!i||s.length===0)return;const c=i.parentElement,a=document.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),c?.insertBefore(a,i),a.appendChild(i);const r=document.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",a.appendChild(r);const o=document.createElement("div");o.dataset.wmapCardMetaPanel="1",Object.assign(o.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const l=Lt(n??{});l&&o.appendChild(l),e.contentWrap.style.position="relative",e.contentWrap.appendChild(o),a.setAttribute("aria-expanded","false"),a.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Dt(a,f=>{r.textContent=f?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(f)),o.style.display=f?"block":"none"})}function je(e,t,n){const i=document.createElement("div");i.className="wmap-gallery-card",Object.assign(i.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${z}px`,maxHeight:`${z}px`});const s=document.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:c,metaPanel:a}=wt(document,e.label??"",e.wafer.metadata??void 0);s.appendChild(c);const r=document.createElement("button");r.dataset.wmapExpandBtn="1",r.title="Open full view",r.innerHTML=pe.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${m.menuBorder}`,borderRadius:"4px",background:m.panelBg,color:m.label,padding:"2px",cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),s.appendChild(r),i.appendChild(s);const o=document.createElement("div");Object.assign(o.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),i.appendChild(o),a&&o.appendChild(a),O.appendChild(i);const l=Ke(o,e,{viewOptions:e.viewOptions?{...d,...e.viewOptions}:d,toolbarControls:"full",showTooltip:!0,padding:U,legendPosition:ne,fallbackFormat:he,statsSummary:e.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>ke(t,e),showMetadataBadge:!1});return l.setViewControlsVisible(!1),l.setSummaryVisible(!1),r.onclick=()=>ke(t,e),{card:i,ctrl:l,canvasWrapper:o,expandBtn:r}}function pn(e){const t=Q[e];if(!t)return;const n=[...R.values()].find(i=>i.cardIndex===e);n?(t.innerHTML=pe.minimize,t.title="Reattach to gallery",t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>mn(n.id)):(t.innerHTML=pe.expand,t.title="Open full view",t.setAttribute("aria-label","Open full view"),t.onclick=()=>ke(e,M[e]))}function N(e){gn(),le()?.remove(),se(null),Re(),M=[];for(const a of w)a&&a.destroy();w=[],q=[],Q=[],be=0,O.innerHTML="",bt=e.length,yt(e.map(a=>typeof a=="function"?null:a));const t=[];for(let a=0;a<e.length;a++){const r=e[a];if(typeof r=="function"){const o=document.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const l=document.createElement("span");l.textContent="\u2026",Object.assign(l.style,{color:m.label,fontSize:"18px"}),o.appendChild(l),O.appendChild(o),M.push(null),w.push(null),q.push(null),Q.push(null),t.push({index:a,factory:r,placeholder:o}),be++}else{const{ctrl:o,canvasWrapper:l,expandBtn:f}=je(r,a,e.length);M.push(r),w.push(o),q.push(l),Q.push(f)}}M.flatMap(a=>a?[...a.hbinDefs??[],...a.sbinDefs??[]]:[]).some(a=>a.color)&&!u.viewOptions?.colorScheme&&(d={...d,colorScheme:"custom"}),Me();const i=++De;let s=0;function c(){if(i!==De)return;if(s>=t.length){if(ue.has(d.plotMode)){const F=d.plotMode;N(ce(F))}return}const{index:a,factory:r,placeholder:o}=t[s++],l=r();M[a]=l,y[a]=l,yt([l]);const{card:f,ctrl:h,canvasWrapper:g,expandBtn:k}=je(l,a,e.length);w[a]=h,q[a]=g,Q[a]=k,be--,o.replaceWith(f),Me(),!p&&!Y?.placement&&l.statsSummary?.findings.length?(D||(ae="wafers"),p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display="none",(Y?.placement??"right")==="left"?A.insertBefore(p,O):A.appendChild(p),I(),T||(T=V("findings","Summary panel",()=>{if(!p)return;const H=p.style.display!=="none";H||I(),p.style.display=H?"none":"flex",oe(T,!H),X()}),E.appendChild(P()),E.appendChild(T)),X()):p&&p.style.display!=="none"&&I(),X(),setTimeout(c,0)}t.length>0&&setTimeout(c,0)}if(ue.has(d.plotMode)&&y.length>0){const e=$e(d.plotMode);d={...d,...e},N(ce(d.plotMode))}else N(B);const Ct=new ResizeObserver(()=>{L==null&&Se()});Ct.observe(O),p&&I();function un(e){const t=q[e];if(!t)return;t.innerHTML="",Object.assign(t.style,{alignItems:"center",justifyContent:"center"});const n=document.createElement("span");n.textContent="Detached \u2014 open in its own window",Object.assign(n.style,{color:m.label,fontSize:"12px",textAlign:"center",padding:"0 12px"}),t.appendChild(n)}function ke(e,t){for(const a of R.values())if(a.cardIndex===e)return;const n=t.label??"Wafer map",i=$t++,s=w[e]?.getOptions(),c=Dn(n);if(c){const a=c.document;a.title=n,Object.assign(a.documentElement.style,{height:"100%"}),Object.assign(a.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),Ln(S,a.documentElement);const r=In(S,a.documentElement,()=>F.setOptions({})),o=a.createElement("div");o.dataset.wmapWindowBanner="1",o.textContent=n,Object.assign(o.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:m.warnBg,color:m.warnText,borderBottom:`1px solid ${m.warnBorder}`,flexShrink:"0"}),a.body.appendChild(o);const l=a.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),a.body.appendChild(l);const{wrap:f,metaPanel:h}=wt(a,n,t.wafer.metadata??void 0),g=a.createElement("div");Object.assign(g.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"}),g.appendChild(f),l.appendChild(g);const k=a.createElement("div");Object.assign(k.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),h&&k.appendChild(h),l.appendChild(k);const F=ze(k,t,void 0,s),H=setInterval(()=>{c.closed&&Be(i)},400);c.addEventListener("pagehide",()=>Be(i)),R.set(i,{id:i,ctrl:F,cardIndex:e,label:n,closePollId:H,stopThemeSync:r,close:()=>{c.closed||c.close()},setTitle:K=>{a.title=K,o.textContent=K,o.style.display="block"}})}else{const a=Tn({title:n,onClose:()=>Be(i),anchor:S});a.contentWrap.style.flexDirection="column",vt(a,n,t.wafer.metadata??void 0);const r=ze(a.contentWrap,t,void 0,s);R.set(i,{id:i,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>a.close(),setTitle:o=>{const l=a.box.querySelector("[data-wmap-window-title]");l&&(l.textContent=o,l.title=o)}})}w[e]?.destroy(),w[e]=null,un(e),pn(e)}function ze(e,t,n,i){const s=t.viewOptions?{...d,...t.viewOptions}:d,c=i?{...s,...i}:s,a=n!==void 0?{...c,plotMode:"value",activeTest:n}:c,r=Ke(e,t,{viewOptions:a,toolbarControls:"full",showTooltip:!0,padding:U,legendPosition:ne,fallbackFormat:he,statsSummary:t.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return r.setViewControlsVisible(!0),r.setSummaryVisible(!0),r.setExpandVisible(!1),r}function Be(e){const t=R.get(e);if(!t)return;R.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const i=t.cardIndex,s=M[i];if(!s)return;const c={...s,viewOptions:n};M[i]=c;const{card:a,ctrl:r,canvasWrapper:o,expandBtn:l}=je(c,i,M.length);q[i]?.parentElement?.replaceWith(a),w[i]=r,q[i]=o,Q[i]=l}function mn(e){const t=R.get(e);t&&(t.close(),Be(e))}function gn(){for(const e of R.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function hn(){const e=[...O.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),i=Math.ceil(t/n),s=e[0].width,c=e[0].height,a=8,r=window.devicePixelRatio||1,o=Math.round(26*r),l=Math.round(12*r),f=document.createElement("canvas");f.width=n*s+(n-1)*a,f.height=i*(c+o)+(i-1)*a;const h=f.getContext("2d"),g=Sn(O);h.fillStyle=g.background,h.fillRect(0,0,f.width,f.height),e.forEach((k,F)=>{const H=F%n,K=Math.floor(F/n),fe=H*(s+a),b=K*(c+o+a),W=k.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";h.fillStyle=g.surface,h.fillRect(fe,b,s,o),h.fillStyle=g.text,h.font=`700 ${l}px system-ui, sans-serif`,h.textAlign="left",h.textBaseline="middle",h.fillText(W,fe+Math.round(10*r),b+o/2,s-Math.round(20*r)),h.drawImage(k,fe,b+o)}),f.toBlob(k=>{k&&jn(k,te,u.onSaveImage)})}return{setItems(e){y=e.map(n=>typeof n=="function"?null:n);const t=d.plotMode;if(ue.has(t))if(e.some(i=>typeof i=="function"))N(e);else{const i=$e(t);d={...d,...i},N(ce(t))}else N(e)},setOptions(e){v(e,{fireCallback:!1})},getOptions(){return{...d}},setFallbackFormat(e){he=e;for(const t of w)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){D=e,ft(),p&&I(),X()},setColumns(e){xt(e)},openUserGuide:pt,destroy(){De++;for(const e of[...R.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();R.clear();for(const e of w)e&&e.destroy();w=[],le()?.remove(),Ct.disconnect(),S.ownerDocument.removeEventListener("click",xe,!0),window.removeEventListener("blur",Je),Ht(),Bt(),E.remove(),G.remove(),A.remove(),p?.remove(),de?.destroy()}}}
20
+ </html>`;ni(a)}),u.appendChild(n)}if(e.length===0){const n=document.createElement("div");Object.assign(n.style,{color:m.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",u.appendChild(n)}else for(const{index:n,item:i,unusualCount:s,notableCount:c,totalCount:a}of e){const r=s?"unusual":c?"notable":"info",o=s+c||a,l=document.createElement("button");l.type="button",Object.assign(l.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:"4px",border:"none",borderLeft:`3px solid ${Mt(r)}`,borderRadius:"3px",background:m.bgHover,cursor:"pointer",fontSize:"11px",textAlign:"left",boxSizing:"border-box"}),l.addEventListener("mouseover",()=>{l.style.background=m.bgActive}),l.addEventListener("mouseout",()=>{l.style.background=m.bgHover});const f=document.createElement("span");f.textContent=i.label??`W${n+1}`,Object.assign(f.style,{color:m.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const h=document.createElement("span");h.textContent=String(o),Object.assign(h.style,{marginLeft:"6px",flexShrink:"0",background:Mt(r),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),l.appendChild(f),l.appendChild(h),l.addEventListener("click",()=>ke(n,i)),u.appendChild(l)}const t=document.createElement("div");t.style.height="12px",u.appendChild(t)}function I(){if(u)if(ae==="lot"&&D){const e=Oe(y.flatMap(n=>n?.hbinDefs??[])),t=Oe(y.flatMap(n=>n?.sbinDefs??[]));ti(u,{lotSummary:D,items:y,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:y.find(n=>n?.testDefs?.length)?.testDefs,passBins:Ue,ringCount:d.ringCount,colorScheme:d.colorScheme,fallbackFormat:he,activeFindingId:ie,warnings:p.warnings?.display??!0?_:[],findingsFilter:jt,onFindingsFilterChange:I,onSaveText:p.onSaveText,onFindingClick:(n,i)=>{ie===n.id?Re():Gt(n,i),I()},onWaferClick:n=>{Te([n])},dieListOptions:p.dieList}),ye()&&u.insertBefore(et(),u.firstChild)}else _t()}function tt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}function Re(){ie=null,We(),Le(),v({highlightBin:void 0},{fireCallback:!1})}function Gt(e,t){if(ie===e.id){Re();return}ie=e.id,t.style.background=m.bgActive,t.style.fontWeight="600";const{kind:n,index:i}=e.variable;n==="test"?v({plotMode:"value",activeTest:i??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?v({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):v({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1}),We(),Le();const s=e.highlight;if(s.kind==="wafer"){Te(s.waferIndices);const c=tt(e);for(const a of s.waferIndices){const l=M[a]?.statsSummary?.findings.find(f=>tt(f)===c)?.highlight?.dieKeys;l?.length&&Ie(l,[a])}}else s.kind==="bin"?s.dieKeys?.length&&Ie(s.dieKeys):(s.kind==="region"||s.kind==="dies")&&s.dieKeys?.length&&Ie(s.dieKeys)}function X(){if(!T)return;const e=!!u;T.style.display=(D||ye())&&e&&!Ae?"flex":"none";const t=u?u.style.display!=="none":!1;(D?.hasNotableFindings||y.some(i=>i?.statsSummary?.hasNotableFindings))&&!t?T.style.color=m.findingIndicator:T.dataset.active||(T.style.color=m.icon)}const E=document.createElement("div");E.dataset.wmapToolbar="gallery",Object.assign(E.style,{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"6px",padding:"3px 4px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const nt=()=>{const e=le();e&&(e.remove(),se(null)),me($,!1)},$=V("mode","Plot mode",()=>{if(le()){nt();return}const e=y.flatMap(g=>g?.dies??[]),t=y.find(g=>g?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:i,stackedEntries:s}=Vn(e,t,{includeStacked:!0}),c=d.plotMode??"hardBin",a=d.activeTest??0;function r(g){return g.plotMode!==c?!1:g.plotMode==="value"?a===(g.activeTest??0):g.plotMode==="metadata"?d.activeMetadataKey===g.activeMetadataKey:!0}function o(g,k){g.activeTest!==void 0?v({plotMode:"value",activeTest:g.activeTest,activeMetadataKey:void 0,logScale:g.logScale}):g.activeMetadataKey!==void 0?v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:g.activeMetadataKey,passFailDisplay:"off"}):v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),k.remove(),se(null),me($,!1)}const l=new Set,f=y.flatMap(g=>g?.metadataFields??[]).filter(g=>!l.has(g.key)&&l.add(g.key)).filter(g=>_n(e,g.key)).map(Gn),h=On($.getBoundingClientRect(),n,i,s,r,o,{makeMenuRow:Nt,makeMenuSection:Vt},c,$.ownerDocument.defaultView??window,f);Et($).appendChild(h),se(h),me($,!0),Ot(h,$,nt)});me($,!1);const Kt=()=>M.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:qt,sync:it}=Pn(J,()=>d.plotMode??"hardBin",()=>d.colorScheme??"default",Kt,e=>v({colorScheme:e}));it();const Xt=B.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Pe(){const e=y.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=xn(d.activeTest??0,e);return{testNumber:t,td:wn(e,t)}}function at(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function re(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&!Wt(e)}function Ut(){if((d.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Pe();return y.some(n=>n?.dies?.some(i=>Un(i,e,t)!==void 0))}const Yt=Hn(J,()=>[{label:"Ring boundaries",active:!!d.showRingBoundaries,onClick:()=>v({showRingBoundaries:!d.showRingBoundaries})},{label:"Quadrant lines",active:!!d.showQuadrantBoundaries,onClick:()=>v({showQuadrantBoundaries:!d.showQuadrantBoundaries})},{label:"Die labels",active:!!d.showDieLabels,onClick:()=>v({showDieLabels:!d.showDieLabels})},{label:"Reticle grid",active:!!d.showReticle,enabled:Xt,onClick:()=>v({showReticle:!d.showReticle})},{label:"XY indicator",active:!!d.showXYIndicator,onClick:()=>v({showXYIndicator:!d.showXYIndicator})},...zn({functionalActive:re(),hasLimits:at()&&!re(),hasRecorded:Ut()&&!re(),display:Ge(d)},e=>v({passFailDisplay:e}))],()=>!!(d.showRingBoundaries||d.showQuadrantBoundaries||d.showDieLabels||d.showReticle||d.showXYIndicator||Ge(d)!=="off")),{btn:Qt,sync:ot}=Fn(J,()=>({plotMode:d.plotMode,legendPosition:ne}),e=>{ne=e;for(const t of w)t&&t.setOptions({legendPosition:ne})});ot();const Zt=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],lt=Ze("aggr","Aggregation method",()=>Zt,()=>d.aggregationMethod??"mean",e=>v({aggregationMethod:e}));function st(){const e=d.plotMode==="stackedValues";lt.style.display=e?"":"none"}st();const{btn:Jt,sync:rt}=An(J,()=>({...d,functionalActive:re()}),e=>v(e));rt();const we=V("specRange","Colorbar range: spec limits",()=>{const e=d.colorbarRangeMode==="data"?"spec":"data";v({colorbarRangeMode:e})});function dt(){const e=(d.plotMode??"hardBin")==="value"&&at()&&Ge(d)==="off"&&!re();we.style.display=e?"":"none";const t=(d.colorbarRangeMode??"spec")==="spec";oe(we,t),we.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}dt();const en=$n(J,()=>d,e=>v(e)),tn=V("downloadAll","Download gallery PNG",hn),nn=Ze("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>L!=null?String(L):"auto",e=>xt(e==="auto"?void 0:Number(e))),C=document.createElement("div");Object.assign(C.style,{display:"inline-flex",alignItems:"center",gap:"0"}),E.appendChild(C),Pt&&C.appendChild($),C.appendChild(qt),C.appendChild(lt),C.appendChild(Jt),C.appendChild(we),C.appendChild(P()),C.appendChild(Yt),C.appendChild(P()),C.appendChild(Qt),C.appendChild(P()),C.appendChild(en),C.appendChild(P()),C.appendChild(nn),C.appendChild(P()),C.appendChild(tn),(D||ye())&&(T=V("findings","Summary panel",()=>{if(!u)return;const e=u.style.display!=="none";e||I(),u.style.display=e?"none":"flex",oe(T,!e),X()}),E.appendChild(P()),E.appendChild(T));let j=null,ve=null,_=[],ct=!1;function ft(){const e=Yn({lotStatsSummary:D,result:{warnings:y.flatMap(n=>n?.warnings??[])}}),t=e.length!==_.length||e.some((n,i)=>n.code!==_[i]?.code||n.message!==_[i]?.message);_=e,(t||!ct)&&(ct=!0,p.warnings?.onWarning?.(e)),an()}function an(){if(!j||!ve)return;const e=_.length,t=e>0;if(j.style.display=t?"flex":"none",ve.style.display=t?"":"none",!t)return;const n=Zn(_[0]),i=`${e} data ${e===1?"warning":"warnings"}`;j.style.color=n==="error"?m.errText:m.warnText,j.ariaLabel=n==="error"?`${i} \u2014 wafers in this lot may be positionally wrong`:i}(p.warnings?.display??!0)&&(ve=P(),j=V("warning","Data warnings",()=>{const e=le();if(xe(new MouseEvent("click")),e)return;const t=Qn(j.getBoundingClientRect(),_);Et(S).appendChild(t),se(t),Ot(t,j,()=>xe(new MouseEvent("click")))}),me(j,!1),E.appendChild(ve),E.appendChild(j)),ft();let U=null;Xe&&(U=V("analysis","Insights",()=>{const e=ee?.style.display!=="none";ut(!e)}),U.dataset.wmapInsightsBtn="1",E.appendChild(P()),E.appendChild(U));function pt(){import("./userGuideHtml.js").then(e=>Rn({buildWaferMap:Xn,renderWaferMap:Ke,renderWaferGallery,analyzeWaferMap:Ee},e.USER_GUIDE_HTML,Ft,S))}At&&(E.appendChild(P()),E.appendChild(V("help","User guide",()=>pt())));const G=document.createElement("div");Object.assign(G.style,{display:"flex",flexDirection:"column",gap:"6px",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"6px",padding:"6px 10px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"});const A=document.createElement("div");Object.assign(A.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let de=null,ee=null;Xe&&(de=li({getItems:()=>y,getLotStats:()=>D,getColorSchemeName:()=>d.colorScheme??"default",passBins:Ue,getRingCount:()=>d.ringCount??4,defaultView:p.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>ut(!1)},showMetadataStrip:!1,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,openWafer:(e,t,n)=>{const i=y[e];if(!i)return;let s=null;const c=Wn({title:t,onClose:()=>s?.destroy(),anchor:S});vt(c,t,i.wafer.metadata??void 0),s=ze(c.contentWrap,i,n)}}),ee=de.el);let Ae=!1;function ut(e){!de||!ee||(Ae=e,ee.style.display=e?"flex":"none",A.style.display=e?"none":"flex",C.style.display=e?"none":"inline-flex",U&&(oe(U,e),U.innerHTML=e?pe.wafer:pe.analysis,U.ariaLabel=e?"Back to gallery view":"Insights"),X(),Me(),e&&de.render())}const on=4,Fe=240,mt=480,ln=720,sn=1.25,gt=p.maxSize;let z=gt??mt;function ht(e){const t=Y*2+110+2;let n=null;for(const i of e){if(i==null||!i.dies?.length)continue;const s=i.dies[0].width;if(!(s>0))continue;const c=i.wafer.radius*2*(on/s),a=Math.ceil(c+t);(n==null||a>n)&&(n=a)}return n}function rn(e){const t=ht(e);return t==null?Fe:Math.min(z,Math.max(Fe,t))}function dn(e){if(gt!=null)return!1;const t=ht(e);if(t==null)return!1;const n=Math.min(ln,Math.max(mt,t));return n<=z?!1:(z=n,!0)}function cn(){for(const e of Array.from(O.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${z}px`,e.style.maxHeight=`${z}px`)}let Ce=Fe,bt=0;function yt(e){const t=dn(e);if(t&&cn(),L!=null){t&&Se();return}const n=rn(e);n>Ce&&(Ce=n),Se()}function xt(e){L=e,Se()}function He(e){return`repeat(${e}, minmax(0, ${z}px))`}function Se(){if(L!=null){O.style.gridTemplateColumns=He(L);return}const e=Math.max(1,bt),t=12,n=O.clientWidth||0,i=c=>(n-t*(c-1))/c;let s=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){for(;s>1&&i(s)<Ce;)s--;const c=Math.min(z,Ce*sn);for(;s<e&&i(s+1)>=c;)s++}O.style.gridTemplateColumns=He(s)}const O=document.createElement("div");if(Object.assign(O.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:He(1),gap:"12px",justifyContent:"start",alignContent:"start"}),ae=D?"lot":"wafers",Q?.placement){const e=Q.placement;u=qe(e),u.style.maxHeight="calc(100vh - 80px)",u.style.position="sticky",u.style.top="8px",u.style.display="flex",u.style.flexDirection="column"}else if(D||ye()){const e=!!Q?.defaultOpen;u=qe("right"),u.style.maxHeight="calc(100vh - 80px)",u.style.position="sticky",u.style.top="8px",u.style.flexDirection="column",u.style.display=e?"flex":"none",I()}X(),u?.style.display!=="none"&&T&&oe(T,!0),(Q?.placement??"right")==="left"?(u&&A.appendChild(u),A.appendChild(O)):(A.appendChild(O),u&&A.appendChild(u)),S.appendChild(E),S.appendChild(G),S.appendChild(A),ee&&S.appendChild(ee);function Me(){G.innerHTML="";const e=d.plotMode??"hardBin",t=!Ae&&Mn.has(e),n=M.filter(b=>b!=null),i=n.find(b=>b.isLotStack),s=ei(n.map(b=>({metadata:b.wafer.metadata??void 0})),i?{lotSize:i.lotSize??n.length,aggrMethod:i.aggrMethod}:void 0),c=e==="metadata",a=d.activeMetadataKey,r=new Set;if(t&&!c)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=e==="softBin"?W.sbin:W.hbin;x!=null&&r.add(x)}const o=t&&!c?[...r].sort((b,W)=>b-W):[],l=new Set;if(t&&c&&a)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=W.metadata?.[a];x!=null&&(typeof x=="string"||typeof x=="number"||typeof x=="boolean")&&l.add(String(x))}const f=t&&c?[...l].sort(Jn):[];if(!s&&!o.length&&!f.length){G.style.display="none";return}if(G.style.display="flex",s&&G.appendChild(s),!o.length&&!f.length)return;const h=document.createElement("div");Object.assign(h.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),s&&Object.assign(h.style,{borderTop:`1px solid ${m.separator}`,paddingTop:"6px"}),G.appendChild(h);const g=vn(d.colorScheme),k=d.highlightBin;if(c){const b=d.highlightMetadataValue,W=M.flatMap(x=>x?.metadataFields??[]).find(x=>x.key===a);f.forEach((x,Ne)=>{const Ve=b===x,St=W?.values?.find(_e=>_e.value===x),bn=St?.color??Cn(Ne);Rt(h,{color:bn,isActive:Ve,label:St?.label??x,onClick:()=>{const _e=d.highlightMetadataValue===x?void 0:x;v({highlightMetadataValue:_e})}})});return}const F=e==="softBin"?M.flatMap(b=>b?.sbinDefs??[]):M.flatMap(b=>b?.hbinDefs??[]),H=new Set,K=[];for(const b of F)H.has(b.bin)||(H.add(b.bin),K.push(b));const fe=K.length>0?new Map(K.map(b=>[b.bin,b])):null;for(const b of o){const W=k===b,x=fe?.get(b),Ne=(d.colorScheme==="custom"?x?.color:void 0)??g.forBin(b);Rt(h,{color:Ne,isActive:W,label:x?.name?`${b} \xB7 ${x.name}`:`Bin ${b}`,onClick:()=>{const Ve=d.highlightBin===b?void 0:b;v({highlightBin:Ve})}})}}function ce(e){const t=y.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(ri)),i=t[0].wafer,s=t.length,c=i.metadata?{...i,metadata:(({wafer:r,waferId:o,...l})=>l)(i.metadata)}:i;function a(r,o){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:o,lotSize:s}}}if(e==="stackedValues"){const r=t.find(f=>f.testDefs?.length)?.testDefs;let o=r?.filter(Wt);if(r?.length||(o=yn(t.flatMap(h=>h.dies)).map(h=>({testNumber:h,name:`Test ${h}`}))),!o?.length)return[];const l=d.aggregationMethod??"mean";return o.map(f=>{const h=Kn(n,l,f.testNumber),g={testNumber:0,name:f.name,unit:f.unit};return{wafer:c,dies:h,testDefs:[g],label:`${f.name} \xB7 ${l}`,isLotStack:!0,aggrMethod:l,lotSize:s,statsSummary:a(Ee({wafer:c,dies:h,testDefs:[g]},{testNumbers:[0]}),l)}})}if(e==="stackedBins"){let r=Oe(t.flatMap(o=>o.hbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(o=>{const l=Tt(n,o.bin,"hard"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,hbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let r=Oe(t.flatMap(o=>o.sbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(o=>{const l=Tt(n,o.bin,"soft"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,sbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,sbinDefs:f}),"countBin")}})}return t}function $e(e){const t=y.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:d.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}const fn=new Set(["default","accessible","custom"]);function v(e,{fireCallback:t=!0}={}){const n=d.plotMode;d={...d,...e};const i=d.plotMode,s=ue.has(i),c=n!==void 0&&ue.has(n),a=be>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(i==="hardBin"||i==="softBin")&&!fn.has(d.colorScheme??"")&&(d={...d,colorScheme:"default"}),e.plotMode!==void 0)if(s){const o=$e(i);if(d={...d,...o},a)for(const l of w)l&&l.setOptions(e);else N(ce(i))}else if(c){const{valueRange:o,lotSize:l,aggregationMethod:f,...h}=d;if(d=h,a)for(const g of w)g&&g.setOptions(e);else N(y.filter(g=>g!==null))}else for(const o of w)o&&o.setOptions(e);else if(e.aggregationMethod!==void 0&&i==="stackedValues")if(a)for(const o of w)o&&o.setOptions(e);else N(ce("stackedValues"));else for(const o of w)o&&o.setOptions(e);Me(),st(),ot(),it();const r=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||r)&&I(),rt(),dt(),t){const o=Object.keys(e);p.onViewOptionsChange?.(d,o,qn(o))}}function wt(e,t,n){const i=e.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0"});const s=e.createElement("span");s.textContent=t,Object.assign(s.style,{fontWeight:"700",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),i.appendChild(s);const c=It(n??{});let a=null;if(c.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",i.appendChild(r),Object.assign(i.style,{cursor:"pointer"}),a=e.createElement("div"),a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const o=Lt(n??{});o&&a.appendChild(o),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Dt(i,l=>{r.textContent=l?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(l)),a&&(a.style.display=l?"block":"none")})}return{wrap:i,metaPanel:a}}function vt(e,t,n){const i=e.box.querySelector("[data-wmap-window-title]"),s=It(n??{});if(!i||s.length===0)return;const c=i.parentElement,a=document.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),c?.insertBefore(a,i),a.appendChild(i);const r=document.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",a.appendChild(r);const o=document.createElement("div");o.dataset.wmapCardMetaPanel="1",Object.assign(o.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const l=Lt(n??{});l&&o.appendChild(l),e.contentWrap.style.position="relative",e.contentWrap.appendChild(o),a.setAttribute("aria-expanded","false"),a.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Dt(a,f=>{r.textContent=f?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(f)),o.style.display=f?"block":"none"})}function je(e,t,n){const i=document.createElement("div");i.className="wmap-gallery-card",Object.assign(i.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${z}px`,maxHeight:`${z}px`});const s=document.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:c,metaPanel:a}=wt(document,e.label??"",e.wafer.metadata??void 0);s.appendChild(c);const r=document.createElement("button");r.dataset.wmapExpandBtn="1",r.title="Open full view",r.innerHTML=pe.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${m.menuBorder}`,borderRadius:"4px",background:m.panelBg,color:m.label,padding:"2px",cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),s.appendChild(r),i.appendChild(s);const o=document.createElement("div");Object.assign(o.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),i.appendChild(o),a&&o.appendChild(a),O.appendChild(i);const l=Ke(o,e,{viewOptions:e.viewOptions?{...d,...e.viewOptions}:d,toolbarControls:"full",showTooltip:!0,padding:Y,legendPosition:ne,fallbackFormat:he,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>ke(t,e),showMetadataBadge:!1});return l.setViewControlsVisible(!1),l.setSummaryVisible(!1),r.onclick=()=>ke(t,e),{card:i,ctrl:l,canvasWrapper:o,expandBtn:r}}function pn(e){const t=Z[e];if(!t)return;const n=[...R.values()].find(i=>i.cardIndex===e);n?(t.innerHTML=pe.minimize,t.title="Reattach to gallery",t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>mn(n.id)):(t.innerHTML=pe.expand,t.title="Open full view",t.setAttribute("aria-label","Open full view"),t.onclick=()=>ke(e,M[e]))}function N(e){gn(),le()?.remove(),se(null),Re(),M=[];for(const a of w)a&&a.destroy();w=[],q=[],Z=[],be=0,O.innerHTML="",bt=e.length,yt(e.map(a=>typeof a=="function"?null:a));const t=[];for(let a=0;a<e.length;a++){const r=e[a];if(typeof r=="function"){const o=document.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const l=document.createElement("span");l.textContent="\u2026",Object.assign(l.style,{color:m.label,fontSize:"18px"}),o.appendChild(l),O.appendChild(o),M.push(null),w.push(null),q.push(null),Z.push(null),t.push({index:a,factory:r,placeholder:o}),be++}else{const{ctrl:o,canvasWrapper:l,expandBtn:f}=je(r,a,e.length);M.push(r),w.push(o),q.push(l),Z.push(f)}}M.flatMap(a=>a?[...a.hbinDefs??[],...a.sbinDefs??[]]:[]).some(a=>a.color)&&!p.viewOptions?.colorScheme&&(d={...d,colorScheme:"custom"}),Me();const i=++De;let s=0;function c(){if(i!==De)return;if(s>=t.length){if(ue.has(d.plotMode)){const F=d.plotMode;N(ce(F))}return}const{index:a,factory:r,placeholder:o}=t[s++],l=r();M[a]=l,y[a]=l,yt([l]);const{card:f,ctrl:h,canvasWrapper:g,expandBtn:k}=je(l,a,e.length);w[a]=h,q[a]=g,Z[a]=k,be--,o.replaceWith(f),Me(),!u&&!Q?.placement&&l.statsSummary?.findings.length?(D||(ae="wafers"),u=qe("right"),u.style.maxHeight="calc(100vh - 80px)",u.style.position="sticky",u.style.top="8px",u.style.flexDirection="column",u.style.display="none",(Q?.placement??"right")==="left"?A.insertBefore(u,O):A.appendChild(u),I(),T||(T=V("findings","Summary panel",()=>{if(!u)return;const H=u.style.display!=="none";H||I(),u.style.display=H?"none":"flex",oe(T,!H),X()}),E.appendChild(P()),E.appendChild(T)),X()):u&&u.style.display!=="none"&&I(),X(),setTimeout(c,0)}t.length>0&&setTimeout(c,0)}if(ue.has(d.plotMode)&&y.length>0){const e=$e(d.plotMode);d={...d,...e},N(ce(d.plotMode))}else N(B);const Ct=new ResizeObserver(()=>{L==null&&Se()});Ct.observe(O),u&&I();function un(e){const t=q[e];if(!t)return;t.innerHTML="",Object.assign(t.style,{alignItems:"center",justifyContent:"center"});const n=document.createElement("span");n.textContent="Detached \u2014 open in its own window",Object.assign(n.style,{color:m.label,fontSize:"12px",textAlign:"center",padding:"0 12px"}),t.appendChild(n)}function ke(e,t){for(const a of R.values())if(a.cardIndex===e)return;const n=t.label??"Wafer map",i=$t++,s=w[e]?.getOptions(),c=Dn(n);if(c){const a=c.document;a.title=n,Object.assign(a.documentElement.style,{height:"100%"}),Object.assign(a.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),Ln(S,a.documentElement);const r=In(S,a.documentElement,()=>F.setOptions({})),o=a.createElement("div");o.dataset.wmapWindowBanner="1",o.textContent=n,Object.assign(o.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:m.warnBg,color:m.warnText,borderBottom:`1px solid ${m.warnBorder}`,flexShrink:"0"}),a.body.appendChild(o);const l=a.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),a.body.appendChild(l);const{wrap:f,metaPanel:h}=wt(a,n,t.wafer.metadata??void 0),g=a.createElement("div");Object.assign(g.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"}),g.appendChild(f),l.appendChild(g);const k=a.createElement("div");Object.assign(k.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),h&&k.appendChild(h),l.appendChild(k);const F=ze(k,t,void 0,s),H=setInterval(()=>{c.closed&&Be(i)},400);c.addEventListener("pagehide",()=>Be(i)),R.set(i,{id:i,ctrl:F,cardIndex:e,label:n,closePollId:H,stopThemeSync:r,close:()=>{c.closed||c.close()},setTitle:K=>{a.title=K,o.textContent=K,o.style.display="block"}})}else{const a=Tn({title:n,onClose:()=>Be(i),anchor:S});a.contentWrap.style.flexDirection="column",vt(a,n,t.wafer.metadata??void 0);const r=ze(a.contentWrap,t,void 0,s);R.set(i,{id:i,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>a.close(),setTitle:o=>{const l=a.box.querySelector("[data-wmap-window-title]");l&&(l.textContent=o,l.title=o)}})}w[e]?.destroy(),w[e]=null,un(e),pn(e)}function ze(e,t,n,i){const s=t.viewOptions?{...d,...t.viewOptions}:d,c=i?{...s,...i}:s,a=n!==void 0?{...c,plotMode:"value",activeTest:n}:c,r=Ke(e,t,{viewOptions:a,toolbarControls:"full",showTooltip:!0,padding:Y,legendPosition:ne,fallbackFormat:he,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return r.setViewControlsVisible(!0),r.setSummaryVisible(!0),r.setExpandVisible(!1),r}function Be(e){const t=R.get(e);if(!t)return;R.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const i=t.cardIndex,s=M[i];if(!s)return;const c={...s,viewOptions:n};M[i]=c;const{card:a,ctrl:r,canvasWrapper:o,expandBtn:l}=je(c,i,M.length);q[i]?.parentElement?.replaceWith(a),w[i]=r,q[i]=o,Z[i]=l}function mn(e){const t=R.get(e);t&&(t.close(),Be(e))}function gn(){for(const e of R.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function hn(){const e=[...O.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),i=Math.ceil(t/n),s=e[0].width,c=e[0].height,a=8,r=window.devicePixelRatio||1,o=Math.round(26*r),l=Math.round(12*r),f=document.createElement("canvas");f.width=n*s+(n-1)*a,f.height=i*(c+o)+(i-1)*a;const h=f.getContext("2d"),g=Sn(O);h.fillStyle=g.background,h.fillRect(0,0,f.width,f.height),e.forEach((k,F)=>{const H=F%n,K=Math.floor(F/n),fe=H*(s+a),b=K*(c+o+a),W=k.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";h.fillStyle=g.surface,h.fillRect(fe,b,s,o),h.fillStyle=g.text,h.font=`700 ${l}px system-ui, sans-serif`,h.textAlign="left",h.textBaseline="middle",h.fillText(W,fe+Math.round(10*r),b+o/2,s-Math.round(20*r)),h.drawImage(k,fe,b+o)}),f.toBlob(k=>{k&&jn(k,te,p.onSaveImage)})}return{setItems(e){y=e.map(n=>typeof n=="function"?null:n);const t=d.plotMode;if(ue.has(t))if(e.some(i=>typeof i=="function"))N(e);else{const i=$e(t);d={...d,...i},N(ce(t))}else N(e)},setOptions(e){v(e,{fireCallback:!1})},getOptions(){return{...d}},setFallbackFormat(e){he=e;for(const t of w)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){D=e,ft(),u&&I(),X()},setColumns(e){xt(e)},openUserGuide:pt,destroy(){De++;for(const e of[...R.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();R.clear();for(const e of w)e&&e.destroy();w=[],le()?.remove(),Ct.disconnect(),S.ownerDocument.removeEventListener("click",xe,!0),window.removeEventListener("blur",Je),Ht(),Bt(),E.remove(),G.remove(),A.remove(),u?.remove(),de?.destroy()}}}
@@ -7,6 +7,7 @@ import { type SaveImageHandler, type SaveTextHandler, type UserGuideExtension }
7
7
  import type { SummaryPanelOptions } from './summaryPanel.js';
8
8
  import { type WarningsOptions } from './warnings.js';
9
9
  import { type InsightsOptions } from './insightsTab.js';
10
+ import { type DieListDisplayOptions } from './dieList.js';
10
11
  /**
11
12
  * Stable display preferences — worth persisting to localStorage or a user profile.
12
13
  * These describe how the user wants to view wafer maps in general.
@@ -191,6 +192,18 @@ export interface RenderOptions extends Omit<ToCanvasOptions, 'viewport' | 'hbinD
191
192
  * Insights has no map for a finding to highlight against.
192
193
  */
193
194
  summaryPanel?: SummaryPanelOptions;
195
+ /**
196
+ * Display preferences for every built-in die-list surface: the
197
+ * coordinate-less map replacement, the "+N dies without position data"
198
+ * footer, and the "View die list" link in the Summary panel (§5.4.4) — on
199
+ * by default whenever `summaryPanel` is set; pass `{ enabled: false }` to
200
+ * hide just that link, leaving the other two surfaces unaffected. This
201
+ * option carries preferences only — the wafer metadata and metadata field
202
+ * definitions the table needs are always taken from the current build
203
+ * result, never from this option, so a host cannot substitute the wrong
204
+ * identity data into an export.
205
+ */
206
+ dieList?: DieListDisplayOptions;
194
207
  /**
195
208
  * Custom tooltip renderer. When provided, replaces the built-in tooltip content.
196
209
  * Return a string (set as innerHTML), an HTMLElement (appended directly), or null to suppress the tooltip.
@@ -1 +1 @@
1
- import{buildView as oi,buildHoverText as ai,findTestDef as it,resolveTestNumber as Et}from"../renderer/buildView.js";import{toCanvas as li,BIN_LEGEND_W as wn,BIN_LEGEND_W_COMPACT as si,BIN_LEGEND_ADAPT_COMPACT as ri,BIN_LEGEND_ADAPT_FLOATING as di}from"./toCanvas.js";import{buildWaferMap as ci,getTestPassStatus as pi,isParametricTest as Bt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as fi}from"../stats/analyzeWaferMap.js";import{CLR as x,Z_BASE as ui,applyOverlayZ as gi,getTooltip as Sn,hideTooltip as ot,reparentTooltip as hi,positionTooltip as Dt,createToolbarHelpers as mi,buildModeMenuEl as yi,openReparentedModal as bi,openUserGuideWindow as vi,makePaletteBtn as xi,makeLogScaleBtn as wi,makeLegendStyleBtn as Si,makeOverlaysBtn as Ci,makeOrientationBtn as Mi,overlayRootFor as Cn,saveImageBlob as Ei,markMenuTrigger as Ye,wireMenuA11y as Mn,wireExpandToggle as Bi,nextFrame as kt,passFailMenuRows as Di,requestedPassFailDisplay as Lt,logWmapVersionOnce as ki,buildDataModeEntries as Li,metadataKeyHasData as Ti,metadataModeEntry as Pi}from"./toolbar.js";import{createSummaryPanelEl as Tt,wrapWithSummaryPanel as Pt,renderWaferSummaryContent as Oi}from"./summaryPanel.js";import{collectWarnings as Ri,buildWarningsMenuEl as Ii,severityOf as Wi}from"./warnings.js";import"../stats/facets.js";import{ICONS as En}from"./icons.js";import{hardBinColor as Hi,softBinColor as Ai,metadataValueColor as Fi}from"../renderer/colorMap.js";import{createInsightsTab as Yi}from"./insightsTab.js";import{createMetadataBadge as zi}from"./metadataBadge.js";import{getDieKey as Me,hasPosition as Bn,isPositionedDie as Xi}from"../core/dies.js";import{buildDieListSection as Ni}from"./dieList.js";import{buildMaplessSummary as Ki}from"./maplessSummary.js";const Dn=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode"]);export function classifyChanged(N){const h=N.some(W=>Dn.has(W)),C=N.some(W=>!Dn.has(W));return h&&C?"mixed":h?"preference":"state"}export function renderWaferMap(N,h,C={}){ki();const W=N.ownerDocument,_=W.defaultView??window;_.getComputedStyle(N).position==="static"&&(N.style.position="relative");const kn=N.clientHeight;C.height!=null&&(N.style.height=typeof C.height=="number"?`${C.height}px`:C.height);const at=h.dataCoverage?h.dataCoverage.unpositionedDies:h.dies.filter(e=>!Bn(e)).length,ze=(h.dataCoverage?h.dataCoverage.totalDies:h.dies.length-at)===0&&at>0,q=document.createElement("div");Object.assign(q.style,{position:"relative",width:"100%",height:"100%"}),C.maxSize!=null&&(q.style.maxWidth=`${C.maxSize}px`,q.style.maxHeight=`${C.maxSize}px`),N.appendChild(q);const w=document.createElement("div");Object.assign(w.style,{position:"relative",width:"100%",height:"100%"});const a=document.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),w.appendChild(a),q.appendChild(w);let Xe=null;if(at>0){let n=function(){if(t){const u=Ni(e,h.testDefs,{onSaveText:C.onSaveText});if(u)return u}const i=it(h.testDefs,s.activeTest??0),r=Bt(i)?s.logScale??i?.logScale??!1:!1;return Ki(e,h.testDefs,{plotMode:s.plotMode??"hardBin",activeTest:s.activeTest,hbinDefs:$,sbinDefs:G,colorScheme:s.colorScheme,logScale:r,colorbarRangeMode:s.colorbarRangeMode,valueRangeDies:h.dies})},o=function(i){const r=document.createElement("button");return r.type="button",Object.assign(r.style,{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",flexShrink:"0",border:`1px solid ${x.menuBorder}`,background:x.menuBg,color:x.text,cursor:"pointer"}),r.textContent=t?"View chart":"View die list",r.addEventListener("click",u=>{u.stopPropagation(),t=!t,r.textContent=t?"View chart":"View die list",i()}),r};const e=h.dies.filter(i=>!Bn(i));let t=!1;if(ze){const i=document.createElement("div");Object.assign(i.style,{position:"absolute",inset:"0",background:x.panelBg,padding:"12px",paddingTop:C.showToolbar??!0?"44px":"12px",boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:"8px",zIndex:"1"});const r=document.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"8px"});const u=document.createElement("span");Object.assign(u.style,{fontSize:"11px",color:x.label,lineHeight:"1.4"}),u.textContent="No die position data for this wafer.",r.appendChild(u);const l=document.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(o(()=>l.replaceChildren(n()))),i.appendChild(r),i.appendChild(l),w.appendChild(i),Xe=()=>{t||l.replaceChildren(n())}}else{const i=document.createElement("div");Object.assign(i.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,fontSize:"11px",color:x.text,cursor:"pointer",padding:"4px 8px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"8px"});const r=document.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,i.appendChild(r);const u=document.createElement("span");u.textContent="\u25BE",Object.assign(u.style,{fontSize:"12px",lineHeight:"1",color:x.label,flexShrink:"0"}),i.appendChild(u),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,d=null;Bi(i,c=>{if(u.textContent=c?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(c)),c){l=document.createElement("div");const p=i.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${p}px`,top:"20%",zIndex:"2",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column",gap:"8px"}),l.addEventListener("click",Q=>Q.stopPropagation());const g=document.createElement("div");Object.assign(g.style,{display:"flex",justifyContent:"flex-end"}),g.appendChild(o(()=>{d&&d.replaceChildren(n())})),l.appendChild(g),d=document.createElement("div"),Object.assign(d.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),d.appendChild(n()),l.appendChild(d),w.appendChild(l)}else l&&(l.remove(),l=null,d=null)}),w.appendChild(i),Xe=()=>{d&&!t&&d.replaceChildren(n())}}}const{onHover:Ne,onClick:Ln,onSelect:re,onViewOptionsChange:Tn,showTooltip:Pn=!0,showToolbar:ge=!0,showMetadataBadge:On=!0,toolbarControls:Ot="full",showPlotModeSelector:Rn=!0,minZoom:In=.4,maxZoom:Wn=20,summaryPanel:Ee,renderTooltip:Rt,passBins:It=[1],showHelpButton:Hn=!1,userGuideExtension:An,onExpand:Wt,showExpandButton:Ht=!0,zIndex:Fn,insights:At,warnings:Ft,viewOptions:Yn={},...de}=C,zn=At?.enabled??!1,Yt=Ft?.display??!0,Xn=gi(Fn);let Be=de.fallbackFormat,ne=C.statsSummary,ie=[],zt=!1;function Xt(){const e=Ri({result:h,statsSummary:ne}),t=e.length!==ie.length||e.some((n,o)=>n.code!==ie[o]?.code||n.message!==ie[o]?.message);ie=e,(t||!zt)&&(zt=!0,Ft?.onWarning?.(e))}Xt();let lt=h,oe=h.wafer,ae=h.dies,M=new Set,$=h.hbinDefs,G=h.sbinDefs,J=h.testDefs,De=h.metadataFields,Nt=h.reticles?.length?h.reticles:void 0,Kt=h.reticleConfig,Vt=h.view?.dataAxisFlip,st=h.isLotStack??!1,rt=h.aggrMethod,dt=h.lotSize,jt=!1,L=null;On&&(L=zi(oe.metadata,{lotStack:_t()}),L.isEmpty()||w.appendChild(L.el));function _t(){return st?{lotSize:dt??1,aggrMethod:rt}:void 0}function Nn(){if(!L)return;L.update(oe.metadata,_t());const e=L.el.isConnected;L.isEmpty()&&e?L.el.remove():!L.isEmpty()&&!e&&w.appendChild(L.el)}const $t=[...$??[],...G??[]].some(e=>e.color);let s={plotMode:"hardBin",colorScheme:$t?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:de.legendPosition??"default",...Yn},le=null,he=!1;zn&&(le=Yi({getItems:()=>[{wafer:oe,dies:ae,hbinDefs:$,sbinDefs:G,testDefs:J,label:String(oe.metadata?.waferId??""),statsSummary:ne}],getColorSchemeName:()=>s.colorScheme??"default",passBins:It,getRingCount:()=>s.ringCount??4,onSaveImage:C.onSaveImage,onSaveText:C.onSaveText,defaultView:At?.defaultView,backTab:{label:"Map",onBack:()=>ct(!1)}}),Object.assign(le.el.style,{position:"absolute",inset:"0",background:x.panelBg,overflowY:"auto",paddingTop:ge?"44px":"0"}),q.appendChild(le.el));function ct(e){le&&(he=e,le.el.style.display=e?"flex":"none",A&&(A.style.display=e||ze?"none":"flex"),D&&(D.style.display=e?"none":"flex"),Z&&(Z.style.display=e?"none":"flex"),L&&(L.el.style.display=e||jt?"none":""),Ze(),F&&(F.innerHTML=e?En.wafer:En.analysis,F.ariaLabel=e?"Back to wafer view":"Insights"),e&&le.render())}let m,Gt,H=null,T=null,pt=[],ke=null,ft=de.legendOffset??{x:0,y:0},Le=!1,me=!1,Te={x:0,y:0},ut={x:0,y:0},ce=!1,ye=!1,Y="pan",be={x:0,y:0},Ke={x:0,y:0},P={x:0,y:0},O={x:0,y:0},Pe=!1,ve=!1;function Oe(){const e=s;m=oi(oe,ae.filter(Xi),{plotMode:e.plotMode,colorScheme:e.colorScheme,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:Nt,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:J,valueRange:e.valueRange,logScale:e.logScale,isLotStack:st,aggregationMethod:rt??e.aggregationMethod,lotSize:dt??e.lotSize,dataAxisFlip:Vt,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:Be,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:De}),Gt=new Map(m.dies.map((t,n)=>[Me(t),n]))}Oe();let z=null,pe=null,Ve=null,Kn={},R=null,ee=null;function Vn(e){const{kind:t,index:n}=e.variable;S(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const o=e.highlight;o.kind==="bin"?(vt(o.dieKeys),S({highlightBin:o.bin})):(o.kind==="region"||o.kind==="dies")&&vt(o.dieKeys)}function Zt(e){Oi(e,{wafer:oe,dies:ae,yieldSummary:lt.yield,dataCoverage:lt.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:J,statsSummary:ne,warnings:Yt?ie:[],passBins:It,ringCount:s.ringCount??4,colorScheme:s.colorScheme,fallbackFormat:Be,activeFindingId:Ve,findingsFilter:Kn,onFindingsFilterChange:fe,onSaveText:C.onSaveText,onFindingClick:(t,n)=>{Ve===t.id?(Ve=null,vt([]),S({highlightBin:void 0})):(Ve=t.id,Vn(t)),fe()}})}function fe(){z&&Zt(z)}function je(){R&&Zt(R)}function Qt(e,t){ge&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(Ee?.placement){const e=Ee.placement;z=Tt(e),Qt(z,e);const t=w.parentElement,n=w.nextSibling;pe=Pt(w,z,e),t?.insertBefore(pe,n),fe()}else if(ne){const e=Ee?.defaultOpen??!ge;R=Tt("right"),Qt(R,"right"),R.style.display=e?"block":"none";const t=w.parentElement,n=w.nextSibling;ee=Pt(w,R,"right"),t?.insertBefore(ee,n),je()}const b=Pn?Sn(W):null;let E=null,B=null,A=null,D=null,_e=null,I=null,Z=null,$e=null,F=null,te=null,Ge=null;function Ut(){if(!te||!Ge)return;const e=ie.length,t=e>0;if(te.style.display=t?"flex":"none",Ge.style.display=t?"":"none",!t)return;const n=Wi(ie[0]),o=`${e} data ${e===1?"warning":"warnings"}`;te.style.color=n==="error"?x.errText:x.warnText,te.ariaLabel=n==="error"?`${o} \u2014 the map may be positionally wrong`:o}const jn=24;let xe=null,gt=null,qt=null,ht=null,mt=null,yt=null,bt=null;function vt(e){M=new Set(e??[]),re&&re(Ct()),v()}function Ze(){if(!I)return;const e=!!(z??R);I.style.display=ne&&e&&!he?"flex":"none";const t=z??R,n=t?t.style.display!=="none":!1;ne?.hasNotableFindings&&!n?I.style.color=x.findingIndicator:I.dataset.active||(I.style.color=x.icon)}if(ge){let Q=function(U){Y=U,o(K,U==="zoom"),o(Ie,U==="pan"),_e&&o(_e,U==="select"),a.style.cursor=U==="pan"?"grab":"crosshair"},qe=function(){xe&&(clearTimeout(xe),xe=null),E&&(E.style.opacity="1")},Je=function(){xe=setTimeout(()=>{E&&(E.style.opacity="0.35")},600)};E=document.createElement("div"),E.dataset.wmapToolbar="single",Object.assign(E.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"calc(100% - 8px)",background:x.menuBg,border:`1px solid ${x.menuBorder}`,borderRadius:"4px",boxShadow:"0 1px 4px rgba(0,0,0,0.12)",zIndex:ui,opacity:"0.35",transition:"opacity 0.2s ease",pointerEvents:"auto"});const e=Sn(W),t=mi(e),{makeBtn:n,setActive:o,makeSep:i,makeMenuRow:r,makeMenuSection:u,makeDropdown:l,makeCheckMenuBtn:d,closeOpenMenu:c,getOpenMenu:p,setOpenMenu:g}=t;gt=c,qt=p,W.addEventListener("click",c,!0),A=document.createElement("div"),Object.assign(A.style,{display:ze?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(A);const Ce=n("download","Download PNG",Gn);A.appendChild(Ce),A.appendChild(i());const K=n("zoomMode","Zoom (drag to zoom region)",()=>Q("zoom")),se=n("zoomIn","Zoom in",()=>Se(a.clientWidth/2,a.clientHeight/2,1.2)),k=n("zoomOut","Zoom out",()=>Se(a.clientWidth/2,a.clientHeight/2,1/1.2)),V=n("reset","Reset zoom (double-click)",()=>Ue());A.appendChild(K),A.appendChild(se),A.appendChild(k),A.appendChild(V),A.appendChild(i());const Ie=n("pan","Pan (drag to move)",()=>Q("pan"));if(A.appendChild(Ie),_e=n("boxSelect","Select (drag to select dies)",()=>Q("select")),A.appendChild(_e),o(Ie,!0),Ot!=="view-only"){let U=function(f){return f.plotMode!==(s.plotMode??"hardBin")?!1:f.plotMode==="value"?(s.activeTest??0)===(f.activeTest??0):f.plotMode==="metadata"?s.activeMetadataKey===f.activeMetadataKey:!0},We=function(f,y){f.activeTest!==void 0?S({plotMode:f.plotMode,activeTest:f.activeTest,activeMetadataKey:void 0,logScale:f.logScale}):f.activeMetadataKey!==void 0?S({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:f.activeMetadataKey,passFailDisplay:"off"}):S({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),y.remove(),g(null),Ye(j,!1)};B=document.createElement("div"),Object.assign(B.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(B),D=document.createElement("div"),Object.assign(D.style,{display:"flex",alignItems:"center",gap:"0"}),B.appendChild(D),D.appendChild(i());const et=()=>{const f=p();f&&(f.remove(),g(null)),Ye(j,!1)},j=n("mode","Plot mode",()=>{if(p()){et();return}const f=ae,y=m.testDefs,{testEntries:nt,binEntries:ue,stackedEntries:He}=Li(f,y,{includeStacked:m.isLotStack}),Mt=(De??[]).filter(Fe=>Ti(f,Fe.key)).map(Pi),Ae=yi(j.getBoundingClientRect(),nt,ue,He,U,We,{makeMenuRow:r,makeMenuSection:u},s.plotMode??"hardBin",j.ownerDocument.defaultView??window,Mt);Cn(j).appendChild(Ae),g(Ae),Ye(j,!0),Mn(Ae,j,et)});Ye(j,!1);const{btn:Zn,sync:Qn}=xi(t,()=>s.plotMode??"hardBin",()=>s.colorScheme??"default",()=>$t,f=>S({colorScheme:f}));mt=Qn,mt();const Un=Ci(t,()=>{const f=!!m.hasReticle,y=(s.plotMode??"hardBin")==="value",{testNumber:nt}=Et(s.activeTest??0,m.testDefs),ue=it(m.testDefs,nt),He=y&&ue!==void 0&&!Bt(ue),Mt=y&&!He&&(ue?.limitLow!==void 0||ue?.limitHigh!==void 0),Ae=y&&!He&&m.dies.some(Fe=>pi(Fe,nt,ue)!==void 0);return[{label:"Ring boundaries",active:!!s.showRingBoundaries,onClick:()=>S({showRingBoundaries:!s.showRingBoundaries})},{label:"Quadrant lines",active:!!s.showQuadrantBoundaries,onClick:()=>S({showQuadrantBoundaries:!s.showQuadrantBoundaries})},{label:"Die labels",active:!!s.showDieLabels,onClick:()=>S({showDieLabels:!s.showDieLabels})},{label:"Reticle grid",active:!!s.showReticle,enabled:f,onClick:()=>S({showReticle:!s.showReticle})},{label:"XY indicator",active:!!s.showXYIndicator,onClick:()=>S({showXYIndicator:!s.showXYIndicator})},...Di({functionalActive:He,hasLimits:Mt,hasRecorded:Ae,display:Lt(s)},Fe=>S({passFailDisplay:Fe}))]},()=>!!(s.showRingBoundaries||s.showQuadrantBoundaries||s.showDieLabels||s.showReticle||s.showXYIndicator||Lt(s)!=="off")),{btn:qn,sync:Jn}=Si(t,()=>s,f=>S({legendPosition:f}));ht=Jn,ht();const xn=()=>{const{testNumber:f}=Et(s.activeTest??0,J),y=it(J,f);return y!==void 0&&!Bt(y)},{btn:ei,sync:ti}=wi(t,()=>({...s,functionalActive:xn()}),f=>S(f));yt=ti,yt();const ni=()=>{const{testNumber:f}=Et(s.activeTest??0,J),y=it(J,f);return y!==void 0&&(y.limitLow!==void 0||y.limitHigh!==void 0)},tt=n("specRange","Colorbar range: spec limits",()=>{const f=s.colorbarRangeMode==="data"?"spec":"data";S({colorbarRangeMode:f})});bt=()=>{const f=s.plotMode==="value"&&ni()&&Lt(s)==="off"&&!xn();tt.style.display=f?"":"none";const y=(s.colorbarRangeMode??"spec")==="spec";o(tt,y),tt.ariaLabel=y?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},bt();const ii=Mi(t,()=>s,f=>S(f));Rn&&D.appendChild(j),D.appendChild(Zn),D.appendChild(ei),D.appendChild(tt),ze||(D.appendChild(i()),D.appendChild(Un),D.appendChild(i()),D.appendChild(qn),D.appendChild(i()),D.appendChild(ii)),ne&&(I=n("findings","Summary panel",()=>{const f=z??R;if(!f)return;const y=f.style.display!=="none";f.style.display=y?"none":"block",o(I,!y),Ze()}),B.appendChild(i()),B.appendChild(I),R?.style.display!=="none"&&o(I,!0),Ze()),Yt&&(Ge=i(),te=n("warning","Data warnings",()=>{const f=p();if(c(new MouseEvent("click")),f)return;const y=Ii(te.getBoundingClientRect(),ie);Cn(q).appendChild(y),g(y),Mn(y,te,()=>c(new MouseEvent("click")))}),Ye(te,!1),B.appendChild(Ge),B.appendChild(te),Ut()),Ht&&(B.appendChild(i()),Z=n("expand","Expand (E)",Wt??Jt),B.appendChild(Z)),le&&(B.appendChild(i()),F=n("analysis","Insights",()=>{ct(!he),o(F,he)}),B.appendChild(F)),Hn&&(B.appendChild(i()),$e=n("help","User guide",()=>vn()),B.appendChild($e))}q.appendChild(E),a.addEventListener("mouseenter",qe),a.addEventListener("mouseleave",Je),E.addEventListener("mouseenter",qe),E.addEventListener("mouseleave",Je)}let we=null;function Jt(){we&&(we.close(),we=null);const e=pe??ee??w;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=bi(E?[e,E]:[e],{ownerDocument:W,onClosed:()=>{we=null,Z&&(Z.style.display="flex"),a.focus({preventScroll:!0})}});t&&(E&&(t.contentWrap.style.position="relative"),we=t,Z&&(Z.style.display="none"))}function en(e){const t=s.plotMode;if(s={...s,...e},e.plotMode!==void 0&&e.plotMode!==t){H=null;const i=s.plotMode;(i==="hardBin"||i==="softBin")&&!new Set(["default","accessible","custom"]).has(s.colorScheme??"")&&(s={...s,colorScheme:"default"})}Object.keys(e).every(i=>i==="legendPosition")||Oe(),ht?.(),mt?.(),yt?.(),bt?.(),v();const o=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||o)&&(fe(),je()),(e.colorScheme!==void 0||o||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Xe?.()}function S(e){en(e);const t=Object.keys(e);Tn?.(s,t,classifyChanged(t))}let xt=!1;function wt(){xt||(xt=!0,kt(()=>{xt=!1,v()},_))}function v(){const e=T??void 0,t=m.dies[0],n=t?{x:t.width,y:t.height}:de.diePitchMm,o=Math.floor(a.clientWidth||a.width),i=!!($?.length||G?.length||m.dies.some(p=>p.hbin!=null||p.sbin!=null)),r=s.legendPosition??"default",u=r==="default"||r==="compact",l=(de.colorbarWidth??16)+28,d=i&&u?r!=="default"?Math.max(wn,l):o<di?0:o<ri?Math.max(si,l):Math.max(wn,l):void 0,c=li(a,m,{...de,topClearance:ge?jn:0,minRightReserve:d,legendPosition:r,legendOffset:ft,diePitchMm:n,fallbackFormat:Be,showAxes:de.showAxes??T!==null,viewport:e,activeBin:s.plotMode==="metadata"?s.highlightMetadataValue:s.highlightBin,hbinDefs:$,sbinDefs:G,metadataFields:De});pt=c.binLegendRows,ke=c.legendBox??null,H||(H=c.viewport),M.size>0&&_n(),ye&&$n()}function _n(){const e=X();if(!e)return;const t=a.getContext("2d"),n=m.hoverPoints,o=m.rectangles[0],i=o?o.width/2*e.ppm:e.ppm*.5,r=o?o.height/2*e.ppm:e.ppm*.5,u=Math.max(1,Math.min(3,i*.08)),l=i-u,d=r-u,c=[];for(const p of M){const g=Gt.get(p);g!==void 0&&c.push({sx:e.originX+n[g].x*e.ppm,sy:e.originY-n[g].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-l,g-d,l*2,d*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-l,g-d,l*2,d*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-l,g-d,l*2,d*2);t.stroke(),t.restore()}}function $n(){const e=a.getContext("2d"),t=Math.min(P.x,O.x),n=Math.min(P.y,O.y),o=Math.abs(O.x-P.x),i=Math.abs(O.y-P.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,o,i),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,o,i),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,o,i),e.restore()}function Gn(){a.toBlob(e=>{e&&Ei(e,C.downloadFilename??"wafermap",C.onSaveImage)})}function tn(e){return H?Math.max(H.ppm*In,Math.min(H.ppm*Wn,e)):e}function Se(e,t,n){const o=T??H;if(!o)return;const i=tn(o.ppm*n),r=i/o.ppm,u=e-(e-o.originX)*r,l=t-(t-o.originY)*r,d=(H?.snapDist??1)/(i/(H?.ppm??i));T={originX:u,originY:l,ppm:i,snapDist:d},v()}function X(){return T??H}function nn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Se(e.clientX-t.left,e.clientY-t.top,n)}else if(T!==null){e.preventDefault();const t=X(),n=T.snapDist;T={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}function on(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function an(e){if(e.button!==0||!X())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(ke&&s.legendPosition==="floating"&&on(n,o,ke)){me=!0,Te={x:n,y:o},ut={...ft};return}if(Pe&&Y!=="pan"){ve=!0,ce=!0,be={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){ye=!0,P=O={x:n,y:o};return}ce=!0,be={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing"}function ln(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(ye){O={x:n,y:o},wt();return}if(me){const p=n-Te.x,g=o-Te.y;p*p+g*g>16&&(me=!1,Le=!0,a.style.cursor="grabbing")}if(Le){ft={x:ut.x+(n-Te.x),y:ut.y+(o-Te.y)},wt();return}if(ce){const p=X(),g=T?.snapDist??H?.snapDist??1;T={originX:Ke.x+(n-be.x),originY:Ke.y+(o-be.y),ppm:p.ppm,snapDist:g},wt();return}const i=X();if(!i)return;const r=(n-i.originX)/i.ppm,u=(i.originY-o)/i.ppm,d=cn(r,u,i.snapDist)?.die??null,c=pt.find(p=>n>=p.x&&n<p.x+p.w&&o>=p.y&&o<p.y+p.h);if(c){a.style.cursor="pointer",b&&(b.innerHTML=c.label??`Bin ${c.bin}`,b.style.display="block",Dt(b,a,e.clientX,e.clientY)),Ne?.(null,e);return}if(Y==="pan"&&(a.style.cursor=d?"crosshair":"grab"),b)if(d)if(Rt){const p=Rt(d);p===null?b.style.display="none":(typeof p=="string"?b.innerHTML=p:(b.innerHTML="",b.appendChild(p)),b.style.display="block",Dt(b,a,e.clientX,e.clientY))}else b.innerHTML=ai(d,m.plotMode,{testDefs:J,hbinDefs:$,sbinDefs:G,fallbackFormat:Be,aggrMethod:m.aggrMethod,lotSize:m.lotSize,waferMeta:oe.metadata,activeTest:m.activeTest,reticleConfig:Kt}),b.style.display="block",Dt(b,a,e.clientX,e.clientY);else b.style.display="none";Ne?.(d,e)}function sn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,i=e.ctrlKey||e.metaKey;if(b&&(n<0||o<0||n>t.width||o>t.height)&&(b.style.display="none"),ye){ye=!1,O={x:n,y:o};const l=n-P.x,d=o-P.y,c=X();if(Y==="zoom"){if(l*l+d*d<25)Se(n,o,2);else if(c){const p=Math.min(P.x,O.x),g=Math.max(P.x,O.x),Q=Math.min(P.y,O.y),Ce=Math.max(P.y,O.y),K=g-p,se=Ce-Q;if(K>4&&se>4){const k=a.clientWidth,V=a.clientHeight,Ie=k/K,qe=V/se,Je=Math.min(Ie,qe),U=tn(c.ppm*Je),We=U/c.ppm,et=(p+g)/2,j=(Q+Ce)/2;T={originX:k/2-(et-c.originX)*We,originY:V/2-(j-c.originY)*We,ppm:U,snapDist:c.snapDist/We}}}v(),a.style.cursor="crosshair";return}if(l*l+d*d<25)St(n,o,i,e);else if(c){const p=(Math.min(P.x,O.x)-c.originX)/c.ppm,g=(Math.max(P.x,O.x)-c.originX)/c.ppm,Q=(c.originY-Math.max(P.y,O.y))/c.ppm,Ce=(c.originY-Math.min(P.y,O.y))/c.ppm,K=m.hoverPoints,se=[];for(let k=0;k<K.length;k++)if(K[k].x>=p&&K[k].x<=g&&K[k].y>=Q&&K[k].y<=Ce){const V=m.dies[k];V&&se.push(V)}if(i)for(const k of se){const V=Me(k);M.has(V)?M.delete(V):M.add(V)}else M=new Set(se.map(k=>Me(k)));re?.(Ct())}v(),a.style.cursor="crosshair";return}if(me){me=!1,St(n,o,i,e);return}if(Le){Le=!1,a.style.cursor="grab";return}if(!ce)return;if(ce=!1,ve){ve=!1,a.style.cursor=Pe||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const r=n-be.x,u=o-be.y;r*r+u*u<25&&St(n,o,i,e)}function St(e,t,n,o){for(const l of pt)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const d=s.highlightBin===l.bin?void 0:l.bin;S({highlightBin:d})}else{const d=s.highlightMetadataValue===l.bin?void 0:l.bin;S({highlightMetadataValue:d})}return}if(ke&&on(e,t,ke))return;const i=X();if(!i)return;const u=cn((e-i.originX)/i.ppm,(i.originY-t)/i.ppm,i.snapDist)?.die??null;if(u){Ln?.(u,o);const l=Me(u);n?M.has(l)?M.delete(l):M.add(l):M=new Set([l]),re?.(Ct()),v()}else n||(M=new Set,re?.([]),v())}function Ct(){const e=[],t=m.hoverPoints;for(let n=0;n<t.length;n++){const o=m.dies[n];o&&M.has(Me(o))&&e.push(o)}return e}function rn(){b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function dn(){ce=!1,ve=!1,ye=!1,me=!1,Le=!1,b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",v()}function cn(e,t,n){const o=m.hoverPoints,i=m.rectangles;for(let d=0;d<i.length;d++){const c=i[d];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const p=m.dies[d];return p?{die:p,index:d}:null}}let r=null,u=-1,l=n*n;for(let d=0;d<o.length;d++){const c=o[d].x-e,p=o[d].y-t,g=c*c+p*p;g<l&&(l=g,r=m.dies[d]??null,u=d)}return r?{die:r,index:u}:null}const pn=new _.ResizeObserver(()=>{H=null,T=null,v()});pn.observe(a),C.height==null&&kn<=0&&kt(()=>kt(()=>{N.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 Re=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`);const Qe=()=>{Re.removeEventListener("change",Qe),Re=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`),Re.addEventListener("change",Qe),v()};Re.addEventListener("change",Qe);const fn=_.matchMedia("(prefers-color-scheme: dark)"),un=()=>v();fn.addEventListener("change",un);const gn=()=>{b&&ot(W)};_.addEventListener("blur",gn);function hn(e){if(e.key==="Escape"&&M.size>0&&(M=new Set,re?.([]),v()),(e.key==="e"||e.key==="E")&&Ot!=="view-only"&&Ht&&!he&&(e.stopPropagation(),(Wt??Jt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Se(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Se(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),Ue())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const o=T?.snapDist??H?.snapDist??1;let i=0,r=0;e.key==="ArrowLeft"&&(i=20,e.preventDefault()),e.key==="ArrowRight"&&(i=-20,e.preventDefault()),e.key==="ArrowUp"&&(r=20,e.preventDefault()),e.key==="ArrowDown"&&(r=-20,e.preventDefault()),(i||r)&&(T={originX:n.originX+i,originY:n.originY+r,ppm:n.ppm,snapDist:o},v())}e.key===" "&&!Pe&&(e.preventDefault(),Pe=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function mn(e){e.key===" "&&(Pe=!1,ve&&(ce=!1,ve=!1),a.style.cursor=Y==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",nn,{passive:!1}),a.addEventListener("pointerdown",an),a.addEventListener("pointermove",ln),a.addEventListener("pointerup",sn),a.addEventListener("pointerleave",rn),a.addEventListener("pointercancel",dn);const yn=()=>Ue();a.addEventListener("dblclick",yn),a.addEventListener("keydown",hn),a.addEventListener("keyup",mn);const bn=e=>{e.stopPropagation()};a.addEventListener("click",bn),a.clientWidth,v(),Xe?.();function Ue(){H=null,T=null,v()}function vn(){import("./userGuideHtml.js").then(e=>vi({buildWaferMap:ci,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:fi},e.USER_GUIDE_HTML,An,N))}return{setDies(e){ae=e,Oe(),v(),z&&fe()},setResult(e){lt=e,oe=e.wafer,ae=e.dies,$=e.hbinDefs,G=e.sbinDefs,J=e.testDefs,De=e.metadataFields,Nt=e.reticles?.length?e.reticles:void 0,Kt=e.reticleConfig,Vt=e.view?.dataAxisFlip,st=e.isLotStack,rt=e.aggrMethod,dt=e.lotSize,Nn(),Oe(),v(),z&&fe()},setOptions(e){en(e)},getOptions(){return{...s}},resetZoom:Ue,setSelection(e){M=new Set(e.map(t=>Me(t))),v()},clearSelection(){M=new Set,re?.([]),v()},setFallbackFormat(e){Be=e,Oe(),v()},setStatsSummary(e){if(ne=e,Xt(),Ut(),z)fe();else if(R)je();else if(e&&!Ee?.placement){const t=Ee?.defaultOpen??!ge;R=Tt("right"),R.style.display=t?"block":"none";const n=w.parentElement,o=w.nextSibling;ee=Pt(w,R,"right"),n?.insertBefore(ee,o),je()}Ze()},setSummaryVisible(e){I&&(I.style.display=e?"flex":"none")},setViewControlsVisible(e){B&&(B.style.display=e?"flex":"none")},setExpandVisible(e){Z&&(Z.style.display=e?"flex":"none")},setHelpButtonVisible(e){$e&&($e.style.display=e?"flex":"none")},setMetadataBadgeVisible(e){jt=!e,L&&(L.el.style.display=e&&!he?"":"none")},openUserGuide:vn,setInsightsOpen(e){ct(e),F&&(e?(F.dataset.active="1",F.style.background=x.bgActive,F.style.color=x.iconActive):(delete F.dataset.active,F.style.background="transparent",F.style.color=x.icon))},closeSummaryPanel(){const e=z??R;!e||e.style.display==="none"||(e.style.display="none",I&&(delete I.dataset.active,I.style.background="transparent",I.style.color=x.icon))},setTooltipParent(e){b&&hi(e)},getActiveLegend(){const e=s.plotMode;if(e==="metadata"){const i=s.activeMetadataKey;if(!i)return null;const r=De?.find(l=>l.key===i),u=[...new Set(ae.map(l=>l.metadata?.[i]).filter(l=>l!=null&&(typeof l=="string"||typeof l=="number"||typeof l=="boolean")).map(String))].sort();return u.length?u.map((l,d)=>{const c=r?.values?.find(g=>g.value===l),p=c?.color??Fi(d);return{bin:l,name:c?.label??l,color:p}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?$:G,o=[...new Set(ae.map(i=>t?i.hbin:i.sbin).filter(i=>i!==void 0))].sort((i,r)=>i-r);return o.length?o.map(i=>{const r=n?.find(l=>l.bin===i),u=r?.color??(t?Hi(i):Ai(i));return{bin:i,name:r?.name??`Bin ${i}`,color:u}}):null},destroy(){we?.close(),xe&&clearTimeout(xe),qt?.()?.remove(),gt&&W.removeEventListener("click",gt,!0),a.removeEventListener("wheel",nn),a.removeEventListener("pointerdown",an),a.removeEventListener("pointermove",ln),a.removeEventListener("pointerup",sn),a.removeEventListener("pointerleave",rn),a.removeEventListener("pointercancel",dn),a.removeEventListener("dblclick",yn),a.removeEventListener("keydown",hn),a.removeEventListener("keyup",mn),a.removeEventListener("click",bn),pn.disconnect(),Re.removeEventListener("change",Qe),fn.removeEventListener("change",un),_.removeEventListener("blur",gn),Xn(),b&&ot(W),E?.remove(),pe&&(pe.parentElement?.insertBefore(w,pe),pe.remove()),ee&&(ee.parentElement?.insertBefore(w,ee),ee.remove()),w.remove(),a.style.cursor="",le?.destroy(),L?.destroy(),q.remove()}}}
1
+ import{buildView as oi,buildHoverText as ai,findTestDef as it,resolveTestNumber as Et}from"../renderer/buildView.js";import{toCanvas as si,BIN_LEGEND_W as wn,BIN_LEGEND_W_COMPACT as li,BIN_LEGEND_ADAPT_COMPACT as ri,BIN_LEGEND_ADAPT_FLOATING as di}from"./toCanvas.js";import{buildWaferMap as ci,getTestPassStatus as pi,isParametricTest as Bt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as fi}from"../stats/analyzeWaferMap.js";import{CLR as x,Z_BASE as ui,applyOverlayZ as gi,getTooltip as Sn,hideTooltip as ot,reparentTooltip as hi,positionTooltip as Dt,createToolbarHelpers as mi,buildModeMenuEl as yi,openReparentedModal as bi,openUserGuideWindow as vi,makePaletteBtn as xi,makeLogScaleBtn as wi,makeLegendStyleBtn as Si,makeOverlaysBtn as Ci,makeOrientationBtn as Mi,overlayRootFor as Cn,saveImageBlob as Ei,markMenuTrigger as Ye,wireMenuA11y as Mn,wireExpandToggle as Bi,nextFrame as kt,passFailMenuRows as Di,requestedPassFailDisplay as Lt,logWmapVersionOnce as ki,buildDataModeEntries as Li,metadataKeyHasData as Ti,metadataModeEntry as Pi}from"./toolbar.js";import{createSummaryPanelEl as Tt,wrapWithSummaryPanel as Pt,renderWaferSummaryContent as Oi}from"./summaryPanel.js";import{collectWarnings as Ri,buildWarningsMenuEl as Ii,severityOf as Wi}from"./warnings.js";import"../stats/facets.js";import{ICONS as En}from"./icons.js";import{hardBinColor as Hi,softBinColor as Ai,metadataValueColor as Fi}from"../renderer/colorMap.js";import{createInsightsTab as Yi}from"./insightsTab.js";import{createMetadataBadge as zi}from"./metadataBadge.js";import{getDieKey as Ee,hasPosition as Bn,isPositionedDie as Xi}from"../core/dies.js";import{buildDieListSection as Ni}from"./dieList.js";import{buildMaplessSummary as Ki}from"./maplessSummary.js";const Dn=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode"]);export function classifyChanged(N){const h=N.some(W=>Dn.has(W)),w=N.some(W=>!Dn.has(W));return h&&w?"mixed":h?"preference":"state"}export function renderWaferMap(N,h,w={}){ki();const W=N.ownerDocument,_=W.defaultView??window;_.getComputedStyle(N).position==="static"&&(N.style.position="relative");const kn=N.clientHeight;w.height!=null&&(N.style.height=typeof w.height=="number"?`${w.height}px`:w.height);const at=h.dataCoverage?h.dataCoverage.unpositionedDies:h.dies.filter(e=>!Bn(e)).length,ze=(h.dataCoverage?h.dataCoverage.totalDies:h.dies.length-at)===0&&at>0,q=document.createElement("div");Object.assign(q.style,{position:"relative",width:"100%",height:"100%"}),w.maxSize!=null&&(q.style.maxWidth=`${w.maxSize}px`,q.style.maxHeight=`${w.maxSize}px`),N.appendChild(q);const S=document.createElement("div");Object.assign(S.style,{position:"relative",width:"100%",height:"100%"});const a=document.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),S.appendChild(a),q.appendChild(S);let Xe=null;if(at>0){let n=function(){if(t){const u=Ni(e,h.testDefs,{...w.dieList,onSaveText:w.onSaveText,waferMetadata:J.metadata,metadataFields:se});if(u)return u}const i=it(h.testDefs,l.activeTest??0),r=Bt(i)?l.logScale??i?.logScale??!1:!1;return Ki(e,h.testDefs,{plotMode:l.plotMode??"hardBin",activeTest:l.activeTest,hbinDefs:$,sbinDefs:G,colorScheme:l.colorScheme,logScale:r,colorbarRangeMode:l.colorbarRangeMode,valueRangeDies:h.dies})},o=function(i){const r=document.createElement("button");return r.type="button",Object.assign(r.style,{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",flexShrink:"0",border:`1px solid ${x.menuBorder}`,background:x.menuBg,color:x.text,cursor:"pointer"}),r.textContent=t?"View chart":"View die list",r.addEventListener("click",u=>{u.stopPropagation(),t=!t,r.textContent=t?"View chart":"View die list",i()}),r};const e=h.dies.filter(i=>!Bn(i));let t=!1;if(ze){const i=document.createElement("div");Object.assign(i.style,{position:"absolute",inset:"0",background:x.panelBg,padding:"12px",paddingTop:w.showToolbar??!0?"44px":"12px",boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:"8px",zIndex:"1"});const r=document.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"8px"});const u=document.createElement("span");Object.assign(u.style,{fontSize:"11px",color:x.label,lineHeight:"1.4"}),u.textContent="No die position data for this wafer.",r.appendChild(u);const s=document.createElement("div");Object.assign(s.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(o(()=>s.replaceChildren(n()))),i.appendChild(r),i.appendChild(s),S.appendChild(i),Xe=()=>{t||s.replaceChildren(n())}}else{const i=document.createElement("div");Object.assign(i.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,fontSize:"11px",color:x.text,cursor:"pointer",padding:"4px 8px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"8px"});const r=document.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,i.appendChild(r);const u=document.createElement("span");u.textContent="\u25BE",Object.assign(u.style,{fontSize:"12px",lineHeight:"1",color:x.label,flexShrink:"0"}),i.appendChild(u),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let s=null,d=null;Bi(i,c=>{if(u.textContent=c?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(c)),c){s=document.createElement("div");const p=i.getBoundingClientRect().height||28;Object.assign(s.style,{position:"absolute",left:"0",right:"0",bottom:`${p}px`,top:"20%",zIndex:"2",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column",gap:"8px"}),s.addEventListener("click",Q=>Q.stopPropagation());const g=document.createElement("div");Object.assign(g.style,{display:"flex",justifyContent:"flex-end"}),g.appendChild(o(()=>{d&&d.replaceChildren(n())})),s.appendChild(g),d=document.createElement("div"),Object.assign(d.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),d.appendChild(n()),s.appendChild(d),S.appendChild(s)}else s&&(s.remove(),s=null,d=null)}),S.appendChild(i),Xe=()=>{d&&!t&&d.replaceChildren(n())}}}const{onHover:Ne,onClick:Ln,onSelect:de,onViewOptionsChange:Tn,showTooltip:Pn=!0,showToolbar:he=!0,showMetadataBadge:On=!0,toolbarControls:Ot="full",showPlotModeSelector:Rn=!0,minZoom:In=.4,maxZoom:Wn=20,summaryPanel:Be,renderTooltip:Rt,passBins:It=[1],showHelpButton:Hn=!1,userGuideExtension:An,onExpand:Wt,showExpandButton:Ht=!0,zIndex:Fn,insights:At,warnings:Ft,viewOptions:Yn={},...ce}=w,zn=At?.enabled??!1,Yt=Ft?.display??!0,Xn=gi(Fn);let De=ce.fallbackFormat,ie=w.statsSummary,oe=[],zt=!1;function Xt(){const e=Ri({result:h,statsSummary:ie}),t=e.length!==oe.length||e.some((n,o)=>n.code!==oe[o]?.code||n.message!==oe[o]?.message);oe=e,(t||!zt)&&(zt=!0,Ft?.onWarning?.(e))}Xt();let st=h,J=h.wafer,ae=h.dies,M=new Set,$=h.hbinDefs,G=h.sbinDefs,ee=h.testDefs,se=h.metadataFields,Nt=h.reticles?.length?h.reticles:void 0,Kt=h.reticleConfig,Vt=h.view?.dataAxisFlip,lt=h.isLotStack??!1,rt=h.aggrMethod,dt=h.lotSize,jt=!1,L=null;On&&(L=zi(J.metadata,{lotStack:_t()}),L.isEmpty()||S.appendChild(L.el));function _t(){return lt?{lotSize:dt??1,aggrMethod:rt}:void 0}function Nn(){if(!L)return;L.update(J.metadata,_t());const e=L.el.isConnected;L.isEmpty()&&e?L.el.remove():!L.isEmpty()&&!e&&S.appendChild(L.el)}const $t=[...$??[],...G??[]].some(e=>e.color);let l={plotMode:"hardBin",colorScheme:$t?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:ce.legendPosition??"default",...Yn},le=null,me=!1;zn&&(le=Yi({getItems:()=>[{wafer:J,dies:ae,hbinDefs:$,sbinDefs:G,testDefs:ee,label:String(J.metadata?.waferId??""),statsSummary:ie}],getColorSchemeName:()=>l.colorScheme??"default",passBins:It,getRingCount:()=>l.ringCount??4,onSaveImage:w.onSaveImage,onSaveText:w.onSaveText,defaultView:At?.defaultView,backTab:{label:"Map",onBack:()=>ct(!1)}}),Object.assign(le.el.style,{position:"absolute",inset:"0",background:x.panelBg,overflowY:"auto",paddingTop:he?"44px":"0"}),q.appendChild(le.el));function ct(e){le&&(me=e,le.el.style.display=e?"flex":"none",A&&(A.style.display=e||ze?"none":"flex"),D&&(D.style.display=e?"none":"flex"),Z&&(Z.style.display=e?"none":"flex"),L&&(L.el.style.display=e||jt?"none":""),Ze(),F&&(F.innerHTML=e?En.wafer:En.analysis,F.ariaLabel=e?"Back to wafer view":"Insights"),e&&le.render())}let m,Gt,H=null,T=null,pt=[],ke=null,ft=ce.legendOffset??{x:0,y:0},Le=!1,ye=!1,Te={x:0,y:0},ut={x:0,y:0},pe=!1,be=!1,Y="pan",ve={x:0,y:0},Ke={x:0,y:0},P={x:0,y:0},O={x:0,y:0},Pe=!1,xe=!1;function Oe(){const e=l;m=oi(J,ae.filter(Xi),{plotMode:e.plotMode,colorScheme:e.colorScheme,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:Nt,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:ee,valueRange:e.valueRange,logScale:e.logScale,isLotStack:lt,aggregationMethod:rt??e.aggregationMethod,lotSize:dt??e.lotSize,dataAxisFlip:Vt,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:De,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:se}),Gt=new Map(m.dies.map((t,n)=>[Ee(t),n]))}Oe();let z=null,fe=null,Ve=null,Kn={},R=null,te=null;function Vn(e){const{kind:t,index:n}=e.variable;C(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const o=e.highlight;o.kind==="bin"?(vt(o.dieKeys),C({highlightBin:o.bin})):(o.kind==="region"||o.kind==="dies")&&vt(o.dieKeys)}function Zt(e){Oi(e,{wafer:J,dies:ae,yieldSummary:st.yield,dataCoverage:st.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:ee,statsSummary:ie,warnings:Yt?oe:[],passBins:It,ringCount:l.ringCount??4,colorScheme:l.colorScheme,fallbackFormat:De,activeFindingId:Ve,findingsFilter:Kn,onFindingsFilterChange:ue,onSaveText:w.onSaveText,metadataFields:se,dieListOptions:w.dieList,onFindingClick:(t,n)=>{Ve===t.id?(Ve=null,vt([]),C({highlightBin:void 0})):(Ve=t.id,Vn(t)),ue()}})}function ue(){z&&Zt(z)}function je(){R&&Zt(R)}function Qt(e,t){he&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(Be?.placement){const e=Be.placement;z=Tt(e),Qt(z,e);const t=S.parentElement,n=S.nextSibling;fe=Pt(S,z,e),t?.insertBefore(fe,n),ue()}else if(ie){const e=Be?.defaultOpen??!he;R=Tt("right"),Qt(R,"right"),R.style.display=e?"block":"none";const t=S.parentElement,n=S.nextSibling;te=Pt(S,R,"right"),t?.insertBefore(te,n),je()}const b=Pn?Sn(W):null;let E=null,B=null,A=null,D=null,_e=null,I=null,Z=null,$e=null,F=null,ne=null,Ge=null;function Ut(){if(!ne||!Ge)return;const e=oe.length,t=e>0;if(ne.style.display=t?"flex":"none",Ge.style.display=t?"":"none",!t)return;const n=Wi(oe[0]),o=`${e} data ${e===1?"warning":"warnings"}`;ne.style.color=n==="error"?x.errText:x.warnText,ne.ariaLabel=n==="error"?`${o} \u2014 the map may be positionally wrong`:o}const jn=24;let we=null,gt=null,qt=null,ht=null,mt=null,yt=null,bt=null;function vt(e){M=new Set(e??[]),de&&de(Ct()),v()}function Ze(){if(!I)return;const e=!!(z??R);I.style.display=ie&&e&&!me?"flex":"none";const t=z??R,n=t?t.style.display!=="none":!1;ie?.hasNotableFindings&&!n?I.style.color=x.findingIndicator:I.dataset.active||(I.style.color=x.icon)}if(he){let Q=function(U){Y=U,o(K,U==="zoom"),o(Ie,U==="pan"),_e&&o(_e,U==="select"),a.style.cursor=U==="pan"?"grab":"crosshair"},qe=function(){we&&(clearTimeout(we),we=null),E&&(E.style.opacity="1")},Je=function(){we=setTimeout(()=>{E&&(E.style.opacity="0.35")},600)};E=document.createElement("div"),E.dataset.wmapToolbar="single",Object.assign(E.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"calc(100% - 8px)",background:x.menuBg,border:`1px solid ${x.menuBorder}`,borderRadius:"4px",boxShadow:"0 1px 4px rgba(0,0,0,0.12)",zIndex:ui,opacity:"0.35",transition:"opacity 0.2s ease",pointerEvents:"auto"});const e=Sn(W),t=mi(e),{makeBtn:n,setActive:o,makeSep:i,makeMenuRow:r,makeMenuSection:u,makeDropdown:s,makeCheckMenuBtn:d,closeOpenMenu:c,getOpenMenu:p,setOpenMenu:g}=t;gt=c,qt=p,W.addEventListener("click",c,!0),A=document.createElement("div"),Object.assign(A.style,{display:ze?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(A);const Me=n("download","Download PNG",Gn);A.appendChild(Me),A.appendChild(i());const K=n("zoomMode","Zoom (drag to zoom region)",()=>Q("zoom")),re=n("zoomIn","Zoom in",()=>Ce(a.clientWidth/2,a.clientHeight/2,1.2)),k=n("zoomOut","Zoom out",()=>Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)),V=n("reset","Reset zoom (double-click)",()=>Ue());A.appendChild(K),A.appendChild(re),A.appendChild(k),A.appendChild(V),A.appendChild(i());const Ie=n("pan","Pan (drag to move)",()=>Q("pan"));if(A.appendChild(Ie),_e=n("boxSelect","Select (drag to select dies)",()=>Q("select")),A.appendChild(_e),o(Ie,!0),Ot!=="view-only"){let U=function(f){return f.plotMode!==(l.plotMode??"hardBin")?!1:f.plotMode==="value"?(l.activeTest??0)===(f.activeTest??0):f.plotMode==="metadata"?l.activeMetadataKey===f.activeMetadataKey:!0},We=function(f,y){f.activeTest!==void 0?C({plotMode:f.plotMode,activeTest:f.activeTest,activeMetadataKey:void 0,logScale:f.logScale}):f.activeMetadataKey!==void 0?C({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:f.activeMetadataKey,passFailDisplay:"off"}):C({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),y.remove(),g(null),Ye(j,!1)};B=document.createElement("div"),Object.assign(B.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(B),D=document.createElement("div"),Object.assign(D.style,{display:"flex",alignItems:"center",gap:"0"}),B.appendChild(D),D.appendChild(i());const et=()=>{const f=p();f&&(f.remove(),g(null)),Ye(j,!1)},j=n("mode","Plot mode",()=>{if(p()){et();return}const f=ae,y=m.testDefs,{testEntries:nt,binEntries:ge,stackedEntries:He}=Li(f,y,{includeStacked:m.isLotStack}),Mt=(se??[]).filter(Fe=>Ti(f,Fe.key)).map(Pi),Ae=yi(j.getBoundingClientRect(),nt,ge,He,U,We,{makeMenuRow:r,makeMenuSection:u},l.plotMode??"hardBin",j.ownerDocument.defaultView??window,Mt);Cn(j).appendChild(Ae),g(Ae),Ye(j,!0),Mn(Ae,j,et)});Ye(j,!1);const{btn:Zn,sync:Qn}=xi(t,()=>l.plotMode??"hardBin",()=>l.colorScheme??"default",()=>$t,f=>C({colorScheme:f}));mt=Qn,mt();const Un=Ci(t,()=>{const f=!!m.hasReticle,y=(l.plotMode??"hardBin")==="value",{testNumber:nt}=Et(l.activeTest??0,m.testDefs),ge=it(m.testDefs,nt),He=y&&ge!==void 0&&!Bt(ge),Mt=y&&!He&&(ge?.limitLow!==void 0||ge?.limitHigh!==void 0),Ae=y&&!He&&m.dies.some(Fe=>pi(Fe,nt,ge)!==void 0);return[{label:"Ring boundaries",active:!!l.showRingBoundaries,onClick:()=>C({showRingBoundaries:!l.showRingBoundaries})},{label:"Quadrant lines",active:!!l.showQuadrantBoundaries,onClick:()=>C({showQuadrantBoundaries:!l.showQuadrantBoundaries})},{label:"Die labels",active:!!l.showDieLabels,onClick:()=>C({showDieLabels:!l.showDieLabels})},{label:"Reticle grid",active:!!l.showReticle,enabled:f,onClick:()=>C({showReticle:!l.showReticle})},{label:"XY indicator",active:!!l.showXYIndicator,onClick:()=>C({showXYIndicator:!l.showXYIndicator})},...Di({functionalActive:He,hasLimits:Mt,hasRecorded:Ae,display:Lt(l)},Fe=>C({passFailDisplay:Fe}))]},()=>!!(l.showRingBoundaries||l.showQuadrantBoundaries||l.showDieLabels||l.showReticle||l.showXYIndicator||Lt(l)!=="off")),{btn:qn,sync:Jn}=Si(t,()=>l,f=>C({legendPosition:f}));ht=Jn,ht();const xn=()=>{const{testNumber:f}=Et(l.activeTest??0,ee),y=it(ee,f);return y!==void 0&&!Bt(y)},{btn:ei,sync:ti}=wi(t,()=>({...l,functionalActive:xn()}),f=>C(f));yt=ti,yt();const ni=()=>{const{testNumber:f}=Et(l.activeTest??0,ee),y=it(ee,f);return y!==void 0&&(y.limitLow!==void 0||y.limitHigh!==void 0)},tt=n("specRange","Colorbar range: spec limits",()=>{const f=l.colorbarRangeMode==="data"?"spec":"data";C({colorbarRangeMode:f})});bt=()=>{const f=l.plotMode==="value"&&ni()&&Lt(l)==="off"&&!xn();tt.style.display=f?"":"none";const y=(l.colorbarRangeMode??"spec")==="spec";o(tt,y),tt.ariaLabel=y?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},bt();const ii=Mi(t,()=>l,f=>C(f));Rn&&D.appendChild(j),D.appendChild(Zn),D.appendChild(ei),D.appendChild(tt),ze||(D.appendChild(i()),D.appendChild(Un),D.appendChild(i()),D.appendChild(qn),D.appendChild(i()),D.appendChild(ii)),ie&&(I=n("findings","Summary panel",()=>{const f=z??R;if(!f)return;const y=f.style.display!=="none";f.style.display=y?"none":"block",o(I,!y),Ze()}),B.appendChild(i()),B.appendChild(I),R?.style.display!=="none"&&o(I,!0),Ze()),Yt&&(Ge=i(),ne=n("warning","Data warnings",()=>{const f=p();if(c(new MouseEvent("click")),f)return;const y=Ii(ne.getBoundingClientRect(),oe);Cn(q).appendChild(y),g(y),Mn(y,ne,()=>c(new MouseEvent("click")))}),Ye(ne,!1),B.appendChild(Ge),B.appendChild(ne),Ut()),Ht&&(B.appendChild(i()),Z=n("expand","Expand (E)",Wt??Jt),B.appendChild(Z)),le&&(B.appendChild(i()),F=n("analysis","Insights",()=>{ct(!me),o(F,me)}),F.dataset.wmapInsightsBtn="1",B.appendChild(F)),Hn&&(B.appendChild(i()),$e=n("help","User guide",()=>vn()),B.appendChild($e))}q.appendChild(E),a.addEventListener("mouseenter",qe),a.addEventListener("mouseleave",Je),E.addEventListener("mouseenter",qe),E.addEventListener("mouseleave",Je)}let Se=null;function Jt(){Se&&(Se.close(),Se=null);const e=fe??te??S;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=bi(E?[e,E]:[e],{ownerDocument:W,onClosed:()=>{Se=null,Z&&(Z.style.display="flex"),a.focus({preventScroll:!0})}});t&&(E&&(t.contentWrap.style.position="relative"),Se=t,Z&&(Z.style.display="none"))}function en(e){const t=l.plotMode;if(l={...l,...e},e.plotMode!==void 0&&e.plotMode!==t){H=null;const i=l.plotMode;(i==="hardBin"||i==="softBin")&&!new Set(["default","accessible","custom"]).has(l.colorScheme??"")&&(l={...l,colorScheme:"default"})}Object.keys(e).every(i=>i==="legendPosition")||Oe(),ht?.(),mt?.(),yt?.(),bt?.(),v();const o=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||o)&&(ue(),je()),(e.colorScheme!==void 0||o||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Xe?.()}function C(e){en(e);const t=Object.keys(e);Tn?.(l,t,classifyChanged(t))}let xt=!1;function wt(){xt||(xt=!0,kt(()=>{xt=!1,v()},_))}function v(){const e=T??void 0,t=m.dies[0],n=t?{x:t.width,y:t.height}:ce.diePitchMm,o=Math.floor(a.clientWidth||a.width),i=!!($?.length||G?.length||m.dies.some(p=>p.hbin!=null||p.sbin!=null)),r=l.legendPosition??"default",u=r==="default"||r==="compact",s=(ce.colorbarWidth??16)+28,d=i&&u?r!=="default"?Math.max(wn,s):o<di?0:o<ri?Math.max(li,s):Math.max(wn,s):void 0,c=si(a,m,{...ce,topClearance:he?jn:0,minRightReserve:d,legendPosition:r,legendOffset:ft,diePitchMm:n,fallbackFormat:De,showAxes:ce.showAxes??T!==null,viewport:e,activeBin:l.plotMode==="metadata"?l.highlightMetadataValue:l.highlightBin,hbinDefs:$,sbinDefs:G,metadataFields:se});pt=c.binLegendRows,ke=c.legendBox??null,H||(H=c.viewport),M.size>0&&_n(),be&&$n()}function _n(){const e=X();if(!e)return;const t=a.getContext("2d"),n=m.hoverPoints,o=m.rectangles[0],i=o?o.width/2*e.ppm:e.ppm*.5,r=o?o.height/2*e.ppm:e.ppm*.5,u=Math.max(1,Math.min(3,i*.08)),s=i-u,d=r-u,c=[];for(const p of M){const g=Gt.get(p);g!==void 0&&c.push({sx:e.originX+n[g].x*e.ppm,sy:e.originY-n[g].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-s,g-d,s*2,d*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-s,g-d,s*2,d*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-s,g-d,s*2,d*2);t.stroke(),t.restore()}}function $n(){const e=a.getContext("2d"),t=Math.min(P.x,O.x),n=Math.min(P.y,O.y),o=Math.abs(O.x-P.x),i=Math.abs(O.y-P.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,o,i),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,o,i),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,o,i),e.restore()}function Gn(){a.toBlob(e=>{e&&Ei(e,w.downloadFilename??"wafermap",w.onSaveImage)})}function tn(e){return H?Math.max(H.ppm*In,Math.min(H.ppm*Wn,e)):e}function Ce(e,t,n){const o=T??H;if(!o)return;const i=tn(o.ppm*n),r=i/o.ppm,u=e-(e-o.originX)*r,s=t-(t-o.originY)*r,d=(H?.snapDist??1)/(i/(H?.ppm??i));T={originX:u,originY:s,ppm:i,snapDist:d},v()}function X(){return T??H}function nn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Ce(e.clientX-t.left,e.clientY-t.top,n)}else if(T!==null){e.preventDefault();const t=X(),n=T.snapDist;T={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}function on(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function an(e){if(e.button!==0||!X())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(ke&&l.legendPosition==="floating"&&on(n,o,ke)){ye=!0,Te={x:n,y:o},ut={...ft};return}if(Pe&&Y!=="pan"){xe=!0,pe=!0,ve={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){be=!0,P=O={x:n,y:o};return}pe=!0,ve={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing"}function sn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(be){O={x:n,y:o},wt();return}if(ye){const p=n-Te.x,g=o-Te.y;p*p+g*g>16&&(ye=!1,Le=!0,a.style.cursor="grabbing")}if(Le){ft={x:ut.x+(n-Te.x),y:ut.y+(o-Te.y)},wt();return}if(pe){const p=X(),g=T?.snapDist??H?.snapDist??1;T={originX:Ke.x+(n-ve.x),originY:Ke.y+(o-ve.y),ppm:p.ppm,snapDist:g},wt();return}const i=X();if(!i)return;const r=(n-i.originX)/i.ppm,u=(i.originY-o)/i.ppm,d=cn(r,u,i.snapDist)?.die??null,c=pt.find(p=>n>=p.x&&n<p.x+p.w&&o>=p.y&&o<p.y+p.h);if(c){a.style.cursor="pointer",b&&(b.innerHTML=c.label??`Bin ${c.bin}`,b.style.display="block",Dt(b,a,e.clientX,e.clientY)),Ne?.(null,e);return}if(Y==="pan"&&(a.style.cursor=d?"crosshair":"grab"),b)if(d)if(Rt){const p=Rt(d);p===null?b.style.display="none":(typeof p=="string"?b.innerHTML=p:(b.innerHTML="",b.appendChild(p)),b.style.display="block",Dt(b,a,e.clientX,e.clientY))}else b.innerHTML=ai(d,m.plotMode,{testDefs:ee,hbinDefs:$,sbinDefs:G,fallbackFormat:De,aggrMethod:m.aggrMethod,lotSize:m.lotSize,waferMeta:J.metadata,metadataFields:se,activeTest:m.activeTest,reticleConfig:Kt}),b.style.display="block",Dt(b,a,e.clientX,e.clientY);else b.style.display="none";Ne?.(d,e)}function ln(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,i=e.ctrlKey||e.metaKey;if(b&&(n<0||o<0||n>t.width||o>t.height)&&(b.style.display="none"),be){be=!1,O={x:n,y:o};const s=n-P.x,d=o-P.y,c=X();if(Y==="zoom"){if(s*s+d*d<25)Ce(n,o,2);else if(c){const p=Math.min(P.x,O.x),g=Math.max(P.x,O.x),Q=Math.min(P.y,O.y),Me=Math.max(P.y,O.y),K=g-p,re=Me-Q;if(K>4&&re>4){const k=a.clientWidth,V=a.clientHeight,Ie=k/K,qe=V/re,Je=Math.min(Ie,qe),U=tn(c.ppm*Je),We=U/c.ppm,et=(p+g)/2,j=(Q+Me)/2;T={originX:k/2-(et-c.originX)*We,originY:V/2-(j-c.originY)*We,ppm:U,snapDist:c.snapDist/We}}}v(),a.style.cursor="crosshair";return}if(s*s+d*d<25)St(n,o,i,e);else if(c){const p=(Math.min(P.x,O.x)-c.originX)/c.ppm,g=(Math.max(P.x,O.x)-c.originX)/c.ppm,Q=(c.originY-Math.max(P.y,O.y))/c.ppm,Me=(c.originY-Math.min(P.y,O.y))/c.ppm,K=m.hoverPoints,re=[];for(let k=0;k<K.length;k++)if(K[k].x>=p&&K[k].x<=g&&K[k].y>=Q&&K[k].y<=Me){const V=m.dies[k];V&&re.push(V)}if(i)for(const k of re){const V=Ee(k);M.has(V)?M.delete(V):M.add(V)}else M=new Set(re.map(k=>Ee(k)));de?.(Ct())}v(),a.style.cursor="crosshair";return}if(ye){ye=!1,St(n,o,i,e);return}if(Le){Le=!1,a.style.cursor="grab";return}if(!pe)return;if(pe=!1,xe){xe=!1,a.style.cursor=Pe||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const r=n-ve.x,u=o-ve.y;r*r+u*u<25&&St(n,o,i,e)}function St(e,t,n,o){for(const s of pt)if(e>=s.x&&e<s.x+s.w&&t>=s.y&&t<s.y+s.h){if(typeof s.bin=="number"){const d=l.highlightBin===s.bin?void 0:s.bin;C({highlightBin:d})}else{const d=l.highlightMetadataValue===s.bin?void 0:s.bin;C({highlightMetadataValue:d})}return}if(ke&&on(e,t,ke))return;const i=X();if(!i)return;const u=cn((e-i.originX)/i.ppm,(i.originY-t)/i.ppm,i.snapDist)?.die??null;if(u){Ln?.(u,o);const s=Ee(u);n?M.has(s)?M.delete(s):M.add(s):M=new Set([s]),de?.(Ct()),v()}else n||(M=new Set,de?.([]),v())}function Ct(){const e=[],t=m.hoverPoints;for(let n=0;n<t.length;n++){const o=m.dies[n];o&&M.has(Ee(o))&&e.push(o)}return e}function rn(){b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function dn(){pe=!1,xe=!1,be=!1,ye=!1,Le=!1,b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",v()}function cn(e,t,n){const o=m.hoverPoints,i=m.rectangles;for(let d=0;d<i.length;d++){const c=i[d];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const p=m.dies[d];return p?{die:p,index:d}:null}}let r=null,u=-1,s=n*n;for(let d=0;d<o.length;d++){const c=o[d].x-e,p=o[d].y-t,g=c*c+p*p;g<s&&(s=g,r=m.dies[d]??null,u=d)}return r?{die:r,index:u}:null}const pn=new _.ResizeObserver(()=>{H=null,T=null,v()});pn.observe(a),w.height==null&&kn<=0&&kt(()=>kt(()=>{N.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 Re=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`);const Qe=()=>{Re.removeEventListener("change",Qe),Re=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`),Re.addEventListener("change",Qe),v()};Re.addEventListener("change",Qe);const fn=_.matchMedia("(prefers-color-scheme: dark)"),un=()=>v();fn.addEventListener("change",un);const gn=()=>{b&&ot(W)};_.addEventListener("blur",gn);function hn(e){if(e.key==="Escape"&&M.size>0&&(M=new Set,de?.([]),v()),(e.key==="e"||e.key==="E")&&Ot!=="view-only"&&Ht&&!me&&(e.stopPropagation(),(Wt??Jt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ce(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),Ue())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const o=T?.snapDist??H?.snapDist??1;let i=0,r=0;e.key==="ArrowLeft"&&(i=20,e.preventDefault()),e.key==="ArrowRight"&&(i=-20,e.preventDefault()),e.key==="ArrowUp"&&(r=20,e.preventDefault()),e.key==="ArrowDown"&&(r=-20,e.preventDefault()),(i||r)&&(T={originX:n.originX+i,originY:n.originY+r,ppm:n.ppm,snapDist:o},v())}e.key===" "&&!Pe&&(e.preventDefault(),Pe=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function mn(e){e.key===" "&&(Pe=!1,xe&&(pe=!1,xe=!1),a.style.cursor=Y==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",nn,{passive:!1}),a.addEventListener("pointerdown",an),a.addEventListener("pointermove",sn),a.addEventListener("pointerup",ln),a.addEventListener("pointerleave",rn),a.addEventListener("pointercancel",dn);const yn=()=>Ue();a.addEventListener("dblclick",yn),a.addEventListener("keydown",hn),a.addEventListener("keyup",mn);const bn=e=>{e.stopPropagation()};a.addEventListener("click",bn),a.clientWidth,v(),Xe?.();function Ue(){H=null,T=null,v()}function vn(){import("./userGuideHtml.js").then(e=>vi({buildWaferMap:ci,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:fi},e.USER_GUIDE_HTML,An,N))}return{setDies(e){ae=e,Oe(),v(),z&&ue()},setResult(e){st=e,J=e.wafer,ae=e.dies,$=e.hbinDefs,G=e.sbinDefs,ee=e.testDefs,se=e.metadataFields,Nt=e.reticles?.length?e.reticles:void 0,Kt=e.reticleConfig,Vt=e.view?.dataAxisFlip,lt=e.isLotStack,rt=e.aggrMethod,dt=e.lotSize,Nn(),Oe(),v(),z&&ue()},setOptions(e){en(e)},getOptions(){return{...l}},resetZoom:Ue,setSelection(e){M=new Set(e.map(t=>Ee(t))),v()},clearSelection(){M=new Set,de?.([]),v()},setFallbackFormat(e){De=e,Oe(),v()},setStatsSummary(e){if(ie=e,Xt(),Ut(),z)ue();else if(R)je();else if(e&&!Be?.placement){const t=Be?.defaultOpen??!he;R=Tt("right"),R.style.display=t?"block":"none";const n=S.parentElement,o=S.nextSibling;te=Pt(S,R,"right"),n?.insertBefore(te,o),je()}Ze()},setSummaryVisible(e){I&&(I.style.display=e?"flex":"none")},setViewControlsVisible(e){B&&(B.style.display=e?"flex":"none")},setExpandVisible(e){Z&&(Z.style.display=e?"flex":"none")},setHelpButtonVisible(e){$e&&($e.style.display=e?"flex":"none")},setMetadataBadgeVisible(e){jt=!e,L&&(L.el.style.display=e&&!me?"":"none")},openUserGuide:vn,setInsightsOpen(e){ct(e),F&&(e?(F.dataset.active="1",F.style.background=x.bgActive,F.style.color=x.iconActive):(delete F.dataset.active,F.style.background="transparent",F.style.color=x.icon))},closeSummaryPanel(){const e=z??R;!e||e.style.display==="none"||(e.style.display="none",I&&(delete I.dataset.active,I.style.background="transparent",I.style.color=x.icon))},setTooltipParent(e){b&&hi(e)},getActiveLegend(){const e=l.plotMode;if(e==="metadata"){const i=l.activeMetadataKey;if(!i)return null;const r=se?.find(s=>s.key===i),u=[...new Set(ae.map(s=>s.metadata?.[i]).filter(s=>s!=null&&(typeof s=="string"||typeof s=="number"||typeof s=="boolean")).map(String))].sort();return u.length?u.map((s,d)=>{const c=r?.values?.find(g=>g.value===s),p=c?.color??Fi(d);return{bin:s,name:c?.label??s,color:p}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?$:G,o=[...new Set(ae.map(i=>t?i.hbin:i.sbin).filter(i=>i!==void 0))].sort((i,r)=>i-r);return o.length?o.map(i=>{const r=n?.find(s=>s.bin===i),u=r?.color??(t?Hi(i):Ai(i));return{bin:i,name:r?.name??`Bin ${i}`,color:u}}):null},destroy(){Se?.close(),we&&clearTimeout(we),qt?.()?.remove(),gt&&W.removeEventListener("click",gt,!0),a.removeEventListener("wheel",nn),a.removeEventListener("pointerdown",an),a.removeEventListener("pointermove",sn),a.removeEventListener("pointerup",ln),a.removeEventListener("pointerleave",rn),a.removeEventListener("pointercancel",dn),a.removeEventListener("dblclick",yn),a.removeEventListener("keydown",hn),a.removeEventListener("keyup",mn),a.removeEventListener("click",bn),pn.disconnect(),Re.removeEventListener("change",Qe),fn.removeEventListener("change",un),_.removeEventListener("blur",gn),Xn(),b&&ot(W),E?.remove(),fe&&(fe.parentElement?.insertBefore(S,fe),fe.remove()),te&&(te.parentElement?.insertBefore(S,te),te.remove()),S.remove(),a.style.cursor="",le?.destroy(),L?.destroy(),q.remove()}}}
@@ -1,11 +1,13 @@
1
1
  import type { Wafer } from '../core/wafer.js';
2
2
  import type { Die } from '../core/dies.js';
3
- import { type BinDef, type TestDef, type YieldSummary } from '../renderer/buildWaferMap.js';
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
5
  import { type FindingsFilter } from '../stats/filterFindings.js';
6
6
  import { buildWarningsBanner, type WaferWarning } from './warnings.js';
7
7
  export { buildWarningsBanner };
8
8
  import { type SaveTextHandler } from './toolbar.js';
9
+ import { type DieListDisplayOptions } from './dieList.js';
10
+ import type { WaferMetadata } from '../core/metadata.js';
9
11
  export interface SummaryPanelOptions {
10
12
  /** Which side of the content area to place the panel. Default 'right'. */
11
13
  placement?: 'right' | 'left' | 'top' | 'bottom';
@@ -125,6 +127,26 @@ export declare function buildLotOverviewSection(lotSummary: LotStatsSummary): HT
125
127
  export declare function buildPerWaferYieldSection(lotSummary: LotStatsSummary, items: Array<{
126
128
  label?: string;
127
129
  } | null>, onWaferClick?: (waferIndex: number) => void): HTMLDivElement | null;
130
+ /**
131
+ * Identity context stamped onto a per-test CSV export, so a file that has
132
+ * left the app still says which wafer(s) it describes. Die-level metadata is
133
+ * deliberately absent from these two exports: a row here aggregates over many
134
+ * dies, so no single die-level value exists, and printing one would be a
135
+ * false claim about the data.
136
+ */
137
+ export interface CsvExportContext {
138
+ /** Single-wafer export: one constant leading column per field. */
139
+ waferMetadata?: WaferMetadata;
140
+ /**
141
+ * Pooled (lot) export: only fields identical across every wafer are
142
+ * emitted, via `commonMetadata` — so a mixed-lot pool prints no false
143
+ * "Lot" column.
144
+ */
145
+ perWaferMetadata?: WaferMetadata[];
146
+ /** Plain-language population size, e.g. "12 wafers pooled". Appended to the
147
+ * section title and emitted as a `Population` CSV column. */
148
+ populationLabel?: string;
149
+ }
128
150
  /** CSV field escaper — exported so `dieList.ts` shares it rather than a second copy. */
129
151
  export declare function csvField(value: string): string;
130
152
  export declare function buildTestSection(dies: Die[], testDefs: TestDef[] | undefined, fallbackFormat?: 'si' | 'engineering',
@@ -158,7 +180,9 @@ precomputedTestStats?: {
158
180
  }>;
159
181
  },
160
182
  /** Optional host hook for the "Export CSV" button — see `saveTextFile` (toolbar.ts). */
161
- onSaveText?: SaveTextHandler): HTMLDivElement | null;
183
+ onSaveText?: SaveTextHandler,
184
+ /** Wafer identity to stamp on the CSV export. See {@link CsvExportContext}. */
185
+ csv?: CsvExportContext): HTMLDivElement | null;
162
186
  /**
163
187
  * "Functional Tests" section — one row per functional (`testType: 'F'`) test
164
188
  * with pass/fail counts and pass rate. The functional counterpart of
@@ -173,7 +197,9 @@ onSaveText?: SaveTextHandler): HTMLDivElement | null;
173
197
  */
174
198
  export declare function buildFunctionalTestSection(dies: Die[], testDefs: TestDef[] | undefined, precomputed?: NonNullable<StatsSummary['stats']['functionalYield']>,
175
199
  /** Optional host hook for the "Export CSV" button — see `saveTextFile` (toolbar.ts). */
176
- onSaveText?: SaveTextHandler): HTMLDivElement | null;
200
+ onSaveText?: SaveTextHandler,
201
+ /** Wafer identity to stamp on the CSV export. See {@link CsvExportContext}. */
202
+ csv?: CsvExportContext): HTMLDivElement | null;
177
203
  /**
178
204
  * Lot-pooled "Functional Tests" section: when every wafer's
179
205
  * `StatsSummary.stats.functionalYield` is available, sums pass/fail/total
@@ -245,6 +271,10 @@ export declare function renderWaferSummaryContent(panel: HTMLDivElement, params:
245
271
  findingsFilter?: FindingsFilter;
246
272
  onFindingsFilterChange?: () => void;
247
273
  onSaveText?: SaveTextHandler;
274
+ /** Label/order hints for die metadata columns, e.g. `WaferMapResult.metadataFields`. */
275
+ metadataFields?: MetadataFieldDef[];
276
+ /** See `RenderOptions.dieList` — gates the "View die list" link below. */
277
+ dieListOptions?: DieListDisplayOptions;
248
278
  }): void;
249
279
  /** Render lot-level content into the panel. Clears existing content. */
250
280
  export declare function renderLotSummaryContent(panel: HTMLDivElement, params: {
@@ -254,6 +284,7 @@ export declare function renderLotSummaryContent(panel: HTMLDivElement, params: {
254
284
  wafer?: Wafer;
255
285
  dies?: Die[];
256
286
  statsSummary?: StatsSummary;
287
+ metadataFields?: MetadataFieldDef[];
257
288
  } | null>;
258
289
  hbinDefs?: BinDef[];
259
290
  sbinDefs?: BinDef[];
@@ -270,5 +301,7 @@ export declare function renderLotSummaryContent(panel: HTMLDivElement, params: {
270
301
  onSaveText?: SaveTextHandler;
271
302
  /** See the wafer panel's `warnings` — collected by the renderer so every surface agrees. */
272
303
  warnings?: WaferWarning[];
304
+ /** See `RenderOptions.dieList` — gates the "View die list" link below. */
305
+ dieListOptions?: DieListDisplayOptions;
273
306
  }): void;
274
307
  //# sourceMappingURL=summaryPanel.d.ts.map