@wafertools/wafermap 0.29.0 → 0.30.1
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 +26 -17
- package/CHANGELOG.md +410 -0
- package/README.md +6 -6
- package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.js +1 -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/correlation.js +2 -2
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.d.ts +1 -0
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/deprecated.d.ts +7 -0
- package/dist/packages/canvas-adapter/deprecated.js +1 -0
- package/dist/packages/canvas-adapter/dieList.d.ts +1 -3
- package/dist/packages/canvas-adapter/dieList.js +7 -7
- package/dist/packages/canvas-adapter/exportName.d.ts +68 -0
- package/dist/packages/canvas-adapter/exportName.js +1 -0
- package/dist/packages/canvas-adapter/icons.js +2 -2
- package/dist/packages/canvas-adapter/index.d.ts +2 -3
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.d.ts +0 -1
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +23 -40
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +96 -104
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +31 -13
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.d.ts +20 -12
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +6 -0
- 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 +26 -15
- 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/deprecated.d.ts +60 -0
- package/dist/packages/core/deprecated.js +1 -0
- package/dist/packages/core/index.d.ts +1 -3
- package/dist/packages/core/index.js +1 -1
- package/dist/packages/core/passBins.d.ts +33 -0
- package/dist/packages/core/passBins.js +1 -0
- package/dist/packages/core/utils.d.ts +12 -0
- package/dist/packages/core/utils.js +1 -1
- package/dist/packages/core/waferLabel.d.ts +35 -0
- package/dist/packages/core/waferLabel.js +1 -0
- package/dist/packages/renderer/binColors.d.ts +105 -13
- package/dist/packages/renderer/binColors.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +8 -9
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +76 -17
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/colorMap.d.ts +4 -3
- package/dist/packages/renderer/colorSchemes.d.ts +8 -6
- package/dist/packages/renderer/deprecate.d.ts +31 -0
- package/dist/packages/renderer/deprecate.js +1 -0
- package/dist/packages/renderer/deprecated.d.ts +45 -0
- package/dist/packages/renderer/deprecated.js +1 -0
- package/dist/packages/renderer/index.d.ts +4 -4
- package/dist/packages/renderer/index.js +1 -1
- package/dist/packages/stats/analyzeWaferLot.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/binPareto.d.ts +6 -1
- package/dist/packages/stats/capability.d.ts +16 -1
- package/dist/packages/stats/capability.js +1 -1
- package/dist/packages/stats/clusterDetection.d.ts +0 -2
- package/dist/packages/stats/deprecated.d.ts +82 -0
- package/dist/packages/stats/deprecated.js +1 -0
- package/dist/packages/stats/index.d.ts +5 -14
- package/dist/packages/stats/index.js +1 -1
- package/dist/packages/stats/normalizeInput.d.ts +10 -0
- package/dist/packages/stats/normalizeInput.js +1 -0
- package/dist/packages/stats/regions.d.ts +9 -2
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderFindingsReport.js +1 -1
- package/dist/packages/stats/renderSummaryReport.d.ts +42 -1
- package/dist/packages/stats/renderSummaryReport.js +34 -34
- package/dist/packages/stats/reportHtml.d.ts +0 -1
- package/dist/packages/stats/reportHtml.js +10 -10
- package/dist/packages/stats/summaryFigures.d.ts +47 -0
- package/dist/packages/stats/summaryFigures.js +1 -0
- package/dist/packages/stats/types.d.ts +118 -43
- package/dist/packages/stats/yield.d.ts +12 -6
- package/dist/packages/stats/yield.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildFacetTable as $e,facetValueOf as Be,FACET_NONE_VALUE as De}from"../stats/facets.js";import{mergeTestDefs as Le}from"../stats/mergeTestDefs.js";import{isParametricTest as Ie}from"../renderer/buildWaferMap.js";import{NO_DATA_FILL as ne}from"../renderer/colorMap.js";import{describeWaferPopulation as Oe,populationStat as Ee}from"../stats/population.js";import{LEADING as Pe,ALPHA as Ae,SPACE as w,EDGE_GUTTER as K,FONT as G,CLR as B,RADIUS as Re,SHADOW as je,controlStyle as We,wireControlHover as ae,wireTooltip as Ge}from"./toolbar.js";import{ICONS as He}from"./icons.js";import{renderCapabilityPanel as Ye}from"./charts/capability.js";import{renderBoxplotPanel as Fe}from"./charts/boxplot.js";import{renderTrendPanel as Me}from"./charts/trend.js";import{renderHistogramPanel as Ne}from"./charts/histogram.js";import{renderCorrelationPanel as Ve}from"./charts/correlation.js";import{renderScatterPanel as _e}from"./charts/scatter.js";import{renderBarPanel as oe}from"./charts/barPanel.js";import{renderBinClusterPanel as ze}from"./charts/binCluster.js";import{renderTestPassRatePanel as Ue}from"./charts/testPassRate.js";import{QUANTITY as qe}from"./charts/palette.js";import{cardFrameStyle as Qe,makeChartGridWrap as X,makeLabeledSelect as Ke,makeLinkedGroupSelect as Xe}from"./charts/chartShell.js";import{buildYieldData as N,buildYieldDataCombined as re}from"../stats/yield.js";import{buildBinParetoData as Je}from"../stats/binPareto.js";import{buildLotTestSection as Ze,buildLotFunctionalSection as et,buildMetadataStripBox as tt}from"./summaryPanel.js";import{buildRegionYieldData as ie,buildRingRegions as nt,buildQuadrantRegions as at}from"../stats/regions.js";import{renderRegionYieldDiagram as se}from"./charts/regionYieldDiagram.js";const ot=[{key:"overview",label:"Overview"},{key:"distributions",label:"Distributions"},{key:"correlation",label:"Correlation"}];export function createInsightsTab(D){const{getItems:le,getLotStats:de,getBinColors:J,passBins:T,getRingCount:ce,onSaveImage:v,onSaveText:V,openWafer:H,focusTest:Z}=D,pe=D.showMetadataStrip??!0,R=D.contentInset??K,d=D.ownerDocument??document,E=d.createElement("div");Object.assign(E.style,{display:"none",flexDirection:"column",width:"100%",paddingTop:"0"});const ue=K,P=d.createElement("div");Object.assign(P.style,{paddingLeft:ue});const $=d.createElement("div");Object.assign($.style,{display:"flex",gap:w.xs,alignItems:"center",background:B.menuBg,border:`1px solid ${B.menuBorder}`,borderRadius:Re.container,boxShadow:je.panel,padding:`0 ${w.lg}`,marginBottom:w.lg,marginLeft:R,marginRight:R}),$.setAttribute("role","tablist"),$.addEventListener("keydown",e=>{if(e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;const n=Array.from($.querySelectorAll('[role="tab"]')),o=n.indexOf(d.activeElement);if(o===-1)return;e.preventDefault();const c=n[(o+(e.key==="ArrowRight"?1:-1)+n.length)%n.length];c.focus(),c.click()});const j=d.createElement("div");Object.assign(j.style,{display:"flex",flexDirection:"column",gap:w.lg,marginTop:"0",paddingLeft:R,paddingRight:R}),E.appendChild(P),E.appendChild($),E.appendChild(j);let W=D.defaultView??"overview",A,I=null,L=null,Y={includeLimits:void 0,clipOutliers:!1};const _=e=>{L!==e&&(L=e,M())};let F=[];function z(e,n,o){H?.(e,n,o)}function fe(e){return H?{open:(n,o)=>z(n,`Wafer ${e.find(c=>c.waferIndex===n)?.label??n}`,o)}:Z&&e.length===1?{open:(n,o)=>Z(o),label:"show this test on the map"}:null}function me(){return le().map((e,n)=>e==null?null:{metadata:e.wafer.metadata??void 0,dies:e.dies,wafer:e.wafer,label:e.label??String(e.wafer.metadata?.waferId??""),waferIndex:n,statsSummary:e.statsSummary,testDefs:e.testDefs}).filter(e=>e!=null)}function ee(e,n){Object.assign(e.style,{background:"none",border:"none",borderBottom:n?`2px solid ${B.iconActive}`:"2px solid transparent",color:n?B.iconActive:B.label,fontWeight:n?"700":"500",fontSize:G.body,padding:`${w.sm} ${K} ${w.md}`,cursor:"pointer",marginBottom:"-1px"})}function be(e,n){const o=d.createElement("button");o.type="button",o.textContent=n;const c=e===W;return ee(o,c),o.dataset.on=c?"true":"false",ae(o,"bare"),o.dataset.wmapInsightsTab=e,o.setAttribute("role","tab"),o.setAttribute("aria-selected",c?"true":"false"),o.tabIndex=c?0:-1,o.addEventListener("click",()=>{W!==e&&(W=e,M())}),o}function ge(e){const n=d.createElement("button");return n.type="button",n.textContent=`\u2039 ${e.label}`,ee(n,!1),n.dataset.wmapInsightsBack="1",n.addEventListener("click",e.onBack),n}function ye(e,n,o,c=!0){const s=X(d),f=J();let y="label";const u=o??"group",m=T.length===1?`bin ${T[0]}`:`bins ${T.join(", ")}`,i=de?.(),b=new Map(i?.lotYieldSeries.map(r=>[r.waferIndex,r.yieldPercent])),h=r=>({...r,label:r.label.replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPercent:b.get(r.waferIndex),key:r.waferIndex}),g=e.map(h),p=n?.map(r=>({key:r.key,items:r.items.map(h)})),t=()=>p?re(p,T,y):N(g,T,y),x={title:n?`Yield by ${u} (pass: ${m})`:`Yield by wafer (pass: ${m})`,data:t(),selfControl:{current:y,options:[["yield","Sort: yield"],["label",n?`Sort: ${u}`:"Sort: wafer ID"]],onChange:r=>(y=r,{data:t()})},barColor:()=>qe,valueLabel:r=>`${r.percent.toFixed(1)}%`,reference:r=>{if(r.length<3)return null;const k=r.map(Q=>Q.percent).sort((Q,ke)=>Q-ke),O=k.length%2?k[(k.length-1)/2]:(k[k.length/2-1]+k[k.length/2])/2;return{value:O,label:`median ${O.toFixed(1)}%`}},drill:p?{onOpenGroup:r=>{const k=p.find(O=>O.key===r.label)?.items??[];return{data:N(k,T,y),title:`Yield by wafer \u2014 ${u}: ${r.label} (pass: ${m})`}},onBack:()=>({data:t(),title:`Yield by ${u} (pass: ${m})`}),groupLabelText:u}:void 0,onOpen:H?r=>{typeof r.key=="number"&&z(r.key,`Wafer ${r.label}`)}:void 0,ownerDocument:d};let C=null;if(c&&(C=oe(x,v),C.card.style.minHeight="360px",s.appendChild(C.card)),n){const r=ze({title:"Hard bin pareto",groups:n.map(k=>({key:k.key,items:k.items.map(O=>({dies:O.dies,hardBinCounts:O.statsSummary?.stats.hardBinCounts,softBinCounts:O.statsSummary?.stats.softBinCounts}))})),onSaveImage:v,ownerDocument:d});return r.card.style.minHeight="360px",s.appendChild(r.card),{card:s,destroy:()=>{C?.destroy(),r.destroy()}}}let a="hbin";const l=r=>r===void 0?ne:(a==="hbin"?f.hard:f.soft).get(r)??ne,S=e.map(r=>({dies:r.dies,hardBinCounts:r.statsSummary?.stats.hardBinCounts,softBinCounts:r.statsSummary?.stats.softBinCounts})),te=()=>Je(S,a),ve={title:"Hard bin pareto",data:te(),selfControl:{current:a,options:[["hbin","Hard bins"],["sbin","Soft bins"]],onChange:r=>(a=r,{data:te(),title:`${a==="hbin"?"Hard":"Soft"} bin pareto`})},barColor:r=>l(r.binCode),ownerDocument:d},q=oe(ve,v);return q.card.style.minHeight="360px",s.appendChild(q.card),{card:s,destroy:()=>{C?.destroy(),q.destroy()}}}function U(){const e=d.createElement("div");return e.dataset.wmapChartCard="1",Object.assign(e.style,{...Qe(),display:"flex",flexDirection:"column",gap:w.lg,minWidth:"0"}),e}function he(e){if(P.innerHTML="",P.style.marginBottom="0",!pe)return;const n=tt(e.map(o=>({metadata:o.metadata})),void 0,{facetableOnly:!1});n&&(n.style.marginBottom="0",P.appendChild(n),P.style.marginBottom=w.xs)}function Ce(e,n,o,c){if(!e.length)return{elements:[],testValuesCard:null,functionalCard:null,destroy:()=>{}};const s=e.map(l=>l.wafer),f=e.map(l=>l.dies),y=e.flatMap(l=>l.dies),u=e.map(l=>l.statsSummary),m=u.every(l=>l!==void 0)?u:void 0,i=ce?.()??4,b=[],h=[],p=Ue({groups:(c??[{key:"",items:e}]).map(l=>({key:l.key,items:l.items.map(S=>({dies:S.dies,testSpecYield:S.statsSummary?.stats.testSpecYield,functionalYield:S.statsSummary?.stats.functionalYield}))})),testDefs:o,onSaveImage:v,ownerDocument:d});p.card.style.minHeight="300px",b.push(p.card),h.push(p.destroy);const t=ie(f,s,i,T,nt);if(t.length){const l=se({title:"Ring yield",mode:"ring",rows:t,onSaveImage:v,ownerDocument:d});b.push(l.card),h.push(l.destroy)}const x=ie(f,s,i,T,at);if(x.length){const l=se({title:"Quadrant yield",mode:"quadrant",rows:x,onSaveImage:v,ownerDocument:d});b.push(l.card),h.push(l.destroy)}let C=null;if(n.length){const l=Ze(y,n,void 0,m,V,f.map(S=>({dies:S})),void 0,"full");if(l){const S=U();S.appendChild(l),C=S}}let a=null;if(o.length){const l=et(y,o,m,V);if(l){const S=U();S.appendChild(l),a=S}}return{elements:b,testValuesCard:C,functionalCard:a,destroy:()=>{for(const l of h)l()}}}function xe(e){const n=T.length===1?`bin ${T[0]}`:`bins ${T.join(", ")}`,o=e.length===1,c=e[0],s=U();Object.assign(s.style,{flexDirection:"row",flexWrap:"wrap",gap:w.md});const f=i=>{const b=i.lastElementChild;return b&&Object.assign(b.style,{borderRight:"none",paddingRight:"0",marginRight:"0"}),i};function y(i,b,h){const g=d.createElement("div");Object.assign(g.style,{display:"flex",alignItems:"baseline",gap:w.sm,paddingRight:w.xxl,marginRight:w.md,borderRight:`1px solid ${B.menuBorder}`});const p=d.createElement("div");p.textContent=i,Object.assign(p.style,{fontSize:G.heading,fontWeight:"700",color:B.value,lineHeight:Pe.tight});const t=d.createElement("div");if(t.textContent=b,Object.assign(t.style,{fontSize:G.body,color:B.label}),g.append(p,t),h){const x=d.createElement("div");x.textContent=h,Object.assign(x.style,{fontSize:G.meta,color:B.label,opacity:Ae.muted}),g.appendChild(x)}return g}if(o){const i=N([{...c,key:c.waferIndex}],T)[0]?.percent;return i!==void 0&&s.appendChild(y(`${i.toFixed(1)}%`,`Yield \xB7 pass: ${n}`)),s.appendChild(y(String(c.dies.length),"Total dies")),f(s)}s.appendChild(y(String(e.length),"Wafers"));const u=N(e.map(i=>({...i,key:i.waferIndex})),T).map(i=>i.percent).filter(i=>Number.isFinite(i));if(u.length){const i=u.reduce((g,p)=>g+p,0)/u.length,b=re([{key:"all",items:e.map(g=>({...g,key:g.waferIndex}))}],T)[0]?.percent,h=b!==void 0&&b.toFixed(1)!==i.toFixed(1);s.appendChild(y(`${i.toFixed(1)}%`,`Mean per-wafer yield \xB7 pass: ${n}`,h?`${b.toFixed(1)}% by dies`:void 0))}const m=e.map(i=>i.statsSummary);if(m.every(i=>i!==void 0)){const i=m.reduce((h,g)=>h+g.stats.analyzedDies,0),b=m.reduce((h,g)=>h+g.stats.excludedDies,0);s.appendChild(y(i.toLocaleString(),"Dies analysed",b?`${b.toLocaleString()} excluded`:void 0))}else s.appendChild(y(e.reduce((i,b)=>i+b.dies.length,0).toLocaleString(),"Total dies"));return f(s)}function we(e,n,o,c,s){const f=d.createElement("div");Object.assign(f.style,{display:"flex",flexDirection:"column",gap:w.lg});const y=e.length===1&&!c;e.length&&!c&&f.appendChild(xe(e));const u=ye(e,c,s,!y);f.appendChild(u.card);const m=Ce(e,n,o,c);for(const i of m.elements)u.card.appendChild(i);return m.testValuesCard&&f.appendChild(m.testValuesCard),m.functionalCard&&f.appendChild(m.functionalCard),{card:f,destroy:()=>{u.destroy(),m.destroy()}}}function Se(e,n,o,c){const s=X(d),f=fe(e),y=a=>{Y=a;for(const l of[g,p,t])l!==u&&l?.setAxisPrefs(a)};let u=null;const m=a=>l=>{u=a(),y(l),u=null},i=a=>({...a,testStats:a.statsSummary?.stats.perTestStats}),b=e.map(i),h=o?.map(a=>({key:a.key,items:a.items.map(i)})),g=Fe({title:"Test value distribution",axisPrefs:Y,onAxisPrefsChange:m(()=>g),onTestChange:a=>x(a),selectedTestNumber:I??void 0,items:b,testDefs:n,groups:h,groupLabelText:c,onSaveImage:v,onGroupChange:a=>_(a),onOpen:f?.open,openActionLabel:f?.label,ownerDocument:d}),p=Ne({title:"Value histogram",axisPrefs:Y,onAxisPrefsChange:m(()=>p),onTestChange:a=>x(a),selectedTestNumber:I??void 0,items:e,testDefs:n,groups:o,onGroupChange:a=>_(a),onSaveImage:v,ownerDocument:d}),t=Me({title:"Wafer-to-wafer trend",axisPrefs:Y,onAxisPrefsChange:m(()=>t),onTestChange:a=>x(a),selectedTestNumber:I??void 0,items:e.map(a=>({label:a.label,key:a.waferIndex,dies:a.dies,testStats:a.statsSummary?.stats.perTestStats})),testDefs:n,onSaveImage:v,centreLabel:Ee(Oe(e.map(a=>a.wafer.metadata)),"mean"),onOpen:H?(a,l)=>z(a,`Wafer ${e.find(S=>S.waferIndex===a)?.label??a}`,l):void 0,ownerDocument:d}),x=a=>{I=a,g.setTest(a),p.setTest(a),t.setTest(a),C.setTest(a)},C=Ye({title:"Process capability",items:e,testDefs:n,onSaveImage:v,selectedTestNumber:I??void 0,onSelectTest:a=>x(a),ownerDocument:d});return s.append(C.card,g.card,p.card,t.card),{card:s,destroy:()=>{C.destroy(),g.destroy(),p.destroy(),t.destroy()}}}function Te(e,n,o){const c=X(d),s=_e({title:"Test scatter",items:e,testDefs:n,groups:o,binColors:J().hard,onSaveImage:v,ownerDocument:d}),f=Ve({title:"Test correlation matrix",items:e,testDefs:n,onSaveImage:v,onSaveText:V,onSelectPair:(y,u)=>s.setXY(y,u),ownerDocument:d});return c.append(f.card,s.card),{card:c,destroy:()=>{f.destroy(),s.destroy()}}}function M(){for(const t of F)t.destroy();F=[],j.innerHTML="",$.innerHTML="",D.backTab&&$.appendChild(ge(D.backTab));for(const t of ot)$.appendChild(be(t.key,t.label));const e=me();he(e);const n=$e(e,{facetableOnly:!0}).filter(t=>t.splittable),o=d.createElement("div");Object.assign(o.style,{display:"flex",gap:w.md,alignItems:"center",marginLeft:w.xxl,paddingBottom:w.xs});let c;n.length>0?(o.appendChild(Ke("Group by:",[{value:"",label:"None"},...n.map(t=>({value:t.key,label:`${t.label} (${t.values.length})`}))],A??"",t=>{A=t||void 0,L=null,M()},{hook:"group-by",ownerDocument:d})),c=n.find(t=>t.key===A)?.label):A=void 0;let s;if(A){const t=new Map,x=[];for(const C of e){const a=Be(C.metadata,A)??De;t.has(a)||(t.set(a,[]),x.push(a)),t.get(a).push(C)}s=x.map(C=>({key:C,items:t.get(C)}))}L!==null&&!s?.some(t=>t.key===L)&&(L=null),s&&s.length>0&&o.appendChild(Xe(s.map(t=>t.key),"Show:",L,t=>_(t),{ownerDocument:d}).el);let f=null;if(D.onOpenGuide){const t=d.createElement("button");t.type="button",t.innerHTML=He.help,t.setAttribute("aria-label","User guide"),Object.assign(t.style,{...We("bare"),display:"inline-flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",flexShrink:"0"}),ae(t,"bare"),Ge(t,"User guide"),t.addEventListener("click",()=>D.onOpenGuide()),Object.assign(t.style,{marginLeft:"auto"}),f=t}$.appendChild(o),f&&$.appendChild(f);const y=L!==null?s?.find(t=>t.key===L):void 0,u=y?.items??e,m=y?void 0:s,i=Le(u),b=i.defs,h=b.filter(Ie);I!==null&&!h.some(t=>t.testNumber===I)&&(I=null);const g=W==="overview"?we(u,h,b,m,c):W==="distributions"?Se(u,h,m,c):Te(u,h,m),p=i.conflicts.filter(t=>t.excluded);if(p.length>0){const t=d.createElement("div");Object.assign(t.style,{color:B.label,fontSize:G.body,padding:`0 ${R} ${w.sm}`});const x=p.slice(0,6).map(l=>l.testNumber).join(", "),C=p.length>6?`, and ${p.length-6} more`:"",a=p.length===1?"it":"them";t.textContent=`${p.length} test ${p.length===1?"number is":"numbers are"} hidden (${x}${C}) \u2014 the wafers in view describe ${a} differently, so their values cannot be pooled. `+(s&&s.length>0?`Pick one ${c??"group"} under "Show:" to analyse ${a}.`:"Load one test program at a time to analyse them."),t.dataset.wmapWithheldTests=String(p.length),j.appendChild(t)}F.push(g),j.appendChild(g.card)}return{el:E,render:M,destroy:()=>{for(const e of F)e.destroy();E.remove()}}}
|
|
1
|
+
import{buildFacetTable as De,facetValueOf as $e,FACET_NONE_VALUE as Le}from"../stats/facets.js";import{mergeTestDefs as Ee}from"../stats/mergeTestDefs.js";import{isParametricTest as Ie}from"../renderer/buildWaferMap.js";import{waferDisplayLabel as Oe}from"../core/waferLabel.js";import{INPUT_DEFAULT_PASS_BINS as A,itemPassBins as Pe,passBinsLabel as ne}from"../core/passBins.js";import{NO_DATA_FILL as ae}from"../renderer/colorMap.js";import{describeWaferPopulation as Ae,populationStat as Re}from"../stats/population.js";import{LEADING as We,ALPHA as je,SPACE as S,EDGE_GUTTER as K,FONT as G,CLR as k,RADIUS as Ge,SHADOW as He,controlStyle as Ye,wireControlHover as oe,wireTooltip as Fe}from"./toolbar.js";import{ICONS as Ne}from"./icons.js";import{renderCapabilityPanel as Me}from"./charts/capability.js";import{renderBoxplotPanel as Ve}from"./charts/boxplot.js";import{renderTrendPanel as _e}from"./charts/trend.js";import{renderHistogramPanel as Ue}from"./charts/histogram.js";import{renderCorrelationPanel as ze}from"./charts/correlation.js";import{renderScatterPanel as qe}from"./charts/scatter.js";import{renderBarPanel as re}from"./charts/barPanel.js";import{renderBinClusterPanel as Qe}from"./charts/binCluster.js";import{renderTestPassRatePanel as Ke}from"./charts/testPassRate.js";import{QUANTITY as Xe}from"./charts/palette.js";import{cardFrameStyle as Je,makeChartGridWrap as X,makeLabeledSelect as Ze,makeLinkedGroupSelect as et}from"./charts/chartShell.js";import{buildYieldData as M,buildYieldDataCombined as se}from"../stats/yield.js";import{buildBinParetoData as tt}from"../stats/binPareto.js";import{buildLotTestSection as nt,buildLotFunctionalSection as at,buildMetadataStripBox as ot}from"./summaryPanel.js";import{buildRegionYieldData as ie,buildRingRegions as rt,buildQuadrantRegions as st}from"../stats/regions.js";import{renderRegionYieldDiagram as le}from"./charts/regionYieldDiagram.js";const it=[{key:"overview",label:"Overview"},{key:"distributions",label:"Distributions"},{key:"correlation",label:"Correlation"}];export function createInsightsTab(D){const{getItems:de,getLotStats:ce,getBinColors:J,getRingCount:pe,onSaveImage:T,onSaveText:V,openWafer:H,focusTest:Z}=D,ue=D.showMetadataStrip??!0,R=D.contentInset??K,d=D.ownerDocument??document,I=d.createElement("div");Object.assign(I.style,{display:"none",flexDirection:"column",width:"100%",paddingTop:"0"});const fe=K,O=d.createElement("div");Object.assign(O.style,{paddingLeft:fe});const B=d.createElement("div");Object.assign(B.style,{display:"flex",gap:S.xs,alignItems:"center",background:k.menuBg,border:`1px solid ${k.menuBorder}`,borderRadius:Ge.container,boxShadow:He.panel,padding:`0 ${S.lg}`,marginBottom:S.lg,marginLeft:R,marginRight:R}),B.setAttribute("role","tablist"),B.addEventListener("keydown",e=>{if(e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;const n=Array.from(B.querySelectorAll('[role="tab"]')),o=n.indexOf(d.activeElement);if(o===-1)return;e.preventDefault();const c=n[(o+(e.key==="ArrowRight"?1:-1)+n.length)%n.length];c.focus(),c.click()});const W=d.createElement("div");Object.assign(W.style,{display:"flex",flexDirection:"column",gap:S.lg,marginTop:"0",paddingLeft:R,paddingRight:R}),I.appendChild(O),I.appendChild(B),I.appendChild(W);let j=D.defaultView??"overview",P,L=null,$=null,Y={includeLimits:void 0,clipOutliers:!1};const _=e=>{$!==e&&($=e,N())};let F=[];function U(e,n,o){H?.(e,n,o)}function me(e){return H?{open:(n,o)=>U(n,`Wafer ${e.find(c=>c.waferIndex===n)?.label??n}`,o)}:Z&&e.length===1?{open:(n,o)=>Z(o),label:"show this test on the map"}:null}function be(){return de().map((e,n)=>e==null?null:{metadata:e.wafer.metadata??void 0,dies:e.dies,wafer:e.wafer,label:Oe(e,n),waferIndex:n,passBins:Pe(e),statsSummary:e.statsSummary,testDefs:e.testDefs}).filter(e=>e!=null)}function ee(e,n){Object.assign(e.style,{background:"none",border:"none",borderBottom:n?`2px solid ${k.iconActive}`:"2px solid transparent",color:n?k.iconActive:k.label,fontWeight:n?"700":"500",fontSize:G.body,padding:`${S.sm} ${K} ${S.md}`,cursor:"pointer",marginBottom:"-1px"})}function ge(e,n){const o=d.createElement("button");o.type="button",o.textContent=n;const c=e===j;return ee(o,c),o.dataset.on=c?"true":"false",oe(o,"bare"),o.dataset.wmapInsightsTab=e,o.setAttribute("role","tab"),o.setAttribute("aria-selected",c?"true":"false"),o.tabIndex=c?0:-1,o.addEventListener("click",()=>{j!==e&&(j=e,N())}),o}function ye(e){const n=d.createElement("button");return n.type="button",n.textContent=`\u2039 ${e.label}`,ee(n,!1),n.dataset.wmapInsightsBack="1",n.addEventListener("click",e.onBack),n}function he(e,n,o,c=!0){const l=X(d),f=J();let y="label";const u=o??"group",m=ne(e.map(s=>s.passBins)),i=ce?.(),b=new Map(i?.lotYieldSeries.map(s=>[s.waferIndex,s.yieldPercent])),h=s=>({...s,label:s.label.replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPercent:b.get(s.waferIndex),key:s.waferIndex}),g=e.map(h),p=n?.map(s=>({key:s.key,items:s.items.map(h)})),t=()=>p?se(p,A,y):M(g,A,y),x={title:n?`Yield by ${u} (pass: ${m})`:`Yield by wafer (pass: ${m})`,data:t(),selfControl:{current:y,options:[["yield","Sort: yield"],["label",n?`Sort: ${u}`:"Sort: wafer ID"]],onChange:s=>(y=s,{data:t()})},barColor:()=>Xe,valueLabel:s=>`${s.percent.toFixed(1)}%`,reference:s=>{if(s.length<3)return null;const v=s.map(Q=>Q.percent).sort((Q,ke)=>Q-ke),E=v.length%2?v[(v.length-1)/2]:(v[v.length/2-1]+v[v.length/2])/2;return{value:E,label:`median ${E.toFixed(1)}%`}},drill:p?{onOpenGroup:s=>{const v=p.find(E=>E.key===s.label)?.items??[];return{data:M(v,A,y),title:`Yield by wafer \u2014 ${u}: ${s.label} (pass: ${m})`}},onBack:()=>({data:t(),title:`Yield by ${u} (pass: ${m})`}),groupLabelText:u}:void 0,onOpen:H?s=>{typeof s.key=="number"&&U(s.key,`Wafer ${s.label}`)}:void 0,ownerDocument:d};let C=null;if(c&&(C=re(x,T),C.card.style.minHeight="360px",l.appendChild(C.card)),n){const s=Qe({title:"Hard bin pareto",groups:n.map(v=>({key:v.key,items:v.items.map(E=>({dies:E.dies,hardBinCounts:E.statsSummary?.stats.hardBinCounts,softBinCounts:E.statsSummary?.stats.softBinCounts}))})),onSaveImage:T,ownerDocument:d});return s.card.style.minHeight="360px",l.appendChild(s.card),{card:l,destroy:()=>{C?.destroy(),s.destroy()}}}let a="hbin";const r=s=>s===void 0?ae:(a==="hbin"?f.hard:f.soft).get(s)??ae,w=e.map(s=>({dies:s.dies,hardBinCounts:s.statsSummary?.stats.hardBinCounts,softBinCounts:s.statsSummary?.stats.softBinCounts})),te=()=>tt(w,a),Be={title:"Hard bin pareto",data:te(),selfControl:{current:a,options:[["hbin","Hard bins"],["sbin","Soft bins"]],onChange:s=>(a=s,{data:te(),title:`${a==="hbin"?"Hard":"Soft"} bin pareto`})},barColor:s=>r(s.binCode),ownerDocument:d},q=re(Be,T);return q.card.style.minHeight="360px",l.appendChild(q.card),{card:l,destroy:()=>{C?.destroy(),q.destroy()}}}function z(){const e=d.createElement("div");return e.dataset.wmapChartCard="1",Object.assign(e.style,{...Je(),display:"flex",flexDirection:"column",gap:S.lg,minWidth:"0"}),e}function Ce(e){if(O.innerHTML="",O.style.marginBottom="0",!ue)return;const n=ot(e.map(o=>({metadata:o.metadata})),void 0,{facetableOnly:!1});n&&(n.style.marginBottom="0",O.appendChild(n),O.style.marginBottom=S.xs)}function xe(e,n,o,c){if(!e.length)return{elements:[],testValuesCard:null,functionalCard:null,destroy:()=>{}};const l=e.map(r=>r.wafer),f=e.map(r=>r.dies),y=e.flatMap(r=>r.dies),u=e.map(r=>r.statsSummary),m=u.every(r=>r!==void 0)?u:void 0,i=pe?.()??4,b=[],h=[],p=Ke({groups:(c??[{key:"",items:e}]).map(r=>({key:r.key,items:r.items.map(w=>({dies:w.dies,testSpecYield:w.statsSummary?.stats.testSpecYield,functionalYield:w.statsSummary?.stats.functionalYield}))})),testDefs:o,onSaveImage:T,ownerDocument:d});p.card.style.minHeight="300px",b.push(p.card),h.push(p.destroy);const t=ie(f,l,i,r=>e[r].passBins,rt);if(t.length){const r=le({title:"Ring yield",mode:"ring",rows:t,onSaveImage:T,ownerDocument:d});b.push(r.card),h.push(r.destroy)}const x=ie(f,l,i,r=>e[r].passBins,st);if(x.length){const r=le({title:"Quadrant yield",mode:"quadrant",rows:x,onSaveImage:T,ownerDocument:d});b.push(r.card),h.push(r.destroy)}let C=null;if(n.length){const r=nt(y,n,void 0,m,V,f.map(w=>({dies:w})),void 0,"full");if(r){const w=z();w.appendChild(r),C=w}}let a=null;if(o.length){const r=at(y,o,m,V);if(r){const w=z();w.appendChild(r),a=w}}return{elements:b,testValuesCard:C,functionalCard:a,destroy:()=>{for(const r of h)r()}}}function Se(e){const n=ne(e.map(i=>i.passBins)),o=e.length===1,c=e[0],l=z();Object.assign(l.style,{flexDirection:"row",flexWrap:"wrap",gap:S.md});const f=i=>{const b=i.lastElementChild;return b&&Object.assign(b.style,{borderRight:"none",paddingRight:"0",marginRight:"0"}),i};function y(i,b,h){const g=d.createElement("div");Object.assign(g.style,{display:"flex",alignItems:"baseline",gap:S.sm,paddingRight:S.xxl,marginRight:S.md,borderRight:`1px solid ${k.menuBorder}`});const p=d.createElement("div");p.textContent=i,Object.assign(p.style,{fontSize:G.heading,fontWeight:"700",color:k.value,lineHeight:We.tight});const t=d.createElement("div");if(t.textContent=b,Object.assign(t.style,{fontSize:G.body,color:k.label}),g.append(p,t),h){const x=d.createElement("div");x.textContent=h,Object.assign(x.style,{fontSize:G.meta,color:k.label,opacity:je.muted}),g.appendChild(x)}return g}if(o){const i=M([{...c,key:c.waferIndex}],A)[0]?.percent;return i!==void 0&&l.appendChild(y(`${i.toFixed(1)}%`,`Yield \xB7 pass: ${n}`)),l.appendChild(y(String(c.dies.length),"Total dies")),f(l)}l.appendChild(y(String(e.length),"Wafers"));const u=M(e.map(i=>({...i,key:i.waferIndex})),A).map(i=>i.percent).filter(i=>Number.isFinite(i));if(u.length){const i=u.reduce((g,p)=>g+p,0)/u.length,b=se([{key:"all",items:e.map(g=>({...g,key:g.waferIndex}))}],A)[0]?.percent,h=b!==void 0&&b.toFixed(1)!==i.toFixed(1);l.appendChild(y(`${i.toFixed(1)}%`,`Mean per-wafer yield \xB7 pass: ${n}`,h?`${b.toFixed(1)}% by dies`:void 0))}const m=e.map(i=>i.statsSummary);if(m.every(i=>i!==void 0)){const i=m.reduce((h,g)=>h+g.stats.analyzedDies,0),b=m.reduce((h,g)=>h+g.stats.excludedDies,0);l.appendChild(y(i.toLocaleString(),"Dies analysed",b?`${b.toLocaleString()} excluded`:void 0))}else l.appendChild(y(e.reduce((i,b)=>i+b.dies.length,0).toLocaleString(),"Total dies"));return f(l)}function we(e,n,o,c,l){const f=d.createElement("div");Object.assign(f.style,{display:"flex",flexDirection:"column",gap:S.lg});const y=e.length===1&&!c;e.length&&!c&&f.appendChild(Se(e));const u=he(e,c,l,!y);f.appendChild(u.card);const m=xe(e,n,o,c);for(const i of m.elements)u.card.appendChild(i);return m.testValuesCard&&f.appendChild(m.testValuesCard),m.functionalCard&&f.appendChild(m.functionalCard),{card:f,destroy:()=>{u.destroy(),m.destroy()}}}function Te(e,n,o,c){const l=X(d),f=me(e),y=a=>{Y=a;for(const r of[g,p,t])r!==u&&r?.setAxisPrefs(a)};let u=null;const m=a=>r=>{u=a(),y(r),u=null},i=a=>({...a,testStats:a.statsSummary?.stats.perTestStats}),b=e.map(i),h=o?.map(a=>({key:a.key,items:a.items.map(i)})),g=Ve({title:"Test value distribution",axisPrefs:Y,onAxisPrefsChange:m(()=>g),onTestChange:a=>x(a),selectedTestNumber:L??void 0,items:b,testDefs:n,groups:h,groupLabelText:c,onSaveImage:T,onGroupChange:a=>_(a),onOpen:f?.open,openActionLabel:f?.label,ownerDocument:d}),p=Ue({title:"Value histogram",axisPrefs:Y,onAxisPrefsChange:m(()=>p),onTestChange:a=>x(a),selectedTestNumber:L??void 0,items:e,testDefs:n,groups:o,onGroupChange:a=>_(a),onSaveImage:T,ownerDocument:d}),t=_e({title:"Wafer-to-wafer trend",axisPrefs:Y,onAxisPrefsChange:m(()=>t),onTestChange:a=>x(a),selectedTestNumber:L??void 0,items:e.map(a=>({label:a.label,key:a.waferIndex,dies:a.dies,testStats:a.statsSummary?.stats.perTestStats})),testDefs:n,onSaveImage:T,centreLabel:Re(Ae(e.map(a=>a.wafer.metadata)),"mean"),onOpen:H?(a,r)=>U(a,`Wafer ${e.find(w=>w.waferIndex===a)?.label??a}`,r):void 0,ownerDocument:d}),x=a=>{L=a,g.setTest(a),p.setTest(a),t.setTest(a),C.setTest(a)},C=Me({title:"Process capability",items:e,testDefs:n,onSaveImage:T,selectedTestNumber:L??void 0,onSelectTest:a=>x(a),ownerDocument:d});return l.append(C.card,g.card,p.card,t.card),{card:l,destroy:()=>{C.destroy(),g.destroy(),p.destroy(),t.destroy()}}}function ve(e,n,o){const c=X(d),l=qe({title:"Test scatter",items:e,testDefs:n,groups:o,binColors:J().hard,onSaveImage:T,ownerDocument:d}),f=ze({title:"Test correlation matrix",items:e,testDefs:n,onSaveImage:T,onSaveText:V,onSelectPair:(y,u)=>l.setXY(y,u),ownerDocument:d});return c.append(f.card,l.card),{card:c,destroy:()=>{f.destroy(),l.destroy()}}}function N(){for(const t of F)t.destroy();F=[],W.innerHTML="",B.innerHTML="",D.backTab&&B.appendChild(ye(D.backTab));for(const t of it)B.appendChild(ge(t.key,t.label));const e=be();Ce(e);const n=De(e,{facetableOnly:!0}).filter(t=>t.splittable),o=d.createElement("div");Object.assign(o.style,{display:"flex",gap:S.md,alignItems:"center",marginLeft:S.xxl,paddingBottom:S.xs});let c;n.length>0?(o.appendChild(Ze("Group by:",[{value:"",label:"None"},...n.map(t=>({value:t.key,label:`${t.label} (${t.values.length})`}))],P??"",t=>{P=t||void 0,$=null,N()},{hook:"group-by",ownerDocument:d})),c=n.find(t=>t.key===P)?.label):P=void 0;let l;if(P){const t=new Map,x=[];for(const C of e){const a=$e(C.metadata,P)??Le;t.has(a)||(t.set(a,[]),x.push(a)),t.get(a).push(C)}l=x.map(C=>({key:C,items:t.get(C)}))}$!==null&&!l?.some(t=>t.key===$)&&($=null),l&&l.length>0&&o.appendChild(et(l.map(t=>t.key),"Show:",$,t=>_(t),{ownerDocument:d}).el);let f=null;if(D.onOpenGuide){const t=d.createElement("button");t.type="button",t.innerHTML=Ne.help,t.setAttribute("aria-label","User guide"),Object.assign(t.style,{...Ye("bare"),display:"inline-flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",flexShrink:"0"}),oe(t,"bare"),Fe(t,"User guide"),t.addEventListener("click",()=>D.onOpenGuide()),Object.assign(t.style,{marginLeft:"auto"}),f=t}B.appendChild(o),f&&B.appendChild(f);const y=$!==null?l?.find(t=>t.key===$):void 0,u=y?.items??e,m=y?void 0:l,i=Ee(u),b=i.defs,h=b.filter(Ie);L!==null&&!h.some(t=>t.testNumber===L)&&(L=null);const g=j==="overview"?we(u,h,b,m,c):j==="distributions"?Te(u,h,m,c):ve(u,h,m),p=i.conflicts.filter(t=>t.excluded);if(p.length>0){const t=d.createElement("div");Object.assign(t.style,{color:k.label,fontSize:G.body,padding:`0 ${R} ${S.sm}`});const x=p.slice(0,6).map(r=>r.testNumber).join(", "),C=p.length>6?`, and ${p.length-6} more`:"",a=p.length===1?"it":"them";t.textContent=`${p.length} test ${p.length===1?"number is":"numbers are"} hidden (${x}${C}) \u2014 the wafers in view describe ${a} differently, so their values cannot be pooled. `+(l&&l.length>0?`Pick one ${c??"group"} under "Show:" to analyse ${a}.`:"Load one test program at a time to analyse them."),t.dataset.wmapWithheldTests=String(p.length),W.appendChild(t)}F.push(g),W.appendChild(g.card)}return{el:I,render:N,destroy:()=>{for(const e of F)e.destroy();I.remove()}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getDieTestValue as $}from"../renderer/buildWaferMap.js";import{resolveTestNumber as T,findTestDef as B}from"../renderer/buildView.js";import{buildBinSection as V}from"./summaryPanel.js";import{buildTestHistogramData as z}from"../stats/histogram.js";import{resolveValueColorFn as F}from"../renderer/colorSchemes.js";import{TRACKING as N,SPACE as y,RADIUS as I,FONT as S,CLR as
|
|
1
|
+
import{getDieTestValue as $}from"../renderer/buildWaferMap.js";import{resolveTestNumber as T,findTestDef as B}from"../renderer/buildView.js";import{buildBinSection as V}from"./summaryPanel.js";import{buildTestHistogramData as z}from"../stats/histogram.js";import{resolveValueColorFn as F}from"../renderer/colorSchemes.js";import{TRACKING as N,SPACE as y,RADIUS as I,FONT as S,CLR as u,wireTooltip as A}from"./toolbar.js";import{fmt as v}from"../renderer/fmt.js";function d(o,n,t){const a=document.createElement(o);return n&&Object.assign(a.style,n),t!==void 0&&(a.textContent=t),a}function W(o,n,t,a,x){let p=1/0,m=-1/0;for(const r of o){const s=$(r,n);s!==void 0&&(s<p&&(p=s),s>m&&(m=s))}const b=a==="spec"&&t&&(t.limitLow!==void 0||t.limitHigh!==void 0);let e,l;b?(e=t.limitLow!==void 0?t.limitLow:isFinite(p)?p:0,l=t.limitHigh!==void 0?t.limitHigh:isFinite(m)?m:1):(e=isFinite(p)?p:0,l=isFinite(m)?m:1),e===l&&(l=e+1);const h=r=>Math.min(1,Math.max(0,r));if(x&&e>0&&l>0){const r=Math.log10(e),s=Math.log10(l)-r;return c=>c<=0?0:h((Math.log10(c)-r)/s)}return r=>h((r-e)/(l-e))}function E(o,n,t,a,x,p,m,b){const e=d("div",{display:"flex",flexDirection:"column",gap:y.xxs,minWidth:"0",flex:"1",minHeight:"0"});e.appendChild(d("div",{fontSize:S.meta,fontWeight:"700",letterSpacing:N,textTransform:"uppercase",color:u.label},n?.name?`${n.name} distribution`:"Value distribution"));const l=o[0].rangeLow,h=o[o.length-1].rangeHigh,r=h-l||1,s=i=>Math.min(1,Math.max(0,(i-l)/r)),c=F(a,x),f=W(p,t,n,m,b),w=Math.max(1,...o.map(i=>i.count)),L=d("div",{position:"relative",display:"flex",alignItems:"flex-end",gap:y.xxs,flex:"1",minHeight:"48px"});for(const i of o){const g=d("div",{flex:"1",minWidth:"2px",background:c(f((i.rangeLow+i.rangeHigh)/2)),height:`${i.count/w*100}%`,borderRadius:"1px 1px 0 0"});g.dataset.wmapBar="1",A(g,`${v(i.rangeLow,n?.unit)} \u2013 ${v(i.rangeHigh,n?.unit)}: ${i.count}`,{asDataPoint:!0}),L.appendChild(g)}const H=[];for(const[i,g]of[[n?.limitLow,"LSL"],[n?.limitHigh,"USL"]]){if(i===void 0||i<l||i>h)continue;const C=s(i)*100,M=d("div",{position:"absolute",top:"0",bottom:"0",left:`${C}%`,width:"2px",marginLeft:"-1px",background:u.value,boxShadow:`0 0 0 1px ${u.panelBg}`,pointerEvents:"none"});M.dataset.wmapLimitMarker="1",L.appendChild(M),H.push({pct:C,text:`${g} ${v(i,n?.unit)}`})}if(e.appendChild(L),H.length){const i=d("div",{position:"relative",height:"14px"});for(const{pct:g,text:C}of H){const M=Math.min(96,Math.max(4,g));i.appendChild(d("span",{position:"absolute",left:`${M}%`,top:"0",transform:"translateX(-50%)",whiteSpace:"nowrap",fontSize:S.body,fontWeight:"600",color:u.text,background:u.panelBg,border:`1px solid ${u.value}`,borderRadius:I.control,padding:"0 3px",lineHeight:"12px"},C))}e.appendChild(i)}const R=d("div",{display:"flex",justifyContent:"space-between",fontSize:S.body,color:u.label});return R.appendChild(d("span",{},v(o[0].rangeLow,n?.unit))),R.appendChild(d("span",{},v(o[o.length-1].rangeHigh,n?.unit))),e.appendChild(R),e}export function buildMaplessSummary(o,n,t){const{plotMode:a,activeTest:x,hbinDefs:p,sbinDefs:m,binColors:b,valueColorScheme:e,reverseValueScheme:l,logScale:h=!1,colorbarRangeMode:r="spec",valueRangeDies:s}=t;if(a==="hardBin"||a==="softBin"){const f=V(o,a==="hardBin"?p:m,a==="hardBin"?"hard":"soft",b);if(f)return f}else if(a==="value"){const{testNumber:c}=T(x??0,n),f=B(n,x??0),w=z([{dies:o}],c,12,f?.limitLow,f?.limitHigh);if(w.length)return E(w,f,c,e,l,s??o,r,h)}return d("div",{padding:y.xl,fontSize:S.body,color:u.label,textAlign:"center"},"No summary available for this view.")}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type BinColors } from '../renderer/binColors.js';
|
|
1
2
|
import { type SaveImageHandler, type SaveTextHandler, type UserGuideExtension } from './toolbar.js';
|
|
2
|
-
import type
|
|
3
|
+
import { type Die } from '../core/dies.js';
|
|
3
4
|
import type { WaferViewOptions } from './renderWaferMap.js';
|
|
4
5
|
import type { RenderableWaferMap } from './renderWaferMap.js';
|
|
5
6
|
import type { LotStatsSummary } from '../stats/types.js';
|
|
@@ -40,8 +41,6 @@ export interface GalleryOptions {
|
|
|
40
41
|
viewOptions?: WaferViewOptions;
|
|
41
42
|
/** Called whenever a shared gallery option changes. */
|
|
42
43
|
onViewOptionsChange?: (opts: WaferViewOptions, changed: (keyof WaferViewOptions)[], category: 'preference' | 'state' | 'mixed') => void;
|
|
43
|
-
/** Legend position for bin modes. Default 'default'. */
|
|
44
|
-
legendPosition?: 'default' | 'compact' | 'bottom' | 'top' | 'left' | 'floating';
|
|
45
44
|
/**
|
|
46
45
|
* Draw a legend on every card as well as the lot-level one. Default false.
|
|
47
46
|
*
|
|
@@ -55,16 +54,22 @@ export interface GalleryOptions {
|
|
|
55
54
|
* disabled with that reason rather than appearing to do nothing.
|
|
56
55
|
*/
|
|
57
56
|
perCardLegend?: boolean;
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Name for the composite gallery PNG, without extension. When omitted, it is
|
|
59
|
+
* named for its lots, wafer count and plot mode
|
|
60
|
+
* (`LOT123_25-wafers_gallery-hard-bin.png`); cards, CSV exports and charts are
|
|
61
|
+
* always named that way. See docs/api.md §5.4.5.
|
|
62
|
+
*
|
|
63
|
+
* **Changes in 0.31.0:** this becomes a prefix for every file the gallery and
|
|
64
|
+
* its cards save. Passing it logs a one-time notice.
|
|
65
|
+
*/
|
|
61
66
|
downloadFilename?: string;
|
|
62
67
|
/**
|
|
63
68
|
* Host hook for persisting the composite gallery PNG. When provided, the save
|
|
64
69
|
* action calls `onSaveImage(blob, suggestedName)` instead of triggering a
|
|
65
70
|
* browser `<a download>` — letting embedded hosts (Tauri, Electron, WebView2)
|
|
66
71
|
* route the image through a native save dialog. `suggestedName` includes the
|
|
67
|
-
* `.png` extension and is
|
|
72
|
+
* `.png` extension and is the generated name (see `downloadFilename`). When omitted, the
|
|
68
73
|
* default browser download behaviour is unchanged.
|
|
69
74
|
*/
|
|
70
75
|
onSaveImage?: SaveImageHandler;
|
|
@@ -76,18 +81,6 @@ export interface GalleryOptions {
|
|
|
76
81
|
* the default browser download behaviour is unchanged.
|
|
77
82
|
*/
|
|
78
83
|
onSaveText?: SaveTextHandler;
|
|
79
|
-
/**
|
|
80
|
-
* Format to use for unitless values outside the normal display range [0.1, 9999].
|
|
81
|
-
* `'engineering'` (default): multiples-of-3 exponent notation (e.g. `12E-6`).
|
|
82
|
-
* `'si'`: SI prefix with no unit suffix (e.g. `12 µ`).
|
|
83
|
-
* Values with a unit always use SI prefix regardless of this setting.
|
|
84
|
-
*/
|
|
85
|
-
fallbackFormat?: 'si' | 'engineering';
|
|
86
|
-
/**
|
|
87
|
-
* Show the plot mode selector in the gallery control bar. Default true.
|
|
88
|
-
* Set to false when the host application manages mode switching itself.
|
|
89
|
-
*/
|
|
90
|
-
showPlotModeSelector?: boolean;
|
|
91
84
|
/** Precomputed lot-level stats summary. Enables the summary panel toggle button in the control bar. */
|
|
92
85
|
lotStatsSummary?: LotStatsSummary;
|
|
93
86
|
/**
|
|
@@ -118,28 +111,13 @@ export interface GalleryOptions {
|
|
|
118
111
|
* own coordinate-less die-list table, which this reuses.
|
|
119
112
|
*/
|
|
120
113
|
dieList?: DieListDisplayOptions;
|
|
121
|
-
/**
|
|
122
|
-
* Bin numbers treated as pass for yield calculation in the summary panel.
|
|
123
|
-
* Defaults to `[1]`. Must match the `passBins` passed to `analyzeWaferLot` / `buildWaferMap`
|
|
124
|
-
* to ensure the summary panel yield label is consistent with the rest of the display.
|
|
125
|
-
*/
|
|
126
|
-
passBins?: number[];
|
|
127
114
|
/**
|
|
128
115
|
* Fix the number of columns in the gallery grid. When set, overrides the
|
|
129
|
-
* auto-computed
|
|
116
|
+
* auto-computed layout and the toolbar columns control: the columns share the
|
|
117
|
+
* full grid width, with no density-derived card size cap.
|
|
130
118
|
* Omit (default) to let the gallery auto-size cards based on die pitch.
|
|
131
119
|
*/
|
|
132
120
|
columns?: number;
|
|
133
|
-
/**
|
|
134
|
-
* Cap each gallery card's rendered width and height at this many CSS pixels.
|
|
135
|
-
* Cards pack from the left rather than stretching to fill the grid width.
|
|
136
|
-
*
|
|
137
|
-
* Omit it and the cap is derived from die density: 480px for an ordinary
|
|
138
|
-
* wafer, widening (to at most 720px) for high-DPW wafers that need the room
|
|
139
|
-
* to keep dies readable. Set it to take hard control instead — an explicit
|
|
140
|
-
* value is never widened, so you own the readability trade-off at high DPW.
|
|
141
|
-
*/
|
|
142
|
-
maxSize?: number;
|
|
143
121
|
/**
|
|
144
122
|
* Show a help button in the gallery control bar that opens the built-in end-user guide in a modal.
|
|
145
123
|
* Default false. Enable in applications that want to surface the guide without linking externally.
|
|
@@ -185,8 +163,6 @@ export interface GalleryController {
|
|
|
185
163
|
setOptions(opts: Partial<WaferViewOptions>): void;
|
|
186
164
|
/** Return the current shared scene options. */
|
|
187
165
|
getOptions(): WaferViewOptions;
|
|
188
|
-
/** Update the fallback format for unitless values across all cards. */
|
|
189
|
-
setFallbackFormat(format: 'si' | 'engineering'): void;
|
|
190
166
|
/** Replace the lot-level stats summary used by the built-in Summary panel. */
|
|
191
167
|
setLotStatsSummary(summary: LotStatsSummary | undefined): void;
|
|
192
168
|
/**
|
|
@@ -195,10 +171,17 @@ export interface GalleryController {
|
|
|
195
171
|
*/
|
|
196
172
|
setFindingsNotice(notice: FindingsNotice | undefined): void;
|
|
197
173
|
/**
|
|
198
|
-
* Set the number of columns
|
|
199
|
-
* the
|
|
174
|
+
* Set the number of grid columns, as the toolbar's Columns control does: the
|
|
175
|
+
* columns share the full grid width. Pass `undefined` to return to the
|
|
176
|
+
* automatic layout, which sizes cards by die pitch.
|
|
200
177
|
*/
|
|
201
178
|
setColumns(columns: number | undefined): void;
|
|
179
|
+
/**
|
|
180
|
+
* The bin colours every card draws, resolved once over the whole gallery with
|
|
181
|
+
* the palette currently chosen — for a host surface of its own (a table
|
|
182
|
+
* swatch, an export). Hard and soft bins are separate maps.
|
|
183
|
+
*/
|
|
184
|
+
getBinColors(): BinColors;
|
|
202
185
|
/**
|
|
203
186
|
* Opens the built-in end-user guide window — the same action the help
|
|
204
187
|
* toolbar button performs, but callable directly. Works regardless of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as ro,resolveTestNumber as co,findTestDef as fo,collectMetadataValues as uo}from"../renderer/buildView.js";import{metadataCategoricalValue as po}from"../core/metadata.js";import{resolveBinColors as go,binColorWarning as mo}from"../renderer/binColors.js";import{NO_DATA_FILL as ho}from"../renderer/colorMap.js";import{metadataValueColor as bo}from"../renderer/colorMap.js";import{resolveCanvasTheme as yo}from"./canvasTheme.js";import{ICONS as $e}from"./icons.js";import{SHADOW as We,LEADING as Ze,TRACKING as wo,controlStyle as xo,wireControlHover as mt,SPACE as x,EDGE_GUTTER as te,MAP_CHROME_INSET as vo,RADIUS as V,FONT as O,CLR as m,sevColor as an,MODE_LABELS as Co,BIN_LEGEND_MODES as sn,STACKED_MODES as be,Z_ABOVE as rn,applyOverlayZ as So,getTooltip as Mo,hideTooltip as dn,createToolbarHelpers as Do,buildModeMenuEl as ko,openDetachWindow as Eo,openFloatingWindow as Bo,openModal as Oo,openReportModal as To,copyWmapThemeTokens as Lo,syncWmapPopupTheme as $o,openUserGuideWindow as Wo,makePaletteBtn as Ro,makeLogScaleBtn as Io,makeLegendStyleBtn as Ao,makeOverlaysBtn as Po,makeOrientationBtn as Fo,menuLayerFor as cn,saveImageBlob as Ho,markMenuTrigger as Re,wireMenuA11y as fn,wireExpandToggle as un,wireTooltip as pn,requestedPassFailDisplay as gn,overlayMenuRows as jo,anyOverlayActive as Vo,logWmapVersionOnce as zo,buildDataModeEntries as No,metadataKeyHasData as _o,metadataModeEntry as Go}from"./toolbar.js";import{aggregateValues as Ko,aggregateBinCounts as mn}from"../core/aggregates.js";import{renderWaferMap as ht}from"./renderWaferMap.js";import{classifyChanged as qo,COLOR_KEYS as Uo}from"./renderWaferMap.js";import{buildWaferMap as Xo,getTestPassStatus as hn,isParametricTest as bt,getDieTestValue as Zo}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ye}from"../stats/analyzeWaferMap.js";import{collectWarnings as Yo,buildWarningsMenuEl as Qo,severityOf as Jo}from"./warnings.js";import{compareNatural as bn}from"../core/utils.js";import{createSummaryPanelEl as yt,buildMetadataStripRow as ei,buildCompactMetadataRows as yn,metadataEntries as wn,renderLotSummaryContent as ti}from"./summaryPanel.js";import{renderLotSummaryReportHtml as ni}from"../stats/renderSummaryReport.js";import{prettyKey as oi}from"../stats/facets.js";import{mergeTestDefs as ii}from"../stats/mergeTestDefs.js";import{getDieKey as li,hasPosition as ai}from"../core/dies.js";function ne(f){const C=new Set;return f.filter(p=>C.has(p.bin)?!1:(C.add(p.bin),!0))}const wt=12;function si(f,C,p){let P=C;if(C.length>wt){const v=C.slice(0,wt-1),T=C.slice(wt-1),oe=T.reduce((Je,re)=>Je+re.count,0);P=[...v,{color:m.label,count:oe,label:`Other (${T.length} bins)`}]}const F=f.createElement("div");Object.assign(F.style,{display:"flex",width:"100%",height:"8px",borderRadius:V.control,overflow:"hidden",border:`1px solid ${m.menuBorder}`,boxSizing:"border-box",marginTop:x.xs,flexShrink:"0"}),F.setAttribute("role","img"),F.setAttribute("aria-label",`Population split: ${P.map(v=>`${v.label} ${Qe(v.count/p*100)}`).join(", ")}`);for(const v of P){const T=v.count/p*100,oe=f.createElement("div");Object.assign(oe.style,{flex:`${T} 1 0`,minWidth:T>0?"2px":"0",background:v.color}),pn(oe,`${v.label} \xB7 ${v.count.toLocaleString()} dies \xB7 ${Qe(T)}`),F.appendChild(oe)}return F}function Qe(f){return f>0&&f<.1?"<0.1%":`${f.toFixed(1)}%`}function xn(f,C){const p=new Map;let P=0;for(const F of f)for(const v of F.dies){if(v.partial||v.edgeExcluded)continue;const T=C(v);T!==void 0&&(p.set(T,(p.get(T)??0)+1),P++)}return{counts:p,total:P}}function vn(f,C){const p=f.ownerDocument.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:`${x.xxs} ${x.xs}`,borderRadius:V.control});const P=f.ownerDocument.createElement("span");Object.assign(P.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:C.color,border:C.isActive?`2px solid ${m.iconActive}`:`1px solid ${m.menuBorder}`,borderRadius:V.control,boxSizing:"border-box"});const F=f.ownerDocument.createElement("span");if(F.textContent=C.label,Object.assign(F.style,{fontWeight:C.isActive?"700":"400",color:C.isActive?m.iconActive:m.text,whiteSpace:"nowrap"}),p.appendChild(P),p.appendChild(F),C.count!==void 0){const v=f.ownerDocument.createElement("span");if(v.textContent=C.count.toLocaleString(),Object.assign(v.style,{color:C.isActive?m.iconActive:m.text,fontWeight:C.isActive?"700":"400",whiteSpace:"nowrap"}),p.appendChild(v),C.percent!==void 0){const T=f.ownerDocument.createElement("span");T.textContent=Qe(C.percent),Object.assign(T.style,{color:m.label,whiteSpace:"nowrap"}),p.appendChild(T)}}p.setAttribute("role","button"),p.setAttribute("aria-pressed",C.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=m.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=m.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",C.onClick),p.addEventListener("keydown",v=>{(v.key==="Enter"||v.key===" ")&&(v.preventDefault(),C.onClick())}),f.appendChild(p)}export function renderWaferGallery(f,C,p={}){zo();const P=p.cardPadding??6,F=p.downloadFilename??"wafer-gallery";let v=p.columns;const T=p.showPlotModeSelector??!0,oe=p.showHelpButton??!1,Je=p.userGuideExtension,re=p.insights?.enabled??!1,Cn=So(p.zIndex),de=p.summaryPanel,ye=p.passBins??[1];let Ie=p.fallbackFormat,H=p.lotStatsSummary,we=p.legendPosition??"default",Ae=p.perCardLegend??!1;function xe(){const e=d.plotMode??"hardBin";return sn.has(e)?null:d.colorbarRangeMode==="data"?"Each map has its own value range, so it keeps its own colour bar":"These wafers have no shared colour bar for value mode, so each map keeps its own"}function xt(){const e=Ae||xe()!==null;for(const t of S)t&&t.setOptions({showLegend:e})}let d={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},S=[],ie=[],ce=[],L=[],w=C.map(e=>typeof e=="function"?null:e);function vt(){return ii(w)}function fe(){if(w.some(e=>e?.testDefs?.length))return vt().defs}let et=0,Pe=0;const z=new Map;let Sn=0,A=null,ve=null,Ct=new Set,h=null,Mn={};function St(e){return w[e]?.statsSummary??H?.perWafer.find(t=>t.waferIndex===e)?.summary}function tt(){return!!(w.some(e=>e?.statsSummary?.findings.length)||H?.perWafer.some(e=>e.summary.findings.length))}const Dn=Mo(),ue=Do(Dn),{makeBtn:Z,setActive:Ce,makeSep:N,makeMenuRow:kn,makeMenuSection:En,makeDropdown:Mt,closeOpenMenu:Fe,getOpenMenu:Se,setOpenMenu:Me}=ue;f.ownerDocument.addEventListener("click",Fe,!0);const Dt=()=>dn();window.addEventListener("blur",Dt);let kt=p.findingsNotice;function Et(e){Ct=new Set(e);const t=[...I.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((o,c)=>{const l=Ct.has(c);o.style.outline=l?`3px solid ${m.findingHighlight}`:"",o.style.outlineOffset=l?"-3px":"",l&&n===void 0&&(n=o)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function Bt(){Et([])}function Ot(){for(const e of S)e&&e.clearSelection()}function nt(e,t){const n=new Set(e),o=t??S.map((c,l)=>l);for(const c of o){const l=L[c],a=S[c];if(!l||!a)continue;const s=l.dies.filter(i=>n.has(li(i)));a.setSelection(s)}}function Bn(){const e=[];for(let t=0;t<w.length;t++){const n=w[t];if(!n)continue;const o=St(t)?.findings??[];o.length&&e.push({index:t,item:n,unusualCount:o.filter(c=>c.severity==="unusual").length,notableCount:o.filter(c=>c.severity==="notable").length,totalCount:o.length})}return e}function On(e){const t=L[e]??w[e];t&&Te(e,t)}function Tn(e){const t=St(e)?.findings??[];if(t.length)return{total:t.length,unusual:t.filter(n=>n.severity==="unusual").length,notable:t.filter(n=>n.severity==="notable").length}}function Ln(){const e=ne(w.flatMap(n=>n?.hbinDefs??[])),t=ne(w.flatMap(n=>n?.sbinDefs??[]));To(ni({items:w.map((n,o)=>({label:n?.label??`W${o+1}`,wafer:n?.wafer,dies:n?.dies,statsSummary:n?.statsSummary})),hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:fe(),passBins:ye,ringCount:d.ringCount}),{anchor:f})}function $n(){if(!h)return;h.innerHTML="";const e=Bn();if(w.length>0){const n=f.ownerDocument.createElement("div"),o=e.length,c=w.filter(Boolean).length;n.textContent=o===0?`No findings on any of the ${c} wafers`:`${o} of ${c} wafer${c===1?"":"s"} with findings`,Object.assign(n.style,{fontSize:O.body,color:m.label,marginBottom:x.md}),h.appendChild(n)}if(e.length>0){const n=f.ownerDocument.createElement("button");n.type="button",n.textContent="Summary report",Object.assign(n.style,{...xo("outlined"),marginBottom:x.lg,display:"block",width:"100%",textAlign:"left"}),mt(n),n.addEventListener("click",Ln),h.appendChild(n)}if(e.length===0){const n=f.ownerDocument.createElement("div");Object.assign(n.style,{color:m.icon,fontSize:O.body,padding:"4px 0"}),n.textContent="No findings on any wafer.",h.appendChild(n)}else for(const{index:n,item:o,unusualCount:c,notableCount:l,totalCount:a}of e){const s=c?"unusual":l?"notable":"info",i=c+l||a,r=f.ownerDocument.createElement("button");r.type="button",Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:x.xs,border:"none",borderLeft:`3px solid ${an(s)}`,borderRadius:V.control,background:m.bgHover,cursor:"pointer",fontSize:O.body,textAlign:"left",boxSizing:"border-box"}),r.addEventListener("mouseover",()=>{r.style.background=m.bgActive}),r.addEventListener("mouseout",()=>{r.style.background=m.bgHover});const u=f.ownerDocument.createElement("span");u.textContent=o.label??`W${n+1}`,Object.assign(u.style,{color:m.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const b=f.ownerDocument.createElement("span");b.textContent=String(i),r.setAttribute("aria-label",`${o.label??`W${n+1}`} \u2014 ${i} finding${i===1?"":"s"}${c?`, ${c} unusual`:""} \u2014 view wafer`),Object.assign(b.style,{marginLeft:x.sm,flexShrink:"0",background:an(s),color:"#fff",borderRadius:V.container,padding:"1px 5px",fontSize:O.body,fontWeight:"600"}),r.appendChild(u),r.appendChild(b),r.addEventListener("click",()=>Te(n,o)),h.appendChild(r)}const t=f.ownerDocument.createElement("div");t.style.height="12px",h.appendChild(t)}function j(){if(h)if(H){const e=ne(w.flatMap(n=>n?.hbinDefs??[])),t=ne(w.flatMap(n=>n?.sbinDefs??[]));ti(h,{lotSummary:H,items:w,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:fe(),passBins:ye,ringCount:d.ringCount,binColors:d.binColors,plotMode:d.plotMode??"hardBin",fallbackFormat:Ie,activeFindingId:ve,warnings:p.warnings?.display??!0?Y:[],findingsFilter:Mn,findingsNotice:kt,onFindingsFilterChange:j,onSaveText:p.onSaveText,onFindingClick:(n,o)=>{ve===n.id?ot():Rn(n,o),j()},onWaferClick:On,findingsFor:Tn,dieListOptions:p.dieList})}else $n()}function Wn(e){const t=e.highlight;return t?.kind==="wafer"&&t.waferIndices?.length?t.waferIndices:null}function Tt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}let He=[];function Lt(){if(He.length!==0){for(const e of He)S[e]?.setOptions({plotMode:d.plotMode,activeTest:d.activeTest});He=[]}}function ot(){ve=null,Bt(),Ot(),Lt(),B({highlightBin:void 0},{fireCallback:!1})}function Rn(e,t){if(ve===e.id){ot();return}ve=e.id,t.style.background=m.bgActive,t.style.fontWeight="600",Lt();const{kind:n,index:o}=e.variable;if(n==="test"){const l=o??0,a=fe();if(a===void 0||a.some(i=>i.testNumber===l))B({plotMode:"value",activeTest:l,highlightBin:void 0},{fireCallback:!1});else{B({highlightBin:void 0},{fireCallback:!1});const r=be.has(d.plotMode??"hardBin")?null:Wn(e);if(r){for(const u of r)S[u]?.setOptions({plotMode:"value",activeTest:l});He=[...r]}}}else n==="softBin"?B({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):B({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1});Bt(),Ot();const c=e.highlight;if(c.kind==="wafer"){Et(c.waferIndices);const l=Tt(e);for(const a of c.waferIndices){const r=L[a]?.statsSummary?.findings.find(u=>Tt(u)===l)?.highlight?.dieKeys;r?.length&&nt(r,[a])}}else c.kind==="bin"?c.dieKeys?.length&&nt(c.dieKeys):(c.kind==="region"||c.kind==="dies")&&c.dieKeys?.length&&nt(c.dieKeys)}function le(){if(!A)return;const e=!!h;A.style.display=(H||tt())&&e&&!Ee?"flex":"none";const t=h?h.style.display!=="none":!1;(H?.hasNotableFindings||w.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?A.style.color=m.findingIndicator:A.dataset.active||(A.style.color=m.icon)}const R=f.ownerDocument.createElement("div");R.dataset.wmapToolbar="gallery",Object.assign(R.style,{flexShrink:"0",marginLeft:"auto",display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:V.control,padding:"0",boxShadow:We.panel,flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const $t=()=>{const e=Se();e&&(e.remove(),Me(null)),Re(K,!1)},K=Z("mode","Plot mode",()=>{if(Se()){$t();return}const e=w.flatMap(y=>y?.dies??[]),t=fe(),{testEntries:n,binEntries:o,stackedEntries:c}=No(e,t,{includeStacked:!0}),l=w.filter(Boolean).length,a=y=>{if(y===void 0)return l;let $=0;for(const se of w)se?.dies?.some(X=>hn(X,y)!==void 0||X.testValues?.[y]!==void 0)&&$++;return $},s=l<2?n:n.map(y=>{const $=a(y.activeTest);return $===l?y:{...y,label:`${y.label} \u2014 ${$} of ${l} wafers`}}),i=d.plotMode??"hardBin",r=d.activeTest??0;function u(y){return y.plotMode!==i?!1:y.plotMode==="value"?r===(y.activeTest??0):y.plotMode==="metadata"?d.activeMetadataKey===y.activeMetadataKey:!0}function b(y,$){y.activeTest!==void 0?B({plotMode:"value",activeTest:y.activeTest,activeMetadataKey:void 0,logScale:y.logScale}):y.activeMetadataKey!==void 0?B({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:y.activeMetadataKey,passFailDisplay:"off"}):B({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),$.remove(),Me(null),Re(K,!1)}const M=new Set,k=w.flatMap(y=>y?.metadataFields??[]).filter(y=>!M.has(y.key)&&M.add(y.key)).filter(y=>_o(e,y.key)).map(Go),D=ko(K.getBoundingClientRect(),s,o,c,u,b,{makeMenuRow:kn,makeMenuSection:En},i,K.ownerDocument.defaultView??window,k);cn(K).appendChild(D),Me(D),Re(K,!0),fn(D,K,$t)});Re(K,!1);const In=()=>L.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:An,sync:Wt}=Ro(ue,()=>({...d,plotMode:d.plotMode??"hardBin"}),In,e=>B(e));Wt();const Pn=C.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function je(){const e=fe(),{testNumber:t}=co(d.activeTest??0,e);return{testNumber:t,td:fo(e,t)}}function Rt(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=je();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function De(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=je();return e!==void 0&&!bt(e)}function Fn(){if((d.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=je();return w.some(n=>n?.dies?.some(o=>hn(o,e,t)!==void 0))}function Hn(e,t){if(!t||!bt(t))return;const n=t.limitLow!==void 0||t.limitHigh!==void 0;if((gn(d)==="spec"&&n?"spec":d.colorbarRangeMode??"spec")==="spec"&&n)return;let l=1/0,a=-1/0;for(const s of w)if(s)for(const i of s.dies){const r=Zo(i,e);r!==void 0&&(r<l&&(l=r),r>a&&(a=r))}if(isFinite(l))return l===a?[l,l+1]:[l,a]}function It(){if((d.plotMode??"hardBin")!=="metadata")return;const e=d.activeMetadataKey;if(!e)return;const t=new Set;for(const n of w)if(n)for(const o of uo(n.dies,e))t.add(o);return{key:e,values:[...t].sort(bn)}}function it(){const e=It();if(!(e===void 0&&d.metadataValueOrder===void 0)){d={...d,metadataValueOrder:e};for(const t of S)t&&t.setOptions({metadataValueOrder:e})}}function lt(){if((d.plotMode??"hardBin")!=="value")return;const{testNumber:e,td:t}=je(),n=Hn(e,t),o=n?{test:e,range:n}:void 0;d={...d,valueRange:o};for(const c of S)c&&c.setOptions({valueRange:o})}let at=!1;function jn(){if(at)return;at=!0,(f.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{at=!1,lt(),it(),At()})}function Ve(){const e=ne(w.flatMap(o=>o?.hbinDefs??[])),t=ne(w.flatMap(o=>o?.sbinDefs??[]));function*n(){for(const o of w)o&&(yield*o.dies)}return go(n(),{passBins:ye,binColorScheme:d.binColorScheme,useDefinedBinColors:d.useDefinedBinColors,hbinDefs:e,sbinDefs:t})}function At(){const e=Ve();d={...d,binColors:e};for(const t of S)t&&t.setOptions({binColors:e})}const Vn=Po(ue,()=>jo(d,Pn,{functionalActive:De(),hasLimits:Rt()&&!De(),hasRecorded:Fn()&&!De(),binMode:(d.plotMode??"hardBin")==="hardBin"||(d.plotMode??"hardBin")==="softBin"},e=>B(e)),()=>Vo(d)),{btn:zn,sync:Pt}=Ao(ue,()=>({plotMode:d.plotMode,legendPosition:we}),e=>{we=e;for(const t of S)t&&t.setOptions({legendPosition:we})},{get:()=>Ae,set:e=>{Ae=e,xt()},blockedReason:xe});Pt();const Nn=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],Ft=Mt("aggr","Aggregation method",()=>Nn,()=>d.aggregationMethod??"mean",e=>B({aggregationMethod:e}));function Ht(){const e=d.plotMode==="stackedValues";Ft.style.display=e?"":"none"}Ht();const{btn:_n,sync:jt}=Io(ue,()=>({...d,functionalActive:De()}),e=>B(e));jt();const ze=Z("specRange","Colorbar range: spec limits",()=>{const e=d.colorbarRangeMode==="data"?"spec":"data";B({colorbarRangeMode:e})});function Vt(){const e=(d.plotMode??"hardBin")==="value"&&Rt()&&gn(d)==="off"&&!De();ze.style.display=e?"":"none";const t=(d.colorbarRangeMode??"spec")==="spec";Ce(ze,t),ze.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}Vt();const Gn=Fo(ue,()=>d,e=>B(e)),Kn=Z("downloadAll","Download gallery PNG",ao),qn=Mt("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>v!=null?String(v):"auto",e=>Yt(e==="auto"?void 0:Number(e))),E=f.ownerDocument.createElement("div");Object.assign(E.style,{display:"inline-flex",alignItems:"center",gap:"0"}),R.appendChild(E),T&&E.appendChild(K),E.appendChild(An),E.appendChild(Ft),E.appendChild(_n),E.appendChild(ze),E.appendChild(N()),E.appendChild(Vn),E.appendChild(N()),E.appendChild(zn),E.appendChild(N()),E.appendChild(Gn),E.appendChild(N()),E.appendChild(qn),E.appendChild(N()),E.appendChild(Kn),(H||tt())&&(A=Z("findings","Summary panel",()=>{if(!h)return;const e=h.style.display!=="none";e||j(),h.style.display=e?"none":"flex",Ce(A,!e),le()}),R.appendChild(N()),R.appendChild(A));let _=null,Ne=null,Y=[],zt=!1;function _e(){const e=Yo({lotStatsSummary:H,result:{warnings:[...w.flatMap(n=>n?.warnings??[]),...vt().warnings]},extra:[d.binColors&&mo(d.binColors,d.plotMode)].filter(n=>!!n)}),t=e.length!==Y.length||e.some((n,o)=>n.code!==Y[o]?.code||n.message!==Y[o]?.message);Y=e,(t||!zt)&&(zt=!0,p.warnings?.onWarning?.(e)),Un()}function Un(){if(!_||!Ne)return;const e=Y.length,t=e>0;if(_.style.display=t?"flex":"none",Ne.style.display=t?"":"none",!t)return;const n=Jo(Y[0]),o=`${e} data ${e===1?"warning":"warnings"}`;_.style.color=n==="error"?m.errText:m.warnText,_.ariaLabel=n==="error"?`${o} \u2014 some wafers may be positionally wrong`:o}(p.warnings?.display??!0)&&(Ne=N(),_=Z("warning","Data warnings",()=>{const e=Se();if(Fe(new MouseEvent("click")),e)return;const t=Qo(_.getBoundingClientRect(),Y,_.ownerDocument.defaultView??window);cn(f).appendChild(t),Me(t),fn(t,_,()=>Fe(new MouseEvent("click")))}),Re(_,!1),R.appendChild(Ne),R.appendChild(_)),_e();let ae=null;re&&(ae=Z("analysis","Insights",()=>{Gt(!Ee)}),ae.dataset.wmapInsightsBtn="1",R.appendChild(N()),R.appendChild(ae));function Nt(){import("./userGuideHtml.js").then(e=>Wo({buildWaferMap:Xo,renderWaferMap:ht,renderWaferGallery,analyzeWaferMap:Ye},e.USER_GUIDE_HTML,Je,f))}oe&&(R.appendChild(N()),R.appendChild(Z("help","User guide",()=>Nt())));const pe=f.ownerDocument.createElement("div");pe.dataset.wmapGalleryMeta="1",Object.assign(pe.style,{flex:"1",minWidth:"0",overflow:"hidden",display:"flex",alignItems:"center",padding:`${x.sm} ${x.lg}`,fontSize:O.sub,lineHeight:Ze.none,boxSizing:"border-box"});const Ge=f.ownerDocument.createElement("div");Object.assign(Ge.style,{background:m.canvasBg,display:"flex",alignItems:"stretch",gap:x.lg,paddingBottom:x.lg,minWidth:"0"});const Q=f.ownerDocument.createElement("div");Q.dataset.wmapGalleryLegend="1",Object.assign(Q.style,{display:"flex",flexDirection:"column",gap:x.sm,background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:V.container,padding:`${x.sm} ${x.lg}`,marginBottom:x.lg,boxShadow:We.panel,fontSize:O.body,lineHeight:Ze.none,boxSizing:"border-box",width:"100%",minWidth:"0"});const G=f.ownerDocument.createElement("div");Object.assign(G.style,{display:"flex",flexDirection:"row",alignItems:"flex-start"});let ge=null,ke=null,_t=null;function Xn(){return re?ge?Promise.resolve(ge):(_t??=import("./insightsTab.js").then(({createInsightsTab:e})=>(ge=e({getItems:()=>w,getLotStats:()=>H,getBinColors:()=>d.binColors??Ve(),passBins:ye,getRingCount:()=>d.ringCount??4,defaultView:p.insights?.defaultView,onOpenGuide:void 0,showMetadataStrip:!1,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,ownerDocument:f.ownerDocument,openWafer:(t,n,o)=>{const c=w[t];if(!c)return;let l=null;const a=Oo({title:n,onClose:()=>l?.destroy(),anchor:f});en(a,n,c.wafer.metadata??void 0),l=ft(a.contentWrap,c,o)}}),ke=ge.el,ke.style.display="none",f.appendChild(ke),ge)),_t):Promise.resolve(null)}let Ee=!1;function Gt(e){re&&(Ee=e,ke&&(ke.style.display=e?"flex":"none"),G.style.display=e?"none":"flex",E.style.display=e?"none":"inline-flex",R.style.display="inline-flex",ae&&(Ce(ae,e),ae.innerHTML=e?$e.wafer:$e.analysis,ae.ariaLabel=e?"Back to gallery view":"Insights"),le(),Ue(),e&&Xn().then(t=>{!t||!Ee||(t.el.style.display="flex",t.render())}))}re&&p.insights?.defaultOpen&&queueMicrotask(()=>Gt(!0));const Zn=4,st=240,Kt=480,Yn=720,Qn=1.25,qt=p.maxSize;let q=qt??Kt;function Ut(e){const t=P*2+110+2;let n=null;for(const o of e){if(o==null||!o.dies?.length)continue;const c=o.dies[0].width;if(!(c>0))continue;const l=o.wafer.radius*2*(Zn/c),a=Math.ceil(l+t);(n==null||a>n)&&(n=a)}return n}function Jn(e){const t=Ut(e);return t==null?st:Math.min(q,Math.max(st,t))}function eo(e){if(qt!=null)return!1;const t=Ut(e);if(t==null)return!1;const n=Math.min(Yn,Math.max(Kt,t));return n<=q?!1:(q=n,!0)}function to(){for(const e of Array.from(I.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${q}px`,e.style.maxHeight=`${q}px`)}let Ke=st,Xt=0;function Zt(e){const t=eo(e);if(t&&to(),v!=null){t&&qe();return}const n=Jn(e);n>Ke&&(Ke=n),qe()}function Yt(e){v=e,qe()}function rt(e){return`repeat(${e}, minmax(0, ${q}px))`}function Qt(e){I.style.gridTemplateColumns!==e&&(I.style.gridTemplateColumns=e)}function qe(){if(v!=null){Qt(rt(v));return}const e=Math.max(1,Xt),t=12,n=I.clientWidth||0,o=l=>(n-t*(l-1))/l;let c=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){const l=Math.min(q,Ke*Qn),a=s=>{let i=0;for(;i<e&&o(i+1)>=s;)i++;return i};c=a(l)||a(Ke)||1}Qt(rt(c))}const I=f.ownerDocument.createElement("div");if(Object.assign(I.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:rt(1),gap:x.xl,paddingLeft:te,paddingRight:te,justifyContent:"start",alignContent:"start",isolation:"isolate"}),de?.placement){const e=de.placement;h=yt(e,te,f.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.display="flex",h.style.flexDirection="column"}else if(H||tt()){const e=!!de?.defaultOpen;h=yt("right",te,f.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display=e?"flex":"none",j()}le(),h?.style.display!=="none"&&A&&Ce(A,!0),(de?.placement??"right")==="left"?(h&&G.appendChild(h),G.appendChild(I)):(G.appendChild(I),h&&G.appendChild(h));const Be=f.ownerDocument.createElement("div");Object.assign(Be.style,{position:"sticky",top:"0",display:"flex",flexDirection:"column",paddingLeft:te,paddingRight:te,paddingTop:te,zIndex:"1",background:m.menuBg}),Ge.appendChild(pe),Ge.appendChild(R),Be.appendChild(Ge),Be.appendChild(Q),f.appendChild(Be),f.appendChild(G);function Ue(){Q.innerHTML="";const e=d.plotMode??"hardBin",t=!Ee&&sn.has(e),n=L.filter(g=>g!=null),o=n.find(g=>g.isLotStack),c=ei(n.map(g=>({metadata:g.wafer.metadata??void 0})),o?{lotSize:o.lotSize??n.length,aggrMethod:o.aggrMethod}:void 0),l=e==="metadata",a=d.activeMetadataKey,s=t&&!l?xn(n,g=>(e==="softBin"?g.sbin:g.hbin)??void 0):{counts:new Map,total:0},i=[...s.counts.keys()].sort((g,W)=>g-W),r=t&&l&&a?xn(n,g=>po(g.metadata?.[a])):{counts:new Map,total:0},u=l?It()?.values:void 0,b=t&&l?(u??[...r.counts.keys()].sort(bn)).filter(g=>r.counts.has(g)):[];if(pe.innerHTML="",c&&pe.appendChild(c),pe.style.display=c?"flex":"none",!i.length&&!b.length){Q.style.display="none";return}Q.style.display="flex";const M=f.ownerDocument.createElement("div");Object.assign(M.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:`${x.sm} ${x.xl}`,maxHeight:"86px",overflowY:"auto",overflowX:"hidden"}),Q.appendChild(M);const k=d.highlightBin,D=L.flatMap(g=>g?.metadataFields??[]).find(g=>g.key===a),y=l?D?.label??(a?oi(a):"Metadata"):Co[e],$=f.ownerDocument.createElement("span");if($.textContent=y,Object.assign($.style,{fontSize:O.body,fontWeight:"700",letterSpacing:wo,textTransform:"uppercase",color:m.label,flexShrink:"0"}),M.appendChild($),!l&&s.total>0){const g=ye.reduce((he,pt)=>he+(s.counts.get(pt)??0),0),W=g/s.total*100,J=f.ownerDocument.createElement("span");J.textContent=`Yield ${Qe(W)}`,Object.assign(J.style,{fontSize:O.body,fontWeight:"700",color:m.value,whiteSpace:"nowrap",flexShrink:"0"});const ee=f.ownerDocument.createElement("span");ee.textContent=`${g.toLocaleString()} / ${s.total.toLocaleString()} dies`,Object.assign(ee.style,{fontSize:O.body,color:m.label,whiteSpace:"nowrap",flexShrink:"0"}),M.appendChild(J),M.appendChild(ee)}if(l){const g=d.highlightMetadataValue;b.forEach((W,J)=>{const ee=g===W,he=D?.values?.find(gt=>gt.value===W),pt=he?.color??bo(J),ln=r.counts.get(W)??0;vn(M,{color:pt,isActive:ee,label:he?.label??W,count:ln,percent:r.total>0?ln/r.total*100:void 0,onClick:()=>{const gt=d.highlightMetadataValue===W?void 0:W;B({highlightMetadataValue:gt})}})});return}const se=e==="softBin"?L.flatMap(g=>g?.sbinDefs??[]):L.flatMap(g=>g?.hbinDefs??[]),X=new Set,Le=[];for(const g of se)X.has(g.bin)||(X.add(g.bin),Le.push(g));const ut=Le.length>0?new Map(Le.map(g=>[g.bin,g])):null,nn=d.binColors??Ve(),so=e==="softBin"?nn.soft:nn.hard,on=g=>so.get(g)??ho;for(const g of i){const W=k===g,J=ut?.get(g),ee=s.counts.get(g)??0;vn(M,{color:on(g),isActive:W,label:J?.name?`${g} \xB7 ${J.name}`:`Bin ${g}`,count:ee,percent:s.total>0?ee/s.total*100:void 0,onClick:()=>{const he=d.highlightBin===g?void 0:g;B({highlightBin:he})}})}s.total>0&&i.length>1&&Q.appendChild(si(f.ownerDocument,[...s.counts.entries()].sort(([,g],[,W])=>W-g).map(([g,W])=>({color:on(g),count:W,label:ut?.get(g)?.name?`${g} \xB7 ${ut.get(g).name}`:`Bin ${g}`})),s.total))}function Oe(e){const t=w.filter(s=>s!==null);if(!t.length)return[];const n=t.map(s=>s.dies.filter(ai)),o=t[0].wafer,c=t.length,l=o.metadata?{...o,metadata:(({wafer:s,waferId:i,...r})=>r)(o.metadata)}:o;function a(s,i){return{...s,stats:{...s.stats,isLotStack:!0,aggregationMethod:i,lotSize:c}}}if(e==="stackedValues"){const s=fe();let i=s?.filter(bt);if(s!==void 0&&i?.length===0)return[];if(s?.length||(i=ro(t.flatMap(b=>b.dies)).map(b=>({testNumber:b,name:`Test ${b}`}))),!i?.length)return[];const r=d.aggregationMethod??"mean";return i.map(u=>{const b=Ko(n,r,u.testNumber),M={testNumber:0,name:u.name,unit:u.unit};return{wafer:l,dies:b,testDefs:[M],label:`${u.name} \xB7 ${r}`,isLotStack:!0,aggrMethod:r,lotSize:c,statsSummary:a(Ye({wafer:l,dies:b,testDefs:[M]},{testNumbers:[0]}),r)}})}if(e==="stackedBins"){let s=ne(t.flatMap(i=>i.hbinDefs??[]));return(!s||s.length===0)&&(s=[...new Set(t.flatMap(r=>r.dies.map(u=>u.hbin).filter(u=>u!=null)))].sort((r,u)=>r-u).map(r=>({bin:r,name:`Bin ${r}`}))),s.map(i=>{const r=mn(n,i.bin,"hard"),u=[{bin:i.bin,name:i.name}];return{wafer:l,dies:r,hbinDefs:u,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:c,statsSummary:a(Ye({wafer:l,dies:r,hbinDefs:u}),"countBin")}})}if(e==="stackedSoftBins"){let s=ne(t.flatMap(i=>i.sbinDefs??[]));return(!s||s.length===0)&&(s=[...new Set(t.flatMap(r=>r.dies.map(u=>u.sbin).filter(u=>u!=null)))].sort((r,u)=>r-u).map(r=>({bin:r,name:`Bin ${r}`}))),s.map(i=>{const r=mn(n,i.bin,"soft"),u=[{bin:i.bin,name:i.name}];return{wafer:l,dies:r,sbinDefs:u,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:c,statsSummary:a(Ye({wafer:l,dies:r,sbinDefs:u}),"countBin")}})}return t}function dt(e){const t=w.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:d.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}function B(e,{fireCallback:t=!0}={}){const n=Object.keys(e),o=d.plotMode,c=xe()!==null;d={...d,...e};const l=d.plotMode,a=be.has(l),s=o!==void 0&&be.has(o),i=Pe>0;if("binColorScheme"in e||"useDefinedBinColors"in e){const u=Ve();d={...d,binColors:u},e={...e,binColors:u}}if(e.plotMode!==void 0)if(a){const u=dt(l);if(d={...d,...u},i)for(const b of S)b&&b.setOptions(e);else U(Oe(l))}else if(s){const{valueRange:u,lotSize:b,aggregationMethod:M,...k}=d;if(d=k,i)for(const D of S)D&&D.setOptions(e);else U(w.filter(D=>D!==null))}else for(const u of S)u&&u.setOptions(e);else if(e.aggregationMethod!==void 0&&l==="stackedValues")if(i)for(const u of S)u&&u.setOptions(e);else U(Oe("stackedValues"));else for(const u of S)u&&u.setOptions(e);xe()!==null!==c&&xt(),Ue(),Ht(),Pt(),Wt();const r=e.plotMode!==void 0&&e.plotMode!==o;(Uo.some(u=>u in e)||r)&&j(),_e(),jt(),Vt(),lt(),it(),t&&p.onViewOptionsChange?.(d,n,qo(n))}function Jt(e,t,n){const o=e.createElement("div");Object.assign(o.style,{display:"flex",alignItems:"center",gap:x.xs,flex:"1",minWidth:"0"});const c=e.createElement("span");c.textContent=t,Object.assign(c.style,{fontWeight:"700",fontSize:O.sub,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(c);const l=wn(n??{});let a=null;if(l.length>0){const s=e.createElement("span");Object.assign(s.style,{fontSize:O.body,lineHeight:Ze.none,color:m.label,flexShrink:"0"}),s.textContent="\u25BE",o.appendChild(s),Object.assign(o.style,{cursor:"pointer",borderRadius:V.control}),o.addEventListener("mouseenter",()=>{o.style.background=m.bgHover}),o.addEventListener("mouseleave",()=>{o.style.background="none"}),a=e.createElement("div"),a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:rn,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:We.menu,padding:`${x.md} ${x.lg}`,fontSize:O.body,display:"none"});const i=yn(n??{});i&&a.appendChild(i),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),un(o,r=>{s.textContent=r?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(r)),a&&(a.style.display=r?"block":"none")})}return{wrap:o,metaPanel:a}}function en(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),c=wn(n??{});if(!o||c.length===0)return;const l=o.parentElement,a=f.ownerDocument.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:x.xs,flex:"1",minWidth:"0",cursor:"pointer"}),mt(a,"bare"),l?.insertBefore(a,o),a.appendChild(o);const s=f.ownerDocument.createElement("span");Object.assign(s.style,{fontSize:O.body,lineHeight:Ze.none,color:m.label,flexShrink:"0"}),s.textContent="\u25BE",a.appendChild(s);const i=f.ownerDocument.createElement("div");i.dataset.wmapCardMetaPanel="1",Object.assign(i.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:rn,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:We.menu,padding:`${x.md} ${x.lg}`,fontSize:O.body,display:"none"});const r=yn(n??{});r&&i.appendChild(r),e.contentWrap.style.position="relative",e.contentWrap.appendChild(i),a.setAttribute("aria-expanded","false"),a.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),un(a,u=>{s.textContent=u?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(u)),i.style.display=u?"block":"none"})}function ct(e,t,n){const o=f.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:V.container,boxShadow:We.panel,overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${q}px`,maxHeight:`${q}px`});const c=f.ownerDocument.createElement("div");Object.assign(c.style,{display:"flex",alignItems:"center",padding:`${x.md} ${x.lg} ${x.sm}`,borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:x.sm});const{wrap:l,metaPanel:a}=Jt(document,e.label??"",e.wafer.metadata??void 0);c.appendChild(l);const s=f.ownerDocument.createElement("button");s.dataset.wmapExpandBtn="1",s.setAttribute("aria-label","Open full view"),pn(s),s.innerHTML=$e.expand,Object.assign(s.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${m.menuBorder}`,borderRadius:V.control,background:m.panelBg,color:m.label,padding:x.xxs,cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),mt(s),c.appendChild(s),o.appendChild(c);const i=f.ownerDocument.createElement("div");Object.assign(i.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),o.appendChild(i),a&&i.appendChild(a),I.appendChild(o);const r=Ae||xe()!==null,u=e.viewOptions?{...d,...e.viewOptions}:d,b=ht(i,e,{viewOptions:{...u,showLegend:r},toolbarControls:"full",showTooltip:!0,padding:P,legendPosition:we,fallbackFormat:Ie,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>Te(t,e),showIdentity:!1,chromeInset:vo});return b.setViewControlsVisible(!1),b.setSummaryVisible(!1),s.onclick=()=>Te(t,e),{card:o,ctrl:b,canvasWrapper:i,expandBtn:s}}function no(e){const t=ce[e];if(!t)return;const n=[...z.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=$e.minimize,t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>io(n.id)):(t.innerHTML=$e.expand,t.setAttribute("aria-label","Open full view"),t.onclick=()=>Te(e,L[e]))}function U(e){lo(),Se()?.remove(),Me(null),ot(),L=[];for(const l of S)l&&l.destroy();S=[],ie=[],ce=[],Pe=0,I.innerHTML="",Xt=e.length,Zt(e.map(l=>typeof l=="function"?null:l));const t=[];for(let l=0;l<e.length;l++){const a=e[l];if(typeof a=="function"){const s=f.ownerDocument.createElement("div");s.className="wmap-gallery-card",Object.assign(s.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:V.container,aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const i=f.ownerDocument.createElement("span");i.textContent="\u2026",Object.assign(i.style,{color:m.label,fontSize:"18px"}),s.appendChild(i),I.appendChild(s),L.push(null),S.push(null),ie.push(null),ce.push(null),t.push({index:l,factory:a,placeholder:s}),Pe++}else{const{ctrl:s,canvasWrapper:i,expandBtn:r}=ct(a,l,e.length);L.push(a),S.push(s),ie.push(i),ce.push(r)}}At(),Ue(),lt(),it();const n=++et;let o=0;function c(){if(n!==et)return;if(o>=t.length){if(be.has(d.plotMode)){const k=d.plotMode;U(Oe(k))}return}const{index:l,factory:a,placeholder:s}=t[o++],i=a();L[l]=i,w[l]=i,Zt([i]);const{card:r,ctrl:u,canvasWrapper:b,expandBtn:M}=ct(i,l,e.length);S[l]=u,ie[l]=b,ce[l]=M,Pe--,s.replaceWith(r),Ue(),jn(),!h&&!de?.placement&&i.statsSummary?.findings.length?(h=yt("right",te,f.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display="none",(de?.placement??"right")==="left"?G.insertBefore(h,I):G.appendChild(h),j(),A||(A=Z("findings","Summary panel",()=>{if(!h)return;const D=h.style.display!=="none";D||j(),h.style.display=D?"none":"flex",Ce(A,!D),le()}),R.appendChild(N()),R.appendChild(A)),le()):h&&h.style.display!=="none"&&j(),le(),setTimeout(c,0)}t.length>0&&setTimeout(c,0)}if(be.has(d.plotMode)&&w.length>0){const e=dt(d.plotMode);d={...d,...e},U(Oe(d.plotMode))}else U(C);_e();let me=0;const tn=new(f.ownerDocument.defaultView??window).ResizeObserver(()=>{if(me)return;me=(f.ownerDocument.defaultView??window).requestAnimationFrame(()=>{me=0,v==null&&qe()})});tn.observe(I),h&&j();function oo(e,t){const n=ie[e];if(!n)return;n.innerHTML="",Object.assign(n.style,{alignItems:"center",justifyContent:"center"});const o=f.ownerDocument.createElement("span");o.textContent=t?"Opened in its own window":"Opened in the wafer viewer",Object.assign(o.style,{color:m.label,fontSize:O.body,textAlign:"center",padding:"0 12px"}),n.appendChild(o)}function Te(e,t){for(const a of z.values())if(a.cardIndex===e)return;const n=t.label??"Wafer map",o=Sn++,c=S[e]?.getOptions(),l=Eo(n);if(l){const a=l.document;a.title=n,Object.assign(a.documentElement.style,{height:"100%"}),Object.assign(a.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:O.family}),Lo(f,a.documentElement);const s=$o(f,a.documentElement,()=>D.setOptions({})),i=a.createElement("div");i.dataset.wmapWindowBanner="1",i.textContent=n,Object.assign(i.style,{display:"none",padding:`${x.sm} ${x.xl}`,fontSize:O.body,fontWeight:"700",background:m.warnBg,color:m.warnText,borderBottom:`1px solid ${m.warnBorder}`,flexShrink:"0"}),a.body.appendChild(i);const r=a.createElement("div");Object.assign(r.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),a.body.appendChild(r);const{wrap:u,metaPanel:b}=Jt(a,n,t.wafer.metadata??void 0),M=a.createElement("div");Object.assign(M.style,{display:"flex",alignItems:"center",padding:`${x.md} ${x.lg} ${x.sm}`,borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:x.sm}),M.appendChild(u),r.appendChild(M);const k=a.createElement("div");Object.assign(k.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),b&&k.appendChild(b),r.appendChild(k);const D=ft(k,t,void 0,c),y=setInterval(()=>{l.closed&&Xe(o)},400);l.addEventListener("pagehide",()=>Xe(o)),z.set(o,{id:o,ctrl:D,cardIndex:e,label:n,closePollId:y,stopThemeSync:s,close:()=>{l.closed||l.close()},setTitle:$=>{a.title=$,i.textContent=$,i.style.display="block"}})}else{const a=Bo({title:n,onClose:()=>Xe(o),anchor:f});a.contentWrap.style.flexDirection="column",en(a,n,t.wafer.metadata??void 0);const s=ft(a.contentWrap,t,void 0,c);z.set(o,{id:o,ctrl:s,cardIndex:e,label:n,closePollId:null,close:()=>a.close(),setTitle:i=>{const r=a.box.querySelector("[data-wmap-window-title]");r&&(r.textContent=i,r.title=i)}})}S[e]?.destroy(),S[e]=null,oo(e,l!==null),no(e)}function ft(e,t,n,o){const c=t.viewOptions?{...d,...t.viewOptions}:d,l=o?{...c,...o}:c,s={...n!==void 0?{...l,plotMode:"value",activeTest:n}:l,showLegend:!0},i=ht(e,t,{viewOptions:s,toolbarControls:"full",showTooltip:!0,padding:P,legendPosition:we,fallbackFormat:Ie,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showIdentity:!1});return i.setViewControlsVisible(!0),i.setSummaryVisible(!0),i.setExpandVisible(!1),i}function Xe(e){const t=z.get(e);if(!t)return;z.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const o=t.cardIndex,c=L[o];if(!c)return;const l={...c,viewOptions:n};L[o]=l;const{card:a,ctrl:s,canvasWrapper:i,expandBtn:r}=ct(l,o,L.length);ie[o]?.parentElement?.replaceWith(a),S[o]=s,ie[o]=i,ce[o]=r}function io(e){const t=z.get(e);t&&(t.close(),Xe(e))}function lo(){for(const e of z.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function ao(){const e=[...I.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),o=Math.ceil(t/n),c=e[0].width,l=e[0].height,a=8,s=(f.ownerDocument.defaultView??window).devicePixelRatio||1,i=Math.round(26*s),r=Math.round(12*s),u=f.ownerDocument.createElement("canvas");u.width=n*c+(n-1)*a,u.height=o*(l+i)+(o-1)*a;const b=u.getContext("2d"),M=yo(I);b.fillStyle=M.background,b.fillRect(0,0,u.width,u.height),e.forEach((k,D)=>{const y=D%n,$=Math.floor(D/n),se=y*(c+a),X=$*(l+i+a),Le=k.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";b.fillStyle=M.surface,b.fillRect(se,X,c,i),b.fillStyle=M.text,b.font=`700 ${r}px system-ui, sans-serif`,b.textAlign="left",b.textBaseline="middle",b.fillText(Le,se+Math.round(10*s),X+i/2,c-Math.round(20*s)),b.drawImage(k,se,X+i)}),u.toBlob(k=>{k&&Ho(k,F,p.onSaveImage)})}return{setItems(e){w=e.map(n=>typeof n=="function"?null:n);const t=d.plotMode;if(be.has(t))if(e.some(o=>typeof o=="function"))U(e);else{const o=dt(t);d={...d,...o},U(Oe(t))}else U(e)},setOptions(e){B(e,{fireCallback:!1})},getOptions(){return{...d}},setFallbackFormat(e){Ie=e;for(const t of S)t&&t.setFallbackFormat(e)},setFindingsNotice(e){kt=e,j()},setLotStatsSummary(e){H=e,_e(),h&&j(),le()},setColumns(e){Yt(e)},openUserGuide:Nt,destroy(){et++;for(const e of[...z.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();z.clear();for(const e of S)e&&e.destroy();S=[],Se()?.remove(),tn.disconnect(),me&&((f.ownerDocument.defaultView??window).cancelAnimationFrame(me),me=0),f.ownerDocument.removeEventListener("click",Fe,!0),window.removeEventListener("blur",Dt),Cn(),dn(),Be.remove(),G.remove(),h?.remove(),ge?.destroy()}}}
|
|
1
|
+
import{getUniqueTestNumbers as bo,resolveTestNumber as yo,findTestDef as wo,collectMetadataValues as xo}from"../renderer/buildView.js";import{metadataCategoricalValue as vo}from"../core/metadata.js";import{resolveBinColorsForMaps as Co,mergeBinDefs as Ke,binColorWarning as So,mixedPassBinsWarning as Mo}from"../renderer/binColors.js";import{itemPassBins as Do,INPUT_DEFAULT_PASS_BINS as Bo}from"../core/passBins.js";import{NO_DATA_FILL as ko}from"../renderer/colorMap.js";import{metadataValueColor as Eo}from"../renderer/colorMap.js";import{resolveCanvasTheme as Oo}from"./canvasTheme.js";import{ICONS as Te}from"./icons.js";import{SHADOW as Le,LEADING as qe,TRACKING as To,controlStyle as Lo,wireControlHover as ht,SPACE as w,EDGE_GUTTER as oe,MAP_CHROME_INSET as $o,RADIUS as N,FONT as T,CLR as g,sevColor as cn,MODE_LABELS as Wo,BIN_LEGEND_MODES as un,STACKED_MODES as ge,Z_ABOVE as fn,applyOverlayZ as Ro,getTooltip as Io,hideTooltip as pn,createToolbarHelpers as Ao,buildModeMenuEl as Po,openDetachWindow as Fo,openFloatingWindow as Ho,openModal as jo,openReportModal as Vo,copyWmapThemeTokens as zo,syncWmapPopupTheme as No,openUserGuideWindow as _o,makePaletteBtn as Go,makeLogScaleBtn as Ko,makeLegendStyleBtn as qo,makeOverlaysBtn as Uo,makeOrientationBtn as Xo,menuLayerFor as mn,saveImageBlob as gn,markMenuTrigger as $e,wireMenuA11y as hn,wireExpandToggle as bn,wireTooltip as yn,requestedPassFailDisplay as wn,overlayMenuRows as Zo,anyOverlayActive as Yo,logWmapVersionOnce as Qo,buildDataModeEntries as Jo,metadataKeyHasData as ei,metadataModeEntry as ti}from"./toolbar.js";import{waferDisplayLabel as Ue,waferIdentityLabel as ni}from"../core/waferLabel.js";import{metadataDisplayValue as oi}from"../core/metadata.js";import{withExportContext as ii,noticeDownloadFilenameChange as ai}from"./exportName.js";import{sortBinsForDisplay as li}from"../stats/binPareto.js";import{diePassStatus as si}from"../core/dies.js";import{aggregateValues as ri,aggregateBinCounts as xn}from"../core/aggregates.js";import{renderWaferMap as di,renderWaferMapCard as vn,toPublicViewOptions as Cn}from"./renderWaferMap.js";import{classifyChanged as ci,COLOR_KEYS as ui}from"./renderWaferMap.js";import{buildWaferMap as fi,getTestPassStatus as Sn,isParametricTest as bt,getDieTestValue as pi}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Xe}from"../stats/analyzeWaferMap.js";import{collectWarnings as mi,buildWarningsMenuEl as gi,severityOf as hi}from"./warnings.js";import{compareNatural as yt}from"../core/utils.js";import{createSummaryPanelEl as wt,buildMetadataStripRow as bi,buildCompactMetadataRows as Mn,metadataEntries as Dn,renderLotSummaryContent as yi,reportMapsFromItems as wi}from"./summaryPanel.js";import{renderLotReportHtml as xi}from"../stats/renderSummaryReport.js";import{prettyKey as vi}from"../stats/facets.js";import{mergeTestDefs as Ci}from"../stats/mergeTestDefs.js";import{getDieKey as Si,hasPosition as Mi}from"../core/dies.js";function Bn(u){if(typeof u!="number"||!Number.isFinite(u))return;const v=Math.round(u);return v>=1?v:void 0}const xt=12;function Di(u,v,p){let A=v;if(v.length>xt){const D=v.slice(0,xt-1),$=v.slice(xt-1),H=$.reduce((Y,j)=>Y+j.count,0);A=[...D,{color:g.label,count:H,label:`Other (${$.length} bins)`}]}const M=u.createElement("div");Object.assign(M.style,{display:"flex",columnGap:"1px",width:"100%",height:"8px",borderRadius:N.control,overflow:"hidden",border:`1px solid ${g.menuBorder}`,boxSizing:"border-box",marginTop:w.xs,flexShrink:"0"}),M.setAttribute("role","img"),M.setAttribute("aria-label",`Population split: ${A.map(D=>`${D.label} ${Ze(D.count/p*100)}`).join(", ")}`);for(const D of A){const $=D.count/p*100,H=u.createElement("div");Object.assign(H.style,{flex:`${$} 1 0`,minWidth:$>0?"2px":"0",background:D.color}),yn(H,`${D.label} \xB7 ${D.count.toLocaleString()} dies \xB7 ${Ze($)}`),M.appendChild(H)}return M}function Ze(u){return u>0&&u<.1?"<0.1%":`${u.toFixed(1)}%`}function kn(u,v,p){const A=new Map;let M=0,D=0;for(const $ of u){const H=p?new Set(p($)):void 0;for(const Y of $.dies){if(Y.partial||Y.edgeExcluded)continue;const j=v(Y);j!==void 0&&(A.set(j,(A.get(j)??0)+1),M++,H&&si(Y,H)&&D++)}}return{counts:A,total:M,pass:D}}function En(u,v){const p=u.ownerDocument.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:`${w.xxs} ${w.xs}`,borderRadius:N.control});const A=u.ownerDocument.createElement("span");Object.assign(A.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:v.color,border:v.isActive?`2px solid ${g.iconActive}`:`1px solid ${g.menuBorder}`,borderRadius:N.control,boxSizing:"border-box"});const M=u.ownerDocument.createElement("span");if(M.textContent=v.label,Object.assign(M.style,{fontWeight:v.isActive?"700":"400",color:v.isActive?g.iconActive:g.text,whiteSpace:"nowrap"}),p.appendChild(A),p.appendChild(M),v.count!==void 0){const D=u.ownerDocument.createElement("span");if(D.textContent=v.count.toLocaleString(),Object.assign(D.style,{color:v.isActive?g.iconActive:g.text,fontWeight:v.isActive?"700":"400",whiteSpace:"nowrap"}),p.appendChild(D),v.percent!==void 0){const $=u.ownerDocument.createElement("span");$.textContent=Ze(v.percent),Object.assign($.style,{color:g.label,whiteSpace:"nowrap"}),p.appendChild($)}}p.setAttribute("role","button"),p.setAttribute("aria-pressed",v.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=g.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=g.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",v.onClick),p.addEventListener("keydown",D=>{(D.key==="Enter"||D.key===" ")&&(D.preventDefault(),v.onClick())}),u.appendChild(p)}export function renderWaferGallery(u,v,p={}){Qo();const A=6;let M=Bn(p.columns);const D=p.showHelpButton??!1,$=p.userGuideExtension,H=p.insights?.enabled??!1,Y=Ro(p.zIndex),j=p.summaryPanel,On=e=>[...Do(e)],vt=()=>x.flatMap(e=>e?[e.ringCount??4]:[]),Ye=()=>vt()[0]??4;function Tn(e){const t=[...new Set(e)].sort((n,o)=>n-o);return t.length<2?null:{code:"ring-count-mixed",severity:"warning",message:`These wafers were built with different ring counts (${t.join(", ")}). Each card and each wafer's findings use their own; the lot's ring yield in the Summary panel, report and Insights uses ${e[0]} rings.`}}let V=p.lotStatsSummary,he=p.viewOptions?.legendPosition??"default",We=p.perCardLegend??!1;function be(){const e=r.plotMode??"hardBin";return un.has(e)?null:r.colorbarRangeMode==="data"?"Each map has its own value range, so it keeps its own colour bar":"These wafers have no shared colour bar for value mode, so each map keeps its own"}function Ct(){const e=We||be()!==null;for(const t of S)t&&t.setOptions({showLegend:e})}let r={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},S=[],ie=[],re=[],L=[];const Re=ii(()=>{const e=L.filter(n=>n!=null);return{lots:[...new Set(e.map(n=>oi(n.wafer.metadata?.lot)).filter(n=>n!==void 0))].sort(yt),...e.length===1?{wafer:ni(e[0])}:{waferCount:e.length}}},p.onSaveImage,p.onSaveText);ai(p.downloadFilename);let x=v.map(e=>typeof e=="function"?null:e);function St(){return Ci(x)}function ye(){if(x.some(e=>e?.testDefs?.length))return St().defs}let Qe=0,Ie=0;const _=new Map;let Ln=0,P=null,we=null,Mt=new Set,h=null,$n={};function Dt(e){return x[e]?.statsSummary??V?.perWafer.find(t=>t.waferIndex===e)?.summary}function Je(){return!!(x.some(e=>e?.statsSummary?.findings.length)||V?.perWafer.some(e=>e.summary.findings.length))}const Wn=Io(),de=Ao(Wn),{makeBtn:Q,setActive:xe,makeSep:G,makeMenuRow:Rn,makeMenuSection:In,makeDropdown:Bt,closeOpenMenu:Ae,getOpenMenu:ve,setOpenMenu:Ce}=de;u.ownerDocument.addEventListener("click",Ae,!0);const kt=()=>pn();window.addEventListener("blur",kt);let Et=p.findingsNotice;function Ot(e){Mt=new Set(e);const t=[...R.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((o,d)=>{const i=Mt.has(d);o.style.outline=i?`3px solid ${g.findingHighlight}`:"",o.style.outlineOffset=i?"-3px":"",i&&n===void 0&&(n=o)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function Tt(){Ot([])}function Lt(){for(const e of S)e&&e.clearSelection()}function et(e,t){const n=new Set(e),o=t??S.map((d,i)=>i);for(const d of o){const i=L[d],l=S[d];if(!i||!l)continue;const s=i.dies.filter(a=>n.has(Si(a)));l.setSelection(s)}}function An(){const e=[];for(let t=0;t<x.length;t++){const n=x[t];if(!n)continue;const o=Dt(t)?.findings??[];o.length&&e.push({index:t,item:n,unusualCount:o.filter(d=>d.severity==="unusual").length,notableCount:o.filter(d=>d.severity==="notable").length,totalCount:o.length})}return e}function Pn(e){const t=L[e]??x[e];t&&Oe(e,t)}function Fn(e){const t=Dt(e)?.findings??[];if(t.length)return{total:t.length,unusual:t.filter(n=>n.severity==="unusual").length,notable:t.filter(n=>n.severity==="notable").length}}function Hn(){Vo(xi(wi(x,Bo,Ye())),{anchor:u})}function jn(){if(!h)return;h.innerHTML="";const e=An();if(x.length>0){const n=u.ownerDocument.createElement("div"),o=e.length,d=x.filter(Boolean).length;n.textContent=o===0?`No findings on any of the ${d} wafers`:`${o} of ${d} wafer${d===1?"":"s"} with findings`,Object.assign(n.style,{fontSize:T.body,color:g.label,marginBottom:w.md}),h.appendChild(n)}if(e.length>0){const n=u.ownerDocument.createElement("button");n.type="button",n.textContent="Summary report",Object.assign(n.style,{...Lo("outlined"),marginBottom:w.lg,display:"block",width:"100%",textAlign:"left"}),ht(n),n.addEventListener("click",Hn),h.appendChild(n)}if(e.length===0){const n=u.ownerDocument.createElement("div");Object.assign(n.style,{color:g.icon,fontSize:T.body,padding:"4px 0"}),n.textContent="No findings on any wafer.",h.appendChild(n)}else for(const{index:n,item:o,unusualCount:d,notableCount:i,totalCount:l}of e){const s=d?"unusual":i?"notable":"info",a=d+i||l,c=u.ownerDocument.createElement("button");c.type="button",Object.assign(c.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:w.xs,border:"none",borderLeft:`3px solid ${cn(s)}`,borderRadius:N.control,background:g.bgHover,cursor:"pointer",fontSize:T.body,textAlign:"left",boxSizing:"border-box"}),c.addEventListener("mouseover",()=>{c.style.background=g.bgActive}),c.addEventListener("mouseout",()=>{c.style.background=g.bgHover});const f=u.ownerDocument.createElement("span");f.textContent=Ue(o,n),Object.assign(f.style,{color:g.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const b=u.ownerDocument.createElement("span");b.textContent=String(a),c.setAttribute("aria-label",`${Ue(o,n)} \u2014 ${a} finding${a===1?"":"s"}${d?`, ${d} unusual`:""} \u2014 view wafer`),Object.assign(b.style,{marginLeft:w.sm,flexShrink:"0",background:cn(s),color:"#fff",borderRadius:N.container,padding:"1px 5px",fontSize:T.body,fontWeight:"600"}),c.appendChild(f),c.appendChild(b),c.addEventListener("click",()=>Oe(n,o)),h.appendChild(c)}const t=u.ownerDocument.createElement("div");t.style.height="12px",h.appendChild(t)}function z(){if(h)if(V){const e=Ke(x.map(n=>n?.hbinDefs)),t=Ke(x.map(n=>n?.sbinDefs));yi(h,{lotSummary:V,items:x,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:ye(),ringCount:Ye(),binColors:r.binColors,plotMode:r.plotMode??"hardBin",fallbackFormat:r.fallbackFormat,activeFindingId:we,warnings:p.warnings?.display??!0?J:[],findingsFilter:$n,findingsNotice:Et,onFindingsFilterChange:z,onSaveText:Re.onSaveText,onFindingClick:(n,o)=>{we===n.id?tt():zn(n,o),z()},onWaferClick:Pn,findingsFor:Fn,dieListOptions:p.dieList})}else jn()}function Vn(e){const t=e.highlight;return t?.kind==="wafer"&&t.waferIndices?.length?t.waferIndices:null}function $t(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}let Pe=[];function Wt(){if(Pe.length!==0){for(const e of Pe)S[e]?.setOptions({plotMode:r.plotMode,activeTest:r.activeTest});Pe=[]}}function tt(){we=null,Tt(),Lt(),Wt(),O({highlightBin:void 0},{fireCallback:!1})}function zn(e,t){if(we===e.id){tt();return}we=e.id,t.style.background=g.bgActive,t.style.fontWeight="600",Wt();const{kind:n,index:o}=e.variable;if(n==="test"){const i=o??0,l=ye();if(l===void 0||l.some(a=>a.testNumber===i))O({plotMode:"value",activeTest:i,highlightBin:void 0},{fireCallback:!1});else{O({highlightBin:void 0},{fireCallback:!1});const c=ge.has(r.plotMode??"hardBin")?null:Vn(e);if(c){for(const f of c)S[f]?.setOptions({plotMode:"value",activeTest:i});Pe=[...c]}}}else n==="softBin"?O({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):O({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1});Tt(),Lt();const d=e.highlight;if(d.kind==="wafer"){Ot(d.waferIndices);const i=$t(e);for(const l of d.waferIndices){const c=L[l]?.statsSummary?.findings.find(f=>$t(f)===i)?.highlight?.dieKeys;c?.length&&et(c,[l])}}else d.kind==="bin"?d.dieKeys?.length&&et(d.dieKeys):(d.kind==="region"||d.kind==="dies")&&d.dieKeys?.length&&et(d.dieKeys)}function ae(){if(!P)return;const e=!!h;P.style.display=(V||Je())&&e&&!Be?"flex":"none";const t=h?h.style.display!=="none":!1;(V?.hasNotableFindings||x.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?P.style.color=g.findingIndicator:P.dataset.active||(P.style.color=g.icon)}const W=u.ownerDocument.createElement("div");W.dataset.wmapToolbar="gallery",Object.assign(W.style,{flexShrink:"0",marginLeft:"auto",display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.control,padding:"0",boxShadow:Le.panel,flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const Rt=()=>{const e=ve();e&&(e.remove(),Ce(null)),$e(X,!1)},X=Q("mode","Plot mode",()=>{if(ve()){Rt();return}const e=x.flatMap(y=>y?.dies??[]),t=ye(),{testEntries:n,binEntries:o,stackedEntries:d}=Jo(e,t,{includeStacked:!0}),i=x.filter(Boolean).length,l=y=>{if(y===void 0)return i;let I=0;for(const se of x)se?.dies?.some(U=>Sn(U,y)!==void 0||U.testValues?.[y]!==void 0)&&I++;return I},s=i<2?n:n.map(y=>{const I=l(y.activeTest);return I===i?y:{...y,label:`${y.label} \u2014 ${I} of ${i} wafers`}}),a=r.plotMode??"hardBin",c=r.activeTest??0;function f(y){return y.plotMode!==a?!1:y.plotMode==="value"?c===(y.activeTest??0):y.plotMode==="metadata"?r.activeMetadataKey===y.activeMetadataKey:!0}function b(y,I){y.activeTest!==void 0?O({plotMode:"value",activeTest:y.activeTest,activeMetadataKey:void 0,logScale:y.logScale}):y.activeMetadataKey!==void 0?O({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:y.activeMetadataKey,passFailDisplay:"off"}):O({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),I.remove(),Ce(null),$e(X,!1)}const E=new Set,B=x.flatMap(y=>y?.metadataFields??[]).filter(y=>!E.has(y.key)&&E.add(y.key)).filter(y=>ei(e,y.key)).map(ti),C=Po(X.getBoundingClientRect(),s,o,d,f,b,{makeMenuRow:Rn,makeMenuSection:In},a,X.ownerDocument.defaultView??window,B);mn(X).appendChild(C),Ce(C),$e(X,!0),hn(C,X,Rt)});$e(X,!1);const Nn=()=>L.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:_n,sync:It}=Go(de,()=>({...r,plotMode:r.plotMode??"hardBin"}),Nn,e=>O(e));It();const Gn=v.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Fe(){const e=ye(),{testNumber:t}=yo(r.activeTest??0,e);return{testNumber:t,td:wo(e,t)}}function At(){if((r.plotMode??"hardBin")!=="value")return!1;const{td:e}=Fe();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function Se(){if((r.plotMode??"hardBin")!=="value")return!1;const{td:e}=Fe();return e!==void 0&&!bt(e)}function Kn(){if((r.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Fe();return x.some(n=>n?.dies?.some(o=>Sn(o,e,t)!==void 0))}function qn(e,t){if(!t||!bt(t))return;const n=t.limitLow!==void 0||t.limitHigh!==void 0;if((wn(r)==="spec"&&n?"spec":r.colorbarRangeMode??"spec")==="spec"&&n)return;let i=1/0,l=-1/0;for(const s of x)if(s)for(const a of s.dies){const c=pi(a,e);c!==void 0&&(c<i&&(i=c),c>l&&(l=c))}if(isFinite(i))return i===l?[i,i+1]:[i,l]}function Pt(){if((r.plotMode??"hardBin")!=="metadata")return;const e=r.activeMetadataKey;if(!e)return;const t=new Set;for(const n of x)if(n)for(const o of xo(n.dies,e))t.add(o);return{key:e,values:[...t].sort(yt)}}function nt(){const e=Pt();if(!(e===void 0&&r.metadataValueOrder===void 0)){r={...r,metadataValueOrder:e};for(const t of S)t&&t.setOptions({metadataValueOrder:e})}}function ot(){if((r.plotMode??"hardBin")!=="value")return;const{testNumber:e,td:t}=Fe(),n=qn(e,t),o=n?{test:e,range:n}:void 0;r={...r,valueRange:o};for(const d of S)d&&d.setOptions({valueRange:o})}let it=!1;function Un(){if(it)return;it=!0,(u.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{it=!1,ot(),nt(),Ht()})}let Ft=[];function ce(){const{colors:e,mixedHardBins:t}=Co(x.filter(n=>n!=null),{binColorScheme:r.binColorScheme,useDefinedBinColors:r.useDefinedBinColors});return Ft=t,e}function Ht(){const e=ce();r={...r,binColors:e};for(const t of S)t&&t.setOptions({binColors:e});Me()}const Xn=Uo(de,()=>Zo(r,Gn,{functionalActive:Se(),hasLimits:At()&&!Se(),hasRecorded:Kn()&&!Se(),binMode:(r.plotMode??"hardBin")==="hardBin"||(r.plotMode??"hardBin")==="softBin"},e=>O(e)),()=>Yo(r)),{btn:Zn,sync:jt}=qo(de,()=>({plotMode:r.plotMode,legendPosition:he}),e=>{he=e;for(const t of S)t&&t.setOptions({legendPosition:he})},{get:()=>We,set:e=>{We=e,Ct()},blockedReason:be});jt();const Yn=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],Vt=Bt("aggr","Aggregation method",()=>Yn,()=>r.aggregationMethod??"mean",e=>O({aggregationMethod:e}));function zt(){const e=r.plotMode==="stackedValues";Vt.style.display=e?"":"none"}zt();const{btn:Qn,sync:Nt}=Ko(de,()=>({...r,functionalActive:Se()}),e=>O(e));Nt();const He=Q("specRange","Colorbar range: spec limits",()=>{const e=r.colorbarRangeMode==="data"?"spec":"data";O({colorbarRangeMode:e})});function _t(){const e=(r.plotMode??"hardBin")==="value"&&At()&&wn(r)==="off"&&!Se();He.style.display=e?"":"none";const t=(r.colorbarRangeMode??"spec")==="spec";xe(He,t),He.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}_t();const Jn=Xo(de,()=>r,e=>O(e)),eo=Q("downloadAll","Download gallery PNG",mo),to=Bt("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>M!=null?String(M):"auto",e=>en(e==="auto"?void 0:Number(e))),k=u.ownerDocument.createElement("div");Object.assign(k.style,{display:"inline-flex",alignItems:"center",gap:"0"}),W.appendChild(k),k.appendChild(X),k.appendChild(_n),k.appendChild(Vt),k.appendChild(Qn),k.appendChild(He),k.appendChild(G()),k.appendChild(Xn),k.appendChild(G()),k.appendChild(Zn),k.appendChild(G()),k.appendChild(Jn),k.appendChild(G()),k.appendChild(to),k.appendChild(G()),k.appendChild(eo),(V||Je())&&(P=Q("findings","Summary panel",()=>{if(!h)return;const e=h.style.display!=="none";e||z(),h.style.display=e?"none":"flex",xe(P,!e),ae()}),W.appendChild(G()),W.appendChild(P));let K=null,je=null,J=[],Gt=!1;function Me(){const e=mi({lotStatsSummary:V,result:{warnings:[...x.flatMap(n=>n?.warnings??[]),...St().warnings]},extra:[r.binColors&&So(r.binColors,r.plotMode),Mo(Ft),Tn(vt())].filter(n=>!!n)}),t=e.length!==J.length||e.some((n,o)=>n.code!==J[o]?.code||n.message!==J[o]?.message);J=e,(t||!Gt)&&(Gt=!0,p.warnings?.onWarning?.(e)),no()}function no(){if(!K||!je)return;const e=J.length,t=e>0;if(K.style.display=t?"flex":"none",je.style.display=t?"":"none",!t)return;const n=hi(J[0]),o=`${e} data ${e===1?"warning":"warnings"}`;K.style.color=n==="error"?g.errText:g.warnText,K.ariaLabel=n==="error"?`${o} \u2014 some wafers may be positionally wrong`:o}(p.warnings?.display??!0)&&(je=G(),K=Q("warning","Data warnings",()=>{const e=ve();if(Ae(new MouseEvent("click")),e)return;const t=gi(K.getBoundingClientRect(),J,K.ownerDocument.defaultView??window);mn(u).appendChild(t),Ce(t),hn(t,K,()=>Ae(new MouseEvent("click")))}),$e(K,!1),W.appendChild(je),W.appendChild(K)),Me();let le=null;H&&(le=Q("analysis","Insights",()=>{Ut(!Be)}),le.dataset.wmapInsightsBtn="1",W.appendChild(G()),W.appendChild(le));function Kt(){import("./userGuideHtml.js").then(e=>_o({buildWaferMap:fi,renderWaferMap:di,renderWaferGallery,analyzeWaferMap:Xe},e.USER_GUIDE_HTML,$,u))}D&&(W.appendChild(G()),W.appendChild(Q("help","User guide",()=>Kt())));const ue=u.ownerDocument.createElement("div");ue.dataset.wmapGalleryMeta="1",Object.assign(ue.style,{flex:"1",minWidth:"0",overflow:"hidden",display:"flex",alignItems:"center",padding:`${w.sm} ${w.lg}`,fontSize:T.sub,lineHeight:qe.none,boxSizing:"border-box"});const Ve=u.ownerDocument.createElement("div");Object.assign(Ve.style,{background:g.canvasBg,display:"flex",alignItems:"stretch",gap:w.lg,paddingBottom:w.lg,minWidth:"0"});const ee=u.ownerDocument.createElement("div");ee.dataset.wmapGalleryLegend="1",Object.assign(ee.style,{display:"flex",flexDirection:"column",gap:w.sm,background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.container,padding:`${w.sm} ${w.lg}`,marginBottom:w.lg,boxShadow:Le.panel,fontSize:T.body,lineHeight:qe.none,boxSizing:"border-box",width:"100%",minWidth:"0"});const q=u.ownerDocument.createElement("div");Object.assign(q.style,{display:"flex",flexDirection:"row",alignItems:"flex-start"});let fe=null,De=null,qt=null;function oo(){return H?fe?Promise.resolve(fe):(qt??=import("./insightsTab.js").then(({createInsightsTab:e})=>(fe=e({getItems:()=>x,getLotStats:()=>V,getBinColors:()=>r.binColors??ce(),getRingCount:Ye,defaultView:p.insights?.defaultView,onOpenGuide:void 0,showMetadataStrip:!1,onSaveImage:Re.onSaveImage,onSaveText:Re.onSaveText,ownerDocument:u.ownerDocument,openWafer:(t,n,o)=>{const d=x[t];if(!d)return;let i=null;const l=jo({title:n,onClose:()=>i?.destroy(),anchor:u});on(l,n,d.wafer.metadata??void 0),i=ut(l.contentWrap,d,o)}}),De=fe.el,De.style.display="none",u.appendChild(De),fe)),qt):Promise.resolve(null)}let Be=!1;function Ut(e){H&&(Be=e,De&&(De.style.display=e?"flex":"none"),q.style.display=e?"none":"flex",k.style.display=e?"none":"inline-flex",W.style.display="inline-flex",le&&(xe(le,e),le.innerHTML=e?Te.wafer:Te.analysis,le.ariaLabel=e?"Back to gallery view":"Insights"),ae(),Ne(),e&&oo().then(t=>{!t||!Be||(t.el.style.display="flex",t.render())}))}H&&p.insights?.defaultOpen&&queueMicrotask(()=>Ut(!0));const io=4,at=240,Xt=480,ao=720,lo=1.25;let pe=Xt;function Zt(e){const t=A*2+110+2;let n=null;for(const o of e){if(o==null||!o.dies?.length)continue;const d=o.dies[0].width;if(!(d>0))continue;const i=o.wafer.radius*2*(io/d),l=Math.ceil(i+t);(n==null||l>n)&&(n=l)}return n}function so(e){const t=Zt(e);return t==null?at:Math.min(pe,Math.max(at,t))}function ro(e){const t=Zt(e);if(t==null)return!1;const n=Math.min(ao,Math.max(Xt,t));return n<=pe?!1:(pe=n,!0)}function lt(){return M!=null?"none":`${pe}px`}function Yt(){const e=lt();for(const t of Array.from(R.children))t.classList.contains("wmap-gallery-card")&&(t.style.maxWidth=e,t.style.maxHeight=e)}let ze=at,Qt=0;function Jt(e){if(ro(e)&&Yt(),M==null){const n=so(e);n>ze&&(ze=n)}rt()}function en(e){M=Bn(e),Yt(),rt()}function st(e){return`repeat(${e}, minmax(0, ${M!=null?"1fr":`${pe}px`}))`}function tn(e){R.style.gridTemplateColumns!==e&&(R.style.gridTemplateColumns=e)}function rt(){if(M!=null){tn(st(M));return}const e=Math.max(1,Qt),t=12,n=R.clientWidth||0,o=i=>(n-t*(i-1))/i;let d=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){const i=Math.min(pe,ze*lo),l=s=>{let a=0;for(;a<e&&o(a+1)>=s;)a++;return a};d=l(i)||l(ze)||1}tn(st(d))}const R=u.ownerDocument.createElement("div");if(Object.assign(R.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:st(1),gap:w.xl,paddingLeft:oe,paddingRight:oe,justifyContent:"start",alignContent:"start",isolation:"isolate"}),j?.placement){const e=j.placement;h=wt(e,oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.display="flex",h.style.flexDirection="column"}else if(V||Je()){const e=!!j?.defaultOpen;h=wt("right",oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display=e?"flex":"none",z()}ae(),h?.style.display!=="none"&&P&&xe(P,!0),(j?.placement??"right")==="left"?(h&&q.appendChild(h),q.appendChild(R)):(q.appendChild(R),h&&q.appendChild(h));const ke=u.ownerDocument.createElement("div");Object.assign(ke.style,{position:"sticky",top:"0",display:"flex",flexDirection:"column",paddingLeft:oe,paddingRight:oe,paddingTop:oe,zIndex:"1",background:g.menuBg}),Ve.appendChild(ue),Ve.appendChild(W),ke.appendChild(Ve),ke.appendChild(ee),u.appendChild(ke),u.appendChild(q);function Ne(){ee.innerHTML="";const e=r.plotMode??"hardBin",t=!Be&&un.has(e),n=L.filter(m=>m!=null),o=n.find(m=>m.isLotStack),d=bi(n.map(m=>({metadata:m.wafer.metadata??void 0})),o?{lotSize:o.lotSize??n.length,aggrMethod:o.aggrMethod}:void 0),i=e==="metadata",l=r.activeMetadataKey,s=t&&!i?kn(n,m=>(e==="softBin"?m.sbin:m.hbin)??void 0,On):{counts:new Map,total:0,pass:0},a=t&&!i?r.binColors??ce():void 0,c=a?e==="softBin"?a.pass.soft:a.pass.hard:new Set,f=li(s.counts.entries(),c).map(([m])=>m),b=t&&i&&l?kn(n,m=>vo(m.metadata?.[l])):{counts:new Map,total:0,pass:0},E=i?Pt()?.values:void 0,B=t&&i?(E??[...b.counts.keys()].sort(yt)).filter(m=>b.counts.has(m)):[];if(ue.innerHTML="",d&&ue.appendChild(d),ue.style.display=d?"flex":"none",!f.length&&!B.length){ee.style.display="none";return}ee.style.display="flex";const C=u.ownerDocument.createElement("div");Object.assign(C.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:`${w.sm} ${w.xl}`,maxHeight:"86px",overflowY:"auto",overflowX:"hidden"}),ee.appendChild(C);const y=r.highlightBin,I=L.flatMap(m=>m?.metadataFields??[]).find(m=>m.key===l),se=i?I?.label??(l?vi(l):"Metadata"):Wo[e],U=u.ownerDocument.createElement("span");if(U.textContent=se,Object.assign(U.style,{fontSize:T.body,fontWeight:"700",letterSpacing:To,textTransform:"uppercase",color:g.label,flexShrink:"0"}),C.appendChild(U),!i&&s.total>0){const m=s.pass,F=m/s.total*100,te=u.ownerDocument.createElement("span");te.textContent=`Yield ${Ze(F)}`,Object.assign(te.style,{fontSize:T.body,fontWeight:"700",color:g.value,whiteSpace:"nowrap",flexShrink:"0"});const ne=u.ownerDocument.createElement("span");ne.textContent=`${m.toLocaleString()} / ${s.total.toLocaleString()} dies`,Object.assign(ne.style,{fontSize:T.body,color:g.label,whiteSpace:"nowrap",flexShrink:"0"}),C.appendChild(te),C.appendChild(ne)}if(i){const m=r.highlightMetadataValue;B.forEach((F,te)=>{const ne=m===F,Ge=I?.values?.find(gt=>gt.value===F),ho=Ge?.color??Eo(te),dn=b.counts.get(F)??0;En(C,{color:ho,isActive:ne,label:Ge?.label??F,count:dn,percent:b.total>0?dn/b.total*100:void 0,onClick:()=>{const gt=r.highlightMetadataValue===F?void 0:F;O({highlightMetadataValue:gt})}})});return}const ft=e==="softBin"?L.flatMap(m=>m?.sbinDefs??[]):L.flatMap(m=>m?.hbinDefs??[]),ln=new Set,pt=[];for(const m of ft)ln.has(m.bin)||(ln.add(m.bin),pt.push(m));const mt=pt.length>0?new Map(pt.map(m=>[m.bin,m])):null,sn=a??r.binColors??ce(),go=e==="softBin"?sn.soft:sn.hard,rn=m=>go.get(m)??ko;for(const m of f){const F=y===m,te=mt?.get(m),ne=s.counts.get(m)??0;En(C,{color:rn(m),isActive:F,label:te?.name?`${m} \xB7 ${te.name}`:`Bin ${m}`,count:ne,percent:s.total>0?ne/s.total*100:void 0,onClick:()=>{const Ge=r.highlightBin===m?void 0:m;O({highlightBin:Ge})}})}s.total>0&&f.length>1&&ee.appendChild(Di(u.ownerDocument,[...s.counts.entries()].sort(([,m],[,F])=>F-m).map(([m,F])=>({color:rn(m),count:F,label:mt?.get(m)?.name?`${m} \xB7 ${mt.get(m).name}`:`Bin ${m}`})),s.total))}function Ee(e){const t=x.filter(s=>s!==null);if(!t.length)return[];const n=t.map(s=>s.dies.filter(Mi)),o=t[0].wafer,d=t.length,i=o.metadata?{...o,metadata:(({wafer:s,waferId:a,...c})=>c)(o.metadata)}:o;function l(s,a){return{...s,stats:{...s.stats,isLotStack:!0,aggregationMethod:a,lotSize:d}}}if(e==="stackedValues"){const s=ye();let a=s?.filter(bt);if(s!==void 0&&a?.length===0)return[];if(s?.length||(a=bo(t.flatMap(b=>b.dies)).map(b=>({testNumber:b,name:`Test ${b}`}))),!a?.length)return[];const c=r.aggregationMethod??"mean";return a.map(f=>{const b=ri(n,c,f.testNumber),E={testNumber:0,name:f.name,unit:f.unit};return{wafer:i,dies:b,testDefs:[E],label:`${f.name} \xB7 ${c}`,isLotStack:!0,aggrMethod:c,lotSize:d,statsSummary:l(Xe({wafer:i,dies:b,testDefs:[E]},{testNumbers:[0]}),c)}})}if(e==="stackedBins"){let s=Ke(t.map(a=>a?.hbinDefs));return(!s||s.length===0)&&(s=[...new Set(t.flatMap(c=>c.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((c,f)=>c-f).map(c=>({bin:c,name:`Bin ${c}`}))),s.map(a=>{const c=xn(n,a.bin,"hard"),f=[{bin:a.bin,name:a.name}];return{wafer:i,dies:c,hbinDefs:f,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:l(Xe({wafer:i,dies:c,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let s=Ke(t.map(a=>a?.sbinDefs));return(!s||s.length===0)&&(s=[...new Set(t.flatMap(c=>c.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((c,f)=>c-f).map(c=>({bin:c,name:`Bin ${c}`}))),s.map(a=>{const c=xn(n,a.bin,"soft"),f=[{bin:a.bin,name:a.name}];return{wafer:i,dies:c,sbinDefs:f,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:l(Xe({wafer:i,dies:c,sbinDefs:f}),"countBin")}})}return t}function dt(e){const t=x.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:r.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}function O(e,{fireCallback:t=!0}={}){const n=Object.keys(e),o=r.plotMode,d=be()!==null;r={...r,...e};const i=r.plotMode,l=ge.has(i),s=o!==void 0&&ge.has(o),a=Ie>0;if("binColorScheme"in e||"useDefinedBinColors"in e){const f=ce();r={...r,binColors:f},e={...e,binColors:f}}if(e.plotMode!==void 0)if(l){const f=dt(i);if(r={...r,...f},a)for(const b of S)b&&b.setOptions(e);else Z(Ee(i))}else if(s){const{valueRange:f,lotSize:b,aggregationMethod:E,...B}=r;if(r=B,a)for(const C of S)C&&C.setOptions(e);else Z(x.filter(C=>C!==null))}else for(const f of S)f&&f.setOptions(e);else if(e.aggregationMethod!==void 0&&i==="stackedValues")if(a)for(const f of S)f&&f.setOptions(e);else Z(Ee("stackedValues"));else for(const f of S)f&&f.setOptions(e);be()!==null!==d&&Ct(),Ne(),zt(),jt(),It();const c=e.plotMode!==void 0&&e.plotMode!==o;(ui.some(f=>f in e)||c)&&z(),Me(),Nt(),_t(),ot(),nt(),t&&p.onViewOptionsChange?.(Cn(r),n,ci(n))}function nn(e,t,n){const o=e.createElement("div");Object.assign(o.style,{display:"flex",alignItems:"center",gap:w.xs,flex:"1",minWidth:"0"});const d=e.createElement("span");d.textContent=t,Object.assign(d.style,{fontWeight:"700",fontSize:T.sub,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(d);const i=Dn(n??{});let l=null;if(i.length>0){const s=e.createElement("span");Object.assign(s.style,{fontSize:T.body,lineHeight:qe.none,color:g.label,flexShrink:"0"}),s.textContent="\u25BE",o.appendChild(s),Object.assign(o.style,{cursor:"pointer",borderRadius:N.control}),o.addEventListener("mouseenter",()=>{o.style.background=g.bgHover}),o.addEventListener("mouseleave",()=>{o.style.background="none"}),l=e.createElement("div"),l.dataset.wmapCardMetaPanel="1",Object.assign(l.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:fn,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:Le.menu,padding:`${w.md} ${w.lg}`,fontSize:T.body,display:"none"});const a=Mn(n??{});a&&l.appendChild(a),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),bn(o,c=>{s.textContent=c?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(c)),l&&(l.style.display=c?"block":"none")})}return{wrap:o,metaPanel:l}}function on(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),d=Dn(n??{});if(!o||d.length===0)return;const i=o.parentElement,l=u.ownerDocument.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",gap:w.xs,flex:"1",minWidth:"0",cursor:"pointer"}),ht(l,"bare"),i?.insertBefore(l,o),l.appendChild(o);const s=u.ownerDocument.createElement("span");Object.assign(s.style,{fontSize:T.body,lineHeight:qe.none,color:g.label,flexShrink:"0"}),s.textContent="\u25BE",l.appendChild(s);const a=u.ownerDocument.createElement("div");a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:fn,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:Le.menu,padding:`${w.md} ${w.lg}`,fontSize:T.body,display:"none"});const c=Mn(n??{});c&&a.appendChild(c),e.contentWrap.style.position="relative",e.contentWrap.appendChild(a),l.setAttribute("aria-expanded","false"),l.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),bn(l,f=>{s.textContent=f?"\u25B4":"\u25BE",l.setAttribute("aria-expanded",String(f)),a.style.display=f?"block":"none"})}function ct(e,t,n){const o=u.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.container,boxShadow:Le.panel,overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:lt(),maxHeight:lt()});const d=u.ownerDocument.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:w.sm});const{wrap:i,metaPanel:l}=nn(document,Ue(e,t),e.wafer.metadata??void 0);d.appendChild(i);const s=u.ownerDocument.createElement("button");s.dataset.wmapExpandBtn="1",s.setAttribute("aria-label","Open full view"),yn(s),s.innerHTML=Te.expand,Object.assign(s.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${g.menuBorder}`,borderRadius:N.control,background:g.panelBg,color:g.label,padding:w.xxs,cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),ht(s),d.appendChild(s),o.appendChild(d);const a=u.ownerDocument.createElement("div");Object.assign(a.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),o.appendChild(a),l&&a.appendChild(l),R.appendChild(o);const c=We||be()!==null,f=e.viewOptions?{...r,...e.viewOptions}:r,b=vn(a,e,{viewOptions:{...f,showLegend:c,legendPosition:he},showTooltip:!0,padding:A,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>Oe(t,e),showIdentity:!1,chromeInset:$o});return b.setViewControlsVisible(!1),b.setSummaryVisible(!1),s.onclick=()=>Oe(t,e),{card:o,ctrl:b,canvasWrapper:a,expandBtn:s}}function co(e){const t=re[e];if(!t)return;const n=[..._.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=Te.minimize,t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>fo(n.id)):(t.innerHTML=Te.expand,t.setAttribute("aria-label","Open full view"),t.onclick=()=>Oe(e,L[e]))}function Z(e){po(),ve()?.remove(),Ce(null),tt(),L=[];for(const i of S)i&&i.destroy();S=[],ie=[],re=[],Ie=0,R.innerHTML="",Qt=e.length,Jt(e.map(i=>typeof i=="function"?null:i));const t=[];for(let i=0;i<e.length;i++){const l=e[i];if(typeof l=="function"){const s=u.ownerDocument.createElement("div");s.className="wmap-gallery-card",Object.assign(s.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.container,aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const a=u.ownerDocument.createElement("span");a.textContent="\u2026",Object.assign(a.style,{color:g.label,fontSize:"18px"}),s.appendChild(a),R.appendChild(s),L.push(null),S.push(null),ie.push(null),re.push(null),t.push({index:i,factory:l,placeholder:s}),Ie++}else{const{ctrl:s,canvasWrapper:a,expandBtn:c}=ct(l,i,e.length);L.push(l),S.push(s),ie.push(a),re.push(c)}}Ht(),Ne(),ot(),nt();const n=++Qe;let o=0;function d(){if(n!==Qe)return;if(o>=t.length){if(ge.has(r.plotMode)){const B=r.plotMode;Z(Ee(B))}return}const{index:i,factory:l,placeholder:s}=t[o++],a=l();L[i]=a,x[i]=a,Jt([a]);const{card:c,ctrl:f,canvasWrapper:b,expandBtn:E}=ct(a,i,e.length);S[i]=f,ie[i]=b,re[i]=E,Ie--,s.replaceWith(c),Ne(),Un(),!h&&!j?.placement&&a.statsSummary?.findings.length?(h=wt("right",oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display="none",(j?.placement??"right")==="left"?q.insertBefore(h,R):q.appendChild(h),z(),P||(P=Q("findings","Summary panel",()=>{if(!h)return;const C=h.style.display!=="none";C||z(),h.style.display=C?"none":"flex",xe(P,!C),ae()}),W.appendChild(G()),W.appendChild(P)),ae()):h&&h.style.display!=="none"&&z(),ae(),setTimeout(d,0)}t.length>0&&setTimeout(d,0)}if(ge.has(r.plotMode)&&x.length>0){const e=dt(r.plotMode);r={...r,...e},Z(Ee(r.plotMode))}else Z(v);Me();let me=0;const an=new(u.ownerDocument.defaultView??window).ResizeObserver(()=>{if(me)return;me=(u.ownerDocument.defaultView??window).requestAnimationFrame(()=>{me=0,M==null&&rt()})});an.observe(R),h&&z();function uo(e,t){const n=ie[e];if(!n)return;n.innerHTML="",Object.assign(n.style,{alignItems:"center",justifyContent:"center"});const o=u.ownerDocument.createElement("span");o.textContent=t?"Opened in its own window":"Opened in the wafer viewer",Object.assign(o.style,{color:g.label,fontSize:T.body,textAlign:"center",padding:"0 12px"}),n.appendChild(o)}function Oe(e,t){for(const l of _.values())if(l.cardIndex===e)return;const n=Ue(t,e),o=Ln++,d=S[e]?.getOptions(),i=Fo(n);if(i){const l=i.document;l.title=n,Object.assign(l.documentElement.style,{height:"100%"}),Object.assign(l.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:T.family}),zo(u,l.documentElement);const s=No(u,l.documentElement,()=>C.setOptions({})),a=l.createElement("div");a.dataset.wmapWindowBanner="1",a.textContent=n,Object.assign(a.style,{display:"none",padding:`${w.sm} ${w.xl}`,fontSize:T.body,fontWeight:"700",background:g.warnBg,color:g.warnText,borderBottom:`1px solid ${g.warnBorder}`,flexShrink:"0"}),l.body.appendChild(a);const c=l.createElement("div");Object.assign(c.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),l.body.appendChild(c);const{wrap:f,metaPanel:b}=nn(l,n,t.wafer.metadata??void 0),E=l.createElement("div");Object.assign(E.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:w.sm}),E.appendChild(f),c.appendChild(E);const B=l.createElement("div");Object.assign(B.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),b&&B.appendChild(b),c.appendChild(B);const C=ut(B,t,void 0,d),y=setInterval(()=>{i.closed&&_e(o)},400);i.addEventListener("pagehide",()=>_e(o)),_.set(o,{id:o,ctrl:C,cardIndex:e,label:n,closePollId:y,stopThemeSync:s,close:()=>{i.closed||i.close()},setTitle:I=>{l.title=I,a.textContent=I,a.style.display="block"}})}else{const l=Ho({title:n,onClose:()=>_e(o),anchor:u});l.contentWrap.style.flexDirection="column",on(l,n,t.wafer.metadata??void 0);const s=ut(l.contentWrap,t,void 0,d);_.set(o,{id:o,ctrl:s,cardIndex:e,label:n,closePollId:null,close:()=>l.close(),setTitle:a=>{const c=l.box.querySelector("[data-wmap-window-title]");c&&(c.textContent=a,c.title=a)}})}S[e]?.destroy(),S[e]=null,uo(e,i!==null),co(e)}function ut(e,t,n,o){const d=t.viewOptions?{...r,...t.viewOptions}:r,i=o?{...d,...o}:d,s={...n!==void 0?{...i,plotMode:"value",activeTest:n}:i,showLegend:!0,legendPosition:he},a=vn(e,t,{viewOptions:s,showTooltip:!0,padding:A,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showIdentity:!1});return a.setViewControlsVisible(!0),a.setSummaryVisible(!0),a.setExpandVisible(!1),a}function _e(e){const t=_.get(e);if(!t||(_.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.(),t.ctrl.destroy(),t.cardIndex===null))return;const n=t.cardIndex,o=L[n];if(!o)return;const{card:d,ctrl:i,canvasWrapper:l,expandBtn:s}=ct(o,n,L.length);ie[n]?.parentElement?.replaceWith(d),S[n]=i,ie[n]=l,re[n]=s}function fo(e){const t=_.get(e);t&&(t.close(),_e(e))}function po(){for(const e of _.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function mo(){const e=[...R.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),o=Math.ceil(t/n),d=e[0].width,i=e[0].height,l=8,s=(u.ownerDocument.defaultView??window).devicePixelRatio||1,a=Math.round(26*s),c=Math.round(12*s),f=u.ownerDocument.createElement("canvas");f.width=n*d+(n-1)*l,f.height=o*(i+a)+(o-1)*l;const b=f.getContext("2d"),E=Oo(R);b.fillStyle=E.background,b.fillRect(0,0,f.width,f.height),e.forEach((B,C)=>{const y=C%n,I=Math.floor(C/n),se=y*(d+l),U=I*(i+a+l),ft=B.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";b.fillStyle=E.surface,b.fillRect(se,U,d,a),b.fillStyle=E.text,b.font=`700 ${c}px system-ui, sans-serif`,b.textAlign="left",b.textBaseline="middle",b.fillText(ft,se+Math.round(10*s),U+a/2,d-Math.round(20*s)),b.drawImage(B,se,U+a)}),f.toBlob(B=>{if(!B)return;if(p.downloadFilename!=null){gn(B,p.downloadFilename,p.onSaveImage);return}const C=S.find(y=>y!=null)?.getExportTitle();gn(B,["gallery",C].filter(Boolean).join(" "),Re.onSaveImage)})}return{setItems(e){x=e.map(n=>typeof n=="function"?null:n);const t=r.plotMode;if(ge.has(t))if(e.some(o=>typeof o=="function"))Z(e);else{const o=dt(t);r={...r,...o},Z(Ee(t))}else Z(e)},setOptions(e){O(e,{fireCallback:!1})},getOptions(){return Cn(r)},setFindingsNotice(e){Et=e,z()},setColumns(e){en(e)},getBinColors(){return r.binColors??ce()},setLotStatsSummary(e){V=e,Me(),h&&z(),ae()},openUserGuide:Kt,destroy(){Qe++;for(const e of[..._.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();_.clear();for(const e of S)e&&e.destroy();S=[],ve()?.remove(),an.disconnect(),me&&((u.ownerDocument.defaultView??window).cancelAnimationFrame(me),me=0),u.ownerDocument.removeEventListener("click",Ae,!0),window.removeEventListener("blur",kt),Y(),pn(),ke.remove(),q.remove(),h?.remove(),fe?.destroy()}}}
|