@wafertools/wafermap 0.30.3 → 0.30.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +2 -2
  3. package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
  4. package/dist/packages/canvas-adapter/charts/capability.js +1 -1
  5. package/dist/packages/canvas-adapter/charts/chartShell.d.ts +1 -1
  6. package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
  7. package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
  8. package/dist/packages/canvas-adapter/charts/scatter.d.ts +5 -1
  9. package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
  10. package/dist/packages/canvas-adapter/charts/sweep.js +1 -1
  11. package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
  12. package/dist/packages/canvas-adapter/charts/trend.js +1 -1
  13. package/dist/packages/canvas-adapter/insightsTab.d.ts +11 -1
  14. package/dist/packages/canvas-adapter/insightsTab.js +1 -1
  15. package/dist/packages/canvas-adapter/maplessSummary.js +1 -1
  16. package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
  17. package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
  18. package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
  19. package/dist/packages/canvas-adapter/toCanvas.js +1 -1
  20. package/dist/packages/canvas-adapter/toolbar.js +1 -1
  21. package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
  22. package/dist/packages/canvas-adapter/userGuideHtml.js +38 -36
  23. package/dist/packages/canvas-adapter/version.d.ts +2 -2
  24. package/dist/packages/canvas-adapter/version.js +1 -1
  25. package/dist/packages/canvas-adapter/warnings.js +1 -1
  26. package/dist/packages/core/dies.d.ts +1 -1
  27. package/dist/packages/renderer/binColors.js +1 -1
  28. package/dist/packages/renderer/buildView.js +1 -1
  29. package/dist/packages/renderer/buildWaferMap.d.ts +40 -12
  30. package/dist/packages/renderer/buildWaferMap.js +1 -1
  31. package/dist/packages/renderer/derivedTests/apply.js +1 -1
  32. package/dist/packages/renderer/derivedTests/parser.js +1 -1
  33. package/dist/packages/renderer/spec.d.ts +17 -0
  34. package/dist/packages/renderer/spec.js +1 -1
  35. package/dist/packages/stats/analyzeWaferMap.js +1 -1
  36. package/dist/packages/stats/capability.d.ts +4 -2
  37. package/dist/packages/stats/capability.js +1 -1
  38. package/dist/packages/stats/correlation.d.ts +1 -1
  39. package/dist/packages/stats/deprecated.d.ts +1 -1
  40. package/dist/packages/stats/deprecated.js +1 -1
  41. package/dist/packages/stats/mergeTestDefs.d.ts +1 -1
  42. package/dist/packages/stats/mergeTestDefs.js +1 -1
  43. package/dist/packages/stats/renderSummaryReport.js +11 -11
  44. package/dist/packages/stats/sweep.d.ts +8 -0
  45. package/dist/packages/stats/sweep.js +1 -1
  46. package/dist/packages/stats/types.d.ts +9 -3
  47. package/package.json +1 -1
@@ -2,7 +2,7 @@ import type { LotStatsSummary } from '../stats/types.js';
2
2
  import type { WaferMapDisplayItem } from './renderWaferGallery.js';
3
3
  import type { BinColors } from '../renderer/binColors.js';
4
4
  import { type SaveImageHandler, type SaveTextHandler } from './toolbar.js';
5
- import type { SweepSpec } from '../stats/sweep.js';
5
+ import { type SweepSpec } from '../stats/sweep.js';
6
6
  export type InsightsView = 'overview' | 'distributions' | 'correlation' | 'sweeps';
7
7
  /** Public option shape for `RenderOptions.insights`/`GalleryOptions.insights`. */
