@wafertools/wafermap 0.21.1 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +181 -0
- package/CHANGELOG.md +261 -1
- package/README.md +9 -1
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/dieList.d.ts +41 -0
- package/dist/packages/canvas-adapter/dieList.js +2 -0
- package/dist/packages/canvas-adapter/icons.js +1 -1
- package/dist/packages/canvas-adapter/index.d.ts +4 -0
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.d.ts +34 -0
- package/dist/packages/canvas-adapter/maplessSummary.js +1 -0
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +9 -11
- package/dist/packages/canvas-adapter/renderWaferGallery.js +8 -8
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +31 -1
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +13 -1
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toolbar.d.ts +4 -1
- package/dist/packages/canvas-adapter/toolbar.js +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +59 -22
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.d.ts +57 -0
- package/dist/packages/canvas-adapter/warnings.js +1 -0
- package/dist/packages/core/classify.d.ts +6 -2
- package/dist/packages/core/dies.d.ts +67 -7
- package/dist/packages/core/dies.js +1 -1
- package/dist/packages/core/probe.d.ts +5 -0
- package/dist/packages/core/probe.js +1 -1
- package/dist/packages/core/transforms.d.ts +4 -4
- package/dist/packages/core/transforms.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +3 -3
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +40 -9
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/index.d.ts +1 -1
- package/dist/packages/renderer/index.js +1 -1
- package/dist/packages/stats/analyzeWaferLot.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/clusterDetection.d.ts +2 -2
- package/dist/packages/stats/patternClassification.d.ts +2 -2
- package/dist/packages/stats/regions.d.ts +6 -6
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderFindingsReport.js +15 -15
- package/dist/packages/stats/renderSummaryReport.js +17 -17
- package/dist/packages/stats/types.d.ts +34 -4
- package/llms.txt +39 -0
- package/package.json +12 -8
|
@@ -39,4 +39,4 @@ export const ICONS={aggr:'<svg viewBox="0 0 24 24" width="16" height="16" fill="
|
|
|
39
39
|
<path d="M4.2 12h15.6"/>
|
|
40
40
|
<path d="M5.8 16h12.4"/>
|
|
41
41
|
|
|
42
|
-
</svg>`,windowMinimize:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 19h14"/></svg>',windowRestore:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="5" width="16" height="14" rx="1.5"/></svg>',xyIndicator:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 19 L5 7"/><path d="M5 7 L3 10"/><path d="M5 7 L7 10"/><path d="M5 19 L17 19"/><path d="M17 19 L14 17"/><path d="M17 19 L14 21"/><text x="18" y="8" font-size="6" fill="currentColor" stroke="none">X</text><text x="2" y="6" font-size="6" fill="currentColor" stroke="none">Y</text></svg>',zoomIn:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="11" x2="11" y1="8" y2="14"/><line x1="8" x2="14" y1="11" y2="11"/></svg>',zoomMode:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m13 13.5 2-2.5-2-2.5"/><path d="m21 21-4.3-4.3"/><path d="M9 8.5 7 11l2 2.5"/><circle cx="11" cy="11" r="8"/></svg>',zoomOut:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="8" x2="14" y1="11" y2="11"/></svg>'};
|
|
42
|
+
</svg>`,warning:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>',windowMinimize:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 19h14"/></svg>',windowRestore:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="5" width="16" height="14" rx="1.5"/></svg>',xyIndicator:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M5 19 L5 7"/><path d="M5 7 L3 10"/><path d="M5 7 L7 10"/><path d="M5 19 L17 19"/><path d="M17 19 L14 17"/><path d="M17 19 L14 21"/><text x="18" y="8" font-size="6" fill="currentColor" stroke="none">X</text><text x="2" y="6" font-size="6" fill="currentColor" stroke="none">Y</text></svg>',zoomIn:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="11" x2="11" y1="8" y2="14"/><line x1="8" x2="14" y1="11" y2="11"/></svg>',zoomMode:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="m13 13.5 2-2.5-2-2.5"/><path d="m21 21-4.3-4.3"/><path d="M9 8.5 7 11l2 2.5"/><circle cx="11" cy="11" r="8"/></svg>',zoomOut:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="8" x2="14" y1="11" y2="11"/></svg>'};
|
|
@@ -5,6 +5,10 @@ export type { RenderOptions, WaferMapController, WaferViewOptions, WaferPreferen
|
|
|
5
5
|
export { renderWaferGallery } from './renderWaferGallery.js';
|
|
6
6
|
export type { WaferMapDisplayItem, WaferMapDisplayItemFactory, GalleryOptions, GalleryController } from './renderWaferGallery.js';
|
|
7
7
|
export type { SummaryPanelOptions } from './summaryPanel.js';
|
|
8
|
+
export { buildDieListSection } from './dieList.js';
|
|
9
|
+
export type { DieListOptions } from './dieList.js';
|
|
10
|
+
export { collectWarnings, severityOf } from './warnings.js';
|
|
11
|
+
export type { WarningsOptions } from './warnings.js';
|
|
8
12
|
export type { InsightsOptions, InsightsView } from './insightsTab.js';
|
|
9
13
|
export { setDetachWindowOpener } from './toolbar.js';
|
|
10
14
|
export type { DetachWindowOpener } from './toolbar.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{toCanvas}from"./toCanvas.js";export{renderWaferMap}from"./renderWaferMap.js";export{renderWaferGallery}from"./renderWaferGallery.js";export{setDetachWindowOpener}from"./toolbar.js";
|
|
1
|
+
export{toCanvas}from"./toCanvas.js";export{renderWaferMap}from"./renderWaferMap.js";export{renderWaferGallery}from"./renderWaferGallery.js";export{buildDieListSection}from"./dieList.js";export{collectWarnings,severityOf}from"./warnings.js";export{setDetachWindowOpener}from"./toolbar.js";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Die } from '../core/dies.js';
|
|
2
|
+
import type { TestDef, BinDef } from '../renderer/buildWaferMap.js';
|
|
3
|
+
import type { PlotMode } from '../renderer/buildView.js';
|
|
4
|
+
export interface MaplessSummaryOptions {
|
|
5
|
+
plotMode: PlotMode;
|
|
6
|
+
activeTest?: number;
|
|
7
|
+
hbinDefs?: BinDef[];
|
|
8
|
+
sbinDefs?: BinDef[];
|
|
9
|
+
colorScheme?: string;
|
|
10
|
+
/** Effective log-scale setting for the active test — same resolution the
|
|
11
|
+
* map itself uses (explicit viewOpts.logScale, falling back to the
|
|
12
|
+
* TestDef's own default). */
|
|
13
|
+
logScale?: boolean;
|
|
14
|
+
/** 'spec' colours the full spec-limit window (like the map's colorbar
|
|
15
|
+
* range toggle); 'data' colours just the observed value range. Default 'spec'. */
|
|
16
|
+
colorbarRangeMode?: 'data' | 'spec';
|
|
17
|
+
/**
|
|
18
|
+
* Full wafer/lot die population for this test (positioned + unpositioned),
|
|
19
|
+
* used only to compute the value→colour range — NOT what gets bucketed
|
|
20
|
+
* into bars, which always stays scoped to `dies` (the caller's own
|
|
21
|
+
* argument, below). Falls back to `dies` when omitted. Passing the full
|
|
22
|
+
* population (e.g. a mixed wafer's footer passing every die, not just the
|
|
23
|
+
* unpositioned subset it's charting) keeps bar colours consistent with
|
|
24
|
+
* whatever range the wafer's own visible map is using for the same test.
|
|
25
|
+
*/
|
|
26
|
+
valueRangeDies?: Die[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Compact, plot-mode-aware summary for dies with no position data. Always
|
|
30
|
+
* returns a mountable element — an unhandled mode/empty data still renders a
|
|
31
|
+
* one-line message rather than leaving the caller with nothing to show.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildMaplessSummary(dies: Die[], testDefs: TestDef[] | undefined, options: MaplessSummaryOptions): HTMLElement;
|
|
34
|
+
//# sourceMappingURL=maplessSummary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getDieTestValue as R}from"../renderer/buildWaferMap.js";import{resolveTestNumber as T,findTestDef as $}from"../renderer/buildView.js";import{buildBinSection as y}from"./summaryPanel.js";import{buildTestHistogramData as B}from"../stats/histogram.js";import{getColorScheme as z}from"../renderer/colorSchemes.js";import{CLR as u,getTooltip as E,positionTooltip as H,hideTooltip as V}from"./toolbar.js";import{fmt as b}from"../renderer/fmt.js";function c(i,n,e){const t=document.createElement(i);return n&&Object.assign(t.style,n),e!==void 0&&(t.textContent=e),t}function F(i,n){i.tabIndex=0,i.setAttribute("role","img"),i.setAttribute("aria-label",n);const e=m=>{const l=E(i.ownerDocument);if(l.textContent=n,l.style.display="block",m)H(l,i,m.clientX,m.clientY);else{const r=i.getBoundingClientRect();H(l,i,r.left+r.width/2,r.top)}},t=()=>V(i.ownerDocument);i.addEventListener("mousemove",e),i.addEventListener("mouseleave",t),i.addEventListener("focus",()=>e()),i.addEventListener("blur",t)}function I(i,n,e,t,m){let l=1/0,r=-1/0;for(const p of i){const a=R(p,n);a!==void 0&&(a<l&&(l=a),a>r&&(r=a))}const f=t==="spec"&&e&&(e.limitLow!==void 0||e.limitHigh!==void 0);let s,d;f?(s=e.limitLow!==void 0?e.limitLow:isFinite(l)?l:0,d=e.limitHigh!==void 0?e.limitHigh:isFinite(r)?r:1):(s=isFinite(l)?l:0,d=isFinite(r)?r:1),s===d&&(d=s+1);const x=p=>Math.min(1,Math.max(0,p));if(m&&s>0&&d>0){const p=Math.log10(s),a=Math.log10(d)-p;return h=>h<=0?0:x((Math.log10(h)-p)/a)}return p=>x((p-s)/(d-s))}function N(i,n,e,t,m,l,r){const f=c("div",{display:"flex",flexDirection:"column",gap:"2px",minWidth:"0",flex:"1",minHeight:"0"});f.appendChild(c("div",{fontSize:"10px",fontWeight:"700",letterSpacing:"0.06em",textTransform:"uppercase",color:u.label},n?.name?`${n.name} distribution`:"Value distribution"));const s=i[0].rangeLow,d=i[i.length-1].rangeHigh,x=d-s||1,p=o=>Math.min(1,Math.max(0,(o-s)/x)),a=z(t),h=I(m,e,n,l,r),S=Math.max(1,...i.map(o=>o.count)),L=c("div",{position:"relative",display:"flex",alignItems:"flex-end",gap:"2px",flex:"1",minHeight:"48px"});for(const o of i){const g=c("div",{flex:"1",minWidth:"2px",background:a.forValue(h((o.rangeLow+o.rangeHigh)/2)),height:`${o.count/S*100}%`,borderRadius:"1px 1px 0 0"});g.dataset.wmapBar="1",F(g,`${b(o.rangeLow,n?.unit)} \u2013 ${b(o.rangeHigh,n?.unit)}: ${o.count}`),L.appendChild(g)}const M=[];for(const[o,g]of[[n?.limitLow,"LSL"],[n?.limitHigh,"USL"]]){if(o===void 0||o<s||o>d)continue;const v=p(o)*100,w=c("div",{position:"absolute",top:"0",bottom:"0",left:`${v}%`,width:"2px",marginLeft:"-1px",background:u.value,boxShadow:`0 0 0 1px ${u.panelBg}`,pointerEvents:"none"});w.dataset.wmapLimitMarker="1",L.appendChild(w),M.push({pct:v,text:`${g} ${b(o,n?.unit)}`})}if(f.appendChild(L),M.length){const o=c("div",{position:"relative",height:"14px"});for(const{pct:g,text:v}of M){const w=Math.min(96,Math.max(4,g));o.appendChild(c("span",{position:"absolute",left:`${w}%`,top:"0",transform:"translateX(-50%)",whiteSpace:"nowrap",fontSize:"9px",fontWeight:"600",color:u.text,background:u.panelBg,border:`1px solid ${u.value}`,borderRadius:"2px",padding:"0 3px",lineHeight:"12px"},v))}f.appendChild(o)}const C=c("div",{display:"flex",justifyContent:"space-between",fontSize:"10px",color:u.label});return C.appendChild(c("span",{},b(i[0].rangeLow,n?.unit))),C.appendChild(c("span",{},b(i[i.length-1].rangeHigh,n?.unit))),f.appendChild(C),f}export function buildMaplessSummary(i,n,e){const{plotMode:t,activeTest:m,hbinDefs:l,sbinDefs:r,colorScheme:f,logScale:s=!1,colorbarRangeMode:d="spec",valueRangeDies:x}=e;if(t==="hardBin"||t==="softBin"){const a=y(i,t==="hardBin"?l:r,t==="hardBin"?"hard":"soft",f);if(a)return a}else if(t==="value"){const{testNumber:p}=T(m??0,n),a=$(n,m??0),h=B([{dies:i}],p,12,a?.limitLow,a?.limitHigh);if(h.length)return N(h,a,p,f,x??i,d,s)}return c("div",{padding:"12px",fontSize:"11px",color:u.label,textAlign:"center"},"No summary available for this view.")}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type SaveImageHandler, type SaveTextHandler, type UserGuideExtension } from './toolbar.js';
|
|
2
2
|
import type { Die } from '../core/dies.js';
|
|
3
3
|
import type { WaferViewOptions } from './renderWaferMap.js';
|
|
4
|
+
import type { RenderableWaferMap } from './renderWaferMap.js';
|
|
4
5
|
import type { LotStatsSummary } from '../stats/types.js';
|
|
6
|
+
import { type WarningsOptions } from './warnings.js';
|
|
5
7
|
import type { SummaryPanelOptions } from './summaryPanel.js';
|
|
6
8
|
import { type InsightsOptions } from './insightsTab.js';
|
|
7
9
|
/**
|
|
@@ -17,17 +19,7 @@ import { type InsightsOptions } from './insightsTab.js';
|
|
|
17
19
|
* ]);
|
|
18
20
|
* ```
|
|
19
21
|
*/
|
|
20
|
-
export interface WaferMapDisplayItem {
|
|
21
|
-
wafer: import('../core/wafer.js').Wafer;
|
|
22
|
-
dies: Die[];
|
|
23
|
-
hbinDefs?: import('../renderer/buildWaferMap.js').BinDef[];
|
|
24
|
-
sbinDefs?: import('../renderer/buildWaferMap.js').BinDef[];
|
|
25
|
-
testDefs?: import('../renderer/buildWaferMap.js').TestDef[];
|
|
26
|
-
metadataFields?: import('../renderer/buildWaferMap.js').MetadataFieldDef[];
|
|
27
|
-
reticles?: import('../core/reticle.js').Reticle[];
|
|
28
|
-
isLotStack?: boolean;
|
|
29
|
-
aggrMethod?: string;
|
|
30
|
-
lotSize?: number;
|
|
22
|
+
export interface WaferMapDisplayItem extends RenderableWaferMap {
|
|
31
23
|
label?: string;
|
|
32
24
|
/** Merged on top of the shared gallery options for this card only. */
|
|
33
25
|
viewOptions?: Partial<WaferViewOptions>;
|
|
@@ -148,6 +140,12 @@ export interface GalleryOptions {
|
|
|
148
140
|
* recomputing it — no other host wiring beyond this option.
|
|
149
141
|
*/
|
|
150
142
|
insights?: InsightsOptions;
|
|
143
|
+
/**
|
|
144
|
+
* Built-in surfacing of the library's own data warnings (see `WarningsOptions`).
|
|
145
|
+
* Defaults on. The gallery collects across every item and de-duplicates, so a
|
|
146
|
+
* geometry advisory affecting the whole lot is stated once, not per card.
|
|
147
|
+
*/
|
|
148
|
+
warnings?: WarningsOptions;
|
|
151
149
|
}
|
|
152
150
|
export interface GalleryController {
|
|
153
151
|
/** Replace all items — destroys existing cards and rebuilds the grid. Accepts pre-built items, factory functions, or a mix. */
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as
|
|
2
|
-
`),
|
|
1
|
+
import{getUniqueTestNumbers as yn,resolveTestNumber as xn,findTestDef as wn}from"../renderer/buildView.js";import{getColorScheme as vn}from"../renderer/colorSchemes.js";import{metadataValueColor as Cn}from"../renderer/colorMap.js";import{resolveCanvasTheme as Sn}from"./canvasTheme.js";import{ICONS as pe}from"./icons.js";import{CLR as m,sevColor as Mt,BIN_LEGEND_MODES as Mn,STACKED_MODES as ue,Z_ABOVE as kt,applyOverlayZ as kn,getTooltip as Bn,hideTooltip as Bt,createToolbarHelpers as En,buildModeMenuEl as On,openDetachWindow as Dn,openFloatingWindow as Tn,openModal as Wn,copyWmapThemeTokens as Ln,syncWmapPopupTheme as In,openUserGuideWindow as Rn,makePaletteBtn as Pn,makeLogScaleBtn as An,makeLegendStyleBtn as Fn,makeOverlaysBtn as Hn,makeOrientationBtn as $n,overlayRootFor as Et,saveImageBlob as jn,markMenuTrigger as me,wireMenuA11y as Ot,wireExpandToggle as Dt,passFailMenuRows as zn,requestedPassFailDisplay as Ge,logWmapVersionOnce as Nn,buildDataModeEntries as Vn,metadataKeyHasData as _n,metadataModeEntry as Gn}from"./toolbar.js";import{aggregateValues as Kn,aggregateBinCounts as Tt}from"../core/aggregates.js";import{renderWaferMap as Ke}from"./renderWaferMap.js";import{classifyChanged as qn}from"./renderWaferMap.js";import{buildWaferMap as Xn,getTestPassStatus as Un,isParametricTest as Wt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ee}from"../stats/analyzeWaferMap.js";import{collectWarnings as Yn,buildWarningsMenuEl as Qn,severityOf as Zn}from"./warnings.js";import{compareNatural as Jn}from"../core/utils.js";import{createSummaryPanelEl as qe,buildMetadataStripRow as ei,buildCompactMetadataRows as Lt,metadataEntries as It,renderLotSummaryContent as ti}from"./summaryPanel.js";import"../stats/facets.js";import{openHtmlReport as ni}from"../stats/renderFindingsReport.js";import{escHtml as ge,renderSection as ii,renderSeverityBadge as ai,reportStyles as oi}from"../stats/reportHtml.js";import{createInsightsTab as li}from"./insightsTab.js";import{getDieKey as si,hasPosition as ri}from"../core/dies.js";function Oe(S){const B=new Set;return S.filter(u=>B.has(u.bin)?!1:(B.add(u.bin),!0))}function Rt(S,B){const u=document.createElement("div");Object.assign(u.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:"2px 4px",borderRadius:"3px"});const U=document.createElement("span");Object.assign(U.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:B.color,border:B.isActive?`2px solid ${m.iconActive}`:`1px solid ${m.menuBorder}`,borderRadius:"2px",boxSizing:"border-box"});const te=document.createElement("span");te.textContent=B.label,Object.assign(te.style,{fontWeight:B.isActive?"700":"400",color:B.isActive?m.iconActive:m.text,whiteSpace:"nowrap"}),u.appendChild(U),u.appendChild(te),u.setAttribute("role","button"),u.setAttribute("aria-pressed",B.isActive?"true":"false"),u.tabIndex=0,u.addEventListener("mouseenter",()=>{u.style.background=m.bgHover}),u.addEventListener("mouseleave",()=>{u.style.background="transparent"}),u.addEventListener("focus",()=>{u.style.background=m.bgHover}),u.addEventListener("blur",()=>{u.style.background="transparent"}),u.addEventListener("click",B.onClick),u.addEventListener("keydown",L=>{(L.key==="Enter"||L.key===" ")&&(L.preventDefault(),B.onClick())}),S.appendChild(u)}export function renderWaferGallery(S,B,u={}){Nn();const U=u.cardPadding??6,te=u.downloadFilename??"wafer-gallery";let L=u.columns;const Pt=u.showPlotModeSelector??!0,At=u.showHelpButton??!1,Ft=u.userGuideExtension,Xe=u.insights?.enabled??!1,Ht=kn(u.zIndex),Y=u.summaryPanel,Ue=u.passBins??[1];let he=u.fallbackFormat,D=u.lotStatsSummary,ne=u.legendPosition??"default",d={plotMode:"hardBin",colorScheme:"default",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,...u.viewOptions},w=[],q=[],Q=[],M=[],y=B.map(e=>typeof e=="function"?null:e),De=0,be=0;const R=new Map;let $t=0,T=null,ie=null,Ye=new Set,p=null,ae="lot",jt={};function Qe(e){return y[e]?.statsSummary??D?.perWafer.find(t=>t.waferIndex===e)?.summary}function ye(){return!!(y.some(e=>e?.statsSummary?.findings.length)||D?.perWafer.some(e=>e.summary.findings.length))}const zt=Bn(),Z=En(zt),{makeBtn:V,setActive:oe,makeSep:P,makeMenuRow:Nt,makeMenuSection:Vt,makeDropdown:Ze,makeCheckMenuBtn:di,closeOpenMenu:xe,getOpenMenu:le,setOpenMenu:se}=Z;S.ownerDocument.addEventListener("click",xe,!0);const Je=()=>Bt();window.addEventListener("blur",Je);function Te(e){Ye=new Set(e);const t=[...O.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((i,s)=>{const c=Ye.has(s);i.style.outline=c?`3px solid ${m.findingHighlight}`:"",i.style.outlineOffset=c?"-3px":"",c&&n===void 0&&(n=i)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function We(){Te([])}function Le(){for(const e of w)e&&e.clearSelection()}function Ie(e,t){const n=new Set(e),i=t??w.map((s,c)=>c);for(const s of i){const c=M[s],a=w[s];if(!c||!a)continue;const r=c.dies.filter(o=>n.has(si(o)));a.setSelection(r)}}function et(){const e=document.createElement("div");Object.assign(e.style,{display:"flex",gap:"4px",marginBottom:"10px",borderBottom:`1px solid ${m.menuBorder}`,paddingBottom:"8px"});for(const t of["lot","wafers"]){const n=document.createElement("button");n.type="button",n.textContent=t==="lot"?"Lot":"Wafers";const i=ae===t;Object.assign(n.style,{border:"none",borderRadius:"4px",padding:"2px 8px",fontSize:"11px",cursor:"pointer",fontWeight:i?"600":"400",background:i?m.bgActive:"transparent",color:i?m.iconHover:m.icon}),n.addEventListener("click",()=>{ae=t,We(),Le(),I()}),e.appendChild(n)}return e}function _t(){if(!p)return;p.innerHTML="",D&&p.appendChild(et());const e=[];for(let n=0;n<y.length;n++){const i=y[n];if(!i)continue;const s=Qe(n)?.findings??[];if(!s.length)continue;const c=s.filter(r=>r.severity==="unusual").length,a=s.filter(r=>r.severity==="notable").length;e.push({index:n,item:i,unusualCount:c,notableCount:a,totalCount:s.length})}if(e.length>0){const n=document.createElement("button");n.type="button",n.textContent="Findings report",Object.assign(n.style,{border:`1px solid ${m.menuBorder}`,borderRadius:"4px",padding:"3px 8px",marginBottom:"10px",fontSize:"10px",color:m.iconHover,background:"none",cursor:"pointer",display:"block",width:"100%",textAlign:"left"}),n.addEventListener("click",()=>{const i=`Findings report \u2014 ${e.length} wafer${e.length>1?"s":""}`,s=new Date().toLocaleString(),c=e.map(({item:r,index:o})=>{const l=Qe(o),f=r.label??`W${o+1}`,h=l.findings.map(g=>`<li>${ai(g.severity)} ${ge(g.summary)}</li>`).join("");return ii(ge(f),`<ul style="margin:0;padding-left:18px;list-style:none">${h}</ul>`)}).join(`
|
|
2
|
+
`),a=`<!DOCTYPE html>
|
|
3
3
|
<html lang="en">
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="UTF-8">
|
|
6
|
-
<title>${
|
|
6
|
+
<title>${ge(i)}</title>
|
|
7
7
|
<style>
|
|
8
|
-
${
|
|
8
|
+
${oi()}
|
|
9
9
|
</style>
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<main class="report">
|
|
13
13
|
<header class="report-header">
|
|
14
|
-
<h1>${
|
|
15
|
-
<p class="report-subtitle">Generated ${
|
|
14
|
+
<h1>${ge(i)}</h1>
|
|
15
|
+
<p class="report-subtitle">Generated ${ge(s)}</p>
|
|
16
16
|
</header>
|
|
17
|
-
${
|
|
17
|
+
${c}
|
|
18
18
|
</main>
|
|
19
19
|
</body>
|
|
20
|
-
</html>`;qn(s)}),f.appendChild(n)}if(e.length===0){const n=document.createElement("div");Object.assign(n.style,{color:g.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",f.appendChild(n)}else for(const{index:n,item:i,unusualCount:l,notableCount:o,totalCount:s}of e){const r=l?"unusual":o?"notable":"info",a=l+o||s,d=document.createElement("button");d.type="button",Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:"4px",border:"none",borderLeft:`3px solid ${xt(r)}`,borderRadius:"3px",background:g.bgHover,cursor:"pointer",fontSize:"11px",textAlign:"left",boxSizing:"border-box"}),d.addEventListener("mouseover",()=>{d.style.background=g.bgActive}),d.addEventListener("mouseout",()=>{d.style.background=g.bgHover});const p=document.createElement("span");p.textContent=i.label??`W${n+1}`,Object.assign(p.style,{color:g.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const h=document.createElement("span");h.textContent=String(a),Object.assign(h.style,{marginLeft:"6px",flexShrink:"0",background:xt(r),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),d.appendChild(p),d.appendChild(h),d.addEventListener("click",()=>ve(n,i)),f.appendChild(d)}const t=document.createElement("div");t.style.height="12px",f.appendChild(t)}function W(){if(f)if(te==="lot"&&T){const e=Me(x.flatMap(n=>n?.hbinDefs??[])),t=Me(x.flatMap(n=>n?.sbinDefs??[]));Kn(f,{lotSummary:T,items:x,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:x.find(n=>n?.testDefs?.length)?.testDefs,passBins:Ge,ringCount:c.ringCount,colorScheme:c.colorScheme,fallbackFormat:pe,activeFindingId:ee,findingsFilter:Wt,onFindingsFilterChange:W,onSaveText:m.onSaveText,onFindingClick:(n,i)=>{ee===n.id?Te():Ht(n,i),W()},onWaferClick:n=>{Be([n])}}),ue()&&f.insertBefore(Qe(),f.firstChild)}else Ft()}function Ze(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}function Te(){ee=null,Ee(),Oe(),v({highlightBin:void 0},{fireCallback:!1})}function Ht(e,t){if(ee===e.id){Te();return}ee=e.id,t.style.background=g.bgActive,t.style.fontWeight="600";const{kind:n,index:i}=e.variable;n==="test"?v({plotMode:"value",activeTest:i??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?v({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):v({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1}),Ee(),Oe();const l=e.highlight;if(l.kind==="wafer"){Be(l.waferIndices);const o=Ze(e);for(const s of l.waferIndices){const d=S[s]?.statsSummary?.findings.find(p=>Ze(p)===o)?.highlight?.dieKeys;d?.length&&De(d,[s])}}else l.kind==="bin"?l.dieKeys?.length&&De(l.dieKeys):(l.kind==="region"||l.kind==="dies")&&l.dieKeys?.length&&De(l.dieKeys)}function G(){if(!E)return;const e=!!f;E.style.display=(T||ue())&&e&&!Ie?"flex":"none";const t=f?f.style.display!=="none":!1;(T?.hasNotableFindings||x.some(i=>i?.statsSummary?.hasNotableFindings))&&!t?E.style.color=g.findingIndicator:E.dataset.active||(E.style.color=g.icon)}const L=document.createElement("div");L.dataset.wmapToolbar="gallery",Object.assign(L.style,{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"6px",padding:"3px 4px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const Je=()=>{const e=me();e&&(e.remove(),ge(null)),Ce(H,!1)},H=_("mode","Plot mode",()=>{if(me()){Je();return}const e=x.flatMap(u=>u?.dies??[]),t=x.find(u=>u?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:i,stackedEntries:l}=Fn(e,t,{includeStacked:!0}),o=c.plotMode??"hardBin",s=c.activeTest??0;function r(u){return u.plotMode!==o?!1:u.plotMode==="value"?s===(u.activeTest??0):u.plotMode==="metadata"?c.activeMetadataKey===u.activeMetadataKey:!0}function a(u,O){u.activeTest!==void 0?v({plotMode:"value",activeTest:u.activeTest,activeMetadataKey:void 0,logScale:u.logScale}):u.activeMetadataKey!==void 0?v({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:u.activeMetadataKey,passFailDisplay:"off"}):v({plotMode:u.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),O.remove(),ge(null),Ce(H,!1)}const d=new Set,p=x.flatMap(u=>u?.metadataFields??[]).filter(u=>!d.has(u.key)&&d.add(u.key)).filter(u=>Hn(e,u.key)).map($n),h=vn(H.getBoundingClientRect(),n,i,l,r,a,{makeMenuRow:Pt,makeMenuSection:At},o,H.ownerDocument.defaultView??window,p);In(H).appendChild(h),ge(h),Ce(H,!0),Rn(h,H,Je)});Ce(H,!1);const $t=()=>S.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:jt,sync:et}=En(U,()=>c.plotMode??"hardBin",()=>c.colorScheme??"default",$t,e=>v({colorScheme:e}));et();const zt=k.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Le(){const e=x.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=pn(c.activeTest??0,e);return{testNumber:t,td:fn(e,t)}}function tt(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Le();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function ie(){if((c.plotMode??"hardBin")!=="value")return!1;const{td:e}=Le();return e!==void 0&&!Mt(e)}function Nt(){if((c.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Le();return x.some(n=>n?.dies?.some(i=>Vn(i,e,t)!==void 0))}const Vt=Tn(U,()=>[{label:"Ring boundaries",active:!!c.showRingBoundaries,onClick:()=>v({showRingBoundaries:!c.showRingBoundaries})},{label:"Quadrant lines",active:!!c.showQuadrantBoundaries,onClick:()=>v({showQuadrantBoundaries:!c.showQuadrantBoundaries})},{label:"Die labels",active:!!c.showDieLabels,onClick:()=>v({showDieLabels:!c.showDieLabels})},{label:"Reticle grid",active:!!c.showReticle,enabled:zt,onClick:()=>v({showReticle:!c.showReticle})},{label:"XY indicator",active:!!c.showXYIndicator,onClick:()=>v({showXYIndicator:!c.showXYIndicator})},...Pn({functionalActive:ie(),hasLimits:tt()&&!ie(),hasRecorded:Nt()&&!ie(),display:ze(c)},e=>v({passFailDisplay:e}))],()=>!!(c.showRingBoundaries||c.showQuadrantBoundaries||c.showDieLabels||c.showReticle||c.showXYIndicator||ze(c)!=="off")),{btn:_t,sync:nt}=Dn(U,()=>({plotMode:c.plotMode,legendPosition:J}),e=>{J=e;for(const t of w)t&&t.setOptions({legendPosition:J})});nt();const Gt=[{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"}],it=Xe("aggr","Aggregation method",()=>Gt,()=>c.aggregationMethod??"mean",e=>v({aggregationMethod:e}));function at(){const e=c.plotMode==="stackedValues";it.style.display=e?"":"none"}at();const{btn:Kt,sync:ot}=On(U,()=>({...c,functionalActive:ie()}),e=>v(e));ot();const he=_("specRange","Colorbar range: spec limits",()=>{const e=c.colorbarRangeMode==="data"?"spec":"data";v({colorbarRangeMode:e})});function lt(){const e=(c.plotMode??"hardBin")==="value"&&tt()&&ze(c)==="off"&&!ie();he.style.display=e?"":"none";const t=(c.colorbarRangeMode??"spec")==="spec";ne(he,t),he.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}lt();const qt=Ln(U,()=>c,e=>v(e)),Xt=_("downloadAll","Download gallery PNG",rn),Ut=Xe("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"}],()=>I!=null?String(I):"auto",e=>mt(e==="auto"?void 0:Number(e))),C=document.createElement("div");Object.assign(C.style,{display:"inline-flex",alignItems:"center",gap:"0"}),L.appendChild(C),Ot&&C.appendChild(H),C.appendChild(jt),C.appendChild(it),C.appendChild(Kt),C.appendChild(he),C.appendChild(F()),C.appendChild(Vt),C.appendChild(F()),C.appendChild(_t),C.appendChild(F()),C.appendChild(qt),C.appendChild(F()),C.appendChild(Ut),C.appendChild(F()),C.appendChild(Xt),(T||ue())&&(E=_("findings","Summary panel",()=>{if(!f)return;const e=f.style.display!=="none";e||W(),f.style.display=e?"none":"flex",ne(E,!e),G()}),L.appendChild(F()),L.appendChild(E));let Y=null;_e&&(Y=_("analysis","Insights",()=>{const e=Q?.style.display!=="none";rt(!e)}),L.appendChild(F()),L.appendChild(Y));function st(){import("./userGuideHtml.js").then(e=>Bn({buildWaferMap:Nn,renderWaferMap:Ne,renderWaferGallery,analyzeWaferMap:Se},e.USER_GUIDE_HTML,Tt,M))}Dt&&(L.appendChild(F()),L.appendChild(_("help","User guide",()=>st())));const N=document.createElement("div");Object.assign(N.style,{display:"flex",flexDirection:"column",gap:"6px",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"6px",padding:"6px 10px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"});const A=document.createElement("div");Object.assign(A.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let ae=null,Q=null;_e&&(ae=Qn({getItems:()=>x,getLotStats:()=>T,getColorSchemeName:()=>c.colorScheme??"default",passBins:Ge,getRingCount:()=>c.ringCount??4,defaultView:m.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>rt(!1)},showMetadataStrip:!1,onSaveImage:m.onSaveImage,onSaveText:m.onSaveText,openWafer:(e,t,n)=>{const i=x[e];if(!i)return;let l=null;const o=Sn({title:t,onClose:()=>l?.destroy(),anchor:M});ht(o,t,i.wafer.metadata??void 0),l=Fe(o.contentWrap,i,n)}}),Q=ae.el);let Ie=!1;function rt(e){!ae||!Q||(Ie=e,Q.style.display=e?"flex":"none",A.style.display=e?"none":"flex",C.style.display=e?"none":"inline-flex",Y&&(ne(Y,e),Y.innerHTML=e?re.wafer:re.analysis,Y.ariaLabel=e?"Back to gallery view":"Insights"),G(),xe(),e&&ae.render())}const Yt=4,We=240,dt=480,Qt=720,Zt=1.25,ct=m.maxSize;let $=ct??dt;function pt(e){const t=K*2+110+2;let n=null;for(const i of e){if(i==null||!i.dies?.length)continue;const l=i.dies[0].width;if(!(l>0))continue;const o=i.wafer.radius*2*(Yt/l),s=Math.ceil(o+t);(n==null||s>n)&&(n=s)}return n}function Jt(e){const t=pt(e);return t==null?We:Math.min($,Math.max(We,t))}function en(e){if(ct!=null)return!1;const t=pt(e);if(t==null)return!1;const n=Math.min(Qt,Math.max(dt,t));return n<=$?!1:($=n,!0)}function tn(){for(const e of Array.from(B.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${$}px`,e.style.maxHeight=`${$}px`)}let be=We,ft=0;function ut(e){const t=en(e);if(t&&tn(),I!=null){t&&ye();return}const n=Jt(e);n>be&&(be=n),ye()}function mt(e){I=e,ye()}function Re(e){return`repeat(${e}, minmax(0, ${$}px))`}function ye(){if(I!=null){B.style.gridTemplateColumns=Re(I);return}const e=Math.max(1,ft),t=12,n=B.clientWidth||0,i=o=>(n-t*(o-1))/o;let l=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){for(;l>1&&i(l)<be;)l--;const o=Math.min($,be*Zt);for(;l<e&&i(l+1)>=o;)l++}B.style.gridTemplateColumns=Re(l)}const B=document.createElement("div");if(Object.assign(B.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:Re(1),gap:"12px",justifyContent:"start",alignContent:"start"}),te=T?"lot":"wafers",q?.placement){const e=q.placement;f=Ve(e),f.style.maxHeight="calc(100vh - 80px)",f.style.position="sticky",f.style.top="8px",f.style.display="flex",f.style.flexDirection="column"}else if(T||ue()){const e=!!q?.defaultOpen;f=Ve("right"),f.style.maxHeight="calc(100vh - 80px)",f.style.position="sticky",f.style.top="8px",f.style.flexDirection="column",f.style.display=e?"flex":"none",W()}G(),f?.style.display!=="none"&&E&&ne(E,!0),(q?.placement??"right")==="left"?(f&&A.appendChild(f),A.appendChild(B)):(A.appendChild(B),f&&A.appendChild(f)),M.appendChild(L),M.appendChild(N),M.appendChild(A),Q&&M.appendChild(Q);function xe(){N.innerHTML="";const e=c.plotMode??"hardBin",t=!Ie&&hn.has(e),n=S.filter(b=>b!=null),i=n.find(b=>b.isLotStack),l=Gn(n.map(b=>({metadata:b.wafer.metadata??void 0})),i?{lotSize:i.lotSize??n.length,aggrMethod:i.aggrMethod}:void 0),o=e==="metadata",s=c.activeMetadataKey,r=new Set;if(t&&!o)for(const b of n)for(const D of b.dies){if(D.partial)continue;const y=e==="softBin"?D.sbin:D.hbin;y!=null&&r.add(y)}const a=t&&!o?[...r].sort((b,D)=>b-D):[],d=new Set;if(t&&o&&s)for(const b of n)for(const D of b.dies){if(D.partial)continue;const y=D.metadata?.[s];y!=null&&(typeof y=="string"||typeof y=="number"||typeof y=="boolean")&&d.add(String(y))}const p=t&&o?[...d].sort(_n):[];if(!l&&!a.length&&!p.length){N.style.display="none";return}if(N.style.display="flex",l&&N.appendChild(l),!a.length&&!p.length)return;const h=document.createElement("div");Object.assign(h.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),l&&Object.assign(h.style,{borderTop:`1px solid ${g.separator}`,paddingTop:"6px"}),N.appendChild(h);const u=un(c.colorScheme),O=c.highlightBin;if(o){const b=c.highlightMetadataValue,D=S.flatMap(y=>y?.metadataFields??[]).find(y=>y.key===s);p.forEach((y,He)=>{const $e=b===y,yt=D?.values?.find(je=>je.value===y),dn=yt?.color??mn(He);Et(h,{color:dn,isActive:$e,label:yt?.label??y,onClick:()=>{const je=c.highlightMetadataValue===y?void 0:y;v({highlightMetadataValue:je})}})});return}const z=e==="softBin"?S.flatMap(b=>b?.sbinDefs??[]):S.flatMap(b=>b?.hbinDefs??[]),R=new Set,le=[];for(const b of z)R.has(b.bin)||(R.add(b.bin),le.push(b));const se=le.length>0?new Map(le.map(b=>[b.bin,b])):null;for(const b of a){const D=O===b,y=se?.get(b),He=(c.colorScheme==="custom"?y?.color:void 0)??u.forBin(b);Et(h,{color:He,isActive:D,label:y?.name?`${b} \xB7 ${y.name}`:`Bin ${b}`,onClick:()=>{const $e=c.highlightBin===b?void 0:b;v({highlightBin:$e})}})}}function oe(e){const t=x.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies),i=t[0].wafer,l=t.length,o=i.metadata?{...i,metadata:(({wafer:r,waferId:a,...d})=>d)(i.metadata)}:i;function s(r,a){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:a,lotSize:l}}}if(e==="stackedValues"){const r=t.find(p=>p.testDefs?.length)?.testDefs;let a=r?.filter(Mt);if(r?.length||(a=cn(t.flatMap(h=>h.dies)).map(h=>({testNumber:h,name:`Test ${h}`}))),!a?.length)return[];const d=c.aggregationMethod??"mean";return a.map(p=>{const h=jn(n,d,p.testNumber),u={testNumber:0,name:p.name,unit:p.unit};return{wafer:o,dies:h,testDefs:[u],label:`${p.name} \xB7 ${d}`,isLotStack:!0,aggrMethod:d,lotSize:l,statsSummary:s(Se({wafer:o,dies:h,testDefs:[u]},{testNumbers:[0]}),d)}})}if(e==="stackedBins"){let r=Me(t.flatMap(a=>a.hbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(d=>d.dies.map(p=>p.hbin).filter(p=>p!=null)))].sort((d,p)=>d-p).map(d=>({bin:d,name:`Bin ${d}`}))),r.map(a=>{const d=St(n,a.bin,"hard"),p=[{bin:a.bin,name:a.name}];return{wafer:o,dies:d,hbinDefs:p,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:l,statsSummary:s(Se({wafer:o,dies:d,hbinDefs:p}),"countBin")}})}if(e==="stackedSoftBins"){let r=Me(t.flatMap(a=>a.sbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(d=>d.dies.map(p=>p.sbin).filter(p=>p!=null)))].sort((d,p)=>d-p).map(d=>({bin:d,name:`Bin ${d}`}))),r.map(a=>{const d=St(n,a.bin,"soft"),p=[{bin:a.bin,name:a.name}];return{wafer:o,dies:d,sbinDefs:p,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:l,statsSummary:s(Se({wafer:o,dies:d,sbinDefs:p}),"countBin")}})}return t}function Pe(e){const t=x.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:c.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}const nn=new Set(["default","accessible","custom"]);function v(e,{fireCallback:t=!0}={}){const n=c.plotMode;c={...c,...e};const i=c.plotMode,l=de.has(i),o=n!==void 0&&de.has(n),s=fe>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(i==="hardBin"||i==="softBin")&&!nn.has(c.colorScheme??"")&&(c={...c,colorScheme:"default"}),e.plotMode!==void 0)if(l){const a=Pe(i);if(c={...c,...a},s)for(const d of w)d&&d.setOptions(e);else j(oe(i))}else if(o){const{valueRange:a,lotSize:d,aggregationMethod:p,...h}=c;if(c=h,s)for(const u of w)u&&u.setOptions(e);else j(x.filter(u=>u!==null))}else for(const a of w)a&&a.setOptions(e);else if(e.aggregationMethod!==void 0&&i==="stackedValues")if(s)for(const a of w)a&&a.setOptions(e);else j(oe("stackedValues"));else for(const a of w)a&&a.setOptions(e);xe(),at(),nt(),et();const r=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||r)&&W(),ot(),lt(),t){const a=Object.keys(e);m.onViewOptionsChange?.(c,a,zn(a))}}function gt(e,t,n){const i=e.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0"});const l=e.createElement("span");l.textContent=t,Object.assign(l.style,{fontWeight:"700",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),i.appendChild(l);const o=Bt(n??{});let s=null;if(o.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),r.textContent="\u25BE",i.appendChild(r),Object.assign(i.style,{cursor:"pointer"}),s=e.createElement("div"),s.dataset.wmapCardMetaPanel="1",Object.assign(s.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:vt,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const a=kt(n??{});a&&s.appendChild(a),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Ct(i,d=>{r.textContent=d?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(d)),s&&(s.style.display=d?"block":"none")})}return{wrap:i,metaPanel:s}}function ht(e,t,n){const i=e.box.querySelector("[data-wmap-window-title]"),l=Bt(n??{});if(!i||l.length===0)return;const o=i.parentElement,s=document.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),o?.insertBefore(s,i),s.appendChild(i);const r=document.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:g.label,flexShrink:"0"}),r.textContent="\u25BE",s.appendChild(r);const a=document.createElement("div");a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:vt,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const d=kt(n??{});d&&a.appendChild(d),e.contentWrap.style.position="relative",e.contentWrap.appendChild(a),s.setAttribute("aria-expanded","false"),s.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Ct(s,p=>{r.textContent=p?"\u25B4":"\u25BE",s.setAttribute("aria-expanded",String(p)),a.style.display=p?"block":"none"})}function Ae(e,t,n){const i=document.createElement("div");i.className="wmap-gallery-card",Object.assign(i.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${$}px`,maxHeight:`${$}px`});const l=document.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:o,metaPanel:s}=gt(document,e.label??"",e.wafer.metadata??void 0);l.appendChild(o);const r=document.createElement("button");r.dataset.wmapExpandBtn="1",r.title="Open full view",r.innerHTML=re.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${g.menuBorder}`,borderRadius:"4px",background:g.panelBg,color:g.label,padding:"2px",cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),l.appendChild(r),i.appendChild(l);const a=document.createElement("div");Object.assign(a.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),i.appendChild(a),s&&a.appendChild(s),B.appendChild(i);const d=Ne(a,e,{viewOptions:e.viewOptions?{...c,...e.viewOptions}:c,toolbarControls:"full",showTooltip:!0,padding:K,legendPosition:J,fallbackFormat:pe,statsSummary:e.statsSummary,onSaveImage:m.onSaveImage,onSaveText:m.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>ve(t,e),showMetadataBadge:!1});return d.setViewControlsVisible(!1),d.setSummaryVisible(!1),r.onclick=()=>ve(t,e),{card:i,ctrl:d,canvasWrapper:a,expandBtn:r}}function an(e){const t=X[e];if(!t)return;const n=[...P.values()].find(i=>i.cardIndex===e);n?(t.innerHTML=re.minimize,t.title="Reattach to gallery",t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>ln(n.id)):(t.innerHTML=re.expand,t.title="Open full view",t.setAttribute("aria-label","Open full view"),t.onclick=()=>ve(e,S[e]))}function j(e){sn(),me()?.remove(),ge(null),Te(),S=[];for(const s of w)s&&s.destroy();w=[],V=[],X=[],fe=0,B.innerHTML="",ft=e.length,ut(e.map(s=>typeof s=="function"?null:s));const t=[];for(let s=0;s<e.length;s++){const r=e[s];if(typeof r=="function"){const a=document.createElement("div");a.className="wmap-gallery-card",Object.assign(a.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const d=document.createElement("span");d.textContent="\u2026",Object.assign(d.style,{color:g.label,fontSize:"18px"}),a.appendChild(d),B.appendChild(a),S.push(null),w.push(null),V.push(null),X.push(null),t.push({index:s,factory:r,placeholder:a}),fe++}else{const{ctrl:a,canvasWrapper:d,expandBtn:p}=Ae(r,s,e.length);S.push(r),w.push(a),V.push(d),X.push(p)}}S.flatMap(s=>s?[...s.hbinDefs??[],...s.sbinDefs??[]]:[]).some(s=>s.color)&&!m.viewOptions?.colorScheme&&(c={...c,colorScheme:"custom"}),xe();const i=++ke;let l=0;function o(){if(i!==ke)return;if(l>=t.length){if(de.has(c.plotMode)){const z=c.plotMode;j(oe(z))}return}const{index:s,factory:r,placeholder:a}=t[l++],d=r();S[s]=d,x[s]=d,ut([d]);const{card:p,ctrl:h,canvasWrapper:u,expandBtn:O}=Ae(d,s,e.length);w[s]=h,V[s]=u,X[s]=O,fe--,a.replaceWith(p),xe(),!f&&!q?.placement&&d.statsSummary?.findings.length?(T||(te="wafers"),f=Ve("right"),f.style.maxHeight="calc(100vh - 80px)",f.style.position="sticky",f.style.top="8px",f.style.flexDirection="column",f.style.display="none",(q?.placement??"right")==="left"?A.insertBefore(f,B):A.appendChild(f),W(),E||(E=_("findings","Summary panel",()=>{if(!f)return;const R=f.style.display!=="none";R||W(),f.style.display=R?"none":"flex",ne(E,!R),G()}),L.appendChild(F()),L.appendChild(E)),G()):f&&f.style.display!=="none"&&W(),G(),setTimeout(o,0)}t.length>0&&setTimeout(o,0)}if(de.has(c.plotMode)&&x.length>0){const e=Pe(c.plotMode);c={...c,...e},j(oe(c.plotMode))}else j(k);const bt=new ResizeObserver(()=>{I==null&&ye()});bt.observe(B),f&&W();function on(e){const t=V[e];if(!t)return;t.innerHTML="",Object.assign(t.style,{alignItems:"center",justifyContent:"center"});const n=document.createElement("span");n.textContent="Detached \u2014 open in its own window",Object.assign(n.style,{color:g.label,fontSize:"12px",textAlign:"center",padding:"0 12px"}),t.appendChild(n)}function ve(e,t){for(const o of P.values())if(o.cardIndex===e)return;const n=t.label??"Wafer map",i=It++,l=wn(n);if(l){const o=l.document;o.title=n,Object.assign(o.documentElement.style,{height:"100%"}),Object.assign(o.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),Mn(M,o.documentElement);const s=kn(M,o.documentElement,()=>O.setOptions({})),r=o.createElement("div");r.dataset.wmapWindowBanner="1",r.textContent=n,Object.assign(r.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:g.warnBg,color:g.warnText,borderBottom:`1px solid ${g.warnBorder}`,flexShrink:"0"}),o.body.appendChild(r);const a=o.createElement("div");Object.assign(a.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),o.body.appendChild(a);const{wrap:d,metaPanel:p}=gt(o,n,t.wafer.metadata??void 0),h=o.createElement("div");Object.assign(h.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:"6px"}),h.appendChild(d),a.appendChild(h);const u=o.createElement("div");Object.assign(u.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),p&&u.appendChild(p),a.appendChild(u);const O=Fe(u,t),z=setInterval(()=>{l.closed&&we(i)},400);l.addEventListener("pagehide",()=>we(i)),P.set(i,{id:i,ctrl:O,cardIndex:e,label:n,closePollId:z,stopThemeSync:s,close:()=>{l.closed||l.close()},setTitle:R=>{o.title=R,r.textContent=R,r.style.display="block"}})}else{const o=Cn({title:n,onClose:()=>we(i),anchor:M});o.contentWrap.style.flexDirection="column",ht(o,n,t.wafer.metadata??void 0);const s=Fe(o.contentWrap,t);P.set(i,{id:i,ctrl:s,cardIndex:e,label:n,closePollId:null,close:()=>o.close(),setTitle:r=>{const a=o.box.querySelector("[data-wmap-window-title]");a&&(a.textContent=r,a.title=r)}})}w[e]?.destroy(),w[e]=null,on(e),an(e)}function Fe(e,t,n){const i=t.viewOptions?{...c,...t.viewOptions}:c,l=n!==void 0?{...i,plotMode:"value",activeTest:n}:i,o=Ne(e,t,{viewOptions:l,toolbarControls:"full",showTooltip:!0,padding:K,legendPosition:J,fallbackFormat:pe,statsSummary:t.statsSummary,onSaveImage:m.onSaveImage,onSaveText:m.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return o.setViewControlsVisible(!0),o.setSummaryVisible(!0),o.setExpandVisible(!1),o}function we(e){const t=P.get(e);if(!t)return;P.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const i=t.cardIndex,l=S[i];if(!l)return;const o={...l,viewOptions:n};S[i]=o;const{card:s,ctrl:r,canvasWrapper:a,expandBtn:d}=Ae(o,i,S.length);V[i]?.parentElement?.replaceWith(s),w[i]=r,V[i]=a,X[i]=d}function ln(e){const t=P.get(e);t&&(t.close(),we(e))}function sn(){for(const e of P.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function rn(){const e=[...B.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),i=Math.ceil(t/n),l=e[0].width,o=e[0].height,s=8,r=window.devicePixelRatio||1,a=Math.round(26*r),d=Math.round(12*r),p=document.createElement("canvas");p.width=n*l+(n-1)*s,p.height=i*(o+a)+(i-1)*s;const h=p.getContext("2d"),u=gn(B);h.fillStyle=u.background,h.fillRect(0,0,p.width,p.height),e.forEach((O,z)=>{const R=z%n,le=Math.floor(z/n),se=R*(l+s),b=le*(o+a+s),D=O.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";h.fillStyle=u.surface,h.fillRect(se,b,l,a),h.fillStyle=u.text,h.font=`700 ${d}px system-ui, sans-serif`,h.textAlign="left",h.textBaseline="middle",h.fillText(D,se+Math.round(10*r),b+a/2,l-Math.round(20*r)),h.drawImage(O,se,b+a)}),p.toBlob(O=>{O&&Wn(O,Z,m.onSaveImage)})}return{setItems(e){x=e.map(n=>typeof n=="function"?null:n);const t=c.plotMode;if(de.has(t))if(e.some(i=>typeof i=="function"))j(e);else{const i=Pe(t);c={...c,...i},j(oe(t))}else j(e)},setOptions(e){v(e,{fireCallback:!1})},getOptions(){return{...c}},setFallbackFormat(e){pe=e;for(const t of w)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){T=e,f&&W(),G()},setColumns(e){mt(e)},openUserGuide:st,destroy(){ke++;for(const e of[...P.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();P.clear();for(const e of w)e&&e.destroy();w=[],me()?.remove(),bt.disconnect(),M.ownerDocument.removeEventListener("click",Ue,!0),window.removeEventListener("blur",Ye),Lt(),wt(),L.remove(),N.remove(),A.remove(),f?.remove(),ae?.destroy()}}}
|
|
20
|
+
</html>`;ni(a)}),p.appendChild(n)}if(e.length===0){const n=document.createElement("div");Object.assign(n.style,{color:m.icon,fontSize:"11px",padding:"4px 0"}),n.textContent="No findings on any wafer.",p.appendChild(n)}else for(const{index:n,item:i,unusualCount:s,notableCount:c,totalCount:a}of e){const r=s?"unusual":c?"notable":"info",o=s+c||a,l=document.createElement("button");l.type="button",Object.assign(l.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:"4px",border:"none",borderLeft:`3px solid ${Mt(r)}`,borderRadius:"3px",background:m.bgHover,cursor:"pointer",fontSize:"11px",textAlign:"left",boxSizing:"border-box"}),l.addEventListener("mouseover",()=>{l.style.background=m.bgActive}),l.addEventListener("mouseout",()=>{l.style.background=m.bgHover});const f=document.createElement("span");f.textContent=i.label??`W${n+1}`,Object.assign(f.style,{color:m.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const h=document.createElement("span");h.textContent=String(o),Object.assign(h.style,{marginLeft:"6px",flexShrink:"0",background:Mt(r),color:"#fff",borderRadius:"8px",padding:"1px 5px",fontSize:"10px",fontWeight:"600"}),l.appendChild(f),l.appendChild(h),l.addEventListener("click",()=>ke(n,i)),p.appendChild(l)}const t=document.createElement("div");t.style.height="12px",p.appendChild(t)}function I(){if(p)if(ae==="lot"&&D){const e=Oe(y.flatMap(n=>n?.hbinDefs??[])),t=Oe(y.flatMap(n=>n?.sbinDefs??[]));ti(p,{lotSummary:D,items:y,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:y.find(n=>n?.testDefs?.length)?.testDefs,passBins:Ue,ringCount:d.ringCount,colorScheme:d.colorScheme,fallbackFormat:he,activeFindingId:ie,warnings:u.warnings?.display??!0?_:[],findingsFilter:jt,onFindingsFilterChange:I,onSaveText:u.onSaveText,onFindingClick:(n,i)=>{ie===n.id?Re():Gt(n,i),I()},onWaferClick:n=>{Te([n])}}),ye()&&p.insertBefore(et(),p.firstChild)}else _t()}function tt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}function Re(){ie=null,We(),Le(),v({highlightBin:void 0},{fireCallback:!1})}function Gt(e,t){if(ie===e.id){Re();return}ie=e.id,t.style.background=m.bgActive,t.style.fontWeight="600";const{kind:n,index:i}=e.variable;n==="test"?v({plotMode:"value",activeTest:i??0,highlightBin:void 0},{fireCallback:!1}):n==="softBin"?v({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):v({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1}),We(),Le();const s=e.highlight;if(s.kind==="wafer"){Te(s.waferIndices);const c=tt(e);for(const a of s.waferIndices){const l=M[a]?.statsSummary?.findings.find(f=>tt(f)===c)?.highlight?.dieKeys;l?.length&&Ie(l,[a])}}else s.kind==="bin"?s.dieKeys?.length&&Ie(s.dieKeys):(s.kind==="region"||s.kind==="dies")&&s.dieKeys?.length&&Ie(s.dieKeys)}function X(){if(!T)return;const e=!!p;T.style.display=(D||ye())&&e&&!Ae?"flex":"none";const t=p?p.style.display!=="none":!1;(D?.hasNotableFindings||y.some(i=>i?.statsSummary?.hasNotableFindings))&&!t?T.style.color=m.findingIndicator:T.dataset.active||(T.style.color=m.icon)}const E=document.createElement("div");E.dataset.wmapToolbar="gallery",Object.assign(E.style,{display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"6px",padding:"3px 4px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const nt=()=>{const e=le();e&&(e.remove(),se(null)),me($,!1)},$=V("mode","Plot mode",()=>{if(le()){nt();return}const e=y.flatMap(g=>g?.dies??[]),t=y.find(g=>g?.testDefs?.length)?.testDefs,{testEntries:n,binEntries:i,stackedEntries:s}=Vn(e,t,{includeStacked:!0}),c=d.plotMode??"hardBin",a=d.activeTest??0;function r(g){return g.plotMode!==c?!1:g.plotMode==="value"?a===(g.activeTest??0):g.plotMode==="metadata"?d.activeMetadataKey===g.activeMetadataKey:!0}function o(g,k){g.activeTest!==void 0?v({plotMode:"value",activeTest:g.activeTest,activeMetadataKey:void 0,logScale:g.logScale}):g.activeMetadataKey!==void 0?v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:g.activeMetadataKey,passFailDisplay:"off"}):v({plotMode:g.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),k.remove(),se(null),me($,!1)}const l=new Set,f=y.flatMap(g=>g?.metadataFields??[]).filter(g=>!l.has(g.key)&&l.add(g.key)).filter(g=>_n(e,g.key)).map(Gn),h=On($.getBoundingClientRect(),n,i,s,r,o,{makeMenuRow:Nt,makeMenuSection:Vt},c,$.ownerDocument.defaultView??window,f);Et($).appendChild(h),se(h),me($,!0),Ot(h,$,nt)});me($,!1);const Kt=()=>M.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:qt,sync:it}=Pn(Z,()=>d.plotMode??"hardBin",()=>d.colorScheme??"default",Kt,e=>v({colorScheme:e}));it();const Xt=B.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Pe(){const e=y.find(n=>n?.testDefs?.length)?.testDefs,{testNumber:t}=xn(d.activeTest??0,e);return{testNumber:t,td:wn(e,t)}}function at(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function re(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=Pe();return e!==void 0&&!Wt(e)}function Ut(){if((d.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Pe();return y.some(n=>n?.dies?.some(i=>Un(i,e,t)!==void 0))}const Yt=Hn(Z,()=>[{label:"Ring boundaries",active:!!d.showRingBoundaries,onClick:()=>v({showRingBoundaries:!d.showRingBoundaries})},{label:"Quadrant lines",active:!!d.showQuadrantBoundaries,onClick:()=>v({showQuadrantBoundaries:!d.showQuadrantBoundaries})},{label:"Die labels",active:!!d.showDieLabels,onClick:()=>v({showDieLabels:!d.showDieLabels})},{label:"Reticle grid",active:!!d.showReticle,enabled:Xt,onClick:()=>v({showReticle:!d.showReticle})},{label:"XY indicator",active:!!d.showXYIndicator,onClick:()=>v({showXYIndicator:!d.showXYIndicator})},...zn({functionalActive:re(),hasLimits:at()&&!re(),hasRecorded:Ut()&&!re(),display:Ge(d)},e=>v({passFailDisplay:e}))],()=>!!(d.showRingBoundaries||d.showQuadrantBoundaries||d.showDieLabels||d.showReticle||d.showXYIndicator||Ge(d)!=="off")),{btn:Qt,sync:ot}=Fn(Z,()=>({plotMode:d.plotMode,legendPosition:ne}),e=>{ne=e;for(const t of w)t&&t.setOptions({legendPosition:ne})});ot();const Zt=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],lt=Ze("aggr","Aggregation method",()=>Zt,()=>d.aggregationMethod??"mean",e=>v({aggregationMethod:e}));function st(){const e=d.plotMode==="stackedValues";lt.style.display=e?"":"none"}st();const{btn:Jt,sync:rt}=An(Z,()=>({...d,functionalActive:re()}),e=>v(e));rt();const we=V("specRange","Colorbar range: spec limits",()=>{const e=d.colorbarRangeMode==="data"?"spec":"data";v({colorbarRangeMode:e})});function dt(){const e=(d.plotMode??"hardBin")==="value"&&at()&&Ge(d)==="off"&&!re();we.style.display=e?"":"none";const t=(d.colorbarRangeMode??"spec")==="spec";oe(we,t),we.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}dt();const en=$n(Z,()=>d,e=>v(e)),tn=V("downloadAll","Download gallery PNG",hn),nn=Ze("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>L!=null?String(L):"auto",e=>xt(e==="auto"?void 0:Number(e))),C=document.createElement("div");Object.assign(C.style,{display:"inline-flex",alignItems:"center",gap:"0"}),E.appendChild(C),Pt&&C.appendChild($),C.appendChild(qt),C.appendChild(lt),C.appendChild(Jt),C.appendChild(we),C.appendChild(P()),C.appendChild(Yt),C.appendChild(P()),C.appendChild(Qt),C.appendChild(P()),C.appendChild(en),C.appendChild(P()),C.appendChild(nn),C.appendChild(P()),C.appendChild(tn),(D||ye())&&(T=V("findings","Summary panel",()=>{if(!p)return;const e=p.style.display!=="none";e||I(),p.style.display=e?"none":"flex",oe(T,!e),X()}),E.appendChild(P()),E.appendChild(T));let j=null,ve=null,_=[],ct=!1;function ft(){const e=Yn({lotStatsSummary:D,result:{warnings:y.flatMap(n=>n?.warnings??[])}}),t=e.length!==_.length||e.some((n,i)=>n.code!==_[i]?.code||n.message!==_[i]?.message);_=e,(t||!ct)&&(ct=!0,u.warnings?.onWarning?.(e)),an()}function an(){if(!j||!ve)return;const e=_.length,t=e>0;if(j.style.display=t?"flex":"none",ve.style.display=t?"":"none",!t)return;const n=Zn(_[0]),i=`${e} data ${e===1?"warning":"warnings"}`;j.style.color=n==="error"?m.errText:m.warnText,j.ariaLabel=n==="error"?`${i} \u2014 wafers in this lot may be positionally wrong`:i}(u.warnings?.display??!0)&&(ve=P(),j=V("warning","Data warnings",()=>{const e=le();if(xe(new MouseEvent("click")),e)return;const t=Qn(j.getBoundingClientRect(),_);Et(S).appendChild(t),se(t),Ot(t,j,()=>xe(new MouseEvent("click")))}),me(j,!1),E.appendChild(ve),E.appendChild(j)),ft();let J=null;Xe&&(J=V("analysis","Insights",()=>{const e=ee?.style.display!=="none";ut(!e)}),E.appendChild(P()),E.appendChild(J));function pt(){import("./userGuideHtml.js").then(e=>Rn({buildWaferMap:Xn,renderWaferMap:Ke,renderWaferGallery,analyzeWaferMap:Ee},e.USER_GUIDE_HTML,Ft,S))}At&&(E.appendChild(P()),E.appendChild(V("help","User guide",()=>pt())));const G=document.createElement("div");Object.assign(G.style,{display:"flex",flexDirection:"column",gap:"6px",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"6px",padding:"6px 10px",marginBottom:"10px",boxShadow:"0 1px 4px rgba(0,0,0,0.10)",fontSize:"12px",lineHeight:"1",boxSizing:"border-box",width:"100%",minWidth:"0"});const A=document.createElement("div");Object.assign(A.style,{display:"flex",flexDirection:"row",gap:"12px",alignItems:"flex-start"});let de=null,ee=null;Xe&&(de=li({getItems:()=>y,getLotStats:()=>D,getColorSchemeName:()=>d.colorScheme??"default",passBins:Ue,getRingCount:()=>d.ringCount??4,defaultView:u.insights?.defaultView,backTab:{label:"Gallery",onBack:()=>ut(!1)},showMetadataStrip:!1,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,openWafer:(e,t,n)=>{const i=y[e];if(!i)return;let s=null;const c=Wn({title:t,onClose:()=>s?.destroy(),anchor:S});vt(c,t,i.wafer.metadata??void 0),s=ze(c.contentWrap,i,n)}}),ee=de.el);let Ae=!1;function ut(e){!de||!ee||(Ae=e,ee.style.display=e?"flex":"none",A.style.display=e?"none":"flex",C.style.display=e?"none":"inline-flex",J&&(oe(J,e),J.innerHTML=e?pe.wafer:pe.analysis,J.ariaLabel=e?"Back to gallery view":"Insights"),X(),Me(),e&&de.render())}const on=4,Fe=240,mt=480,ln=720,sn=1.25,gt=u.maxSize;let z=gt??mt;function ht(e){const t=U*2+110+2;let n=null;for(const i of e){if(i==null||!i.dies?.length)continue;const s=i.dies[0].width;if(!(s>0))continue;const c=i.wafer.radius*2*(on/s),a=Math.ceil(c+t);(n==null||a>n)&&(n=a)}return n}function rn(e){const t=ht(e);return t==null?Fe:Math.min(z,Math.max(Fe,t))}function dn(e){if(gt!=null)return!1;const t=ht(e);if(t==null)return!1;const n=Math.min(ln,Math.max(mt,t));return n<=z?!1:(z=n,!0)}function cn(){for(const e of Array.from(O.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${z}px`,e.style.maxHeight=`${z}px`)}let Ce=Fe,bt=0;function yt(e){const t=dn(e);if(t&&cn(),L!=null){t&&Se();return}const n=rn(e);n>Ce&&(Ce=n),Se()}function xt(e){L=e,Se()}function He(e){return`repeat(${e}, minmax(0, ${z}px))`}function Se(){if(L!=null){O.style.gridTemplateColumns=He(L);return}const e=Math.max(1,bt),t=12,n=O.clientWidth||0,i=c=>(n-t*(c-1))/c;let s=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){for(;s>1&&i(s)<Ce;)s--;const c=Math.min(z,Ce*sn);for(;s<e&&i(s+1)>=c;)s++}O.style.gridTemplateColumns=He(s)}const O=document.createElement("div");if(Object.assign(O.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:He(1),gap:"12px",justifyContent:"start",alignContent:"start"}),ae=D?"lot":"wafers",Y?.placement){const e=Y.placement;p=qe(e),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.display="flex",p.style.flexDirection="column"}else if(D||ye()){const e=!!Y?.defaultOpen;p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display=e?"flex":"none",I()}X(),p?.style.display!=="none"&&T&&oe(T,!0),(Y?.placement??"right")==="left"?(p&&A.appendChild(p),A.appendChild(O)):(A.appendChild(O),p&&A.appendChild(p)),S.appendChild(E),S.appendChild(G),S.appendChild(A),ee&&S.appendChild(ee);function Me(){G.innerHTML="";const e=d.plotMode??"hardBin",t=!Ae&&Mn.has(e),n=M.filter(b=>b!=null),i=n.find(b=>b.isLotStack),s=ei(n.map(b=>({metadata:b.wafer.metadata??void 0})),i?{lotSize:i.lotSize??n.length,aggrMethod:i.aggrMethod}:void 0),c=e==="metadata",a=d.activeMetadataKey,r=new Set;if(t&&!c)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=e==="softBin"?W.sbin:W.hbin;x!=null&&r.add(x)}const o=t&&!c?[...r].sort((b,W)=>b-W):[],l=new Set;if(t&&c&&a)for(const b of n)for(const W of b.dies){if(W.partial)continue;const x=W.metadata?.[a];x!=null&&(typeof x=="string"||typeof x=="number"||typeof x=="boolean")&&l.add(String(x))}const f=t&&c?[...l].sort(Jn):[];if(!s&&!o.length&&!f.length){G.style.display="none";return}if(G.style.display="flex",s&&G.appendChild(s),!o.length&&!f.length)return;const h=document.createElement("div");Object.assign(h.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:"6px 14px"}),s&&Object.assign(h.style,{borderTop:`1px solid ${m.separator}`,paddingTop:"6px"}),G.appendChild(h);const g=vn(d.colorScheme),k=d.highlightBin;if(c){const b=d.highlightMetadataValue,W=M.flatMap(x=>x?.metadataFields??[]).find(x=>x.key===a);f.forEach((x,Ne)=>{const Ve=b===x,St=W?.values?.find(_e=>_e.value===x),bn=St?.color??Cn(Ne);Rt(h,{color:bn,isActive:Ve,label:St?.label??x,onClick:()=>{const _e=d.highlightMetadataValue===x?void 0:x;v({highlightMetadataValue:_e})}})});return}const F=e==="softBin"?M.flatMap(b=>b?.sbinDefs??[]):M.flatMap(b=>b?.hbinDefs??[]),H=new Set,K=[];for(const b of F)H.has(b.bin)||(H.add(b.bin),K.push(b));const fe=K.length>0?new Map(K.map(b=>[b.bin,b])):null;for(const b of o){const W=k===b,x=fe?.get(b),Ne=(d.colorScheme==="custom"?x?.color:void 0)??g.forBin(b);Rt(h,{color:Ne,isActive:W,label:x?.name?`${b} \xB7 ${x.name}`:`Bin ${b}`,onClick:()=>{const Ve=d.highlightBin===b?void 0:b;v({highlightBin:Ve})}})}}function ce(e){const t=y.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(ri)),i=t[0].wafer,s=t.length,c=i.metadata?{...i,metadata:(({wafer:r,waferId:o,...l})=>l)(i.metadata)}:i;function a(r,o){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:o,lotSize:s}}}if(e==="stackedValues"){const r=t.find(f=>f.testDefs?.length)?.testDefs;let o=r?.filter(Wt);if(r?.length||(o=yn(t.flatMap(h=>h.dies)).map(h=>({testNumber:h,name:`Test ${h}`}))),!o?.length)return[];const l=d.aggregationMethod??"mean";return o.map(f=>{const h=Kn(n,l,f.testNumber),g={testNumber:0,name:f.name,unit:f.unit};return{wafer:c,dies:h,testDefs:[g],label:`${f.name} \xB7 ${l}`,isLotStack:!0,aggrMethod:l,lotSize:s,statsSummary:a(Ee({wafer:c,dies:h,testDefs:[g]},{testNumbers:[0]}),l)}})}if(e==="stackedBins"){let r=Oe(t.flatMap(o=>o.hbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(o=>{const l=Tt(n,o.bin,"hard"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,hbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let r=Oe(t.flatMap(o=>o.sbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(l=>l.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((l,f)=>l-f).map(l=>({bin:l,name:`Bin ${l}`}))),r.map(o=>{const l=Tt(n,o.bin,"soft"),f=[{bin:o.bin,name:o.name}];return{wafer:c,dies:l,sbinDefs:f,label:`${o.bin} \xB7 ${o.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:s,statsSummary:a(Ee({wafer:c,dies:l,sbinDefs:f}),"countBin")}})}return t}function $e(e){const t=y.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:d.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}const fn=new Set(["default","accessible","custom"]);function v(e,{fireCallback:t=!0}={}){const n=d.plotMode;d={...d,...e};const i=d.plotMode,s=ue.has(i),c=n!==void 0&&ue.has(n),a=be>0;if(e.plotMode!==void 0&&e.plotMode!==n&&(i==="hardBin"||i==="softBin")&&!fn.has(d.colorScheme??"")&&(d={...d,colorScheme:"default"}),e.plotMode!==void 0)if(s){const o=$e(i);if(d={...d,...o},a)for(const l of w)l&&l.setOptions(e);else N(ce(i))}else if(c){const{valueRange:o,lotSize:l,aggregationMethod:f,...h}=d;if(d=h,a)for(const g of w)g&&g.setOptions(e);else N(y.filter(g=>g!==null))}else for(const o of w)o&&o.setOptions(e);else if(e.aggregationMethod!==void 0&&i==="stackedValues")if(a)for(const o of w)o&&o.setOptions(e);else N(ce("stackedValues"));else for(const o of w)o&&o.setOptions(e);Me(),st(),ot(),it();const r=e.plotMode!==void 0&&e.plotMode!==n;if((e.colorScheme!==void 0||r)&&I(),rt(),dt(),t){const o=Object.keys(e);u.onViewOptionsChange?.(d,o,qn(o))}}function wt(e,t,n){const i=e.createElement("div");Object.assign(i.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0"});const s=e.createElement("span");s.textContent=t,Object.assign(s.style,{fontWeight:"700",fontSize:"13px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),i.appendChild(s);const c=It(n??{});let a=null;if(c.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",i.appendChild(r),Object.assign(i.style,{cursor:"pointer"}),a=e.createElement("div"),a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const o=Lt(n??{});o&&a.appendChild(o),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),Dt(i,l=>{r.textContent=l?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(l)),a&&(a.style.display=l?"block":"none")})}return{wrap:i,metaPanel:a}}function vt(e,t,n){const i=e.box.querySelector("[data-wmap-window-title]"),s=It(n??{});if(!i||s.length===0)return;const c=i.parentElement,a=document.createElement("div");Object.assign(a.style,{display:"flex",alignItems:"center",gap:"4px",flex:"1",minWidth:"0",cursor:"pointer"}),c?.insertBefore(a,i),a.appendChild(i);const r=document.createElement("span");Object.assign(r.style,{fontSize:"12px",lineHeight:"1",color:m.label,flexShrink:"0"}),r.textContent="\u25BE",a.appendChild(r);const o=document.createElement("div");o.dataset.wmapCardMetaPanel="1",Object.assign(o.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:kt,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:"0 2px 6px rgba(0,0,0,0.15)",padding:"8px 10px",fontSize:"11px",display:"none"});const l=Lt(n??{});l&&o.appendChild(l),e.contentWrap.style.position="relative",e.contentWrap.appendChild(o),a.setAttribute("aria-expanded","false"),a.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),Dt(a,f=>{r.textContent=f?"\u25B4":"\u25BE",a.setAttribute("aria-expanded",String(f)),o.style.display=f?"block":"none"})}function je(e,t,n){const i=document.createElement("div");i.className="wmap-gallery-card",Object.assign(i.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${z}px`,maxHeight:`${z}px`});const s=document.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"});const{wrap:c,metaPanel:a}=wt(document,e.label??"",e.wafer.metadata??void 0);s.appendChild(c);const r=document.createElement("button");r.dataset.wmapExpandBtn="1",r.title="Open full view",r.innerHTML=pe.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${m.menuBorder}`,borderRadius:"4px",background:m.panelBg,color:m.label,padding:"2px",cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),s.appendChild(r),i.appendChild(s);const o=document.createElement("div");Object.assign(o.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),i.appendChild(o),a&&o.appendChild(a),O.appendChild(i);const l=Ke(o,e,{viewOptions:e.viewOptions?{...d,...e.viewOptions}:d,toolbarControls:"full",showTooltip:!0,padding:U,legendPosition:ne,fallbackFormat:he,statsSummary:e.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>ke(t,e),showMetadataBadge:!1});return l.setViewControlsVisible(!1),l.setSummaryVisible(!1),r.onclick=()=>ke(t,e),{card:i,ctrl:l,canvasWrapper:o,expandBtn:r}}function pn(e){const t=Q[e];if(!t)return;const n=[...R.values()].find(i=>i.cardIndex===e);n?(t.innerHTML=pe.minimize,t.title="Reattach to gallery",t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>mn(n.id)):(t.innerHTML=pe.expand,t.title="Open full view",t.setAttribute("aria-label","Open full view"),t.onclick=()=>ke(e,M[e]))}function N(e){gn(),le()?.remove(),se(null),Re(),M=[];for(const a of w)a&&a.destroy();w=[],q=[],Q=[],be=0,O.innerHTML="",bt=e.length,yt(e.map(a=>typeof a=="function"?null:a));const t=[];for(let a=0;a<e.length;a++){const r=e[a];if(typeof r=="function"){const o=document.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:"10px",aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const l=document.createElement("span");l.textContent="\u2026",Object.assign(l.style,{color:m.label,fontSize:"18px"}),o.appendChild(l),O.appendChild(o),M.push(null),w.push(null),q.push(null),Q.push(null),t.push({index:a,factory:r,placeholder:o}),be++}else{const{ctrl:o,canvasWrapper:l,expandBtn:f}=je(r,a,e.length);M.push(r),w.push(o),q.push(l),Q.push(f)}}M.flatMap(a=>a?[...a.hbinDefs??[],...a.sbinDefs??[]]:[]).some(a=>a.color)&&!u.viewOptions?.colorScheme&&(d={...d,colorScheme:"custom"}),Me();const i=++De;let s=0;function c(){if(i!==De)return;if(s>=t.length){if(ue.has(d.plotMode)){const F=d.plotMode;N(ce(F))}return}const{index:a,factory:r,placeholder:o}=t[s++],l=r();M[a]=l,y[a]=l,yt([l]);const{card:f,ctrl:h,canvasWrapper:g,expandBtn:k}=je(l,a,e.length);w[a]=h,q[a]=g,Q[a]=k,be--,o.replaceWith(f),Me(),!p&&!Y?.placement&&l.statsSummary?.findings.length?(D||(ae="wafers"),p=qe("right"),p.style.maxHeight="calc(100vh - 80px)",p.style.position="sticky",p.style.top="8px",p.style.flexDirection="column",p.style.display="none",(Y?.placement??"right")==="left"?A.insertBefore(p,O):A.appendChild(p),I(),T||(T=V("findings","Summary panel",()=>{if(!p)return;const H=p.style.display!=="none";H||I(),p.style.display=H?"none":"flex",oe(T,!H),X()}),E.appendChild(P()),E.appendChild(T)),X()):p&&p.style.display!=="none"&&I(),X(),setTimeout(c,0)}t.length>0&&setTimeout(c,0)}if(ue.has(d.plotMode)&&y.length>0){const e=$e(d.plotMode);d={...d,...e},N(ce(d.plotMode))}else N(B);const Ct=new ResizeObserver(()=>{L==null&&Se()});Ct.observe(O),p&&I();function un(e){const t=q[e];if(!t)return;t.innerHTML="",Object.assign(t.style,{alignItems:"center",justifyContent:"center"});const n=document.createElement("span");n.textContent="Detached \u2014 open in its own window",Object.assign(n.style,{color:m.label,fontSize:"12px",textAlign:"center",padding:"0 12px"}),t.appendChild(n)}function ke(e,t){for(const a of R.values())if(a.cardIndex===e)return;const n=t.label??"Wafer map",i=$t++,s=w[e]?.getOptions(),c=Dn(n);if(c){const a=c.document;a.title=n,Object.assign(a.documentElement.style,{height:"100%"}),Object.assign(a.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'}),Ln(S,a.documentElement);const r=In(S,a.documentElement,()=>F.setOptions({})),o=a.createElement("div");o.dataset.wmapWindowBanner="1",o.textContent=n,Object.assign(o.style,{display:"none",padding:"6px 12px",fontSize:"12px",fontWeight:"700",background:m.warnBg,color:m.warnText,borderBottom:`1px solid ${m.warnBorder}`,flexShrink:"0"}),a.body.appendChild(o);const l=a.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),a.body.appendChild(l);const{wrap:f,metaPanel:h}=wt(a,n,t.wafer.metadata??void 0),g=a.createElement("div");Object.assign(g.style,{display:"flex",alignItems:"center",padding:"8px 10px 6px",borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:"6px"}),g.appendChild(f),l.appendChild(g);const k=a.createElement("div");Object.assign(k.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),h&&k.appendChild(h),l.appendChild(k);const F=ze(k,t,void 0,s),H=setInterval(()=>{c.closed&&Be(i)},400);c.addEventListener("pagehide",()=>Be(i)),R.set(i,{id:i,ctrl:F,cardIndex:e,label:n,closePollId:H,stopThemeSync:r,close:()=>{c.closed||c.close()},setTitle:K=>{a.title=K,o.textContent=K,o.style.display="block"}})}else{const a=Tn({title:n,onClose:()=>Be(i),anchor:S});a.contentWrap.style.flexDirection="column",vt(a,n,t.wafer.metadata??void 0);const r=ze(a.contentWrap,t,void 0,s);R.set(i,{id:i,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>a.close(),setTitle:o=>{const l=a.box.querySelector("[data-wmap-window-title]");l&&(l.textContent=o,l.title=o)}})}w[e]?.destroy(),w[e]=null,un(e),pn(e)}function ze(e,t,n,i){const s=t.viewOptions?{...d,...t.viewOptions}:d,c=i?{...s,...i}:s,a=n!==void 0?{...c,plotMode:"value",activeTest:n}:c,r=Ke(e,t,{viewOptions:a,toolbarControls:"full",showTooltip:!0,padding:U,legendPosition:ne,fallbackFormat:he,statsSummary:t.statsSummary,onSaveImage:u.onSaveImage,onSaveText:u.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showMetadataBadge:!1});return r.setViewControlsVisible(!0),r.setSummaryVisible(!0),r.setExpandVisible(!1),r}function Be(e){const t=R.get(e);if(!t)return;R.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const i=t.cardIndex,s=M[i];if(!s)return;const c={...s,viewOptions:n};M[i]=c;const{card:a,ctrl:r,canvasWrapper:o,expandBtn:l}=je(c,i,M.length);q[i]?.parentElement?.replaceWith(a),w[i]=r,q[i]=o,Q[i]=l}function mn(e){const t=R.get(e);t&&(t.close(),Be(e))}function gn(){for(const e of R.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function hn(){const e=[...O.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),i=Math.ceil(t/n),s=e[0].width,c=e[0].height,a=8,r=window.devicePixelRatio||1,o=Math.round(26*r),l=Math.round(12*r),f=document.createElement("canvas");f.width=n*s+(n-1)*a,f.height=i*(c+o)+(i-1)*a;const h=f.getContext("2d"),g=Sn(O);h.fillStyle=g.background,h.fillRect(0,0,f.width,f.height),e.forEach((k,F)=>{const H=F%n,K=Math.floor(F/n),fe=H*(s+a),b=K*(c+o+a),W=k.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";h.fillStyle=g.surface,h.fillRect(fe,b,s,o),h.fillStyle=g.text,h.font=`700 ${l}px system-ui, sans-serif`,h.textAlign="left",h.textBaseline="middle",h.fillText(W,fe+Math.round(10*r),b+o/2,s-Math.round(20*r)),h.drawImage(k,fe,b+o)}),f.toBlob(k=>{k&&jn(k,te,u.onSaveImage)})}return{setItems(e){y=e.map(n=>typeof n=="function"?null:n);const t=d.plotMode;if(ue.has(t))if(e.some(i=>typeof i=="function"))N(e);else{const i=$e(t);d={...d,...i},N(ce(t))}else N(e)},setOptions(e){v(e,{fireCallback:!1})},getOptions(){return{...d}},setFallbackFormat(e){he=e;for(const t of w)t&&t.setFallbackFormat(e)},setLotStatsSummary(e){D=e,ft(),p&&I(),X()},setColumns(e){xt(e)},openUserGuide:pt,destroy(){De++;for(const e of[...R.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();R.clear();for(const e of w)e&&e.destroy();w=[],le()?.remove(),Ct.disconnect(),S.ownerDocument.removeEventListener("click",xe,!0),window.removeEventListener("blur",Je),Ht(),Bt(),E.remove(),G.remove(),A.remove(),p?.remove(),de?.destroy()}}}
|
|
@@ -5,6 +5,7 @@ import type { WaferMapResult } from '../renderer/buildWaferMap.js';
|
|
|
5
5
|
import type { StatsSummary } from '../stats/types.js';
|
|
6
6
|
import { type SaveImageHandler, type SaveTextHandler, type UserGuideExtension } from './toolbar.js';
|
|
7
7
|
import type { SummaryPanelOptions } from './summaryPanel.js';
|
|
8
|
+
import { type WarningsOptions } from './warnings.js';
|
|
8
9
|
import { type InsightsOptions } from './insightsTab.js';
|
|
9
10
|
/**
|
|
10
11
|
* Stable display preferences — worth persisting to localStorage or a user profile.
|
|
@@ -254,6 +255,19 @@ export interface RenderOptions extends Omit<ToCanvasOptions, 'viewport' | 'hbinD
|
|
|
254
255
|
* group by).
|
|
255
256
|
*/
|
|
256
257
|
insights?: InsightsOptions;
|
|
258
|
+
/**
|
|
259
|
+
* Built-in surfacing of the library's own data warnings (see `WarningsOptions`).
|
|
260
|
+
*
|
|
261
|
+
* Defaults to showing them: the library raises geometry advisories that mean
|
|
262
|
+
* dies may be drawn in the wrong place, and analysis advisories that mean a
|
|
263
|
+
* feature silently produced nothing. It has the information, so telling the
|
|
264
|
+
* user is its responsibility rather than the caller's.
|
|
265
|
+
*
|
|
266
|
+
* Hosts with their own notification system should pass
|
|
267
|
+
* `{ display: false, onWarning }` — the library still collects, de-duplicates
|
|
268
|
+
* and severity-orders, and the host owns only presentation.
|
|
269
|
+
*/
|
|
270
|
+
warnings?: WarningsOptions;
|
|
257
271
|
}
|
|
258
272
|
export interface WaferMapController {
|
|
259
273
|
/** Update the die data (e.g. after a data reload) — rebuilds scene, preserves zoom/pan. */
|
|
@@ -312,5 +326,21 @@ export interface WaferMapController {
|
|
|
312
326
|
destroy(): void;
|
|
313
327
|
}
|
|
314
328
|
export declare function classifyChanged(keys: (keyof WaferViewOptions)[]): 'preference' | 'state' | 'mixed';
|
|
315
|
-
|
|
329
|
+
/**
|
|
330
|
+
* What `renderWaferMap` actually needs: a wafer and its dies, plus anything
|
|
331
|
+
* else `buildWaferMap` would have produced *if* the caller went through it.
|
|
332
|
+
*
|
|
333
|
+
* A `WaferMapResult` satisfies this, so nothing changes for the ordinary
|
|
334
|
+
* `buildWaferMap` → `renderWaferMap` path. The reason it isn't simply
|
|
335
|
+
* `WaferMapResult` is `renderWaferGallery`: it renders every card through this
|
|
336
|
+
* same function, but a card is a `WaferMapDisplayItem` — a hand-built or
|
|
337
|
+
* gallery-synthesised shape carrying no `dataCoverage`, `viewport`,
|
|
338
|
+
* `legendBox`, `binLegendRows` or `reticleConfig`. Those cards used to arrive
|
|
339
|
+
* as `item as WaferMapResult`, which told the type checker the fields were
|
|
340
|
+
* there when at runtime they were simply absent; reading one unguarded threw,
|
|
341
|
+
* and each such read had to be found the hard way. Declaring them optional
|
|
342
|
+
* hands that job back to the compiler.
|
|
343
|
+
*/
|
|
344
|
+
export type RenderableWaferMap = Pick<WaferMapResult, 'wafer' | 'dies'> & Partial<Omit<WaferMapResult, 'wafer' | 'dies'>>;
|
|
345
|
+
export declare function renderWaferMap(container: HTMLElement, result: RenderableWaferMap, options?: RenderOptions): WaferMapController;
|
|
316
346
|
//# sourceMappingURL=renderWaferMap.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{buildView as Vn,buildHoverText as _n,findTestDef as vt,resolveTestNumber as bt}from"../renderer/buildView.js";import{toCanvas as Gn,BIN_LEGEND_W as dn,BIN_LEGEND_W_COMPACT as Zn,BIN_LEGEND_ADAPT_COMPACT as Qn,BIN_LEGEND_ADAPT_FLOATING as jn}from"./toCanvas.js";import{buildWaferMap as Un,getTestPassStatus as $n,isParametricTest as cn}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as qn}from"../stats/analyzeWaferMap.js";import{CLR as q,Z_BASE as Jn,applyOverlayZ as ei,getTooltip as pn,hideTooltip as $e,reparentTooltip as ti,positionTooltip as xt,createToolbarHelpers as ni,buildModeMenuEl as ii,openReparentedModal as oi,openUserGuideWindow as ai,makePaletteBtn as si,makeLogScaleBtn as li,makeLegendStyleBtn as ri,makeOverlaysBtn as di,makeOrientationBtn as ci,overlayRootFor as pi,saveImageBlob as fi,markMenuTrigger as qe,wireMenuA11y as ui,nextFrame as wt,passFailMenuRows as hi,requestedPassFailDisplay as Mt,logWmapVersionOnce as gi,buildDataModeEntries as mi,metadataKeyHasData as yi,metadataModeEntry as vi}from"./toolbar.js";import{createSummaryPanelEl as St,wrapWithSummaryPanel as Ct,renderWaferSummaryContent as bi}from"./summaryPanel.js";import"../stats/facets.js";import{ICONS as fn}from"./icons.js";import{hardBinColor as xi,softBinColor as wi,metadataValueColor as Mi}from"../renderer/colorMap.js";import{createInsightsTab as Si}from"./insightsTab.js";import{createMetadataBadge as Ci}from"./metadataBadge.js";import{getDieKey as Me}from"../core/dies.js";const un=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode"]);export function classifyChanged(z){const w=z.some(R=>un.has(R)),M=z.some(R=>!un.has(R));return w&&M?"mixed":w?"preference":"state"}export function renderWaferMap(z,w,M={}){gi();const R=z.ownerDocument,_=R.defaultView??window;_.getComputedStyle(z).position==="static"&&(z.style.position="relative");const hn=z.clientHeight;M.height!=null&&(z.style.height=typeof M.height=="number"?`${M.height}px`:M.height);const J=document.createElement("div");Object.assign(J.style,{position:"relative",width:"100%",height:"100%"}),M.maxSize!=null&&(J.style.maxWidth=`${M.maxSize}px`,J.style.maxHeight=`${M.maxSize}px`),z.appendChild(J);const x=document.createElement("div");Object.assign(x.style,{position:"relative",width:"100%",height:"100%"});const a=document.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),x.appendChild(a),J.appendChild(x);const{onHover:Ye,onClick:gn,onSelect:oe,onViewOptionsChange:mn,showTooltip:yn=!0,showToolbar:fe=!0,showMetadataBadge:vn=!0,toolbarControls:Et="full",showPlotModeSelector:bn=!0,minZoom:xn=.4,maxZoom:wn=20,summaryPanel:Se,renderTooltip:Bt,passBins:kt=[1],showHelpButton:Mn=!1,userGuideExtension:Sn,onExpand:Dt,showExpandButton:Lt=!0,zIndex:Cn,insights:Pt,viewOptions:En={},...ae}=M,Bn=Pt?.enabled??!1,kn=ei(Cn);let Ce=ae.fallbackFormat,se=M.statsSummary,Je=w,ee=w.wafer,le=w.dies,S=new Set,Q=w.hbinDefs,j=w.sbinDefs,U=w.testDefs,Ee=w.metadataFields,Tt=w.reticles?.length?w.reticles:void 0,Ot=w.reticleConfig,Rt=w.view?.dataAxisFlip,et=w.isLotStack,tt=w.aggrMethod,nt=w.lotSize,It=!1,k=null;vn&&(k=Ci(ee.metadata,{lotStack:At()}),k.isEmpty()||x.appendChild(k.el));function At(){return et?{lotSize:nt??1,aggrMethod:tt}:void 0}function Dn(){if(!k)return;k.update(ee.metadata,At());const e=k.el.isConnected;k.isEmpty()&&e?k.el.remove():!k.isEmpty()&&!e&&x.appendChild(k.el)}const Ft=[...Q??[],...j??[]].some(e=>e.color);let s={plotMode:"hardBin",colorScheme:Ft?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:ae.legendPosition??"default",...En},te=null,ue=!1;Bn&&(te=Si({getItems:()=>[{wafer:ee,dies:le,hbinDefs:Q,sbinDefs:j,testDefs:U,label:String(ee.metadata?.waferId??""),statsSummary:se}],getColorSchemeName:()=>s.colorScheme??"default",passBins:kt,getRingCount:()=>s.ringCount??4,onSaveImage:M.onSaveImage,onSaveText:M.onSaveText,defaultView:Pt?.defaultView,backTab:{label:"Map",onBack:()=>it(!1)}}),Object.assign(te.el.style,{position:"absolute",inset:"0",background:q.panelBg,overflowY:"auto",paddingTop:fe?"44px":"0"}),J.appendChild(te.el));function it(e){te&&(ue=e,te.el.style.display=e?"flex":"none",F&&(F.style.display=e?"none":"flex"),E&&(E.style.display=e?"none":"flex"),G&&(G.style.display=e?"none":"flex"),k&&(k.el.style.display=e||It?"none":""),Ne(),Y&&(Y.innerHTML=e?fn.wafer:fn.analysis,Y.ariaLabel=e?"Back to wafer view":"Insights"),e&&te.render())}let h,Yt,I=null,D=null,ot=[],Be=null,at=ae.legendOffset??{x:0,y:0},ke=!1,he=!1,De={x:0,y:0},st={x:0,y:0},re=!1,ge=!1,H="pan",me={x:0,y:0},He={x:0,y:0},L={x:0,y:0},P={x:0,y:0},Le=!1,ye=!1;function Pe(){const e=s;h=Vn(ee,le,{plotMode:e.plotMode,colorScheme:e.colorScheme,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:Tt,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:U,valueRange:e.valueRange,logScale:e.logScale,isLotStack:et,aggregationMethod:tt??e.aggregationMethod,lotSize:nt??e.lotSize,dataAxisFlip:Rt,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:Ce,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:Q,sbinDefs:j,metadataFields:Ee}),Yt=new Map(h.dies.map((t,n)=>[Me(t),n]))}Pe();let X=null,de=null,Xe=null,Ln={},T=null,$=null;function Pn(e){const{kind:t,index:n}=e.variable;v(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),v({highlightBin:i.bin})):(i.kind==="region"||i.kind==="dies")&&ft(i.dieKeys)}function Ht(e){bi(e,{wafer:ee,dies:le,yieldSummary:Je.yield,dataCoverage:Je.dataCoverage,hbinDefs:Q,sbinDefs:j,testDefs:U,statsSummary:se,passBins:kt,ringCount:s.ringCount??4,colorScheme:s.colorScheme,fallbackFormat:Ce,activeFindingId:Xe,findingsFilter:Ln,onFindingsFilterChange:ce,onSaveText:M.onSaveText,onFindingClick:(t,n)=>{Xe===t.id?(Xe=null,ft([]),v({highlightBin:void 0})):(Xe=t.id,Pn(t)),ce()}})}function ce(){X&&Ht(X)}function We(){T&&Ht(T)}function Xt(e,t){fe&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(Se?.placement){const e=Se.placement;X=St(e),Xt(X,e);const t=x.parentElement,n=x.nextSibling;de=Ct(x,X,e),t?.insertBefore(de,n),ce()}else if(se){const e=Se?.defaultOpen??!fe;T=St("right"),Xt(T,"right"),T.style.display=e?"block":"none";const t=x.parentElement,n=x.nextSibling;$=Ct(x,T,"right"),t?.insertBefore($,n),We()}const m=yn?pn(R):null;let C=null,A=null,F=null,E=null,ze=null,O=null,G=null,Ke=null,Y=null;const Tn=24;let ve=null,lt=null,Wt=null,rt=null,dt=null,ct=null,pt=null;function ft(e){S=new Set(e??[]),oe&&oe(mt()),y()}function Ne(){if(!O)return;const e=!!(X??T);O.style.display=se&&e&&!ue?"flex":"none";const t=X??T,n=t?t.style.display!=="none":!1;se?.hasNotableFindings&&!n?O.style.color=q.findingIndicator:O.dataset.active||(O.style.color=q.icon)}if(fe){let ne=function(Z){H=Z,i(K,Z==="zoom"),i(Oe,Z==="pan"),ze&&i(ze,Z==="select"),a.style.cursor=Z==="pan"?"grab":"crosshair"},Ge=function(){ve&&(clearTimeout(ve),ve=null),C&&(C.style.opacity="1")},Ze=function(){ve=setTimeout(()=>{C&&(C.style.opacity="0.35")},600)};C=document.createElement("div"),C.dataset.wmapToolbar="single",Object.assign(C.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",background:q.menuBg,border:`1px solid ${q.menuBorder}`,borderRadius:"4px",boxShadow:"0 1px 4px rgba(0,0,0,0.12)",zIndex:Jn,opacity:"0.35",transition:"opacity 0.2s ease",pointerEvents:"auto"});const e=pn(R),t=ni(e),{makeBtn:n,setActive:i,makeSep:o,makeMenuRow:f,makeMenuSection:g,makeDropdown:l,makeCheckMenuBtn:p,closeOpenMenu:d,getOpenMenu:r,setOpenMenu:u}=t;lt=d,Wt=r,R.addEventListener("click",d,!0),F=document.createElement("div"),Object.assign(F.style,{display:"flex",alignItems:"center",gap:"0"}),C.appendChild(F);const we=n("download","Download PNG",In);F.appendChild(we),F.appendChild(o());const K=n("zoomMode","Zoom (drag to zoom region)",()=>ne("zoom")),ie=n("zoomIn","Zoom in",()=>xe(a.clientWidth/2,a.clientHeight/2,1.2)),B=n("zoomOut","Zoom out",()=>xe(a.clientWidth/2,a.clientHeight/2,1/1.2)),N=n("reset","Reset zoom (double-click)",()=>_e());F.appendChild(K),F.appendChild(ie),F.appendChild(B),F.appendChild(N),F.appendChild(o());const Oe=n("pan","Pan (drag to move)",()=>ne("pan"));if(F.appendChild(Oe),ze=n("boxSelect","Select (drag to select dies)",()=>ne("select")),F.appendChild(ze),i(Oe,!0),Et!=="view-only"){let Z=function(c){return c.plotMode!==(s.plotMode??"hardBin")?!1:c.plotMode==="value"?(s.activeTest??0)===(c.activeTest??0):c.plotMode==="metadata"?s.activeMetadataKey===c.activeMetadataKey:!0},Re=function(c,b){c.activeTest!==void 0?v({plotMode:c.plotMode,activeTest:c.activeTest,activeMetadataKey:void 0,logScale:c.logScale}):c.activeMetadataKey!==void 0?v({plotMode:c.plotMode,activeTest:void 0,activeMetadataKey:c.activeMetadataKey,passFailDisplay:"off"}):v({plotMode:c.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),b.remove(),u(null),qe(V,!1)};A=document.createElement("div"),Object.assign(A.style,{display:"flex",alignItems:"center",gap:"0"}),C.appendChild(A),E=document.createElement("div"),Object.assign(E.style,{display:"flex",alignItems:"center",gap:"0"}),A.appendChild(E),E.appendChild(o());const Qe=()=>{const c=r();c&&(c.remove(),u(null)),qe(V,!1)},V=n("mode","Plot mode",()=>{if(r()){Qe();return}const c=h.dies,b=h.testDefs,{testEntries:Ue,binEntries:pe,stackedEntries:Ie}=mi(c,b,{includeStacked:h.isLotStack}),yt=(Ee??[]).filter(Fe=>yi(c,Fe.key)).map(vi),Ae=ii(V.getBoundingClientRect(),Ue,pe,Ie,Z,Re,{makeMenuRow:f,makeMenuSection:g},s.plotMode??"hardBin",V.ownerDocument.defaultView??window,yt);pi(V).appendChild(Ae),u(Ae),qe(V,!0),ui(Ae,V,Qe)});qe(V,!1);const{btn:An,sync:Fn}=si(t,()=>s.plotMode??"hardBin",()=>s.colorScheme??"default",()=>Ft,c=>v({colorScheme:c}));dt=Fn,dt();const Yn=di(t,()=>{const c=!!h.hasReticle,b=(s.plotMode??"hardBin")==="value",{testNumber:Ue}=bt(s.activeTest??0,h.testDefs),pe=vt(h.testDefs,Ue),Ie=b&&pe!==void 0&&!cn(pe),yt=b&&!Ie&&(pe?.limitLow!==void 0||pe?.limitHigh!==void 0),Ae=b&&!Ie&&h.dies.some(Fe=>$n(Fe,Ue,pe)!==void 0);return[{label:"Ring boundaries",active:!!s.showRingBoundaries,onClick:()=>v({showRingBoundaries:!s.showRingBoundaries})},{label:"Quadrant lines",active:!!s.showQuadrantBoundaries,onClick:()=>v({showQuadrantBoundaries:!s.showQuadrantBoundaries})},{label:"Die labels",active:!!s.showDieLabels,onClick:()=>v({showDieLabels:!s.showDieLabels})},{label:"Reticle grid",active:!!s.showReticle,enabled:c,onClick:()=>v({showReticle:!s.showReticle})},{label:"XY indicator",active:!!s.showXYIndicator,onClick:()=>v({showXYIndicator:!s.showXYIndicator})},...hi({functionalActive:Ie,hasLimits:yt,hasRecorded:Ae,display:Mt(s)},Fe=>v({passFailDisplay:Fe}))]},()=>!!(s.showRingBoundaries||s.showQuadrantBoundaries||s.showDieLabels||s.showReticle||s.showXYIndicator||Mt(s)!=="off")),{btn:Hn,sync:Xn}=ri(t,()=>s,c=>v({legendPosition:c}));rt=Xn,rt();const rn=()=>{const{testNumber:c}=bt(s.activeTest??0,U),b=vt(U,c);return b!==void 0&&!cn(b)},{btn:Wn,sync:zn}=li(t,()=>({...s,functionalActive:rn()}),c=>v(c));ct=zn,ct();const Kn=()=>{const{testNumber:c}=bt(s.activeTest??0,U),b=vt(U,c);return b!==void 0&&(b.limitLow!==void 0||b.limitHigh!==void 0)},je=n("specRange","Colorbar range: spec limits",()=>{const c=s.colorbarRangeMode==="data"?"spec":"data";v({colorbarRangeMode:c})});pt=()=>{const c=s.plotMode==="value"&&Kn()&&Mt(s)==="off"&&!rn();je.style.display=c?"":"none";const b=(s.colorbarRangeMode??"spec")==="spec";i(je,b),je.ariaLabel=b?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},pt();const Nn=ci(t,()=>s,c=>v(c));bn&&E.appendChild(V),E.appendChild(An),E.appendChild(Wn),E.appendChild(je),E.appendChild(o()),E.appendChild(Yn),E.appendChild(o()),E.appendChild(Hn),E.appendChild(o()),E.appendChild(Nn),se&&(O=n("findings","Summary panel",()=>{const c=X??T;if(!c)return;const b=c.style.display!=="none";c.style.display=b?"none":"block",i(O,!b),Ne()}),A.appendChild(o()),A.appendChild(O),T?.style.display!=="none"&&i(O,!0),Ne()),Lt&&(A.appendChild(o()),G=n("expand","Expand (E)",Dt??zt),A.appendChild(G)),te&&(A.appendChild(o()),Y=n("analysis","Insights",()=>{it(!ue),i(Y,ue)}),A.appendChild(Y)),Mn&&(A.appendChild(o()),Ke=n("help","User guide",()=>ln()),A.appendChild(Ke))}J.appendChild(C),a.addEventListener("mouseenter",Ge),a.addEventListener("mouseleave",Ze),C.addEventListener("mouseenter",Ge),C.addEventListener("mouseleave",Ze)}let be=null;function zt(){be&&(be.close(),be=null);const e=de??$??x;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=oi(C?[e,C]:[e],{ownerDocument:R,onClosed:()=>{be=null,G&&(G.style.display="flex"),a.focus({preventScroll:!0})}});t&&(C&&(t.contentWrap.style.position="relative"),be=t,G&&(G.style.display="none"))}function Kt(e){const t=s.plotMode;if(s={...s,...e},e.plotMode!==void 0&&e.plotMode!==t){I=null;const o=s.plotMode;(o==="hardBin"||o==="softBin")&&!new Set(["default","accessible","custom"]).has(s.colorScheme??"")&&(s={...s,colorScheme:"default"})}Object.keys(e).every(o=>o==="legendPosition")||Pe(),rt?.(),dt?.(),ct?.(),pt?.(),y();const i=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||i)&&(ce(),We())}function v(e){Kt(e);const t=Object.keys(e);mn?.(s,t,classifyChanged(t))}let ut=!1;function ht(){ut||(ut=!0,wt(()=>{ut=!1,y()},_))}function y(){const e=D??void 0,t=h.dies[0],n=t?{x:t.width,y:t.height}:ae.diePitchMm,i=Math.floor(a.clientWidth||a.width),o=!!(Q?.length||j?.length||h.dies.some(r=>r.hbin!=null||r.sbin!=null)),f=s.legendPosition??"default",g=f==="default"||f==="compact",l=(ae.colorbarWidth??16)+28,p=o&&g?f!=="default"?Math.max(dn,l):i<jn?0:i<Qn?Math.max(Zn,l):Math.max(dn,l):void 0,d=Gn(a,h,{...ae,topClearance:fe?Tn:0,minRightReserve:p,legendPosition:f,legendOffset:at,diePitchMm:n,fallbackFormat:Ce,showAxes:ae.showAxes??D!==null,viewport:e,activeBin:s.plotMode==="metadata"?s.highlightMetadataValue:s.highlightBin,hbinDefs:Q,sbinDefs:j,metadataFields:Ee});ot=d.binLegendRows,Be=d.legendBox??null,I||(I=d.viewport),S.size>0&&On(),ge&&Rn()}function On(){const e=W();if(!e)return;const t=a.getContext("2d"),n=h.hoverPoints,i=h.rectangles[0],o=i?i.width/2*e.ppm:e.ppm*.5,f=i?i.height/2*e.ppm:e.ppm*.5,g=Math.max(1,Math.min(3,o*.08)),l=o-g,p=f-g,d=[];for(const r of S){const u=Yt.get(r);u!==void 0&&d.push({sx:e.originX+n[u].x*e.ppm,sy:e.originY-n[u].y*e.ppm})}if(d.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:r,sy:u}of d)t.rect(r-l,u-p,l*2,p*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:r,sy:u}of d)t.rect(r-l,u-p,l*2,p*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:r,sy:u}of d)t.rect(r-l,u-p,l*2,p*2);t.stroke(),t.restore()}}function Rn(){const e=a.getContext("2d"),t=Math.min(L.x,P.x),n=Math.min(L.y,P.y),i=Math.abs(P.x-L.x),o=Math.abs(P.y-L.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 In(){a.toBlob(e=>{e&&fi(e,M.downloadFilename??"wafermap",M.onSaveImage)})}function Nt(e){return I?Math.max(I.ppm*xn,Math.min(I.ppm*wn,e)):e}function xe(e,t,n){const i=D??I;if(!i)return;const o=Nt(i.ppm*n),f=o/i.ppm,g=e-(e-i.originX)*f,l=t-(t-i.originY)*f,p=(I?.snapDist??1)/(o/(I?.ppm??o));D={originX:g,originY:l,ppm:o,snapDist:p},y()}function W(){return D??I}function Vt(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;xe(e.clientX-t.left,e.clientY-t.top,n)}else if(D!==null){e.preventDefault();const t=W(),n=D.snapDist;D={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},y()}}function _t(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function Gt(e){if(e.button!==0||!W())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(Be&&s.legendPosition==="floating"&&_t(n,i,Be)){he=!0,De={x:n,y:i},st={...at};return}if(Le&&H!=="pan"){ye=!0,re=!0,me={x:n,y:i},He={x:W().originX,y:W().originY},a.style.cursor="grabbing";return}if(H==="zoom"||H==="select"){ge=!0,L=P={x:n,y:i};return}re=!0,me={x:n,y:i},He={x:W().originX,y:W().originY},a.style.cursor="grabbing"}function Zt(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top;if(ge){P={x:n,y:i},ht();return}if(he){const r=n-De.x,u=i-De.y;r*r+u*u>16&&(he=!1,ke=!0,a.style.cursor="grabbing")}if(ke){at={x:st.x+(n-De.x),y:st.y+(i-De.y)},ht();return}if(re){const r=W(),u=D?.snapDist??I?.snapDist??1;D={originX:He.x+(n-me.x),originY:He.y+(i-me.y),ppm:r.ppm,snapDist:u},ht();return}const o=W();if(!o)return;const f=(n-o.originX)/o.ppm,g=(o.originY-i)/o.ppm,p=$t(f,g,o.snapDist)?.die??null,d=ot.find(r=>n>=r.x&&n<r.x+r.w&&i>=r.y&&i<r.y+r.h);if(d){a.style.cursor="pointer",m&&(m.innerHTML=d.label??`Bin ${d.bin}`,m.style.display="block",xt(m,a,e.clientX,e.clientY)),Ye?.(null,e);return}if(H==="pan"&&(a.style.cursor=p?"crosshair":"grab"),m)if(p)if(Bt){const r=Bt(p);r===null?m.style.display="none":(typeof r=="string"?m.innerHTML=r:(m.innerHTML="",m.appendChild(r)),m.style.display="block",xt(m,a,e.clientX,e.clientY))}else m.innerHTML=_n(p,h.plotMode,{testDefs:U,hbinDefs:Q,sbinDefs:j,fallbackFormat:Ce,aggrMethod:h.aggrMethod,lotSize:h.lotSize,waferMeta:ee.metadata,activeTest:h.activeTest,reticleConfig:Ot}),m.style.display="block",xt(m,a,e.clientX,e.clientY);else m.style.display="none";Ye?.(p,e)}function Qt(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,i=e.clientY-t.top,o=e.ctrlKey||e.metaKey;if(m&&(n<0||i<0||n>t.width||i>t.height)&&(m.style.display="none"),ge){ge=!1,P={x:n,y:i};const l=n-L.x,p=i-L.y,d=W();if(H==="zoom"){if(l*l+p*p<25)xe(n,i,2);else if(d){const r=Math.min(L.x,P.x),u=Math.max(L.x,P.x),ne=Math.min(L.y,P.y),we=Math.max(L.y,P.y),K=u-r,ie=we-ne;if(K>4&&ie>4){const B=a.clientWidth,N=a.clientHeight,Oe=B/K,Ge=N/ie,Ze=Math.min(Oe,Ge),Z=Nt(d.ppm*Ze),Re=Z/d.ppm,Qe=(r+u)/2,V=(ne+we)/2;D={originX:B/2-(Qe-d.originX)*Re,originY:N/2-(V-d.originY)*Re,ppm:Z,snapDist:d.snapDist/Re}}}y(),a.style.cursor="crosshair";return}if(l*l+p*p<25)gt(n,i,o,e);else if(d){const r=(Math.min(L.x,P.x)-d.originX)/d.ppm,u=(Math.max(L.x,P.x)-d.originX)/d.ppm,ne=(d.originY-Math.max(L.y,P.y))/d.ppm,we=(d.originY-Math.min(L.y,P.y))/d.ppm,K=h.hoverPoints,ie=[];for(let B=0;B<K.length;B++)if(K[B].x>=r&&K[B].x<=u&&K[B].y>=ne&&K[B].y<=we){const N=h.dies[B];N&&ie.push(N)}if(o)for(const B of ie){const N=Me(B);S.has(N)?S.delete(N):S.add(N)}else S=new Set(ie.map(B=>Me(B)));oe?.(mt())}y(),a.style.cursor="crosshair";return}if(he){he=!1,gt(n,i,o,e);return}if(ke){ke=!1,a.style.cursor="grab";return}if(!re)return;if(re=!1,ye){ye=!1,a.style.cursor=Le||H==="pan"?"grab":"crosshair";return}a.style.cursor=H==="pan"?"grab":"crosshair";const f=n-me.x,g=i-me.y;f*f+g*g<25&>(n,i,o,e)}function gt(e,t,n,i){for(const l of ot)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const p=s.highlightBin===l.bin?void 0:l.bin;v({highlightBin:p})}else{const p=s.highlightMetadataValue===l.bin?void 0:l.bin;v({highlightMetadataValue:p})}return}if(Be&&_t(e,t,Be))return;const o=W();if(!o)return;const g=$t((e-o.originX)/o.ppm,(o.originY-t)/o.ppm,o.snapDist)?.die??null;if(g){gn?.(g,i);const l=Me(g);n?S.has(l)?S.delete(l):S.add(l):S=new Set([l]),oe?.(mt()),y()}else n||(S=new Set,oe?.([]),y())}function mt(){const e=[],t=h.hoverPoints;for(let n=0;n<t.length;n++){const i=h.dies[n];i&&S.has(Me(i))&&e.push(i)}return e}function jt(){m&&$e(R),Ye?.(null,new MouseEvent("mouseleave")),a.style.cursor=H==="pan"?"grab":"crosshair"}function Ut(){re=!1,ye=!1,ge=!1,he=!1,ke=!1,m&&$e(R),Ye?.(null,new MouseEvent("mouseleave")),a.style.cursor=H==="pan"?"grab":"crosshair",y()}function $t(e,t,n){const i=h.hoverPoints,o=h.rectangles;for(let p=0;p<o.length;p++){const d=o[p];if(Math.abs(e-d.x)<=d.width/2&&Math.abs(t-d.y)<=d.height/2){const r=h.dies[p];return r?{die:r,index:p}:null}}let f=null,g=-1,l=n*n;for(let p=0;p<i.length;p++){const d=i[p].x-e,r=i[p].y-t,u=d*d+r*r;u<l&&(l=u,f=h.dies[p]??null,g=p)}return f?{die:f,index:g}:null}const qt=new _.ResizeObserver(()=>{I=null,D=null,y()});qt.observe(a),M.height==null&&hn<=0&&wt(()=>wt(()=>{z.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 Te=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`);const Ve=()=>{Te.removeEventListener("change",Ve),Te=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`),Te.addEventListener("change",Ve),y()};Te.addEventListener("change",Ve);const Jt=_.matchMedia("(prefers-color-scheme: dark)"),en=()=>y();Jt.addEventListener("change",en);const tn=()=>{m&&$e(R)};_.addEventListener("blur",tn);function nn(e){if(e.key==="Escape"&&S.size>0&&(S=new Set,oe?.([]),y()),(e.key==="e"||e.key==="E")&&Et!=="view-only"&&Lt&&!ue&&(e.stopPropagation(),(Dt??zt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),xe(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),xe(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),_e())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=W();if(n){const i=D?.snapDist??I?.snapDist??1;let o=0,f=0;e.key==="ArrowLeft"&&(o=20,e.preventDefault()),e.key==="ArrowRight"&&(o=-20,e.preventDefault()),e.key==="ArrowUp"&&(f=20,e.preventDefault()),e.key==="ArrowDown"&&(f=-20,e.preventDefault()),(o||f)&&(D={originX:n.originX+o,originY:n.originY+f,ppm:n.ppm,snapDist:i},y())}e.key===" "&&!Le&&(e.preventDefault(),Le=!0,H!=="pan"&&(a.style.cursor="grab"))}}function on(e){e.key===" "&&(Le=!1,ye&&(re=!1,ye=!1),a.style.cursor=H==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",Vt,{passive:!1}),a.addEventListener("pointerdown",Gt),a.addEventListener("pointermove",Zt),a.addEventListener("pointerup",Qt),a.addEventListener("pointerleave",jt),a.addEventListener("pointercancel",Ut);const an=()=>_e();a.addEventListener("dblclick",an),a.addEventListener("keydown",nn),a.addEventListener("keyup",on);const sn=e=>{e.stopPropagation()};a.addEventListener("click",sn),a.clientWidth,y();function _e(){I=null,D=null,y()}function ln(){import("./userGuideHtml.js").then(e=>ai({buildWaferMap:Un,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:qn},e.USER_GUIDE_HTML,Sn,z))}return{setDies(e){le=e,Pe(),y(),X&&ce()},setResult(e){Je=e,ee=e.wafer,le=e.dies,Q=e.hbinDefs,j=e.sbinDefs,U=e.testDefs,Ee=e.metadataFields,Tt=e.reticles?.length?e.reticles:void 0,Ot=e.reticleConfig,Rt=e.view?.dataAxisFlip,et=e.isLotStack,tt=e.aggrMethod,nt=e.lotSize,Dn(),Pe(),y(),X&&ce()},setOptions(e){Kt(e)},getOptions(){return{...s}},resetZoom:_e,setSelection(e){S=new Set(e.map(t=>Me(t))),y()},clearSelection(){S=new Set,oe?.([]),y()},setFallbackFormat(e){Ce=e,Pe(),y()},setStatsSummary(e){if(se=e,X)ce();else if(T)We();else if(e&&!Se?.placement){const t=Se?.defaultOpen??!fe;T=St("right"),T.style.display=t?"block":"none";const n=x.parentElement,i=x.nextSibling;$=Ct(x,T,"right"),n?.insertBefore($,i),We()}Ne()},setSummaryVisible(e){O&&(O.style.display=e?"flex":"none")},setViewControlsVisible(e){A&&(A.style.display=e?"flex":"none")},setExpandVisible(e){G&&(G.style.display=e?"flex":"none")},setHelpButtonVisible(e){Ke&&(Ke.style.display=e?"flex":"none")},setMetadataBadgeVisible(e){It=!e,k&&(k.el.style.display=e&&!ue?"":"none")},openUserGuide:ln,setInsightsOpen(e){it(e),Y&&(e?(Y.dataset.active="1",Y.style.background=q.bgActive,Y.style.color=q.iconActive):(delete Y.dataset.active,Y.style.background="transparent",Y.style.color=q.icon))},closeSummaryPanel(){const e=X??T;!e||e.style.display==="none"||(e.style.display="none",O&&(delete O.dataset.active,O.style.background="transparent",O.style.color=q.icon))},setTooltipParent(e){m&&ti(e)},getActiveLegend(){const e=s.plotMode;if(e==="metadata"){const o=s.activeMetadataKey;if(!o)return null;const f=Ee?.find(l=>l.key===o),g=[...new Set(le.map(l=>l.metadata?.[o]).filter(l=>l!=null&&(typeof l=="string"||typeof l=="number"||typeof l=="boolean")).map(String))].sort();return g.length?g.map((l,p)=>{const d=f?.values?.find(u=>u.value===l),r=d?.color??Mi(p);return{bin:l,name:d?.label??l,color:r}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?Q:j,i=[...new Set(le.map(o=>t?o.hbin:o.sbin).filter(o=>o!==void 0))].sort((o,f)=>o-f);return i.length?i.map(o=>{const f=n?.find(l=>l.bin===o),g=f?.color??(t?xi(o):wi(o));return{bin:o,name:f?.name??`Bin ${o}`,color:g}}):null},destroy(){be?.close(),ve&&clearTimeout(ve),Wt?.()?.remove(),lt&&R.removeEventListener("click",lt,!0),a.removeEventListener("wheel",Vt),a.removeEventListener("pointerdown",Gt),a.removeEventListener("pointermove",Zt),a.removeEventListener("pointerup",Qt),a.removeEventListener("pointerleave",jt),a.removeEventListener("pointercancel",Ut),a.removeEventListener("dblclick",an),a.removeEventListener("keydown",nn),a.removeEventListener("keyup",on),a.removeEventListener("click",sn),qt.disconnect(),Te.removeEventListener("change",Ve),Jt.removeEventListener("change",en),_.removeEventListener("blur",tn),kn(),m&&$e(R),C?.remove(),de&&(de.parentElement?.insertBefore(x,de),de.remove()),$&&($.parentElement?.insertBefore(x,$),$.remove()),x.remove(),a.style.cursor="",te?.destroy(),k?.destroy(),J.remove()}}}
|
|
1
|
+
import{buildView as oi,buildHoverText as ai,findTestDef as it,resolveTestNumber as Et}from"../renderer/buildView.js";import{toCanvas as li,BIN_LEGEND_W as wn,BIN_LEGEND_W_COMPACT as si,BIN_LEGEND_ADAPT_COMPACT as ri,BIN_LEGEND_ADAPT_FLOATING as di}from"./toCanvas.js";import{buildWaferMap as ci,getTestPassStatus as pi,isParametricTest as Bt}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as fi}from"../stats/analyzeWaferMap.js";import{CLR as x,Z_BASE as ui,applyOverlayZ as gi,getTooltip as Sn,hideTooltip as ot,reparentTooltip as hi,positionTooltip as Dt,createToolbarHelpers as mi,buildModeMenuEl as yi,openReparentedModal as bi,openUserGuideWindow as vi,makePaletteBtn as xi,makeLogScaleBtn as wi,makeLegendStyleBtn as Si,makeOverlaysBtn as Ci,makeOrientationBtn as Mi,overlayRootFor as Cn,saveImageBlob as Ei,markMenuTrigger as Ye,wireMenuA11y as Mn,wireExpandToggle as Bi,nextFrame as kt,passFailMenuRows as Di,requestedPassFailDisplay as Lt,logWmapVersionOnce as ki,buildDataModeEntries as Li,metadataKeyHasData as Ti,metadataModeEntry as Pi}from"./toolbar.js";import{createSummaryPanelEl as Tt,wrapWithSummaryPanel as Pt,renderWaferSummaryContent as Oi}from"./summaryPanel.js";import{collectWarnings as Ri,buildWarningsMenuEl as Ii,severityOf as Wi}from"./warnings.js";import"../stats/facets.js";import{ICONS as En}from"./icons.js";import{hardBinColor as Hi,softBinColor as Ai,metadataValueColor as Fi}from"../renderer/colorMap.js";import{createInsightsTab as Yi}from"./insightsTab.js";import{createMetadataBadge as zi}from"./metadataBadge.js";import{getDieKey as Me,hasPosition as Bn,isPositionedDie as Xi}from"../core/dies.js";import{buildDieListSection as Ni}from"./dieList.js";import{buildMaplessSummary as Ki}from"./maplessSummary.js";const Dn=new Set(["colorScheme","rotation","flipX","flipY","showDieLabels","showPartialDies","showRingBoundaries","showQuadrantBoundaries","showReticle","showXYIndicator","ringCount","legendPosition","logScale","colorbarRangeMode"]);export function classifyChanged(N){const h=N.some(W=>Dn.has(W)),C=N.some(W=>!Dn.has(W));return h&&C?"mixed":h?"preference":"state"}export function renderWaferMap(N,h,C={}){ki();const W=N.ownerDocument,_=W.defaultView??window;_.getComputedStyle(N).position==="static"&&(N.style.position="relative");const kn=N.clientHeight;C.height!=null&&(N.style.height=typeof C.height=="number"?`${C.height}px`:C.height);const at=h.dataCoverage?h.dataCoverage.unpositionedDies:h.dies.filter(e=>!Bn(e)).length,ze=(h.dataCoverage?h.dataCoverage.totalDies:h.dies.length-at)===0&&at>0,q=document.createElement("div");Object.assign(q.style,{position:"relative",width:"100%",height:"100%"}),C.maxSize!=null&&(q.style.maxWidth=`${C.maxSize}px`,q.style.maxHeight=`${C.maxSize}px`),N.appendChild(q);const w=document.createElement("div");Object.assign(w.style,{position:"relative",width:"100%",height:"100%"});const a=document.createElement("canvas");Object.assign(a.style,{width:"100%",height:"100%",display:"block"}),w.appendChild(a),q.appendChild(w);let Xe=null;if(at>0){let n=function(){if(t){const u=Ni(e,h.testDefs,{onSaveText:C.onSaveText});if(u)return u}const i=it(h.testDefs,s.activeTest??0),r=Bt(i)?s.logScale??i?.logScale??!1:!1;return Ki(e,h.testDefs,{plotMode:s.plotMode??"hardBin",activeTest:s.activeTest,hbinDefs:$,sbinDefs:G,colorScheme:s.colorScheme,logScale:r,colorbarRangeMode:s.colorbarRangeMode,valueRangeDies:h.dies})},o=function(i){const r=document.createElement("button");return r.type="button",Object.assign(r.style,{fontSize:"10px",padding:"2px 6px",borderRadius:"4px",flexShrink:"0",border:`1px solid ${x.menuBorder}`,background:x.menuBg,color:x.text,cursor:"pointer"}),r.textContent=t?"View chart":"View die list",r.addEventListener("click",u=>{u.stopPropagation(),t=!t,r.textContent=t?"View chart":"View die list",i()}),r};const e=h.dies.filter(i=>!Bn(i));let t=!1;if(ze){const i=document.createElement("div");Object.assign(i.style,{position:"absolute",inset:"0",background:x.panelBg,padding:"12px",paddingTop:C.showToolbar??!0?"44px":"12px",boxSizing:"border-box",overflow:"hidden",display:"flex",flexDirection:"column",gap:"8px",zIndex:"1"});const r=document.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"space-between",alignItems:"flex-start",gap:"8px"});const u=document.createElement("span");Object.assign(u.style,{fontSize:"11px",color:x.label,lineHeight:"1.4"}),u.textContent="No die position data for this wafer.",r.appendChild(u);const l=document.createElement("div");Object.assign(l.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),r.appendChild(o(()=>l.replaceChildren(n()))),i.appendChild(r),i.appendChild(l),w.appendChild(i),Xe=()=>{t||l.replaceChildren(n())}}else{const i=document.createElement("div");Object.assign(i.style,{position:"absolute",left:"0",right:"0",bottom:"0",zIndex:"3",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,fontSize:"11px",color:x.text,cursor:"pointer",padding:"4px 8px",display:"flex",alignItems:"center",justifyContent:"space-between",gap:"8px"});const r=document.createElement("span");r.textContent=`+${e.length} ${e.length===1?"die":"dies"} without position data`,i.appendChild(r);const u=document.createElement("span");u.textContent="\u25BE",Object.assign(u.style,{fontSize:"12px",lineHeight:"1",color:x.label,flexShrink:"0"}),i.appendChild(u),i.setAttribute("aria-expanded","false"),i.setAttribute("aria-label",`${e.length} dies without position data. Click to view.`);let l=null,d=null;Bi(i,c=>{if(u.textContent=c?"\u25B4":"\u25BE",i.setAttribute("aria-expanded",String(c)),c){l=document.createElement("div");const p=i.getBoundingClientRect().height||28;Object.assign(l.style,{position:"absolute",left:"0",right:"0",bottom:`${p}px`,top:"20%",zIndex:"2",background:x.panelBg,borderTop:`1px solid ${x.menuBorder}`,padding:"8px",boxSizing:"border-box",display:"flex",flexDirection:"column",gap:"8px"}),l.addEventListener("click",Q=>Q.stopPropagation());const g=document.createElement("div");Object.assign(g.style,{display:"flex",justifyContent:"flex-end"}),g.appendChild(o(()=>{d&&d.replaceChildren(n())})),l.appendChild(g),d=document.createElement("div"),Object.assign(d.style,{flex:"1",minHeight:"0",overflow:"auto",display:"flex",flexDirection:"column"}),d.appendChild(n()),l.appendChild(d),w.appendChild(l)}else l&&(l.remove(),l=null,d=null)}),w.appendChild(i),Xe=()=>{d&&!t&&d.replaceChildren(n())}}}const{onHover:Ne,onClick:Ln,onSelect:re,onViewOptionsChange:Tn,showTooltip:Pn=!0,showToolbar:ge=!0,showMetadataBadge:On=!0,toolbarControls:Ot="full",showPlotModeSelector:Rn=!0,minZoom:In=.4,maxZoom:Wn=20,summaryPanel:Ee,renderTooltip:Rt,passBins:It=[1],showHelpButton:Hn=!1,userGuideExtension:An,onExpand:Wt,showExpandButton:Ht=!0,zIndex:Fn,insights:At,warnings:Ft,viewOptions:Yn={},...de}=C,zn=At?.enabled??!1,Yt=Ft?.display??!0,Xn=gi(Fn);let Be=de.fallbackFormat,ne=C.statsSummary,ie=[],zt=!1;function Xt(){const e=Ri({result:h,statsSummary:ne}),t=e.length!==ie.length||e.some((n,o)=>n.code!==ie[o]?.code||n.message!==ie[o]?.message);ie=e,(t||!zt)&&(zt=!0,Ft?.onWarning?.(e))}Xt();let lt=h,oe=h.wafer,ae=h.dies,M=new Set,$=h.hbinDefs,G=h.sbinDefs,J=h.testDefs,De=h.metadataFields,Nt=h.reticles?.length?h.reticles:void 0,Kt=h.reticleConfig,Vt=h.view?.dataAxisFlip,st=h.isLotStack??!1,rt=h.aggrMethod,dt=h.lotSize,jt=!1,L=null;On&&(L=zi(oe.metadata,{lotStack:_t()}),L.isEmpty()||w.appendChild(L.el));function _t(){return st?{lotSize:dt??1,aggrMethod:rt}:void 0}function Nn(){if(!L)return;L.update(oe.metadata,_t());const e=L.el.isConnected;L.isEmpty()&&e?L.el.remove():!L.isEmpty()&&!e&&w.appendChild(L.el)}const $t=[...$??[],...G??[]].some(e=>e.color);let s={plotMode:"hardBin",colorScheme:$t?"custom":"default",showDieLabels:!1,showPartialDies:!0,showRingBoundaries:!1,showQuadrantBoundaries:!1,showReticle:!1,showXYIndicator:!1,ringCount:4,rotation:0,flipX:!1,flipY:!1,legendPosition:de.legendPosition??"default",...Yn},le=null,he=!1;zn&&(le=Yi({getItems:()=>[{wafer:oe,dies:ae,hbinDefs:$,sbinDefs:G,testDefs:J,label:String(oe.metadata?.waferId??""),statsSummary:ne}],getColorSchemeName:()=>s.colorScheme??"default",passBins:It,getRingCount:()=>s.ringCount??4,onSaveImage:C.onSaveImage,onSaveText:C.onSaveText,defaultView:At?.defaultView,backTab:{label:"Map",onBack:()=>ct(!1)}}),Object.assign(le.el.style,{position:"absolute",inset:"0",background:x.panelBg,overflowY:"auto",paddingTop:ge?"44px":"0"}),q.appendChild(le.el));function ct(e){le&&(he=e,le.el.style.display=e?"flex":"none",A&&(A.style.display=e||ze?"none":"flex"),D&&(D.style.display=e?"none":"flex"),Z&&(Z.style.display=e?"none":"flex"),L&&(L.el.style.display=e||jt?"none":""),Ze(),F&&(F.innerHTML=e?En.wafer:En.analysis,F.ariaLabel=e?"Back to wafer view":"Insights"),e&&le.render())}let m,Gt,H=null,T=null,pt=[],ke=null,ft=de.legendOffset??{x:0,y:0},Le=!1,me=!1,Te={x:0,y:0},ut={x:0,y:0},ce=!1,ye=!1,Y="pan",be={x:0,y:0},Ke={x:0,y:0},P={x:0,y:0},O={x:0,y:0},Pe=!1,ve=!1;function Oe(){const e=s;m=oi(oe,ae.filter(Xi),{plotMode:e.plotMode,colorScheme:e.colorScheme,showDieLabels:e.showDieLabels,showPartialDies:e.showPartialDies,showRingBoundaries:e.showRingBoundaries,showQuadrantBoundaries:e.showQuadrantBoundaries,showReticle:e.showReticle,showXYIndicator:e.showXYIndicator,reticles:Nt,ringCount:e.ringCount,highlightBin:e.highlightBin,highlightMetadataValue:e.highlightMetadataValue,activeTest:e.activeTest,activeMetadataKey:e.activeMetadataKey,testDefs:J,valueRange:e.valueRange,logScale:e.logScale,isLotStack:st,aggregationMethod:rt??e.aggregationMethod,lotSize:dt??e.lotSize,dataAxisFlip:Vt,colorbarRangeMode:e.colorbarRangeMode,passFailDisplay:e.passFailDisplay,fallbackFormat:Be,interactiveTransform:{rotation:e.rotation??0,flipX:e.flipX??!1,flipY:e.flipY??!1}},{hbinDefs:$,sbinDefs:G,metadataFields:De}),Gt=new Map(m.dies.map((t,n)=>[Me(t),n]))}Oe();let z=null,pe=null,Ve=null,Kn={},R=null,ee=null;function Vn(e){const{kind:t,index:n}=e.variable;S(t==="test"?{plotMode:"value",activeTest:n??0,highlightBin:void 0}:t==="softBin"?{plotMode:"softBin",highlightBin:void 0}:{plotMode:"hardBin",highlightBin:void 0});const o=e.highlight;o.kind==="bin"?(vt(o.dieKeys),S({highlightBin:o.bin})):(o.kind==="region"||o.kind==="dies")&&vt(o.dieKeys)}function Zt(e){Oi(e,{wafer:oe,dies:ae,yieldSummary:lt.yield,dataCoverage:lt.dataCoverage,hbinDefs:$,sbinDefs:G,testDefs:J,statsSummary:ne,warnings:Yt?ie:[],passBins:It,ringCount:s.ringCount??4,colorScheme:s.colorScheme,fallbackFormat:Be,activeFindingId:Ve,findingsFilter:Kn,onFindingsFilterChange:fe,onSaveText:C.onSaveText,onFindingClick:(t,n)=>{Ve===t.id?(Ve=null,vt([]),S({highlightBin:void 0})):(Ve=t.id,Vn(t)),fe()}})}function fe(){z&&Zt(z)}function je(){R&&Zt(R)}function Qt(e,t){ge&&(t==="right"||t==="top")&&(e.style.paddingTop="44px")}if(Ee?.placement){const e=Ee.placement;z=Tt(e),Qt(z,e);const t=w.parentElement,n=w.nextSibling;pe=Pt(w,z,e),t?.insertBefore(pe,n),fe()}else if(ne){const e=Ee?.defaultOpen??!ge;R=Tt("right"),Qt(R,"right"),R.style.display=e?"block":"none";const t=w.parentElement,n=w.nextSibling;ee=Pt(w,R,"right"),t?.insertBefore(ee,n),je()}const b=Pn?Sn(W):null;let E=null,B=null,A=null,D=null,_e=null,I=null,Z=null,$e=null,F=null,te=null,Ge=null;function Ut(){if(!te||!Ge)return;const e=ie.length,t=e>0;if(te.style.display=t?"flex":"none",Ge.style.display=t?"":"none",!t)return;const n=Wi(ie[0]),o=`${e} data ${e===1?"warning":"warnings"}`;te.style.color=n==="error"?x.errText:x.warnText,te.ariaLabel=n==="error"?`${o} \u2014 the map may be positionally wrong`:o}const jn=24;let xe=null,gt=null,qt=null,ht=null,mt=null,yt=null,bt=null;function vt(e){M=new Set(e??[]),re&&re(Ct()),v()}function Ze(){if(!I)return;const e=!!(z??R);I.style.display=ne&&e&&!he?"flex":"none";const t=z??R,n=t?t.style.display!=="none":!1;ne?.hasNotableFindings&&!n?I.style.color=x.findingIndicator:I.dataset.active||(I.style.color=x.icon)}if(ge){let Q=function(U){Y=U,o(K,U==="zoom"),o(Ie,U==="pan"),_e&&o(_e,U==="select"),a.style.cursor=U==="pan"?"grab":"crosshair"},qe=function(){xe&&(clearTimeout(xe),xe=null),E&&(E.style.opacity="1")},Je=function(){xe=setTimeout(()=>{E&&(E.style.opacity="0.35")},600)};E=document.createElement("div"),E.dataset.wmapToolbar="single",Object.assign(E.style,{position:"absolute",top:"4px",right:"4px",display:"flex",flexDirection:"row",alignItems:"center",flexWrap:"wrap-reverse",justifyContent:"flex-end",maxWidth:"calc(100% - 8px)",background:x.menuBg,border:`1px solid ${x.menuBorder}`,borderRadius:"4px",boxShadow:"0 1px 4px rgba(0,0,0,0.12)",zIndex:ui,opacity:"0.35",transition:"opacity 0.2s ease",pointerEvents:"auto"});const e=Sn(W),t=mi(e),{makeBtn:n,setActive:o,makeSep:i,makeMenuRow:r,makeMenuSection:u,makeDropdown:l,makeCheckMenuBtn:d,closeOpenMenu:c,getOpenMenu:p,setOpenMenu:g}=t;gt=c,qt=p,W.addEventListener("click",c,!0),A=document.createElement("div"),Object.assign(A.style,{display:ze?"none":"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(A);const Ce=n("download","Download PNG",Gn);A.appendChild(Ce),A.appendChild(i());const K=n("zoomMode","Zoom (drag to zoom region)",()=>Q("zoom")),se=n("zoomIn","Zoom in",()=>Se(a.clientWidth/2,a.clientHeight/2,1.2)),k=n("zoomOut","Zoom out",()=>Se(a.clientWidth/2,a.clientHeight/2,1/1.2)),V=n("reset","Reset zoom (double-click)",()=>Ue());A.appendChild(K),A.appendChild(se),A.appendChild(k),A.appendChild(V),A.appendChild(i());const Ie=n("pan","Pan (drag to move)",()=>Q("pan"));if(A.appendChild(Ie),_e=n("boxSelect","Select (drag to select dies)",()=>Q("select")),A.appendChild(_e),o(Ie,!0),Ot!=="view-only"){let U=function(f){return f.plotMode!==(s.plotMode??"hardBin")?!1:f.plotMode==="value"?(s.activeTest??0)===(f.activeTest??0):f.plotMode==="metadata"?s.activeMetadataKey===f.activeMetadataKey:!0},We=function(f,y){f.activeTest!==void 0?S({plotMode:f.plotMode,activeTest:f.activeTest,activeMetadataKey:void 0,logScale:f.logScale}):f.activeMetadataKey!==void 0?S({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:f.activeMetadataKey,passFailDisplay:"off"}):S({plotMode:f.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),y.remove(),g(null),Ye(j,!1)};B=document.createElement("div"),Object.assign(B.style,{display:"flex",alignItems:"center",gap:"0",flexWrap:"wrap",justifyContent:"flex-end"}),E.appendChild(B),D=document.createElement("div"),Object.assign(D.style,{display:"flex",alignItems:"center",gap:"0"}),B.appendChild(D),D.appendChild(i());const et=()=>{const f=p();f&&(f.remove(),g(null)),Ye(j,!1)},j=n("mode","Plot mode",()=>{if(p()){et();return}const f=ae,y=m.testDefs,{testEntries:nt,binEntries:ue,stackedEntries:He}=Li(f,y,{includeStacked:m.isLotStack}),Mt=(De??[]).filter(Fe=>Ti(f,Fe.key)).map(Pi),Ae=yi(j.getBoundingClientRect(),nt,ue,He,U,We,{makeMenuRow:r,makeMenuSection:u},s.plotMode??"hardBin",j.ownerDocument.defaultView??window,Mt);Cn(j).appendChild(Ae),g(Ae),Ye(j,!0),Mn(Ae,j,et)});Ye(j,!1);const{btn:Zn,sync:Qn}=xi(t,()=>s.plotMode??"hardBin",()=>s.colorScheme??"default",()=>$t,f=>S({colorScheme:f}));mt=Qn,mt();const Un=Ci(t,()=>{const f=!!m.hasReticle,y=(s.plotMode??"hardBin")==="value",{testNumber:nt}=Et(s.activeTest??0,m.testDefs),ue=it(m.testDefs,nt),He=y&&ue!==void 0&&!Bt(ue),Mt=y&&!He&&(ue?.limitLow!==void 0||ue?.limitHigh!==void 0),Ae=y&&!He&&m.dies.some(Fe=>pi(Fe,nt,ue)!==void 0);return[{label:"Ring boundaries",active:!!s.showRingBoundaries,onClick:()=>S({showRingBoundaries:!s.showRingBoundaries})},{label:"Quadrant lines",active:!!s.showQuadrantBoundaries,onClick:()=>S({showQuadrantBoundaries:!s.showQuadrantBoundaries})},{label:"Die labels",active:!!s.showDieLabels,onClick:()=>S({showDieLabels:!s.showDieLabels})},{label:"Reticle grid",active:!!s.showReticle,enabled:f,onClick:()=>S({showReticle:!s.showReticle})},{label:"XY indicator",active:!!s.showXYIndicator,onClick:()=>S({showXYIndicator:!s.showXYIndicator})},...Di({functionalActive:He,hasLimits:Mt,hasRecorded:Ae,display:Lt(s)},Fe=>S({passFailDisplay:Fe}))]},()=>!!(s.showRingBoundaries||s.showQuadrantBoundaries||s.showDieLabels||s.showReticle||s.showXYIndicator||Lt(s)!=="off")),{btn:qn,sync:Jn}=Si(t,()=>s,f=>S({legendPosition:f}));ht=Jn,ht();const xn=()=>{const{testNumber:f}=Et(s.activeTest??0,J),y=it(J,f);return y!==void 0&&!Bt(y)},{btn:ei,sync:ti}=wi(t,()=>({...s,functionalActive:xn()}),f=>S(f));yt=ti,yt();const ni=()=>{const{testNumber:f}=Et(s.activeTest??0,J),y=it(J,f);return y!==void 0&&(y.limitLow!==void 0||y.limitHigh!==void 0)},tt=n("specRange","Colorbar range: spec limits",()=>{const f=s.colorbarRangeMode==="data"?"spec":"data";S({colorbarRangeMode:f})});bt=()=>{const f=s.plotMode==="value"&&ni()&&Lt(s)==="off"&&!xn();tt.style.display=f?"":"none";const y=(s.colorbarRangeMode??"spec")==="spec";o(tt,y),tt.ariaLabel=y?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"},bt();const ii=Mi(t,()=>s,f=>S(f));Rn&&D.appendChild(j),D.appendChild(Zn),D.appendChild(ei),D.appendChild(tt),ze||(D.appendChild(i()),D.appendChild(Un),D.appendChild(i()),D.appendChild(qn),D.appendChild(i()),D.appendChild(ii)),ne&&(I=n("findings","Summary panel",()=>{const f=z??R;if(!f)return;const y=f.style.display!=="none";f.style.display=y?"none":"block",o(I,!y),Ze()}),B.appendChild(i()),B.appendChild(I),R?.style.display!=="none"&&o(I,!0),Ze()),Yt&&(Ge=i(),te=n("warning","Data warnings",()=>{const f=p();if(c(new MouseEvent("click")),f)return;const y=Ii(te.getBoundingClientRect(),ie);Cn(q).appendChild(y),g(y),Mn(y,te,()=>c(new MouseEvent("click")))}),Ye(te,!1),B.appendChild(Ge),B.appendChild(te),Ut()),Ht&&(B.appendChild(i()),Z=n("expand","Expand (E)",Wt??Jt),B.appendChild(Z)),le&&(B.appendChild(i()),F=n("analysis","Insights",()=>{ct(!he),o(F,he)}),B.appendChild(F)),Hn&&(B.appendChild(i()),$e=n("help","User guide",()=>vn()),B.appendChild($e))}q.appendChild(E),a.addEventListener("mouseenter",qe),a.addEventListener("mouseleave",Je),E.addEventListener("mouseenter",qe),E.addEventListener("mouseleave",Je)}let we=null;function Jt(){we&&(we.close(),we=null);const e=pe??ee??w;e.style.flex="1",e.style.minWidth="0",e.style.minHeight="0";const t=bi(E?[e,E]:[e],{ownerDocument:W,onClosed:()=>{we=null,Z&&(Z.style.display="flex"),a.focus({preventScroll:!0})}});t&&(E&&(t.contentWrap.style.position="relative"),we=t,Z&&(Z.style.display="none"))}function en(e){const t=s.plotMode;if(s={...s,...e},e.plotMode!==void 0&&e.plotMode!==t){H=null;const i=s.plotMode;(i==="hardBin"||i==="softBin")&&!new Set(["default","accessible","custom"]).has(s.colorScheme??"")&&(s={...s,colorScheme:"default"})}Object.keys(e).every(i=>i==="legendPosition")||Oe(),ht?.(),mt?.(),yt?.(),bt?.(),v();const o=e.plotMode!==void 0&&e.plotMode!==t;(e.colorScheme!==void 0||o)&&(fe(),je()),(e.colorScheme!==void 0||o||e.activeTest!==void 0||e.logScale!==void 0||e.colorbarRangeMode!==void 0)&&Xe?.()}function S(e){en(e);const t=Object.keys(e);Tn?.(s,t,classifyChanged(t))}let xt=!1;function wt(){xt||(xt=!0,kt(()=>{xt=!1,v()},_))}function v(){const e=T??void 0,t=m.dies[0],n=t?{x:t.width,y:t.height}:de.diePitchMm,o=Math.floor(a.clientWidth||a.width),i=!!($?.length||G?.length||m.dies.some(p=>p.hbin!=null||p.sbin!=null)),r=s.legendPosition??"default",u=r==="default"||r==="compact",l=(de.colorbarWidth??16)+28,d=i&&u?r!=="default"?Math.max(wn,l):o<di?0:o<ri?Math.max(si,l):Math.max(wn,l):void 0,c=li(a,m,{...de,topClearance:ge?jn:0,minRightReserve:d,legendPosition:r,legendOffset:ft,diePitchMm:n,fallbackFormat:Be,showAxes:de.showAxes??T!==null,viewport:e,activeBin:s.plotMode==="metadata"?s.highlightMetadataValue:s.highlightBin,hbinDefs:$,sbinDefs:G,metadataFields:De});pt=c.binLegendRows,ke=c.legendBox??null,H||(H=c.viewport),M.size>0&&_n(),ye&&$n()}function _n(){const e=X();if(!e)return;const t=a.getContext("2d"),n=m.hoverPoints,o=m.rectangles[0],i=o?o.width/2*e.ppm:e.ppm*.5,r=o?o.height/2*e.ppm:e.ppm*.5,u=Math.max(1,Math.min(3,i*.08)),l=i-u,d=r-u,c=[];for(const p of M){const g=Gt.get(p);g!==void 0&&c.push({sx:e.originX+n[g].x*e.ppm,sy:e.originY-n[g].y*e.ppm})}if(c.length){t.save(),t.setLineDash([]),t.fillStyle="rgba(0,0,0,0.12)",t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-l,g-d,l*2,d*2);t.fill(),t.strokeStyle="rgba(255,255,255,0.9)",t.lineWidth=3,t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-l,g-d,l*2,d*2);t.stroke(),t.strokeStyle="rgba(0,0,0,0.9)",t.lineWidth=1.5,t.beginPath();for(const{sx:p,sy:g}of c)t.rect(p-l,g-d,l*2,d*2);t.stroke(),t.restore()}}function $n(){const e=a.getContext("2d"),t=Math.min(P.x,O.x),n=Math.min(P.y,O.y),o=Math.abs(O.x-P.x),i=Math.abs(O.y-P.y);e.save(),e.fillStyle="rgba(0,0,0,0.08)",e.fillRect(t,n,o,i),e.setLineDash([5,3]),e.strokeStyle="rgba(255,255,255,0.9)",e.lineWidth=3,e.strokeRect(t,n,o,i),e.strokeStyle="rgba(0,0,0,0.9)",e.lineWidth=1.5,e.strokeRect(t,n,o,i),e.restore()}function Gn(){a.toBlob(e=>{e&&Ei(e,C.downloadFilename??"wafermap",C.onSaveImage)})}function tn(e){return H?Math.max(H.ppm*In,Math.min(H.ppm*Wn,e)):e}function Se(e,t,n){const o=T??H;if(!o)return;const i=tn(o.ppm*n),r=i/o.ppm,u=e-(e-o.originX)*r,l=t-(t-o.originY)*r,d=(H?.snapDist??1)/(i/(H?.ppm??i));T={originX:u,originY:l,ppm:i,snapDist:d},v()}function X(){return T??H}function nn(e){if(e.ctrlKey||e.metaKey){e.preventDefault();const t=a.getBoundingClientRect(),n=e.deltaY<0?1.12:1/1.12;Se(e.clientX-t.left,e.clientY-t.top,n)}else if(T!==null){e.preventDefault();const t=X(),n=T.snapDist;T={originX:t.originX-e.deltaX,originY:t.originY-e.deltaY,ppm:t.ppm,snapDist:n},v()}}function on(e,t,n){return e>=n.x&&e<n.x+n.w&&t>=n.y&&t<n.y+n.h}function an(e){if(e.button!==0||!X())return;a.focus({preventScroll:!0}),a.setPointerCapture(e.pointerId);const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(ke&&s.legendPosition==="floating"&&on(n,o,ke)){me=!0,Te={x:n,y:o},ut={...ft};return}if(Pe&&Y!=="pan"){ve=!0,ce=!0,be={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing";return}if(Y==="zoom"||Y==="select"){ye=!0,P=O={x:n,y:o};return}ce=!0,be={x:n,y:o},Ke={x:X().originX,y:X().originY},a.style.cursor="grabbing"}function ln(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top;if(ye){O={x:n,y:o},wt();return}if(me){const p=n-Te.x,g=o-Te.y;p*p+g*g>16&&(me=!1,Le=!0,a.style.cursor="grabbing")}if(Le){ft={x:ut.x+(n-Te.x),y:ut.y+(o-Te.y)},wt();return}if(ce){const p=X(),g=T?.snapDist??H?.snapDist??1;T={originX:Ke.x+(n-be.x),originY:Ke.y+(o-be.y),ppm:p.ppm,snapDist:g},wt();return}const i=X();if(!i)return;const r=(n-i.originX)/i.ppm,u=(i.originY-o)/i.ppm,d=cn(r,u,i.snapDist)?.die??null,c=pt.find(p=>n>=p.x&&n<p.x+p.w&&o>=p.y&&o<p.y+p.h);if(c){a.style.cursor="pointer",b&&(b.innerHTML=c.label??`Bin ${c.bin}`,b.style.display="block",Dt(b,a,e.clientX,e.clientY)),Ne?.(null,e);return}if(Y==="pan"&&(a.style.cursor=d?"crosshair":"grab"),b)if(d)if(Rt){const p=Rt(d);p===null?b.style.display="none":(typeof p=="string"?b.innerHTML=p:(b.innerHTML="",b.appendChild(p)),b.style.display="block",Dt(b,a,e.clientX,e.clientY))}else b.innerHTML=ai(d,m.plotMode,{testDefs:J,hbinDefs:$,sbinDefs:G,fallbackFormat:Be,aggrMethod:m.aggrMethod,lotSize:m.lotSize,waferMeta:oe.metadata,activeTest:m.activeTest,reticleConfig:Kt}),b.style.display="block",Dt(b,a,e.clientX,e.clientY);else b.style.display="none";Ne?.(d,e)}function sn(e){const t=a.getBoundingClientRect(),n=e.clientX-t.left,o=e.clientY-t.top,i=e.ctrlKey||e.metaKey;if(b&&(n<0||o<0||n>t.width||o>t.height)&&(b.style.display="none"),ye){ye=!1,O={x:n,y:o};const l=n-P.x,d=o-P.y,c=X();if(Y==="zoom"){if(l*l+d*d<25)Se(n,o,2);else if(c){const p=Math.min(P.x,O.x),g=Math.max(P.x,O.x),Q=Math.min(P.y,O.y),Ce=Math.max(P.y,O.y),K=g-p,se=Ce-Q;if(K>4&&se>4){const k=a.clientWidth,V=a.clientHeight,Ie=k/K,qe=V/se,Je=Math.min(Ie,qe),U=tn(c.ppm*Je),We=U/c.ppm,et=(p+g)/2,j=(Q+Ce)/2;T={originX:k/2-(et-c.originX)*We,originY:V/2-(j-c.originY)*We,ppm:U,snapDist:c.snapDist/We}}}v(),a.style.cursor="crosshair";return}if(l*l+d*d<25)St(n,o,i,e);else if(c){const p=(Math.min(P.x,O.x)-c.originX)/c.ppm,g=(Math.max(P.x,O.x)-c.originX)/c.ppm,Q=(c.originY-Math.max(P.y,O.y))/c.ppm,Ce=(c.originY-Math.min(P.y,O.y))/c.ppm,K=m.hoverPoints,se=[];for(let k=0;k<K.length;k++)if(K[k].x>=p&&K[k].x<=g&&K[k].y>=Q&&K[k].y<=Ce){const V=m.dies[k];V&&se.push(V)}if(i)for(const k of se){const V=Me(k);M.has(V)?M.delete(V):M.add(V)}else M=new Set(se.map(k=>Me(k)));re?.(Ct())}v(),a.style.cursor="crosshair";return}if(me){me=!1,St(n,o,i,e);return}if(Le){Le=!1,a.style.cursor="grab";return}if(!ce)return;if(ce=!1,ve){ve=!1,a.style.cursor=Pe||Y==="pan"?"grab":"crosshair";return}a.style.cursor=Y==="pan"?"grab":"crosshair";const r=n-be.x,u=o-be.y;r*r+u*u<25&&St(n,o,i,e)}function St(e,t,n,o){for(const l of pt)if(e>=l.x&&e<l.x+l.w&&t>=l.y&&t<l.y+l.h){if(typeof l.bin=="number"){const d=s.highlightBin===l.bin?void 0:l.bin;S({highlightBin:d})}else{const d=s.highlightMetadataValue===l.bin?void 0:l.bin;S({highlightMetadataValue:d})}return}if(ke&&on(e,t,ke))return;const i=X();if(!i)return;const u=cn((e-i.originX)/i.ppm,(i.originY-t)/i.ppm,i.snapDist)?.die??null;if(u){Ln?.(u,o);const l=Me(u);n?M.has(l)?M.delete(l):M.add(l):M=new Set([l]),re?.(Ct()),v()}else n||(M=new Set,re?.([]),v())}function Ct(){const e=[],t=m.hoverPoints;for(let n=0;n<t.length;n++){const o=m.dies[n];o&&M.has(Me(o))&&e.push(o)}return e}function rn(){b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair"}function dn(){ce=!1,ve=!1,ye=!1,me=!1,Le=!1,b&&ot(W),Ne?.(null,new MouseEvent("mouseleave")),a.style.cursor=Y==="pan"?"grab":"crosshair",v()}function cn(e,t,n){const o=m.hoverPoints,i=m.rectangles;for(let d=0;d<i.length;d++){const c=i[d];if(Math.abs(e-c.x)<=c.width/2&&Math.abs(t-c.y)<=c.height/2){const p=m.dies[d];return p?{die:p,index:d}:null}}let r=null,u=-1,l=n*n;for(let d=0;d<o.length;d++){const c=o[d].x-e,p=o[d].y-t,g=c*c+p*p;g<l&&(l=g,r=m.dies[d]??null,u=d)}return r?{die:r,index:u}:null}const pn=new _.ResizeObserver(()=>{H=null,T=null,v()});pn.observe(a),C.height==null&&kn<=0&&kt(()=>kt(()=>{N.clientHeight>0||console.warn("[wafermap] The map container has zero height, so the map cannot render. renderWaferMap fills its container \u2014 give the container a resolved height: an explicit CSS `height` (e.g. 600px), a height-resolved flex/grid parent, or `position:absolute; inset:0`. Alternatively pass `{ height: 600 }` in the render options and the library will size it for you.")}));let Re=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`);const Qe=()=>{Re.removeEventListener("change",Qe),Re=_.matchMedia(`(resolution: ${_.devicePixelRatio}dppx)`),Re.addEventListener("change",Qe),v()};Re.addEventListener("change",Qe);const fn=_.matchMedia("(prefers-color-scheme: dark)"),un=()=>v();fn.addEventListener("change",un);const gn=()=>{b&&ot(W)};_.addEventListener("blur",gn);function hn(e){if(e.key==="Escape"&&M.size>0&&(M=new Set,re?.([]),v()),(e.key==="e"||e.key==="E")&&Ot!=="view-only"&&Ht&&!he&&(e.stopPropagation(),(Wt??Jt)()),(e.ctrlKey||e.metaKey)&&(e.key==="="||e.key==="+"?(e.preventDefault(),Se(a.clientWidth/2,a.clientHeight/2,1.2)):e.key==="-"?(e.preventDefault(),Se(a.clientWidth/2,a.clientHeight/2,1/1.2)):e.key==="0"&&(e.preventDefault(),Ue())),!e.ctrlKey&&!e.metaKey&&!e.shiftKey){const n=X();if(n){const o=T?.snapDist??H?.snapDist??1;let i=0,r=0;e.key==="ArrowLeft"&&(i=20,e.preventDefault()),e.key==="ArrowRight"&&(i=-20,e.preventDefault()),e.key==="ArrowUp"&&(r=20,e.preventDefault()),e.key==="ArrowDown"&&(r=-20,e.preventDefault()),(i||r)&&(T={originX:n.originX+i,originY:n.originY+r,ppm:n.ppm,snapDist:o},v())}e.key===" "&&!Pe&&(e.preventDefault(),Pe=!0,Y!=="pan"&&(a.style.cursor="grab"))}}function mn(e){e.key===" "&&(Pe=!1,ve&&(ce=!1,ve=!1),a.style.cursor=Y==="pan"?"grab":"crosshair")}a.style.cursor="grab",a.setAttribute("tabindex","0"),a.addEventListener("wheel",nn,{passive:!1}),a.addEventListener("pointerdown",an),a.addEventListener("pointermove",ln),a.addEventListener("pointerup",sn),a.addEventListener("pointerleave",rn),a.addEventListener("pointercancel",dn);const yn=()=>Ue();a.addEventListener("dblclick",yn),a.addEventListener("keydown",hn),a.addEventListener("keyup",mn);const bn=e=>{e.stopPropagation()};a.addEventListener("click",bn),a.clientWidth,v(),Xe?.();function Ue(){H=null,T=null,v()}function vn(){import("./userGuideHtml.js").then(e=>vi({buildWaferMap:ci,renderWaferMap,renderWaferGallery:void 0,analyzeWaferMap:fi},e.USER_GUIDE_HTML,An,N))}return{setDies(e){ae=e,Oe(),v(),z&&fe()},setResult(e){lt=e,oe=e.wafer,ae=e.dies,$=e.hbinDefs,G=e.sbinDefs,J=e.testDefs,De=e.metadataFields,Nt=e.reticles?.length?e.reticles:void 0,Kt=e.reticleConfig,Vt=e.view?.dataAxisFlip,st=e.isLotStack,rt=e.aggrMethod,dt=e.lotSize,Nn(),Oe(),v(),z&&fe()},setOptions(e){en(e)},getOptions(){return{...s}},resetZoom:Ue,setSelection(e){M=new Set(e.map(t=>Me(t))),v()},clearSelection(){M=new Set,re?.([]),v()},setFallbackFormat(e){Be=e,Oe(),v()},setStatsSummary(e){if(ne=e,Xt(),Ut(),z)fe();else if(R)je();else if(e&&!Ee?.placement){const t=Ee?.defaultOpen??!ge;R=Tt("right"),R.style.display=t?"block":"none";const n=w.parentElement,o=w.nextSibling;ee=Pt(w,R,"right"),n?.insertBefore(ee,o),je()}Ze()},setSummaryVisible(e){I&&(I.style.display=e?"flex":"none")},setViewControlsVisible(e){B&&(B.style.display=e?"flex":"none")},setExpandVisible(e){Z&&(Z.style.display=e?"flex":"none")},setHelpButtonVisible(e){$e&&($e.style.display=e?"flex":"none")},setMetadataBadgeVisible(e){jt=!e,L&&(L.el.style.display=e&&!he?"":"none")},openUserGuide:vn,setInsightsOpen(e){ct(e),F&&(e?(F.dataset.active="1",F.style.background=x.bgActive,F.style.color=x.iconActive):(delete F.dataset.active,F.style.background="transparent",F.style.color=x.icon))},closeSummaryPanel(){const e=z??R;!e||e.style.display==="none"||(e.style.display="none",I&&(delete I.dataset.active,I.style.background="transparent",I.style.color=x.icon))},setTooltipParent(e){b&&hi(e)},getActiveLegend(){const e=s.plotMode;if(e==="metadata"){const i=s.activeMetadataKey;if(!i)return null;const r=De?.find(l=>l.key===i),u=[...new Set(ae.map(l=>l.metadata?.[i]).filter(l=>l!=null&&(typeof l=="string"||typeof l=="number"||typeof l=="boolean")).map(String))].sort();return u.length?u.map((l,d)=>{const c=r?.values?.find(g=>g.value===l),p=c?.color??Fi(d);return{bin:l,name:c?.label??l,color:p}}):null}if(e!=="hardBin"&&e!=="softBin")return null;const t=e==="hardBin",n=t?$:G,o=[...new Set(ae.map(i=>t?i.hbin:i.sbin).filter(i=>i!==void 0))].sort((i,r)=>i-r);return o.length?o.map(i=>{const r=n?.find(l=>l.bin===i),u=r?.color??(t?Hi(i):Ai(i));return{bin:i,name:r?.name??`Bin ${i}`,color:u}}):null},destroy(){we?.close(),xe&&clearTimeout(xe),qt?.()?.remove(),gt&&W.removeEventListener("click",gt,!0),a.removeEventListener("wheel",nn),a.removeEventListener("pointerdown",an),a.removeEventListener("pointermove",ln),a.removeEventListener("pointerup",sn),a.removeEventListener("pointerleave",rn),a.removeEventListener("pointercancel",dn),a.removeEventListener("dblclick",yn),a.removeEventListener("keydown",hn),a.removeEventListener("keyup",mn),a.removeEventListener("click",bn),pn.disconnect(),Re.removeEventListener("change",Qe),fn.removeEventListener("change",un),_.removeEventListener("blur",gn),Xn(),b&&ot(W),E?.remove(),pe&&(pe.parentElement?.insertBefore(w,pe),pe.remove()),ee&&(ee.parentElement?.insertBefore(w,ee),ee.remove()),w.remove(),a.style.cursor="",le?.destroy(),L?.destroy(),q.remove()}}}
|