@wafertools/wafermap 0.30.1 → 0.30.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +71 -11
- package/CHANGELOG.md +464 -8
- package/README.md +6 -3
- package/dist/packages/canvas-adapter/chartPopulation.d.ts +48 -0
- package/dist/packages/canvas-adapter/chartPopulation.js +1 -0
- package/dist/packages/canvas-adapter/charts/barPanel.d.ts +4 -1
- package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
- package/dist/packages/canvas-adapter/charts/boxplot.d.ts +4 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.js +1 -1
- package/dist/packages/canvas-adapter/charts/chartShell.d.ts +81 -7
- package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
- package/dist/packages/canvas-adapter/charts/correlation.js +2 -2
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.js +1 -1
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/regionYieldDiagram.js +1 -1
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/charts/sweep.d.ts +31 -0
- package/dist/packages/canvas-adapter/charts/sweep.js +1 -0
- package/dist/packages/canvas-adapter/charts/trend.d.ts +3 -1
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/chunked.d.ts +45 -0
- package/dist/packages/canvas-adapter/chunked.js +1 -0
- package/dist/packages/canvas-adapter/dieList.js +2 -2
- package/dist/packages/canvas-adapter/drilldown.d.ts +23 -0
- package/dist/packages/canvas-adapter/drilldown.js +1 -0
- package/dist/packages/canvas-adapter/icons.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.d.ts +55 -3
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +55 -0
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +55 -9
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +30 -2
- package/dist/packages/canvas-adapter/toolbar.js +2 -2
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +126 -3
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.js +1 -1
- package/dist/packages/core/aggregates.js +1 -1
- package/dist/packages/core/utils.d.ts +55 -0
- package/dist/packages/core/utils.js +1 -1
- package/dist/packages/renderer/axisTicks.d.ts +32 -0
- package/dist/packages/renderer/axisTicks.js +1 -0
- package/dist/packages/renderer/binColors.d.ts +14 -0
- package/dist/packages/renderer/binColors.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +11 -37
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +58 -1
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/deprecate.d.ts +13 -5
- package/dist/packages/renderer/deprecate.js +1 -1
- package/dist/packages/renderer/derivedTests/apply.d.ts +85 -0
- package/dist/packages/renderer/derivedTests/apply.js +1 -0
- package/dist/packages/renderer/derivedTests/evaluate.d.ts +48 -0
- package/dist/packages/renderer/derivedTests/evaluate.js +1 -0
- package/dist/packages/renderer/derivedTests/parser.d.ts +148 -0
- package/dist/packages/renderer/derivedTests/parser.js +2 -0
- package/dist/packages/renderer/fmt.d.ts +24 -2
- package/dist/packages/renderer/fmt.js +1 -1
- package/dist/packages/renderer/index.d.ts +1 -0
- package/dist/packages/renderer/index.js +1 -1
- package/dist/packages/renderer/spec.d.ts +49 -0
- package/dist/packages/renderer/spec.js +1 -0
- package/dist/packages/renderer/testLabel.d.ts +154 -0
- package/dist/packages/renderer/testLabel.js +1 -0
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/capability.d.ts +60 -0
- package/dist/packages/stats/capability.js +1 -1
- package/dist/packages/stats/correlation.d.ts +33 -0
- package/dist/packages/stats/correlation.js +1 -1
- package/dist/packages/stats/deprecated.d.ts +3 -0
- package/dist/packages/stats/deprecated.js +1 -1
- package/dist/packages/stats/findingsNarrative.js +1 -1
- package/dist/packages/stats/index.d.ts +2 -2
- package/dist/packages/stats/index.js +1 -1
- package/dist/packages/stats/math.d.ts +27 -2
- package/dist/packages/stats/math.js +1 -1
- package/dist/packages/stats/mergeTestDefs.js +1 -1
- package/dist/packages/stats/renderFindingsReport.js +8 -28
- package/dist/packages/stats/renderSummaryReport.js +22 -31
- package/dist/packages/stats/reportHtml.d.ts +27 -0
- package/dist/packages/stats/reportHtml.js +35 -14
- package/dist/packages/stats/sweep.d.ts +178 -0
- package/dist/packages/stats/sweep.js +1 -0
- package/dist/packages/stats/sweepXFromName.d.ts +27 -0
- package/dist/packages/stats/sweepXFromName.js +1 -0
- package/dist/packages/stats/testPassRate.js +1 -1
- package/dist/packages/stats/types.d.ts +28 -1
- package/llms.txt +14 -8
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildView as vi,buildHoverText as xi,findTestDef as dt,resolveTestNumber as zt,buildMapTitle as Ci}from"../renderer/buildView.js";import{drawMapCanvas as wi,BIN_LEGEND_W as Fn,BIN_LEGEND_W_COMPACT as Si,BIN_LEGEND_ADAPT_COMPACT as Mi,BIN_LEGEND_ADAPT_FLOATING as Ei}from"./toCanvas.js";import{buildWaferMap as Di,getTestPassStatus as Bi,isParametricTest as Yt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as ki}from"../stats/analyzeWaferMap.js";import{SHADOW as Li,LEADING as An,wireControlHover as Hn,SPACE as F,EDGE_GUTTER as Ti,RADIUS as Vn,FONT as ct,CLR as v,applyOverlayZ as Pi,getTooltip as zn,hideTooltip as ft,positionTooltip as Yn,createToolbarHelpers as Oi,buildModeMenuEl as Ri,openReparentedModal as Ii,openUserGuideWindow as Wi,makePaletteBtn as Fi,makeLogScaleBtn as Ai,makeLegendStyleBtn as Hi,makeOverlaysBtn as Vi,makeOrientationBtn as zi,menuLayerFor as Nn,saveImageBlob as Xn,markMenuTrigger as Ke,wireMenuA11y as jn,wireExpandToggle as Yi,nextFrame as Nt,requestedPassFailDisplay as Ni,overlayMenuRows as Xi,anyOverlayActive as ji,logWmapVersionOnce as _i,buildDataModeEntries as Ki,metadataKeyHasData as $i,metadataModeEntry as Gi}from"./toolbar.js";import{waferDisplayLabel as Ui,waferIdentityLabel as Zi}from"../core/waferLabel.js";import{metadataDisplayValue as Qi}from"../core/metadata.js";import{withExportContext as qi,noticeDownloadFilenameChange as Ji}from"./exportName.js";import{createSummaryPanelEl as Xt,wrapWithSummaryPanel as jt,renderWaferSummaryContent as eo}from"./summaryPanel.js";import{collectWarnings as to,buildWarningsMenuEl as no,severityOf as io}from"./warnings.js";import{ICONS as _n}from"./icons.js";import{createIdentityHeader as oo,collapsedLabel as _t}from"./identityHeader.js";import{getDieKey as Be,hasPosition as Kn,isPositionedDie as so}from"../core/dies.js";import{buildDieListSection as lo}from"./dieList.js";import{buildMaplessSummary as ao}from"./maplessSummary.js";import{resolveBinColors as ro,binColorWarning as co}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as fo}from"../core/passBins.js";const $n=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(P){const m=P.some(p=>$n.has(p)),b=P.some(p=>!$n.has(p));return m&&b?"mixed":m?"preference":"state"}export function toPublicViewOptions(P){const{metadataValueOrder:m,binColors:b,lotSize:p,...B}=P;return B}export function renderWaferMap(P,m,b={}){return renderWaferMapCard(P,m,b)}export function renderWaferMapCard(P,m,b={}){_i();const p=P.ownerDocument,B=p.defaultView??window,ke=qi(()=>{const e=Qi(V.metadata?.lot);return{lots:e!==void 0?[e]:[],...ee.isLotStack?{stackedWafers:h?.lotSize??!0}:{wafer:Zi({label:ee.label,wafer:V})}}},b.onSaveImage,b.onSaveText);Ji(b.downloadFilename);function Kt(){const e=h.plotMode==="softBin"||h.plotMode==="stackedSoftBins"?G:$,{primary:t,secondary:n}=Ci(h,d.fallbackFormat,e);return[t,ee.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}B.getComputedStyle(P).position==="static"&&(P.style.position="relative");const Gn=P.clientHeight;b.height!=null&&(P.style.height=typeof b.height=="number"?`${b.height}px`:b.height);const pt=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!Kn(e)).length,$e=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-pt)===0&&pt>0,Le=p.createElement("div");Object.assign(Le.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),P.appendChild(Le);const ye=p.createElement("div");Object.assign(ye.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const ce=b.chromeInset??Ti,K=p.createElement("div");Object.assign(K.style,{display:"flex",alignItems:"stretch",gap:F.sm,background:v.canvasBg,paddingBottom:F.lg,paddingTop:ce,paddingLeft:ce,paddingRight:ce,flexShrink:"0",minWidth:"0"}),Le.appendChild(K),Le.appendChild(ye);function Te(){const e=[...K.children].some(t=>t.style.display!=="none");K.style.display=e?"flex":"none"}const w=p.createElement("div");Object.assign(w.style,{position:"relative",width:"100%",height:"100%"});const s=p.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),w.appendChild(s),ye.appendChild(w);let Ge=null;if(pt>0){let n=function(){if(t){const f=lo(e,m.testDefs,{...b.dieList,onSaveText:ke.onSaveText,waferMetadata:V.metadata,metadataFields:pe,ownerDocument:p});if(f)return f}const o=dt(m.testDefs,d.activeTest??0),r=Yt(o)?d.logScale??o?.logScale??!1:!1;return ao(e,m.testDefs,{plotMode:d.plotMode??"hardBin",activeTest:d.activeTest,hbinDefs:$,sbinDefs:G,binColors:h.binColors,valueColorScheme:d.valueColorScheme,reverseValueScheme:d.reverseValueScheme,logScale:r,colorbarRangeMode:d.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const r=p.createElement("button");return r.type="button",Hn(r),Object.assign(r.style,{fontSize:ct.body,padding:`${F.xxs} ${F.sm}`,borderRadius:Vn.control,flexShrink:"0",border:`1px solid ${v.menuBorder}`,background:v.menuBg,color:v.text,cursor:"pointer"}),r.textContent=t?"View chart":"View die list",r.addEventListener("click",f=>{f.stopPropagation(),t=!t,r.textContent=t?"View chart":"View die list",o()}),r};const e=m.dies.filter(o=>!Kn(o));let t=!1;if($e){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:v.panelBg,padding:F.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:F.md,zIndex:"1"});const r=p.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:F.md});const f=p.createElement("span");Object.assign(f.style,{fontSize:ct.body,color:v.label,lineHeight:An.base}),f.textContent="No die position data for this wafer.",r.appendChild(f);const l=p.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(r),o.appendChild(l),w.appendChild(o),Ge=()=>{t||l.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:v.panelBg,borderTop:`1px solid ${v.menuBorder}`,fontSize:ct.body,color:v.text,cursor:"pointer",padding:`${F.xs} ${F.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:F.md}),Hn(o,"bare");const r=p.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(r);const f=p.createElement("span");f.textContent="\u25BE",Object.assign(f.style,{fontSize:ct.body,lineHeight:An.none,color:v.label,flexShrink:"0"}),o.appendChild(f),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,a=null;Yi(o,c=>{if(f.textContent=c?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(c)),c){l=p.createElement("div");const g=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${g}px`,top:"20%",zIndex:"2",background:v.panelBg,borderTop:`1px solid ${v.menuBorder}`,padding:F.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:F.md}),l.addEventListener("click",se=>se.stopPropagation());const y=p.createElement("div");Object.assign(y.style,{display:"flex",justifyContent:"flex-end"}),y.appendChild(i(()=>{a&&a.replaceChildren(n())})),l.appendChild(y),a=p.createElement("div"),Object.assign(a.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(n()),l.appendChild(a),w.appendChild(l)}else l&&(l.remove(),l=null,a=null)}),w.appendChild(o),Ge=()=>{a&&!t&&a.replaceChildren(n())}}}const{onHover:Ue,onClick:Un,onSelect:fe,onViewOptionsChange:Zn,showTooltip:Qn=!0,showToolbar:Pe=!0,showIdentity:$t=!0,summaryPanel:Oe,showHelpButton:Gt=!1,userGuideExtension:qn,onExpand:Ut,showExpandButton:Zt=!0,zIndex:Jn,insights:ut,warnings:Qt,viewOptions:ei={},...be}=b,Re=ut?.enabled??!1,ti=.4,ni=20,Ze=[...m.passBins??fo],qt=Qt?.display??!0,ii=Pi(Jn);let le=b.statsSummary,ae=[],Jt=!1,Qe=null,en=!1;function gt(){const e=to({result:m,statsSummary:le,extra:Qe?[Qe]:[]}),t=e.length!==ae.length||e.some((n,i)=>n.code!==ae[i]?.code||n.message!==ae[i]?.message);ae=e,(t||!Jt)&&(Jt=!0,Qt?.onWarning?.(e))}gt();let ee=m,V=m.wafer,ve=m.dies,M=new Set,$=m.hbinDefs,G=m.sbinDefs,te=m.testDefs,pe=m.metadataFields,tn=m.reticles?.length?m.reticles:void 0,nn=m.reticleConfig,on=m.view?.dataAxisFlip,ht=m.isLotStack??!1,mt=m.aggrMethod,yt=m.lotSize;const oi=Pe&ℜlet z=null,Q=null,q=null;$t&&(z=oo(_t(V.metadata??{},Ie())??"",V.metadata,{lotStack:Ie(),ownerDocument:p}),w.appendChild(z.metaPanel),z.metaPanel.style.visibility="visible",z.isEmpty()||(Q=sn(z.wrap),K.insertBefore(Q,K.firstChild),Te()));function sn(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${F.sm} ${F.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:F.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function Ie(){return ht?{lotSize:yt??1,aggrMethod:mt}:void 0}function si(){if(!z)return;z.update(_t(V.metadata??{},Ie())??"",V.metadata,Ie());const e=Q?.isConnected??!1,t=!z.isEmpty();!t&&e?(Q.remove(),Q=null):t&&!e&&(Q=sn(z.wrap),Q.style.display="",K.insertBefore(Q,K.firstChild),Te())}const li=[...$??[],...G??[]].some(e=>e.color);let d={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...ei},Y=null,ne=!1,ln=null;function ai(){return Re?Y?Promise.resolve(Y):(ln??=import("./insightsTab.js").then(({createInsightsTab:e})=>(Y=e({getItems:()=>[{wafer:V,dies:ve,hbinDefs:$,sbinDefs:G,testDefs:te,label:Ui({wafer:V},0),passBins:Ze,statsSummary:le}],getBinColors:()=>h.binColors,getRingCount:()=>ee.ringCount??4,onSaveImage:ke.onSaveImage,onSaveText:ke.onSaveText,defaultView:ut?.defaultView,showMetadataStrip:!1,contentInset:ce,backTab:oi?void 0:{label:"Map",onBack:()=>We(!1)},onOpenGuide:Gt&&!Pe?()=>Wt():void 0,focusTest:t=>{E({plotMode:"value",activeTest:t,highlightBin:void 0}),We(!1)},ownerDocument:p}),Object.assign(Y.el.style,{position:"absolute",inset:"0",background:v.canvasBg,overflowY:"auto",paddingTop:"0"}),Y.el.style.display="none",ye.appendChild(Y.el),Y)),ln):Promise.resolve(null)}let an=0;const bt=["wheel","touchstart","pointerdown","keydown"];function ri(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const f of i)B.clearTimeout(f);i.length=0;for(const f of bt)e.removeEventListener(f,o)},r=()=>n||!ne?!0:(e.scrollTop=t,e.scrollTop>=t);if(!r()){for(const f of bt)e.addEventListener(f,o,{passive:!0,once:!0});for(const f of[0,50,150,300,600])i.push(B.setTimeout(()=>{r()},f));i.push(B.setTimeout(()=>{for(const f of bt)e.removeEventListener(f,o)},700))}}function We(e){if(!Re)return;const t=ne;ne=e,Y&&!e&&t&&(an=Y.el.scrollTop),Y&&(Y.el.style.display=e?"flex":"none"),w.style.visibility=e?"hidden":"",A&&(A.style.display=e||$e?"none":"flex"),T&&(T.style.display=e?"none":"flex"),q&&(q.style.display=he?"none":"flex"),ie&&(ie.style.display="flex"),Q&&(Q.style.display=""),Te(),z&&e&&z.collapse(),nt(),H&&(H.innerHTML=e?_n.wafer:_n.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&ai().then(n=>{!n||!ne||(n.el.style.display="flex",n.render(),ri(n.el,an))})}Re&&ut?.defaultOpen&&queueMicrotask(()=>We(!0));let h,rn,N=null,k=null,vt=[],xt;function dn(e){xt!==e&&(xt=e,x())}let Fe=null,Ct=be.legendOffset??{x:0,y:0},Ae=!1,xe=!1,He={x:0,y:0},wt={x:0,y:0},ue=!1,Ce=!1,X="pan",we={x:0,y:0},qe={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Ve=!1,Se=!1;function St(){const e=d;h=vi(V,ve.filter(so),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??ro(ve,{passBins:Ze,binColorScheme:e.binColorScheme,hbinDefs:$,sbinDefs:G,useDefinedBinColors:e.useDefinedBinColors}),passBins:Ze,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:tn,ringCount:ee.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:te,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:ht,aggregationMethod:mt??e.aggregationMethod,lotSize:yt??e.lotSize,dataAxisFlip:on,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:pe}),rn=new Map(h.dies.map((n,i)=>[Be(n),i]));const t=e.binColors?null:co(h.binColors,h.plotMode);t?.message!==Qe?.message&&(Qe=t,gt(),en&&Mt())}St();let U=null,Me=null,Je=null,cn=b.findingsNotice,di={},I=null,re=null;function ci(e){const{kind:t,index:n}=e.variable;E(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const i=e.highlight;i.kind==="bin"?(Tt(i.dieKeys),E({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Tt(i.dieKeys)}function fn(e){eo(e,{wafer:V,dies:ve,yieldSummary:ee.yield,dataCoverage:ee.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:te,statsSummary:le,warnings:qt?ae:[],passBins:Ze,ringCount:ee.ringCount??4,binColors:h.binColors,plotMode:d.plotMode??"hardBin",metadataShownElsewhere:$t,fallbackFormat:d.fallbackFormat,activeFindingId:Je,findingsFilter:di,findingsNotice:cn,onFindingsFilterChange:ge,onSaveText:ke.onSaveText,metadataFields:pe,dieListOptions:b.dieList,onFindingClick:(t,n)=>{Je===t.id?(Je=null,Tt([]),E({highlightBin:void 0})):(Je=t.id,ci(t)),ge()}})}function ge(){U&&fn(U)}function ze(){I&&fn(I)}if(Oe?.placement){const e=Oe.placement;U=Xt(e,ce,p);const t=w.parentElement,n=w.nextSibling;Me=jt(w,U,e),t?.insertBefore(Me,n),ge()}else if(le){const e=Oe?.defaultOpen??!Pe;I=Xt("right",ce,p),I.style.display=e?"block":"none";const t=w.parentElement,n=w.nextSibling;re=jt(w,I,"right"),t?.insertBefore(re,n),ze()}const W=Qn?zn(p):null;let ie=null,L=null,A=null,T=null,et=null,j=null,pn=null,H=null,oe=null,tt=null;en=!0;function Mt(){if(!oe||!tt)return;const e=ae.length,t=e>0;if(oe.style.display=t?"flex":"none",tt.style.display=t?"":"none",!t)return;const n=io(ae[0]),i=`${e} data ${e===1?"warning":"warnings"}`;oe.style.color=n==="error"?v.errText:v.warnText,oe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Et=null,un=null,Dt=null,Bt=null,kt=null,Lt=null;function Tt(e){M=new Set(e??[]),fe&&fe(It()),x()}function nt(){if(!j)return;const e=!!(U??I);j.style.display=le&&e&&!ne?"flex":"none";const t=U??I,n=t?t.style.display!=="none":!1;le?.hasNotableFindings&&!n?j.style.color=v.findingIndicator:j.dataset.active||(j.style.color=v.icon)}let gn=null;function hn(e){const t=U??I;t&&(t.style.display=e?"block":"none",j&&gn?.(j,e),nt())}if(Pe){let g=function(D){X=D,i(se,D==="zoom"),i(S,D==="pan"),et&&i(et,D==="select"),s.style.cursor=D==="pan"?"grab":"crosshair"};ie=p.createElement("div"),ie.dataset.wmapToolbar="single",Object.assign(ie.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:v.menuBg,border:`1px solid ${v.menuBorder}`,borderRadius:Vn.control,boxShadow:Li.panel,pointerEvents:"auto"});const e=zn(p),t=Oi(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:r,makeMenuSection:f,closeOpenMenu:l,getOpenMenu:a,setOpenMenu:c}=t;gn=i,Et=l,un=a,p.addEventListener("click",l,!0),A=p.createElement("div"),Object.assign(A.style,{display:$e?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(A);const y=n("download","Download PNG",ui);A.appendChild(y),A.appendChild(o());const se=n("zoomMode","Zoom (drag to zoom region)",()=>g("zoom")),De=n("zoomIn","Zoom in",()=>Ee(s.clientWidth/2,s.clientHeight/2,1.2)),J=n("zoomOut","Zoom out",()=>Ee(s.clientWidth/2,s.clientHeight/2,1/1.2)),de=n("reset","Reset zoom (double-click)",()=>ot());A.appendChild(se),A.appendChild(De),A.appendChild(J),A.appendChild(de),A.appendChild(o());const S=n("pan","Pan (drag to move)",()=>g("pan"));A.appendChild(S),et=n("boxSelect","Select (drag to select dies)",()=>g("select")),A.appendChild(et),i(S,!0);{let D=function(u){return u.plotMode!==(d.plotMode??"hardBin")?!1:u.plotMode==="value"?(d.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?d.activeMetadataKey===u.activeMetadataKey:!0},Ft=function(u,C){u.activeTest!==void 0?E({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?E({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):E({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),C.remove(),c(null),Ke(Z,!1)};L=p.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(L),T=p.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const st=()=>{const u=a();u&&(u.remove(),c(null)),Ke(Z,!1)},Z=n("mode","Plot mode",()=>{if(a()){st();return}const u=ve,C=h.testDefs,{testEntries:rt,binEntries:me,stackedEntries:Xe}=Ki(u,C,{includeStacked:h.isLotStack}),Vt=(pe??[]).filter(_e=>$i(u,_e.key)).map(Gi),je=Ri(Z.getBoundingClientRect(),rt,me,Xe,D,Ft,{makeMenuRow:r,makeMenuSection:f},d.plotMode??"hardBin",Z.ownerDocument.defaultView??window,Vt);Nn(Z).appendChild(je),c(je),Ke(Z,!0),jn(je,Z,st)});Ke(Z,!1);const{btn:lt,sync:Ne}=Fi(t,()=>({...d,plotMode:d.plotMode??"hardBin"}),()=>li,E);Bt=Ne,Bt();const At=Vi(t,()=>{const u=!!h.hasReticle,C=(d.plotMode??"hardBin")==="value",{testNumber:rt}=zt(d.activeTest??0,h.testDefs),me=dt(h.testDefs,rt),Xe=C&&me!==void 0&&!Yt(me),Vt=C&&!Xe&&(me?.limitLow!==void 0||me?.limitHigh!==void 0),je=C&&!Xe&&h.dies.some(_e=>Bi(_e,rt,me)!==void 0);return Xi(d,u,{functionalActive:Xe,hasLimits:Vt,hasRecorded:je,binMode:(d.plotMode??"hardBin")==="hardBin"||(d.plotMode??"hardBin")==="softBin"},_e=>E(_e))},()=>ji(d)),{btn:Ht,sync:gi}=Hi(t,()=>d,u=>E({legendPosition:u}));Dt=gi,Dt();const Wn=()=>{const{testNumber:u}=zt(d.activeTest??0,te),C=dt(te,u);return C!==void 0&&!Yt(C)},{btn:hi,sync:mi}=Ai(t,()=>({...d,functionalActive:Wn()}),u=>E(u));kt=mi,kt();const yi=()=>{const{testNumber:u}=zt(d.activeTest??0,te),C=dt(te,u);return C!==void 0&&(C.limitLow!==void 0||C.limitHigh!==void 0)},at=n("specRange","Colorbar range: spec limits",()=>{const u=d.colorbarRangeMode==="data"?"spec":"data";E({colorbarRangeMode:u})});Lt=()=>{const u=d.plotMode==="value"&&yi()&&Ni(d)==="off"&&!Wn();at.style.display=u?"":"none";const C=(d.colorbarRangeMode??"spec")==="spec";i(at,C),at.ariaLabel=C?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},Lt();const bi=zi(t,()=>d,u=>E(u));T.appendChild(Z),T.appendChild(lt),T.appendChild(hi),T.appendChild(at),$e||(T.appendChild(o()),T.appendChild(At),T.appendChild(o()),T.appendChild(Ht),T.appendChild(o()),T.appendChild(bi)),le&&(j=n("findings","Summary panel",()=>{const u=U??I;u&&hn(u.style.display==="none")}),L.appendChild(o()),L.appendChild(j),I?.style.display!=="none"&&i(j,!0),nt()),qt&&(tt=o(),oe=n("warning","Data warnings",()=>{const u=a();if(l(new MouseEvent("click")),u)return;const C=no(oe.getBoundingClientRect(),ae,B);Nn(ye).appendChild(C),c(C),jn(C,oe,()=>l(new MouseEvent("click")))}),Ke(oe,!1),L.appendChild(tt),L.appendChild(oe),Mt()),Re&&(L.appendChild(o()),H=n("analysis","Insights",()=>{We(!ne),i(H,ne)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),Zt&&(L.appendChild(o()),q=n("expand","Expand (E)",Ut??mn),L.appendChild(q)),Gt&&(L.appendChild(o()),pn=n("help","User guide",()=>Wt()),L.appendChild(pn))}K.appendChild(ie),Te()}let he=null;function mn(){he&&(he.close(),he=null);const e=ye;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=_t(V.metadata??{},Ie()),n=K.childElementCount>0?[K,e]:[e],i=Ii(n,{ownerDocument:p,boxSize:ne?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{he=null,q&&(q.style.display="flex"),ne||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),he=i,q&&(q.style.display="none"))}function yn(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&d.binColors!==void 0&&(e={...e,binColors:void 0});const t=d.plotMode;d={...d,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(r=>r==="legendPosition"||r==="showLegend"||r==="markFailingDies")||St(),Dt?.(),Bt?.(),kt?.(),Lt?.(),x();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(r=>r in e);(o||i)&&(ge(),ze()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Ge?.()}function E(e){yn(e);const t=Object.keys(e);Zn?.(d,t,classifyChanged(t))}let Pt=!1;function Ot(){Pt||(Pt=!0,Nt(()=>{Pt=!1,x()},B))}function x(){const e=k??void 0,t=h.dies[0],n=t?{x:t.width,y:t.height}:be.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!($?.length||G?.length||h.dies.some(y=>y.hbin!=null||y.sbin!=null)),r=d.legendPosition??"default",f=d.showLegend??!0,l=r==="default"||r==="compact",a=(be.colorbarWidth??16)+28,c=o&&l?r!=="default"?Math.max(Fn,a):i<Ei?0:i<Mi?Math.max(Si,a):Math.max(Fn,a):void 0,g=wi(s,h,{...be,minRightReserve:f?c:0,showColorbar:f&&(be.showColorbar??!0),markFailingDies:d.markFailingDies??!1,legendPosition:r,legendOffset:Ct,diePitchMm:n,fallbackFormat:d.fallbackFormat,showAxes:be.showAxes??k!==null,viewport:e,activeBin:d.plotMode==="metadata"?d.highlightMetadataValue:d.highlightBin,hoverBin:xt,hbinDefs:$,sbinDefs:G,metadataFields:pe});vt=g.binLegendRows,Fe=g.legendBox??null,k===null&&(N=g.viewport),M.size>0&&fi(),Ce&&pi()}function fi(){const e=_();if(!e)return;const t=s.getContext("2d"),n=h.hoverPoints,i=h.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,r=i?i.height/2*e.ppm:e.ppm*.5,f=Math.max(1,Math.min(3,o*.08)),l=o-f,a=r-f,c=[];for(const g of M){const y=rn.get(g);y!==void 0&&c.push({sx:e.originX+n[y].x*e.ppm,sy:e.originY-n[y].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:g,sy:y}of c)t.rect(g-l,y-a,l*2,a*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:g,sy:y}of c)t.rect(g-l,y-a,l*2,a*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:g,sy:y}of c)t.rect(g-l,y-a,l*2,a*2);t.stroke(),t.restore()}}function pi(){const e=s.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),i=Math.abs(R.x-O.x),o=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,i,o),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,i,o),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,i,o),e.restore()}function ui(){s.toBlob(e=>{e&&(b.downloadFilename!=null?Xn(e,b.downloadFilename,b.onSaveImage):Xn(e,Kt(),ke.onSaveImage))})}function bn(e){return N?Math.max(N.ppm*ti,Math.min(N.ppm*ni,e)):e}function Ee(e,t,n){const i=k??N;if(!i)return;const o=bn(i.ppm*n),r=o/i.ppm,f=e-(e-i.originX)*r,l=t-(t-i.originY)*r,a=(N?.snapDist??1)/(o/(N?.ppm??o));k={originX:f,originY:l,ppm:o,snapDist:a},x()}function _(){return k??N}function vn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Ee(e.clientX-t.left,e.clientY-t.top,n)}else if(k!==null){e.preventDefault();const t=_(),n=k.snapDist;k={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},x()}}function xn(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function Cn(e){if(e.button!==0||!_())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Fe&&d.legendPosition==="floating"&&xn(n,i,Fe)){xe=!0,He={x:n,y:i},wt={...Ct};return}if(Ve&&X!=="pan"){Se=!0,ue=!0,we={x:n,y:i},qe={x:_().originX,y:_().originY},s.style.cursor="grabbing";return}if(X==="zoom"||X==="select"){Ce=!0,O=R={x:n,y:i};return}ue=!0,we={x:n,y:i},qe={x:_().originX,y:_().originY},s.style.cursor="grabbing"}function wn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ce){R={x:n,y:i},Ot();return}if(xe){const g=n-He.x,y=i-He.y;g*g+y*y>16&&(xe=!1,Ae=!0,s.style.cursor="grabbing")}if(Ae){Ct={x:wt.x+(n-He.x),y:wt.y+(i-He.y)},Ot();return}if(ue){const g=_(),y=k?.snapDist??N?.snapDist??1;k={originX:qe.x+(n-we.x),originY:qe.y+(i-we.y),ppm:g.ppm,snapDist:y},Ot();return}const o=_();if(!o)return;const r=(n-o.originX)/o.ppm,f=(o.originY-i)/o.ppm,a=Dn(r,f,o.snapDist)?.die??null,c=vt.find(g=>n>=g.x&&n<g.x+g.w&&i>=g.y&&i<g.y+g.h);if(dn(c?c.bin:void 0),c){s.style.cursor="pointer",W&&(W.textContent=c.label??`Bin ${c.bin}`,W.style.display="block",Yn(W,s,e.clientX,e.clientY)),Ue?.(null,e);return}X==="pan"&&(s.style.cursor=a?"crosshair":"grab"),W&&(a?(W.innerHTML=xi(a,h.plotMode,{testDefs:te,hbinDefs:$,sbinDefs:G,fallbackFormat:d.fallbackFormat,aggrMethod:h.aggrMethod,lotSize:h.lotSize,metadataFields:pe,activeTest:h.activeTest,reticleConfig:nn}),W.style.display="block",Yn(W,s,e.clientX,e.clientY)):W.style.display="none"),Ue?.(a,e)}function Sn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(W&&(n<0||i<0||n>t.width||i>t.height)&&(W.style.display="none"),Ce){Ce=!1,R={x:n,y:i};const l=n-O.x,a=i-O.y,c=_();if(X==="zoom"){if(l*l+a*a<25)Ee(n,i,2);else if(c){const g=Math.min(O.x,R.x),y=Math.max(O.x,R.x),se=Math.min(O.y,R.y),De=Math.max(O.y,R.y),J=y-g,de=De-se;if(J>4&&de>4){const S=s.clientWidth,D=s.clientHeight,Ft=S/J,st=D/de,Z=Math.min(Ft,st),lt=bn(c.ppm*Z),Ne=lt/c.ppm,At=(g+y)/2,Ht=(se+De)/2;k={originX:S/2-(At-c.originX)*Ne,originY:D/2-(Ht-c.originY)*Ne,ppm:lt,snapDist:c.snapDist/Ne}}}x(),s.style.cursor="crosshair";return}if(l*l+a*a<25)Rt(n,i,o,e);else if(c){const g=(Math.min(O.x,R.x)-c.originX)/c.ppm,y=(Math.max(O.x,R.x)-c.originX)/c.ppm,se=(c.originY-Math.max(O.y,R.y))/c.ppm,De=(c.originY-Math.min(O.y,R.y))/c.ppm,J=h.hoverPoints,de=[];for(let S=0;S<J.length;S++)if(J[S].x>=g&&J[S].x<=y&&J[S].y>=se&&J[S].y<=De){const D=h.dies[S];D&&de.push(D)}if(o)for(const S of de){const D=Be(S);M.has(D)?M.delete(D):M.add(D)}else M=new Set(de.map(S=>Be(S)));fe?.(It())}x(),s.style.cursor="crosshair";return}if(xe){xe=!1,Rt(n,i,o,e);return}if(Ae){Ae=!1,s.style.cursor="grab";return}if(!ue)return;if(ue=!1,Se){Se=!1,s.style.cursor=Ve||X==="pan"?"grab":"crosshair";return}s.style.cursor=X==="pan"?"grab":"crosshair";const r=n-we.x,f=i-we.y;r*r+f*f<25&&Rt(n,i,o,e)}function Rt(e,t,n,i){for(const l of vt)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const a=d.highlightBin===l.bin?void 0:l.bin;E({highlightBin:a})}else{const a=d.highlightMetadataValue===l.bin?void 0:l.bin;E({highlightMetadataValue:a})}return}if(Fe&&xn(e,t,Fe))return;const o=_();if(!o)return;const f=Dn((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(f){Un?.(f,i);const l=Be(f);n?M.has(l)?M.delete(l):M.add(l):M=new Set([l]),fe?.(It()),x()}else n||(M=new Set,fe?.([]),x())}function It(){const e=[],t=h.hoverPoints;for(let n=0;n<t.length;n++){const i=h.dies[n];i&&M.has(Be(i))&&e.push(i)}return e}function Mn(){dn(void 0),W&&ft(p),Ue?.(null,new MouseEvent("mouseleave")),s.style.cursor=X==="pan"?"grab":"crosshair"}function En(){ue=!1,Se=!1,Ce=!1,xe=!1,Ae=!1,W&&ft(p),Ue?.(null,new MouseEvent("mouseleave")),s.style.cursor=X==="pan"?"grab":"crosshair",x()}function Dn(e,t,n){const i=h.hoverPoints,o=h.rectangles;for(let a=0;a<o.length;a++){const c=o[a];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const g=h.dies[a];return g?{die:g,index:a}:null}}let r=null,f=-1,l=n*n;for(let a=0;a<i.length;a++){const c=i[a].x-e,g=i[a].y-t,y=c*c+g*g;y<l&&(l=y,r=h.dies[a]??null,f=a)}return r?{die:r,index:f}:null}const Bn=new B.ResizeObserver(()=>{N=null,k=null,x()});Bn.observe(s),b.height==null&&Gn<=0&&Nt(()=>Nt(()=>{P.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let Ye=B.matchMedia(`(resolution: ${B.devicePixelRatio}dppx)`);const it=()=>{Ye.removeEventListener("change",it),Ye=B.matchMedia(`(resolution: ${B.devicePixelRatio}dppx)`),Ye.addEventListener("change",it),x()};Ye.addEventListener("change",it);const kn=B.matchMedia("(prefers-color-scheme: dark)"),Ln=()=>x();kn.addEventListener("change",Ln);const Tn=()=>{W&&ft(p)};B.addEventListener("blur",Tn);function Pn(e){if(e.key==="Escape"&&M.size>0&&(M=new Set,fe?.([]),x()),(e.key==="e"||e.key==="E")&&Zt&&(e.stopPropagation(),(Ut??mn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Ee(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Ee(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),ot())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=_();if(n){const i=k?.snapDist??N?.snapDist??1;let o=0,r=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(r=20,e.preventDefault()),e.key==="ArrowDown"&&(r=-20,e.preventDefault()),(o||r)&&(k={originX:n.originX+o,originY:n.originY+r,ppm:n.ppm,snapDist:i},x())}e.key===" "&&!Ve&&(e.preventDefault(),Ve=!0,X!=="pan"&&(s.style.cursor="grab"))}}function On(e){e.key===" "&&(Ve=!1,Se&&(ue=!1,Se=!1),s.style.cursor=X==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",vn,{passive:!1}),s.addEventListener("pointerdown",Cn),s.addEventListener("pointermove",wn),s.addEventListener("pointerup",Sn),s.addEventListener("pointerleave",Mn),s.addEventListener("pointercancel",En);const Rn=()=>ot();s.addEventListener("dblclick",Rn),s.addEventListener("keydown",Pn),s.addEventListener("keyup",On);const In=e=>{e.stopPropagation()};s.addEventListener("click",In),s.clientWidth,x(),Ge?.();function ot(){N=null,k=null,x()}function Wt(){import("./userGuideHtml.js").then(e=>Wi({buildWaferMap:Di,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:ki},e.USER_GUIDE_HTML,qn,P))}return Te(),{setResult(e){ee=e,V=e.wafer,ve=e.dies,$=e.hbinDefs,G=e.sbinDefs,te=e.testDefs,pe=e.metadataFields,tn=e.reticles?.length?e.reticles:void 0,nn=e.reticleConfig,on=e.view?.dataAxisFlip,ht=e.isLotStack,mt=e.aggrMethod,yt=e.lotSize,si(),St(),x(),U&&ge()},setOptions(e){yn(e)},getOptions(){return{...d}},resetZoom:ot,setSelection(e){M=new Set(e.map(t=>Be(t))),x()},clearSelection(){M=new Set,fe?.([]),x()},setFindingsNotice(e){cn=e,U?ge():I&&ze()},setStatsSummary(e){if(le=e,gt(),Mt(),U)ge();else if(I)ze();else if(e&&!Oe?.placement){const t=Oe?.defaultOpen??!Pe;I=Xt("right",ce,p),I.style.display=t?"block":"none";const n=w.parentElement,i=w.nextSibling;re=jt(w,I,"right"),n?.insertBefore(re,i),ze()}nt()},closeSummaryPanel(){hn(!1)},getExportTitle(){return Kt()},getBinColors(){return h.binColors},setSummaryVisible(e){j&&(j.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){q&&(q.style.display=e?"flex":"none")},openUserGuide:Wt,setInsightsOpen(e){We(e),H&&(e?(H.dataset.active="1",H.style.background=v.bgActive,H.style.color=v.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=v.icon))},destroy(){he?.close(),un?.()?.remove(),Et&&p.removeEventListener("click",Et,!0),s.removeEventListener("wheel",vn),s.removeEventListener("pointerdown",Cn),s.removeEventListener("pointermove",wn),s.removeEventListener("pointerup",Sn),s.removeEventListener("pointerleave",Mn),s.removeEventListener("pointercancel",En),s.removeEventListener("dblclick",Rn),s.removeEventListener("keydown",Pn),s.removeEventListener("keyup",On),s.removeEventListener("click",In),Bn.disconnect(),Ye.removeEventListener("change",it),kn.removeEventListener("change",Ln),B.removeEventListener("blur",Tn),ii(),W&&ft(p),ie?.remove(),Me&&(Me.parentElement?.insertBefore(w,Me),Me.remove()),re&&(re.parentElement?.insertBefore(w,re),re.remove()),w.remove(),s.style.cursor="",Y?.destroy(),z?.destroy(),Le.remove()}}}
|
|
1
|
+
import{buildView as Oi,buildHoverText as Ri,findTestDef as gt,resolveTestNumber as _t,buildMapTitle as Ii}from"../renderer/buildView.js";import{drawMapCanvas as Wi,BIN_LEGEND_W as $n,BIN_LEGEND_W_COMPACT as Fi,BIN_LEGEND_ADAPT_COMPACT as Ai,BIN_LEGEND_ADAPT_FLOATING as Hi}from"./toCanvas.js";import{buildWaferMap as zi,getTestPassStatus as Vi,isParametricTest as $t}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Yi}from"../stats/analyzeWaferMap.js";import{SHADOW as Xi,LEADING as Gn,wireControlHover as Un,SPACE as A,EDGE_GUTTER as Ni,RADIUS as Zn,FONT as mt,CLR as w,applyOverlayZ as ji,getTooltip as Qn,hideTooltip as yt,positionTooltip as qn,createToolbarHelpers as Ki,buildModeMenuEl as _i,openReparentedModal as $i,openUserGuideWindow as Gi,makePaletteBtn as Ui,makeLogScaleBtn as Zi,makeLegendStyleBtn as Qi,makeOverlaysBtn as qi,makeOrientationBtn as Ji,menuLayerFor as Jn,saveImageBlob as ei,markMenuTrigger as Qe,wireMenuA11y as ti,wireExpandToggle as eo,nextFrame as Gt,requestedPassFailDisplay as to,overlayMenuRows as no,anyOverlayActive as io,logWmapVersionOnce as oo,buildDataModeEntries as so,metadataKeyHasData as lo,metadataModeEntry as ao}from"./toolbar.js";import{waferIdentityLabel as ro}from"../core/waferLabel.js";import{metadataDisplayValue as co}from"../core/metadata.js";import{withExportContext as fo,noticeDownloadFilenameChange as po}from"./exportName.js";import{createSummaryPanelEl as Ut,wrapWithSummaryPanel as Zt,renderWaferSummaryContentSteps as uo}from"./summaryPanel.js";import{runChunked as ho}from"./chunked.js";import{collectWarnings as go,buildWarningsMenuEl as mo,severityOf as yo}from"./warnings.js";import{ICONS as ni}from"./icons.js";import{hasDrilldownTargets as bo,selectionPopulation as vo,waferPopulation as xo}from"./chartPopulation.js";import{createIdentityHeader as wo,collapsedLabel as Qt}from"./identityHeader.js";import{getDieKey as fe,hasPosition as ii,isPositionedDie as Co}from"../core/dies.js";import{buildDieListSection as So}from"./dieList.js";import{buildMaplessSummary as Mo}from"./maplessSummary.js";import{resolveBinColors as Eo,binColorWarning as Do}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as ko}from"../core/passBins.js";const oi=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(P){const m=P.some(p=>oi.has(p)),v=P.some(p=>!oi.has(p));return m&&v?"mixed":m?"preference":"state"}export function toPublicViewOptions(P){const{metadataValueOrder:m,binColors:v,lotSize:p,...k}=P;return k}export function renderWaferMap(P,m,v={}){return renderWaferMapCard(P,m,v)}export function renderWaferMapCard(P,m,v={}){oo();const p=P.ownerDocument,k=p.defaultView??window,qt=()=>q.label,Jt=()=>ro({label:qt(),wafer:V}),xe=fo(()=>{const e=co(V.metadata?.lot);return{lots:e!==void 0?[e]:[],...q.isLotStack?{stackedWafers:g?.lotSize??!0}:{wafer:Jt()}}},v.onSaveImage,v.onSaveText);po(v.downloadFilename);function en(){const e=g.plotMode==="softBin"||g.plotMode==="stackedSoftBins"?G:$,{primary:t,secondary:n}=Ii(g,c.fallbackFormat,e);return[t,q.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}k.getComputedStyle(P).position==="static"&&(P.style.position="relative");const si=P.clientHeight;v.height!=null&&(P.style.height=typeof v.height=="number"?`${v.height}px`:v.height);const bt=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!ii(e)).length,Oe=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-bt)===0&&bt>0,Re=p.createElement("div");Object.assign(Re.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),P.appendChild(Re);const we=p.createElement("div");Object.assign(we.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const pe=v.chromeInset??Ni,_=p.createElement("div");Object.assign(_.style,{display:"flex",alignItems:"stretch",gap:A.sm,background:w.canvasBg,paddingBottom:A.lg,paddingTop:pe,paddingLeft:pe,paddingRight:pe,flexShrink:"0",minWidth:"0"}),Re.appendChild(_),Re.appendChild(we);function Ie(){const e=[..._.children].some(t=>t.style.display!=="none");_.style.display=e?"flex":"none"}const M=p.createElement("div");Object.assign(M.style,{position:"relative",width:"100%",height:"100%"});const s=p.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),M.appendChild(s),we.appendChild(M);let qe=null;if(bt>0){let n=function(){if(t){const d=So(e,m.testDefs,{...v.dieList,onSaveText:xe.onSaveText,waferMetadata:V.metadata,metadataFields:he,ownerDocument:p});if(d)return d}const o=gt(m.testDefs,c.activeTest??0),a=$t(o)?c.logScale??o?.logScale??!1:!1;return Mo(e,m.testDefs,{plotMode:c.plotMode??"hardBin",activeTest:c.activeTest,hbinDefs:$,sbinDefs:G,binColors:g.binColors,valueColorScheme:c.valueColorScheme,reverseValueScheme:c.reverseValueScheme,logScale:a,colorbarRangeMode:c.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const a=p.createElement("button");return a.type="button",Un(a),Object.assign(a.style,{fontSize:mt.body,padding:`${A.xxs} ${A.sm}`,borderRadius:Zn.control,flexShrink:"0",border:`1px solid ${w.menuBorder}`,background:w.menuBg,color:w.text,cursor:"pointer"}),a.textContent=t?"View chart":"View die list",a.addEventListener("click",d=>{d.stopPropagation(),t=!t,a.textContent=t?"View chart":"View die list",o()}),a};const e=m.dies.filter(o=>!ii(o));let t=!1;if(Oe){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:w.panelBg,padding:A.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:A.md,zIndex:"1"});const a=p.createElement("div");Object.assign(a.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:A.md});const d=p.createElement("span");Object.assign(d.style,{fontSize:mt.body,color:w.label,lineHeight:Gn.base}),d.textContent="No die position data for this wafer.",a.appendChild(d);const l=p.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(a),o.appendChild(l),M.appendChild(o),qe=()=>{t||l.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,fontSize:mt.body,color:w.text,cursor:"pointer",padding:`${A.xs} ${A.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:A.md}),Un(o,"bare");const a=p.createElement("span");a.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(a);const d=p.createElement("span");d.textContent="\u25BE",Object.assign(d.style,{fontSize:mt.body,lineHeight:Gn.none,color:w.label,flexShrink:"0"}),o.appendChild(d),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,r=null;eo(o,f=>{if(d.textContent=f?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(f)),f){l=p.createElement("div");const h=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${h}px`,top:"20%",zIndex:"2",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,padding:A.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:A.md}),l.addEventListener("click",se=>se.stopPropagation());const y=p.createElement("div");Object.assign(y.style,{display:"flex",justifyContent:"flex-end"}),y.appendChild(i(()=>{r&&r.replaceChildren(n())})),l.appendChild(y),r=p.createElement("div"),Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(n()),l.appendChild(r),M.appendChild(l)}else l&&(l.remove(),l=null,r=null)}),M.appendChild(o),qe=()=>{r&&!t&&r.replaceChildren(n())}}}const{onHover:Je,onClick:li,onSelect:le,onViewOptionsChange:ai,showTooltip:ri=!0,showToolbar:We=!0,showIdentity:tn=!0,summaryPanel:Fe,showHelpButton:nn=!1,userGuideExtension:di,onExpand:on,showExpandButton:sn=!0,zIndex:ci,insights:Ce,warnings:ln,viewOptions:fi={},...Se}=v,Ae=Ce?.enabled??!1,pi=.4,ui=20,et=[...m.passBins??ko],an=ln?.display??!0,hi=ji(ci);let ae=v.statsSummary,re=[],rn=!1,tt=null,dn=!1;function vt(){const e=go({result:m,statsSummary:ae,extra:tt?[tt]:[]}),t=e.length!==re.length||e.some((n,i)=>n.code!==re[i]?.code||n.message!==re[i]?.message);re=e,(t||!rn)&&(rn=!0,ln?.onWarning?.(e))}vt();let q=m,V=m.wafer,ue=m.dies,C=new Set;const gi={sweeps:Ce?.sweeps,onSaveImage:xe.onSaveImage},xt=()=>!Oe&&bo(U,Ce?.sweeps);let cn=null,nt=null,it=!1,fn=!1,$=m.hbinDefs,G=m.sbinDefs,U=m.testDefs,he=m.metadataFields,pn=m.reticles?.length?m.reticles:void 0,un=m.reticleConfig,hn=m.view?.dataAxisFlip,wt=m.isLotStack??!1,Ct=m.aggrMethod,St=m.lotSize;const mi=We&&Ae;let Y=null,J=null,ee=null;tn&&(Y=wo(Qt(V.metadata??{},He())??"",V.metadata,{lotStack:He(),ownerDocument:p}),M.appendChild(Y.metaPanel),Y.metaPanel.style.visibility="visible",Y.isEmpty()||(J=gn(Y.wrap),_.insertBefore(J,_.firstChild),Ie()));function gn(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${A.sm} ${A.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:A.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function He(){return wt?{lotSize:St??1,aggrMethod:Ct}:void 0}function yi(){if(!Y)return;Y.update(Qt(V.metadata??{},He())??"",V.metadata,He());const e=J?.isConnected??!1,t=!Y.isEmpty();!t&&e?(J.remove(),J=null):t&&!e&&(J=gn(Y.wrap),J.style.display="",_.insertBefore(J,_.firstChild),Ie())}const bi=[...$??[],...G??[]].some(e=>e.color);let c={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...fi},X=null,te=!1,mn=null;function vi(){return Ae?X?Promise.resolve(X):(mn??=import("./insightsTab.js").then(({createInsightsTab:e})=>(X=e({getItems:()=>[{wafer:V,dies:ue,hbinDefs:$,sbinDefs:G,testDefs:U,label:qt(),passBins:et,statsSummary:ae}],getBinColors:()=>g.binColors,getRingCount:()=>q.ringCount??4,onSaveImage:xe.onSaveImage,onSaveText:xe.onSaveText,defaultView:Ce?.defaultView,sweeps:Ce?.sweeps,showMetadataStrip:!1,contentInset:pe,backTab:mi?void 0:{label:"Map",onBack:()=>ze(!1)},onOpenGuide:nn&&!We?()=>Xt():void 0,focusTest:t=>{D({plotMode:"value",activeTest:t,highlightBin:void 0}),ze(!1)},ownerDocument:p}),Object.assign(X.el.style,{position:"absolute",inset:"0",background:w.canvasBg,overflowY:"auto",paddingTop:"0"}),X.el.style.display="none",we.appendChild(X.el),X)),mn):Promise.resolve(null)}let yn=0;const Mt=["wheel","touchstart","pointerdown","keydown"];function xi(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const d of i)k.clearTimeout(d);i.length=0;for(const d of Mt)e.removeEventListener(d,o)},a=()=>n||!te?!0:(e.scrollTop=t,e.scrollTop>=t);if(!a()){for(const d of Mt)e.addEventListener(d,o,{passive:!0,once:!0});for(const d of[0,50,150,300,600])i.push(k.setTimeout(()=>{a()},d));i.push(k.setTimeout(()=>{for(const d of Mt)e.removeEventListener(d,o)},700))}}function ze(e){if(!Ae)return;const t=te;te=e,X&&!e&&t&&(yn=X.el.scrollTop),X&&(X.el.style.display=e?"flex":"none"),M.style.visibility=e?"hidden":"",F&&(F.style.display=e||Oe?"none":"flex"),T&&(T.style.display=e?"none":"flex"),ee&&(ee.style.display=be?"none":"flex"),ie&&(ie.style.display="flex"),J&&(J.style.display=""),Ie(),Y&&e&&Y.collapse(),rt(),H&&(H.innerHTML=e?ni.wafer:ni.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&vi().then(n=>{!n||!te||(n.el.style.display="flex",n.render(),xi(n.el,yn))})}Ae&&Ce?.defaultOpen&&queueMicrotask(()=>ze(!0));let g,bn,N=null,B=null,Et=[],Dt;function vn(e){Dt!==e&&(Dt=e,x())}let ge=null,kt=Se.legendOffset??{x:0,y:0},Ve=!1,Me=!1,Ye={x:0,y:0},Bt={x:0,y:0},me=!1,Ee=!1,j="pan",De={x:0,y:0},ot={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Xe=!1,ke=!1;function Lt(){const e=c;g=Oi(V,ue.filter(Co),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??Eo(ue,{passBins:et,binColorScheme:e.binColorScheme,hbinDefs:$,sbinDefs:G,useDefinedBinColors:e.useDefinedBinColors}),passBins:et,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:pn,ringCount:q.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:U,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:wt,aggregationMethod:Ct??e.aggregationMethod,lotSize:St??e.lotSize,dataAxisFlip:hn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:he}),bn=new Map(g.dies.map((n,i)=>[fe(n),i]));const t=e.binColors?null:Do(g.binColors,g.plotMode);t?.message!==tt?.message&&(tt=t,vt(),dn&&Tt())}Lt();let Z=null,Be=null,st=null,xn=v.findingsNotice,wi={},I=null,de=null;function Ci(e){const{kind:t,index:n}=e.variable;D(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const i=e.highlight;i.kind==="bin"?(Ft(i.dieKeys),D({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Ft(i.dieKeys)}const Ne=new Map;function wn(e){Ne.get(e)?.cancel(),Ne.delete(e);const t=ho(uo(e,{wafer:V,dies:ue,yieldSummary:q.yield,dataCoverage:q.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:U,statsSummary:ae,warnings:an?re:[],passBins:et,ringCount:q.ringCount??4,binColors:g.binColors,plotMode:c.plotMode??"hardBin",metadataShownElsewhere:tn,fallbackFormat:c.fallbackFormat,activeFindingId:st,findingsFilter:wi,findingsNotice:xn,onFindingsFilterChange:ye,onSaveText:xe.onSaveText,metadataFields:he,dieListOptions:v.dieList,onFindingClick:(n,i)=>{st===n.id?(st=null,Ft([]),D({highlightBin:void 0})):(st=n.id,Ci(n)),ye()}}));t.done||Ne.set(e,t)}function ye(){Z&&wn(Z)}function je(){I&&wn(I)}if(Fe?.placement){const e=Fe.placement;Z=Ut(e,pe,p);const t=M.parentElement,n=M.nextSibling;Be=Zt(M,Z,e),t?.insertBefore(Be,n),ye()}else if(ae){const e=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=e?"block":"none";const t=M.parentElement,n=M.nextSibling;de=Zt(M,I,"right"),t?.insertBefore(de,n),je()}const W=ri?Qn(p):null;let ie=null,L=null,F=null,T=null,lt=null,K=null,Cn=null,H=null,oe=null,at=null;dn=!0;function Tt(){if(!oe||!at)return;const e=re.length,t=e>0;if(oe.style.display=t?"flex":"none",at.style.display=t?"":"none",!t)return;const n=yo(re[0]),i=`${e} data ${e===1?"warning":"warnings"}`;oe.style.color=n==="error"?w.errText:w.warnText,oe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Pt=null,Sn=null,Ot=null,Rt=null,It=null,Wt=null;function Ft(e){C=new Set(e??[]),le&&le(Ke()),x()}function rt(){if(!K)return;const e=!!(Z??I);K.style.display=ae&&e&&!te?"flex":"none";const t=Z??I,n=t?t.style.display!=="none":!1;ae?.hasNotableFindings&&!n?K.style.color=w.findingIndicator:K.dataset.active||(K.style.color=w.icon)}let Mn=null;function En(e){const t=Z??I;t&&(t.style.display=e?"block":"none",K&&Mn?.(K,e),rt())}if(We){let h=function(b){j=b,i(se,b==="zoom"),i(E,b==="pan"),lt&&i(lt,b==="select"),s.style.cursor=b==="pan"?"grab":"crosshair"};ie=p.createElement("div"),ie.dataset.wmapToolbar="single",Object.assign(ie.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:w.menuBg,border:`1px solid ${w.menuBorder}`,borderRadius:Zn.control,boxShadow:Xi.panel,pointerEvents:"auto"});const e=Qn(p),t=Ki(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:a,makeMenuSection:d,closeOpenMenu:l,getOpenMenu:r,setOpenMenu:f}=t;Mn=i,Pt=l,Sn=r,p.addEventListener("click",l,!0),F=p.createElement("div"),Object.assign(F.style,{display:Oe?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(F);const y=n("download","Download PNG",Ei);F.appendChild(y),F.appendChild(o());const se=n("zoomMode","Zoom (drag to zoom region)",()=>h("zoom")),Te=n("zoomIn","Zoom in",()=>Le(s.clientWidth/2,s.clientHeight/2,1.2)),ne=n("zoomOut","Zoom out",()=>Le(s.clientWidth/2,s.clientHeight/2,1/1.2)),ce=n("reset","Reset zoom (double-click)",()=>ct());F.appendChild(se),F.appendChild(Te),F.appendChild(ne),F.appendChild(ce),F.appendChild(o());const E=n("pan","Pan (drag to move)",()=>h("pan"));F.appendChild(E),lt=n("boxSelect","Select (drag to select dies)",()=>h("select")),F.appendChild(lt);{const b=n("drilldown","Chart this wafer",()=>{const Pe=b.getBoundingClientRect();In({x:Pe.left,y:Pe.bottom+4},b)});b.setAttribute("aria-haspopup","menu"),nt=b,Rn(),F.appendChild(b)}i(E,!0);{let b=function(u){return u.plotMode!==(c.plotMode??"hardBin")?!1:u.plotMode==="value"?(c.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?c.activeMetadataKey===u.activeMetadataKey:!0},Pe=function(u,S){u.activeTest!==void 0?D({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),S.remove(),f(null),Qe(Q,!1)};L=p.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(L),T=p.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const ft=()=>{const u=r();u&&(u.remove(),f(null)),Qe(Q,!1)},Q=n("mode","Plot mode",()=>{if(r()){ft();return}const u=ue,S=g.testDefs,{testEntries:ht,binEntries:ve,stackedEntries:Ge}=so(u,S,{includeStacked:g.isLotStack}),Kt=(he??[]).filter(Ze=>lo(u,Ze.key)).map(ao),Ue=_i(Q.getBoundingClientRect(),ht,ve,Ge,b,Pe,{makeMenuRow:a,makeMenuSection:d},c.plotMode??"hardBin",Q.ownerDocument.defaultView??window,Kt);Jn(Q).appendChild(Ue),f(Ue),Qe(Q,!0),ti(Ue,Q,ft)});Qe(Q,!1);const{btn:pt,sync:$e}=Ui(t,()=>({...c,plotMode:c.plotMode??"hardBin"}),()=>bi,D);Rt=$e,Rt();const Nt=qi(t,()=>{const u=!!g.hasReticle,S=(c.plotMode??"hardBin")==="value",{testNumber:ht}=_t(c.activeTest??0,g.testDefs),ve=gt(g.testDefs,ht),Ge=S&&ve!==void 0&&!$t(ve),Kt=S&&!Ge&&(ve?.limitLow!==void 0||ve?.limitHigh!==void 0),Ue=S&&!Ge&&g.dies.some(Ze=>Vi(Ze,ht,ve)!==void 0);return no(c,u,{functionalActive:Ge,hasLimits:Kt,hasRecorded:Ue,binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},Ze=>D(Ze))},()=>io(c)),{btn:jt,sync:ki}=Qi(t,()=>c,u=>D({legendPosition:u}));Ot=ki,Ot();const _n=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&!$t(S)},{btn:Bi,sync:Li}=Zi(t,()=>({...c,functionalActive:_n()}),u=>D(u));It=Li,It();const Ti=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&(S.limitLow!==void 0||S.limitHigh!==void 0)},ut=n("specRange","Colorbar range: spec limits",()=>{const u=c.colorbarRangeMode==="data"?"spec":"data";D({colorbarRangeMode:u})});Wt=()=>{const u=c.plotMode==="value"&&Ti()&&to(c)==="off"&&!_n();ut.style.display=u?"":"none";const S=(c.colorbarRangeMode??"spec")==="spec";i(ut,S),ut.ariaLabel=S?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},Wt();const Pi=Ji(t,()=>c,u=>D(u));T.appendChild(Q),T.appendChild(pt),T.appendChild(Bi),T.appendChild(ut),Oe||(T.appendChild(o()),T.appendChild(Nt),T.appendChild(o()),T.appendChild(jt),T.appendChild(o()),T.appendChild(Pi)),ae&&(K=n("findings","Summary panel",()=>{const u=Z??I;u&&En(u.style.display==="none")}),L.appendChild(o()),L.appendChild(K),I?.style.display!=="none"&&i(K,!0),rt()),an&&(at=o(),oe=n("warning","Data warnings",()=>{const u=r();if(l(new MouseEvent("click")),u)return;const S=mo(oe.getBoundingClientRect(),re,k);Jn(we).appendChild(S),f(S),ti(S,oe,()=>l(new MouseEvent("click")))}),Qe(oe,!1),L.appendChild(at),L.appendChild(oe),Tt()),Ae&&(L.appendChild(o()),H=n("analysis","Insights",()=>{ze(!te),i(H,te)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),sn&&(L.appendChild(o()),ee=n("expand","Expand (E)",on??Dn),L.appendChild(ee)),nn&&(L.appendChild(o()),Cn=n("help","User guide",()=>Xt()),L.appendChild(Cn))}_.appendChild(ie),Ie()}let be=null;function Dn(){be&&(be.close(),be=null);const e=we;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=Qt(V.metadata??{},He()),n=_.childElementCount>0?[_,e]:[e],i=$i(n,{ownerDocument:p,boxSize:te?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{be=null,ee&&(ee.style.display="flex"),te||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),be=i,ee&&(ee.style.display="none"))}function kn(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&c.binColors!==void 0&&(e={...e,binColors:void 0});const t=c.plotMode;c={...c,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(a=>a==="legendPosition"||a==="showLegend"||a==="markFailingDies")||Lt(),Ot?.(),Rt?.(),It?.(),Wt?.(),x();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(a=>a in e);(o||i)&&(ye(),je()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&qe?.()}function D(e){kn(e);const t=Object.keys(e);ai?.(c,t,classifyChanged(t))}let At=!1;function Ht(){At||(At=!0,Gt(()=>{At=!1,x()},k))}function x(){const e=B??void 0,t=g.dies[0],n=t?{x:t.width,y:t.height}:Se.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!($?.length||G?.length||g.dies.some(y=>y.hbin!=null||y.sbin!=null)),a=c.legendPosition??"default",d=c.showLegend??!0,l=a==="default"||a==="compact",r=(Se.colorbarWidth??16)+28,f=o&&l?a!=="default"?Math.max($n,r):i<Hi?0:i<Ai?Math.max(Fi,r):Math.max($n,r):void 0,h=Wi(s,g,{...Se,minRightReserve:d?f:0,showColorbar:d&&(Se.showColorbar??!0),markFailingDies:c.markFailingDies??!1,legendPosition:a,legendOffset:kt,diePitchMm:n,fallbackFormat:c.fallbackFormat,showAxes:Se.showAxes??B!==null,viewport:e,activeBin:c.plotMode==="metadata"?c.highlightMetadataValue:c.highlightBin,hoverBin:Dt,hbinDefs:$,sbinDefs:G,metadataFields:he});Et=h.binLegendRows,ge=h.legendBox??null,B===null&&(N=h.viewport),C.size>0&&Si(),Ee&&Mi(),Rn()}function Si(){const e=z();if(!e)return;const t=s.getContext("2d"),n=g.hoverPoints,i=g.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,a=i?i.height/2*e.ppm:e.ppm*.5,d=Math.max(1,Math.min(3,o*.08)),l=o-d,r=a-d,f=[];for(const h of C){const y=bn.get(h);y!==void 0&&f.push({sx:e.originX+n[y].x*e.ppm,sy:e.originY-n[y].y*e.ppm})}if(f.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.restore()}}function Mi(){const e=s.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),i=Math.abs(R.x-O.x),o=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,i,o),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,i,o),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,i,o),e.restore()}function Ei(){s.toBlob(e=>{e&&(v.downloadFilename!=null?ei(e,v.downloadFilename,v.onSaveImage):ei(e,en(),xe.onSaveImage))})}function Bn(e){return N?Math.max(N.ppm*pi,Math.min(N.ppm*ui,e)):e}function Le(e,t,n){const i=B??N;if(!i)return;const o=Bn(i.ppm*n),a=o/i.ppm,d=e-(e-i.originX)*a,l=t-(t-i.originY)*a,r=(N?.snapDist??1)/(o/(N?.ppm??o));B={originX:d,originY:l,ppm:o,snapDist:r},x()}function z(){return B??N}function Ln(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Le(e.clientX-t.left,e.clientY-t.top,n)}else if(B!==null){e.preventDefault();const t=z(),n=B.snapDist;B={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},x()}}function zt(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function Tn(e){if(it=!1,e.button!==0||!z())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(ge&&c.legendPosition==="floating"&&zt(n,i,ge)){Me=!0,Ye={x:n,y:i},Bt={...kt};return}if(Xe&&j!=="pan"){ke=!0,me=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing";return}if(j==="zoom"||j==="select"){Ee=!0,O=R={x:n,y:i};return}me=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing"}function Pn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ee){R={x:n,y:i},Ht();return}if(Me){const h=n-Ye.x,y=i-Ye.y;h*h+y*y>16&&(Me=!1,Ve=!0,s.style.cursor="grabbing")}if(Ve){kt={x:Bt.x+(n-Ye.x),y:Bt.y+(i-Ye.y)},Ht();return}if(me){const h=z(),y=B?.snapDist??N?.snapDist??1;B={originX:ot.x+(n-De.x),originY:ot.y+(i-De.y),ppm:h.ppm,snapDist:y},Ht();return}const o=z();if(!o)return;const a=(n-o.originX)/o.ppm,d=(o.originY-i)/o.ppm,r=Yt(a,d,o.snapDist)?.die??null,f=Et.find(h=>n>=h.x&&n<h.x+h.w&&i>=h.y&&i<h.y+h.h);if(vn(f?f.bin:void 0),f){s.style.cursor="pointer",W&&(W.textContent=f.label??`Bin ${f.bin}`,W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})),Je?.(null,e);return}j==="pan"&&(s.style.cursor=r?"crosshair":"grab"),W&&(r?(W.innerHTML=Ri(r,g.plotMode,{testDefs:U,hbinDefs:$,sbinDefs:G,fallbackFormat:c.fallbackFormat,aggrMethod:g.aggrMethod,lotSize:g.lotSize,metadataFields:he,activeTest:g.activeTest,reticleConfig:un}),W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})):W.style.display="none"),Je?.(r,e)}function On(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(W&&(n<0||i<0||n>t.width||i>t.height)&&(W.style.display="none"),Ee){Ee=!1,R={x:n,y:i};const l=n-O.x,r=i-O.y,f=z();if(j==="zoom"){if(l*l+r*r<25)Le(n,i,2);else if(f){const h=Math.min(O.x,R.x),y=Math.max(O.x,R.x),se=Math.min(O.y,R.y),Te=Math.max(O.y,R.y),ne=y-h,ce=Te-se;if(ne>4&&ce>4){const E=s.clientWidth,b=s.clientHeight,Pe=E/ne,ft=b/ce,Q=Math.min(Pe,ft),pt=Bn(f.ppm*Q),$e=pt/f.ppm,Nt=(h+y)/2,jt=(se+Te)/2;B={originX:E/2-(Nt-f.originX)*$e,originY:b/2-(jt-f.originY)*$e,ppm:pt,snapDist:f.snapDist/$e}}}x(),s.style.cursor="crosshair";return}if(l*l+r*r<25)Vt(n,i,o,e);else if(f){const h=(Math.min(O.x,R.x)-f.originX)/f.ppm,y=(Math.max(O.x,R.x)-f.originX)/f.ppm,se=(f.originY-Math.max(O.y,R.y))/f.ppm,Te=(f.originY-Math.min(O.y,R.y))/f.ppm,ne=g.hoverPoints,ce=[];for(let E=0;E<ne.length;E++)if(ne[E].x>=h&&ne[E].x<=y&&ne[E].y>=se&&ne[E].y<=Te){const b=g.dies[E];b&&ce.push(b)}if(o)for(const E of ce){const b=fe(E);C.has(b)?C.delete(b):C.add(b)}else C=new Set(ce.map(E=>fe(E)));le?.(Ke())}x(),s.style.cursor="crosshair";return}if(Me){Me=!1,Vt(n,i,o,e);return}if(Ve){Ve=!1,s.style.cursor="grab";return}if(!me)return;if(me=!1,ke){ke=!1,s.style.cursor=Xe||j==="pan"?"grab":"crosshair";return}s.style.cursor=j==="pan"?"grab":"crosshair";const a=n-De.x,d=i-De.y;a*a+d*d<25&&Vt(n,i,o,e)}function Vt(e,t,n,i){for(const l of Et)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const r=c.highlightBin===l.bin?void 0:l.bin;D({highlightBin:r})}else{const r=c.highlightMetadataValue===l.bin?void 0:l.bin;D({highlightMetadataValue:r})}return}if(ge&&zt(e,t,ge))return;const o=z();if(!o)return;const d=Yt((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(d){li?.(d,i);const l=fe(d);n?C.has(l)?C.delete(l):C.add(l):C=new Set([l]),le?.(Ke()),x()}else n||(C=new Set,le?.([]),x())}function Ke(){const e=[],t=g.hoverPoints;for(let n=0;n<t.length;n++){const i=g.dies[n];i&&C.has(fe(i))&&e.push(i)}return e}function Rn(){nt&&(nt.style.display=xt()?"flex":"none",nt.ariaLabel=C.size>0?"Chart the selected dies (or right-click)":"Chart this wafer (or right-click)")}function Di(){const e={waferLabel:Jt(),testDefs:U,isLotStack:q.isLotStack,activeTest:c.plotMode==="value"?c.activeTest:void 0};return C.size>0?vo(Ke(),e):xo(ue,e)}function In(e,t){if(!xt())return;const n=Di();import("./drilldown.js").then(({openDrilldownMenu:i})=>{fn||(cn=i(e,t,n,gi))})}function Wn(e){e.stopPropagation();const t=it;if(it=!1,!xt()||te)return;const n=s.getBoundingClientRect();if(!t){const o=e.clientX-n.left,a=e.clientY-n.top;if(ge&&zt(o,a,ge))return;const d=z(),l=d?Yt((o-d.originX)/d.ppm,(d.originY-a)/d.ppm,d.snapDist)?.die:void 0;l&&!C.has(fe(l))&&(C=new Set([fe(l)]),le?.(Ke()),x())}e.preventDefault();const i=t?{x:n.left+n.width/2,y:n.top+n.height/2}:{x:e.clientX,y:e.clientY};In(i,s)}function Fn(){vn(void 0),W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair"}function An(){me=!1,ke=!1,Ee=!1,Me=!1,Ve=!1,W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair",x()}function Yt(e,t,n){const i=g.hoverPoints,o=g.rectangles;for(let r=0;r<o.length;r++){const f=o[r];if(Math.abs(e-f.x)<=f.width/2&&Math.abs(t-f.y)<=f.height/2){const h=g.dies[r];return h?{die:h,index:r}:null}}let a=null,d=-1,l=n*n;for(let r=0;r<i.length;r++){const f=i[r].x-e,h=i[r].y-t,y=f*f+h*h;y<l&&(l=y,a=g.dies[r]??null,d=r)}return a?{die:a,index:d}:null}const Hn=new k.ResizeObserver(()=>{N=null,B=null,x()});Hn.observe(s),v.height==null&&si<=0&&Gt(()=>Gt(()=>{P.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let _e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`);const dt=()=>{_e.removeEventListener("change",dt),_e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`),_e.addEventListener("change",dt),x()};_e.addEventListener("change",dt);const zn=k.matchMedia("(prefers-color-scheme: dark)"),Vn=()=>x();zn.addEventListener("change",Vn);const Yn=()=>{W&&yt(p)};k.addEventListener("blur",Yn);function Xn(e){if((e.key==="ContextMenu"||e.shiftKey&&e.key==="F10")&&(it=!0),e.key==="Escape"&&C.size>0&&(C=new Set,le?.([]),x()),(e.key==="e"||e.key==="E")&&sn&&(e.stopPropagation(),(on??Dn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),ct())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=z();if(n){const i=B?.snapDist??N?.snapDist??1;let o=0,a=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(a=20,e.preventDefault()),e.key==="ArrowDown"&&(a=-20,e.preventDefault()),(o||a)&&(B={originX:n.originX+o,originY:n.originY+a,ppm:n.ppm,snapDist:i},x())}e.key===" "&&!Xe&&(e.preventDefault(),Xe=!0,j!=="pan"&&(s.style.cursor="grab"))}}function Nn(e){e.key===" "&&(Xe=!1,ke&&(me=!1,ke=!1),s.style.cursor=j==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",Ln,{passive:!1}),s.addEventListener("pointerdown",Tn),s.addEventListener("pointermove",Pn),s.addEventListener("pointerup",On),s.addEventListener("pointerleave",Fn),s.addEventListener("pointercancel",An);const jn=()=>ct();s.addEventListener("dblclick",jn),s.addEventListener("keydown",Xn),s.addEventListener("keyup",Nn),s.addEventListener("contextmenu",Wn);const Kn=e=>{e.stopPropagation()};s.addEventListener("click",Kn),s.clientWidth,x(),qe?.();function ct(){N=null,B=null,x()}function Xt(){import("./userGuideHtml.js").then(e=>Gi({buildWaferMap:zi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:Yi},e.USER_GUIDE_HTML,di,P))}return Ie(),{setResult(e){q=e,V=e.wafer,ue=e.dies,$=e.hbinDefs,G=e.sbinDefs,U=e.testDefs,he=e.metadataFields,pn=e.reticles?.length?e.reticles:void 0,un=e.reticleConfig,hn=e.view?.dataAxisFlip,wt=e.isLotStack,Ct=e.aggrMethod,St=e.lotSize,yi(),Lt(),x(),Z&&ye()},setOptions(e){kn(e)},getOptions(){return{...c}},resetZoom:ct,setSelection(e){C=new Set(e.map(t=>fe(t))),x()},clearSelection(){C=new Set,le?.([]),x()},setFindingsNotice(e){xn=e,Z?ye():I&&je()},setStatsSummary(e){if(ae=e,vt(),Tt(),Z)ye();else if(I)je();else if(e&&!Fe?.placement){const t=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=t?"block":"none";const n=M.parentElement,i=M.nextSibling;de=Zt(M,I,"right"),n?.insertBefore(de,i),je()}rt()},closeSummaryPanel(){En(!1)},getExportTitle(){return en()},getBinColors(){return g.binColors},setSummaryVisible(e){K&&(K.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){ee&&(ee.style.display=e?"flex":"none")},openUserGuide:Xt,setInsightsOpen(e){ze(e),H&&(e?(H.dataset.active="1",H.style.background=w.bgActive,H.style.color=w.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=w.icon))},destroy(){fn=!0;for(const e of Ne.values())e.cancel();Ne.clear(),be?.close(),Sn?.()?.remove(),Pt&&p.removeEventListener("click",Pt,!0),s.removeEventListener("wheel",Ln),s.removeEventListener("pointerdown",Tn),s.removeEventListener("pointermove",Pn),s.removeEventListener("pointerup",On),s.removeEventListener("pointerleave",Fn),s.removeEventListener("pointercancel",An),s.removeEventListener("dblclick",jn),s.removeEventListener("keydown",Xn),s.removeEventListener("keyup",Nn),s.removeEventListener("contextmenu",Wn),cn?.(),s.removeEventListener("click",Kn),Hn.disconnect(),_e.removeEventListener("change",dt),zn.removeEventListener("change",Vn),k.removeEventListener("blur",Yn),hi(),W&&yt(p),ie?.remove(),Be&&(Be.parentElement?.insertBefore(M,Be),Be.remove()),de&&(de.parentElement?.insertBefore(M,de),de.remove()),M.remove(),s.style.cursor="",X?.destroy(),Y?.destroy(),Re.remove()}}}
|
|
@@ -12,6 +12,7 @@ import { type CapabilityItem } from '../stats/capability.js';
|
|
|
12
12
|
import { type SaveTextHandler } from './toolbar.js';
|
|
13
13
|
import { type DieListDisplayOptions } from './dieList.js';
|
|
14
14
|
export { csvField } from '../core/utils.js';
|
|
15
|
+
import { type Chunked } from '../core/utils.js';
|
|
15
16
|
import type { WaferMetadata } from '../core/metadata.js';
|
|
16
17
|
export interface SummaryPanelOptions {
|
|
17
18
|
/** Which side of the content area to place the panel. Default 'right'. */
|
|
@@ -221,7 +222,20 @@ export interface CsvExportContext {
|
|
|
221
222
|
* section title and emitted as a `Population` CSV column. */
|
|
222
223
|
populationLabel?: string;
|
|
223
224
|
}
|
|
224
|
-
|
|
225
|
+
/**
|
|
226
|
+
* {@link buildTestSectionSteps}, run straight through — the entry for every
|
|
227
|
+
* caller that is not staging its render across tasks.
|
|
228
|
+
*/
|
|
229
|
+
export declare function buildTestSection(...args: Parameters<typeof buildTestSectionSteps>): HTMLDivElement | null;
|
|
230
|
+
/**
|
|
231
|
+
* @internal The Test Values table as a {@link Chunked} computation: one step per
|
|
232
|
+
* test for the descriptive statistics, plus the steps of the capability pass it
|
|
233
|
+
* delegates to. This is the single largest piece of work in either summary
|
|
234
|
+
* panel — at lot scale it scans the pooled dies once per test and sorts every
|
|
235
|
+
* test's values — so it is the one that has to be interruptible for the panel
|
|
236
|
+
* not to block the main thread for seconds at a time.
|
|
237
|
+
*/
|
|
238
|
+
export declare function buildTestSectionSteps(dies: Die[], testDefs: TestDef[] | undefined, fallbackFormat?: 'si' | 'engineering',
|
|
225
239
|
/**
|
|
226
240
|
* When supplied, each test's descriptive stats and spec-yield are read from
|
|
227
241
|
* `.perTestStats`/`.testSpecYield` (already computed once by
|
|
@@ -274,7 +288,7 @@ panel?: HTMLElement,
|
|
|
274
288
|
* information for no benefit. The CSV export always carries every column
|
|
275
289
|
* regardless.
|
|
276
290
|
*/
|
|
277
|
-
columns?: 'compact' | 'full'): HTMLDivElement | null
|
|
291
|
+
columns?: 'compact' | 'full'): Chunked<HTMLDivElement | null>;
|
|
278
292
|
/**
|
|
279
293
|
* "Functional Tests" section — one row per functional (`testType: 'F'`) test
|
|
280
294
|
* with pass/fail counts and pass rate. The functional counterpart of
|
|
@@ -368,7 +382,11 @@ notice?: FindingsNotice): HTMLDivElement | null;
|
|
|
368
382
|
* they aren't reconstructable from per-wafer quartiles alone — but
|
|
369
383
|
* `buildTestSection`'s display doesn't need them.)
|
|
370
384
|
*/
|
|
371
|
-
|
|
385
|
+
/** {@link buildLotTestSectionSteps}, run straight through. */
|
|
386
|
+
export declare function buildLotTestSection(...args: Parameters<typeof buildLotTestSectionSteps>): HTMLDivElement | null;
|
|
387
|
+
/** @internal {@link buildLotTestSection} as a {@link Chunked} computation —
|
|
388
|
+
* see {@link buildTestSectionSteps}, which does the work. */
|
|
389
|
+
export declare function buildLotTestSectionSteps(allDies: Die[], testDefs: TestDef[] | undefined, fallbackFormat?: 'si' | 'engineering', perWaferSummaries?: StatsSummary[],
|
|
372
390
|
/** Optional host hook for the "Export CSV" button — see `saveTextFile` (toolbar.ts). */
|
|
373
391
|
onSaveText?: SaveTextHandler,
|
|
374
392
|
/**
|
|
@@ -379,7 +397,7 @@ capabilityItems?: CapabilityItem[],
|
|
|
379
397
|
/** Panel element owning the collapsed state. Omit for a stateless render. */
|
|
380
398
|
panel?: HTMLElement,
|
|
381
399
|
/** See `buildTestSection`'s `columns`. Defaults to the full set. */
|
|
382
|
-
columns?: 'compact' | 'full'): HTMLDivElement | null
|
|
400
|
+
columns?: 'compact' | 'full'): Chunked<HTMLDivElement | null>;
|
|
383
401
|
export declare function createSummaryPanelEl(placement: 'right' | 'left' | 'top' | 'bottom',
|
|
384
402
|
/**
|
|
385
403
|
* Inset from the edge this panel docks against — stated by the caller,
|
|
@@ -403,8 +421,22 @@ export declare function createSummaryPanelEl(placement: 'right' | 'left' | 'top'
|
|
|
403
421
|
edgeInset: string, ownerDocument?: Document): HTMLDivElement;
|
|
404
422
|
/** Wrap the canvas + panel in a flex container according to placement. */
|
|
405
423
|
export declare function wrapWithSummaryPanel(content: HTMLElement, panel: HTMLDivElement, placement: 'right' | 'left' | 'top' | 'bottom'): HTMLDivElement;
|
|
406
|
-
/**
|
|
407
|
-
|
|
424
|
+
/**
|
|
425
|
+
* {@link renderWaferSummaryContentSteps}, run straight through — the entry for a
|
|
426
|
+
* caller that does not stage its render.
|
|
427
|
+
*/
|
|
428
|
+
export declare function renderWaferSummaryContent(...args: Parameters<typeof renderWaferSummaryContentSteps>): void;
|
|
429
|
+
/**
|
|
430
|
+
* @internal Render all wafer-level sections into a panel element, as a
|
|
431
|
+
* {@link Chunked} computation. Clears existing content.
|
|
432
|
+
*
|
|
433
|
+
* Chunked for the same reason the lot panel is: the Test Values table walks
|
|
434
|
+
* every die once per test, which on a single 400,000-die wafer is seconds of
|
|
435
|
+
* uninterruptible work on the main thread. Sections are appended as they are
|
|
436
|
+
* built, so the panel fills in. The synchronous entry above is this drained —
|
|
437
|
+
* one implementation, not a second progressive copy.
|
|
438
|
+
*/
|
|
439
|
+
export declare function renderWaferSummaryContentSteps(panel: HTMLDivElement, params: {
|
|
408
440
|
wafer: Wafer;
|
|
409
441
|
dies: Die[];
|
|
410
442
|
yieldSummary?: YieldSummary;
|
|
@@ -461,7 +493,7 @@ export declare function renderWaferSummaryContent(panel: HTMLDivElement, params:
|
|
|
461
493
|
* authoritative in neither place, is the thing being avoided in both cases.
|
|
462
494
|
*/
|
|
463
495
|
metadataShownElsewhere?: boolean;
|
|
464
|
-
}): void
|
|
496
|
+
}): Chunked<void>;
|
|
465
497
|
/** Render lot-level content into the panel. Clears existing content. */
|
|
466
498
|
/** A gallery item as the lot report reads it — every field optional, since a slot may not have loaded. */
|
|
467
499
|
type ReportItem = {
|
|
@@ -482,7 +514,21 @@ type ReportItem = {
|
|
|
482
514
|
* as the cards do. `passBins`/`ringCount` fill in only for an item built without them.
|
|
483
515
|
*/
|
|
484
516
|
export declare function reportMapsFromItems(items: ReadonlyArray<ReportItem | null | undefined>, passBins: readonly number[], ringCount: number): ReportMap[];
|
|
485
|
-
|
|
517
|
+
/**
|
|
518
|
+
* {@link renderLotSummaryContentSteps}, run straight through — the entry for a
|
|
519
|
+
* caller that is not staging the render across tasks.
|
|
520
|
+
*/
|
|
521
|
+
export declare function renderLotSummaryContent(...args: Parameters<typeof renderLotSummaryContentSteps>): void;
|
|
522
|
+
/**
|
|
523
|
+
* @internal The lot summary panel as a {@link Chunked} computation: it pools
|
|
524
|
+
* every die of every wafer and derives bin, region and per-test sections from
|
|
525
|
+
* that pool, which at lot scale is the longest single piece of work anywhere in
|
|
526
|
+
* this library — 15.3 s on a 50-wafer lot of 4,000 dies x 100 tests, enough for
|
|
527
|
+
* the browser to offer to kill the page. Each step is one section, or one test
|
|
528
|
+
* within the Test Values table, and each section is appended as it is built, so
|
|
529
|
+
* the panel fills in rather than arriving at once.
|
|
530
|
+
*/
|
|
531
|
+
export declare function renderLotSummaryContentSteps(panel: HTMLDivElement, params: {
|
|
486
532
|
lotSummary: LotStatsSummary;
|
|
487
533
|
/** `passBins` on an item is that wafer's own (`WaferMapResult.passBins`) and wins over the top-level fallback. */
|
|
488
534
|
items: Array<ReportItem & {
|
|
@@ -517,5 +563,5 @@ export declare function renderLotSummaryContent(panel: HTMLDivElement, params: {
|
|
|
517
563
|
unusual: number;
|
|
518
564
|
notable: number;
|
|
519
565
|
} | undefined;
|
|
520
|
-
}): void
|
|
566
|
+
}): Chunked<void>;
|
|
521
567
|
//# sourceMappingURL=summaryPanel.d.ts.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{waferDisplayLabel as me}from"../core/waferLabel.js";import{itemPassBins as he,passBinsLabel as Ke}from"../core/passBins.js";import{isParametricTest as Ge}from"../renderer/buildWaferMap.js";import{buildRingRegions as Ue,buildQuadrantRegions as Qe,buildRegionYieldData as Xe}from"../stats/regions.js";import{computeFunctionalYield as Ze}from"../stats/analyzeWaferMap.js";import{renderWaferReportHtml as Je,renderLotReportHtml as et}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as tt}from"../stats/findingsNarrative.js";import{filterFindings as nt}from"../stats/filterFindings.js";import{buildFacetTable as ot,prettyKey as Ce}from"../stats/facets.js";import{commonMetadata as we}from"../stats/facets.js";import{resolveMetadataColumns as it}from"../stats/metadataColumns.js";import{resolveBinColors as Se,resolveBinColorsByWafer as st}from"../renderer/binColors.js";import{NO_DATA_FILL as at}from"../renderer/colorMap.js";import{describeWaferPopulation as ve,populationLabel as rt}from"../stats/population.js";import{buildWarningsBanner as ge,collectWarnings as $e}from"./warnings.js";export{ge as buildWarningsBanner};import{fmt as ke,fmtAggregationMethod as lt,plainBinTerms as ne}from"../renderer/fmt.js";import{getUniqueTestNumbers as dt}from"../renderer/buildView.js";import{quantile as oe}from"../stats/math.js";import{buildCapabilityData as ct}from"../stats/capability.js";import{sortBinsForDisplay as pt}from"../stats/binPareto.js";import{poolFunctionalYield as ut}from"../stats/testPassRate.js";import{makeLabeledSelect as Be,makeSegmented as be}from"./charts/chartShell.js";import{SHADOW as Le,MOTION as Ne,LEADING as Q,TRACKING as re,wireControlHover as q,controlStyle as le,SPACE as y,RADIUS as _,FONT as E,CLR as B,sevColor as de,openModal as Fe,openReportModal as Ee,saveTextFile as De,wireTooltip as ie}from"./toolbar.js";import{buildDieListSection as ft}from"./dieList.js";export{csvField}from"../core/utils.js";import{medianOfSorted as mt,csvField as ce}from"../core/utils.js";import{metadataDisplayValue as ht}from"../core/metadata.js";const gt=B.panelBg,Re=`1px solid ${B.menuBorder}`,bt="12px",Y=B.label,K=B.value,Te="10px";function l(e,t,o,n=document){const i=n.createElement(e);return t&&Object.assign(i.style,t),o!==void 0&&(i.textContent=o),i}function J(e){return l("div",{fontSize:Te,fontWeight:"700",letterSpacing:re,textTransform:"uppercase",color:Y,marginBottom:y.sm},e)}const Me=new WeakMap,Ie=["regionYield","testValues","functionalTests"];function pe(e){if(!e)return{collapsed:new Set(Ie),regionMode:"ring",waferSort:"slot"};let t=Me.get(e);return t||(t={collapsed:new Set(Ie),regionMode:"ring",waferSort:"slot"},Me.set(e,t)),t}function X(e,t=!0,o,n){const i=l("div"),d=pe(n?.panel);n?.stateKey&&n.panel&&(t=!d.collapsed.has(n.stateKey));const s=document.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",gap:y.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const p=l("span",{fontSize:E.meta,color:Y,transition:`transform ${Ne.base}`,transform:t?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:Q.none,marginRight:"1px"},"\u25B6"),c=l("span",{fontSize:Te,fontWeight:"700",letterSpacing:re,textTransform:"uppercase",color:Y,flex:"1"},e);if(q(s,"bare"),s.setAttribute("aria-expanded",t?"true":"false"),s.appendChild(p),s.appendChild(c),o){const b=l("span",{fontSize:E.meta,fontWeight:"700",background:B.warnBg,color:B.warnText,borderRadius:_.pill,padding:"1px 5px"},o);s.appendChild(b)}const r=l("div");r.style.display=t?"block":"none";let a=t;if(s.addEventListener("click",()=>{a=!a,r.style.display=a?"block":"none",p.style.transform=a?"rotate(90deg)":"rotate(0deg)",s.setAttribute("aria-expanded",a?"true":"false"),n?.stateKey&&n.panel&&(a?d.collapsed.delete(n.stateKey):d.collapsed.add(n.stateKey))}),n?.control){const b=l("div",{display:"flex",alignItems:"center",gap:y.sm});s.style.width="auto",s.style.flex="1",b.appendChild(s);const u=()=>{r.innerHTML="",n.render?.(r)},S=n.control(u);S&&(S.style.marginBottom="6px",S.addEventListener("click",N=>N.stopPropagation()),b.appendChild(S)),i.appendChild(b)}else i.appendChild(s);return i.appendChild(r),n?.render?.(r),{outer:i,content:r}}function Ae(){return l("div",{height:"1px",background:B.separator,margin:`${bt} 0`,flexShrink:"0"})}function xe(e,t,o=B.barFill,n,i){const d=l("div",{marginBottom:"5px"}),s=l("div",{display:"flex",justifyContent:"space-between",fontSize:E.body,color:K,marginBottom:y.xxs}),p=l("span",{color:Y},e),c=l("span",{fontWeight:"600"},`${t.toFixed(1)}%`);s.appendChild(p),s.appendChild(c);const r=n!==void 0?n:Math.min(100,Math.max(0,t)),a=o,b=l("div",{position:"relative",height:"9px",background:B.bgActive,borderRadius:_.control,overflow:"hidden"}),u=l("div",{height:"100%",width:`${r}%`,background:a,borderRadius:_.control,transition:`width ${Ne.base}`});if(b.appendChild(u),i!==void 0){const S=l("div",{position:"absolute",top:"0",bottom:"0",left:`${i}%`,width:"2px",marginLeft:"-1px",background:B.value,opacity:"0.8"});b.appendChild(S)}return d.appendChild(s),d.appendChild(b),d}function We(){const e=l("div",{display:"flex",gap:y.sm,marginBottom:y.md});return e.finish=()=>{const t=e.lastElementChild;t&&Object.assign(t.style,{borderRight:"none",paddingRight:"0"})},e}function se(e,t,o){const n=l("div",{padding:`${y.xxs} ${y.md} ${y.xxs} 0`,borderRight:Re,textAlign:"center",flex:"1"}),i=l("div",{fontSize:E.heading,fontWeight:"700",color:K,lineHeight:Q.tight},e),d=l("div",{fontSize:E.body,color:Y,marginTop:y.xxs},t);return n.appendChild(i),n.appendChild(d),o&&n.appendChild(l("div",{fontSize:E.body,color:Y,opacity:"0.85"},o)),n}function Pe(e,t){const o=l("div",{display:"flex",justifyContent:"space-between",fontSize:E.body,gap:y.md,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},e),i=l("span",{color:K,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},t);return o.appendChild(n),o.appendChild(i),o}function xt(e,t){const o=l("div",{display:"flex",fontSize:E.body,gap:y.sm,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},`${e}:`),i=l("span",{color:K,fontWeight:"500",wordBreak:"break-all"},t);return o.appendChild(n),o.appendChild(i),o}export function metadataEntries(e){const t=[];for(const[o,n]of Object.entries(e)){const i=ht(n);i!==void 0&&t.push([o,i])}return t}const yt=["lot","product","testprogram","split"],ue=e=>{const t=yt.indexOf(e.toLowerCase().replace(/[^a-z]/g,""));return t===-1?Number.MAX_SAFE_INTEGER:t};export function buildFacetSummaryChips(e,t=3){if(!e.length)return null;const o=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`}),n=[...e].sort((p,c)=>ue(p.key)-ue(c.key)),i=n.filter(p=>ue(p.key)!==Number.MAX_SAFE_INTEGER),d=n.filter(p=>ue(p.key)===Number.MAX_SAFE_INTEGER),s=p=>{const c=l("span",{whiteSpace:"nowrap"}),r=l("span",{color:Y},`${Ce(p.key)}: `);c.appendChild(r);const a=p.values.slice(0,t),b=p.values.length-a.length;let u=a.map(S=>S.value).join(", ");return b>0&&(u+=` +${b} more`),c.appendChild(document.createTextNode(u)),c};for(const p of i)o.appendChild(s(p));if(d.length){const p=l("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${y.xs} ${y.lg}`});for(const a of d)p.appendChild(s(a));const c=l("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:B.iconActive,fontSize:E.body,whiteSpace:"nowrap"});c.type="button",q(c,"bare");const r=a=>{p.style.display=a?"contents":"none",c.textContent=a?"less":`+${d.length} more`,c.setAttribute("aria-expanded",String(a))};r(!1),c.addEventListener("click",()=>r(c.getAttribute("aria-expanded")!=="true")),o.appendChild(p),o.appendChild(c)}return o}export function buildMetadataStripRow(e,t,o){const n=ot(e,o),i=buildFacetSummaryChips(n);if(!i&&!t)return null;const d=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(t){const s=l("span",{fontWeight:"500",whiteSpace:"nowrap"},t.aggrMethod?`${t.lotSize} wafers stacked \xB7 ${t.aggrMethod}`:`${t.lotSize} wafers stacked`);d.appendChild(s)}return i&&d.appendChild(i),d}const Ct={display:"flex",flexDirection:"column",gap:y.sm,background:B.menuBg,border:`1px solid ${B.menuBorder}`,borderRadius:_.container,padding:`${y.sm} ${y.lg}`,boxShadow:Le.panel,fontSize:E.body,lineHeight:Q.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(e,t,o){const n=buildMetadataStripRow(e,t,o);if(!n)return null;const i=l("div",Ct);return i.appendChild(n),i}export function buildCompactMetadataRows(e){const t=metadataEntries(e);if(!t.length)return null;const o=l("div");for(const[n,i]of t)o.appendChild(xt(Ce(n),i));return o}export function buildMetadataInfoSection(e,t){const o=buildMetadataStripRow(e,t,{facetableOnly:e.length>1});if(!o)return null;const n=l("div");return n.appendChild(J("Wafer Info")),n.appendChild(o),n}export function buildYieldSection(e,t,o=[1]){const n=l("div");n.appendChild(J("Summary"));const i=We();if(i.appendChild(se(String(e.totalDies),"Total dies")),e.partialDies>0&&i.appendChild(se(String(e.partialDies),"Partial")),e.yieldPercent!==null){const d=Ke([o]);i.appendChild(se(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${d}`))}return i.finish(),n.appendChild(i),e.edgeExcludedDies>0&&n.appendChild(Pe("Edge excluded (outer zone)",String(e.edgeExcludedDies))),n}export function buildBinSection(e,t,o,n,i,d){const s=new Map;if(i)for(const[r,a]of Object.entries(i))s.set(Number(r),a);else for(const r of e){if(r.partial||r.edgeExcluded)continue;const a=o==="hard"?r.hbin:r.sbin;a!=null&&s.set(a,(s.get(a)??0)+1)}if(!s.size)return null;const p=n??Se(e,{passBins:d,...o==="hard"?{hbinDefs:t}:{sbinDefs:t}}),c=l("div");c.appendChild(J(ze(o,[...s.values()].reduce((r,a)=>r+a,0))));for(const r of He(s,t,p[o],p.pass[o]))c.appendChild(r);return c}function ze(e,t){return`${e==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${t})`}function He(e,t,o,n){const i=[...e.values()].reduce((p,c)=>p+c,0),d=t?new Map(t.map(p=>[p.bin,p])):null;return pt(e.entries(),n).map(([p,c])=>{const r=d?.get(p),a=r?.name?`Bin ${p} \xB7 ${r.name}`:`Bin ${p}`,b=c/i*100,u=o.get(p)??at;return xe(`${a} (${c})`,b,u)})}export function buildBinBreakdownSection(e){const{dies:t,hbinDefs:o,sbinDefs:n,hardCounts:i,softCounts:d,plotMode:s,passBins:p=[1],panel:c}=e,r=e.binColors??Se(t,{passBins:p,hbinDefs:o,sbinDefs:n}),a=m=>{const x=m==="hard"?i:d,C=new Map;if(x){for(const[v,k]of Object.entries(x))C.set(Number(v),k);return C}for(const v of t){if(v.partial||v.edgeExcluded)continue;const k=m==="hard"?v.hbin:v.sbin;k!=null&&C.set(k,(C.get(k)??0)+1)}return C},b=a("hard"),u=a("soft"),S=b.size>0,N=u.size>0;if(!S&&!N)return null;const A=pe(c),P=s==="softBin"||s==="stackedSoftBins"?"soft":s==="hardBin"||s==="stackedBins"?"hard":void 0;let R=A.binMode??P??(S?"hard":"soft");R==="hard"&&!S&&(R="soft"),R==="soft"&&!N&&(R="hard");const H=R==="hard"?b:u,h=R==="hard"?o:n,f=[...H.values()].reduce((m,x)=>m+x,0),{outer:w}=X(ze(R,f),!0,void 0,{stateKey:"bins",panel:c,render:m=>{const x=R==="hard"?r.hard:r.soft;for(const C of He(H,h,x,r.pass[R]))m.appendChild(C)},control:S&&N&&c?()=>be([["hard","Hard"],["soft","Soft"]],R,m=>{A.binMode=m;const x=buildBinBreakdownSection(e);x&&w.replaceWith(x)},c.ownerDocument,!0):void 0});return w}export function buildLotBinSection(e,t,o,n){return buildBinSection(e,t,o,n)}export function buildRegionYieldPanelSection(e){const{diesByWafer:t,allWafers:o,ringCount:n,passBins:i,panel:d}=e,s=pe(d),p=a=>Xe(t,o,n,i,a==="ring"?Ue:Qe);if(!p("ring").length&&!p("quadrant").length)return null;const c=s.regionMode,{outer:r}=X(c==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:d,render:a=>{const b=p(c);if(!b.length){a.appendChild(l("div",{fontSize:E.body,color:Y},"No positioned dies for this breakdown."));return}for(const{label:u,n:S,yieldPercent:N}of b)a.appendChild(xe(`${u} (N=${S})`,N))},control:d?()=>be([["ring","Ring"],["quadrant","Quadrant"]],c,a=>{s.regionMode=a;const b=buildRegionYieldPanelSection(e);b&&r.replaceWith(b)},d.ownerDocument,!0):void 0});return r}export function buildLotOverviewSection(e,t=[]){const o=l("div"),n=ve(e.perWafer.map(s=>s.summary.wafer));o.appendChild(J(n.lotId!==void 0?"Lot Summary":"Summary"));const i=We();i.appendChild(se(String(e.stats.waferCount),"Wafers"));const d=e.perWafer.map(s=>s.summary.stats.yieldPercent).filter(s=>s!==null);if(d.length){const s=d.reduce((p,c)=>p+c,0)/d.length;i.appendChild(se(`${s.toFixed(1)}%`,"Mean per-wafer yield"))}if(i.finish(),o.appendChild(i),t.length){const s=t.reduce((c,r)=>c+r.stats.analyzedDies,0),p=t.reduce((c,r)=>c+r.stats.excludedDies,0);(s||p)&&o.appendChild(Pe("Dies analysed",p?`${s.toLocaleString()} (${p.toLocaleString()} excluded)`:s.toLocaleString()))}return o}export function buildPerWaferYieldSection(e,t,o,n,i){const d=e.perWafer.map(f=>({waferIndex:f.waferIndex,label:me(t[f.waferIndex],f.waferIndex).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:f.summary.stats.yieldPercent})).filter(f=>f.yieldPct!==null);if(!d.length)return null;const s=Math.min(...d.map(f=>f.yieldPct)),p=Math.max(...d.map(f=>f.yieldPct)),c=s===p?"":` (${s.toFixed(1)}\u2013${p.toFixed(1)}%)`,r=[...d.map(f=>f.yieldPct)].sort((f,w)=>f-w),a=mt(r),b=oe(r,.25),u=oe(r,.75),S=d.length>=5?b-1.5*(u-b):-1/0,N=pe(n),A=f=>{const w=N.waferSort==="yield"?[...d].sort((m,x)=>m.yieldPct-x.yieldPct):d;for(const{waferIndex:m,label:x,yieldPct:C}of w){const k=C<S?`${x} \xB7 low outlier`:x,T=xe(k,C,void 0,void 0,a),M=i?.(m);M?.total&&H(T,M),h(T,m,x,C,M),f.appendChild(T)}},P=` \xB7 median ${a.toFixed(1)}%`,{outer:R}=X("Wafer Yield"+c+P,!0,void 0,{stateKey:"waferYield",panel:n,render:A,control:n?f=>be([["slot","Slot"],["yield","Yield"]],N.waferSort,w=>{N.waferSort=w,f()},n.ownerDocument,!0):void 0});return R;function H(f,w){const m=w.unusual?"unusual":w.notable?"notable":"info",x=l("span",{marginLeft:y.sm,flexShrink:"0",background:de(m),color:"#fff",borderRadius:_.container,padding:"0 5px",fontSize:E.body,fontWeight:"600"},`${w.total}`);x.setAttribute("aria-hidden","true"),ie(x,`${w.total} finding${w.total===1?"":"s"}`+(w.unusual?`, ${w.unusual} unusual`:"")+(w.notable?`, ${w.notable} notable`:"")),f.firstElementChild?.firstElementChild?.appendChild(x)}function h(f,w,m,x,C){o&&(f.style.cursor="pointer",f.style.borderRadius="4px",f.style.padding="2px 3px",f.style.marginLeft="-3px",f.style.marginRight="-3px",f.setAttribute("role","button"),f.setAttribute("aria-label",`${m}, ${x.toFixed(1)}% yield`+(C?.total?`, ${C.total} finding${C.total===1?"":"s"}${C.unusual?`, ${C.unusual} unusual`:""}`:"")+" \u2014 open wafer"),f.tabIndex=0,f.addEventListener("mouseenter",()=>{f.style.background=B.bgHover}),f.addEventListener("mouseleave",()=>{f.style.background=""}),f.addEventListener("focus",()=>{f.style.background=B.bgHover}),f.addEventListener("blur",()=>{f.style.background=""}),f.addEventListener("click",()=>o(w)),f.addEventListener("keydown",v=>{(v.key==="Enter"||v.key===" ")&&(v.preventDefault(),o(w))}))}}function wt(e){const t=[...e].sort((i,d)=>i-d),o=e.reduce((i,d)=>i+d,0)/e.length,n=e.reduce((i,d)=>i+(d-o)**2,0)/e.length;return{min:t[0],max:t[t.length-1],mean:o,count:e.length,stddev:Math.sqrt(n),median:oe(t,.5),q1:oe(t,.25),q3:oe(t,.75)}}function Ye(e,t){if(!e)return[];const o=e.waferMetadata??(e.perWaferMetadata?we(e.perWaferMetadata.map(n=>({metadata:n}))):void 0);return!o||!Object.keys(o).length?[]:it({waferMetadata:o,waferKeys:"identity",waferPlacement:"csv",reservedLabels:t}).columns}function Oe(e){return e?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:e.populationLabel,get:()=>e.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(e,t,o,n,i,d,s,p,c="full"){const r=e.filter(g=>!g.partial&&!g.edgeExcluded),a=new Map((n?.perTestStats??[]).map(g=>[g.testNumber,g])),b=new Map((n?.testSpecYield??[]).map(g=>[g.testNumber,g]));let u;if(t?.length?u=t.filter(Ge).map(g=>({testNumber:g.testNumber,name:g.name,unit:g.unit,limitLow:g.limitLow,limitHigh:g.limitHigh})):u=dt(r).map(F=>({testNumber:F,name:`Test ${F}`})),!u.length)return null;const S=u.filter(g=>r.some(F=>{const O=F.testValues?.[g.testNumber];return O!==void 0&&isFinite(O)}));if(!S.length)return null;const N=S.some(g=>g.limitLow!==void 0||g.limitHigh!==void 0),A=[];for(const g of S){const F=a.get(g.testNumber),O=F&&F.stddev!==void 0&&F.median!==void 0&&F.q1!==void 0&&F.q3!==void 0;let L;if(O){const $=F;L={testNumber:g.testNumber,min:$.min,max:$.max,mean:$.mean,count:$.count,stddev:$.stddev,median:$.median,q1:$.q1,q3:$.q3}}else{const $=r.map(D=>D.testValues?.[g.testNumber]).filter(D=>D!==void 0&&isFinite(D));if(!$.length)continue;L={testNumber:g.testNumber,...wt($)}}let I=null,z=0;if(g.limitLow!==void 0||g.limitHigh!==void 0){const $=b.get(g.testNumber);if($)({yieldPercent:I,totalDies:z}=$);else{const D=r.map(j=>j.testValues?.[g.testNumber]).filter(j=>j!==void 0&&isFinite(j)),Z=D.filter(j=>g.limitLow!==void 0&&j<g.limitLow||g.limitHigh!==void 0&&j>g.limitHigh).length;z=D.length,I=D.length>0?(D.length-Z)/D.length*100:null}}A.push({entry:g,stats:L,specYieldPct:I,specN:z})}if(!A.length)return null;const P=new Map;if(s?.length&&t?.length)for(const g of ct(s,t))g.hasSpec&&P.set(g.testNumber,g.ppk);const R=P.size>0,h=new Set(A.map(g=>g.stats.count)).size===1?A[0].stats.count:null,f=l("div"),w=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:y.sm}),m=h!==null?` \xB7 N=${h.toLocaleString()}`:"",x=d?.populationLabel?`Test Values (${A.length}) \u2014 ${d.populationLabel}${m}`:`Test Values (${A.length})${m}`,C=J(x);C.style.marginBottom="0",w.appendChild(C);const v=document.createElement("button");v.type="button",v.textContent="Test values CSV",Object.assign(v.style,{...le("outlined")}),q(v),v.addEventListener("click",()=>{const g=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];R&&g.push("Ppk");const F=A.some($=>$.specYieldPct!==null&&$.specN!==$.stats.count);N&&(g.push("LSL","USL","Spec Yield %"),F&&g.push("Spec Yield N"));const O=[...Ye(d,g),...Oe(d)],I=[[...O.map($=>$.label),...g].map(ce).join(",")],z=$=>ke($,void 0,"engineering");for(const{entry:$,stats:D,specYieldPct:Z,specN:j}of A){const ae=[...O.map(te=>te.constant??""),$.name,$.unit??"",String(D.count),z(D.min),z(D.q1),z(D.median),z(D.mean),z(D.q3),z(D.max),z(D.stddev)];if(R){const te=P.get($.testNumber);ae.push(te==null?"":te.toFixed(3))}N&&(ae.push($.limitLow!==void 0?z($.limitLow):"",$.limitHigh!==void 0?z($.limitHigh):"",Z!==null?Z.toFixed(1):""),F&&ae.push($.limitLow!==void 0||$.limitHigh!==void 0?String(j):"")),I.push(ae.map(ce).join(","))}De(I.join(`
|
|
2
|
-
`),"test-values.csv","text/csv",
|
|
3
|
-
`),"functional-tests.csv","text/csv",n)}),b.appendChild(N),a.appendChild(b);const A=l("table",{width:"100%",borderCollapse:"collapse",fontSize:E.body}),P=document.createElement("thead"),R=document.createElement("tr"),H=c===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const m of H)R.appendChild(l("th",{textAlign:m==="Test"?"left":"right",fontWeight:"700",fontSize:E.body,letterSpacing:re,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${B.menuBorder}`,whiteSpace:"nowrap"},m));P.appendChild(R),A.appendChild(P);const h=document.createElement("tbody");for(const m of s){const x=document.createElement("tr"),C=(v,k="right")=>{x.appendChild(l("td",{textAlign:k,padding:`${y.xs} ${y.md}`,borderBottom:`1px solid ${B.menuBorder}`,color:K,whiteSpace:"nowrap"},v))};C(m.label,"left"),c===null&&C(String(m.totalDies)),C(String(m.passDies)),C(String(m.failDies)),C(m.passRatePercent!==null?`${m.passRatePercent.toFixed(1)}%`:"\u2014"),h.appendChild(x)}A.appendChild(h);const f=l("div",{overflowX:"auto"});if(f.appendChild(A),!d)return a.appendChild(f),a;b.remove();const{outer:w}=X(u,!0,void 0,{stateKey:"functionalTests",panel:d,render:m=>m.appendChild(f),control:()=>N});return w}export function buildLotFunctionalSection(e,t,o,n,i){const d=o?.length?{perWaferMetadata:o.map(p=>p.wafer??{}),populationLabel:`${o.length} wafer${o.length===1?"":"s"} pooled`}:void 0,s=ut(o);return s?buildFunctionalTestSection(e,t,s,n,d,i):buildFunctionalTestSection(e,t,void 0,n,d,i)}const ee={unusual:0,notable:1,info:2};function ye(e){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:_.pill,background:de(e),flexShrink:"0"})}function _e(e,t){let o=e.summary;return t&&(o.startsWith(`${t} has `)?o=o.slice(t.length+5):o.startsWith(`${t} `)&&(o=o.slice(t.length+1))),o=ne(o),o.length?o[0].toUpperCase()+o.slice(1):o}export function buildFindingsSection(e,t,o,n,i=!1){if(!e.length)return null;const d=e.some(h=>h.severity==="unusual"||h.severity==="notable"),s=d?e.filter(h=>h.severity!=="info").length.toString():void 0,{outer:p,content:c}=i?(()=>{const h=l("div");return{outer:h,content:h}})():X(`Findings (${e.length})`,d,s);function r(h){return h.reduce((f,w)=>ee[w.severity]<ee[f]?w.severity:f,"info")}function a(h){const f=new Map;for(const m of h){const x=`${m.comparison.family}\0${m.comparison.left}`,C=f.get(x)??[];C.push(m),f.set(x,C)}const w=[...f.entries()].map(([m,x])=>{const C=[...x].sort((v,k)=>ee[v.severity]-ee[k.severity]);return{key:m,findings:C,worst:r(C)}});return w.sort((m,x)=>ee[m.worst]-ee[x.worst]),w}function b(h,f){const m={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[h]??h;return f.toLowerCase().startsWith(m.toLowerCase())?f:`${m}: ${f}`}const u=e.filter(h=>h.comparison.family==="spatial-pattern"),S=new Set([...u.flatMap(h=>h.relatedIds??[]),...e.flatMap(h=>h.absorbedIds??[])]),N=e.filter(h=>h.comparison.family!=="spatial-pattern"&&!S.has(h.id)),A=a(N);function P(h,f=!1,w){const m=n===h.id,x=document.createElement("button");return x.type="button",x.dataset.wmapFinding=h.id,x.textContent=_e(h,w),ie(x,h.summary),x.setAttribute("aria-current",m?"true":"false"),Object.assign(x.style,{border:`1px solid ${B.menuBorder}`,borderLeft:`3px solid ${de(h.severity)}`,background:m?B.bgActive:B.menuBg,borderRadius:_.container,padding:f?"6px 10px":"8px 10px",textAlign:"left",fontSize:f?"10px":"11px",fontWeight:m?"600":"400",color:B.text,cursor:"pointer",width:"100%",marginBottom:y.xs}),q(x,"bare"),x.addEventListener("click",()=>o(h,x)),x}const R=ne(tt(e)??"");if(R){const h=l("div",{background:B.bgActive,borderRadius:_.container,padding:`${y.md} ${y.lg}`,marginBottom:y.md,display:"flex",gap:y.md,alignItems:"flex-start"}),f=l("span",{flex:"1",fontSize:E.body,lineHeight:Q.base,color:B.text},R);h.appendChild(f);const w=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:E.body,color:B.icon,cursor:"pointer",padding:"0",lineHeight:Q.base,whiteSpace:"nowrap"},"Detail \u25B8");w.type="button",q(w,"bare"),w.addEventListener("click",()=>{const m=Fe({title:"Findings Summary",onClose:()=>{},anchor:w}),x=l("p",{fontSize:"16px",lineHeight:Q.base,color:B.text,padding:`${y.xxl} ${y.xxxl} ${y.xxl}`,margin:"0",borderBottom:`1px solid ${B.menuBorder}`,flexShrink:"0"},R);m.contentWrap.appendChild(x);const C=l("div",{overflowY:"auto",padding:`${y.xxl} ${y.xxxl}`,flex:"1"}),v=(k,T)=>{const M=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:E.sub,fontWeight:"600",color:K,marginTop:y.lg,marginBottom:y.xs});return M.appendChild(ye(k)),M.appendChild(l("span",{},T)),M};for(const k of u){C.appendChild(v(k.severity,k.comparison.left)),C.appendChild(l("div",{fontSize:E.body,color:B.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},ne(k.summary)));const T=e.filter(M=>k.relatedIds?.includes(M.id));for(const M of T)C.appendChild(l("div",{fontSize:E.body,color:Y,padding:"2px 0 2px 23px",marginBottom:y.xxs},ne(M.summary)))}for(const k of A){const[T,M]=k.key.split("\0");C.appendChild(v(k.worst,b(T,M)));for(const W of k.findings)C.appendChild(l("div",{fontSize:E.body,color:B.text,padding:"4px 0 4px 15px",marginBottom:y.xxs},_e(W,M)))}m.contentWrap.appendChild(C),Object.assign(m.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),h.appendChild(w),c.appendChild(h)}let H=!0;for(const h of u){H||c.appendChild(l("div",{height:"1px",background:B.separator,margin:"4px 0"})),H=!1;const f=e.filter(v=>h.relatedIds?.includes(v.id)),w=f.length>0,m=l("div",{position:"relative",marginBottom:w?"2px":"4px"}),x=n===h.id,C=document.createElement("button");if(C.type="button",C.dataset.wmapFinding=h.id,Object.assign(C.style,{border:`1px solid ${B.menuBorder}`,borderLeft:`3px solid ${de(h.severity)}`,background:x?B.bgActive:B.menuBg,borderRadius:_.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:E.body,fontWeight:x?"600":"500",color:B.text,cursor:"pointer",width:"100%"}),C.textContent=ne(h.summary),ie(C,h.summary),C.setAttribute("aria-current",x?"true":"false"),q(C,"bare"),C.addEventListener("click",()=>o(h,C)),m.appendChild(C),w){const v=l("div",{display:"none",paddingLeft:"12px",marginBottom:y.xs});for(const M of f)v.appendChild(P(M,!0));m.appendChild(v);let k=!1;const T=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:E.body,color:B.icon,cursor:"pointer",padding:`${y.xxs} ${y.xs}`,lineHeight:Q.none},"\u25B8");q(T,"bare"),T.type="button",ie(T),T.setAttribute("aria-label","Show supporting findings"),T.setAttribute("aria-expanded","false"),T.addEventListener("click",M=>{M.stopPropagation(),k=!k,v.style.display=k?"block":"none",T.textContent=k?"\u25BE":"\u25B8";const W=k?"Hide supporting findings":"Show supporting findings";T.setAttribute("aria-label",W),T.setAttribute("aria-expanded",String(k))}),m.appendChild(T)}c.appendChild(m)}for(const h of A){H||c.appendChild(l("div",{height:"1px",background:B.separator,margin:"4px 0"})),H=!1;const[f,w]=h.key.split("\0"),m=l("div",{display:"flex",alignItems:"center",gap:y.sm,fontSize:E.body,fontWeight:"600",color:K,margin:"2px 0 4px"});m.appendChild(ye(h.worst)),m.appendChild(l("span",{},b(f,w))),c.appendChild(m);for(const x of h.findings)c.appendChild(P(x,!1,w))}return p}const St=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],vt=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],$t=["unusual","notable","info"],kt={unusual:"Unusual",notable:"Notable",info:"Info"};function Bt(e,t,o){const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:y.lg,marginBottom:y.lg,paddingBottom:"10px",borderBottom:`1px solid ${B.separator}`}),i={unusual:0,notable:0,info:0};for(const r of e)i[r.severity]++;const d=$t.filter(r=>i[r]>0),s=new Set(t.severity===void 0?d:Array.isArray(t.severity)?t.severity:[t.severity]),p=l("div",{display:"flex",gap:y.xs,flexWrap:"wrap"});for(const r of d){const a=document.createElement("button");a.type="button";const b=()=>{const u=s.has(r);a.setAttribute("aria-pressed",u?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${B.menuBorder}`,borderRadius:_.pill,background:u?B.bgActive:"none",opacity:u?"1":"0.5",color:B.text,fontSize:E.body,padding:`${y.xxs} ${y.md}`,cursor:"pointer"}),a.dataset.on=u?"true":"false"};a.appendChild(ye(r)),a.appendChild(l("span",{},`${kt[r]} ${i[r]}`)),ie(a,()=>s.has(r)?"Click to hide these findings":"Click to show these findings"),b(),q(a,"bare"),a.addEventListener("click",()=>{s.has(r)?s.delete(r):s.add(r),t.severity=s.size===d.length?void 0:[...s],o()}),p.appendChild(a)}n.appendChild(p);const c=t.kind!==void 0||t.family!==void 0;return(e.length>=Lt||c)&&(n.appendChild(Be("Kind:",St,t.kind??"",r=>{t.kind=r||void 0,o()},{maxWidth:"130px"})),n.appendChild(Be("Region:",vt,t.family??"",r=>{t.family=r||void 0,o()},{maxWidth:"150px"}))),n}const Lt=8;function Nt(e,t){const o=l("div",{display:"flex",flexDirection:"column",gap:y.xs,padding:y.md,marginBottom:y.md,background:B.bgHover,borderRadius:_.control},void 0,t);if(o.appendChild(l("div",{fontSize:E.body,color:B.value},e.message,t)),e.detail&&o.appendChild(l("div",{fontSize:E.meta,color:Y},e.detail,t)),e.actionLabel&&e.onAction){const n=l("button",le("outlined"),e.actionLabel,t);n.type="button",n.style.alignSelf="flex-start",n.style.marginTop=y.xs,q(n),n.addEventListener("click",e.onAction),o.appendChild(n)}return o}export function buildFindingsSectionWithFilter(e,t,o,n,i,d,s){if(!e.findings.length&&!s)return null;const p=e.findings.some(N=>N.severity==="unusual"||N.severity==="notable"),c=p?e.findings.filter(N=>N.severity!=="info").length.toString():void 0,r=d?.ownerDocument??document,{outer:a,content:b}=X(`Findings (${e.findings.length})`,p||!!s,c,{stateKey:"findings",panel:d});if(s&&b.appendChild(Nt(s,r)),!e.findings.length)return a;b.appendChild(Bt(e.findings,n,i));const u=nt(e,n);if(!u.length)return b.appendChild(l("div",{color:Y,fontSize:E.body,textAlign:"center",padding:`${y.xxl} ${y.md}`},"No findings match the current filter.")),a;const S=buildFindingsSection(u,e,t,o,!0);return S&&b.appendChild(S),a}export function buildLotTestSection(e,t,o,n,i,d,s,p="full"){const c=n?.length?{perWaferMetadata:n.map(a=>a.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;let r;if(n?.length&&n.every(a=>a.stats.perTestStats!==void 0)){const a=new Map;for(const b of n)for(const u of b.stats.perTestStats??[]){const S=a.get(u.testNumber);S?(S.n+=u.count,S.sum+=u.mean*u.count,S.min=Math.min(S.min,u.min),S.max=Math.max(S.max,u.max)):a.set(u.testNumber,{n:u.count,sum:u.mean*u.count,min:u.min,max:u.max})}r={perTestStats:[...a.entries()].map(([b,u])=>({testNumber:b,count:u.n,min:u.min,max:u.max,mean:u.sum/u.n}))}}if(n?.length&&n.every(a=>a.stats.testSpecYield!==void 0)){const a=new Map;for(const b of n)for(const u of b.stats.testSpecYield??[]){const S=a.get(u.testNumber);S?(S.passDies+=u.passDies,S.totalDies+=u.totalDies):a.set(u.testNumber,{passDies:u.passDies,totalDies:u.totalDies})}r={...r,testSpecYield:[...a.entries()].map(([b,u])=>({testNumber:b,totalDies:u.totalDies,yieldPercent:u.totalDies>0?u.passDies/u.totalDies*100:null}))}}return buildTestSection(e,t,o,r,i,c,d,s,p)}export function createSummaryPanelEl(e,t,o=document){const n=e==="top"||e==="bottom",i=l("div",{background:gt,color:B.text,fontVariantNumeric:"tabular-nums",border:Re,borderRadius:_.container,padding:y.xl,overflowY:"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:E.family,fontSize:E.sub,boxShadow:Le.panel},void 0,o);return e==="right"&&(i.style.marginRight=t),e==="left"&&(i.style.marginLeft=t),e==="bottom"&&(i.style.marginBottom=t),n?(i.style.height="180px",i.style.width="100%"):(i.style.width="300px",i.style.maxHeight="100%"),i}export function wrapWithSummaryPanel(e,t,o){const n=o==="top"||o==="bottom",i=l("div",{display:"flex",flexDirection:n?"column":"row",gap:y.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:n?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",o==="right"||o==="bottom"?(i.appendChild(e),i.appendChild(t)):(i.appendChild(t),i.appendChild(e)),i}function je(e){return l("div",{fontSize:E.heading,fontWeight:"600",color:K,marginBottom:y.lg},e)}function fe(e,t){const o=l("button",le("outlined"),e);return o.type="button",q(o),o.addEventListener("click",t),o}function qe(...e){const t=e.filter(n=>!!n);if(!t.length)return null;const o=l("div",{display:"flex",flexWrap:"wrap",gap:y.sm,marginBottom:y.lg});for(const n of t)o.appendChild(n);return o}function Ve(e,t,o,n,i,d,s,p,c,r,a){const b=e.ownerDocument,u=Fe({title:"Die list",onClose:()=>{},anchor:e,ownerDocument:b});u.contentWrap.style.padding="14px 16px";const S=ft(t,o,{...s,title:n,onSaveText:p,waferMetadata:i,metadataFields:d,extraColumn:c,getWafer:r,ringCount:a,ownerDocument:b});S&&u.contentWrap.appendChild(S)}export function renderWaferSummaryContent(e,t){const o=e.scrollTop;e.innerHTML="";const{wafer:n,dies:i,yieldSummary:d,dataCoverage:s,hbinDefs:p,sbinDefs:c,testDefs:r,statsSummary:a,passBins:b=[1],ringCount:u=4,binColors:S,plotMode:N,fallbackFormat:A,onFindingClick:P,activeFindingId:R=null,findingsFilter:H,onFindingsFilterChange:h,findingsNotice:f,onSaveText:w,metadataFields:m,dieListOptions:x,metadataShownElsewhere:C}=t;e.appendChild(je("Wafer Summary"));const v=t.warnings??$e({statsSummary:a});v.length&&e.appendChild(ge(v,e.ownerDocument));const k=d&&s?fe("Summary report",()=>{Ee(Je({wafer:n,dies:i,yield:d,dataCoverage:s,hbinDefs:p,sbinDefs:c,testDefs:r,passBins:b,ringCount:u},a),{anchor:e})}):null,T=(x?.enabled??!0)&&i.length?fe("View die list",()=>{Ve(e,i,r,`Die list \u2014 ${i.length} dies`,n.metadata,m,x,w,void 0,()=>n,u)}):null,M=qe(k,T);M&&e.appendChild(M);const W=[],V=a?.stats.isLotStack?a.stats:void 0,G=V?.lotSize!==void 0?{lotSize:V.lotSize,aggrMethod:lt(V.aggregationMethod)}:void 0;C||W.push(buildMetadataInfoSection([{metadata:n.metadata??void 0}],G)),d&&s&&W.push(buildYieldSection(d,s,b)),a&&P&&H&&h&&W.push(buildFindingsSectionWithFilter(a,P,R,H,h,e,f)),W.push(buildBinBreakdownSection({dies:i,hbinDefs:p,sbinDefs:c,binColors:S,hardCounts:a?.stats.hardBinCounts,softCounts:a?.stats.softBinCounts,plotMode:N,passBins:b,panel:e})),W.push(buildRegionYieldPanelSection({diesByWafer:[i],allWafers:[n],ringCount:u,passBins:b,panel:e}));const U=n.metadata?{waferMetadata:n.metadata}:void 0;W.push(buildTestSection(i,r,A,a?.stats,w,U,[{dies:i}],e,"compact")),W.push(buildFunctionalTestSection(i,r,a?.stats.functionalYield,w,U,e));let g=!0;for(const F of W)F&&(g||e.appendChild(Ae()),g=!1,e.appendChild(F));e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=o}export function reportMapsFromItems(e,t,o){const n=[];return e.forEach((i,d)=>{!i?.wafer||!i.dies||n.push({...i,wafer:i.wafer,dies:i.dies,label:me(i,d),passBins:[...he(i,t)],ringCount:i.ringCount??o})}),n}export function renderLotSummaryContent(e,t){const o=e.scrollTop;e.innerHTML="";const{lotSummary:n,items:i,hbinDefs:d,sbinDefs:s,testDefs:p,passBins:c=[1],ringCount:r=4,binColors:a,plotMode:b,fallbackFormat:u,onFindingClick:S,activeFindingId:N=null,onWaferClick:A,findingsFilter:P,onFindingsFilterChange:R,findingsNotice:H,onSaveText:h,dieListOptions:f,findingsFor:w}=t;e.appendChild(je(`Summary \u2014 ${rt(ve(n.perWafer.map(L=>L.summary.wafer)))}`));const m=t.warnings??$e({lotStatsSummary:n});m.length&&e.appendChild(ge(m,e.ownerDocument));const x=fe("Summary report",()=>{Ee(et(reportMapsFromItems(i,c,r)),{anchor:e})}),C=[],v=[],k=[],T=[],M=[],W=new WeakMap,V=new WeakMap;for(let L=0;L<i.length;L++){const I=i[L];if(!I){v.push([]);continue}I.wafer&&(C.push(I.wafer),T.push(I.dies??[]),M.push(he(I,c)));const z=I.dies??[],$=me(I,L);for(const D of z)W.set(D,$),I.wafer&&V.set(D,I.wafer);v.push(z),k.push(...z)}const G=f?.enabled??!0?fe("View die list",()=>{k.length&&Ve(e,k,p,`Die list \u2014 ${k.length} dies across ${i.length} wafer${i.length===1?"":"s"}`,we(i.filter(L=>!!L).map(L=>({metadata:L.wafer?.metadata}))),i.find(L=>L?.metadataFields?.length)?.metadataFields,f,h,{label:"Wafer",get:L=>W.get(L)},L=>V.get(L),r)}):null,U=qe(x,G);U&&e.appendChild(U);const g=i.map(L=>L?.statsSummary).filter(L=>!!L),F=[buildLotOverviewSection(n,g)];S&&P&&R&&F.push(buildFindingsSectionWithFilter(n,S,N,P,R,e,H)),F.push(buildPerWaferYieldSection(n,i,A,e,w),buildBinBreakdownSection({dies:k,hbinDefs:d,sbinDefs:s,plotMode:b,passBins:c,panel:e,binColors:a??st(i.flatMap(L=>L?[{dies:L.dies??[],passBins:he(L,c)}]:[]),{hbinDefs:d,sbinDefs:s}).colors}),buildRegionYieldPanelSection({diesByWafer:T,allWafers:C,ringCount:r,passBins:L=>M[L],panel:e}),p?.length?buildLotTestSection(k,p,u,g,h,v.map(L=>({dies:L})),e,"compact"):null,p?.length?buildLotFunctionalSection(k,p,g,h,e):null);let O=!0;for(const L of F)L&&(O||e.appendChild(Ae()),O=!1,e.appendChild(L));e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=o}
|
|
1
|
+
import{waferDisplayLabel as ve}from"../core/waferLabel.js";import{itemPassBins as Se,passBinsLabel as lt}from"../core/passBins.js";import{isParametricTest as dt}from"../renderer/buildWaferMap.js";import{testLabel as ct,markedTestLabel as pt,unmarkedLabel as ut,derivedFields as we,derivedKeyText as ft,derivedCsvCell as Ne,isDerivedTest as Te,DERIVED_CSV_HEADER as De}from"../renderer/testLabel.js";import{buildRingRegions as mt,buildQuadrantRegions as gt,buildRegionYieldData as ht}from"../stats/regions.js";import{computeFunctionalYield as bt}from"../stats/analyzeWaferMap.js";import{renderWaferReportHtml as xt,renderLotReportHtml as yt}from"../stats/renderSummaryReport.js";import{buildFindingsNarrative as Ct}from"../stats/findingsNarrative.js";import{formatFindingTooltip as vt}from"../stats/reportHtml.js";import{filterFindings as St}from"../stats/filterFindings.js";import{buildFacetTable as wt,prettyKey as Ee}from"../stats/facets.js";import{commonMetadata as Fe}from"../stats/facets.js";import{resolveMetadataColumns as $t}from"../stats/metadataColumns.js";import{resolveBinColors as Re,resolveBinColorsByWafer as kt}from"../renderer/binColors.js";import{NO_DATA_FILL as Lt}from"../renderer/colorMap.js";import{describeWaferPopulation as Me,populationLabel as Bt}from"../stats/population.js";import{buildWarningsBanner as $e,collectWarnings as Ie}from"./warnings.js";export{$e as buildWarningsBanner};import{fmt as Ae,fmtAggregationMethod as Nt,plainBinTerms as de}from"../renderer/fmt.js";import{getUniqueTestNumbers as Tt}from"../renderer/buildView.js";import{describeSorted as Dt,quantile as We}from"../stats/math.js";import{pooledTestStatsSteps as Et}from"../stats/capability.js";import{sortBinsForDisplay as Ft}from"../stats/binPareto.js";import{poolFunctionalYield as Rt}from"../stats/testPassRate.js";import{makeLabeledSelect as Pe,makeSegmented as ke}from"./charts/chartShell.js";import{SHADOW as ze,MOTION as He,LEADING as ne,TRACKING as fe,wireControlHover as G,controlStyle as me,SPACE as x,RADIUS as q,FONT as T,CLR as $,sevColor as ge,openModal as Oe,openReportModal as Ye,saveTextFile as _e,wireTooltip as ce}from"./toolbar.js";import{buildDieListSection as Mt}from"./dieList.js";export{csvField}from"../core/utils.js";import{csvField as he,drain as be,maxOf as It,medianOfSorted as At,minOf as Wt}from"../core/utils.js";import{metadataDisplayValue as Pt}from"../core/metadata.js";const zt=$.panelBg,je=`1px solid ${$.menuBorder}`,Ht="12px",Y=$.label,ie=$.value,Ke="10px";function l(e,t,i,n=document){const o=n.createElement(e);return t&&Object.assign(o.style,t),i!==void 0&&(o.textContent=i),o}function se(e){return l("div",{fontSize:Ke,fontWeight:"700",letterSpacing:fe,textTransform:"uppercase",color:Y,marginBottom:x.sm},e)}const Ve=new WeakMap,qe=["regionYield","testValues","functionalTests"];function xe(e){if(!e)return{collapsed:new Set(qe),regionMode:"ring",waferSort:"slot"};let t=Ve.get(e);return t||(t={collapsed:new Set(qe),regionMode:"ring",waferSort:"slot"},Ve.set(e,t)),t}function oe(e,t=!0,i,n){const o=l("div"),u=xe(n?.panel);n?.stateKey&&n.panel&&(t=!u.collapsed.has(n.stateKey));const s=document.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",gap:x.xs,width:"100%",background:"none",border:"none",cursor:"pointer",padding:"0 0 6px",textAlign:"left"});const m=l("span",{fontSize:T.meta,color:Y,transition:`transform ${He.base}`,transform:t?"rotate(90deg)":"rotate(0deg)",display:"inline-block",lineHeight:ne.none,marginRight:"1px"},"\u25B6"),p=l("span",{fontSize:Ke,fontWeight:"700",letterSpacing:fe,textTransform:"uppercase",color:Y,flex:"1"},e);if(G(s,"bare"),s.setAttribute("aria-expanded",t?"true":"false"),s.appendChild(m),s.appendChild(p),i){const b=l("span",{fontSize:T.meta,fontWeight:"700",background:$.warnBg,color:$.warnText,borderRadius:q.pill,padding:"1px 5px"},i);s.appendChild(b)}const r=l("div");r.style.display=t?"block":"none";let a=t;if(s.addEventListener("click",()=>{a=!a,r.style.display=a?"block":"none",m.style.transform=a?"rotate(90deg)":"rotate(0deg)",s.setAttribute("aria-expanded",a?"true":"false"),n?.stateKey&&n.panel&&(a?u.collapsed.delete(n.stateKey):u.collapsed.add(n.stateKey))}),n?.control){const b=l("div",{display:"flex",alignItems:"center",gap:x.sm});s.style.width="auto",s.style.flex="1",b.appendChild(s);const f=()=>{r.innerHTML="",n.render?.(r)},w=n.control(f);w&&(w.style.marginBottom="6px",w.addEventListener("click",k=>k.stopPropagation()),b.appendChild(w)),o.appendChild(b)}else o.appendChild(s);return o.appendChild(r),n?.render?.(r),{outer:o,content:r}}function Ge(){return l("div",{height:"1px",background:$.separator,margin:`${Ht} 0`,flexShrink:"0"})}function Le(e,t,i=$.barFill,n,o){const u=l("div",{marginBottom:"5px"}),s=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,color:ie,marginBottom:x.xxs}),m=l("span",{color:Y},e),p=l("span",{fontWeight:"600"},`${t.toFixed(1)}%`);s.appendChild(m),s.appendChild(p);const r=n!==void 0?n:Math.min(100,Math.max(0,t)),a=i,b=l("div",{position:"relative",height:"9px",background:$.bgActive,borderRadius:q.control,overflow:"hidden"}),f=l("div",{height:"100%",width:`${r}%`,background:a,borderRadius:q.control,transition:`width ${He.base}`});if(b.appendChild(f),o!==void 0){const w=l("div",{position:"absolute",top:"0",bottom:"0",left:`${o}%`,width:"2px",marginLeft:"-1px",background:$.value,opacity:"0.8"});b.appendChild(w)}return u.appendChild(s),u.appendChild(b),u}function Ue(){const e=l("div",{display:"flex",gap:x.sm,marginBottom:x.md});return e.finish=()=>{const t=e.lastElementChild;t&&Object.assign(t.style,{borderRight:"none",paddingRight:"0"})},e}function pe(e,t,i){const n=l("div",{padding:`${x.xxs} ${x.md} ${x.xxs} 0`,borderRight:je,textAlign:"center",flex:"1"}),o=l("div",{fontSize:T.heading,fontWeight:"700",color:ie,lineHeight:ne.tight},e),u=l("div",{fontSize:T.body,color:Y,marginTop:x.xxs},t);return n.appendChild(o),n.appendChild(u),i&&n.appendChild(l("div",{fontSize:T.body,color:Y,opacity:"0.85"},i)),n}function Qe(e,t){const i=l("div",{display:"flex",justifyContent:"space-between",fontSize:T.body,gap:x.md,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},e),o=l("span",{color:ie,textAlign:"right",fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}function Ot(e,t){const i=l("div",{display:"flex",fontSize:T.body,gap:x.sm,marginBottom:"3px"}),n=l("span",{color:Y,flexShrink:"0"},`${e}:`),o=l("span",{color:ie,fontWeight:"500",wordBreak:"break-all"},t);return i.appendChild(n),i.appendChild(o),i}export function metadataEntries(e){const t=[];for(const[i,n]of Object.entries(e)){const o=Pt(n);o!==void 0&&t.push([i,o])}return t}const Yt=["lot","product","testprogram","split"],ye=e=>{const t=Yt.indexOf(e.toLowerCase().replace(/[^a-z]/g,""));return t===-1?Number.MAX_SAFE_INTEGER:t};export function buildFacetSummaryChips(e,t=3){if(!e.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:`${x.xs} ${x.lg}`}),n=[...e].sort((m,p)=>ye(m.key)-ye(p.key)),o=n.filter(m=>ye(m.key)!==Number.MAX_SAFE_INTEGER),u=n.filter(m=>ye(m.key)===Number.MAX_SAFE_INTEGER),s=m=>{const p=l("span",{whiteSpace:"nowrap"}),r=l("span",{color:Y},`${Ee(m.key)}: `);p.appendChild(r);const a=m.values.slice(0,t),b=m.values.length-a.length;let f=a.map(w=>w.value).join(", ");return b>0&&(f+=` +${b} more`),p.appendChild(document.createTextNode(f)),p};for(const m of o)i.appendChild(s(m));if(u.length){const m=l("span",{display:"none",flexWrap:"wrap",alignItems:"baseline",gap:`${x.xs} ${x.lg}`});for(const a of u)m.appendChild(s(a));const p=l("button",{background:"none",border:"none",padding:"0",cursor:"pointer",color:$.iconActive,fontSize:T.body,whiteSpace:"nowrap"});p.type="button",G(p,"bare");const r=a=>{m.style.display=a?"contents":"none",p.textContent=a?"less":`+${u.length} more`,p.setAttribute("aria-expanded",String(a))};r(!1),p.addEventListener("click",()=>r(p.getAttribute("aria-expanded")!=="true")),i.appendChild(m),i.appendChild(p)}return i}export function buildMetadataStripRow(e,t,i){const n=wt(e,i),o=buildFacetSummaryChips(n);if(!o&&!t)return null;const u=l("div",{display:"flex",flexWrap:"wrap",alignItems:"baseline",gap:"4px 14px"});if(t){const s=l("span",{fontWeight:"500",whiteSpace:"nowrap"},t.aggrMethod?`${t.lotSize} wafers stacked \xB7 ${t.aggrMethod}`:`${t.lotSize} wafers stacked`);u.appendChild(s)}return o&&u.appendChild(o),u}const _t={display:"flex",flexDirection:"column",gap:x.sm,background:$.menuBg,border:`1px solid ${$.menuBorder}`,borderRadius:q.container,padding:`${x.sm} ${x.lg}`,boxShadow:ze.panel,fontSize:T.body,lineHeight:ne.none,boxSizing:"border-box",width:"100%",minWidth:"0"};export function buildMetadataStripBox(e,t,i){const n=buildMetadataStripRow(e,t,i);if(!n)return null;const o=l("div",_t);return o.appendChild(n),o}export function buildCompactMetadataRows(e){const t=metadataEntries(e);if(!t.length)return null;const i=l("div");for(const[n,o]of t)i.appendChild(Ot(Ee(n),o));return i}export function buildMetadataInfoSection(e,t){const i=buildMetadataStripRow(e,t,{facetableOnly:e.length>1});if(!i)return null;const n=l("div");return n.appendChild(se("Wafer Info")),n.appendChild(i),n}export function buildYieldSection(e,t,i=[1]){const n=l("div");n.appendChild(se("Summary"));const o=Ue();if(o.appendChild(pe(String(e.totalDies),"Total dies")),e.partialDies>0&&o.appendChild(pe(String(e.partialDies),"Partial")),e.yieldPercent!==null){const u=lt([i]);o.appendChild(pe(`${e.yieldPercent.toFixed(1)}%`,"Yield",`pass: ${u}`))}return o.finish(),n.appendChild(o),e.edgeExcludedDies>0&&n.appendChild(Qe("Edge excluded (outer zone)",String(e.edgeExcludedDies))),n}export function buildBinSection(e,t,i,n,o,u){const s=new Map;if(o)for(const[r,a]of Object.entries(o))s.set(Number(r),a);else for(const r of e){if(r.partial||r.edgeExcluded)continue;const a=i==="hard"?r.hbin:r.sbin;a!=null&&s.set(a,(s.get(a)??0)+1)}if(!s.size)return null;const m=n??Re(e,{passBins:u,...i==="hard"?{hbinDefs:t}:{sbinDefs:t}}),p=l("div");p.appendChild(se(Xe(i,[...s.values()].reduce((r,a)=>r+a,0))));for(const r of Ze(s,t,m[i],m.pass[i]))p.appendChild(r);return p}function Xe(e,t){return`${e==="hard"?"Hard":"Soft"} Bin Breakdown \u2014 % of dies (N=${t})`}function Ze(e,t,i,n){const o=[...e.values()].reduce((m,p)=>m+p,0),u=t?new Map(t.map(m=>[m.bin,m])):null;return Ft(e.entries(),n).map(([m,p])=>{const r=u?.get(m),a=r?.name?`Bin ${m} \xB7 ${r.name}`:`Bin ${m}`,b=p/o*100,f=i.get(m)??Lt;return Le(`${a} (${p})`,b,f)})}export function buildBinBreakdownSection(e){const{dies:t,hbinDefs:i,sbinDefs:n,hardCounts:o,softCounts:u,plotMode:s,passBins:m=[1],panel:p}=e,r=e.binColors??Re(t,{passBins:m,hbinDefs:i,sbinDefs:n}),a=v=>{const g=v==="hard"?o:u,h=new Map;if(g){for(const[y,S]of Object.entries(g))h.set(Number(y),S);return h}for(const y of t){if(y.partial||y.edgeExcluded)continue;const S=v==="hard"?y.hbin:y.sbin;S!=null&&h.set(S,(h.get(S)??0)+1)}return h},b=a("hard"),f=a("soft"),w=b.size>0,k=f.size>0;if(!w&&!k)return null;const F=xe(p),H=s==="softBin"||s==="stackedSoftBins"?"soft":s==="hardBin"||s==="stackedBins"?"hard":void 0;let I=F.binMode??H??(w?"hard":"soft");I==="hard"&&!w&&(I="soft"),I==="soft"&&!k&&(I="hard");const O=I==="hard"?b:f,z=I==="hard"?i:n,C=[...O.values()].reduce((v,g)=>v+g,0),{outer:d}=oe(Xe(I,C),!0,void 0,{stateKey:"bins",panel:p,render:v=>{const g=I==="hard"?r.hard:r.soft;for(const h of Ze(O,z,g,r.pass[I]))v.appendChild(h)},control:w&&k&&p?()=>ke([["hard","Hard"],["soft","Soft"]],I,v=>{F.binMode=v;const g=buildBinBreakdownSection(e);g&&d.replaceWith(g)},p.ownerDocument,!0):void 0});return d}export function buildLotBinSection(e,t,i,n){return buildBinSection(e,t,i,n)}export function buildRegionYieldPanelSection(e){const{diesByWafer:t,allWafers:i,ringCount:n,passBins:o,panel:u}=e,s=xe(u),m=a=>ht(t,i,n,o,a==="ring"?mt:gt);if(!m("ring").length&&!m("quadrant").length)return null;const p=s.regionMode,{outer:r}=oe(p==="ring"?"Ring Yield":"Quadrant Yield",!0,void 0,{stateKey:"regionYield",panel:u,render:a=>{const b=m(p);if(!b.length){a.appendChild(l("div",{fontSize:T.body,color:Y},"No positioned dies for this breakdown."));return}for(const{label:f,n:w,yieldPercent:k}of b)a.appendChild(Le(`${f} (N=${w})`,k))},control:u?()=>ke([["ring","Ring"],["quadrant","Quadrant"]],p,a=>{s.regionMode=a;const b=buildRegionYieldPanelSection(e);b&&r.replaceWith(b)},u.ownerDocument,!0):void 0});return r}export function buildLotOverviewSection(e,t=[]){const i=l("div"),n=Me(e.perWafer.map(s=>s.summary.wafer));i.appendChild(se(n.lotId!==void 0?"Lot Summary":"Summary"));const o=Ue();o.appendChild(pe(String(e.stats.waferCount),"Wafers"));const u=e.perWafer.map(s=>s.summary.stats.yieldPercent).filter(s=>s!==null);if(u.length){const s=u.reduce((m,p)=>m+p,0)/u.length;o.appendChild(pe(`${s.toFixed(1)}%`,"Mean per-wafer yield"))}if(o.finish(),i.appendChild(o),t.length){const s=t.reduce((p,r)=>p+r.stats.analyzedDies,0),m=t.reduce((p,r)=>p+r.stats.excludedDies,0);(s||m)&&i.appendChild(Qe("Dies analysed",m?`${s.toLocaleString()} (${m.toLocaleString()} excluded)`:s.toLocaleString()))}return i}export function buildPerWaferYieldSection(e,t,i,n,o){const u=e.perWafer.map(C=>({waferIndex:C.waferIndex,label:ve(t[C.waferIndex],C.waferIndex).replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPct:C.summary.stats.yieldPercent})).filter(C=>C.yieldPct!==null);if(!u.length)return null;const s=Wt(u.map(C=>C.yieldPct)),m=It(u.map(C=>C.yieldPct)),p=s===m?"":` (${s.toFixed(1)}\u2013${m.toFixed(1)}%)`,r=[...u.map(C=>C.yieldPct)].sort((C,d)=>C-d),a=At(r),b=We(r,.25),f=We(r,.75),w=u.length>=5?b-1.5*(f-b):-1/0,k=xe(n),F=C=>{const d=k.waferSort==="yield"?[...u].sort((v,g)=>v.yieldPct-g.yieldPct):u;for(const{waferIndex:v,label:g,yieldPct:h}of d){const S=h<w?`${g} \xB7 low outlier`:g,L=Le(S,h,void 0,void 0,a),A=o?.(v);A?.total&&O(L,A),z(L,v,g,h,A),C.appendChild(L)}},H=` \xB7 median ${a.toFixed(1)}%`,{outer:I}=oe("Wafer Yield"+p+H,!0,void 0,{stateKey:"waferYield",panel:n,render:F,control:n?C=>ke([["slot","Slot"],["yield","Yield"]],k.waferSort,d=>{k.waferSort=d,C()},n.ownerDocument,!0):void 0});return I;function O(C,d){const v=d.unusual?"unusual":d.notable?"notable":"info",g=l("span",{marginLeft:x.sm,flexShrink:"0",background:ge(v),color:"#fff",borderRadius:q.container,padding:"0 5px",fontSize:T.body,fontWeight:"600"},`${d.total}`);g.setAttribute("aria-hidden","true"),ce(g,`${d.total} finding${d.total===1?"":"s"}`+(d.unusual?`, ${d.unusual} unusual`:"")+(d.notable?`, ${d.notable} notable`:"")),C.firstElementChild?.firstElementChild?.appendChild(g)}function z(C,d,v,g,h){i&&(C.style.cursor="pointer",C.style.borderRadius="4px",C.style.padding="2px 3px",C.style.marginLeft="-3px",C.style.marginRight="-3px",C.setAttribute("role","button"),C.setAttribute("aria-label",`${v}, ${g.toFixed(1)}% yield`+(h?.total?`, ${h.total} finding${h.total===1?"":"s"}${h.unusual?`, ${h.unusual} unusual`:""}`:"")+" \u2014 open wafer"),C.tabIndex=0,C.addEventListener("mouseenter",()=>{C.style.background=$.bgHover}),C.addEventListener("mouseleave",()=>{C.style.background=""}),C.addEventListener("focus",()=>{C.style.background=$.bgHover}),C.addEventListener("blur",()=>{C.style.background=""}),C.addEventListener("click",()=>i(d)),C.addEventListener("keydown",y=>{(y.key==="Enter"||y.key===" ")&&(y.preventDefault(),i(d))}))}}function jt(e){return Dt([...e].sort((t,i)=>t-i))}function Je(e,t){if(!e)return[];const i=e.waferMetadata??(e.perWaferMetadata?Fe(e.perWaferMetadata.map(n=>({metadata:n}))):void 0);return!i||!Object.keys(i).length?[]:$t({waferMetadata:i,waferKeys:"identity",waferPlacement:"csv",reservedLabels:t}).columns}function et(e){return e?.populationLabel?[{key:"population",label:"Population",scope:"wafer",constant:e.populationLabel,get:()=>e.populationLabel,csvOnly:!0}]:[]}export function buildTestSection(...e){return be(buildTestSectionSteps(...e))}export function*buildTestSectionSteps(e,t,i,n,o,u,s,m,p="full"){const r=e.filter(c=>!c.partial&&!c.edgeExcluded),a=new Map((n?.perTestStats??[]).map(c=>[c.testNumber,c])),b=new Map((n?.testSpecYield??[]).map(c=>[c.testNumber,c]));let f;if(t?.length?f=t.filter(dt).map(c=>({testNumber:c.testNumber,name:c.name,unit:c.unit,limitLow:c.limitLow,limitHigh:c.limitHigh,...we(c)})):f=Tt(r).map(W=>({testNumber:W,name:ct(void 0,W)})),!f.length)return null;const w=f.filter(c=>r.some(W=>{const j=W.testValues?.[c.testNumber];return j!==void 0&&isFinite(j)}));if(!w.length)return null;const k=w.some(c=>c.limitLow!==void 0||c.limitHigh!==void 0),F=[],H=c=>!!c&&c.stddev!==void 0&&c.median!==void 0&&c.q1!==void 0&&c.q3!==void 0,I=c=>c.limitLow!==void 0||c.limitHigh!==void 0,O=!!(s?.length&&t?.length),C=(O||w.some(c=>!H(a.get(c.testNumber))||I(c)&&!b.has(c.testNumber)))&&t?.length?yield*Et(s??[{dies:e}],t):void 0;for(const c of w){yield;const W=a.get(c.testNumber),j=C?.specTally.get(c.testNumber),ee=C?.stats.get(c.testNumber),K=()=>r.map(E=>E.testValues?.[c.testNumber]).filter(E=>E!==void 0&&isFinite(E));let Q;if(H(W)){const E=W;Q={testNumber:c.testNumber,min:E.min,max:E.max,mean:E.mean,count:E.count,stddev:E.stddev,median:E.median,q1:E.q1,q3:E.q3}}else if(ee)Q={testNumber:c.testNumber,...ee};else{const E=K();if(!E.length)continue;Q={testNumber:c.testNumber,...jt(E)}}let M=null,B=0;if(I(c)){const E=b.get(c.testNumber);if(E)({yieldPercent:M,totalDies:B}=E);else if(j)B=j.n,M=B>0?(B-j.fail)/B*100:null;else{const X=K();let ue=0;for(const te of X)(c.limitLow!==void 0&&te<c.limitLow||c.limitHigh!==void 0&&te>c.limitHigh)&&ue++;B=X.length,M=X.length>0?(X.length-ue)/X.length*100:null}}F.push({entry:c,stats:Q,specYieldPct:M,specN:B})}if(!F.length)return null;const d=new Map;for(const c of(O?C?.capability:void 0)??[])c.hasSpec&&d.set(c.testNumber,c.ppk);const v=d.size>0,h=new Set(F.map(c=>c.stats.count)).size===1?F[0].stats.count:null,y=l("div"),S=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:x.sm}),L=h!==null?` \xB7 N=${h.toLocaleString()}`:"",A=u?.populationLabel?`Test Values (${F.length}) \u2014 ${u.populationLabel}${L}`:`Test Values (${F.length})${L}`,D=se(A);D.style.marginBottom="0",S.appendChild(D);const R=document.createElement("button");R.type="button",R.textContent="Test values CSV",Object.assign(R.style,{...me("outlined")}),G(R),R.addEventListener("click",()=>{const c=["Test","Unit","N","Min","Q1","Median","Mean","Q3","Max","StdDev"];v&&c.push("Ppk");const W=F.some(B=>B.specYieldPct!==null&&B.specN!==B.stats.count);k&&(c.push("LSL","USL","Spec Yield %"),W&&c.push("Spec Yield N"));const j=F.some(B=>Te(B.entry));j&&c.push(De);const ee=[...Je(u,c),...et(u)],Q=[[...ee.map(B=>B.label),...c].map(he).join(",")],M=B=>Ae(B,void 0,"engineering");for(const{entry:B,stats:E,specYieldPct:X,specN:ue}of F){const te=[...ee.map(le=>le.constant??""),B.name,B.unit??"",String(E.count),M(E.min),M(E.q1),M(E.median),M(E.mean),M(E.q3),M(E.max),M(E.stddev)];if(v){const le=d.get(B.testNumber);te.push(le==null?"":le.toFixed(3))}k&&(te.push(B.limitLow!==void 0?M(B.limitLow):"",B.limitHigh!==void 0?M(B.limitHigh):"",X!==null?X.toFixed(1):""),W&&te.push(B.limitLow!==void 0||B.limitHigh!==void 0?String(ue):"")),j&&te.push(Ne(B)),Q.push(te.map(he).join(","))}_e(Q.join(`
|
|
2
|
+
`),"test-values.csv","text/csv",o)}),S.appendChild(R),y.appendChild(S);const P=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),Z=document.createElement("thead"),J=document.createElement("tr"),_=["Test"];h===null&&_.push("N"),p==="full"&&_.push("Min","Q1","Median"),_.push("Mean"),p==="full"&&_.push("Q3","Max","StdDev"),v&&_.push("Ppk"),p==="full"&&k&&_.push("LSL","USL"),k&&_.push("Spec yield");for(const c of _){const W=l("th",{textAlign:c==="Test"?"left":"right",fontWeight:"600",fontSize:T.meta,letterSpacing:fe,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},c);J.appendChild(W)}Z.appendChild(J),P.appendChild(Z);const U=document.createElement("tbody");for(const{entry:c,stats:W,specYieldPct:j,specN:ee}of F){const K=B=>Ae(B,c.unit,i),Q=document.createElement("tr"),M=(B,E="right")=>{const X=l("td",{textAlign:E,padding:`${x.xs} ${x.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:$.text,whiteSpace:"nowrap"},B);Q.appendChild(X)};if(M(pt(c,c.testNumber),"left"),h===null&&M(`${W.count}`),p==="full"&&(M(K(W.min)),M(K(W.q1)),M(K(W.median))),M(K(W.mean)),p==="full"&&(M(K(W.q3)),M(K(W.max)),M(K(W.stddev))),v){const B=d.get(c.testNumber);M(B==null?"\u2014":B.toFixed(2))}p==="full"&&k&&(M(c.limitLow!==void 0?K(c.limitLow):"\u2014"),M(c.limitHigh!==void 0?K(c.limitHigh):"\u2014")),k&&M(j!==null?h!==null&&ee===h?`${j.toFixed(1)}%`:`${j.toFixed(1)}% (N=${ee})`:"\u2014"),U.appendChild(Q)}P.appendChild(U);const N=l("div",{overflowX:"auto"});N.appendChild(P);const V=ot(N,F.map(c=>({label:c.entry.name,...we(c.entry)})));if(!m)return y.appendChild(V),y;S.remove();const{outer:re}=oe(A,!0,void 0,{stateKey:"testValues",panel:m,render:c=>c.appendChild(V),control:()=>R});return re}export function buildFunctionalTestSection(e,t,i,n,o,u){const s=i??bt(e,t);if(!s?.length)return null;const p=new Set(s.map(g=>g.totalDies)).size===1?s[0].totalDies:null,r=p!==null?` \xB7 N=${p.toLocaleString()}`:"",a=l("div"),b=l("div",{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:x.sm}),f=o?.populationLabel?`Functional Tests (${s.length}) \u2014 ${o.populationLabel}${r}`:`Functional Tests (${s.length})${r}`,w=se(f);w.style.marginBottom="0",b.appendChild(w);const k=document.createElement("button");k.type="button",k.textContent="Functional CSV",Object.assign(k.style,{...me("outlined")}),G(k),k.addEventListener("click",()=>{const g=["Test","N","Pass","Fail","Pass Rate %"],h=s.some(L=>Te(L));h&&g.push(De);const y=[...Je(o,g),...et(o)],S=[[...y.map(L=>L.label),...g].map(he).join(",")];for(const L of s)S.push([...y.map(A=>A.constant??""),ut(L.label),String(L.totalDies),String(L.passDies),String(L.failDies),L.passRatePercent!==null?L.passRatePercent.toFixed(1):"",...h?[Ne(L)]:[]].map(he).join(","));_e(S.join(`
|
|
3
|
+
`),"functional-tests.csv","text/csv",n)}),b.appendChild(k),a.appendChild(b);const F=l("table",{width:"100%",borderCollapse:"collapse",fontSize:T.body}),H=document.createElement("thead"),I=document.createElement("tr"),O=p===null?["Test","N","Pass","Fail","Pass rate"]:["Test","Pass","Fail","Pass rate"];for(const g of O)I.appendChild(l("th",{textAlign:g==="Test"?"left":"right",fontWeight:"700",fontSize:T.body,letterSpacing:fe,textTransform:"uppercase",color:Y,padding:"3px 8px 5px",borderBottom:`1px solid ${$.menuBorder}`,whiteSpace:"nowrap"},g));H.appendChild(I),F.appendChild(H);const z=document.createElement("tbody");for(const g of s){const h=document.createElement("tr"),y=(S,L="right")=>{h.appendChild(l("td",{textAlign:L,padding:`${x.xs} ${x.md}`,borderBottom:`1px solid ${$.menuBorder}`,color:ie,whiteSpace:"nowrap"},S))};y(g.label,"left"),p===null&&y(String(g.totalDies)),y(String(g.passDies)),y(String(g.failDies)),y(g.passRatePercent!==null?`${g.passRatePercent.toFixed(1)}%`:"\u2014"),z.appendChild(h)}F.appendChild(z);const C=l("div",{overflowX:"auto"});C.appendChild(F);const d=ot(C,s);if(!u)return a.appendChild(d),a;b.remove();const{outer:v}=oe(f,!0,void 0,{stateKey:"functionalTests",panel:u,render:g=>g.appendChild(d),control:()=>k});return v}export function buildLotFunctionalSection(e,t,i,n,o){const u=i?.length?{perWaferMetadata:i.map(m=>m.wafer??{}),populationLabel:`${i.length} wafer${i.length===1?"":"s"} pooled`}:void 0,s=Rt(i);return s?buildFunctionalTestSection(e,t,s,n,u,o):buildFunctionalTestSection(e,t,void 0,n,u,o)}const ae={unusual:0,notable:1,info:2};function Be(e){return l("span",{display:"inline-block",width:"7px",height:"7px",borderRadius:q.pill,background:ge(e),flexShrink:"0"})}function tt(e,t){let i=e.summary;if(t){const n=[" has "," have "].find(o=>i.startsWith(`${t}${o}`));n?i=i.slice(t.length+n.length):i.startsWith(`${t} `)&&(i=i.slice(t.length+1))}return i=de(i),i.length?i[0].toUpperCase()+i.slice(1):i}function nt(e){return it(e.map(t=>({label:t.variable.label,...we(t.variable)})))}function it(e){const t=ft(e);return t?l("div",{fontSize:T.body,color:Y,marginTop:x.sm,lineHeight:ne.base},t):null}function ot(e,t){const i=it(t);if(!i)return e;const n=l("div",{});return n.append(e,i),n}export function buildFindingsSection(e,t,i,n,o=!1){if(!e.length)return null;const u=e.some(d=>d.severity==="unusual"||d.severity==="notable"),s=u?e.filter(d=>d.severity!=="info").length.toString():void 0,{outer:m,content:p}=o?(()=>{const d=l("div");return{outer:d,content:d}})():oe(`Findings (${e.length})`,u,s);function r(d){return d.reduce((v,g)=>ae[g.severity]<ae[v]?g.severity:v,"info")}function a(d){const v=new Map;for(const h of d){const y=`${h.comparison.family}\0${h.comparison.left}`,S=v.get(y)??[];S.push(h),v.set(y,S)}const g=[...v.entries()].map(([h,y])=>{const S=[...y].sort((L,A)=>ae[L.severity]-ae[A.severity]);return{key:h,findings:S,worst:r(S)}});return g.sort((h,y)=>ae[h.worst]-ae[y.worst]),g}function b(d,v){const h={ring:"Ring",quadrant:"Quadrant",sector:"Sector","reticle-position":"Reticle","test-site":"Test site",cluster:"Cluster","edge-arc":"Edge arc",wafer:"Wafer"}[d]??d;return v.toLowerCase().startsWith(h.toLowerCase())?v:`${h}: ${v}`}const f=e.filter(d=>d.comparison.family==="spatial-pattern"),w=new Set([...f.flatMap(d=>d.relatedIds??[]),...e.flatMap(d=>d.absorbedIds??[])]),k=e.filter(d=>d.comparison.family!=="spatial-pattern"&&!w.has(d.id)),F=a(k),H=()=>[...F.flatMap(d=>d.findings),...f.flatMap(d=>e.filter(v=>d.relatedIds?.includes(v.id)))];function I(d,v=!1,g){const h=n===d.id,y=document.createElement("button");return y.type="button",y.dataset.wmapFinding=d.id,y.textContent=tt(d,g),ce(y,vt(d)),y.setAttribute("aria-current",h?"true":"false"),Object.assign(y.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${ge(d.severity)}`,background:h?$.bgActive:$.menuBg,borderRadius:q.container,padding:v?"6px 10px":"8px 10px",textAlign:"left",fontSize:v?"10px":"11px",fontWeight:h?"600":"400",color:$.text,cursor:"pointer",width:"100%",marginBottom:x.xs}),G(y,"bare"),y.addEventListener("click",()=>i(d,y)),y}const O=de(Ct(e)??"");if(O){const d=l("div",{background:$.bgActive,borderRadius:q.container,padding:`${x.md} ${x.lg}`,marginBottom:x.md,display:"flex",gap:x.md,alignItems:"flex-start"}),v=l("span",{flex:"1",fontSize:T.body,lineHeight:ne.base,color:$.text},O);d.appendChild(v);const g=l("button",{flexShrink:"0",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:"0",lineHeight:ne.base,whiteSpace:"nowrap"},"Detail \u25B8");g.type="button",G(g,"bare"),g.addEventListener("click",()=>{const h=Oe({title:"Findings Summary",onClose:()=>{},anchor:g}),y=l("p",{fontSize:"16px",lineHeight:ne.base,color:$.text,padding:`${x.xxl} ${x.xxxl} ${x.xxl}`,margin:"0",borderBottom:`1px solid ${$.menuBorder}`,flexShrink:"0"},O);h.contentWrap.appendChild(y);const S=l("div",{overflowY:"auto",padding:`${x.xxl} ${x.xxxl}`,flex:"1"}),L=(D,R)=>{const P=l("div",{display:"flex",alignItems:"center",gap:"7px",fontSize:T.sub,fontWeight:"600",color:ie,marginTop:x.lg,marginBottom:x.xs});return P.appendChild(Be(D)),P.appendChild(l("span",{},R)),P};for(const D of f){S.appendChild(L(D.severity,D.comparison.left)),S.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:x.xxs},de(D.summary)));const R=e.filter(P=>D.relatedIds?.includes(P.id));for(const P of R)S.appendChild(l("div",{fontSize:T.body,color:Y,padding:"2px 0 2px 23px",marginBottom:x.xxs},de(P.summary)))}for(const D of F){const[R,P]=D.key.split("\0");S.appendChild(L(D.worst,b(R,P)));for(const Z of D.findings)S.appendChild(l("div",{fontSize:T.body,color:$.text,padding:"4px 0 4px 15px",marginBottom:x.xxs},tt(Z,P)))}const A=nt(H());A&&S.appendChild(A),h.contentWrap.appendChild(S),Object.assign(h.contentWrap.style,{flexDirection:"column",overflow:"hidden"})}),d.appendChild(g),p.appendChild(d)}let z=!0;for(const d of f){z||p.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),z=!1;const v=e.filter(L=>d.relatedIds?.includes(L.id)),g=v.length>0,h=l("div",{position:"relative",marginBottom:g?"2px":"4px"}),y=n===d.id,S=document.createElement("button");if(S.type="button",S.dataset.wmapFinding=d.id,Object.assign(S.style,{border:`1px solid ${$.menuBorder}`,borderLeft:`3px solid ${ge(d.severity)}`,background:y?$.bgActive:$.menuBg,borderRadius:q.container,padding:"8px 32px 8px 10px",textAlign:"left",fontSize:T.body,fontWeight:y?"600":"500",color:$.text,cursor:"pointer",width:"100%"}),S.textContent=de(d.summary),ce(S,d.summary),S.setAttribute("aria-current",y?"true":"false"),G(S,"bare"),S.addEventListener("click",()=>i(d,S)),h.appendChild(S),g){const L=l("div",{display:"none",paddingLeft:"12px",marginBottom:x.xs});for(const R of v)L.appendChild(I(R,!0));h.appendChild(L);let A=!1;const D=l("button",{position:"absolute",top:"50%",right:"8px",transform:"translateY(-50%)",border:"none",background:"none",fontSize:T.body,color:$.icon,cursor:"pointer",padding:`${x.xxs} ${x.xs}`,lineHeight:ne.none},"\u25B8");G(D,"bare"),D.type="button",ce(D),D.setAttribute("aria-label","Show supporting findings"),D.setAttribute("aria-expanded","false"),D.addEventListener("click",R=>{R.stopPropagation(),A=!A,L.style.display=A?"block":"none",D.textContent=A?"\u25BE":"\u25B8";const P=A?"Hide supporting findings":"Show supporting findings";D.setAttribute("aria-label",P),D.setAttribute("aria-expanded",String(A))}),h.appendChild(D)}p.appendChild(h)}for(const d of F){z||p.appendChild(l("div",{height:"1px",background:$.separator,margin:"4px 0"})),z=!1;const[v,g]=d.key.split("\0"),h=l("div",{display:"flex",alignItems:"center",gap:x.sm,fontSize:T.body,fontWeight:"600",color:ie,margin:"2px 0 4px"});h.appendChild(Be(d.worst)),h.appendChild(l("span",{},b(v,g))),p.appendChild(h);for(const y of d.findings)p.appendChild(I(y,!1,g))}const C=nt(H());return C&&p.appendChild(C),m}const Kt=[{value:"",label:"All kinds"},{value:"yield",label:"Yield"},{value:"hardBin",label:"Hard bin"},{value:"softBin",label:"Soft bin"},{value:"test",label:"Test value"},{value:"functionalTest",label:"Functional test"},{value:"spatialPattern",label:"Spatial pattern"}],Vt=[{value:"",label:"All regions"},{value:"ring",label:"Ring"},{value:"quadrant",label:"Quadrant"},{value:"reticle-position",label:"Reticle position"},{value:"test-site",label:"Test site"},{value:"wafer",label:"Wafer"},{value:"sector",label:"Sector"},{value:"cluster",label:"Cluster"},{value:"edge-arc",label:"Edge arc"},{value:"spatial-pattern",label:"Spatial pattern"}],qt=["unusual","notable","info"],Gt={unusual:"Unusual",notable:"Notable",info:"Info"};function Ut(e,t,i){const n=l("div",{display:"flex",flexWrap:"wrap",alignItems:"center",gap:x.lg,marginBottom:x.lg,paddingBottom:"10px",borderBottom:`1px solid ${$.separator}`}),o={unusual:0,notable:0,info:0};for(const r of e)o[r.severity]++;const u=qt.filter(r=>o[r]>0),s=new Set(t.severity===void 0?u:Array.isArray(t.severity)?t.severity:[t.severity]),m=l("div",{display:"flex",gap:x.xs,flexWrap:"wrap"});for(const r of u){const a=document.createElement("button");a.type="button";const b=()=>{const f=s.has(r);a.setAttribute("aria-pressed",f?"true":"false"),Object.assign(a.style,{display:"inline-flex",alignItems:"center",gap:"5px",border:`1px solid ${$.menuBorder}`,borderRadius:q.pill,background:f?$.bgActive:"none",opacity:f?"1":"0.5",color:$.text,fontSize:T.body,padding:`${x.xxs} ${x.md}`,cursor:"pointer"}),a.dataset.on=f?"true":"false"};a.appendChild(Be(r)),a.appendChild(l("span",{},`${Gt[r]} ${o[r]}`)),ce(a,()=>s.has(r)?"Click to hide these findings":"Click to show these findings"),b(),G(a,"bare"),a.addEventListener("click",()=>{s.has(r)?s.delete(r):s.add(r),t.severity=s.size===u.length?void 0:[...s],i()}),m.appendChild(a)}n.appendChild(m);const p=t.kind!==void 0||t.family!==void 0;return(e.length>=Qt||p)&&(n.appendChild(Pe("Kind:",Kt,t.kind??"",r=>{t.kind=r||void 0,i()},{maxWidth:"130px"})),n.appendChild(Pe("Region:",Vt,t.family??"",r=>{t.family=r||void 0,i()},{maxWidth:"150px"}))),n}const Qt=8;function Xt(e,t){const i=l("div",{display:"flex",flexDirection:"column",gap:x.xs,padding:x.md,marginBottom:x.md,background:$.bgHover,borderRadius:q.control},void 0,t);if(i.appendChild(l("div",{fontSize:T.body,color:$.value},e.message,t)),e.detail&&i.appendChild(l("div",{fontSize:T.meta,color:Y},e.detail,t)),e.actionLabel&&e.onAction){const n=l("button",me("outlined"),e.actionLabel,t);n.type="button",n.style.alignSelf="flex-start",n.style.marginTop=x.xs,G(n),n.addEventListener("click",e.onAction),i.appendChild(n)}return i}export function buildFindingsSectionWithFilter(e,t,i,n,o,u,s){if(!e.findings.length&&!s)return null;const m=e.findings.some(k=>k.severity==="unusual"||k.severity==="notable"),p=m?e.findings.filter(k=>k.severity!=="info").length.toString():void 0,r=u?.ownerDocument??document,{outer:a,content:b}=oe(`Findings (${e.findings.length})`,m||!!s,p,{stateKey:"findings",panel:u});if(s&&b.appendChild(Xt(s,r)),!e.findings.length)return a;b.appendChild(Ut(e.findings,n,o));const f=St(e,n);if(!f.length)return b.appendChild(l("div",{color:Y,fontSize:T.body,textAlign:"center",padding:`${x.xxl} ${x.md}`},"No findings match the current filter.")),a;const w=buildFindingsSection(f,e,t,i,!0);return w&&b.appendChild(w),a}export function buildLotTestSection(...e){return be(buildLotTestSectionSteps(...e))}export function*buildLotTestSectionSteps(e,t,i,n,o,u,s,m="full"){const p=n?.length?{perWaferMetadata:n.map(a=>a.wafer??{}),populationLabel:`${n.length} wafer${n.length===1?"":"s"} pooled`}:void 0;let r;if(n?.length&&n.every(a=>a.stats.perTestStats!==void 0)){const a=new Map;for(const b of n)for(const f of b.stats.perTestStats??[]){const w=a.get(f.testNumber);w?(w.n+=f.count,w.sum+=f.mean*f.count,w.min=Math.min(w.min,f.min),w.max=Math.max(w.max,f.max)):a.set(f.testNumber,{n:f.count,sum:f.mean*f.count,min:f.min,max:f.max})}r={perTestStats:[...a.entries()].map(([b,f])=>({testNumber:b,count:f.n,min:f.min,max:f.max,mean:f.sum/f.n}))}}if(n?.length&&n.every(a=>a.stats.testSpecYield!==void 0)){const a=new Map;for(const b of n)for(const f of b.stats.testSpecYield??[]){const w=a.get(f.testNumber);w?(w.passDies+=f.passDies,w.totalDies+=f.totalDies):a.set(f.testNumber,{passDies:f.passDies,totalDies:f.totalDies})}r={...r,testSpecYield:[...a.entries()].map(([b,f])=>({testNumber:b,totalDies:f.totalDies,yieldPercent:f.totalDies>0?f.passDies/f.totalDies*100:null}))}}return yield*buildTestSectionSteps(e,t,i,r,o,p,u,s,m)}export function createSummaryPanelEl(e,t,i=document){const n=e==="top"||e==="bottom",o=l("div",{background:zt,color:$.text,fontVariantNumeric:"tabular-nums",border:je,borderRadius:q.container,padding:x.xl,overflowY:"auto",overflowX:n?"auto":"hidden",flexShrink:"0",boxSizing:"border-box",fontFamily:T.family,fontSize:T.sub,boxShadow:ze.panel},void 0,i);return e==="right"&&(o.style.marginRight=t),e==="left"&&(o.style.marginLeft=t),e==="bottom"&&(o.style.marginBottom=t),n?(o.style.height="180px",o.style.width="100%"):(o.style.width="300px",o.style.maxHeight="100%"),o}export function wrapWithSummaryPanel(e,t,i){const n=i==="top"||i==="bottom",o=l("div",{display:"flex",flexDirection:n?"column":"row",gap:x.md,width:"100%",height:"100%",flex:"1 1 0",minHeight:"0",boxSizing:"border-box",alignItems:n?"flex-start":"stretch"});return e.style.flex="1 1 0",e.style.minWidth="0",e.style.minHeight="0",i==="right"||i==="bottom"?(o.appendChild(e),o.appendChild(t)):(o.appendChild(t),o.appendChild(e)),o}function st(e){return l("div",{fontSize:T.heading,fontWeight:"600",color:ie,marginBottom:x.lg},e)}function Ce(e,t){const i=l("button",me("outlined"),e);return i.type="button",G(i),i.addEventListener("click",t),i}function at(...e){const t=e.filter(n=>!!n);if(!t.length)return null;const i=l("div",{display:"flex",flexWrap:"wrap",gap:x.sm,marginBottom:x.lg});for(const n of t)i.appendChild(n);return i}function rt(e,t,i,n,o,u,s,m,p,r,a){const b=e.ownerDocument,f=Oe({title:"Die list",onClose:()=>{},anchor:e,ownerDocument:b});f.contentWrap.style.padding="14px 16px";const w=Mt(t,i,{...s,title:n,onSaveText:m,waferMetadata:o,metadataFields:u,extraColumn:p,getWafer:r,ringCount:a,ownerDocument:b});w&&f.contentWrap.appendChild(w)}export function renderWaferSummaryContent(...e){be(renderWaferSummaryContentSteps(...e))}export function*renderWaferSummaryContentSteps(e,t){const i=e.scrollTop;e.innerHTML="";const{wafer:n,dies:o,yieldSummary:u,dataCoverage:s,hbinDefs:m,sbinDefs:p,testDefs:r,statsSummary:a,passBins:b=[1],ringCount:f=4,binColors:w,plotMode:k,fallbackFormat:F,onFindingClick:H,activeFindingId:I=null,findingsFilter:O,onFindingsFilterChange:z,findingsNotice:C,onSaveText:d,metadataFields:v,dieListOptions:g,metadataShownElsewhere:h}=t;e.appendChild(st("Wafer Summary"));const y=t.warnings??Ie({statsSummary:a});y.length&&e.appendChild($e(y,e.ownerDocument));const S=u&&s?Ce("Summary report",()=>{Ye(xt({wafer:n,dies:o,yield:u,dataCoverage:s,hbinDefs:m,sbinDefs:p,testDefs:r,passBins:b,ringCount:f},a),{anchor:e})}):null,L=(g?.enabled??!0)&&o.length?Ce("View die list",()=>{rt(e,o,r,`Die list \u2014 ${o.length} dies`,n.metadata,v,g,d,void 0,()=>n,f)}):null,A=at(S,L);A&&e.appendChild(A);let D=!0;const R=_=>{_&&(D||e.appendChild(Ge()),D=!1,e.appendChild(_))},P=a?.stats.isLotStack?a.stats:void 0,Z=P?.lotSize!==void 0?{lotSize:P.lotSize,aggrMethod:Nt(P.aggregationMethod)}:void 0;h||R(buildMetadataInfoSection([{metadata:n.metadata??void 0}],Z)),u&&s&&R(buildYieldSection(u,s,b)),yield,a&&H&&O&&z&&(R(buildFindingsSectionWithFilter(a,H,I,O,z,e,C)),yield),R(buildBinBreakdownSection({dies:o,hbinDefs:m,sbinDefs:p,binColors:w,hardCounts:a?.stats.hardBinCounts,softCounts:a?.stats.softBinCounts,plotMode:k,passBins:b,panel:e})),yield,R(buildRegionYieldPanelSection({diesByWafer:[o],allWafers:[n],ringCount:f,passBins:b,panel:e})),yield;const J=n.metadata?{waferMetadata:n.metadata}:void 0;R(yield*buildTestSectionSteps(o,r,F,a?.stats,d,J,[{dies:o}],e,"compact")),yield,R(buildFunctionalTestSection(o,r,a?.stats.functionalYield,d,J,e)),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}export function reportMapsFromItems(e,t,i){const n=[];return e.forEach((o,u)=>{!o?.wafer||!o.dies||n.push({...o,wafer:o.wafer,dies:o.dies,label:ve(o,u),passBins:[...Se(o,t)],ringCount:o.ringCount??i})}),n}export function renderLotSummaryContent(...e){be(renderLotSummaryContentSteps(...e))}export function*renderLotSummaryContentSteps(e,t){const i=e.scrollTop;e.innerHTML="";const{lotSummary:n,items:o,hbinDefs:u,sbinDefs:s,testDefs:m,passBins:p=[1],ringCount:r=4,binColors:a,plotMode:b,fallbackFormat:f,onFindingClick:w,activeFindingId:k=null,onWaferClick:F,findingsFilter:H,onFindingsFilterChange:I,findingsNotice:O,onSaveText:z,dieListOptions:C,findingsFor:d}=t;e.appendChild(st(`Summary \u2014 ${Bt(Me(n.perWafer.map(N=>N.summary.wafer)))}`));const v=t.warnings??Ie({lotStatsSummary:n});v.length&&e.appendChild($e(v,e.ownerDocument));const g=Ce("Summary report",()=>{Ye(yt(reportMapsFromItems(o,p,r)),{anchor:e})}),h=[],y=[],S=[],L=[],A=[],D=new WeakMap,R=new WeakMap;for(let N=0;N<o.length;N++){yield;const V=o[N];if(!V){y.push([]);continue}V.wafer&&(h.push(V.wafer),L.push(V.dies??[]),A.push(Se(V,p)));const re=V.dies??[],c=ve(V,N);for(const W of re)D.set(W,c),V.wafer&&R.set(W,V.wafer);y.push(re);for(const W of re)S.push(W)}const P=C?.enabled??!0?Ce("View die list",()=>{S.length&&rt(e,S,m,`Die list \u2014 ${S.length} dies across ${o.length} wafer${o.length===1?"":"s"}`,Fe(o.filter(N=>!!N).map(N=>({metadata:N.wafer?.metadata}))),o.find(N=>N?.metadataFields?.length)?.metadataFields,C,z,{label:"Wafer",get:N=>D.get(N)},N=>R.get(N),r)}):null,Z=at(g,P);Z&&e.appendChild(Z);const J=o.map(N=>N?.statsSummary).filter(N=>!!N);let _=!0;const U=N=>{N&&(_||e.appendChild(Ge()),_=!1,e.appendChild(N))};U(buildLotOverviewSection(n,J)),yield,w&&H&&I&&(U(buildFindingsSectionWithFilter(n,w,k,H,I,e,O)),yield),U(buildPerWaferYieldSection(n,o,F,e,d)),yield,U(buildBinBreakdownSection({dies:S,hbinDefs:u,sbinDefs:s,plotMode:b,passBins:p,panel:e,binColors:a??kt(o.flatMap(N=>N?[{dies:N.dies??[],passBins:Se(N,p)}]:[]),{hbinDefs:u,sbinDefs:s}).colors})),yield,U(buildRegionYieldPanelSection({diesByWafer:L,allWafers:h,ringCount:r,passBins:N=>A[N],panel:e})),yield,m?.length&&(U(yield*buildLotTestSectionSteps(S,m,f,J,z,y.map(N=>({dies:N})),e,"compact")),yield,U(buildLotFunctionalSection(S,m,J,z,e))),e.appendChild(l("div",{height:"12px",flexShrink:"0"})),e.scrollTop=i}
|