8
8
  export interface InsightsOptions {
@@ -65,6 +65,14 @@ export interface InsightsOptions {
65
65
  * the syntax is one syntax library-wide.
66
66
  */
67
67
  sweeps?: SweepSpec[];
68
+ /**
69
+ * Offers a "Remove" button on the Sweeps tab's notice about sweeps that name
70
+ * none of the data's tests — typically sweeps a host kept from another test
71
+ * program. Called with those sweeps' ids; the host drops them and re-renders
72
+ * with the remaining `sweeps`. Without it the notice still shows, with no
73
+ * button. The library never edits the host's sweep list itself.
74
+ */
75
+ onRemoveSweeps?: (ids: string[]) => void;
68
76
  /**
69
77
  * Open the Insights view on mount instead of starting on the map/grid.
70
78
  * Default false — the tab is offered, the map is what you see first.
@@ -123,6 +131,8 @@ export interface InsightsTabDeps {
123
131
  defaultView?: InsightsView;
124
132
  /** Sweep definitions to render in the Distributions view — see `InsightsOptions.sweeps`. */
125
133
  sweeps?: SweepSpec[];
134
+ /** See `InsightsOptions.onRemoveSweeps`. */
135
+ onRemoveSweeps?: (ids: string[]) => void;
126
136
  /**
127
137
  * When provided, the tab bar gets a leading "‹ Map"/"‹ Gallery" tab that
128
138
  * exits Insights back to the host's normal view — one visible navigation
@@ -1 +1 @@
1
- import{buildFacetTable as Re,facetValueOf as We,FACET_NONE_VALUE as Me}from"../stats/facets.js";import{mergeTestDefs as re}from"../stats/mergeTestDefs.js";import{isParametricTest as Ye}from"../renderer/buildWaferMap.js";import{waferDisplayLabel as je,waferIdentityLabel as Ge}from"../core/waferLabel.js";import{hasDrilldownTargets as se,waferPopulation as He}from"./chartPopulation.js";import{openDrilldownMenu as Fe}from"./drilldown.js";import{INPUT_DEFAULT_PASS_BINS as R,itemPassBins as Ne,passBinsLabel as ie}from"../core/passBins.js";import{NO_DATA_FILL as le}from"../renderer/colorMap.js";import{describeWaferPopulation as Ve,populationStat as _e}from"../stats/population.js";import{LEADING as Ue,ALPHA as ze,SPACE as x,EDGE_GUTTER as Z,FONT as Y,CLR as B,RADIUS as qe,SHADOW as Qe,controlStyle as Ke,wireControlHover as de,wireTooltip as Xe}from"./toolbar.js";import{ICONS as Je}from"./icons.js";import{renderCapabilityPanel as Ze}from"./charts/capability.js";import{renderBoxplotPanel as et}from"./charts/boxplot.js";import{renderTrendPanel as tt}from"./charts/trend.js";import{renderSweepPanel as nt}from"./charts/sweep.js";import{renderHistogramPanel as at}from"./charts/histogram.js";import{renderCorrelationPanel as ot}from"./charts/correlation.js";import{renderScatterPanel as rt}from"./charts/scatter.js";import{renderBarPanel as ce}from"./charts/barPanel.js";import{renderBinClusterPanel as st}from"./charts/binCluster.js";import{renderTestPassRatePanel as it}from"./charts/testPassRate.js";import{QUANTITY as lt}from"./charts/palette.js";import{cardFrameStyle as dt,makeChartGridWrap as V,makeLabeledSelect as ct,makeLinkedGroupSelect as pt}from"./charts/chartShell.js";import{buildYieldData as _,buildYieldDataCombined as pe}from"../stats/yield.js";import{buildBinParetoData as ut}from"../stats/binPareto.js";import{buildLotTestSection as ft,buildLotFunctionalSection as mt,buildMetadataStripBox as bt}from"./summaryPanel.js";import{buildRegionYieldData as ue,buildRingRegions as gt,buildQuadrantRegions as yt}from"../stats/regions.js";import{renderRegionYieldDiagram as fe}from"./charts/regionYieldDiagram.js";const me=[{key:"overview",label:"Overview"},{key:"distributions",label:"Distributions"},{key:"correlation",label:"Correlation"}],ht={key:"sweeps",label:"Sweeps"};export function createInsightsTab(T){const{getItems:be,getLotStats:ge,getBinColors:ee,getRingCount:ye,onSaveImage:v,onSaveText:U,openWafer:j,focusTest:te}=T,he=T.showMetadataStrip??!0,W=T.contentInset??Z,p=T.ownerDocument??document,P=p.createElement("div");Object.assign(P.style,{display:"none",flexDirection:"column",width:"100%",paddingTop:"0"});const we=Z,O=p.createElement("div");Object.assign(O.style,{paddingLeft:we});const D=p.createElement("div");Object.assign(D.style,{display:"flex",gap:x.xs,alignItems:"center",background:B.menuBg,border:`1px solid ${B.menuBorder}`,borderRadius:qe.container,boxShadow:Qe.panel,padding:`0 ${x.lg}`,marginBottom:x.lg,marginLeft:W,marginRight:W}),D.setAttribute("role","tablist"),D.addEventListener("keydown",e=>{if(e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;const t=Array.from(D.querySelectorAll('[role="tab"]')),r=t.indexOf(p.activeElement);if(r===-1)return;e.preventDefault();const c=t[(r+(e.key==="ArrowRight"?1:-1)+t.length)%t.length];c.focus(),c.click()});const M=p.createElement("div");Object.assign(M.style,{display:"flex",flexDirection:"column",gap:x.lg,marginTop:"0",paddingLeft:W,paddingRight:W}),P.appendChild(O),P.appendChild(D),P.appendChild(M);const ne=(T.sweeps?.length??0)>0,Ce=ne?[...me,ht]:me;let E=T.defaultView==="sweeps"&&!ne?"overview":T.defaultView??"overview",A,L=null,$=null,G={includeLimits:void 0,clipOutliers:!1};const z=e=>{$!==e&&($=e,F())};let H=new Map;function ae(){for(const e of H.values())e.destroy();H=new Map}function q(e,t,r){j?.(e,t,r)}function Q(e){if(e.some(t=>se(t.testDefs,T.sweeps)))return(t,r,c)=>{const i=e.find(f=>f.waferIndex===t);if(!i||!se(i.testDefs,T.sweeps))return;c.preventDefault();const s=He(i.dies,{waferLabel:i.identity,testDefs:i.testDefs,activeTest:r??L??void 0,waferIndex:t});Fe({x:c.clientX,y:c.clientY},c.target,s,{sweeps:T.sweeps,onSaveImage:v})}}function Se(e){return j?{open:(t,r)=>q(t,`Wafer ${e.find(c=>c.waferIndex===t)?.label??t}`,r)}:te&&e.length===1?{open:(t,r)=>te(r),label:"show this test on the map"}:null}function xe(){return be().map((e,t)=>e==null?null:{metadata:e.wafer.metadata??void 0,dies:e.dies,wafer:e.wafer,label:je(e,t),identity:Ge(e),waferIndex:t,passBins:Ne(e),statsSummary:e.statsSummary,testDefs:e.testDefs}).filter(e=>e!=null)}function oe(e,t){Object.assign(e.style,{background:"none",border:"none",borderBottom:t?`2px solid ${B.iconActive}`:"2px solid transparent",color:t?B.iconActive:B.label,fontWeight:t?"700":"500",fontSize:Y.body,padding:`${x.sm} ${Z} ${x.md}`,cursor:"pointer",marginBottom:"-1px"})}function Te(e,t){const r=p.createElement("button");r.type="button",r.textContent=t;const c=e===E;return oe(r,c),r.dataset.on=c?"true":"false",de(r,"bare"),r.dataset.wmapInsightsTab=e,r.setAttribute("role","tab"),r.setAttribute("aria-selected",c?"true":"false"),r.tabIndex=c?0:-1,r.addEventListener("click",()=>{E!==e&&(E=e,F({keepSections:!0}))}),r}function ve(e){const t=p.createElement("button");return t.type="button",t.textContent=`\u2039 ${e.label}`,oe(t,!1),t.dataset.wmapInsightsBack="1",t.addEventListener("click",e.onBack),t}function ke(e,t,r,c=!0){const i=V(p),s=ee();let f="label";const b=r??"group",u=ie(e.map(d=>d.passBins)),l=ge?.(),g=new Map(l?.lotYieldSeries.map(d=>[d.waferIndex,d.yieldPercent])),C=d=>({...d,label:d.label.replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPercent:g.get(d.waferIndex),key:d.waferIndex}),m=e.map(C),y=t?.map(d=>({key:d.key,items:d.items.map(C)})),S=()=>y?pe(y,R,f):_(m,R,f),w={title:t?`Yield by ${b} (pass: ${u})`:`Yield by wafer (pass: ${u})`,data:S(),selfControl:{current:f,options:[["yield","Sort: yield"],["label",t?`Sort: ${b}`:"Sort: wafer ID"]],onChange:d=>(f=d,{data:S()})},barColor:()=>lt,valueLabel:d=>`${d.percent.toFixed(1)}%`,reference:d=>{if(d.length<3)return null;const k=d.map(J=>J.percent).sort((J,Ae)=>J-Ae),I=k.length%2?k[(k.length-1)/2]:(k[k.length/2-1]+k[k.length/2])/2;return{value:I,label:`median ${I.toFixed(1)}%`}},drill:y?{onOpenGroup:d=>{const k=y.find(I=>I.key===d.label)?.items??[];return{data:_(k,R,f),title:`Yield by wafer \u2014 ${b}: ${d.label} (pass: ${u})`}},onBack:()=>({data:S(),title:`Yield by ${b} (pass: ${u})`}),groupLabelText:b}:void 0,onOpen:j?d=>{typeof d.key=="number"&&q(d.key,`Wafer ${d.label}`)}:void 0,onWaferContextMenu:Q(e),ownerDocument:p};let n=null;if(c&&(n=ce(w,v),n.card.style.minHeight="360px",i.appendChild(n.card)),t){const d=st({title:"Hard bin pareto",groups:t.map(k=>({key:k.key,items:k.items.map(I=>({dies:I.dies,hardBinCounts:I.statsSummary?.stats.hardBinCounts,softBinCounts:I.statsSummary?.stats.softBinCounts}))})),onSaveImage:v,ownerDocument:p});return d.card.style.minHeight="360px",i.appendChild(d.card),{card:i,destroy:()=>{n?.destroy(),d.destroy()}}}let a="hbin";const o=d=>d===void 0?le:(a==="hbin"?s.hard:s.soft).get(d)??le,h=e.map(d=>({dies:d.dies,hardBinCounts:d.statsSummary?.stats.hardBinCounts,softBinCounts:d.statsSummary?.stats.softBinCounts})),N=()=>ut(h,a),Oe={title:"Hard bin pareto",data:N(),selfControl:{current:a,options:[["hbin","Hard bins"],["sbin","Soft bins"]],onChange:d=>(a=d,{data:N(),title:`${a==="hbin"?"Hard":"Soft"} bin pareto`})},barColor:d=>o(d.binCode),ownerDocument:p},X=ce(Oe,v);return X.card.style.minHeight="360px",i.appendChild(X.card),{card:i,destroy:()=>{n?.destroy(),X.destroy()}}}function K(){const e=p.createElement("div");return e.dataset.wmapChartCard="1",Object.assign(e.style,{...dt(),display:"flex",flexDirection:"column",gap:x.lg,minWidth:"0"}),e}function De(e){if(O.innerHTML="",O.style.marginBottom="0",!he)return;const t=bt(e.map(r=>({metadata:r.metadata})),void 0,{facetableOnly:!1});t&&(t.style.marginBottom="0",O.appendChild(t),O.style.marginBottom=x.xs)}function Be(e,t,r,c){if(!e.length)return{elements:[],testValuesCard:null,functionalCard:null,destroy:()=>{}};const i=e.map(o=>o.wafer),s=e.map(o=>o.dies),f=e.flatMap(o=>o.dies),b=e.map(o=>o.statsSummary),u=b.every(o=>o!==void 0)?b:void 0,l=ye?.()??4,g=[],C=[],y=it({groups:(c??[{key:"",items:e}]).map(o=>({key:o.key,items:o.items.map(h=>({dies:h.dies,testSpecYield:h.statsSummary?.stats.testSpecYield,functionalYield:h.statsSummary?.stats.functionalYield}))})),testDefs:r,onSaveImage:v,ownerDocument:p});y.card.style.minHeight="300px",g.push(y.card),C.push(y.destroy);const S=ue(s,i,l,o=>e[o].passBins,gt);if(S.length){const o=fe({title:"Ring yield",mode:"ring",rows:S,onSaveImage:v,ownerDocument:p});g.push(o.card),C.push(o.destroy)}const w=ue(s,i,l,o=>e[o].passBins,yt);if(w.length){const o=fe({title:"Quadrant yield",mode:"quadrant",rows:w,onSaveImage:v,ownerDocument:p});g.push(o.card),C.push(o.destroy)}let n=null;if(t.length){const o=ft(f,t,void 0,u,U,s.map(h=>({dies:h})),void 0,"full");if(o){const h=K();h.appendChild(o),n=h}}let a=null;if(r.length){const o=mt(f,r,u,U);if(o){const h=K();h.appendChild(o),a=h}}return{elements:g,testValuesCard:n,functionalCard:a,destroy:()=>{for(const o of C)o()}}}function Le(e){const t=ie(e.map(l=>l.passBins)),r=e.length===1,c=e[0],i=K();Object.assign(i.style,{flexDirection:"row",flexWrap:"wrap",gap:x.md});const s=l=>{const g=l.lastElementChild;return g&&Object.assign(g.style,{borderRight:"none",paddingRight:"0",marginRight:"0"}),l};function f(l,g,C){const m=p.createElement("div");Object.assign(m.style,{display:"flex",alignItems:"baseline",gap:x.sm,paddingRight:x.xxl,marginRight:x.md,borderRight:`1px solid ${B.menuBorder}`});const y=p.createElement("div");y.textContent=l,Object.assign(y.style,{fontSize:Y.heading,fontWeight:"700",color:B.value,lineHeight:Ue.tight});const S=p.createElement("div");if(S.textContent=g,Object.assign(S.style,{fontSize:Y.body,color:B.label}),m.append(y,S),C){const w=p.createElement("div");w.textContent=C,Object.assign(w.style,{fontSize:Y.meta,color:B.label,opacity:ze.muted}),m.appendChild(w)}return m}if(r){const l=_([{...c,key:c.waferIndex}],R)[0]?.percent;return l!==void 0&&i.appendChild(f(`${l.toFixed(1)}%`,`Yield \xB7 pass: ${t}`)),i.appendChild(f(String(c.dies.length),"Total dies")),s(i)}i.appendChild(f(String(e.length),"Wafers"));const b=_(e.map(l=>({...l,key:l.waferIndex})),R).map(l=>l.percent).filter(l=>Number.isFinite(l));if(b.length){const l=b.reduce((m,y)=>m+y,0)/b.length,g=pe([{key:"all",items:e.map(m=>({...m,key:m.waferIndex}))}],R)[0]?.percent,C=g!==void 0&&g.toFixed(1)!==l.toFixed(1);i.appendChild(f(`${l.toFixed(1)}%`,`Mean per-wafer yield \xB7 pass: ${t}`,C?`${g.toFixed(1)}% by dies`:void 0))}const u=e.map(l=>l.statsSummary);if(u.every(l=>l!==void 0)){const l=u.reduce((C,m)=>C+m.stats.analyzedDies,0),g=u.reduce((C,m)=>C+m.stats.excludedDies,0);i.appendChild(f(l.toLocaleString(),"Dies analysed",g?`${g.toLocaleString()} excluded`:void 0))}else i.appendChild(f(e.reduce((l,g)=>l+g.dies.length,0).toLocaleString(),"Total dies"));return s(i)}function $e(e,t,r,c,i){const s=p.createElement("div");Object.assign(s.style,{display:"flex",flexDirection:"column",gap:x.lg});const f=e.length===1&&!c;e.length&&!c&&s.appendChild(Le(e));const b=ke(e,c,i,!f);s.appendChild(b.card);const u=Be(e,t,r,c);for(const l of u.elements)b.card.appendChild(l);return u.testValuesCard&&s.appendChild(u.testValuesCard),u.functionalCard&&s.appendChild(u.functionalCard),{card:s,destroy:()=>{b.destroy(),u.destroy()}}}function Ee(e,t,r,c){const i=V(p),s=Se(e),f=a=>{G=a;for(const o of[m,y,S])o!==b&&o?.setAxisPrefs(a)};let b=null;const u=a=>o=>{b=a(),f(o),b=null},l=a=>({...a,testStats:a.statsSummary?.stats.perTestStats}),g=e.map(l),C=r?.map(a=>({key:a.key,items:a.items.map(l)})),m=et({title:"Test value distribution",axisPrefs:G,onAxisPrefsChange:u(()=>m),onTestChange:a=>w(a),selectedTestNumber:L??void 0,items:g,testDefs:t,groups:C,groupLabelText:c,onSaveImage:v,onGroupChange:a=>z(a),onOpen:s?.open,openActionLabel:s?.label,onWaferContextMenu:Q(e),ownerDocument:p}),y=at({title:"Value histogram",axisPrefs:G,onAxisPrefsChange:u(()=>y),onTestChange:a=>w(a),selectedTestNumber:L??void 0,items:e,testDefs:t,groups:r,onGroupChange:a=>z(a),onSaveImage:v,ownerDocument:p}),S=tt({title:"Wafer-to-wafer trend",axisPrefs:G,onAxisPrefsChange:u(()=>S),onTestChange:a=>w(a),selectedTestNumber:L??void 0,items:e.map(a=>({label:a.label,key:a.waferIndex,dies:a.dies,testStats:a.statsSummary?.stats.perTestStats})),testDefs:t,onSaveImage:v,centreLabel:_e(Ve(e.map(a=>a.wafer.metadata)),"mean"),onOpen:j?(a,o)=>q(a,`Wafer ${e.find(h=>h.waferIndex===a)?.label??a}`,o):void 0,onWaferContextMenu:Q(e),ownerDocument:p}),w=a=>{L=a,m.setTest(a),y.setTest(a),S.setTest(a),n.setTest(a)},n=Ze({title:"Process capability",items:e,testDefs:t,onSaveImage:v,selectedTestNumber:L??void 0,onSelectTest:a=>w(a),ownerDocument:p});return i.append(n.card,m.card,y.card,S.card),{card:i,destroy:()=>{n.destroy(),m.destroy(),y.destroy(),S.destroy()}}}function Ie(e){const t=V(p),r=re(e).defs,c=e.flatMap(s=>s.dies),i=(T.sweeps??[]).map(s=>nt({spec:s,dies:c,testDefs:r,onSaveImage:v,ownerDocument:p}));for(const s of i)t.appendChild(s.card);return{card:t,destroy:()=>{for(const s of i)s.destroy()}}}function Pe(e,t,r){const c=V(p),i=rt({title:"Test scatter",items:e,testDefs:t,groups:r,binColors:ee().hard,onSaveImage:v,ownerDocument:p}),s=ot({title:"Test correlation matrix",items:e,testDefs:t,onSaveImage:v,onSaveText:U,onSelectPair:(f,b)=>i.setXY(f,b),ownerDocument:p});return c.append(s.card,i.card),{card:c,destroy:()=>{s.destroy(),i.destroy()}}}function F(e){e?.keepSections||ae(),M.innerHTML="",D.innerHTML="",T.backTab&&D.appendChild(ve(T.backTab));for(const n of Ce)D.appendChild(Te(n.key,n.label));const t=xe();De(t);const r=Re(t,{facetableOnly:!0}).filter(n=>n.splittable),c=p.createElement("div");Object.assign(c.style,{display:"flex",gap:x.md,alignItems:"center",marginLeft:x.xxl,paddingBottom:x.xs});let i;r.length>0?(c.appendChild(ct("Group by:",[{value:"",label:"None"},...r.map(n=>({value:n.key,label:`${n.label} (${n.values.length})`}))],A??"",n=>{A=n||void 0,$=null,F()},{hook:"group-by",ownerDocument:p})),i=r.find(n=>n.key===A)?.label):A=void 0;let s;if(A){const n=new Map,a=[];for(const o of t){const h=We(o.metadata,A)??Me;n.has(h)||(n.set(h,[]),a.push(h)),n.get(h).push(o)}s=a.map(o=>({key:o,items:n.get(o)}))}$!==null&&!s?.some(n=>n.key===$)&&($=null),s&&s.length>0&&c.appendChild(pt(s.map(n=>n.key),"Show:",$,n=>z(n),{ownerDocument:p}).el);let f=null;if(T.onOpenGuide){const n=p.createElement("button");n.type="button",n.innerHTML=Je.help,n.setAttribute("aria-label","User guide"),Object.assign(n.style,{...Ke("bare"),display:"inline-flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",flexShrink:"0"}),de(n,"bare"),Xe(n,"User guide"),n.addEventListener("click",()=>T.onOpenGuide()),Object.assign(n.style,{marginLeft:"auto"}),f=n}D.appendChild(c),f&&D.appendChild(f);const b=$!==null?s?.find(n=>n.key===$):void 0,u=b?.items??t,l=b?void 0:s,g=re(u),C=g.defs,m=C.filter(Ye);L!==null&&!m.some(n=>n.testNumber===L)&&(L=null);const y=e?.keepSections?H.get(E):void 0,S=y??(E==="overview"?$e(u,m,C,l,i):E==="distributions"?Ee(u,m,l,i):E==="sweeps"?Ie(u):Pe(u,m,l));y||H.set(E,S);const w=g.conflicts.filter(n=>n.excluded);if(w.length>0){const n=p.createElement("div");Object.assign(n.style,{color:B.label,fontSize:Y.body,padding:`0 ${W} ${x.sm}`});const a=w.slice(0,6).map(N=>N.testNumber).join(", "),o=w.length>6?`, and ${w.length-6} more`:"",h=w.length===1?"it":"them";n.textContent=`${w.length} test ${w.length===1?"number is":"numbers are"} hidden (${a}${o}) \u2014 the wafers in view describe ${h} differently, so their values cannot be pooled. `+(s&&s.length>0?`Pick one ${i??"group"} under "Show:" to analyse ${h}.`:"Load one test program at a time to analyse them."),n.dataset.wmapWithheldTests=String(w.length),M.appendChild(n)}M.appendChild(S.card)}return{el:P,render:F,destroy:()=>{ae(),P.remove()}}}
1
+ import{buildFacetTable as Ye,facetValueOf as Ge,FACET_NONE_VALUE as He}from"../stats/facets.js";import{mergeTestDefs as re}from"../stats/mergeTestDefs.js";import{isParametricTest as Fe}from"../renderer/buildWaferMap.js";import{waferDisplayLabel as Ne,waferIdentityLabel as Ve}from"../core/waferLabel.js";import{hasDrilldownTargets as ie,waferPopulation as _e}from"./chartPopulation.js";import{openDrilldownMenu as Ue}from"./drilldown.js";import{INPUT_DEFAULT_PASS_BINS as R,itemPassBins as ze,passBinsLabel as le}from"../core/passBins.js";import{NO_DATA_FILL as de}from"../renderer/colorMap.js";import{describeWaferPopulation as qe,populationStat as Qe}from"../stats/population.js";import{LEADING as ce,ALPHA as Ke,SPACE as x,EDGE_GUTTER as Z,FONT as W,CLR as k,RADIUS as pe,SHADOW as Xe,controlStyle as ue,wireControlHover as ee,wireTooltip as Je}from"./toolbar.js";import{ICONS as Ze}from"./icons.js";import{renderCapabilityPanel as et}from"./charts/capability.js";import{renderBoxplotPanel as tt}from"./charts/boxplot.js";import{renderTrendPanel as nt}from"./charts/trend.js";import{renderSweepPanel as at}from"./charts/sweep.js";import{sweepAppliesTo as ot}from"../stats/sweep.js";import{renderHistogramPanel as st}from"./charts/histogram.js";import{renderCorrelationPanel as rt}from"./charts/correlation.js";import{renderScatterPanel as it}from"./charts/scatter.js";import{renderBarPanel as fe}from"./charts/barPanel.js";import{renderBinClusterPanel as lt}from"./charts/binCluster.js";import{renderTestPassRatePanel as dt}from"./charts/testPassRate.js";import{QUANTITY as ct}from"./charts/palette.js";import{cardFrameStyle as pt,makeChartGridWrap as V,makeLabeledSelect as ut,makeLinkedGroupSelect as ft}from"./charts/chartShell.js";import{buildYieldData as _,buildYieldDataCombined as me}from"../stats/yield.js";import{buildBinParetoData as mt}from"../stats/binPareto.js";import{buildLotTestSection as bt,buildLotFunctionalSection as gt,buildMetadataStripBox as ht}from"./summaryPanel.js";import{buildRegionYieldData as be,buildRingRegions as yt,buildQuadrantRegions as wt}from"../stats/regions.js";import{renderRegionYieldDiagram as ge}from"./charts/regionYieldDiagram.js";const he=[{key:"overview",label:"Overview"},{key:"distributions",label:"Distributions"},{key:"correlation",label:"Correlation"}],Ct={key:"sweeps",label:"Sweeps"};export function createInsightsTab(v){const{getItems:ye,getLotStats:we,getBinColors:te,getRingCount:Ce,onSaveImage:T,onSaveText:U,openWafer:Y,focusTest:ne}=v,xe=v.showMetadataStrip??!0,j=v.contentInset??Z,p=v.ownerDocument??document,O=p.createElement("div");Object.assign(O.style,{display:"none",flexDirection:"column",width:"100%",paddingTop:"0"});const Se=Z,P=p.createElement("div");Object.assign(P.style,{paddingLeft:Se});const B=p.createElement("div");Object.assign(B.style,{display:"flex",gap:x.xs,alignItems:"center",background:k.menuBg,border:`1px solid ${k.menuBorder}`,borderRadius:pe.container,boxShadow:Xe.panel,padding:`0 ${x.lg}`,marginBottom:x.lg,marginLeft:j,marginRight:j}),B.setAttribute("role","tablist"),B.addEventListener("keydown",e=>{if(e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;const t=Array.from(B.querySelectorAll('[role="tab"]')),o=t.indexOf(p.activeElement);if(o===-1)return;e.preventDefault();const r=t[(o+(e.key==="ArrowRight"?1:-1)+t.length)%t.length];r.focus(),r.click()});const M=p.createElement("div");Object.assign(M.style,{display:"flex",flexDirection:"column",gap:x.lg,marginTop:"0",paddingLeft:j,paddingRight:j}),O.appendChild(P),O.appendChild(B),O.appendChild(M);const ae=(v.sweeps?.length??0)>0,ve=ae?[...he,Ct]:he;let L=v.defaultView==="sweeps"&&!ae?"overview":v.defaultView??"overview",A,$=null,E=null,G={includeLimits:void 0,clipOutliers:!1};const z=e=>{E!==e&&(E=e,F())};let H=new Map;function oe(){for(const e of H.values())e.destroy();H=new Map}function q(e,t,o){Y?.(e,t,o)}function Q(e){if(e.some(t=>ie(t.testDefs,v.sweeps)))return(t,o,r)=>{const i=e.find(f=>f.waferIndex===t);if(!i||!ie(i.testDefs,v.sweeps))return;r.preventDefault();const l=_e(i.dies,{waferLabel:i.identity,testDefs:i.testDefs,activeTest:o??$??void 0,waferIndex:t});Ue({x:r.clientX,y:r.clientY},r.target,l,{sweeps:v.sweeps,onSaveImage:T})}}function Te(e){return Y?{open:(t,o)=>q(t,`Wafer ${e.find(r=>r.waferIndex===t)?.label??t}`,o)}:ne&&e.length===1?{open:(t,o)=>ne(o),label:"show this test on the map"}:null}function ke(){return ye().map((e,t)=>e==null?null:{metadata:e.wafer.metadata??void 0,dies:e.dies,wafer:e.wafer,label:Ne(e,t),identity:Ve(e),waferIndex:t,passBins:ze(e),statsSummary:e.statsSummary,testDefs:e.testDefs}).filter(e=>e!=null)}function se(e,t){Object.assign(e.style,{background:"none",border:"none",borderBottom:t?`2px solid ${k.iconActive}`:"2px solid transparent",color:t?k.iconActive:k.label,fontWeight:t?"700":"500",fontSize:W.body,padding:`${x.sm} ${Z} ${x.md}`,cursor:"pointer",marginBottom:"-1px"})}function De(e,t){const o=p.createElement("button");o.type="button",o.textContent=t;const r=e===L;return se(o,r),o.dataset.on=r?"true":"false",ee(o,"bare"),o.dataset.wmapInsightsTab=e,o.setAttribute("role","tab"),o.setAttribute("aria-selected",r?"true":"false"),o.tabIndex=r?0:-1,o.addEventListener("click",()=>{L!==e&&(L=e,F({keepSections:!0}))}),o}function Be(e){const t=p.createElement("button");return t.type="button",t.textContent=`\u2039 ${e.label}`,se(t,!1),t.dataset.wmapInsightsBack="1",t.addEventListener("click",e.onBack),t}function $e(e,t,o,r=!0){const i=V(p),l=te();let f="label";const u=o??"group",m=le(e.map(c=>c.passBins)),d=we?.(),g=new Map(d?.lotYieldSeries.map(c=>[c.waferIndex,c.yieldPercent])),C=c=>({...c,label:c.label.replace(/\s*·\s*\d+(\.\d+)?%$/,""),yieldPercent:g.get(c.waferIndex),key:c.waferIndex}),b=e.map(C),h=t?.map(c=>({key:c.key,items:c.items.map(C)})),S=()=>h?me(h,R,f):_(b,R,f),w={title:t?`Yield by ${u} (pass: ${m})`:`Yield by wafer (pass: ${m})`,data:S(),selfControl:{current:f,options:[["yield","Sort: yield"],["label",t?`Sort: ${u}`:"Sort: wafer ID"]],onChange:c=>(f=c,{data:S()})},barColor:()=>ct,valueLabel:c=>`${c.percent.toFixed(1)}%`,reference:c=>{if(c.length<3)return null;const D=c.map(J=>J.percent).sort((J,Me)=>J-Me),I=D.length%2?D[(D.length-1)/2]:(D[D.length/2-1]+D[D.length/2])/2;return{value:I,label:`median ${I.toFixed(1)}%`}},drill:h?{onOpenGroup:c=>{const D=h.find(I=>I.key===c.label)?.items??[];return{data:_(D,R,f),title:`Yield by wafer \u2014 ${u}: ${c.label} (pass: ${m})`}},onBack:()=>({data:S(),title:`Yield by ${u} (pass: ${m})`}),groupLabelText:u}:void 0,onOpen:Y?c=>{typeof c.key=="number"&&q(c.key,`Wafer ${c.label}`)}:void 0,onWaferContextMenu:Q(e),ownerDocument:p};let n=null;if(r&&(n=fe(w,T),n.card.style.minHeight="360px",i.appendChild(n.card)),t){const c=lt({title:"Hard bin pareto",groups:t.map(D=>({key:D.key,items:D.items.map(I=>({dies:I.dies,hardBinCounts:I.statsSummary?.stats.hardBinCounts,softBinCounts:I.statsSummary?.stats.softBinCounts}))})),onSaveImage:T,ownerDocument:p});return c.card.style.minHeight="360px",i.appendChild(c.card),{card:i,destroy:()=>{n?.destroy(),c.destroy()}}}let a="hbin";const s=c=>c===void 0?de:(a==="hbin"?l.hard:l.soft).get(c)??de,y=e.map(c=>({dies:c.dies,hardBinCounts:c.statsSummary?.stats.hardBinCounts,softBinCounts:c.statsSummary?.stats.softBinCounts})),N=()=>mt(y,a),je={title:"Hard bin pareto",data:N(),selfControl:{current:a,options:[["hbin","Hard bins"],["sbin","Soft bins"]],onChange:c=>(a=c,{data:N(),title:`${a==="hbin"?"Hard":"Soft"} bin pareto`})},barColor:c=>s(c.binCode),ownerDocument:p},X=fe(je,T);return X.card.style.minHeight="360px",i.appendChild(X.card),{card:i,destroy:()=>{n?.destroy(),X.destroy()}}}function K(){const e=p.createElement("div");return e.dataset.wmapChartCard="1",Object.assign(e.style,{...pt(),display:"flex",flexDirection:"column",gap:x.lg,minWidth:"0"}),e}function Ee(e){if(P.innerHTML="",P.style.marginBottom="0",!xe)return;const t=ht(e.map(o=>({metadata:o.metadata})),void 0,{facetableOnly:!1});t&&(t.style.marginBottom="0",P.appendChild(t),P.style.marginBottom=x.xs)}function Le(e,t,o,r){if(!e.length)return{elements:[],testValuesCard:null,functionalCard:null,destroy:()=>{}};const i=e.map(s=>s.wafer),l=e.map(s=>s.dies),f=e.flatMap(s=>s.dies),u=e.map(s=>s.statsSummary),m=u.every(s=>s!==void 0)?u:void 0,d=Ce?.()??4,g=[],C=[],h=dt({groups:(r??[{key:"",items:e}]).map(s=>({key:s.key,items:s.items.map(y=>({dies:y.dies,testSpecYield:y.statsSummary?.stats.testSpecYield,functionalYield:y.statsSummary?.stats.functionalYield}))})),testDefs:o,onSaveImage:T,ownerDocument:p});h.card.style.minHeight="300px",g.push(h.card),C.push(h.destroy);const S=be(l,i,d,s=>e[s].passBins,yt);if(S.length){const s=ge({title:"Ring yield",mode:"ring",rows:S,onSaveImage:T,ownerDocument:p});g.push(s.card),C.push(s.destroy)}const w=be(l,i,d,s=>e[s].passBins,wt);if(w.length){const s=ge({title:"Quadrant yield",mode:"quadrant",rows:w,onSaveImage:T,ownerDocument:p});g.push(s.card),C.push(s.destroy)}let n=null;if(t.length){const s=bt(f,t,void 0,m,U,l.map(y=>({dies:y})),void 0,"full");if(s){const y=K();y.appendChild(s),n=y}}let a=null;if(o.length){const s=gt(f,o,m,U);if(s){const y=K();y.appendChild(s),a=y}}return{elements:g,testValuesCard:n,functionalCard:a,destroy:()=>{for(const s of C)s()}}}function Ie(e){const t=le(e.map(d=>d.passBins)),o=e.length===1,r=e[0],i=K();Object.assign(i.style,{flexDirection:"row",flexWrap:"wrap",gap:x.md});const l=d=>{const g=d.lastElementChild;return g&&Object.assign(g.style,{borderRight:"none",paddingRight:"0",marginRight:"0"}),d};function f(d,g,C){const b=p.createElement("div");Object.assign(b.style,{display:"flex",alignItems:"baseline",gap:x.sm,paddingRight:x.xxl,marginRight:x.md,borderRight:`1px solid ${k.menuBorder}`});const h=p.createElement("div");h.textContent=d,Object.assign(h.style,{fontSize:W.heading,fontWeight:"700",color:k.value,lineHeight:ce.tight});const S=p.createElement("div");if(S.textContent=g,Object.assign(S.style,{fontSize:W.body,color:k.label}),b.append(h,S),C){const w=p.createElement("div");w.textContent=C,Object.assign(w.style,{fontSize:W.meta,color:k.label,opacity:Ke.muted}),b.appendChild(w)}return b}if(o){const d=_([{...r,key:r.waferIndex}],R)[0]?.percent;return d!==void 0&&i.appendChild(f(`${d.toFixed(1)}%`,`Yield \xB7 pass: ${t}`)),i.appendChild(f(String(r.dies.length),"Total dies")),l(i)}i.appendChild(f(String(e.length),"Wafers"));const u=_(e.map(d=>({...d,key:d.waferIndex})),R).map(d=>d.percent).filter(d=>Number.isFinite(d));if(u.length){const d=u.reduce((b,h)=>b+h,0)/u.length,g=me([{key:"all",items:e.map(b=>({...b,key:b.waferIndex}))}],R)[0]?.percent,C=g!==void 0&&g.toFixed(1)!==d.toFixed(1);i.appendChild(f(`${d.toFixed(1)}%`,`Mean per-wafer yield \xB7 pass: ${t}`,C?`${g.toFixed(1)}% by dies`:void 0))}const m=e.map(d=>d.statsSummary);if(m.every(d=>d!==void 0)){const d=m.reduce((C,b)=>C+b.stats.analyzedDies,0),g=m.reduce((C,b)=>C+b.stats.excludedDies,0);i.appendChild(f(d.toLocaleString(),"Dies analysed",g?`${g.toLocaleString()} excluded`:void 0))}else i.appendChild(f(e.reduce((d,g)=>d+g.dies.length,0).toLocaleString(),"Total dies"));return l(i)}function Oe(e,t,o,r,i){const l=p.createElement("div");Object.assign(l.style,{display:"flex",flexDirection:"column",gap:x.lg});const f=e.length===1&&!r;e.length&&!r&&l.appendChild(Ie(e));const u=$e(e,r,i,!f);l.appendChild(u.card);const m=Le(e,t,o,r);for(const d of m.elements)u.card.appendChild(d);return m.testValuesCard&&l.appendChild(m.testValuesCard),m.functionalCard&&l.appendChild(m.functionalCard),{card:l,destroy:()=>{u.destroy(),m.destroy()}}}function Pe(e,t,o,r){const i=V(p),l=Te(e),f=a=>{G=a;for(const s of[b,h,S])s!==u&&s?.setAxisPrefs(a)};let u=null;const m=a=>s=>{u=a(),f(s),u=null},d=a=>({...a,testStats:a.statsSummary?.stats.perTestStats}),g=e.map(d),C=o?.map(a=>({key:a.key,items:a.items.map(d)})),b=tt({title:"Test value distribution",axisPrefs:G,onAxisPrefsChange:m(()=>b),onTestChange:a=>w(a),selectedTestNumber:$??void 0,items:g,testDefs:t,groups:C,groupLabelText:r,onSaveImage:T,onGroupChange:a=>z(a),onOpen:l?.open,openActionLabel:l?.label,onWaferContextMenu:Q(e),ownerDocument:p}),h=st({title:"Value histogram",axisPrefs:G,onAxisPrefsChange:m(()=>h),onTestChange:a=>w(a),selectedTestNumber:$??void 0,items:e,testDefs:t,groups:o,onGroupChange:a=>z(a),onSaveImage:T,ownerDocument:p}),S=nt({title:"Wafer-to-wafer trend",axisPrefs:G,onAxisPrefsChange:m(()=>S),onTestChange:a=>w(a),selectedTestNumber:$??void 0,items:e.map(a=>({label:a.label,key:a.waferIndex,dies:a.dies,testStats:a.statsSummary?.stats.perTestStats})),testDefs:t,onSaveImage:T,centreLabel:Qe(qe(e.map(a=>a.wafer.metadata)),"mean"),onOpen:Y?(a,s)=>q(a,`Wafer ${e.find(y=>y.waferIndex===a)?.label??a}`,s):void 0,onWaferContextMenu:Q(e),ownerDocument:p}),w=a=>{$=a,b.setTest(a),h.setTest(a),S.setTest(a),n.setTest(a)},n=et({title:"Process capability",items:e,testDefs:t,onSaveImage:T,selectedTestNumber:$??void 0,onSelectTest:a=>w(a),ownerDocument:p});return i.append(n.card,b.card,h.card,S.card),{card:i,destroy:()=>{n.destroy(),b.destroy(),h.destroy(),S.destroy()}}}function Ae(e){const t=V(p),o=re(e).defs,r=e.flatMap(u=>u.dies),i=v.sweeps??[],l=i.filter(u=>!ot(u,o));l.length>0&&t.appendChild(Re(l,i.length));const f=i.map(u=>at({spec:u,dies:r,testDefs:o,onSaveImage:T,ownerDocument:p}));for(const u of f)t.appendChild(u.card);return{card:t,destroy:()=>{for(const u of f)u.destroy()}}}function Re(e,t){const o=p.createElement("div");o.setAttribute("role","status"),Object.assign(o.style,{gridColumn:"1 / -1",display:"flex",flexWrap:"wrap",alignItems:"center",gap:x.md,padding:`${x.sm} ${x.md}`,background:k.warnBg,border:`1px solid ${k.warnBorder}`,borderRadius:pe.container,color:k.warnText,fontSize:W.body,lineHeight:ce.base});const r=e.length,i=p.createElement("span");if(i.style.flex="1 1 24ch",i.textContent=(r===t?r===1?"This sweep names no test in this data":"None of these sweeps names a test in this data":`${r} of ${t} sweeps name no test in this data: ${e.map(l=>l.title).join(", ")}`)+` \u2014 ${r===1?"it":"they"} may belong to another test program.`,o.appendChild(i),v.onRemoveSweeps){const l=p.createElement("button");l.type="button",Object.assign(l.style,ue("outlined")),l.textContent=r===1?"Remove this sweep":`Remove these ${r} sweeps`,ee(l);const f=e.map(u=>u.id);l.addEventListener("click",()=>v.onRemoveSweeps(f)),o.appendChild(l)}return o}function We(e,t,o){const r=V(p),i=it({title:"Test scatter",items:e,testDefs:t,groups:o,binColors:te().hard,onSaveImage:T,ownerDocument:p}),l=rt({title:"Test correlation matrix",items:e,testDefs:t,onSaveImage:T,onSaveText:U,onSelectPair:(f,u)=>i.setXY(f,u),ownerDocument:p});return r.append(l.card,i.card),{card:r,destroy:()=>{l.destroy(),i.destroy()}}}function F(e){e?.keepSections||oe(),M.innerHTML="",B.innerHTML="",v.backTab&&B.appendChild(Be(v.backTab));for(const n of ve)B.appendChild(De(n.key,n.label));const t=ke();Ee(t);const o=Ye(t,{facetableOnly:!0}).filter(n=>n.splittable),r=p.createElement("div");Object.assign(r.style,{display:"flex",gap:x.md,alignItems:"center",marginLeft:x.xxl,paddingBottom:x.xs});let i;o.length>0?(r.appendChild(ut("Group by:",[{value:"",label:"None"},...o.map(n=>({value:n.key,label:`${n.label} (${n.values.length})`}))],A??"",n=>{A=n||void 0,E=null,F()},{hook:"group-by",ownerDocument:p})),i=o.find(n=>n.key===A)?.label):A=void 0;let l;if(A){const n=new Map,a=[];for(const s of t){const y=Ge(s.metadata,A)??He;n.has(y)||(n.set(y,[]),a.push(y)),n.get(y).push(s)}l=a.map(s=>({key:s,items:n.get(s)}))}E!==null&&!l?.some(n=>n.key===E)&&(E=null),l&&l.length>0&&r.appendChild(ft(l.map(n=>n.key),"Show:",E,n=>z(n),{ownerDocument:p}).el);let f=null;if(v.onOpenGuide){const n=p.createElement("button");n.type="button",n.innerHTML=Ze.help,n.setAttribute("aria-label","User guide"),Object.assign(n.style,{...ue("bare"),display:"inline-flex",alignItems:"center",justifyContent:"center",width:"24px",height:"24px",flexShrink:"0"}),ee(n,"bare"),Je(n,"User guide"),n.addEventListener("click",()=>v.onOpenGuide()),Object.assign(n.style,{marginLeft:"auto"}),f=n}B.appendChild(r),f&&B.appendChild(f);const u=E!==null?l?.find(n=>n.key===E):void 0,m=u?.items??t,d=u?void 0:l,g=re(m),C=g.defs,b=C.filter(Fe);$!==null&&!b.some(n=>n.testNumber===$)&&($=null);const h=e?.keepSections?H.get(L):void 0,S=h??(L==="overview"?Oe(m,b,C,d,i):L==="distributions"?Pe(m,b,d,i):L==="sweeps"?Ae(m):We(m,b,d));h||H.set(L,S);const w=g.conflicts.filter(n=>n.excluded);if(w.length>0){const n=p.createElement("div");Object.assign(n.style,{color:k.label,fontSize:W.body,padding:`0 ${j} ${x.sm}`});const a=w.slice(0,6).map(N=>N.testNumber).join(", "),s=w.length>6?`, and ${w.length-6} more`:"",y=w.length===1?"it":"them";n.textContent=`${w.length} test ${w.length===1?"number is":"numbers are"} hidden (${a}${s}) \u2014 the wafers in view describe ${y} differently, so their values cannot be pooled. `+(l&&l.length>0?`Pick one ${i??"group"} under "Show:" to analyse ${y}.`:"Load one test program at a time to analyse them."),n.dataset.wmapWithheldTests=String(w.length),M.appendChild(n)}M.appendChild(S.card)}return{el:O,render:F,destroy:()=>{oe(),O.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 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
+ 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 H,CLR as u,wireTooltip as A}from"./toolbar.js";import{fmt as v}from"../renderer/fmt.js";function d(o,n,e){const a=document.createElement(o);return n&&Object.assign(a.style,n),e!==void 0&&(a.textContent=e),a}function W(o,n,e,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"&&e&&(e.limitLow!==void 0||e.limitHigh!==void 0);let t,l;b?(t=e.limitLow!==void 0?e.limitLow:isFinite(p)?p:0,l=e.limitHigh!==void 0?e.limitHigh:isFinite(m)?m:1):(t=isFinite(p)?p:0,l=isFinite(m)?m:1),t===l&&(l=t+1);const h=r=>Math.min(1,Math.max(0,r));if(x&&t>0&&l>0){const r=Math.log10(t),s=Math.log10(l)-r;return c=>c<=0?0:h((Math.log10(c)-r)/s)}return r=>h((r-t)/(l-t))}function E(o,n,e,a,x,p,m,b){const t=d("div",{display:"flex",flexDirection:"column",gap:y.xxs,minWidth:"0",flex:"1",minHeight:"0"});t.appendChild(d("div",{fontSize:H.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,e,n,m,b),w=Math.max(1,...o.map(i=>i.count)),S=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}),S.appendChild(g)}const L=[];for(const[i,g]of[[n?.limitLow,"Lo limit"],[n?.limitHigh,"Hi limit"]]){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",S.appendChild(M),L.push({pct:C,text:`${g} ${v(i,n?.unit)}`})}if(t.appendChild(S),L.length){const i=d("div",{position:"relative",height:"14px"});for(const{pct:g,text:C}of L){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:H.body,fontWeight:"600",color:u.text,background:u.panelBg,border:`1px solid ${u.value}`,borderRadius:I.control,padding:"0 3px",lineHeight:"12px"},C))}t.appendChild(i)}const R=d("div",{display:"flex",justifyContent:"space-between",fontSize:H.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))),t.appendChild(R),t}export function buildMaplessSummary(o,n,e){const{plotMode:a,activeTest:x,hbinDefs:p,sbinDefs:m,binColors:b,valueColorScheme:t,reverseValueScheme:l,logScale:h=!1,colorbarRangeMode:r="spec",valueRangeDies:s}=e;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,t,l,s??o,r,h)}return d("div",{padding:y.xl,fontSize:H.body,color:u.label,textAlign:"center"},"No summary available for this view.")}
@@ -1 +1 @@
1
- import{getUniqueTestNumbers as Do,resolveTestNumber as ko,findTestDef as Eo,collectMetadataValues as Bo}from"../renderer/buildView.js";import{metadataCategoricalValue as Oo}from"../core/metadata.js";import{resolveBinColorsForMaps as To,mergeBinDefs as Ye,binColorWarning as Lo,mixedPassBinsWarning as Ro,binColorsEqual as Io}from"../renderer/binColors.js";import{itemPassBins as Wo,INPUT_DEFAULT_PASS_BINS as $o}from"../core/passBins.js";import{NO_DATA_FILL as Ao}from"../renderer/colorMap.js";import{metadataValueColor as Po}from"../renderer/colorMap.js";import{resolveCanvasTheme as Fo}from"./canvasTheme.js";import{ICONS as We}from"./icons.js";import{SHADOW as $e,LEADING as Ze,TRACKING as Ho,controlStyle as jo,wireControlHover as xt,SPACE as w,EDGE_GUTTER as oe,MAP_CHROME_INSET as Vo,RADIUS as z,FONT as L,CLR as h,sevColor as gn,MODE_LABELS as No,BIN_LEGEND_MODES as hn,STACKED_MODES as be,Z_ABOVE as bn,applyOverlayZ as zo,getTooltip as _o,hideTooltip as yn,createToolbarHelpers as Go,buildModeMenuEl as Ko,openDetachWindow as qo,openFloatingWindow as Uo,openModal as Xo,openReportModal as Yo,copyWmapThemeTokens as Zo,syncWmapPopupTheme as Qo,openUserGuideWindow as Jo,makePaletteBtn as ei,makeLogScaleBtn as ti,makeLegendStyleBtn as ni,makeOverlaysBtn as oi,makeOrientationBtn as ii,menuLayerFor as wn,saveImageBlob as vn,markMenuTrigger as Ae,wireMenuA11y as xn,wireExpandToggle as Cn,wireTooltip as Sn,requestedPassFailDisplay as Mn,overlayMenuRows as ai,anyOverlayActive as li,logWmapVersionOnce as si,buildDataModeEntries as ri,metadataKeyHasData as di,metadataModeEntry as ci}from"./toolbar.js";import{waferDisplayLabel as Qe,waferIdentityLabel as Dn}from"../core/waferLabel.js";import{metadataDisplayValue as ui}from"../core/metadata.js";import{withExportContext as fi,noticeDownloadFilenameChange as pi}from"./exportName.js";import{sortBinsForDisplay as mi}from"../stats/binPareto.js";import{diePassStatus as gi}from"../core/dies.js";import{aggregateValues as hi,aggregateBinCounts as kn}from"../core/aggregates.js";import{renderWaferMap as bi,renderWaferMapCard as En,toPublicViewOptions as Bn}from"./renderWaferMap.js";import{hasDrilldownTargets as yi,waferPopulation as wi}from"./chartPopulation.js";import{classifyChanged as vi,COLOR_KEYS as xi}from"./renderWaferMap.js";import{buildWaferMap as Ci,getTestPassStatus as On,isParametricTest as Ct,getDieTestValue as Si}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Je}from"../stats/analyzeWaferMap.js";import{collectWarnings as Mi,buildWarningsMenuEl as Di,severityOf as ki}from"./warnings.js";import{compareNatural as St,arrayEqual as Tn}from"../core/utils.js";import{createSummaryPanelEl as Mt,buildMetadataStripRow as Ei,buildCompactMetadataRows as Ln,metadataEntries as Rn,renderLotSummaryContentSteps as Bi,reportMapsFromItems as Oi}from"./summaryPanel.js";import{renderLotReportHtml as Ti}from"../stats/renderSummaryReport.js";import{prettyKey as Li}from"../stats/facets.js";import{testLabel as Ri,markedTestLabel as Ii,derivedFields as Wi}from"../renderer/testLabel.js";import{mergeTestDefs as $i}from"../stats/mergeTestDefs.js";import{getDieKey as Ai,hasPosition as Pi}from"../core/dies.js";import{runChunked as Fi}from"./chunked.js";function In(f){if(typeof f!="number"||!Number.isFinite(f))return;const C=Math.round(f);return C>=1?C:void 0}const Dt=12;function Hi(f,C,p){let A=C;if(C.length>Dt){const E=C.slice(0,Dt-1),I=C.slice(Dt-1),H=I.reduce((X,ie)=>X+ie.count,0);A=[...E,{color:h.label,count:H,label:`Other (${I.length} bins)`}]}const k=f.createElement("div");Object.assign(k.style,{display:"flex",columnGap:"1px",width:"100%",height:"8px",borderRadius:z.control,overflow:"hidden",border:`1px solid ${h.menuBorder}`,boxSizing:"border-box",marginTop:w.xs,flexShrink:"0"}),k.setAttribute("role","img"),k.setAttribute("aria-label",`Population split: ${A.map(E=>`${E.label} ${et(E.count/p*100)}`).join(", ")}`);for(const E of A){const I=E.count/p*100,H=f.createElement("div");Object.assign(H.style,{flex:`${I} 1 0`,minWidth:I>0?"2px":"0",background:E.color}),Sn(H,`${E.label} \xB7 ${E.count.toLocaleString()} dies \xB7 ${et(I)}`),k.appendChild(H)}return k}function et(f){return f>0&&f<.1?"<0.1%":`${f.toFixed(1)}%`}function Wn(f,C,p){const A=new Map;let k=0,E=0;for(const I of f){const H=p?new Set(p(I)):void 0;for(const X of I.dies){if(X.partial||X.edgeExcluded)continue;const ie=C(X);ie!==void 0&&(A.set(ie,(A.get(ie)??0)+1),k++,H&&gi(X,H)&&E++)}}return{counts:A,total:k,pass:E}}function $n(f,C){const p=f.ownerDocument.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:`${w.xxs} ${w.xs}`,borderRadius:z.control});const A=f.ownerDocument.createElement("span");Object.assign(A.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:C.color,border:C.isActive?`2px solid ${h.iconActive}`:`1px solid ${h.menuBorder}`,borderRadius:z.control,boxSizing:"border-box"});const k=f.ownerDocument.createElement("span");if(k.textContent=C.label,Object.assign(k.style,{fontWeight:C.isActive?"700":"400",color:C.isActive?h.iconActive:h.text,whiteSpace:"nowrap"}),p.appendChild(A),p.appendChild(k),C.count!==void 0){const E=f.ownerDocument.createElement("span");if(E.textContent=C.count.toLocaleString(),Object.assign(E.style,{color:C.isActive?h.iconActive:h.text,fontWeight:C.isActive?"700":"400",whiteSpace:"nowrap"}),p.appendChild(E),C.percent!==void 0){const I=f.ownerDocument.createElement("span");I.textContent=et(C.percent),Object.assign(I.style,{color:h.label,whiteSpace:"nowrap"}),p.appendChild(I)}}p.setAttribute("role","button"),p.setAttribute("aria-pressed",C.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=h.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=h.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",C.onClick),p.addEventListener("keydown",E=>{(E.key==="Enter"||E.key===" ")&&(E.preventDefault(),C.onClick())}),f.appendChild(p)}export function renderWaferGallery(f,C,p={}){si();const A=6;let k=In(p.columns);const E=p.showHelpButton??!1,I=p.userGuideExtension,H=p.insights?.enabled??!1,X=p.insights?.sweeps?{sweeps:p.insights.sweeps}:void 0,ie=zo(p.zIndex),re=p.summaryPanel,An=e=>[...Wo(e)],kt=()=>v.flatMap(e=>e?[e.ringCount??4]:[]),tt=()=>kt()[0]??4;function Pn(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,ye=p.viewOptions?.legendPosition??"default",Pe=p.perCardLegend??!1;function we(){const e=c.plotMode??"hardBin";return hn.has(e)?null:c.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 Et(){const e=Pe||we()!==null;for(const t of S)t&&t.setOptions({showLegend:e})}let c={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},S=[],ae=[],de=[],R=[];const Fe=fi(()=>{const e=R.filter(n=>n!=null);return{lots:[...new Set(e.map(n=>ui(n.wafer.metadata?.lot)).filter(n=>n!==void 0))].sort(St),...e.length===1?{wafer:Dn(e[0])}:{waferCount:e.length}}},p.onSaveImage,p.onSaveText);pi(p.downloadFilename);let v=C.map(e=>typeof e=="function"?null:e);function Bt(){return $i(v)}function ve(){if(v.some(e=>e?.testDefs?.length))return Bt().defs}let xe=0,He=0;const _=new Map;let Fn=0,P=null,Ce=null,Ot=new Set,b=null,Hn={};function Tt(e){return v[e]?.statsSummary??V?.perWafer.find(t=>t.waferIndex===e)?.summary}function nt(){return!!(v.some(e=>e?.statsSummary?.findings.length)||V?.perWafer.some(e=>e.summary.findings.length))}const jn=_o(),ce=Go(jn),{makeBtn:Q,setActive:Se,makeSep:G,makeMenuRow:Vn,makeMenuSection:Nn,makeDropdown:Lt,closeOpenMenu:je,getOpenMenu:Me,setOpenMenu:De}=ce;f.ownerDocument.addEventListener("click",je,!0);const Rt=()=>yn();window.addEventListener("blur",Rt);let It=p.findingsNotice;function Wt(e){Ot=new Set(e);const t=[...$.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((o,d)=>{const l=Ot.has(d);o.style.outline=l?`3px solid ${h.findingHighlight}`:"",o.style.outlineOffset=l?"-3px":"",l&&n===void 0&&(n=o)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function $t(){Wt([])}function At(){for(const e of S)e&&e.clearSelection()}function ot(e,t){const n=new Set(e),o=t??S.map((d,l)=>l);for(const d of o){const l=R[d],a=S[d];if(!l||!a)continue;const r=l.dies.filter(i=>n.has(Ai(i)));a.setSelection(r)}}function zn(){const e=[];for(let t=0;t<v.length;t++){const n=v[t];if(!n)continue;const o=Tt(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 _n(e){const t=R[e]??v[e];t&&Ie(e,t)}function Gn(e){const t=Tt(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 Kn(){Yo(Ti(Oi(v,$o,tt())),{anchor:f})}function qn(){if(!b)return;b.innerHTML="";const e=zn();if(v.length>0){const n=f.ownerDocument.createElement("div"),o=e.length,d=v.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:L.body,color:h.label,marginBottom:w.md}),b.appendChild(n)}if(e.length>0){const n=f.ownerDocument.createElement("button");n.type="button",n.textContent="Summary report",Object.assign(n.style,{...jo("outlined"),marginBottom:w.lg,display:"block",width:"100%",textAlign:"left"}),xt(n),n.addEventListener("click",Kn),b.appendChild(n)}if(e.length===0){const n=f.ownerDocument.createElement("div");Object.assign(n.style,{color:h.icon,fontSize:L.body,padding:"4px 0"}),n.textContent="No findings on any wafer.",b.appendChild(n)}else for(const{index:n,item:o,unusualCount:d,notableCount:l,totalCount:a}of e){const r=d?"unusual":l?"notable":"info",i=d+l||a,s=f.ownerDocument.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:w.xs,border:"none",borderLeft:`3px solid ${gn(r)}`,borderRadius:z.control,background:h.bgHover,cursor:"pointer",fontSize:L.body,textAlign:"left",boxSizing:"border-box"}),s.addEventListener("mouseover",()=>{s.style.background=h.bgActive}),s.addEventListener("mouseout",()=>{s.style.background=h.bgHover});const u=f.ownerDocument.createElement("span");u.textContent=Qe(o,n),Object.assign(u.style,{color:h.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const m=f.ownerDocument.createElement("span");m.textContent=String(i),s.setAttribute("aria-label",`${Qe(o,n)} \u2014 ${i} finding${i===1?"":"s"}${d?`, ${d} unusual`:""} \u2014 view wafer`),Object.assign(m.style,{marginLeft:w.sm,flexShrink:"0",background:gn(r),color:"#fff",borderRadius:z.container,padding:"1px 5px",fontSize:L.body,fontWeight:"600"}),s.appendChild(u),s.appendChild(m),s.addEventListener("click",()=>Ie(n,o)),b.appendChild(s)}const t=f.ownerDocument.createElement("div");t.style.height="12px",b.appendChild(t)}let ue=null,ke=null;function N(){if(b)if(ue?.cancel(),ue=null,V){const e=Ye(v.map(n=>n?.hbinDefs)),t=Ye(v.map(n=>n?.sbinDefs));ue=Fi(Bi(b,{lotSummary:V,items:v,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:ve(),ringCount:tt(),binColors:c.binColors,plotMode:c.plotMode??"hardBin",fallbackFormat:c.fallbackFormat,activeFindingId:Ce,warnings:p.warnings?.display??!0?J:[],findingsFilter:Hn,findingsNotice:It,onFindingsFilterChange:N,onSaveText:Fe.onSaveText,onFindingClick:(n,o)=>{Ce===n.id?it():Xn(n,o),N()},onWaferClick:_n,findingsFor:Gn,dieListOptions:p.dieList}),{onDone:()=>{const n=ke;ke=null,n?.()}})}else qn()}function Un(e){const t=e.highlight;return t?.kind==="wafer"&&t.waferIndices?.length?t.waferIndices:null}function Pt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}let Ve=[];function Ft(){if(Ve.length!==0){for(const e of Ve)S[e]?.setOptions({plotMode:c.plotMode,activeTest:c.activeTest});Ve=[]}}function it(){Ce=null,$t(),At(),Ft(),T({highlightBin:void 0},{fireCallback:!1})}function Xn(e,t){if(Ce===e.id){it();return}Ce=e.id,t.style.background=h.bgActive,t.style.fontWeight="600",Ft();const{kind:n,index:o}=e.variable;if(n==="test"){const l=o??0,a=ve();if(a===void 0||a.some(i=>i.testNumber===l))T({plotMode:"value",activeTest:l,highlightBin:void 0},{fireCallback:!1});else{T({highlightBin:void 0},{fireCallback:!1});const s=be.has(c.plotMode??"hardBin")?null:Un(e);if(s){for(const u of s)S[u]?.setOptions({plotMode:"value",activeTest:l});Ve=[...s]}}}else n==="softBin"?T({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):T({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1});$t(),At();const d=e.highlight;if(d.kind==="wafer"){Wt(d.waferIndices);const l=Pt(e);for(const a of d.waferIndices){const s=R[a]?.statsSummary?.findings.find(u=>Pt(u)===l)?.highlight?.dieKeys;s?.length&&ot(s,[a])}}else d.kind==="bin"?d.dieKeys?.length&&ot(d.dieKeys):(d.kind==="region"||d.kind==="dies")&&d.dieKeys?.length&&ot(d.dieKeys)}function le(){if(!P)return;const e=!!b;P.style.display=(V||nt())&&e&&!Te?"flex":"none";const t=b?b.style.display!=="none":!1;(V?.hasNotableFindings||v.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?P.style.color=h.findingIndicator:P.dataset.active||(P.style.color=h.icon)}const W=f.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:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.control,padding:"0",boxShadow:$e.panel,flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const Ht=()=>{const e=Me();e&&(e.remove(),De(null)),Ae(Y,!1)},Y=Q("mode","Plot mode",()=>{if(Me()){Ht();return}const e=v.flatMap(y=>y?.dies??[]),t=ve(),{testEntries:n,binEntries:o,stackedEntries:d}=ri(e,t,{includeStacked:!0}),l=v.filter(Boolean).length,a=y=>{if(y===void 0)return l;let B=0;for(const j of v)j?.dies?.some(U=>On(U,y)!==void 0||U.testValues?.[y]!==void 0)&&B++;return B},r=l<2?n:n.map(y=>{const B=a(y.activeTest);return B===l?y:{...y,label:`${y.label} \u2014 ${B} of ${l} wafers`}}),i=c.plotMode??"hardBin",s=c.activeTest??0;function u(y){return y.plotMode!==i?!1:y.plotMode==="value"?s===(y.activeTest??0):y.plotMode==="metadata"?c.activeMetadataKey===y.activeMetadataKey:!0}function m(y,B){y.activeTest!==void 0?T({plotMode:"value",activeTest:y.activeTest,activeMetadataKey:void 0,logScale:y.logScale}):y.activeMetadataKey!==void 0?T({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:y.activeMetadataKey,passFailDisplay:"off"}):T({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),B.remove(),De(null),Ae(Y,!1)}const M=new Set,D=v.flatMap(y=>y?.metadataFields??[]).filter(y=>!M.has(y.key)&&M.add(y.key)).filter(y=>di(e,y.key)).map(ci),x=Ko(Y.getBoundingClientRect(),r,o,d,u,m,{makeMenuRow:Vn,makeMenuSection:Nn},i,Y.ownerDocument.defaultView??window,D);wn(Y).appendChild(x),De(x),Ae(Y,!0),xn(x,Y,Ht)});Ae(Y,!1);const Yn=()=>R.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:Zn,sync:jt}=ei(ce,()=>({...c,plotMode:c.plotMode??"hardBin"}),Yn,e=>T(e));jt();const Qn=C.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Ne(){const e=ve(),{testNumber:t}=ko(c.activeTest??0,e);return{testNumber:t,td:Eo(e,t)}}function Vt(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Ne();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function Ee(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Ne();return e!==void 0&&!Ct(e)}function Jn(){if((c.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Ne();return v.some(n=>n?.dies?.some(o=>On(o,e,t)!==void 0))}function eo(e,t){if(!t||!Ct(t))return;const n=t.limitLow!==void 0||t.limitHigh!==void 0;if((Mn(c)==="spec"&&n?"spec":c.colorbarRangeMode??"spec")==="spec"&&n)return;let l=1/0,a=-1/0;for(const r of v)if(r)for(const i of r.dies){const s=Si(i,e);s!==void 0&&(s<l&&(l=s),s>a&&(a=s))}if(isFinite(l))return l===a?[l,l+1]:[l,a]}function at(e,t,n){const o=c[e];if(o===t||o!=null&&t!=null&&n(o,t))return!1;c={...c,[e]:t};for(const d of S)d&&d.setOptions({[e]:t});return!0}function Nt(){if((c.plotMode??"hardBin")!=="metadata")return;const e=c.activeMetadataKey;if(!e)return;const t=new Set;for(const n of v)if(n)for(const o of Bo(n.dies,e))t.add(o);return{key:e,values:[...t].sort(St)}}function lt(){at("metadataValueOrder",Nt(),(e,t)=>e.key===t.key&&Tn(e.values,t.values))}function st(){if((c.plotMode??"hardBin")!=="value")return;const{testNumber:e,td:t}=Ne(),n=eo(e,t);at("valueRange",n?{test:e,range:n}:void 0,(d,l)=>{const a=s=>Array.isArray(s)?{test:void 0,range:s}:{test:s.test,range:s.range},r=a(d),i=a(l);return r.test===i.test&&Tn(r.range,i.range)})}let rt=!1;function to(){if(rt)return;rt=!0,(f.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{rt=!1,st(),lt(),_t()})}let dt=!1;function no(){if(dt)return;dt=!0,(f.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{dt=!1,qe()})}let zt=[];function fe(){const{colors:e,mixedHardBins:t}=To(v.filter(n=>n!=null),{binColorScheme:c.binColorScheme,useDefinedBinColors:c.useDefinedBinColors});return zt=t,e}function _t(){at("binColors",fe(),Io),Be()}const oo=oi(ce,()=>ai(c,Qn,{functionalActive:Ee(),hasLimits:Vt()&&!Ee(),hasRecorded:Jn()&&!Ee(),binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},e=>T(e)),()=>li(c)),{btn:io,sync:Gt}=ni(ce,()=>({plotMode:c.plotMode,legendPosition:ye}),e=>{ye=e;for(const t of S)t&&t.setOptions({legendPosition:ye})},{get:()=>Pe,set:e=>{Pe=e,Et()},blockedReason:we});Gt();const ao=[{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"}],Kt=Lt("aggr","Aggregation method",()=>ao,()=>c.aggregationMethod??"mean",e=>T({aggregationMethod:e}));function qt(){const e=c.plotMode==="stackedValues";Kt.style.display=e?"":"none"}qt();const{btn:lo,sync:Ut}=ti(ce,()=>({...c,functionalActive:Ee()}),e=>T(e));Ut();const ze=Q("specRange","Colorbar range: spec limits",()=>{const e=c.colorbarRangeMode==="data"?"spec":"data";T({colorbarRangeMode:e})});function Xt(){const e=(c.plotMode??"hardBin")==="value"&&Vt()&&Mn(c)==="off"&&!Ee();ze.style.display=e?"":"none";const t=(c.colorbarRangeMode??"spec")==="spec";Se(ze,t),ze.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}Xt();const so=ii(ce,()=>c,e=>T(e)),ro=Q("downloadAll","Download gallery PNG",Co),co=Lt("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"}],()=>k!=null?String(k):"auto",e=>ln(e==="auto"?void 0:Number(e))),O=f.ownerDocument.createElement("div");Object.assign(O.style,{display:"inline-flex",alignItems:"center",gap:"0"}),W.appendChild(O),O.appendChild(Y),O.appendChild(Zn),O.appendChild(Kt),O.appendChild(lo),O.appendChild(ze),O.appendChild(G()),O.appendChild(oo),O.appendChild(G()),O.appendChild(io),O.appendChild(G()),O.appendChild(so),O.appendChild(G()),O.appendChild(co),O.appendChild(G()),O.appendChild(ro),(V||nt())&&(P=Q("findings","Summary panel",()=>{if(!b)return;const e=b.style.display!=="none";e||N(),b.style.display=e?"none":"flex",Se(P,!e),le()}),W.appendChild(G()),W.appendChild(P));let K=null,_e=null,J=[],Yt=!1;function Be(){const e=Mi({lotStatsSummary:V,result:{warnings:[...v.flatMap(n=>n?.warnings??[]),...Bt().warnings]},extra:[c.binColors&&Lo(c.binColors,c.plotMode),Ro(zt),Pn(kt())].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||!Yt)&&(Yt=!0,p.warnings?.onWarning?.(e)),uo()}function uo(){if(!K||!_e)return;const e=J.length,t=e>0;if(K.style.display=t?"flex":"none",_e.style.display=t?"":"none",!t)return;const n=ki(J[0]),o=`${e} data ${e===1?"warning":"warnings"}`;K.style.color=n==="error"?h.errText:h.warnText,K.ariaLabel=n==="error"?`${o} \u2014 some wafers may be positionally wrong`:o}(p.warnings?.display??!0)&&(_e=G(),K=Q("warning","Data warnings",()=>{const e=Me();if(je(new MouseEvent("click")),e)return;const t=Di(K.getBoundingClientRect(),J,K.ownerDocument.defaultView??window);wn(f).appendChild(t),De(t),xn(t,K,()=>je(new MouseEvent("click")))}),Ae(K,!1),W.appendChild(_e),W.appendChild(K)),Be();let se=null;H&&(se=Q("analysis","Insights",()=>{Jt(!Te)}),se.dataset.wmapInsightsBtn="1",W.appendChild(G()),W.appendChild(se));function Zt(){import("./userGuideHtml.js").then(e=>Jo({buildWaferMap:Ci,renderWaferMap:bi,renderWaferGallery,analyzeWaferMap:Je},e.USER_GUIDE_HTML,I,f))}E&&(W.appendChild(G()),W.appendChild(Q("help","User guide",()=>Zt())));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:`${w.sm} ${w.lg}`,fontSize:L.sub,lineHeight:Ze.none,boxSizing:"border-box"});const Ge=f.ownerDocument.createElement("div");Object.assign(Ge.style,{background:h.canvasBg,display:"flex",alignItems:"stretch",gap:w.lg,paddingBottom:w.lg,minWidth:"0"});const ee=f.ownerDocument.createElement("div");ee.dataset.wmapGalleryLegend="1",Object.assign(ee.style,{display:"flex",flexDirection:"column",gap:w.sm,background:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.container,padding:`${w.sm} ${w.lg}`,marginBottom:w.lg,boxShadow:$e.panel,fontSize:L.body,lineHeight:Ze.none,boxSizing:"border-box",width:"100%",minWidth:"0"});const q=f.ownerDocument.createElement("div");Object.assign(q.style,{display:"flex",flexDirection:"row",alignItems:"flex-start"});let me=null,Oe=null,Qt=null;function fo(){return H?me?Promise.resolve(me):(Qt??=import("./insightsTab.js").then(({createInsightsTab:e})=>(me=e({getItems:()=>v,getLotStats:()=>V,getBinColors:()=>c.binColors??fe(),getRingCount:tt,defaultView:p.insights?.defaultView,sweeps:p.insights?.sweeps,onOpenGuide:void 0,showMetadataStrip:!1,onSaveImage:Fe.onSaveImage,onSaveText:Fe.onSaveText,ownerDocument:f.ownerDocument,openWafer:(t,n,o)=>{const d=v[t];if(!d)return;let l=null;const a=Xo({title:n,onClose:()=>l?.destroy(),anchor:f});dn(a,n,d.wafer.metadata??void 0),l=ht(a.contentWrap,d,o)}}),Oe=me.el,Oe.style.display="none",f.appendChild(Oe),me)),Qt):Promise.resolve(null)}let Te=!1;function Jt(e){H&&(Te=e,Oe&&(Oe.style.display=e?"flex":"none"),q.style.display=e?"none":"flex",O.style.display=e?"none":"inline-flex",W.style.display="inline-flex",se&&(Se(se,e),se.innerHTML=e?We.wafer:We.analysis,se.ariaLabel=e?"Back to gallery view":"Insights"),le(),qe(),e&&fo().then(t=>{!t||!Te||(t.el.style.display="flex",t.render())}))}H&&p.insights?.defaultOpen&&queueMicrotask(()=>Jt(!0));const po=4,ct=240,en=480,mo=720,go=1.25;let ge=en;function tn(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 l=o.wafer.radius*2*(po/d),a=Math.ceil(l+t);(n==null||a>n)&&(n=a)}return n}function ho(e){const t=tn(e);return t==null?ct:Math.min(ge,Math.max(ct,t))}function bo(e){const t=tn(e);if(t==null)return!1;const n=Math.min(mo,Math.max(en,t));return n<=ge?!1:(ge=n,!0)}function ut(){return k!=null?"none":`${ge}px`}function nn(){const e=ut();for(const t of Array.from($.children))t.classList.contains("wmap-gallery-card")&&(t.style.maxWidth=e,t.style.maxHeight=e)}let Ke=ct,on=0;function an(e){if(bo(e)&&nn(),k==null){const n=ho(e);n>Ke&&(Ke=n)}pt()}function ln(e){k=In(e),nn(),pt()}function ft(e){return`repeat(${e}, minmax(0, ${k!=null?"1fr":`${ge}px`}))`}function sn(e){$.style.gridTemplateColumns!==e&&($.style.gridTemplateColumns=e)}function pt(){if(k!=null){sn(ft(k));return}const e=Math.max(1,on),t=12,n=$.clientWidth||0,o=l=>(n-t*(l-1))/l;let d=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){const l=Math.min(ge,Ke*go),a=r=>{let i=0;for(;i<e&&o(i+1)>=r;)i++;return i};d=a(l)||a(Ke)||1}sn(ft(d))}const $=f.ownerDocument.createElement("div");if(Object.assign($.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:ft(1),gap:w.xl,paddingLeft:oe,paddingRight:oe,justifyContent:"start",alignContent:"start",isolation:"isolate"}),re?.placement){const e=re.placement;b=Mt(e,oe,f.ownerDocument),b.style.maxHeight="calc(100vh - 80px)",b.style.position="sticky",b.style.top="8px",b.style.display="flex",b.style.flexDirection="column"}else if(V||nt()){const e=!!re?.defaultOpen;b=Mt("right",oe,f.ownerDocument),b.style.maxHeight="calc(100vh - 80px)",b.style.position="sticky",b.style.top="8px",b.style.flexDirection="column",b.style.display=e?"flex":"none",N()}le(),b?.style.display!=="none"&&P&&Se(P,!0),(re?.placement??"right")==="left"?(b&&q.appendChild(b),q.appendChild($)):(q.appendChild($),b&&q.appendChild(b));const Le=f.ownerDocument.createElement("div");Object.assign(Le.style,{position:"sticky",top:"0",display:"flex",flexDirection:"column",paddingLeft:oe,paddingRight:oe,paddingTop:oe,zIndex:"1",background:h.menuBg}),Ge.appendChild(pe),Ge.appendChild(W),Le.appendChild(Ge),Le.appendChild(ee),f.appendChild(Le),f.appendChild(q);function qe(){ee.innerHTML="";const e=c.plotMode??"hardBin",t=!Te&&hn.has(e),n=R.filter(g=>g!=null),o=n.find(g=>g.isLotStack),d=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=c.activeMetadataKey,r=t&&!l?Wn(n,g=>(e==="softBin"?g.sbin:g.hbin)??void 0,An):{counts:new Map,total:0,pass:0},i=t&&!l?c.binColors??fe():void 0,s=i?e==="softBin"?i.pass.soft:i.pass.hard:new Set,u=mi(r.counts.entries(),s).map(([g])=>g),m=t&&l&&a?Wn(n,g=>Oo(g.metadata?.[a])):{counts:new Map,total:0,pass:0},M=l?Nt()?.values:void 0,D=t&&l?(M??[...m.counts.keys()].sort(St)).filter(g=>m.counts.has(g)):[];if(pe.innerHTML="",d&&pe.appendChild(d),pe.style.display=d?"flex":"none",!u.length&&!D.length){ee.style.display="none";return}ee.style.display="flex";const x=f.ownerDocument.createElement("div");Object.assign(x.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:`${w.sm} ${w.xl}`,maxHeight:"86px",overflowY:"auto",overflowX:"hidden"}),ee.appendChild(x);const y=c.highlightBin,B=R.flatMap(g=>g?.metadataFields??[]).find(g=>g.key===a),j=l?B?.label??(a?Li(a):"Metadata"):No[e],U=f.ownerDocument.createElement("span");if(U.textContent=j,Object.assign(U.style,{fontSize:L.body,fontWeight:"700",letterSpacing:Ho,textTransform:"uppercase",color:h.label,flexShrink:"0"}),x.appendChild(U),!l&&r.total>0){const g=r.pass,F=g/r.total*100,te=f.ownerDocument.createElement("span");te.textContent=`Yield ${et(F)}`,Object.assign(te.style,{fontSize:L.body,fontWeight:"700",color:h.value,whiteSpace:"nowrap",flexShrink:"0"});const ne=f.ownerDocument.createElement("span");ne.textContent=`${g.toLocaleString()} / ${r.total.toLocaleString()} dies`,Object.assign(ne.style,{fontSize:L.body,color:h.label,whiteSpace:"nowrap",flexShrink:"0"}),x.appendChild(te),x.appendChild(ne)}if(l){const g=c.highlightMetadataValue;D.forEach((F,te)=>{const ne=g===F,Xe=B?.values?.find(vt=>vt.value===F),Mo=Xe?.color??Po(te),mn=m.counts.get(F)??0;$n(x,{color:Mo,isActive:ne,label:Xe?.label??F,count:mn,percent:m.total>0?mn/m.total*100:void 0,onClick:()=>{const vt=c.highlightMetadataValue===F?void 0:F;T({highlightMetadataValue:vt})}})});return}const bt=e==="softBin"?R.flatMap(g=>g?.sbinDefs??[]):R.flatMap(g=>g?.hbinDefs??[]),un=new Set,yt=[];for(const g of bt)un.has(g.bin)||(un.add(g.bin),yt.push(g));const wt=yt.length>0?new Map(yt.map(g=>[g.bin,g])):null,fn=i??c.binColors??fe(),So=e==="softBin"?fn.soft:fn.hard,pn=g=>So.get(g)??Ao;for(const g of u){const F=y===g,te=wt?.get(g),ne=r.counts.get(g)??0;$n(x,{color:pn(g),isActive:F,label:te?.name?`${g} \xB7 ${te.name}`:`Bin ${g}`,count:ne,percent:r.total>0?ne/r.total*100:void 0,onClick:()=>{const Xe=c.highlightBin===g?void 0:g;T({highlightBin:Xe})}})}r.total>0&&u.length>1&&ee.appendChild(Hi(f.ownerDocument,[...r.counts.entries()].sort(([,g],[,F])=>F-g).map(([g,F])=>({color:pn(g),count:F,label:wt?.get(g)?.name?`${g} \xB7 ${wt.get(g).name}`:`Bin ${g}`})),r.total))}function Re(e){const t=v.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(Pi)),o=t[0].wafer,d=t.length,l=o.metadata?{...o,metadata:(({wafer:r,waferId:i,...s})=>s)(o.metadata)}:o;function a(r,i){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:i,lotSize:d}}}if(e==="stackedValues"){const r=ve();let i=r?.filter(Ct);if(r!==void 0&&i?.length===0)return[];if(r?.length||(i=Do(t.flatMap(m=>m.dies)).map(m=>({testNumber:m,name:Ri(void 0,m)}))),!i?.length)return[];const s=c.aggregationMethod??"mean";return i.map(u=>{const m=hi(n,s,u.testNumber),M={testNumber:0,name:u.name,unit:u.unit,...Wi(u)};return{wafer:l,dies:m,testDefs:[M],label:`${Ii(u,u.testNumber)} \xB7 ${s}`,isLotStack:!0,aggrMethod:s,lotSize:d,statsSummary:a(Je({wafer:l,dies:m,testDefs:[M]},{testNumbers:[0]}),s)}})}if(e==="stackedBins"){let r=Ye(t.map(i=>i?.hbinDefs));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(s=>s.dies.map(u=>u.hbin).filter(u=>u!=null)))].sort((s,u)=>s-u).map(s=>({bin:s,name:`Bin ${s}`}))),r.map(i=>{const s=kn(n,i.bin,"hard"),u=[{bin:i.bin,name:i.name}];return{wafer:l,dies:s,hbinDefs:u,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:a(Je({wafer:l,dies:s,hbinDefs:u}),"countBin")}})}if(e==="stackedSoftBins"){let r=Ye(t.map(i=>i?.sbinDefs));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(s=>s.dies.map(u=>u.sbin).filter(u=>u!=null)))].sort((s,u)=>s-u).map(s=>({bin:s,name:`Bin ${s}`}))),r.map(i=>{const s=kn(n,i.bin,"soft"),u=[{bin:i.bin,name:i.name}];return{wafer:l,dies:s,sbinDefs:u,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:a(Je({wafer:l,dies:s,sbinDefs:u}),"countBin")}})}return t}function mt(e){const t=v.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:c.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}function T(e,{fireCallback:t=!0}={}){const n=Object.keys(e),o=c.plotMode,d=we()!==null;c={...c,...e};const l=c.plotMode,a=be.has(l),r=o!==void 0&&be.has(o),i=He>0;if("binColorScheme"in e||"useDefinedBinColors"in e){const u=fe();c={...c,binColors:u},e={...e,binColors:u}}if(e.plotMode!==void 0)if(a){const u=mt(l);if(c={...c,...u},i)for(const m of S)m&&m.setOptions(e);else Z(Re(l))}else if(r){const{valueRange:u,lotSize:m,aggregationMethod:M,...D}=c;if(c=D,i)for(const x of S)x&&x.setOptions(e);else Z(v.filter(x=>x!==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 Z(Re("stackedValues"));else for(const u of S)u&&u.setOptions(e);we()!==null!==d&&Et(),qe(),qt(),Gt(),jt();const s=e.plotMode!==void 0&&e.plotMode!==o;(xi.some(u=>u in e)||s)&&N(),Be(),Ut(),Xt(),st(),lt(),t&&p.onViewOptionsChange?.(Bn(c),n,vi(n))}function rn(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:L.sub,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(d);const l=Rn(n??{});let a=null;if(l.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:L.body,lineHeight:Ze.none,color:h.label,flexShrink:"0"}),r.textContent="\u25BE",o.appendChild(r),Object.assign(o.style,{cursor:"pointer",borderRadius:z.control}),o.addEventListener("mouseenter",()=>{o.style.background=h.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:bn,background:h.menuBg,borderBottom:`1px solid ${h.menuBorder}`,boxShadow:$e.menu,padding:`${w.md} ${w.lg}`,fontSize:L.body,display:"none"});const i=Ln(n??{});i&&a.appendChild(i),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Cn(o,s=>{r.textContent=s?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(s)),a&&(a.style.display=s?"block":"none")})}return{wrap:o,metaPanel:a}}function dn(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),d=Rn(n??{});if(!o||d.length===0)return;const l=o.parentElement,a=f.ownerDocument.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:w.xs,flex:"1",minWidth:"0",cursor:"pointer"}),xt(a,"bare"),l?.insertBefore(a,o),a.appendChild(o);const r=f.ownerDocument.createElement("span");Object.assign(r.style,{fontSize:L.body,lineHeight:Ze.none,color:h.label,flexShrink:"0"}),r.textContent="\u25BE",a.appendChild(r);const i=f.ownerDocument.createElement("div");i.dataset.wmapCardMetaPanel="1",Object.assign(i.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:bn,background:h.menuBg,borderBottom:`1px solid ${h.menuBorder}`,boxShadow:$e.menu,padding:`${w.md} ${w.lg}`,fontSize:L.body,display:"none"});const s=Ln(n??{});s&&i.appendChild(s),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.`),Cn(a,u=>{r.textContent=u?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(u)),i.style.display=u?"block":"none"})}function gt(e,t,n){const o=f.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.container,boxShadow:$e.panel,overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:ut(),maxHeight:ut()});const d=f.ownerDocument.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${h.menuBorder}`,flexShrink:"0",gap:w.sm});const{wrap:l,metaPanel:a}=rn(document,Qe(e,t),e.wafer.metadata??void 0);d.appendChild(l);const r=f.ownerDocument.createElement("button");r.dataset.wmapExpandBtn="1",r.setAttribute("aria-label","Open full view"),Sn(r),r.innerHTML=We.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${h.menuBorder}`,borderRadius:z.control,background:h.panelBg,color:h.label,padding:w.xxs,cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),xt(r),d.appendChild(r),o.appendChild(d);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),$.appendChild(o),o.addEventListener("contextmenu",M=>{if(M.defaultPrevented)return;const D=p.insights?.sweeps;if(!yi(e.testDefs,D))return;M.preventDefault();const x=e.viewOptions?{...c,...e.viewOptions}:c,y=wi(e.dies,{waferLabel:Dn(e),testDefs:e.testDefs,isLotStack:e.isLotStack,activeTest:x.plotMode==="value"?x.activeTest:void 0,waferIndex:t}),B={x:M.clientX,y:M.clientY};import("./drilldown.js").then(({openDrilldownMenu:j})=>{o.isConnected&&j(B,o,y,{sweeps:D,onSaveImage:p.onSaveImage})})});const s=Pe||we()!==null,u=e.viewOptions?{...c,...e.viewOptions}:c,m=En(i,e,{viewOptions:{...u,showLegend:s,legendPosition:ye},showTooltip:!0,padding:A,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,insights:X,onExpand:()=>Ie(t,e),showIdentity:!1,chromeInset:Vo});return m.setViewControlsVisible(!1),m.setSummaryVisible(!1),r.onclick=()=>Ie(t,e),{card:o,ctrl:m,canvasWrapper:i,expandBtn:r}}function yo(e){const t=de[e];if(!t)return;const n=[..._.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=We.minimize,t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>vo(n.id)):(t.innerHTML=We.expand,t.setAttribute("aria-label","Open full view"),t.onclick=()=>Ie(e,R[e]))}function Z(e){xo(),Me()?.remove(),De(null),it(),R=[];for(const i of S)i&&i.destroy();S=[],ae=[],de=[],He=0,$.innerHTML="",on=e.length,an(e.map(i=>typeof i=="function"?null:i));const t=[];for(let i=0;i<e.length;i++){const s=e[i];if(typeof s=="function"){const u=f.ownerDocument.createElement("div");u.className="wmap-gallery-card",Object.assign(u.style,{background:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.container,aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const m=f.ownerDocument.createElement("span");m.textContent="\u2026",Object.assign(m.style,{color:h.label,fontSize:"18px"}),u.appendChild(m),$.appendChild(u),R.push(null),S.push(null),ae.push(null),de.push(null),t.push({index:i,factory:s,placeholder:u}),He++}else{const{ctrl:u,canvasWrapper:m,expandBtn:M}=gt(s,i,e.length);R.push(s),S.push(u),ae.push(m),de.push(M)}}_t(),qe(),st(),lt();const n=++xe,o=()=>{setTimeout(()=>{n===xe&&p.onItemsResolved?.()},0)},d=i=>{setTimeout(()=>{n===xe&&p.onItemResolved?.(i,e.length)},0)};let l=e.length-t.length;l>0&&d(l);let a=0;function r(){if(n!==xe)return;if(a>=t.length){if(be.has(c.plotMode)){const B=c.plotMode;Z(Re(B));return}ke=o,N(),ue||(ke=null,o());return}const{index:i,factory:s,placeholder:u}=t[a++],m=s();R[i]=m,v[i]=m,an([m]);const{card:M,ctrl:D,canvasWrapper:x,expandBtn:y}=gt(m,i,e.length);S[i]=D,ae[i]=x,de[i]=y,He--,u.replaceWith(M),d(++l),no(),to(),!b&&!re?.placement&&m.statsSummary?.findings.length&&(b=Mt("right",oe,f.ownerDocument),b.style.maxHeight="calc(100vh - 80px)",b.style.position="sticky",b.style.top="8px",b.style.flexDirection="column",b.style.display="none",(re?.placement??"right")==="left"?q.insertBefore(b,$):q.appendChild(b),N(),P||(P=Q("findings","Summary panel",()=>{if(!b)return;const j=b.style.display!=="none";j||N(),b.style.display=j?"none":"flex",Se(P,!j),le()}),W.appendChild(G()),W.appendChild(P)),le()),le(),setTimeout(r,0)}t.length>0?setTimeout(r,0):o()}if(be.has(c.plotMode)&&v.length>0){const e=mt(c.plotMode);c={...c,...e},Z(Re(c.plotMode))}else Z(C);Be();let he=0;const cn=new(f.ownerDocument.defaultView??window).ResizeObserver(()=>{if(he)return;he=(f.ownerDocument.defaultView??window).requestAnimationFrame(()=>{he=0,k==null&&pt()})});cn.observe($),b&&N();function wo(e,t){const n=ae[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:h.label,fontSize:L.body,textAlign:"center",padding:"0 12px"}),n.appendChild(o)}function Ie(e,t){for(const a of _.values())if(a.cardIndex===e)return;const n=Qe(t,e),o=Fn++,d=S[e]?.getOptions(),l=qo(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:L.family}),Zo(f,a.documentElement);const r=Qo(f,a.documentElement,()=>x.setOptions({})),i=a.createElement("div");i.dataset.wmapWindowBanner="1",i.textContent=n,Object.assign(i.style,{display:"none",padding:`${w.sm} ${w.xl}`,fontSize:L.body,fontWeight:"700",background:h.warnBg,color:h.warnText,borderBottom:`1px solid ${h.warnBorder}`,flexShrink:"0"}),a.body.appendChild(i);const s=a.createElement("div");Object.assign(s.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),a.body.appendChild(s);const{wrap:u,metaPanel:m}=rn(a,n,t.wafer.metadata??void 0),M=a.createElement("div");Object.assign(M.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${h.menuBorder}`,flexShrink:"0",gap:w.sm}),M.appendChild(u),s.appendChild(M);const D=a.createElement("div");Object.assign(D.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),m&&D.appendChild(m),s.appendChild(D);const x=ht(D,t,void 0,d),y=setInterval(()=>{l.closed&&Ue(o)},400);l.addEventListener("pagehide",()=>Ue(o)),_.set(o,{id:o,ctrl:x,cardIndex:e,label:n,closePollId:y,stopThemeSync:r,close:()=>{l.closed||l.close()},setTitle:B=>{a.title=B,i.textContent=B,i.style.display="block"}})}else{const a=Uo({title:n,onClose:()=>Ue(o),anchor:f});a.contentWrap.style.flexDirection="column",dn(a,n,t.wafer.metadata??void 0);const r=ht(a.contentWrap,t,void 0,d);_.set(o,{id:o,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>a.close(),setTitle:i=>{const s=a.box.querySelector("[data-wmap-window-title]");s&&(s.textContent=i,s.title=i)}})}S[e]?.destroy(),S[e]=null,wo(e,l!==null),yo(e)}function ht(e,t,n,o){const d=t.viewOptions?{...c,...t.viewOptions}:c,l=o?{...d,...o}:d,r={...n!==void 0?{...l,plotMode:"value",activeTest:n}:l,showLegend:!0,legendPosition:ye},i=En(e,t,{viewOptions:r,showTooltip:!0,padding:A,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,insights:X,showExpandButton:!1,showIdentity:!1});return i.setViewControlsVisible(!0),i.setSummaryVisible(!0),i.setExpandVisible(!1),i}function Ue(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=R[n];if(!o)return;const{card:d,ctrl:l,canvasWrapper:a,expandBtn:r}=gt(o,n,R.length);ae[n]?.parentElement?.replaceWith(d),S[n]=l,ae[n]=a,de[n]=r}function vo(e){const t=_.get(e);t&&(t.close(),Ue(e))}function xo(){for(const e of _.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function Co(){const e=[...$.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,l=e[0].height,a=8,r=(f.ownerDocument.defaultView??window).devicePixelRatio||1,i=Math.round(26*r),s=Math.round(12*r),u=f.ownerDocument.createElement("canvas");u.width=n*d+(n-1)*a,u.height=o*(l+i)+(o-1)*a;const m=u.getContext("2d"),M=Fo($);m.fillStyle=M.background,m.fillRect(0,0,u.width,u.height),e.forEach((D,x)=>{const y=x%n,B=Math.floor(x/n),j=y*(d+a),U=B*(l+i+a),bt=D.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";m.fillStyle=M.surface,m.fillRect(j,U,d,i),m.fillStyle=M.text,m.font=`700 ${s}px system-ui, sans-serif`,m.textAlign="left",m.textBaseline="middle",m.fillText(bt,j+Math.round(10*r),U+i/2,d-Math.round(20*r)),m.drawImage(D,j,U+i)}),u.toBlob(D=>{if(!D)return;if(p.downloadFilename!=null){vn(D,p.downloadFilename,p.onSaveImage);return}const x=S.find(y=>y!=null)?.getExportTitle();vn(D,["gallery",x].filter(Boolean).join(" "),Fe.onSaveImage)})}return{setItems(e){v=e.map(n=>typeof n=="function"?null:n);const t=c.plotMode;if(be.has(t))if(e.some(o=>typeof o=="function"))Z(e);else{const o=mt(t);c={...c,...o},Z(Re(t))}else Z(e)},setOptions(e){T(e,{fireCallback:!1})},getOptions(){return Bn(c)},setFindingsNotice(e){It=e,N()},setColumns(e){ln(e)},getBinColors(){return c.binColors??fe()},setLotStatsSummary(e){V=e,Be(),b&&N(),le()},openUserGuide:Zt,destroy(){xe++,ue?.cancel(),ue=null,ke=null;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=[],Me()?.remove(),cn.disconnect(),he&&((f.ownerDocument.defaultView??window).cancelAnimationFrame(he),he=0),f.ownerDocument.removeEventListener("click",je,!0),window.removeEventListener("blur",Rt),ie(),yn(),Le.remove(),q.remove(),b?.remove(),me?.destroy()}}}
1
+ import{getUniqueTestNumbers as Do,resolveTestNumber as ko,findTestDef as Eo,collectMetadataValues as Bo}from"../renderer/buildView.js";import{metadataCategoricalValue as Oo}from"../core/metadata.js";import{resolveBinColorsForMaps as To,mergeBinDefs as Ye,binColorWarning as Lo,mixedPassBinsWarning as Ro,binColorsEqual as Io}from"../renderer/binColors.js";import{itemPassBins as Wo,INPUT_DEFAULT_PASS_BINS as $o}from"../core/passBins.js";import{NO_DATA_FILL as Ao}from"../renderer/colorMap.js";import{metadataValueColor as Po}from"../renderer/colorMap.js";import{resolveCanvasTheme as Fo}from"./canvasTheme.js";import{ICONS as We}from"./icons.js";import{SHADOW as $e,LEADING as Ze,TRACKING as Ho,controlStyle as jo,wireControlHover as xt,SPACE as w,EDGE_GUTTER as oe,MAP_CHROME_INSET as Vo,RADIUS as z,FONT as L,CLR as h,sevColor as gn,MODE_LABELS as No,BIN_LEGEND_MODES as hn,STACKED_MODES as be,Z_ABOVE as bn,applyOverlayZ as zo,getTooltip as _o,hideTooltip as yn,createToolbarHelpers as Go,buildModeMenuEl as Ko,openDetachWindow as qo,openFloatingWindow as Uo,openModal as Xo,openReportModal as Yo,copyWmapThemeTokens as Zo,syncWmapPopupTheme as Qo,openUserGuideWindow as Jo,makePaletteBtn as ei,makeLogScaleBtn as ti,makeLegendStyleBtn as ni,makeOverlaysBtn as oi,makeOrientationBtn as ii,menuLayerFor as wn,saveImageBlob as vn,markMenuTrigger as Ae,wireMenuA11y as xn,wireExpandToggle as Cn,wireTooltip as Sn,requestedPassFailDisplay as Mn,overlayMenuRows as ai,anyOverlayActive as li,logWmapVersionOnce as si,buildDataModeEntries as ri,metadataKeyHasData as di,metadataModeEntry as ci}from"./toolbar.js";import{waferDisplayLabel as Qe,waferIdentityLabel as Dn}from"../core/waferLabel.js";import{metadataDisplayValue as ui}from"../core/metadata.js";import{withExportContext as fi,noticeDownloadFilenameChange as pi}from"./exportName.js";import{sortBinsForDisplay as mi}from"../stats/binPareto.js";import{diePassStatus as gi}from"../core/dies.js";import{aggregateValues as hi,aggregateBinCounts as kn}from"../core/aggregates.js";import{renderWaferMap as bi,renderWaferMapCard as En,toPublicViewOptions as Bn}from"./renderWaferMap.js";import{hasDrilldownTargets as yi,waferPopulation as wi}from"./chartPopulation.js";import{classifyChanged as vi,COLOR_KEYS as xi}from"./renderWaferMap.js";import{buildWaferMap as Ci,getTestPassStatus as On,isParametricTest as Ct,getDieTestValue as Si}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Je}from"../stats/analyzeWaferMap.js";import{collectWarnings as Mi,buildWarningsMenuEl as Di,severityOf as ki}from"./warnings.js";import{compareNatural as St,arrayEqual as Tn}from"../core/utils.js";import{createSummaryPanelEl as Mt,buildMetadataStripRow as Ei,buildCompactMetadataRows as Ln,metadataEntries as Rn,renderLotSummaryContentSteps as Bi,reportMapsFromItems as Oi}from"./summaryPanel.js";import{renderLotReportHtml as Ti}from"../stats/renderSummaryReport.js";import{prettyKey as Li}from"../stats/facets.js";import{testLabel as Ri,markedTestLabel as Ii,derivedFields as Wi}from"../renderer/testLabel.js";import{mergeTestDefs as $i}from"../stats/mergeTestDefs.js";import{getDieKey as Ai,hasPosition as Pi}from"../core/dies.js";import{runChunked as Fi}from"./chunked.js";function In(f){if(typeof f!="number"||!Number.isFinite(f))return;const C=Math.round(f);return C>=1?C:void 0}const Dt=12;function Hi(f,C,p){let A=C;if(C.length>Dt){const E=C.slice(0,Dt-1),I=C.slice(Dt-1),H=I.reduce((X,ie)=>X+ie.count,0);A=[...E,{color:h.label,count:H,label:`Other (${I.length} bins)`}]}const k=f.createElement("div");Object.assign(k.style,{display:"flex",columnGap:"1px",width:"100%",height:"8px",borderRadius:z.control,overflow:"hidden",border:`1px solid ${h.menuBorder}`,boxSizing:"border-box",marginTop:w.xs,flexShrink:"0"}),k.setAttribute("role","img"),k.setAttribute("aria-label",`Population split: ${A.map(E=>`${E.label} ${et(E.count/p*100)}`).join(", ")}`);for(const E of A){const I=E.count/p*100,H=f.createElement("div");Object.assign(H.style,{flex:`${I} 1 0`,minWidth:I>0?"2px":"0",background:E.color}),Sn(H,`${E.label} \xB7 ${E.count.toLocaleString()} dies \xB7 ${et(I)}`),k.appendChild(H)}return k}function et(f){return f>0&&f<.1?"<0.1%":`${f.toFixed(1)}%`}function Wn(f,C,p){const A=new Map;let k=0,E=0;for(const I of f){const H=p?new Set(p(I)):void 0;for(const X of I.dies){if(X.partial||X.edgeExcluded)continue;const ie=C(X);ie!==void 0&&(A.set(ie,(A.get(ie)??0)+1),k++,H&&gi(X,H)&&E++)}}return{counts:A,total:k,pass:E}}function $n(f,C){const p=f.ownerDocument.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:`${w.xxs} ${w.xs}`,borderRadius:z.control});const A=f.ownerDocument.createElement("span");Object.assign(A.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:C.color,border:C.isActive?`2px solid ${h.iconActive}`:`1px solid ${h.menuBorder}`,borderRadius:z.control,boxSizing:"border-box"});const k=f.ownerDocument.createElement("span");if(k.textContent=C.label,Object.assign(k.style,{fontWeight:C.isActive?"700":"400",color:C.isActive?h.iconActive:h.text,whiteSpace:"nowrap"}),p.appendChild(A),p.appendChild(k),C.count!==void 0){const E=f.ownerDocument.createElement("span");if(E.textContent=C.count.toLocaleString(),Object.assign(E.style,{color:C.isActive?h.iconActive:h.text,fontWeight:C.isActive?"700":"400",whiteSpace:"nowrap"}),p.appendChild(E),C.percent!==void 0){const I=f.ownerDocument.createElement("span");I.textContent=et(C.percent),Object.assign(I.style,{color:h.label,whiteSpace:"nowrap"}),p.appendChild(I)}}p.setAttribute("role","button"),p.setAttribute("aria-pressed",C.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=h.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=h.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",C.onClick),p.addEventListener("keydown",E=>{(E.key==="Enter"||E.key===" ")&&(E.preventDefault(),C.onClick())}),f.appendChild(p)}export function renderWaferGallery(f,C,p={}){si();const A=6;let k=In(p.columns);const E=p.showHelpButton??!1,I=p.userGuideExtension,H=p.insights?.enabled??!1,X=p.insights?.sweeps?{sweeps:p.insights.sweeps}:void 0,ie=zo(p.zIndex),re=p.summaryPanel,An=e=>[...Wo(e)],kt=()=>v.flatMap(e=>e?[e.ringCount??4]:[]),tt=()=>kt()[0]??4;function Pn(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,ye=p.viewOptions?.legendPosition??"default",Pe=p.perCardLegend??!1;function we(){const e=c.plotMode??"hardBin";return hn.has(e)?null:c.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 Et(){const e=Pe||we()!==null;for(const t of S)t&&t.setOptions({showLegend:e})}let c={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},S=[],ae=[],de=[],R=[];const Fe=fi(()=>{const e=R.filter(n=>n!=null);return{lots:[...new Set(e.map(n=>ui(n.wafer.metadata?.lot)).filter(n=>n!==void 0))].sort(St),...e.length===1?{wafer:Dn(e[0])}:{waferCount:e.length}}},p.onSaveImage,p.onSaveText);pi(p.downloadFilename);let v=C.map(e=>typeof e=="function"?null:e);function Bt(){return $i(v)}function ve(){if(v.some(e=>e?.testDefs?.length))return Bt().defs}let xe=0,He=0;const _=new Map;let Fn=0,P=null,Ce=null,Ot=new Set,b=null,Hn={};function Tt(e){return v[e]?.statsSummary??V?.perWafer.find(t=>t.waferIndex===e)?.summary}function nt(){return!!(v.some(e=>e?.statsSummary?.findings.length)||V?.perWafer.some(e=>e.summary.findings.length))}const jn=_o(),ce=Go(jn),{makeBtn:Q,setActive:Se,makeSep:G,makeMenuRow:Vn,makeMenuSection:Nn,makeDropdown:Lt,closeOpenMenu:je,getOpenMenu:Me,setOpenMenu:De}=ce;f.ownerDocument.addEventListener("click",je,!0);const Rt=()=>yn();window.addEventListener("blur",Rt);let It=p.findingsNotice;function Wt(e){Ot=new Set(e);const t=[...$.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((o,d)=>{const l=Ot.has(d);o.style.outline=l?`3px solid ${h.findingHighlight}`:"",o.style.outlineOffset=l?"-3px":"",l&&n===void 0&&(n=o)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function $t(){Wt([])}function At(){for(const e of S)e&&e.clearSelection()}function ot(e,t){const n=new Set(e),o=t??S.map((d,l)=>l);for(const d of o){const l=R[d],a=S[d];if(!l||!a)continue;const r=l.dies.filter(i=>n.has(Ai(i)));a.setSelection(r)}}function zn(){const e=[];for(let t=0;t<v.length;t++){const n=v[t];if(!n)continue;const o=Tt(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 _n(e){const t=R[e]??v[e];t&&Ie(e,t)}function Gn(e){const t=Tt(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 Kn(){Yo(Ti(Oi(v,$o,tt())),{anchor:f})}function qn(){if(!b)return;b.innerHTML="";const e=zn();if(v.length>0){const n=f.ownerDocument.createElement("div"),o=e.length,d=v.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:L.body,color:h.label,marginBottom:w.md}),b.appendChild(n)}if(e.length>0){const n=f.ownerDocument.createElement("button");n.type="button",n.textContent="Summary report",Object.assign(n.style,{...jo("outlined"),marginBottom:w.lg,display:"block",width:"100%",textAlign:"left"}),xt(n),n.addEventListener("click",Kn),b.appendChild(n)}if(e.length===0){const n=f.ownerDocument.createElement("div");Object.assign(n.style,{color:h.icon,fontSize:L.body,padding:"4px 0"}),n.textContent="No findings on any wafer.",b.appendChild(n)}else for(const{index:n,item:o,unusualCount:d,notableCount:l,totalCount:a}of e){const r=d?"unusual":l?"notable":"info",i=d+l||a,s=f.ownerDocument.createElement("button");s.type="button",Object.assign(s.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:w.xs,border:"none",borderLeft:`3px solid ${gn(r)}`,borderRadius:z.control,background:h.bgHover,cursor:"pointer",fontSize:L.body,textAlign:"left",boxSizing:"border-box"}),s.addEventListener("mouseover",()=>{s.style.background=h.bgActive}),s.addEventListener("mouseout",()=>{s.style.background=h.bgHover});const u=f.ownerDocument.createElement("span");u.textContent=Qe(o,n),Object.assign(u.style,{color:h.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const m=f.ownerDocument.createElement("span");m.textContent=String(i),s.setAttribute("aria-label",`${Qe(o,n)} \u2014 ${i} finding${i===1?"":"s"}${d?`, ${d} unusual`:""} \u2014 view wafer`),Object.assign(m.style,{marginLeft:w.sm,flexShrink:"0",background:gn(r),color:"#fff",borderRadius:z.container,padding:"1px 5px",fontSize:L.body,fontWeight:"600"}),s.appendChild(u),s.appendChild(m),s.addEventListener("click",()=>Ie(n,o)),b.appendChild(s)}const t=f.ownerDocument.createElement("div");t.style.height="12px",b.appendChild(t)}let ue=null,ke=null;function N(){if(b)if(ue?.cancel(),ue=null,V){const e=Ye(v.map(n=>n?.hbinDefs)),t=Ye(v.map(n=>n?.sbinDefs));ue=Fi(Bi(b,{lotSummary:V,items:v,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:ve(),ringCount:tt(),binColors:c.binColors,plotMode:c.plotMode??"hardBin",fallbackFormat:c.fallbackFormat,activeFindingId:Ce,warnings:p.warnings?.display??!0?J:[],findingsFilter:Hn,findingsNotice:It,onFindingsFilterChange:N,onSaveText:Fe.onSaveText,onFindingClick:(n,o)=>{Ce===n.id?it():Xn(n,o),N()},onWaferClick:_n,findingsFor:Gn,dieListOptions:p.dieList}),{onDone:()=>{const n=ke;ke=null,n?.()}})}else qn()}function Un(e){const t=e.highlight;return t?.kind==="wafer"&&t.waferIndices?.length?t.waferIndices:null}function Pt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}let Ve=[];function Ft(){if(Ve.length!==0){for(const e of Ve)S[e]?.setOptions({plotMode:c.plotMode,activeTest:c.activeTest});Ve=[]}}function it(){Ce=null,$t(),At(),Ft(),T({highlightBin:void 0},{fireCallback:!1})}function Xn(e,t){if(Ce===e.id){it();return}Ce=e.id,t.style.background=h.bgActive,t.style.fontWeight="600",Ft();const{kind:n,index:o}=e.variable;if(n==="test"){const l=o??0,a=ve();if(a===void 0||a.some(i=>i.testNumber===l))T({plotMode:"value",activeTest:l,highlightBin:void 0},{fireCallback:!1});else{T({highlightBin:void 0},{fireCallback:!1});const s=be.has(c.plotMode??"hardBin")?null:Un(e);if(s){for(const u of s)S[u]?.setOptions({plotMode:"value",activeTest:l});Ve=[...s]}}}else n==="softBin"?T({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):T({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1});$t(),At();const d=e.highlight;if(d.kind==="wafer"){Wt(d.waferIndices);const l=Pt(e);for(const a of d.waferIndices){const s=R[a]?.statsSummary?.findings.find(u=>Pt(u)===l)?.highlight?.dieKeys;s?.length&&ot(s,[a])}}else d.kind==="bin"?d.dieKeys?.length&&ot(d.dieKeys):(d.kind==="region"||d.kind==="dies")&&d.dieKeys?.length&&ot(d.dieKeys)}function le(){if(!P)return;const e=!!b;P.style.display=(V||nt())&&e&&!Te?"flex":"none";const t=b?b.style.display!=="none":!1;(V?.hasNotableFindings||v.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?P.style.color=h.findingIndicator:P.dataset.active||(P.style.color=h.icon)}const W=f.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:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.control,padding:"0",boxShadow:$e.panel,flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const Ht=()=>{const e=Me();e&&(e.remove(),De(null)),Ae(Y,!1)},Y=Q("mode","Plot mode",()=>{if(Me()){Ht();return}const e=v.flatMap(y=>y?.dies??[]),t=ve(),{testEntries:n,binEntries:o,stackedEntries:d}=ri(e,t,{includeStacked:!0}),l=v.filter(Boolean).length,a=y=>{if(y===void 0)return l;let B=0;for(const j of v)j?.dies?.some(U=>On(U,y)!==void 0||U.testValues?.[y]!==void 0)&&B++;return B},r=l<2?n:n.map(y=>{const B=a(y.activeTest);return B===l?y:{...y,label:`${y.label} \u2014 ${B} of ${l} wafers`}}),i=c.plotMode??"hardBin",s=c.activeTest??0;function u(y){return y.plotMode!==i?!1:y.plotMode==="value"?s===(y.activeTest??0):y.plotMode==="metadata"?c.activeMetadataKey===y.activeMetadataKey:!0}function m(y,B){y.activeTest!==void 0?T({plotMode:"value",activeTest:y.activeTest,activeMetadataKey:void 0,logScale:y.logScale}):y.activeMetadataKey!==void 0?T({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:y.activeMetadataKey,passFailDisplay:"off"}):T({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),B.remove(),De(null),Ae(Y,!1)}const M=new Set,D=v.flatMap(y=>y?.metadataFields??[]).filter(y=>!M.has(y.key)&&M.add(y.key)).filter(y=>di(e,y.key)).map(ci),x=Ko(Y.getBoundingClientRect(),r,o,d,u,m,{makeMenuRow:Vn,makeMenuSection:Nn},i,Y.ownerDocument.defaultView??window,D);wn(Y).appendChild(x),De(x),Ae(Y,!0),xn(x,Y,Ht)});Ae(Y,!1);const Yn=()=>R.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:Zn,sync:jt}=ei(ce,()=>({...c,plotMode:c.plotMode??"hardBin"}),Yn,e=>T(e));jt();const Qn=C.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Ne(){const e=ve(),{testNumber:t}=ko(c.activeTest??0,e);return{testNumber:t,td:Eo(e,t)}}function Vt(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Ne();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function Ee(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Ne();return e!==void 0&&!Ct(e)}function Jn(){if((c.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Ne();return v.some(n=>n?.dies?.some(o=>On(o,e,t)!==void 0))}function eo(e,t){if(!t||!Ct(t))return;const n=t.limitLow!==void 0||t.limitHigh!==void 0;if((Mn(c)==="spec"&&n?"spec":c.colorbarRangeMode??"spec")==="spec"&&n)return;let l=1/0,a=-1/0;for(const r of v)if(r)for(const i of r.dies){const s=Si(i,e);s!==void 0&&(s<l&&(l=s),s>a&&(a=s))}if(isFinite(l))return l===a?[l,l+1]:[l,a]}function at(e,t,n){const o=c[e];if(o===t||o!=null&&t!=null&&n(o,t))return!1;c={...c,[e]:t};for(const d of S)d&&d.setOptions({[e]:t});return!0}function Nt(){if((c.plotMode??"hardBin")!=="metadata")return;const e=c.activeMetadataKey;if(!e)return;const t=new Set;for(const n of v)if(n)for(const o of Bo(n.dies,e))t.add(o);return{key:e,values:[...t].sort(St)}}function lt(){at("metadataValueOrder",Nt(),(e,t)=>e.key===t.key&&Tn(e.values,t.values))}function st(){if((c.plotMode??"hardBin")!=="value")return;const{testNumber:e,td:t}=Ne(),n=eo(e,t);at("valueRange",n?{test:e,range:n}:void 0,(d,l)=>{const a=s=>Array.isArray(s)?{test:void 0,range:s}:{test:s.test,range:s.range},r=a(d),i=a(l);return r.test===i.test&&Tn(r.range,i.range)})}let rt=!1;function to(){if(rt)return;rt=!0,(f.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{rt=!1,st(),lt(),_t()})}let dt=!1;function no(){if(dt)return;dt=!0,(f.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{dt=!1,qe()})}let zt=[];function fe(){const{colors:e,mixedHardBins:t}=To(v.filter(n=>n!=null),{binColorScheme:c.binColorScheme,useDefinedBinColors:c.useDefinedBinColors});return zt=t,e}function _t(){at("binColors",fe(),Io),Be()}const oo=oi(ce,()=>ai(c,Qn,{functionalActive:Ee(),hasLimits:Vt()&&!Ee(),hasRecorded:Jn()&&!Ee(),binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},e=>T(e)),()=>li(c)),{btn:io,sync:Gt}=ni(ce,()=>({plotMode:c.plotMode,legendPosition:ye}),e=>{ye=e;for(const t of S)t&&t.setOptions({legendPosition:ye})},{get:()=>Pe,set:e=>{Pe=e,Et()},blockedReason:we});Gt();const ao=[{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"}],Kt=Lt("aggr","Aggregation method",()=>ao,()=>c.aggregationMethod??"mean",e=>T({aggregationMethod:e}));function qt(){const e=c.plotMode==="stackedValues";Kt.style.display=e?"":"none"}qt();const{btn:lo,sync:Ut}=ti(ce,()=>({...c,functionalActive:Ee()}),e=>T(e));Ut();const ze=Q("specRange","Colorbar range: test limits",()=>{const e=c.colorbarRangeMode==="data"?"spec":"data";T({colorbarRangeMode:e})});function Xt(){const e=(c.plotMode??"hardBin")==="value"&&Vt()&&Mn(c)==="off"&&!Ee();ze.style.display=e?"":"none";const t=(c.colorbarRangeMode??"spec")==="spec";Se(ze,t),ze.ariaLabel=t?"Colorbar range: test limits (click for data range)":"Colorbar range: data range (click for test limits)"}Xt();const so=ii(ce,()=>c,e=>T(e)),ro=Q("downloadAll","Download gallery PNG",Co),co=Lt("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"}],()=>k!=null?String(k):"auto",e=>ln(e==="auto"?void 0:Number(e))),O=f.ownerDocument.createElement("div");Object.assign(O.style,{display:"inline-flex",alignItems:"center",gap:"0"}),W.appendChild(O),O.appendChild(Y),O.appendChild(Zn),O.appendChild(Kt),O.appendChild(lo),O.appendChild(ze),O.appendChild(G()),O.appendChild(oo),O.appendChild(G()),O.appendChild(io),O.appendChild(G()),O.appendChild(so),O.appendChild(G()),O.appendChild(co),O.appendChild(G()),O.appendChild(ro),(V||nt())&&(P=Q("findings","Summary panel",()=>{if(!b)return;const e=b.style.display!=="none";e||N(),b.style.display=e?"none":"flex",Se(P,!e),le()}),W.appendChild(G()),W.appendChild(P));let K=null,_e=null,J=[],Yt=!1;function Be(){const e=Mi({lotStatsSummary:V,result:{warnings:[...v.flatMap(n=>n?.warnings??[]),...Bt().warnings]},extra:[c.binColors&&Lo(c.binColors,c.plotMode),Ro(zt),Pn(kt())].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||!Yt)&&(Yt=!0,p.warnings?.onWarning?.(e)),uo()}function uo(){if(!K||!_e)return;const e=J.length,t=e>0;if(K.style.display=t?"flex":"none",_e.style.display=t?"":"none",!t)return;const n=ki(J[0]),o=`${e} data ${e===1?"warning":"warnings"}`;K.style.color=n==="error"?h.errText:h.warnText,K.ariaLabel=n==="error"?`${o} \u2014 some wafers may be positionally wrong`:o}(p.warnings?.display??!0)&&(_e=G(),K=Q("warning","Data warnings",()=>{const e=Me();if(je(new MouseEvent("click")),e)return;const t=Di(K.getBoundingClientRect(),J,K.ownerDocument.defaultView??window);wn(f).appendChild(t),De(t),xn(t,K,()=>je(new MouseEvent("click")))}),Ae(K,!1),W.appendChild(_e),W.appendChild(K)),Be();let se=null;H&&(se=Q("analysis","Insights",()=>{Jt(!Te)}),se.dataset.wmapInsightsBtn="1",W.appendChild(G()),W.appendChild(se));function Zt(){import("./userGuideHtml.js").then(e=>Jo({buildWaferMap:Ci,renderWaferMap:bi,renderWaferGallery,analyzeWaferMap:Je},e.USER_GUIDE_HTML,I,f))}E&&(W.appendChild(G()),W.appendChild(Q("help","User guide",()=>Zt())));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:`${w.sm} ${w.lg}`,fontSize:L.sub,lineHeight:Ze.none,boxSizing:"border-box"});const Ge=f.ownerDocument.createElement("div");Object.assign(Ge.style,{background:h.canvasBg,display:"flex",alignItems:"stretch",gap:w.lg,paddingBottom:w.lg,minWidth:"0"});const ee=f.ownerDocument.createElement("div");ee.dataset.wmapGalleryLegend="1",Object.assign(ee.style,{display:"flex",flexDirection:"column",gap:w.sm,background:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.container,padding:`${w.sm} ${w.lg}`,marginBottom:w.lg,boxShadow:$e.panel,fontSize:L.body,lineHeight:Ze.none,boxSizing:"border-box",width:"100%",minWidth:"0"});const q=f.ownerDocument.createElement("div");Object.assign(q.style,{display:"flex",flexDirection:"row",alignItems:"flex-start"});let me=null,Oe=null,Qt=null;function fo(){return H?me?Promise.resolve(me):(Qt??=import("./insightsTab.js").then(({createInsightsTab:e})=>(me=e({getItems:()=>v,getLotStats:()=>V,getBinColors:()=>c.binColors??fe(),getRingCount:tt,defaultView:p.insights?.defaultView,sweeps:p.insights?.sweeps,onRemoveSweeps:p.insights?.onRemoveSweeps,onOpenGuide:void 0,showMetadataStrip:!1,onSaveImage:Fe.onSaveImage,onSaveText:Fe.onSaveText,ownerDocument:f.ownerDocument,openWafer:(t,n,o)=>{const d=v[t];if(!d)return;let l=null;const a=Xo({title:n,onClose:()=>l?.destroy(),anchor:f});dn(a,n,d.wafer.metadata??void 0),l=ht(a.contentWrap,d,o)}}),Oe=me.el,Oe.style.display="none",f.appendChild(Oe),me)),Qt):Promise.resolve(null)}let Te=!1;function Jt(e){H&&(Te=e,Oe&&(Oe.style.display=e?"flex":"none"),q.style.display=e?"none":"flex",O.style.display=e?"none":"inline-flex",W.style.display="inline-flex",se&&(Se(se,e),se.innerHTML=e?We.wafer:We.analysis,se.ariaLabel=e?"Back to gallery view":"Insights"),le(),qe(),e&&fo().then(t=>{!t||!Te||(t.el.style.display="flex",t.render())}))}H&&p.insights?.defaultOpen&&queueMicrotask(()=>Jt(!0));const po=4,ct=240,en=480,mo=720,go=1.25;let ge=en;function tn(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 l=o.wafer.radius*2*(po/d),a=Math.ceil(l+t);(n==null||a>n)&&(n=a)}return n}function ho(e){const t=tn(e);return t==null?ct:Math.min(ge,Math.max(ct,t))}function bo(e){const t=tn(e);if(t==null)return!1;const n=Math.min(mo,Math.max(en,t));return n<=ge?!1:(ge=n,!0)}function ut(){return k!=null?"none":`${ge}px`}function nn(){const e=ut();for(const t of Array.from($.children))t.classList.contains("wmap-gallery-card")&&(t.style.maxWidth=e,t.style.maxHeight=e)}let Ke=ct,on=0;function an(e){if(bo(e)&&nn(),k==null){const n=ho(e);n>Ke&&(Ke=n)}pt()}function ln(e){k=In(e),nn(),pt()}function ft(e){return`repeat(${e}, minmax(0, ${k!=null?"1fr":`${ge}px`}))`}function sn(e){$.style.gridTemplateColumns!==e&&($.style.gridTemplateColumns=e)}function pt(){if(k!=null){sn(ft(k));return}const e=Math.max(1,on),t=12,n=$.clientWidth||0,o=l=>(n-t*(l-1))/l;let d=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){const l=Math.min(ge,Ke*go),a=r=>{let i=0;for(;i<e&&o(i+1)>=r;)i++;return i};d=a(l)||a(Ke)||1}sn(ft(d))}const $=f.ownerDocument.createElement("div");if(Object.assign($.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:ft(1),gap:w.xl,paddingLeft:oe,paddingRight:oe,justifyContent:"start",alignContent:"start",isolation:"isolate"}),re?.placement){const e=re.placement;b=Mt(e,oe,f.ownerDocument),b.style.maxHeight="calc(100vh - 80px)",b.style.position="sticky",b.style.top="8px",b.style.display="flex",b.style.flexDirection="column"}else if(V||nt()){const e=!!re?.defaultOpen;b=Mt("right",oe,f.ownerDocument),b.style.maxHeight="calc(100vh - 80px)",b.style.position="sticky",b.style.top="8px",b.style.flexDirection="column",b.style.display=e?"flex":"none",N()}le(),b?.style.display!=="none"&&P&&Se(P,!0),(re?.placement??"right")==="left"?(b&&q.appendChild(b),q.appendChild($)):(q.appendChild($),b&&q.appendChild(b));const Le=f.ownerDocument.createElement("div");Object.assign(Le.style,{position:"sticky",top:"0",display:"flex",flexDirection:"column",paddingLeft:oe,paddingRight:oe,paddingTop:oe,zIndex:"1",background:h.menuBg}),Ge.appendChild(pe),Ge.appendChild(W),Le.appendChild(Ge),Le.appendChild(ee),f.appendChild(Le),f.appendChild(q);function qe(){ee.innerHTML="";const e=c.plotMode??"hardBin",t=!Te&&hn.has(e),n=R.filter(g=>g!=null),o=n.find(g=>g.isLotStack),d=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=c.activeMetadataKey,r=t&&!l?Wn(n,g=>(e==="softBin"?g.sbin:g.hbin)??void 0,An):{counts:new Map,total:0,pass:0},i=t&&!l?c.binColors??fe():void 0,s=i?e==="softBin"?i.pass.soft:i.pass.hard:new Set,u=mi(r.counts.entries(),s).map(([g])=>g),m=t&&l&&a?Wn(n,g=>Oo(g.metadata?.[a])):{counts:new Map,total:0,pass:0},M=l?Nt()?.values:void 0,D=t&&l?(M??[...m.counts.keys()].sort(St)).filter(g=>m.counts.has(g)):[];if(pe.innerHTML="",d&&pe.appendChild(d),pe.style.display=d?"flex":"none",!u.length&&!D.length){ee.style.display="none";return}ee.style.display="flex";const x=f.ownerDocument.createElement("div");Object.assign(x.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:`${w.sm} ${w.xl}`,maxHeight:"86px",overflowY:"auto",overflowX:"hidden"}),ee.appendChild(x);const y=c.highlightBin,B=R.flatMap(g=>g?.metadataFields??[]).find(g=>g.key===a),j=l?B?.label??(a?Li(a):"Metadata"):No[e],U=f.ownerDocument.createElement("span");if(U.textContent=j,Object.assign(U.style,{fontSize:L.body,fontWeight:"700",letterSpacing:Ho,textTransform:"uppercase",color:h.label,flexShrink:"0"}),x.appendChild(U),!l&&r.total>0){const g=r.pass,F=g/r.total*100,te=f.ownerDocument.createElement("span");te.textContent=`Yield ${et(F)}`,Object.assign(te.style,{fontSize:L.body,fontWeight:"700",color:h.value,whiteSpace:"nowrap",flexShrink:"0"});const ne=f.ownerDocument.createElement("span");ne.textContent=`${g.toLocaleString()} / ${r.total.toLocaleString()} dies`,Object.assign(ne.style,{fontSize:L.body,color:h.label,whiteSpace:"nowrap",flexShrink:"0"}),x.appendChild(te),x.appendChild(ne)}if(l){const g=c.highlightMetadataValue;D.forEach((F,te)=>{const ne=g===F,Xe=B?.values?.find(vt=>vt.value===F),Mo=Xe?.color??Po(te),mn=m.counts.get(F)??0;$n(x,{color:Mo,isActive:ne,label:Xe?.label??F,count:mn,percent:m.total>0?mn/m.total*100:void 0,onClick:()=>{const vt=c.highlightMetadataValue===F?void 0:F;T({highlightMetadataValue:vt})}})});return}const bt=e==="softBin"?R.flatMap(g=>g?.sbinDefs??[]):R.flatMap(g=>g?.hbinDefs??[]),un=new Set,yt=[];for(const g of bt)un.has(g.bin)||(un.add(g.bin),yt.push(g));const wt=yt.length>0?new Map(yt.map(g=>[g.bin,g])):null,fn=i??c.binColors??fe(),So=e==="softBin"?fn.soft:fn.hard,pn=g=>So.get(g)??Ao;for(const g of u){const F=y===g,te=wt?.get(g),ne=r.counts.get(g)??0;$n(x,{color:pn(g),isActive:F,label:te?.name?`${g} \xB7 ${te.name}`:`Bin ${g}`,count:ne,percent:r.total>0?ne/r.total*100:void 0,onClick:()=>{const Xe=c.highlightBin===g?void 0:g;T({highlightBin:Xe})}})}r.total>0&&u.length>1&&ee.appendChild(Hi(f.ownerDocument,[...r.counts.entries()].sort(([,g],[,F])=>F-g).map(([g,F])=>({color:pn(g),count:F,label:wt?.get(g)?.name?`${g} \xB7 ${wt.get(g).name}`:`Bin ${g}`})),r.total))}function Re(e){const t=v.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(Pi)),o=t[0].wafer,d=t.length,l=o.metadata?{...o,metadata:(({wafer:r,waferId:i,...s})=>s)(o.metadata)}:o;function a(r,i){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:i,lotSize:d}}}if(e==="stackedValues"){const r=ve();let i=r?.filter(Ct);if(r!==void 0&&i?.length===0)return[];if(r?.length||(i=Do(t.flatMap(m=>m.dies)).map(m=>({testNumber:m,name:Ri(void 0,m)}))),!i?.length)return[];const s=c.aggregationMethod??"mean";return i.map(u=>{const m=hi(n,s,u.testNumber),M={testNumber:0,name:u.name,unit:u.unit,...Wi(u)};return{wafer:l,dies:m,testDefs:[M],label:`${Ii(u,u.testNumber)} \xB7 ${s}`,isLotStack:!0,aggrMethod:s,lotSize:d,statsSummary:a(Je({wafer:l,dies:m,testDefs:[M]},{testNumbers:[0]}),s)}})}if(e==="stackedBins"){let r=Ye(t.map(i=>i?.hbinDefs));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(s=>s.dies.map(u=>u.hbin).filter(u=>u!=null)))].sort((s,u)=>s-u).map(s=>({bin:s,name:`Bin ${s}`}))),r.map(i=>{const s=kn(n,i.bin,"hard"),u=[{bin:i.bin,name:i.name}];return{wafer:l,dies:s,hbinDefs:u,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:a(Je({wafer:l,dies:s,hbinDefs:u}),"countBin")}})}if(e==="stackedSoftBins"){let r=Ye(t.map(i=>i?.sbinDefs));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(s=>s.dies.map(u=>u.sbin).filter(u=>u!=null)))].sort((s,u)=>s-u).map(s=>({bin:s,name:`Bin ${s}`}))),r.map(i=>{const s=kn(n,i.bin,"soft"),u=[{bin:i.bin,name:i.name}];return{wafer:l,dies:s,sbinDefs:u,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:a(Je({wafer:l,dies:s,sbinDefs:u}),"countBin")}})}return t}function mt(e){const t=v.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:c.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}function T(e,{fireCallback:t=!0}={}){const n=Object.keys(e),o=c.plotMode,d=we()!==null;c={...c,...e};const l=c.plotMode,a=be.has(l),r=o!==void 0&&be.has(o),i=He>0;if("binColorScheme"in e||"useDefinedBinColors"in e){const u=fe();c={...c,binColors:u},e={...e,binColors:u}}if(e.plotMode!==void 0)if(a){const u=mt(l);if(c={...c,...u},i)for(const m of S)m&&m.setOptions(e);else Z(Re(l))}else if(r){const{valueRange:u,lotSize:m,aggregationMethod:M,...D}=c;if(c=D,i)for(const x of S)x&&x.setOptions(e);else Z(v.filter(x=>x!==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 Z(Re("stackedValues"));else for(const u of S)u&&u.setOptions(e);we()!==null!==d&&Et(),qe(),qt(),Gt(),jt();const s=e.plotMode!==void 0&&e.plotMode!==o;(xi.some(u=>u in e)||s)&&N(),Be(),Ut(),Xt(),st(),lt(),t&&p.onViewOptionsChange?.(Bn(c),n,vi(n))}function rn(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:L.sub,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(d);const l=Rn(n??{});let a=null;if(l.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:L.body,lineHeight:Ze.none,color:h.label,flexShrink:"0"}),r.textContent="\u25BE",o.appendChild(r),Object.assign(o.style,{cursor:"pointer",borderRadius:z.control}),o.addEventListener("mouseenter",()=>{o.style.background=h.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:bn,background:h.menuBg,borderBottom:`1px solid ${h.menuBorder}`,boxShadow:$e.menu,padding:`${w.md} ${w.lg}`,fontSize:L.body,display:"none"});const i=Ln(n??{});i&&a.appendChild(i),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Cn(o,s=>{r.textContent=s?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(s)),a&&(a.style.display=s?"block":"none")})}return{wrap:o,metaPanel:a}}function dn(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),d=Rn(n??{});if(!o||d.length===0)return;const l=o.parentElement,a=f.ownerDocument.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:w.xs,flex:"1",minWidth:"0",cursor:"pointer"}),xt(a,"bare"),l?.insertBefore(a,o),a.appendChild(o);const r=f.ownerDocument.createElement("span");Object.assign(r.style,{fontSize:L.body,lineHeight:Ze.none,color:h.label,flexShrink:"0"}),r.textContent="\u25BE",a.appendChild(r);const i=f.ownerDocument.createElement("div");i.dataset.wmapCardMetaPanel="1",Object.assign(i.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:bn,background:h.menuBg,borderBottom:`1px solid ${h.menuBorder}`,boxShadow:$e.menu,padding:`${w.md} ${w.lg}`,fontSize:L.body,display:"none"});const s=Ln(n??{});s&&i.appendChild(s),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.`),Cn(a,u=>{r.textContent=u?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(u)),i.style.display=u?"block":"none"})}function gt(e,t,n){const o=f.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.container,boxShadow:$e.panel,overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:ut(),maxHeight:ut()});const d=f.ownerDocument.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${h.menuBorder}`,flexShrink:"0",gap:w.sm});const{wrap:l,metaPanel:a}=rn(document,Qe(e,t),e.wafer.metadata??void 0);d.appendChild(l);const r=f.ownerDocument.createElement("button");r.dataset.wmapExpandBtn="1",r.setAttribute("aria-label","Open full view"),Sn(r),r.innerHTML=We.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${h.menuBorder}`,borderRadius:z.control,background:h.panelBg,color:h.label,padding:w.xxs,cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),xt(r),d.appendChild(r),o.appendChild(d);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),$.appendChild(o),o.addEventListener("contextmenu",M=>{if(M.defaultPrevented)return;const D=p.insights?.sweeps;if(!yi(e.testDefs,D))return;M.preventDefault();const x=e.viewOptions?{...c,...e.viewOptions}:c,y=wi(e.dies,{waferLabel:Dn(e),testDefs:e.testDefs,isLotStack:e.isLotStack,activeTest:x.plotMode==="value"?x.activeTest:void 0,waferIndex:t}),B={x:M.clientX,y:M.clientY};import("./drilldown.js").then(({openDrilldownMenu:j})=>{o.isConnected&&j(B,o,y,{sweeps:D,onSaveImage:p.onSaveImage})})});const s=Pe||we()!==null,u=e.viewOptions?{...c,...e.viewOptions}:c,m=En(i,e,{viewOptions:{...u,showLegend:s,legendPosition:ye},showTooltip:!0,padding:A,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,insights:X,onExpand:()=>Ie(t,e),showIdentity:!1,chromeInset:Vo});return m.setViewControlsVisible(!1),m.setSummaryVisible(!1),r.onclick=()=>Ie(t,e),{card:o,ctrl:m,canvasWrapper:i,expandBtn:r}}function yo(e){const t=de[e];if(!t)return;const n=[..._.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=We.minimize,t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>vo(n.id)):(t.innerHTML=We.expand,t.setAttribute("aria-label","Open full view"),t.onclick=()=>Ie(e,R[e]))}function Z(e){xo(),Me()?.remove(),De(null),it(),R=[];for(const i of S)i&&i.destroy();S=[],ae=[],de=[],He=0,$.innerHTML="",on=e.length,an(e.map(i=>typeof i=="function"?null:i));const t=[];for(let i=0;i<e.length;i++){const s=e[i];if(typeof s=="function"){const u=f.ownerDocument.createElement("div");u.className="wmap-gallery-card",Object.assign(u.style,{background:h.menuBg,border:`1px solid ${h.menuBorder}`,borderRadius:z.container,aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const m=f.ownerDocument.createElement("span");m.textContent="\u2026",Object.assign(m.style,{color:h.label,fontSize:"18px"}),u.appendChild(m),$.appendChild(u),R.push(null),S.push(null),ae.push(null),de.push(null),t.push({index:i,factory:s,placeholder:u}),He++}else{const{ctrl:u,canvasWrapper:m,expandBtn:M}=gt(s,i,e.length);R.push(s),S.push(u),ae.push(m),de.push(M)}}_t(),qe(),st(),lt();const n=++xe,o=()=>{setTimeout(()=>{n===xe&&p.onItemsResolved?.()},0)},d=i=>{setTimeout(()=>{n===xe&&p.onItemResolved?.(i,e.length)},0)};let l=e.length-t.length;l>0&&d(l);let a=0;function r(){if(n!==xe)return;if(a>=t.length){if(be.has(c.plotMode)){const B=c.plotMode;Z(Re(B));return}ke=o,N(),ue||(ke=null,o());return}const{index:i,factory:s,placeholder:u}=t[a++],m=s();R[i]=m,v[i]=m,an([m]);const{card:M,ctrl:D,canvasWrapper:x,expandBtn:y}=gt(m,i,e.length);S[i]=D,ae[i]=x,de[i]=y,He--,u.replaceWith(M),d(++l),no(),to(),!b&&!re?.placement&&m.statsSummary?.findings.length&&(b=Mt("right",oe,f.ownerDocument),b.style.maxHeight="calc(100vh - 80px)",b.style.position="sticky",b.style.top="8px",b.style.flexDirection="column",b.style.display="none",(re?.placement??"right")==="left"?q.insertBefore(b,$):q.appendChild(b),N(),P||(P=Q("findings","Summary panel",()=>{if(!b)return;const j=b.style.display!=="none";j||N(),b.style.display=j?"none":"flex",Se(P,!j),le()}),W.appendChild(G()),W.appendChild(P)),le()),le(),setTimeout(r,0)}t.length>0?setTimeout(r,0):o()}if(be.has(c.plotMode)&&v.length>0){const e=mt(c.plotMode);c={...c,...e},Z(Re(c.plotMode))}else Z(C);Be();let he=0;const cn=new(f.ownerDocument.defaultView??window).ResizeObserver(()=>{if(he)return;he=(f.ownerDocument.defaultView??window).requestAnimationFrame(()=>{he=0,k==null&&pt()})});cn.observe($),b&&N();function wo(e,t){const n=ae[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:h.label,fontSize:L.body,textAlign:"center",padding:"0 12px"}),n.appendChild(o)}function Ie(e,t){for(const a of _.values())if(a.cardIndex===e)return;const n=Qe(t,e),o=Fn++,d=S[e]?.getOptions(),l=qo(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:L.family}),Zo(f,a.documentElement);const r=Qo(f,a.documentElement,()=>x.setOptions({})),i=a.createElement("div");i.dataset.wmapWindowBanner="1",i.textContent=n,Object.assign(i.style,{display:"none",padding:`${w.sm} ${w.xl}`,fontSize:L.body,fontWeight:"700",background:h.warnBg,color:h.warnText,borderBottom:`1px solid ${h.warnBorder}`,flexShrink:"0"}),a.body.appendChild(i);const s=a.createElement("div");Object.assign(s.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),a.body.appendChild(s);const{wrap:u,metaPanel:m}=rn(a,n,t.wafer.metadata??void 0),M=a.createElement("div");Object.assign(M.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${h.menuBorder}`,flexShrink:"0",gap:w.sm}),M.appendChild(u),s.appendChild(M);const D=a.createElement("div");Object.assign(D.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),m&&D.appendChild(m),s.appendChild(D);const x=ht(D,t,void 0,d),y=setInterval(()=>{l.closed&&Ue(o)},400);l.addEventListener("pagehide",()=>Ue(o)),_.set(o,{id:o,ctrl:x,cardIndex:e,label:n,closePollId:y,stopThemeSync:r,close:()=>{l.closed||l.close()},setTitle:B=>{a.title=B,i.textContent=B,i.style.display="block"}})}else{const a=Uo({title:n,onClose:()=>Ue(o),anchor:f});a.contentWrap.style.flexDirection="column",dn(a,n,t.wafer.metadata??void 0);const r=ht(a.contentWrap,t,void 0,d);_.set(o,{id:o,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>a.close(),setTitle:i=>{const s=a.box.querySelector("[data-wmap-window-title]");s&&(s.textContent=i,s.title=i)}})}S[e]?.destroy(),S[e]=null,wo(e,l!==null),yo(e)}function ht(e,t,n,o){const d=t.viewOptions?{...c,...t.viewOptions}:c,l=o?{...d,...o}:d,r={...n!==void 0?{...l,plotMode:"value",activeTest:n}:l,showLegend:!0,legendPosition:ye},i=En(e,t,{viewOptions:r,showTooltip:!0,padding:A,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,insights:X,showExpandButton:!1,showIdentity:!1});return i.setViewControlsVisible(!0),i.setSummaryVisible(!0),i.setExpandVisible(!1),i}function Ue(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=R[n];if(!o)return;const{card:d,ctrl:l,canvasWrapper:a,expandBtn:r}=gt(o,n,R.length);ae[n]?.parentElement?.replaceWith(d),S[n]=l,ae[n]=a,de[n]=r}function vo(e){const t=_.get(e);t&&(t.close(),Ue(e))}function xo(){for(const e of _.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function Co(){const e=[...$.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,l=e[0].height,a=8,r=(f.ownerDocument.defaultView??window).devicePixelRatio||1,i=Math.round(26*r),s=Math.round(12*r),u=f.ownerDocument.createElement("canvas");u.width=n*d+(n-1)*a,u.height=o*(l+i)+(o-1)*a;const m=u.getContext("2d"),M=Fo($);m.fillStyle=M.background,m.fillRect(0,0,u.width,u.height),e.forEach((D,x)=>{const y=x%n,B=Math.floor(x/n),j=y*(d+a),U=B*(l+i+a),bt=D.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";m.fillStyle=M.surface,m.fillRect(j,U,d,i),m.fillStyle=M.text,m.font=`700 ${s}px system-ui, sans-serif`,m.textAlign="left",m.textBaseline="middle",m.fillText(bt,j+Math.round(10*r),U+i/2,d-Math.round(20*r)),m.drawImage(D,j,U+i)}),u.toBlob(D=>{if(!D)return;if(p.downloadFilename!=null){vn(D,p.downloadFilename,p.onSaveImage);return}const x=S.find(y=>y!=null)?.getExportTitle();vn(D,["gallery",x].filter(Boolean).join(" "),Fe.onSaveImage)})}return{setItems(e){v=e.map(n=>typeof n=="function"?null:n);const t=c.plotMode;if(be.has(t))if(e.some(o=>typeof o=="function"))Z(e);else{const o=mt(t);c={...c,...o},Z(Re(t))}else Z(e)},setOptions(e){T(e,{fireCallback:!1})},getOptions(){return Bn(c)},setFindingsNotice(e){It=e,N()},setColumns(e){ln(e)},getBinColors(){return c.binColors??fe()},setLotStatsSummary(e){V=e,Be(),b&&N(),le()},openUserGuide:Zt,destroy(){xe++,ue?.cancel(),ue=null,ke=null;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=[],Me()?.remove(),cn.disconnect(),he&&((f.ownerDocument.defaultView??window).cancelAnimationFrame(he),he=0),f.ownerDocument.removeEventListener("click",je,!0),window.removeEventListener("blur",Rt),ie(),yn(),Le.remove(),q.remove(),b?.remove(),me?.destroy()}}}
@@ -1 +1 @@
1
- import{buildView as Oi,buildHoverText as Ri,findTestDef as gt,resolveTestNumber as _t,buildMapTitle as Ii}from"../renderer/buildView.js";import{drawMapCanvas as Wi,BIN_LEGEND_W as $n,BIN_LEGEND_W_COMPACT as Fi,BIN_LEGEND_ADAPT_COMPACT as Ai,BIN_LEGEND_ADAPT_FLOATING as Hi}from"./toCanvas.js";import{buildWaferMap as zi,getTestPassStatus as Vi,isParametricTest as $t}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Yi}from"../stats/analyzeWaferMap.js";import{SHADOW as Xi,LEADING as Gn,wireControlHover as Un,SPACE as A,EDGE_GUTTER as Ni,RADIUS as Zn,FONT as mt,CLR as w,applyOverlayZ as ji,getTooltip as Qn,hideTooltip as yt,positionTooltip as qn,createToolbarHelpers as Ki,buildModeMenuEl as _i,openReparentedModal as $i,openUserGuideWindow as Gi,makePaletteBtn as Ui,makeLogScaleBtn as Zi,makeLegendStyleBtn as Qi,makeOverlaysBtn as qi,makeOrientationBtn as Ji,menuLayerFor as Jn,saveImageBlob as ei,markMenuTrigger as Qe,wireMenuA11y as ti,wireExpandToggle as eo,nextFrame as Gt,requestedPassFailDisplay as to,overlayMenuRows as no,anyOverlayActive as io,logWmapVersionOnce as oo,buildDataModeEntries as so,metadataKeyHasData as lo,metadataModeEntry as ao}from"./toolbar.js";import{waferIdentityLabel as ro}from"../core/waferLabel.js";import{metadataDisplayValue as co}from"../core/metadata.js";import{withExportContext as fo,noticeDownloadFilenameChange as po}from"./exportName.js";import{createSummaryPanelEl as Ut,wrapWithSummaryPanel as Zt,renderWaferSummaryContentSteps as uo}from"./summaryPanel.js";import{runChunked as ho}from"./chunked.js";import{collectWarnings as go,buildWarningsMenuEl as mo,severityOf as yo}from"./warnings.js";import{ICONS as ni}from"./icons.js";import{hasDrilldownTargets as bo,selectionPopulation as vo,waferPopulation as xo}from"./chartPopulation.js";import{createIdentityHeader as wo,collapsedLabel as Qt}from"./identityHeader.js";import{getDieKey as fe,hasPosition as ii,isPositionedDie as Co}from"../core/dies.js";import{buildDieListSection as So}from"./dieList.js";import{buildMaplessSummary as Mo}from"./maplessSummary.js";import{resolveBinColors as Eo,binColorWarning as Do}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as ko}from"../core/passBins.js";const oi=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(P){const m=P.some(p=>oi.has(p)),v=P.some(p=>!oi.has(p));return m&&v?"mixed":m?"preference":"state"}export function toPublicViewOptions(P){const{metadataValueOrder:m,binColors:v,lotSize:p,...k}=P;return k}export function renderWaferMap(P,m,v={}){return renderWaferMapCard(P,m,v)}export function renderWaferMapCard(P,m,v={}){oo();const p=P.ownerDocument,k=p.defaultView??window,qt=()=>q.label,Jt=()=>ro({label:qt(),wafer:V}),xe=fo(()=>{const e=co(V.metadata?.lot);return{lots:e!==void 0?[e]:[],...q.isLotStack?{stackedWafers:g?.lotSize??!0}:{wafer:Jt()}}},v.onSaveImage,v.onSaveText);po(v.downloadFilename);function en(){const e=g.plotMode==="softBin"||g.plotMode==="stackedSoftBins"?G:$,{primary:t,secondary:n}=Ii(g,c.fallbackFormat,e);return[t,q.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}k.getComputedStyle(P).position==="static"&&(P.style.position="relative");const si=P.clientHeight;v.height!=null&&(P.style.height=typeof v.height=="number"?`${v.height}px`:v.height);const bt=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!ii(e)).length,Oe=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-bt)===0&&bt>0,Re=p.createElement("div");Object.assign(Re.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),P.appendChild(Re);const we=p.createElement("div");Object.assign(we.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const pe=v.chromeInset??Ni,_=p.createElement("div");Object.assign(_.style,{display:"flex",alignItems:"stretch",gap:A.sm,background:w.canvasBg,paddingBottom:A.lg,paddingTop:pe,paddingLeft:pe,paddingRight:pe,flexShrink:"0",minWidth:"0"}),Re.appendChild(_),Re.appendChild(we);function Ie(){const e=[..._.children].some(t=>t.style.display!=="none");_.style.display=e?"flex":"none"}const M=p.createElement("div");Object.assign(M.style,{position:"relative",width:"100%",height:"100%"});const s=p.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),M.appendChild(s),we.appendChild(M);let qe=null;if(bt>0){let n=function(){if(t){const d=So(e,m.testDefs,{...v.dieList,onSaveText:xe.onSaveText,waferMetadata:V.metadata,metadataFields:he,ownerDocument:p});if(d)return d}const o=gt(m.testDefs,c.activeTest??0),a=$t(o)?c.logScale??o?.logScale??!1:!1;return Mo(e,m.testDefs,{plotMode:c.plotMode??"hardBin",activeTest:c.activeTest,hbinDefs:$,sbinDefs:G,binColors:g.binColors,valueColorScheme:c.valueColorScheme,reverseValueScheme:c.reverseValueScheme,logScale:a,colorbarRangeMode:c.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const a=p.createElement("button");return a.type="button",Un(a),Object.assign(a.style,{fontSize:mt.body,padding:`${A.xxs} ${A.sm}`,borderRadius:Zn.control,flexShrink:"0",border:`1px solid ${w.menuBorder}`,background:w.menuBg,color:w.text,cursor:"pointer"}),a.textContent=t?"View chart":"View die list",a.addEventListener("click",d=>{d.stopPropagation(),t=!t,a.textContent=t?"View chart":"View die list",o()}),a};const e=m.dies.filter(o=>!ii(o));let t=!1;if(Oe){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:w.panelBg,padding:A.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:A.md,zIndex:"1"});const a=p.createElement("div");Object.assign(a.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:A.md});const d=p.createElement("span");Object.assign(d.style,{fontSize:mt.body,color:w.label,lineHeight:Gn.base}),d.textContent="No die position data for this wafer.",a.appendChild(d);const l=p.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(a),o.appendChild(l),M.appendChild(o),qe=()=>{t||l.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,fontSize:mt.body,color:w.text,cursor:"pointer",padding:`${A.xs} ${A.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:A.md}),Un(o,"bare");const a=p.createElement("span");a.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(a);const d=p.createElement("span");d.textContent="\u25BE",Object.assign(d.style,{fontSize:mt.body,lineHeight:Gn.none,color:w.label,flexShrink:"0"}),o.appendChild(d),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,r=null;eo(o,f=>{if(d.textContent=f?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(f)),f){l=p.createElement("div");const h=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${h}px`,top:"20%",zIndex:"2",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,padding:A.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:A.md}),l.addEventListener("click",se=>se.stopPropagation());const y=p.createElement("div");Object.assign(y.style,{display:"flex",justifyContent:"flex-end"}),y.appendChild(i(()=>{r&&r.replaceChildren(n())})),l.appendChild(y),r=p.createElement("div"),Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(n()),l.appendChild(r),M.appendChild(l)}else l&&(l.remove(),l=null,r=null)}),M.appendChild(o),qe=()=>{r&&!t&&r.replaceChildren(n())}}}const{onHover:Je,onClick:li,onSelect:le,onViewOptionsChange:ai,showTooltip:ri=!0,showToolbar:We=!0,showIdentity:tn=!0,summaryPanel:Fe,showHelpButton:nn=!1,userGuideExtension:di,onExpand:on,showExpandButton:sn=!0,zIndex:ci,insights:Ce,warnings:ln,viewOptions:fi={},...Se}=v,Ae=Ce?.enabled??!1,pi=.4,ui=20,et=[...m.passBins??ko],an=ln?.display??!0,hi=ji(ci);let ae=v.statsSummary,re=[],rn=!1,tt=null,dn=!1;function vt(){const e=go({result:m,statsSummary:ae,extra:tt?[tt]:[]}),t=e.length!==re.length||e.some((n,i)=>n.code!==re[i]?.code||n.message!==re[i]?.message);re=e,(t||!rn)&&(rn=!0,ln?.onWarning?.(e))}vt();let q=m,V=m.wafer,ue=m.dies,C=new Set;const gi={sweeps:Ce?.sweeps,onSaveImage:xe.onSaveImage},xt=()=>!Oe&&bo(U,Ce?.sweeps);let cn=null,nt=null,it=!1,fn=!1,$=m.hbinDefs,G=m.sbinDefs,U=m.testDefs,he=m.metadataFields,pn=m.reticles?.length?m.reticles:void 0,un=m.reticleConfig,hn=m.view?.dataAxisFlip,wt=m.isLotStack??!1,Ct=m.aggrMethod,St=m.lotSize;const mi=We&&Ae;let Y=null,J=null,ee=null;tn&&(Y=wo(Qt(V.metadata??{},He())??"",V.metadata,{lotStack:He(),ownerDocument:p}),M.appendChild(Y.metaPanel),Y.metaPanel.style.visibility="visible",Y.isEmpty()||(J=gn(Y.wrap),_.insertBefore(J,_.firstChild),Ie()));function gn(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${A.sm} ${A.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:A.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function He(){return wt?{lotSize:St??1,aggrMethod:Ct}:void 0}function yi(){if(!Y)return;Y.update(Qt(V.metadata??{},He())??"",V.metadata,He());const e=J?.isConnected??!1,t=!Y.isEmpty();!t&&e?(J.remove(),J=null):t&&!e&&(J=gn(Y.wrap),J.style.display="",_.insertBefore(J,_.firstChild),Ie())}const bi=[...$??[],...G??[]].some(e=>e.color);let c={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...fi},X=null,te=!1,mn=null;function vi(){return Ae?X?Promise.resolve(X):(mn??=import("./insightsTab.js").then(({createInsightsTab:e})=>(X=e({getItems:()=>[{wafer:V,dies:ue,hbinDefs:$,sbinDefs:G,testDefs:U,label:qt(),passBins:et,statsSummary:ae}],getBinColors:()=>g.binColors,getRingCount:()=>q.ringCount??4,onSaveImage:xe.onSaveImage,onSaveText:xe.onSaveText,defaultView:Ce?.defaultView,sweeps:Ce?.sweeps,showMetadataStrip:!1,contentInset:pe,backTab:mi?void 0:{label:"Map",onBack:()=>ze(!1)},onOpenGuide:nn&&!We?()=>Xt():void 0,focusTest:t=>{D({plotMode:"value",activeTest:t,highlightBin:void 0}),ze(!1)},ownerDocument:p}),Object.assign(X.el.style,{position:"absolute",inset:"0",background:w.canvasBg,overflowY:"auto",paddingTop:"0"}),X.el.style.display="none",we.appendChild(X.el),X)),mn):Promise.resolve(null)}let yn=0;const Mt=["wheel","touchstart","pointerdown","keydown"];function xi(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const d of i)k.clearTimeout(d);i.length=0;for(const d of Mt)e.removeEventListener(d,o)},a=()=>n||!te?!0:(e.scrollTop=t,e.scrollTop>=t);if(!a()){for(const d of Mt)e.addEventListener(d,o,{passive:!0,once:!0});for(const d of[0,50,150,300,600])i.push(k.setTimeout(()=>{a()},d));i.push(k.setTimeout(()=>{for(const d of Mt)e.removeEventListener(d,o)},700))}}function ze(e){if(!Ae)return;const t=te;te=e,X&&!e&&t&&(yn=X.el.scrollTop),X&&(X.el.style.display=e?"flex":"none"),M.style.visibility=e?"hidden":"",F&&(F.style.display=e||Oe?"none":"flex"),T&&(T.style.display=e?"none":"flex"),ee&&(ee.style.display=be?"none":"flex"),ie&&(ie.style.display="flex"),J&&(J.style.display=""),Ie(),Y&&e&&Y.collapse(),rt(),H&&(H.innerHTML=e?ni.wafer:ni.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&vi().then(n=>{!n||!te||(n.el.style.display="flex",n.render(),xi(n.el,yn))})}Ae&&Ce?.defaultOpen&&queueMicrotask(()=>ze(!0));let g,bn,N=null,B=null,Et=[],Dt;function vn(e){Dt!==e&&(Dt=e,x())}let ge=null,kt=Se.legendOffset??{x:0,y:0},Ve=!1,Me=!1,Ye={x:0,y:0},Bt={x:0,y:0},me=!1,Ee=!1,j="pan",De={x:0,y:0},ot={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Xe=!1,ke=!1;function Lt(){const e=c;g=Oi(V,ue.filter(Co),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??Eo(ue,{passBins:et,binColorScheme:e.binColorScheme,hbinDefs:$,sbinDefs:G,useDefinedBinColors:e.useDefinedBinColors}),passBins:et,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:pn,ringCount:q.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:U,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:wt,aggregationMethod:Ct??e.aggregationMethod,lotSize:St??e.lotSize,dataAxisFlip:hn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:he}),bn=new Map(g.dies.map((n,i)=>[fe(n),i]));const t=e.binColors?null:Do(g.binColors,g.plotMode);t?.message!==tt?.message&&(tt=t,vt(),dn&&Tt())}Lt();let Z=null,Be=null,st=null,xn=v.findingsNotice,wi={},I=null,de=null;function Ci(e){const{kind:t,index:n}=e.variable;D(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const i=e.highlight;i.kind==="bin"?(Ft(i.dieKeys),D({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Ft(i.dieKeys)}const Ne=new Map;function wn(e){Ne.get(e)?.cancel(),Ne.delete(e);const t=ho(uo(e,{wafer:V,dies:ue,yieldSummary:q.yield,dataCoverage:q.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:U,statsSummary:ae,warnings:an?re:[],passBins:et,ringCount:q.ringCount??4,binColors:g.binColors,plotMode:c.plotMode??"hardBin",metadataShownElsewhere:tn,fallbackFormat:c.fallbackFormat,activeFindingId:st,findingsFilter:wi,findingsNotice:xn,onFindingsFilterChange:ye,onSaveText:xe.onSaveText,metadataFields:he,dieListOptions:v.dieList,onFindingClick:(n,i)=>{st===n.id?(st=null,Ft([]),D({highlightBin:void 0})):(st=n.id,Ci(n)),ye()}}));t.done||Ne.set(e,t)}function ye(){Z&&wn(Z)}function je(){I&&wn(I)}if(Fe?.placement){const e=Fe.placement;Z=Ut(e,pe,p);const t=M.parentElement,n=M.nextSibling;Be=Zt(M,Z,e),t?.insertBefore(Be,n),ye()}else if(ae){const e=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=e?"block":"none";const t=M.parentElement,n=M.nextSibling;de=Zt(M,I,"right"),t?.insertBefore(de,n),je()}const W=ri?Qn(p):null;let ie=null,L=null,F=null,T=null,lt=null,K=null,Cn=null,H=null,oe=null,at=null;dn=!0;function Tt(){if(!oe||!at)return;const e=re.length,t=e>0;if(oe.style.display=t?"flex":"none",at.style.display=t?"":"none",!t)return;const n=yo(re[0]),i=`${e} data ${e===1?"warning":"warnings"}`;oe.style.color=n==="error"?w.errText:w.warnText,oe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Pt=null,Sn=null,Ot=null,Rt=null,It=null,Wt=null;function Ft(e){C=new Set(e??[]),le&&le(Ke()),x()}function rt(){if(!K)return;const e=!!(Z??I);K.style.display=ae&&e&&!te?"flex":"none";const t=Z??I,n=t?t.style.display!=="none":!1;ae?.hasNotableFindings&&!n?K.style.color=w.findingIndicator:K.dataset.active||(K.style.color=w.icon)}let Mn=null;function En(e){const t=Z??I;t&&(t.style.display=e?"block":"none",K&&Mn?.(K,e),rt())}if(We){let h=function(b){j=b,i(se,b==="zoom"),i(E,b==="pan"),lt&&i(lt,b==="select"),s.style.cursor=b==="pan"?"grab":"crosshair"};ie=p.createElement("div"),ie.dataset.wmapToolbar="single",Object.assign(ie.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:w.menuBg,border:`1px solid ${w.menuBorder}`,borderRadius:Zn.control,boxShadow:Xi.panel,pointerEvents:"auto"});const e=Qn(p),t=Ki(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:a,makeMenuSection:d,closeOpenMenu:l,getOpenMenu:r,setOpenMenu:f}=t;Mn=i,Pt=l,Sn=r,p.addEventListener("click",l,!0),F=p.createElement("div"),Object.assign(F.style,{display:Oe?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(F);const y=n("download","Download PNG",Ei);F.appendChild(y),F.appendChild(o());const se=n("zoomMode","Zoom (drag to zoom region)",()=>h("zoom")),Te=n("zoomIn","Zoom in",()=>Le(s.clientWidth/2,s.clientHeight/2,1.2)),ne=n("zoomOut","Zoom out",()=>Le(s.clientWidth/2,s.clientHeight/2,1/1.2)),ce=n("reset","Reset zoom (double-click)",()=>ct());F.appendChild(se),F.appendChild(Te),F.appendChild(ne),F.appendChild(ce),F.appendChild(o());const E=n("pan","Pan (drag to move)",()=>h("pan"));F.appendChild(E),lt=n("boxSelect","Select (drag to select dies)",()=>h("select")),F.appendChild(lt);{const b=n("drilldown","Chart this wafer",()=>{const Pe=b.getBoundingClientRect();In({x:Pe.left,y:Pe.bottom+4},b)});b.setAttribute("aria-haspopup","menu"),nt=b,Rn(),F.appendChild(b)}i(E,!0);{let b=function(u){return u.plotMode!==(c.plotMode??"hardBin")?!1:u.plotMode==="value"?(c.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?c.activeMetadataKey===u.activeMetadataKey:!0},Pe=function(u,S){u.activeTest!==void 0?D({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),S.remove(),f(null),Qe(Q,!1)};L=p.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(L),T=p.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const ft=()=>{const u=r();u&&(u.remove(),f(null)),Qe(Q,!1)},Q=n("mode","Plot mode",()=>{if(r()){ft();return}const u=ue,S=g.testDefs,{testEntries:ht,binEntries:ve,stackedEntries:Ge}=so(u,S,{includeStacked:g.isLotStack}),Kt=(he??[]).filter(Ze=>lo(u,Ze.key)).map(ao),Ue=_i(Q.getBoundingClientRect(),ht,ve,Ge,b,Pe,{makeMenuRow:a,makeMenuSection:d},c.plotMode??"hardBin",Q.ownerDocument.defaultView??window,Kt);Jn(Q).appendChild(Ue),f(Ue),Qe(Q,!0),ti(Ue,Q,ft)});Qe(Q,!1);const{btn:pt,sync:$e}=Ui(t,()=>({...c,plotMode:c.plotMode??"hardBin"}),()=>bi,D);Rt=$e,Rt();const Nt=qi(t,()=>{const u=!!g.hasReticle,S=(c.plotMode??"hardBin")==="value",{testNumber:ht}=_t(c.activeTest??0,g.testDefs),ve=gt(g.testDefs,ht),Ge=S&&ve!==void 0&&!$t(ve),Kt=S&&!Ge&&(ve?.limitLow!==void 0||ve?.limitHigh!==void 0),Ue=S&&!Ge&&g.dies.some(Ze=>Vi(Ze,ht,ve)!==void 0);return no(c,u,{functionalActive:Ge,hasLimits:Kt,hasRecorded:Ue,binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},Ze=>D(Ze))},()=>io(c)),{btn:jt,sync:ki}=Qi(t,()=>c,u=>D({legendPosition:u}));Ot=ki,Ot();const _n=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&!$t(S)},{btn:Bi,sync:Li}=Zi(t,()=>({...c,functionalActive:_n()}),u=>D(u));It=Li,It();const Ti=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&(S.limitLow!==void 0||S.limitHigh!==void 0)},ut=n("specRange","Colorbar range: spec limits",()=>{const u=c.colorbarRangeMode==="data"?"spec":"data";D({colorbarRangeMode:u})});Wt=()=>{const u=c.plotMode==="value"&&Ti()&&to(c)==="off"&&!_n();ut.style.display=u?"":"none";const S=(c.colorbarRangeMode??"spec")==="spec";i(ut,S),ut.ariaLabel=S?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},Wt();const Pi=Ji(t,()=>c,u=>D(u));T.appendChild(Q),T.appendChild(pt),T.appendChild(Bi),T.appendChild(ut),Oe||(T.appendChild(o()),T.appendChild(Nt),T.appendChild(o()),T.appendChild(jt),T.appendChild(o()),T.appendChild(Pi)),ae&&(K=n("findings","Summary panel",()=>{const u=Z??I;u&&En(u.style.display==="none")}),L.appendChild(o()),L.appendChild(K),I?.style.display!=="none"&&i(K,!0),rt()),an&&(at=o(),oe=n("warning","Data warnings",()=>{const u=r();if(l(new MouseEvent("click")),u)return;const S=mo(oe.getBoundingClientRect(),re,k);Jn(we).appendChild(S),f(S),ti(S,oe,()=>l(new MouseEvent("click")))}),Qe(oe,!1),L.appendChild(at),L.appendChild(oe),Tt()),Ae&&(L.appendChild(o()),H=n("analysis","Insights",()=>{ze(!te),i(H,te)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),sn&&(L.appendChild(o()),ee=n("expand","Expand (E)",on??Dn),L.appendChild(ee)),nn&&(L.appendChild(o()),Cn=n("help","User guide",()=>Xt()),L.appendChild(Cn))}_.appendChild(ie),Ie()}let be=null;function Dn(){be&&(be.close(),be=null);const e=we;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=Qt(V.metadata??{},He()),n=_.childElementCount>0?[_,e]:[e],i=$i(n,{ownerDocument:p,boxSize:te?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{be=null,ee&&(ee.style.display="flex"),te||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),be=i,ee&&(ee.style.display="none"))}function kn(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&c.binColors!==void 0&&(e={...e,binColors:void 0});const t=c.plotMode;c={...c,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(a=>a==="legendPosition"||a==="showLegend"||a==="markFailingDies")||Lt(),Ot?.(),Rt?.(),It?.(),Wt?.(),x();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(a=>a in e);(o||i)&&(ye(),je()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&qe?.()}function D(e){kn(e);const t=Object.keys(e);ai?.(c,t,classifyChanged(t))}let At=!1;function Ht(){At||(At=!0,Gt(()=>{At=!1,x()},k))}function x(){const e=B??void 0,t=g.dies[0],n=t?{x:t.width,y:t.height}:Se.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!($?.length||G?.length||g.dies.some(y=>y.hbin!=null||y.sbin!=null)),a=c.legendPosition??"default",d=c.showLegend??!0,l=a==="default"||a==="compact",r=(Se.colorbarWidth??16)+28,f=o&&l?a!=="default"?Math.max($n,r):i<Hi?0:i<Ai?Math.max(Fi,r):Math.max($n,r):void 0,h=Wi(s,g,{...Se,minRightReserve:d?f:0,showColorbar:d&&(Se.showColorbar??!0),markFailingDies:c.markFailingDies??!1,legendPosition:a,legendOffset:kt,diePitchMm:n,fallbackFormat:c.fallbackFormat,showAxes:Se.showAxes??B!==null,viewport:e,activeBin:c.plotMode==="metadata"?c.highlightMetadataValue:c.highlightBin,hoverBin:Dt,hbinDefs:$,sbinDefs:G,metadataFields:he});Et=h.binLegendRows,ge=h.legendBox??null,B===null&&(N=h.viewport),C.size>0&&Si(),Ee&&Mi(),Rn()}function Si(){const e=z();if(!e)return;const t=s.getContext("2d"),n=g.hoverPoints,i=g.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,a=i?i.height/2*e.ppm:e.ppm*.5,d=Math.max(1,Math.min(3,o*.08)),l=o-d,r=a-d,f=[];for(const h of C){const y=bn.get(h);y!==void 0&&f.push({sx:e.originX+n[y].x*e.ppm,sy:e.originY-n[y].y*e.ppm})}if(f.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.restore()}}function Mi(){const e=s.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),i=Math.abs(R.x-O.x),o=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,i,o),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,i,o),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,i,o),e.restore()}function Ei(){s.toBlob(e=>{e&&(v.downloadFilename!=null?ei(e,v.downloadFilename,v.onSaveImage):ei(e,en(),xe.onSaveImage))})}function Bn(e){return N?Math.max(N.ppm*pi,Math.min(N.ppm*ui,e)):e}function Le(e,t,n){const i=B??N;if(!i)return;const o=Bn(i.ppm*n),a=o/i.ppm,d=e-(e-i.originX)*a,l=t-(t-i.originY)*a,r=(N?.snapDist??1)/(o/(N?.ppm??o));B={originX:d,originY:l,ppm:o,snapDist:r},x()}function z(){return B??N}function Ln(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Le(e.clientX-t.left,e.clientY-t.top,n)}else if(B!==null){e.preventDefault();const t=z(),n=B.snapDist;B={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},x()}}function zt(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function Tn(e){if(it=!1,e.button!==0||!z())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(ge&&c.legendPosition==="floating"&&zt(n,i,ge)){Me=!0,Ye={x:n,y:i},Bt={...kt};return}if(Xe&&j!=="pan"){ke=!0,me=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing";return}if(j==="zoom"||j==="select"){Ee=!0,O=R={x:n,y:i};return}me=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing"}function Pn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ee){R={x:n,y:i},Ht();return}if(Me){const h=n-Ye.x,y=i-Ye.y;h*h+y*y>16&&(Me=!1,Ve=!0,s.style.cursor="grabbing")}if(Ve){kt={x:Bt.x+(n-Ye.x),y:Bt.y+(i-Ye.y)},Ht();return}if(me){const h=z(),y=B?.snapDist??N?.snapDist??1;B={originX:ot.x+(n-De.x),originY:ot.y+(i-De.y),ppm:h.ppm,snapDist:y},Ht();return}const o=z();if(!o)return;const a=(n-o.originX)/o.ppm,d=(o.originY-i)/o.ppm,r=Yt(a,d,o.snapDist)?.die??null,f=Et.find(h=>n>=h.x&&n<h.x+h.w&&i>=h.y&&i<h.y+h.h);if(vn(f?f.bin:void 0),f){s.style.cursor="pointer",W&&(W.textContent=f.label??`Bin ${f.bin}`,W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})),Je?.(null,e);return}j==="pan"&&(s.style.cursor=r?"crosshair":"grab"),W&&(r?(W.innerHTML=Ri(r,g.plotMode,{testDefs:U,hbinDefs:$,sbinDefs:G,fallbackFormat:c.fallbackFormat,aggrMethod:g.aggrMethod,lotSize:g.lotSize,metadataFields:he,activeTest:g.activeTest,reticleConfig:un}),W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})):W.style.display="none"),Je?.(r,e)}function On(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(W&&(n<0||i<0||n>t.width||i>t.height)&&(W.style.display="none"),Ee){Ee=!1,R={x:n,y:i};const l=n-O.x,r=i-O.y,f=z();if(j==="zoom"){if(l*l+r*r<25)Le(n,i,2);else if(f){const h=Math.min(O.x,R.x),y=Math.max(O.x,R.x),se=Math.min(O.y,R.y),Te=Math.max(O.y,R.y),ne=y-h,ce=Te-se;if(ne>4&&ce>4){const E=s.clientWidth,b=s.clientHeight,Pe=E/ne,ft=b/ce,Q=Math.min(Pe,ft),pt=Bn(f.ppm*Q),$e=pt/f.ppm,Nt=(h+y)/2,jt=(se+Te)/2;B={originX:E/2-(Nt-f.originX)*$e,originY:b/2-(jt-f.originY)*$e,ppm:pt,snapDist:f.snapDist/$e}}}x(),s.style.cursor="crosshair";return}if(l*l+r*r<25)Vt(n,i,o,e);else if(f){const h=(Math.min(O.x,R.x)-f.originX)/f.ppm,y=(Math.max(O.x,R.x)-f.originX)/f.ppm,se=(f.originY-Math.max(O.y,R.y))/f.ppm,Te=(f.originY-Math.min(O.y,R.y))/f.ppm,ne=g.hoverPoints,ce=[];for(let E=0;E<ne.length;E++)if(ne[E].x>=h&&ne[E].x<=y&&ne[E].y>=se&&ne[E].y<=Te){const b=g.dies[E];b&&ce.push(b)}if(o)for(const E of ce){const b=fe(E);C.has(b)?C.delete(b):C.add(b)}else C=new Set(ce.map(E=>fe(E)));le?.(Ke())}x(),s.style.cursor="crosshair";return}if(Me){Me=!1,Vt(n,i,o,e);return}if(Ve){Ve=!1,s.style.cursor="grab";return}if(!me)return;if(me=!1,ke){ke=!1,s.style.cursor=Xe||j==="pan"?"grab":"crosshair";return}s.style.cursor=j==="pan"?"grab":"crosshair";const a=n-De.x,d=i-De.y;a*a+d*d<25&&Vt(n,i,o,e)}function Vt(e,t,n,i){for(const l of Et)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const r=c.highlightBin===l.bin?void 0:l.bin;D({highlightBin:r})}else{const r=c.highlightMetadataValue===l.bin?void 0:l.bin;D({highlightMetadataValue:r})}return}if(ge&&zt(e,t,ge))return;const o=z();if(!o)return;const d=Yt((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(d){li?.(d,i);const l=fe(d);n?C.has(l)?C.delete(l):C.add(l):C=new Set([l]),le?.(Ke()),x()}else n||(C=new Set,le?.([]),x())}function Ke(){const e=[],t=g.hoverPoints;for(let n=0;n<t.length;n++){const i=g.dies[n];i&&C.has(fe(i))&&e.push(i)}return e}function Rn(){nt&&(nt.style.display=xt()?"flex":"none",nt.ariaLabel=C.size>0?"Chart the selected dies (or right-click)":"Chart this wafer (or right-click)")}function Di(){const e={waferLabel:Jt(),testDefs:U,isLotStack:q.isLotStack,activeTest:c.plotMode==="value"?c.activeTest:void 0};return C.size>0?vo(Ke(),e):xo(ue,e)}function In(e,t){if(!xt())return;const n=Di();import("./drilldown.js").then(({openDrilldownMenu:i})=>{fn||(cn=i(e,t,n,gi))})}function Wn(e){e.stopPropagation();const t=it;if(it=!1,!xt()||te)return;const n=s.getBoundingClientRect();if(!t){const o=e.clientX-n.left,a=e.clientY-n.top;if(ge&&zt(o,a,ge))return;const d=z(),l=d?Yt((o-d.originX)/d.ppm,(d.originY-a)/d.ppm,d.snapDist)?.die:void 0;l&&!C.has(fe(l))&&(C=new Set([fe(l)]),le?.(Ke()),x())}e.preventDefault();const i=t?{x:n.left+n.width/2,y:n.top+n.height/2}:{x:e.clientX,y:e.clientY};In(i,s)}function Fn(){vn(void 0),W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair"}function An(){me=!1,ke=!1,Ee=!1,Me=!1,Ve=!1,W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair",x()}function Yt(e,t,n){const i=g.hoverPoints,o=g.rectangles;for(let r=0;r<o.length;r++){const f=o[r];if(Math.abs(e-f.x)<=f.width/2&&Math.abs(t-f.y)<=f.height/2){const h=g.dies[r];return h?{die:h,index:r}:null}}let a=null,d=-1,l=n*n;for(let r=0;r<i.length;r++){const f=i[r].x-e,h=i[r].y-t,y=f*f+h*h;y<l&&(l=y,a=g.dies[r]??null,d=r)}return a?{die:a,index:d}:null}const Hn=new k.ResizeObserver(()=>{N=null,B=null,x()});Hn.observe(s),v.height==null&&si<=0&&Gt(()=>Gt(()=>{P.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let _e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`);const dt=()=>{_e.removeEventListener("change",dt),_e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`),_e.addEventListener("change",dt),x()};_e.addEventListener("change",dt);const zn=k.matchMedia("(prefers-color-scheme: dark)"),Vn=()=>x();zn.addEventListener("change",Vn);const Yn=()=>{W&&yt(p)};k.addEventListener("blur",Yn);function Xn(e){if((e.key==="ContextMenu"||e.shiftKey&&e.key==="F10")&&(it=!0),e.key==="Escape"&&C.size>0&&(C=new Set,le?.([]),x()),(e.key==="e"||e.key==="E")&&sn&&(e.stopPropagation(),(on??Dn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),ct())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=z();if(n){const i=B?.snapDist??N?.snapDist??1;let o=0,a=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(a=20,e.preventDefault()),e.key==="ArrowDown"&&(a=-20,e.preventDefault()),(o||a)&&(B={originX:n.originX+o,originY:n.originY+a,ppm:n.ppm,snapDist:i},x())}e.key===" "&&!Xe&&(e.preventDefault(),Xe=!0,j!=="pan"&&(s.style.cursor="grab"))}}function Nn(e){e.key===" "&&(Xe=!1,ke&&(me=!1,ke=!1),s.style.cursor=j==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",Ln,{passive:!1}),s.addEventListener("pointerdown",Tn),s.addEventListener("pointermove",Pn),s.addEventListener("pointerup",On),s.addEventListener("pointerleave",Fn),s.addEventListener("pointercancel",An);const jn=()=>ct();s.addEventListener("dblclick",jn),s.addEventListener("keydown",Xn),s.addEventListener("keyup",Nn),s.addEventListener("contextmenu",Wn);const Kn=e=>{e.stopPropagation()};s.addEventListener("click",Kn),s.clientWidth,x(),qe?.();function ct(){N=null,B=null,x()}function Xt(){import("./userGuideHtml.js").then(e=>Gi({buildWaferMap:zi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:Yi},e.USER_GUIDE_HTML,di,P))}return Ie(),{setResult(e){q=e,V=e.wafer,ue=e.dies,$=e.hbinDefs,G=e.sbinDefs,U=e.testDefs,he=e.metadataFields,pn=e.reticles?.length?e.reticles:void 0,un=e.reticleConfig,hn=e.view?.dataAxisFlip,wt=e.isLotStack,Ct=e.aggrMethod,St=e.lotSize,yi(),Lt(),x(),Z&&ye()},setOptions(e){kn(e)},getOptions(){return{...c}},resetZoom:ct,setSelection(e){C=new Set(e.map(t=>fe(t))),x()},clearSelection(){C=new Set,le?.([]),x()},setFindingsNotice(e){xn=e,Z?ye():I&&je()},setStatsSummary(e){if(ae=e,vt(),Tt(),Z)ye();else if(I)je();else if(e&&!Fe?.placement){const t=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=t?"block":"none";const n=M.parentElement,i=M.nextSibling;de=Zt(M,I,"right"),n?.insertBefore(de,i),je()}rt()},closeSummaryPanel(){En(!1)},getExportTitle(){return en()},getBinColors(){return g.binColors},setSummaryVisible(e){K&&(K.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){ee&&(ee.style.display=e?"flex":"none")},openUserGuide:Xt,setInsightsOpen(e){ze(e),H&&(e?(H.dataset.active="1",H.style.background=w.bgActive,H.style.color=w.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=w.icon))},destroy(){fn=!0;for(const e of Ne.values())e.cancel();Ne.clear(),be?.close(),Sn?.()?.remove(),Pt&&p.removeEventListener("click",Pt,!0),s.removeEventListener("wheel",Ln),s.removeEventListener("pointerdown",Tn),s.removeEventListener("pointermove",Pn),s.removeEventListener("pointerup",On),s.removeEventListener("pointerleave",Fn),s.removeEventListener("pointercancel",An),s.removeEventListener("dblclick",jn),s.removeEventListener("keydown",Xn),s.removeEventListener("keyup",Nn),s.removeEventListener("contextmenu",Wn),cn?.(),s.removeEventListener("click",Kn),Hn.disconnect(),_e.removeEventListener("change",dt),zn.removeEventListener("change",Vn),k.removeEventListener("blur",Yn),hi(),W&&yt(p),ie?.remove(),Be&&(Be.parentElement?.insertBefore(M,Be),Be.remove()),de&&(de.parentElement?.insertBefore(M,de),de.remove()),M.remove(),s.style.cursor="",X?.destroy(),Y?.destroy(),Re.remove()}}}
1
+ import{buildView as Oi,buildHoverText as Ri,findTestDef as gt,resolveTestNumber as _t,buildMapTitle as Ii}from"../renderer/buildView.js";import{drawMapCanvas as Wi,BIN_LEGEND_W as $n,BIN_LEGEND_W_COMPACT as Fi,BIN_LEGEND_ADAPT_COMPACT as Ai,BIN_LEGEND_ADAPT_FLOATING as Hi}from"./toCanvas.js";import{buildWaferMap as zi,getTestPassStatus as Vi,isParametricTest as $t}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Yi}from"../stats/analyzeWaferMap.js";import{SHADOW as Xi,LEADING as Gn,wireControlHover as Un,SPACE as A,EDGE_GUTTER as Ni,RADIUS as Zn,FONT as mt,CLR as w,applyOverlayZ as ji,getTooltip as Qn,hideTooltip as yt,positionTooltip as qn,createToolbarHelpers as Ki,buildModeMenuEl as _i,openReparentedModal as $i,openUserGuideWindow as Gi,makePaletteBtn as Ui,makeLogScaleBtn as Zi,makeLegendStyleBtn as Qi,makeOverlaysBtn as qi,makeOrientationBtn as Ji,menuLayerFor as Jn,saveImageBlob as ei,markMenuTrigger as Qe,wireMenuA11y as ti,wireExpandToggle as eo,nextFrame as Gt,requestedPassFailDisplay as to,overlayMenuRows as no,anyOverlayActive as io,logWmapVersionOnce as oo,buildDataModeEntries as so,metadataKeyHasData as lo,metadataModeEntry as ao}from"./toolbar.js";import{waferIdentityLabel as ro}from"../core/waferLabel.js";import{metadataDisplayValue as co}from"../core/metadata.js";import{withExportContext as fo,noticeDownloadFilenameChange as po}from"./exportName.js";import{createSummaryPanelEl as Ut,wrapWithSummaryPanel as Zt,renderWaferSummaryContentSteps as uo}from"./summaryPanel.js";import{runChunked as ho}from"./chunked.js";import{collectWarnings as go,buildWarningsMenuEl as mo,severityOf as yo}from"./warnings.js";import{ICONS as ni}from"./icons.js";import{hasDrilldownTargets as bo,selectionPopulation as vo,waferPopulation as xo}from"./chartPopulation.js";import{createIdentityHeader as wo,collapsedLabel as Qt}from"./identityHeader.js";import{getDieKey as fe,hasPosition as ii,isPositionedDie as Co}from"../core/dies.js";import{buildDieListSection as So}from"./dieList.js";import{buildMaplessSummary as Mo}from"./maplessSummary.js";import{resolveBinColors as Eo,binColorWarning as Do}from"../renderer/binColors.js";import{INPUT_DEFAULT_PASS_BINS as ko}from"../core/passBins.js";const oi=new Set(["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","legendPosition","logScale","colorbarRangeMode","markFailingDies","fallbackFormat"]);export const COLOR_KEYS=["binColorScheme","valueColorScheme","reverseValueScheme","useDefinedBinColors","binColors"];export function classifyChanged(P){const m=P.some(p=>oi.has(p)),v=P.some(p=>!oi.has(p));return m&&v?"mixed":m?"preference":"state"}export function toPublicViewOptions(P){const{metadataValueOrder:m,binColors:v,lotSize:p,...k}=P;return k}export function renderWaferMap(P,m,v={}){return renderWaferMapCard(P,m,v)}export function renderWaferMapCard(P,m,v={}){oo();const p=P.ownerDocument,k=p.defaultView??window,qt=()=>q.label,Jt=()=>ro({label:qt(),wafer:V}),we=fo(()=>{const e=co(V.metadata?.lot);return{lots:e!==void 0?[e]:[],...q.isLotStack?{stackedWafers:g?.lotSize??!0}:{wafer:Jt()}}},v.onSaveImage,v.onSaveText);po(v.downloadFilename);function en(){const e=g.plotMode==="softBin"||g.plotMode==="stackedSoftBins"?G:$,{primary:t,secondary:n}=Ii(g,c.fallbackFormat,e);return[t,q.isLotStack?"":n].filter(Boolean).join(" ")||"wafer-map"}k.getComputedStyle(P).position==="static"&&(P.style.position="relative");const si=P.clientHeight;v.height!=null&&(P.style.height=typeof v.height=="number"?`${v.height}px`:v.height);const bt=m.dataCoverage?m.dataCoverage.unpositionedDies:m.dies.filter(e=>!ii(e)).length,Oe=(m.dataCoverage?m.dataCoverage.totalDies:m.dies.length-bt)===0&&bt>0,Re=p.createElement("div");Object.assign(Re.style,{display:"flex",flexDirection:"column",width:"100%",height:"100%"}),P.appendChild(Re);const Ce=p.createElement("div");Object.assign(Ce.style,{position:"relative",width:"100%",flex:"1 1 auto",minHeight:"0"});const pe=v.chromeInset??Ni,_=p.createElement("div");Object.assign(_.style,{display:"flex",alignItems:"stretch",gap:A.sm,background:w.canvasBg,paddingBottom:A.lg,paddingTop:pe,paddingLeft:pe,paddingRight:pe,flexShrink:"0",minWidth:"0"}),Re.appendChild(_),Re.appendChild(Ce);function Ie(){const e=[..._.children].some(t=>t.style.display!=="none");_.style.display=e?"flex":"none"}const M=p.createElement("div");Object.assign(M.style,{position:"relative",width:"100%",height:"100%"});const s=p.createElement("canvas");Object.assign(s.style,{width:"100%",height:"100%",display:"block"}),M.appendChild(s),Ce.appendChild(M);let qe=null;if(bt>0){let n=function(){if(t){const d=So(e,m.testDefs,{...v.dieList,onSaveText:we.onSaveText,waferMetadata:V.metadata,metadataFields:ge,ownerDocument:p});if(d)return d}const o=gt(m.testDefs,c.activeTest??0),a=$t(o)?c.logScale??o?.logScale??!1:!1;return Mo(e,m.testDefs,{plotMode:c.plotMode??"hardBin",activeTest:c.activeTest,hbinDefs:$,sbinDefs:G,binColors:g.binColors,valueColorScheme:c.valueColorScheme,reverseValueScheme:c.reverseValueScheme,logScale:a,colorbarRangeMode:c.colorbarRangeMode,valueRangeDies:m.dies})},i=function(o){const a=p.createElement("button");return a.type="button",Un(a),Object.assign(a.style,{fontSize:mt.body,padding:`${A.xxs} ${A.sm}`,borderRadius:Zn.control,flexShrink:"0",border:`1px solid ${w.menuBorder}`,background:w.menuBg,color:w.text,cursor:"pointer"}),a.textContent=t?"View chart":"View die list",a.addEventListener("click",d=>{d.stopPropagation(),t=!t,a.textContent=t?"View chart":"View die list",o()}),a};const e=m.dies.filter(o=>!ii(o));let t=!1;if(Oe){const o=p.createElement("div");Object.assign(o.style,{position:"absolute",inset:"0",background:w.panelBg,padding:A.xl,boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:A.md,zIndex:"1"});const a=p.createElement("div");Object.assign(a.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:A.md});const d=p.createElement("span");Object.assign(d.style,{fontSize:mt.body,color:w.label,lineHeight:Gn.base}),d.textContent="No die position data for this wafer.",a.appendChild(d);const l=p.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),a.appendChild(i(()=>l.replaceChildren(n()))),o.appendChild(a),o.appendChild(l),M.appendChild(o),qe=()=>{t||l.replaceChildren(n())}}else{const o=p.createElement("div");Object.assign(o.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,fontSize:mt.body,color:w.text,cursor:"pointer",padding:`${A.xs} ${A.md}`,display:"flex",alignItems:"center",justifyContent:"space-between",gap:A.md}),Un(o,"bare");const a=p.createElement("span");a.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,o.appendChild(a);const d=p.createElement("span");d.textContent="\u25BE",Object.assign(d.style,{fontSize:mt.body,lineHeight:Gn.none,color:w.label,flexShrink:"0"}),o.appendChild(d),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,r=null;eo(o,f=>{if(d.textContent=f?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(f)),f){l=p.createElement("div");const h=o.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${h}px`,top:"20%",zIndex:"2",background:w.panelBg,borderTop:`1px solid ${w.menuBorder}`,padding:A.md,boxSizing:"border-box",display:"flex",flexDirection:"column",gap:A.md}),l.addEventListener("click",se=>se.stopPropagation());const y=p.createElement("div");Object.assign(y.style,{display:"flex",justifyContent:"flex-end"}),y.appendChild(i(()=>{r&&r.replaceChildren(n())})),l.appendChild(y),r=p.createElement("div"),Object.assign(r.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(n()),l.appendChild(r),M.appendChild(l)}else l&&(l.remove(),l=null,r=null)}),M.appendChild(o),qe=()=>{r&&!t&&r.replaceChildren(n())}}}const{onHover:Je,onClick:li,onSelect:le,onViewOptionsChange:ai,showTooltip:ri=!0,showToolbar:We=!0,showIdentity:tn=!0,summaryPanel:Fe,showHelpButton:nn=!1,userGuideExtension:di,onExpand:on,showExpandButton:sn=!0,zIndex:ci,insights:ue,warnings:ln,viewOptions:fi={},...Se}=v,Ae=ue?.enabled??!1,pi=.4,ui=20,et=[...m.passBins??ko],an=ln?.display??!0,hi=ji(ci);let ae=v.statsSummary,re=[],rn=!1,tt=null,dn=!1;function vt(){const e=go({result:m,statsSummary:ae,extra:tt?[tt]:[]}),t=e.length!==re.length||e.some((n,i)=>n.code!==re[i]?.code||n.message!==re[i]?.message);re=e,(t||!rn)&&(rn=!0,ln?.onWarning?.(e))}vt();let q=m,V=m.wafer,he=m.dies,C=new Set;const gi={sweeps:ue?.sweeps,onSaveImage:we.onSaveImage},xt=()=>!Oe&&bo(U,ue?.sweeps);let cn=null,nt=null,it=!1,fn=!1,$=m.hbinDefs,G=m.sbinDefs,U=m.testDefs,ge=m.metadataFields,pn=m.reticles?.length?m.reticles:void 0,un=m.reticleConfig,hn=m.view?.dataAxisFlip,wt=m.isLotStack??!1,Ct=m.aggrMethod,St=m.lotSize;const mi=We&&Ae;let Y=null,J=null,ee=null;tn&&(Y=wo(Qt(V.metadata??{},He())??"",V.metadata,{lotStack:He(),ownerDocument:p}),M.appendChild(Y.metaPanel),Y.metaPanel.style.visibility="visible",Y.isEmpty()||(J=gn(Y.wrap),_.insertBefore(J,_.firstChild),Ie()));function gn(e){const t=p.createElement("div");return Object.assign(t.style,{display:"flex",alignItems:"center",padding:`${A.sm} ${A.lg}`,flex:"1 1 auto",minWidth:"0",overflow:"hidden",gap:A.sm}),Object.assign(e.style,{flex:"1",minWidth:"0"}),t.appendChild(e),t}function He(){return wt?{lotSize:St??1,aggrMethod:Ct}:void 0}function yi(){if(!Y)return;Y.update(Qt(V.metadata??{},He())??"",V.metadata,He());const e=J?.isConnected??!1,t=!Y.isEmpty();!t&&e?(J.remove(),J=null):t&&!e&&(J=gn(Y.wrap),J.style.display="",_.insertBefore(J,_.firstChild),Ie())}const bi=[...$??[],...G??[]].some(e=>e.color);let c={plotMode:"hardBin",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,rotation:0,flipX:!1,flipY:!1,legendPosition:"default",...fi},X=null,te=!1,mn=null;function vi(){return Ae?X?Promise.resolve(X):(mn??=import("./insightsTab.js").then(({createInsightsTab:e})=>(X=e({getItems:()=>[{wafer:V,dies:he,hbinDefs:$,sbinDefs:G,testDefs:U,label:qt(),passBins:et,statsSummary:ae}],getBinColors:()=>g.binColors,getRingCount:()=>q.ringCount??4,onSaveImage:we.onSaveImage,onSaveText:we.onSaveText,defaultView:ue?.defaultView,sweeps:ue?.sweeps,onRemoveSweeps:ue?.onRemoveSweeps,showMetadataStrip:!1,contentInset:pe,backTab:mi?void 0:{label:"Map",onBack:()=>ze(!1)},onOpenGuide:nn&&!We?()=>Xt():void 0,focusTest:t=>{D({plotMode:"value",activeTest:t,highlightBin:void 0}),ze(!1)},ownerDocument:p}),Object.assign(X.el.style,{position:"absolute",inset:"0",background:w.canvasBg,overflowY:"auto",paddingTop:"0"}),X.el.style.display="none",Ce.appendChild(X.el),X)),mn):Promise.resolve(null)}let yn=0;const Mt=["wheel","touchstart","pointerdown","keydown"];function xi(e,t){if(t<=0)return;let n=!1;const i=[],o=()=>{n=!0;for(const d of i)k.clearTimeout(d);i.length=0;for(const d of Mt)e.removeEventListener(d,o)},a=()=>n||!te?!0:(e.scrollTop=t,e.scrollTop>=t);if(!a()){for(const d of Mt)e.addEventListener(d,o,{passive:!0,once:!0});for(const d of[0,50,150,300,600])i.push(k.setTimeout(()=>{a()},d));i.push(k.setTimeout(()=>{for(const d of Mt)e.removeEventListener(d,o)},700))}}function ze(e){if(!Ae)return;const t=te;te=e,X&&!e&&t&&(yn=X.el.scrollTop),X&&(X.el.style.display=e?"flex":"none"),M.style.visibility=e?"hidden":"",F&&(F.style.display=e||Oe?"none":"flex"),T&&(T.style.display=e?"none":"flex"),ee&&(ee.style.display=ve?"none":"flex"),ie&&(ie.style.display="flex"),J&&(J.style.display=""),Ie(),Y&&e&&Y.collapse(),rt(),H&&(H.innerHTML=e?ni.wafer:ni.analysis,H.ariaLabel=e?"Back to wafer view":"Insights"),e&&vi().then(n=>{!n||!te||(n.el.style.display="flex",n.render(),xi(n.el,yn))})}Ae&&ue?.defaultOpen&&queueMicrotask(()=>ze(!0));let g,bn,N=null,B=null,Et=[],Dt;function vn(e){Dt!==e&&(Dt=e,x())}let me=null,kt=Se.legendOffset??{x:0,y:0},Ve=!1,Me=!1,Ye={x:0,y:0},Bt={x:0,y:0},ye=!1,Ee=!1,j="pan",De={x:0,y:0},ot={x:0,y:0},O={x:0,y:0},R={x:0,y:0},Xe=!1,ke=!1;function Lt(){const e=c;g=Oi(V,he.filter(Co),{plotMode:e.plotMode,binColorScheme:e.binColorScheme,valueColorScheme:e.valueColorScheme,reverseValueScheme:e.reverseValueScheme,useDefinedBinColors:e.useDefinedBinColors,binColors:e.binColors??Eo(he,{passBins:et,binColorScheme:e.binColorScheme,hbinDefs:$,sbinDefs:G,useDefinedBinColors:e.useDefinedBinColors}),passBins:et,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:pn,ringCount:q.ringCount??4,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:U,valueRange:e.valueRange,metadataValueOrder:e.metadataValueOrder,logScale:e.logScale,isLotStack:wt,aggregationMethod:Ct??e.aggregationMethod,lotSize:St??e.lotSize,dataAxisFlip:hn,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:e.fallbackFormat,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:ge}),bn=new Map(g.dies.map((n,i)=>[fe(n),i]));const t=e.binColors?null:Do(g.binColors,g.plotMode);t?.message!==tt?.message&&(tt=t,vt(),dn&&Tt())}Lt();let Z=null,Be=null,st=null,xn=v.findingsNotice,wi={},I=null,de=null;function Ci(e){const{kind:t,index:n}=e.variable;D(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const i=e.highlight;i.kind==="bin"?(Ft(i.dieKeys),D({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&Ft(i.dieKeys)}const Ne=new Map;function wn(e){Ne.get(e)?.cancel(),Ne.delete(e);const t=ho(uo(e,{wafer:V,dies:he,yieldSummary:q.yield,dataCoverage:q.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:U,statsSummary:ae,warnings:an?re:[],passBins:et,ringCount:q.ringCount??4,binColors:g.binColors,plotMode:c.plotMode??"hardBin",metadataShownElsewhere:tn,fallbackFormat:c.fallbackFormat,activeFindingId:st,findingsFilter:wi,findingsNotice:xn,onFindingsFilterChange:be,onSaveText:we.onSaveText,metadataFields:ge,dieListOptions:v.dieList,onFindingClick:(n,i)=>{st===n.id?(st=null,Ft([]),D({highlightBin:void 0})):(st=n.id,Ci(n)),be()}}));t.done||Ne.set(e,t)}function be(){Z&&wn(Z)}function je(){I&&wn(I)}if(Fe?.placement){const e=Fe.placement;Z=Ut(e,pe,p);const t=M.parentElement,n=M.nextSibling;Be=Zt(M,Z,e),t?.insertBefore(Be,n),be()}else if(ae){const e=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=e?"block":"none";const t=M.parentElement,n=M.nextSibling;de=Zt(M,I,"right"),t?.insertBefore(de,n),je()}const W=ri?Qn(p):null;let ie=null,L=null,F=null,T=null,lt=null,K=null,Cn=null,H=null,oe=null,at=null;dn=!0;function Tt(){if(!oe||!at)return;const e=re.length,t=e>0;if(oe.style.display=t?"flex":"none",at.style.display=t?"":"none",!t)return;const n=yo(re[0]),i=`${e} data ${e===1?"warning":"warnings"}`;oe.style.color=n==="error"?w.errText:w.warnText,oe.ariaLabel=n==="error"?`${i} \u2014 the map may be positionally wrong`:i}let Pt=null,Sn=null,Ot=null,Rt=null,It=null,Wt=null;function Ft(e){C=new Set(e??[]),le&&le(Ke()),x()}function rt(){if(!K)return;const e=!!(Z??I);K.style.display=ae&&e&&!te?"flex":"none";const t=Z??I,n=t?t.style.display!=="none":!1;ae?.hasNotableFindings&&!n?K.style.color=w.findingIndicator:K.dataset.active||(K.style.color=w.icon)}let Mn=null;function En(e){const t=Z??I;t&&(t.style.display=e?"block":"none",K&&Mn?.(K,e),rt())}if(We){let h=function(b){j=b,i(se,b==="zoom"),i(E,b==="pan"),lt&&i(lt,b==="select"),s.style.cursor=b==="pan"?"grab":"crosshair"};ie=p.createElement("div"),ie.dataset.wmapToolbar="single",Object.assign(ie.style,{marginLeft:"auto",flexShrink:"0",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"100%",background:w.menuBg,border:`1px solid ${w.menuBorder}`,borderRadius:Zn.control,boxShadow:Xi.panel,pointerEvents:"auto"});const e=Qn(p),t=Ki(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:a,makeMenuSection:d,closeOpenMenu:l,getOpenMenu:r,setOpenMenu:f}=t;Mn=i,Pt=l,Sn=r,p.addEventListener("click",l,!0),F=p.createElement("div"),Object.assign(F.style,{display:Oe?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(F);const y=n("download","Download PNG",Ei);F.appendChild(y),F.appendChild(o());const se=n("zoomMode","Zoom (drag to zoom region)",()=>h("zoom")),Te=n("zoomIn","Zoom in",()=>Le(s.clientWidth/2,s.clientHeight/2,1.2)),ne=n("zoomOut","Zoom out",()=>Le(s.clientWidth/2,s.clientHeight/2,1/1.2)),ce=n("reset","Reset zoom (double-click)",()=>ct());F.appendChild(se),F.appendChild(Te),F.appendChild(ne),F.appendChild(ce),F.appendChild(o());const E=n("pan","Pan (drag to move)",()=>h("pan"));F.appendChild(E),lt=n("boxSelect","Select (drag to select dies)",()=>h("select")),F.appendChild(lt);{const b=n("drilldown","Chart this wafer",()=>{const Pe=b.getBoundingClientRect();In({x:Pe.left,y:Pe.bottom+4},b)});b.setAttribute("aria-haspopup","menu"),nt=b,Rn(),F.appendChild(b)}i(E,!0);{let b=function(u){return u.plotMode!==(c.plotMode??"hardBin")?!1:u.plotMode==="value"?(c.activeTest??0)===(u.activeTest??0):u.plotMode==="metadata"?c.activeMetadataKey===u.activeMetadataKey:!0},Pe=function(u,S){u.activeTest!==void 0?D({plotMode:u.plotMode,activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):D({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),S.remove(),f(null),Qe(Q,!1)};L=p.createElement("div"),Object.assign(L.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),ie.appendChild(L),T=p.createElement("div"),Object.assign(T.style,{display:"flex",alignItems:"center",gap:"0"}),L.appendChild(T),T.appendChild(o());const ft=()=>{const u=r();u&&(u.remove(),f(null)),Qe(Q,!1)},Q=n("mode","Plot mode",()=>{if(r()){ft();return}const u=he,S=g.testDefs,{testEntries:ht,binEntries:xe,stackedEntries:Ge}=so(u,S,{includeStacked:g.isLotStack}),Kt=(ge??[]).filter(Ze=>lo(u,Ze.key)).map(ao),Ue=_i(Q.getBoundingClientRect(),ht,xe,Ge,b,Pe,{makeMenuRow:a,makeMenuSection:d},c.plotMode??"hardBin",Q.ownerDocument.defaultView??window,Kt);Jn(Q).appendChild(Ue),f(Ue),Qe(Q,!0),ti(Ue,Q,ft)});Qe(Q,!1);const{btn:pt,sync:$e}=Ui(t,()=>({...c,plotMode:c.plotMode??"hardBin"}),()=>bi,D);Rt=$e,Rt();const Nt=qi(t,()=>{const u=!!g.hasReticle,S=(c.plotMode??"hardBin")==="value",{testNumber:ht}=_t(c.activeTest??0,g.testDefs),xe=gt(g.testDefs,ht),Ge=S&&xe!==void 0&&!$t(xe),Kt=S&&!Ge&&(xe?.limitLow!==void 0||xe?.limitHigh!==void 0),Ue=S&&!Ge&&g.dies.some(Ze=>Vi(Ze,ht,xe)!==void 0);return no(c,u,{functionalActive:Ge,hasLimits:Kt,hasRecorded:Ue,binMode:(c.plotMode??"hardBin")==="hardBin"||(c.plotMode??"hardBin")==="softBin"},Ze=>D(Ze))},()=>io(c)),{btn:jt,sync:ki}=Qi(t,()=>c,u=>D({legendPosition:u}));Ot=ki,Ot();const _n=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&!$t(S)},{btn:Bi,sync:Li}=Zi(t,()=>({...c,functionalActive:_n()}),u=>D(u));It=Li,It();const Ti=()=>{const{testNumber:u}=_t(c.activeTest??0,U),S=gt(U,u);return S!==void 0&&(S.limitLow!==void 0||S.limitHigh!==void 0)},ut=n("specRange","Colorbar range: test limits",()=>{const u=c.colorbarRangeMode==="data"?"spec":"data";D({colorbarRangeMode:u})});Wt=()=>{const u=c.plotMode==="value"&&Ti()&&to(c)==="off"&&!_n();ut.style.display=u?"":"none";const S=(c.colorbarRangeMode??"spec")==="spec";i(ut,S),ut.ariaLabel=S?"Colorbar range: test limits (click for data range)":"Colorbar range: data range (click for test limits)"},Wt();const Pi=Ji(t,()=>c,u=>D(u));T.appendChild(Q),T.appendChild(pt),T.appendChild(Bi),T.appendChild(ut),Oe||(T.appendChild(o()),T.appendChild(Nt),T.appendChild(o()),T.appendChild(jt),T.appendChild(o()),T.appendChild(Pi)),ae&&(K=n("findings","Summary panel",()=>{const u=Z??I;u&&En(u.style.display==="none")}),L.appendChild(o()),L.appendChild(K),I?.style.display!=="none"&&i(K,!0),rt()),an&&(at=o(),oe=n("warning","Data warnings",()=>{const u=r();if(l(new MouseEvent("click")),u)return;const S=mo(oe.getBoundingClientRect(),re,k);Jn(Ce).appendChild(S),f(S),ti(S,oe,()=>l(new MouseEvent("click")))}),Qe(oe,!1),L.appendChild(at),L.appendChild(oe),Tt()),Ae&&(L.appendChild(o()),H=n("analysis","Insights",()=>{ze(!te),i(H,te)}),H.dataset.wmapInsightsBtn="1",L.appendChild(H)),sn&&(L.appendChild(o()),ee=n("expand","Expand (E)",on??Dn),L.appendChild(ee)),nn&&(L.appendChild(o()),Cn=n("help","User guide",()=>Xt()),L.appendChild(Cn))}_.appendChild(ie),Ie()}let ve=null;function Dn(){ve&&(ve.close(),ve=null);const e=Ce;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=Qt(V.metadata??{},He()),n=_.childElementCount>0?[_,e]:[e],i=$i(n,{ownerDocument:p,boxSize:te?{width:"min(96vw, 1600px)",height:"min(92vh, 1000px)"}:void 0,onClosed:()=>{ve=null,ee&&(ee.style.display="flex"),te||s.focus({preventScroll:!0})}});i&&(i.box.setAttribute("aria-label",t??"Expanded wafer map"),n.length>1&&(i.contentWrap.style.flexDirection="column"),ve=i,ee&&(ee.style.display="none"))}function kn(e){("binColorScheme"in e||"useDefinedBinColors"in e)&&!("binColors"in e)&&c.binColors!==void 0&&(e={...e,binColors:void 0});const t=c.plotMode;c={...c,...e},e.plotMode!==void 0&&e.plotMode,Object.keys(e).every(a=>a==="legendPosition"||a==="showLegend"||a==="markFailingDies")||Lt(),Ot?.(),Rt?.(),It?.(),Wt?.(),x();const i=e.plotMode!==void 0&&e.plotMode!==t,o=COLOR_KEYS.some(a=>a in e);(o||i)&&(be(),je()),(o||i||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&qe?.()}function D(e){kn(e);const t=Object.keys(e);ai?.(c,t,classifyChanged(t))}let At=!1;function Ht(){At||(At=!0,Gt(()=>{At=!1,x()},k))}function x(){const e=B??void 0,t=g.dies[0],n=t?{x:t.width,y:t.height}:Se.diePitchMm,i=Math.floor(s.clientWidth||s.width),o=!!($?.length||G?.length||g.dies.some(y=>y.hbin!=null||y.sbin!=null)),a=c.legendPosition??"default",d=c.showLegend??!0,l=a==="default"||a==="compact",r=(Se.colorbarWidth??16)+28,f=o&&l?a!=="default"?Math.max($n,r):i<Hi?0:i<Ai?Math.max(Fi,r):Math.max($n,r):void 0,h=Wi(s,g,{...Se,minRightReserve:d?f:0,showColorbar:d&&(Se.showColorbar??!0),markFailingDies:c.markFailingDies??!1,legendPosition:a,legendOffset:kt,diePitchMm:n,fallbackFormat:c.fallbackFormat,showAxes:Se.showAxes??B!==null,viewport:e,activeBin:c.plotMode==="metadata"?c.highlightMetadataValue:c.highlightBin,hoverBin:Dt,hbinDefs:$,sbinDefs:G,metadataFields:ge});Et=h.binLegendRows,me=h.legendBox??null,B===null&&(N=h.viewport),C.size>0&&Si(),Ee&&Mi(),Rn()}function Si(){const e=z();if(!e)return;const t=s.getContext("2d"),n=g.hoverPoints,i=g.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,a=i?i.height/2*e.ppm:e.ppm*.5,d=Math.max(1,Math.min(3,o*.08)),l=o-d,r=a-d,f=[];for(const h of C){const y=bn.get(h);y!==void 0&&f.push({sx:e.originX+n[y].x*e.ppm,sy:e.originY-n[y].y*e.ppm})}if(f.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:h,sy:y}of f)t.rect(h-l,y-r,l*2,r*2);t.stroke(),t.restore()}}function Mi(){const e=s.getContext("2d"),t=Math.min(O.x,R.x),n=Math.min(O.y,R.y),i=Math.abs(R.x-O.x),o=Math.abs(R.y-O.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,i,o),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,i,o),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,i,o),e.restore()}function Ei(){s.toBlob(e=>{e&&(v.downloadFilename!=null?ei(e,v.downloadFilename,v.onSaveImage):ei(e,en(),we.onSaveImage))})}function Bn(e){return N?Math.max(N.ppm*pi,Math.min(N.ppm*ui,e)):e}function Le(e,t,n){const i=B??N;if(!i)return;const o=Bn(i.ppm*n),a=o/i.ppm,d=e-(e-i.originX)*a,l=t-(t-i.originY)*a,r=(N?.snapDist??1)/(o/(N?.ppm??o));B={originX:d,originY:l,ppm:o,snapDist:r},x()}function z(){return B??N}function Ln(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=s.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Le(e.clientX-t.left,e.clientY-t.top,n)}else if(B!==null){e.preventDefault();const t=z(),n=B.snapDist;B={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},x()}}function zt(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function Tn(e){if(it=!1,e.button!==0||!z())return;s.focus({preventScroll:!0}),s.setPointerCapture(e.pointerId);const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(me&&c.legendPosition==="floating"&&zt(n,i,me)){Me=!0,Ye={x:n,y:i},Bt={...kt};return}if(Xe&&j!=="pan"){ke=!0,ye=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing";return}if(j==="zoom"||j==="select"){Ee=!0,O=R={x:n,y:i};return}ye=!0,De={x:n,y:i},ot={x:z().originX,y:z().originY},s.style.cursor="grabbing"}function Pn(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Ee){R={x:n,y:i},Ht();return}if(Me){const h=n-Ye.x,y=i-Ye.y;h*h+y*y>16&&(Me=!1,Ve=!0,s.style.cursor="grabbing")}if(Ve){kt={x:Bt.x+(n-Ye.x),y:Bt.y+(i-Ye.y)},Ht();return}if(ye){const h=z(),y=B?.snapDist??N?.snapDist??1;B={originX:ot.x+(n-De.x),originY:ot.y+(i-De.y),ppm:h.ppm,snapDist:y},Ht();return}const o=z();if(!o)return;const a=(n-o.originX)/o.ppm,d=(o.originY-i)/o.ppm,r=Yt(a,d,o.snapDist)?.die??null,f=Et.find(h=>n>=h.x&&n<h.x+h.w&&i>=h.y&&i<h.y+h.h);if(vn(f?f.bin:void 0),f){s.style.cursor="pointer",W&&(W.textContent=f.label??`Bin ${f.bin}`,W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})),Je?.(null,e);return}j==="pan"&&(s.style.cursor=r?"crosshair":"grab"),W&&(r?(W.innerHTML=Ri(r,g.plotMode,{testDefs:U,hbinDefs:$,sbinDefs:G,fallbackFormat:c.fallbackFormat,aggrMethod:g.aggrMethod,lotSize:g.lotSize,metadataFields:ge,activeTest:g.activeTest,reticleConfig:un}),W.style.display="block",qn(W,s,e.clientX,e.clientY,{followPointer:!0})):W.style.display="none"),Je?.(r,e)}function On(e){const t=s.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(W&&(n<0||i<0||n>t.width||i>t.height)&&(W.style.display="none"),Ee){Ee=!1,R={x:n,y:i};const l=n-O.x,r=i-O.y,f=z();if(j==="zoom"){if(l*l+r*r<25)Le(n,i,2);else if(f){const h=Math.min(O.x,R.x),y=Math.max(O.x,R.x),se=Math.min(O.y,R.y),Te=Math.max(O.y,R.y),ne=y-h,ce=Te-se;if(ne>4&&ce>4){const E=s.clientWidth,b=s.clientHeight,Pe=E/ne,ft=b/ce,Q=Math.min(Pe,ft),pt=Bn(f.ppm*Q),$e=pt/f.ppm,Nt=(h+y)/2,jt=(se+Te)/2;B={originX:E/2-(Nt-f.originX)*$e,originY:b/2-(jt-f.originY)*$e,ppm:pt,snapDist:f.snapDist/$e}}}x(),s.style.cursor="crosshair";return}if(l*l+r*r<25)Vt(n,i,o,e);else if(f){const h=(Math.min(O.x,R.x)-f.originX)/f.ppm,y=(Math.max(O.x,R.x)-f.originX)/f.ppm,se=(f.originY-Math.max(O.y,R.y))/f.ppm,Te=(f.originY-Math.min(O.y,R.y))/f.ppm,ne=g.hoverPoints,ce=[];for(let E=0;E<ne.length;E++)if(ne[E].x>=h&&ne[E].x<=y&&ne[E].y>=se&&ne[E].y<=Te){const b=g.dies[E];b&&ce.push(b)}if(o)for(const E of ce){const b=fe(E);C.has(b)?C.delete(b):C.add(b)}else C=new Set(ce.map(E=>fe(E)));le?.(Ke())}x(),s.style.cursor="crosshair";return}if(Me){Me=!1,Vt(n,i,o,e);return}if(Ve){Ve=!1,s.style.cursor="grab";return}if(!ye)return;if(ye=!1,ke){ke=!1,s.style.cursor=Xe||j==="pan"?"grab":"crosshair";return}s.style.cursor=j==="pan"?"grab":"crosshair";const a=n-De.x,d=i-De.y;a*a+d*d<25&&Vt(n,i,o,e)}function Vt(e,t,n,i){for(const l of Et)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const r=c.highlightBin===l.bin?void 0:l.bin;D({highlightBin:r})}else{const r=c.highlightMetadataValue===l.bin?void 0:l.bin;D({highlightMetadataValue:r})}return}if(me&&zt(e,t,me))return;const o=z();if(!o)return;const d=Yt((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(d){li?.(d,i);const l=fe(d);n?C.has(l)?C.delete(l):C.add(l):C=new Set([l]),le?.(Ke()),x()}else n||(C=new Set,le?.([]),x())}function Ke(){const e=[],t=g.hoverPoints;for(let n=0;n<t.length;n++){const i=g.dies[n];i&&C.has(fe(i))&&e.push(i)}return e}function Rn(){nt&&(nt.style.display=xt()?"flex":"none",nt.ariaLabel=C.size>0?"Chart the selected dies (or right-click)":"Chart this wafer (or right-click)")}function Di(){const e={waferLabel:Jt(),testDefs:U,isLotStack:q.isLotStack,activeTest:c.plotMode==="value"?c.activeTest:void 0};return C.size>0?vo(Ke(),e):xo(he,e)}function In(e,t){if(!xt())return;const n=Di();import("./drilldown.js").then(({openDrilldownMenu:i})=>{fn||(cn=i(e,t,n,gi))})}function Wn(e){e.stopPropagation();const t=it;if(it=!1,!xt()||te)return;const n=s.getBoundingClientRect();if(!t){const o=e.clientX-n.left,a=e.clientY-n.top;if(me&&zt(o,a,me))return;const d=z(),l=d?Yt((o-d.originX)/d.ppm,(d.originY-a)/d.ppm,d.snapDist)?.die:void 0;l&&!C.has(fe(l))&&(C=new Set([fe(l)]),le?.(Ke()),x())}e.preventDefault();const i=t?{x:n.left+n.width/2,y:n.top+n.height/2}:{x:e.clientX,y:e.clientY};In(i,s)}function Fn(){vn(void 0),W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair"}function An(){ye=!1,ke=!1,Ee=!1,Me=!1,Ve=!1,W&&yt(p),Je?.(null,new MouseEvent("mouseleave")),s.style.cursor=j==="pan"?"grab":"crosshair",x()}function Yt(e,t,n){const i=g.hoverPoints,o=g.rectangles;for(let r=0;r<o.length;r++){const f=o[r];if(Math.abs(e-f.x)<=f.width/2&&Math.abs(t-f.y)<=f.height/2){const h=g.dies[r];return h?{die:h,index:r}:null}}let a=null,d=-1,l=n*n;for(let r=0;r<i.length;r++){const f=i[r].x-e,h=i[r].y-t,y=f*f+h*h;y<l&&(l=y,a=g.dies[r]??null,d=r)}return a?{die:a,index:d}:null}const Hn=new k.ResizeObserver(()=>{N=null,B=null,x()});Hn.observe(s),v.height==null&&si<=0&&Gt(()=>Gt(()=>{P.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let _e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`);const dt=()=>{_e.removeEventListener("change",dt),_e=k.matchMedia(`(resolution: ${k.devicePixelRatio}dppx)`),_e.addEventListener("change",dt),x()};_e.addEventListener("change",dt);const zn=k.matchMedia("(prefers-color-scheme: dark)"),Vn=()=>x();zn.addEventListener("change",Vn);const Yn=()=>{W&&yt(p)};k.addEventListener("blur",Yn);function Xn(e){if((e.key==="ContextMenu"||e.shiftKey&&e.key==="F10")&&(it=!0),e.key==="Escape"&&C.size>0&&(C=new Set,le?.([]),x()),(e.key==="e"||e.key==="E")&&sn&&(e.stopPropagation(),(on??Dn)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Le(s.clientWidth/2,s.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),ct())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=z();if(n){const i=B?.snapDist??N?.snapDist??1;let o=0,a=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(a=20,e.preventDefault()),e.key==="ArrowDown"&&(a=-20,e.preventDefault()),(o||a)&&(B={originX:n.originX+o,originY:n.originY+a,ppm:n.ppm,snapDist:i},x())}e.key===" "&&!Xe&&(e.preventDefault(),Xe=!0,j!=="pan"&&(s.style.cursor="grab"))}}function Nn(e){e.key===" "&&(Xe=!1,ke&&(ye=!1,ke=!1),s.style.cursor=j==="pan"?"grab":"crosshair")}s.style.cursor="grab",s.setAttribute("tabindex","0"),s.addEventListener("wheel",Ln,{passive:!1}),s.addEventListener("pointerdown",Tn),s.addEventListener("pointermove",Pn),s.addEventListener("pointerup",On),s.addEventListener("pointerleave",Fn),s.addEventListener("pointercancel",An);const jn=()=>ct();s.addEventListener("dblclick",jn),s.addEventListener("keydown",Xn),s.addEventListener("keyup",Nn),s.addEventListener("contextmenu",Wn);const Kn=e=>{e.stopPropagation()};s.addEventListener("click",Kn),s.clientWidth,x(),qe?.();function ct(){N=null,B=null,x()}function Xt(){import("./userGuideHtml.js").then(e=>Gi({buildWaferMap:zi,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:Yi},e.USER_GUIDE_HTML,di,P))}return Ie(),{setResult(e){q=e,V=e.wafer,he=e.dies,$=e.hbinDefs,G=e.sbinDefs,U=e.testDefs,ge=e.metadataFields,pn=e.reticles?.length?e.reticles:void 0,un=e.reticleConfig,hn=e.view?.dataAxisFlip,wt=e.isLotStack,Ct=e.aggrMethod,St=e.lotSize,yi(),Lt(),x(),Z&&be()},setOptions(e){kn(e)},getOptions(){return{...c}},resetZoom:ct,setSelection(e){C=new Set(e.map(t=>fe(t))),x()},clearSelection(){C=new Set,le?.([]),x()},setFindingsNotice(e){xn=e,Z?be():I&&je()},setStatsSummary(e){if(ae=e,vt(),Tt(),Z)be();else if(I)je();else if(e&&!Fe?.placement){const t=Fe?.defaultOpen??!We;I=Ut("right",pe,p),I.style.display=t?"block":"none";const n=M.parentElement,i=M.nextSibling;de=Zt(M,I,"right"),n?.insertBefore(de,i),je()}rt()},closeSummaryPanel(){En(!1)},getExportTitle(){return en()},getBinColors(){return g.binColors},setSummaryVisible(e){K&&(K.style.display=e?"flex":"none")},setViewControlsVisible(e){L&&(L.style.display=e?"flex":"none")},setExpandVisible(e){ee&&(ee.style.display=e?"flex":"none")},openUserGuide:Xt,setInsightsOpen(e){ze(e),H&&(e?(H.dataset.active="1",H.style.background=w.bgActive,H.style.color=w.iconActive):(delete H.dataset.active,H.style.background="transparent",H.style.color=w.icon))},destroy(){fn=!0;for(const e of Ne.values())e.cancel();Ne.clear(),ve?.close(),Sn?.()?.remove(),Pt&&p.removeEventListener("click",Pt,!0),s.removeEventListener("wheel",Ln),s.removeEventListener("pointerdown",Tn),s.removeEventListener("pointermove",Pn),s.removeEventListener("pointerup",On),s.removeEventListener("pointerleave",Fn),s.removeEventListener("pointercancel",An),s.removeEventListener("dblclick",jn),s.removeEventListener("keydown",Xn),s.removeEventListener("keyup",Nn),s.removeEventListener("contextmenu",Wn),cn?.(),s.removeEventListener("click",Kn),Hn.disconnect(),_e.removeEventListener("change",dt),zn.removeEventListener("change",Vn),k.removeEventListener("blur",Yn),hi(),W&&yt(p),ie?.remove(),Be&&(Be.parentElement?.insertBefore(M,Be),Be.remove()),de&&(de.parentElement?.insertBefore(M,de),de.remove()),M.remove(),s.style.cursor="",X?.destroy(),Y?.destroy(),Re.remove()}}}