@wafertools/wafermap 0.30.0 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +13 -3
- package/CHANGELOG.md +175 -0
- package/README.md +3 -3
- package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.js +1 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.js +1 -1
- package/dist/packages/canvas-adapter/charts/correlation.js +2 -2
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.d.ts +1 -0
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/deprecated.d.ts +0 -3
- package/dist/packages/canvas-adapter/deprecated.js +1 -1
- package/dist/packages/canvas-adapter/dieList.js +1 -1
- package/dist/packages/canvas-adapter/exportName.d.ts +68 -0
- package/dist/packages/canvas-adapter/exportName.js +1 -0
- package/dist/packages/canvas-adapter/icons.js +2 -2
- package/dist/packages/canvas-adapter/index.d.ts +2 -1
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +25 -3
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +24 -2
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +21 -6
- package/dist/packages/canvas-adapter/summaryPanel.js +3 -3
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +6 -0
- package/dist/packages/canvas-adapter/toolbar.js +2 -2
- package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
- package/dist/packages/canvas-adapter/userGuideHtml.js +15 -8
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.js +1 -1
- package/dist/packages/core/deprecated.d.ts +8 -12
- package/dist/packages/core/deprecated.js +1 -1
- package/dist/packages/core/index.d.ts +1 -1
- package/dist/packages/core/index.js +1 -1
- package/dist/packages/core/utils.d.ts +12 -0
- package/dist/packages/core/utils.js +1 -1
- package/dist/packages/core/waferLabel.d.ts +12 -2
- package/dist/packages/core/waferLabel.js +1 -1
- package/dist/packages/renderer/binColors.d.ts +38 -0
- package/dist/packages/renderer/binColors.js +1 -1
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +30 -5
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/deprecate.d.ts +7 -0
- package/dist/packages/renderer/deprecate.js +1 -1
- package/dist/packages/renderer/deprecated.d.ts +2 -2
- package/dist/packages/renderer/deprecated.js +1 -1
- package/dist/packages/renderer/index.d.ts +2 -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/capability.d.ts +16 -1
- package/dist/packages/stats/capability.js +1 -1
- package/dist/packages/stats/deprecated.d.ts +30 -35
- package/dist/packages/stats/deprecated.js +1 -1
- package/dist/packages/stats/index.d.ts +4 -2
- package/dist/packages/stats/index.js +1 -1
- package/dist/packages/stats/normalizeInput.d.ts +10 -0
- package/dist/packages/stats/normalizeInput.js +1 -0
- package/dist/packages/stats/regions.d.ts +2 -0
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderFindingsReport.js +1 -1
- package/dist/packages/stats/renderSummaryReport.d.ts +39 -1
- package/dist/packages/stats/renderSummaryReport.js +26 -26
- package/dist/packages/stats/reportHtml.d.ts +0 -1
- package/dist/packages/stats/reportHtml.js +10 -10
- package/dist/packages/stats/summaryFigures.d.ts +47 -0
- package/dist/packages/stats/summaryFigures.js +1 -0
- package/dist/packages/stats/types.d.ts +118 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{deprecated as e}from"../renderer/deprecate.js";import{toCanvas as
|
|
1
|
+
import{deprecated as e}from"../renderer/deprecate.js";import{toCanvas as i}from"./toCanvas.js";import{buildDieListSection as o}from"./dieList.js";const t="If you depend on it, say so at https://github.com/wafertools/wafermap/issues.",a="It belongs to the low-level drawing pipeline, which is being withdrawn: build with buildWaferMap and draw with renderWaferMap or renderWaferGallery.",r="renderWaferMap and renderWaferGallery show the die list themselves (the dieList option).";export const toCanvas=e(i,"toCanvas",`${a} ${t}`),buildDieListSection=e(o,"buildDieListSection",`${r} ${t}`);
|
|
@@ -10,4 +10,4 @@ import{hasPosition as R,isPositionedDie as O}from"../core/dies.js";import{classi
|
|
|
10
10
|
border-bottom: 1px solid ${c.menuBorder}; white-space: nowrap;
|
|
11
11
|
}
|
|
12
12
|
`,t.head.appendChild(o)}function d(t,o,n,a){const i=t.createElement(o);return n&&Object.assign(i.style,n),a!==void 0&&(i.textContent=a),i}function U(t){return R(t)?String(t.x):""}function q(t){return R(t)?String(t.y):""}function J(t,o){if(o!==void 0)return o.filter(a=>a.testNumber!==void 0);const n=new Map;for(const a of t)for(const i of Object.keys(a.testValues??{})){const s=Number(i);n.has(s)||n.set(s,{testNumber:s,name:`Test ${s}`})}return[...n.values()].sort((a,i)=>a.testNumber-i.testNumber)}function Z(t,o,n){if(!o)return;const a=new Map;for(const i of t){if(!O(i))continue;const s=o(i);s&&a.set(i,z(i,s,{ringCount:n}))}return a.size>0?a:void 0}export function buildDieListSection(t,o,n={}){if(!t.length)return null;const a=n.ownerDocument??document;Q(a);const i=J(t,o),s=n.maxRows??_,S=Math.max(0,t.length-s),H=S>0?t.slice(0,s):t,f=d(a,"div",{display:"flex",flexDirection:"column",gap:X.md,flex:"1",minHeight:"0",minWidth:"0"}),w=d(a,"div",{display:"flex",alignItems:"center",justifyContent:"space-between",flexShrink:"0"});w.appendChild(d(a,"div",{fontSize:C.meta,fontWeight:"700",letterSpacing:W,textTransform:"uppercase",color:c.label},n.title??`Die list (${t.length})`));const g=d(a,"button",{fontSize:C.body,padding:"3px 8px",borderRadius:I.control,...K("outlined"),background:c.menuBg},"Export CSV");g.type="button",G(g),w.appendChild(g),f.appendChild(w),n.note&&f.appendChild(d(a,"div",{fontSize:C.body,color:c.label,lineHeight:D.base,flexShrink:"0"},n.note));const v=Z(t,n.getWafer,n.ringCount??4),P=t.some(e=>e.edgeExcluded===!0),j=[...n.extraColumn?[n.extraColumn.label]:[],"X","Y","Ring","Quadrant","Edge excluded","Site","Hard bin","Soft bin",...i.map(e=>e.unit?`${e.name} (${e.unit})`:e.name)],{columns:M,truncatedKeys:h}=V({dies:t,waferMetadata:n.waferMetadata,metadataFields:n.metadataFields,dieKeys:n.metadataColumns,waferKeys:n.waferMetadataColumns==="none"?"none":void 0,waferPlacement:n.waferMetadataColumns??"csv",reservedLabels:j}),y=[...n.extraColumn?[{label:n.extraColumn.label,get:e=>n.extraColumn.get(e)??""}]:[],{label:"X",get:U},{label:"Y",get:q},...v?[{label:"Ring",get:e=>{const l=v.get(e);return l?String(l.ring):""}},{label:"Quadrant",get:e=>v.get(e)?.quadrant??""}]:[],...P?[{label:"Edge excluded",get:e=>e.edgeExcluded?"Yes":"No"}]:[],{label:"Site",get:e=>e.siteNum!==void 0?String(e.siteNum):""},{label:"Hard bin",get:e=>e.hbin!==void 0?String(e.hbin):""},{label:"Soft bin",get:e=>e.sbin!==void 0?String(e.sbin):""},...i.map(e=>{const l=!B(e);return{label:e.unit?`${e.name} (${e.unit})`:e.name,get:r=>{if(l){const p=x(r,e.testNumber,e);return p===void 0?"":p?"PASS":"FAIL"}const u=r.testValues?.[e.testNumber];if(u!==void 0)return k(u,e.unit);const b=x(r,e.testNumber,e);return b===void 0?"":b?"PASS":"FAIL"},csvGet:r=>{if(l){const p=x(r,e.testNumber,e);return p===void 0?"":p?"PASS":"FAIL"}const u=r.testValues?.[e.testNumber];if(u!==void 0)return k(u,void 0,"engineering");const b=x(r,e.testNumber,e);return b===void 0?"":b?"PASS":"FAIL"}}}),...M.map(e=>({label:e.label,get:e.get,csvOnly:e.csvOnly}))],N=y.filter(e=>!e.csvOnly),$=d(a,"div",{overflow:"auto",flex:"1",minHeight:"0",minWidth:"0",border:`1px solid ${c.menuBorder}`,borderRadius:I.control,...n.maxHeight?{maxHeight:n.maxHeight}:{}}),m=a.createElement("table");m.className="wmap-dielist-table",m.setAttribute("aria-label",n.title??`Die list (${t.length} dies)`);const E=d(a,"thead"),A=d(a,"tr");for(const e of N){const l=a.createElement("th");l.className="wmap-dielist-th",l.scope="col",l.textContent=e.label,A.appendChild(l)}E.appendChild(A),m.appendChild(E);const L=d(a,"tbody");for(const e of H){const l=d(a,"tr");for(const r of N){const u=a.createElement("td");u.className="wmap-dielist-td",u.textContent=r.get(e),l.appendChild(u)}L.appendChild(l)}if(m.appendChild(L),$.appendChild(m),f.appendChild($),S>0||h.length>0){const e=[];S>0&&e.push(`Showing the first ${s.toLocaleString()} of ${t.length.toLocaleString()} dies. The CSV export contains all ${t.length.toLocaleString()}.`),h.length>0&&e.push(`${h.length} further metadata field${h.length===1?"":"s"} not shown.`),f.appendChild(d(a,"div",{fontSize:C.body,color:c.label,lineHeight:D.base,flexShrink:"0"},e.join(" ")))}return g.addEventListener("click",()=>{const e=[y.map(l=>T(l.label)).join(",")];for(const l of t)e.push(y.map(r=>T((r.csvGet??r.get)(l))).join(","));Y(e.join(`
|
|
13
|
-
`),"
|
|
13
|
+
`),"die-list.csv","text/csv",n.onSaveText)}),f}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Names for saved files — the one rule for every PNG and CSV the library saves.
|
|
3
|
+
*
|
|
4
|
+
* Every export used to be named for its content alone (`dies.csv`,
|
|
5
|
+
* `test-values.csv`, `wafermap.png`, a chart's title), so saving the same export
|
|
6
|
+
* from two wafers gave `dies.csv` and `dies (1).csv`, and nothing in the file
|
|
7
|
+
* name said which lot or wafer either one described. The library has that
|
|
8
|
+
* identity, so naming the file is its job, not the host's.
|
|
9
|
+
*
|
|
10
|
+
* The split: a save site names only its CONTENT (`die-list.csv`, the map's
|
|
11
|
+
* title) and keeps passing its `onSaveImage`/`onSaveText` handler as before.
|
|
12
|
+
* Each renderer wraps the host's handlers once with `withExportContext`, which
|
|
13
|
+
* prepends the context it knows — the host's `downloadFilename` prefix, the lot,
|
|
14
|
+
* the wafer or wafer count — read at save time, so the name follows
|
|
15
|
+
* `setResult`, `setItems` and mode changes. No save site threads identity.
|
|
16
|
+
*
|
|
17
|
+
* @internal Not exported from the package: hosts receive the result as the
|
|
18
|
+
* `suggestedName` argument of their save hooks.
|
|
19
|
+
*/
|
|
20
|
+
import { type SaveImageHandler, type SaveTextHandler } from './toolbar.js';
|
|
21
|
+
/**
|
|
22
|
+
* Tell a host that passes `downloadFilename` its meaning changes in 0.31.0.
|
|
23
|
+
* Until then it keeps its documented meaning — the whole name of the map or
|
|
24
|
+
* gallery PNG — and nothing else reads it; changing that in a patch release
|
|
25
|
+
* would break hosts that match the name their `onSaveImage` receives.
|
|
26
|
+
*/
|
|
27
|
+
export declare function noticeDownloadFilenameChange(downloadFilename: string | undefined): void;
|
|
28
|
+
/** What a renderer knows about the data behind an export. */
|
|
29
|
+
export interface ExportContext {
|
|
30
|
+
/**
|
|
31
|
+
* Leads the name, and suppresses any context it already names. Reserved for
|
|
32
|
+
* `downloadFilename` from 0.31.0; no renderer sets it before then (see
|
|
33
|
+
* `noticeDownloadFilenameChange`).
|
|
34
|
+
*/
|
|
35
|
+
prefix?: string;
|
|
36
|
+
/** Distinct lot IDs covered, in display order. */
|
|
37
|
+
lots: string[];
|
|
38
|
+
/** One wafer's identity (`waferIdentityLabel`), when the export covers exactly one. */
|
|
39
|
+
wafer?: string;
|
|
40
|
+
/** Wafers covered, when the export covers several (a gallery or lot). */
|
|
41
|
+
waferCount?: number;
|
|
42
|
+
/** Set on a lot-stacked map: the wafers aggregated into it, or `true` when unknown. */
|
|
43
|
+
stackedWafers?: number | true;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The file name for an export: `prefix_lot_wafer_content.ext`, each part only
|
|
47
|
+
* when known and not already named by the prefix.
|
|
48
|
+
*
|
|
49
|
+
* @param ctx what the renderer knows (see `ExportContext`)
|
|
50
|
+
* @param contentName the save site's own name, with extension — e.g.
|
|
51
|
+
* `die-list.csv`, or a map title plus `.png`
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildExportFilename(ctx: ExportContext, contentName: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Wrap a renderer's save hooks so every export it makes is named by
|
|
56
|
+
* `buildExportFilename`. The returned handlers are always defined: with no host
|
|
57
|
+
* hook they perform the browser download themselves, so a save site cannot
|
|
58
|
+
* bypass the naming by falling through to its own default path.
|
|
59
|
+
*
|
|
60
|
+
* Hand the host's RAW hooks, never these, to anything that wraps again (a
|
|
61
|
+
* gallery card or detached window is its own renderer with its own context) —
|
|
62
|
+
* wrapping twice would name the lot twice.
|
|
63
|
+
*/
|
|
64
|
+
export declare function withExportContext(getContext: () => ExportContext, onSaveImage: SaveImageHandler | undefined, onSaveText: SaveTextHandler | undefined): {
|
|
65
|
+
onSaveImage: SaveImageHandler;
|
|
66
|
+
onSaveText: SaveTextHandler;
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=exportName.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{downloadBlob as u}from"./toolbar.js";import{noticeOnce as _}from"../renderer/deprecate.js";export function noticeDownloadFilenameChange(e){e!=null&&_("downloadFilename",'downloadFilename becomes a prefix in 0.31.0: the library will append the lot, wafer and content (e.g. "<downloadFilename>_W05_hard-bin.png") and apply it to every saved file, CSVs included. Until then it names only the map or gallery PNG, as before.')}const $=60,m=180,g=/^(con|prn|aux|nul|com\d|lpt\d)$/i;function f(e){return e.normalize("NFC").replace(/[^\p{L}\p{N}._+-]+/gu,"-").replace(/-{2,}/g,"-").replace(/^[-._]+|[-._]+$/g,"").slice(0,$).replace(/[-._]+$/g,"")}function c(e,n){return/^\d+$/.test(n)?`${e}-${n}`:n}function w(e,n){const o=`_${e.toLowerCase().replace(/[-_.\s]+/g,"_")}_`,r=`_${n.toLowerCase().replace(/[-_.\s]+/g,"_")}_`;return o.includes(r)}export function buildExportFilename(e,n){const o=n.lastIndexOf("."),r=o>=0?n.slice(o):"",l=f(o>=0?n.slice(0,o):n).toLowerCase(),t=e.prefix?.trim()?f(e.prefix):"",a=[];if(e.lots.length===1?a.push({raw:e.lots[0],text:c("lot",e.lots[0])}):e.lots.length>1&&a.push({raw:`${e.lots.length}-lots`,text:`${e.lots.length}-lots`}),e.stackedWafers!==void 0){const i=e.stackedWafers===!0?"stacked":`stacked-${e.stackedWafers}-wafer${e.stackedWafers===1?"":"s"}`;a.push({raw:i,text:i})}else e.wafer!==void 0?a.push({raw:e.wafer,text:c("wafer",e.wafer)}):e.waferCount!==void 0&&e.waferCount>1&&a.push({raw:`${e.waferCount}-wafers`,text:`${e.waferCount}-wafers`});const p=[t];for(const{raw:i,text:h}of a){const d=f(h);d&&(t&&(w(t,f(i))||w(t,d))||p.push(d))}p.push(l);let s=p.filter(Boolean).join("_").slice(0,m).replace(/[-_.]+$/g,"");return s||(s="wafermap"),g.test(s)&&(s=`wafermap-${s}`),`${s}${r}`}export function withExportContext(e,n,o){return{onSaveImage:(r,l)=>{const t=buildExportFilename(e(),l);if(n)return n(r,t);u(r,t)},onSaveText:(r,l,t)=>{const a=buildExportFilename(e(),l);if(o)return o(r,a,t);u(new Blob([r],{type:t}),a)}}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const ICONS={aggr:'<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="M18 4H6l6 8-6 8h12"/></svg>',analysis:'<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="M3 3v18h18"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/></svg>',boxSelect:'<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 3a2 2 0 0 0-2 2"/><path d="M19 3a2 2 0 0 1 2 2"/><path d="M21 19a2 2 0 0 1-2 2"/><path d="M5 21a2 2 0 0 1-2-2"/><path d="M9 3h1"/><path d="M9 21h1"/><path d="M14 3h1"/><path d="M14 21h1"/><path d="M3 9v1"/><path d="M21 9v1"/><path d="M3 14v1"/><path d="M21 14v1"/></svg>',close:'<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="M18 6 6 18"/><path d="m6 6 12 12"/></svg>',columns:`<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
1
|
+
export const ICONS={aggr:'<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="M18 4H6l6 8-6 8h12"/></svg>',analysis:'<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="M3 3v18h18"/><path d="M18 17V9"/><path d="M13 17V5"/><path d="M8 17v-3"/></svg>',boxSelect:'<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 3a2 2 0 0 0-2 2"/><path d="M19 3a2 2 0 0 1 2 2"/><path d="M21 19a2 2 0 0 1-2 2"/><path d="M5 21a2 2 0 0 1-2-2"/><path d="M9 3h1"/><path d="M9 21h1"/><path d="M14 3h1"/><path d="M14 21h1"/><path d="M3 9v1"/><path d="M21 9v1"/><path d="M3 14v1"/><path d="M21 14v1"/></svg>',close:'<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="M18 6 6 18"/><path d="m6 6 12 12"/></svg>',collapse:'<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="m7 20 5-5 5 5"/><path d="m7 4 5 5 5-5"/></svg>',columns:`<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
2
2
|
<rect x="3" y="3" width="4" height="18" rx="1"/>
|
|
3
3
|
<rect x="10" y="3" width="4" height="18" rx="1"/>
|
|
4
4
|
<rect x="17" y="3" width="4" height="18" rx="1"/>
|
|
@@ -13,7 +13,7 @@ export const ICONS={aggr:'<svg viewBox="0 0 24 24" width="16" height="16" fill="
|
|
|
13
13
|
<path d="M3 12 c0 2.5 4 4 9 4 s9-1.5 9-4" />
|
|
14
14
|
|
|
15
15
|
<path d="M3 17 c0 2.5 4 4 9 4 s9-1.5 9-4" />
|
|
16
|
-
</svg>`,orient:'<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="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" fill="currentColor" stroke="none"/></svg>',overlays:'<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="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></svg>',palette:'<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="m14.622 17.897-10.68-2.913"/><path d="M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0z"/><path d="M9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15"/></svg>',pan:'<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="M12 2v20"/><path d="m15 19-3 3-3-3"/><path d="m19 9 3 3-3 3"/><path d="M2 12h20"/><path d="m5 9-3 3 3 3"/><path d="m9 5 3-3 3 3"/></svg>',print:'<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="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><path d="M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6"/><rect x="6" y="14" width="12" height="8" rx="1"/></svg>',quadrants:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><line x1="12" y1="3" x2="12" y2="21"/><line x1="3" y1="12" x2="21" y2="12"/></svg>',reset:'<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="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>',reticle:'<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="3" y="3" width="8" height="6" rx="0.5"/><rect x="13" y="3" width="8" height="6" rx="0.5"/><rect x="3" y="11" width="8" height="6" rx="0.5"/><rect x="13" y="11" width="8" height="6" rx="0.5"/><rect x="3" y="19" width="8" height="2" rx="0.5" stroke-dasharray="2 1"/><rect x="13" y="19" width="8" height="2" rx="0.5" stroke-dasharray="2 1"/></svg>',rings:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5.5"/><circle cx="12" cy="12" r="2" fill="currentColor" stroke="none"/></svg>',rotateCW:'<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="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg>',specRange:'<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 4 L5 20"/><path d="M5 4 L8 4"/><path d="M5 20 L8 20"/><path d="M19 4 L19 20"/><path d="M19 4 L16 4"/><path d="M19 20 L16 20"/><path d="M5 12 L19 12" stroke-dasharray="3 2"/></svg>',wafer:`<svg
|
|
16
|
+
</svg>`,orient:'<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="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76" fill="currentColor" stroke="none"/></svg>',overlays:'<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="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z"/><circle cx="12" cy="12" r="3"/></svg>',palette:'<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="m14.622 17.897-10.68-2.913"/><path d="M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0z"/><path d="M9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15"/></svg>',pan:'<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="M12 2v20"/><path d="m15 19-3 3-3-3"/><path d="m19 9 3 3-3 3"/><path d="M2 12h20"/><path d="m5 9-3 3 3 3"/><path d="m9 5 3-3 3 3"/></svg>',print:'<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="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><path d="M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6"/><rect x="6" y="14" width="12" height="8" rx="1"/></svg>',quadrants:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><line x1="12" y1="3" x2="12" y2="21"/><line x1="3" y1="12" x2="21" y2="12"/></svg>',reset:'<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="M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8"/><path d="M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>',reticle:'<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="3" y="3" width="8" height="6" rx="0.5"/><rect x="13" y="3" width="8" height="6" rx="0.5"/><rect x="3" y="11" width="8" height="6" rx="0.5"/><rect x="13" y="11" width="8" height="6" rx="0.5"/><rect x="3" y="19" width="8" height="2" rx="0.5" stroke-dasharray="2 1"/><rect x="13" y="19" width="8" height="2" rx="0.5" stroke-dasharray="2 1"/></svg>',rings:'<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="12" r="5.5"/><circle cx="12" cy="12" r="2" fill="currentColor" stroke="none"/></svg>',rotateCW:'<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="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg>',specRange:'<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 4 L5 20"/><path d="M5 4 L8 4"/><path d="M5 20 L8 20"/><path d="M19 4 L19 20"/><path d="M19 4 L16 4"/><path d="M19 20 L16 20"/><path d="M5 12 L19 12" stroke-dasharray="3 2"/></svg>',uncollapse:'<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="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/></svg>',wafer:`<svg
|
|
17
17
|
viewBox="0 0 24 24"
|
|
18
18
|
width="16"
|
|
19
19
|
height="16"
|
|
@@ -15,5 +15,6 @@ export type { UserGuideExtension } from './toolbar.js';
|
|
|
15
15
|
export { openWaferMapGuide } from './toolbar.js';
|
|
16
16
|
export { ICONS } from './icons.js';
|
|
17
17
|
export type { OverlayHandle } from './toolbar.js';
|
|
18
|
-
export {
|
|
18
|
+
export { openReportModal } from './toolbar.js';
|
|
19
|
+
export { toCanvas, buildDieListSection, } from './deprecated.js';
|
|
19
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{WMAP_VERSION,WMAP_BUILD_TIME}from"./version.js";export{renderWaferMap}from"./renderWaferMap.js";export{renderWaferGallery}from"./renderWaferGallery.js";export{collectWarnings,severityOf}from"./warnings.js";export{setDetachWindowOpener}from"./toolbar.js";export{openWaferMapGuide}from"./toolbar.js";export{ICONS}from"./icons.js";export{toCanvas,buildDieListSection
|
|
1
|
+
export{WMAP_VERSION,WMAP_BUILD_TIME}from"./version.js";export{renderWaferMap}from"./renderWaferMap.js";export{renderWaferGallery}from"./renderWaferGallery.js";export{collectWarnings,severityOf}from"./warnings.js";export{setDetachWindowOpener}from"./toolbar.js";export{openWaferMapGuide}from"./toolbar.js";export{ICONS}from"./icons.js";export{openReportModal}from"./toolbar.js";export{toCanvas,buildDieListSection}from"./deprecated.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type BinColors } from '../renderer/binColors.js';
|
|
1
2
|
import { type SaveImageHandler, type SaveTextHandler, type UserGuideExtension } from './toolbar.js';
|
|
2
3
|
import { type Die } from '../core/dies.js';
|
|
3
4
|
import type { WaferViewOptions } from './renderWaferMap.js';
|
|
@@ -53,14 +54,22 @@ export interface GalleryOptions {
|
|
|
53
54
|
* disabled with that reason rather than appearing to do nothing.
|
|
54
55
|
*/
|
|
55
56
|
perCardLegend?: boolean;
|
|
56
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Name for the composite gallery PNG, without extension. When omitted, it is
|
|
59
|
+
* named for its lots, wafer count and plot mode
|
|
60
|
+
* (`LOT123_25-wafers_gallery-hard-bin.png`); cards, CSV exports and charts are
|
|
61
|
+
* always named that way. See docs/api.md §5.4.5.
|
|
62
|
+
*
|
|
63
|
+
* **Changes in 0.31.0:** this becomes a prefix for every file the gallery and
|
|
64
|
+
* its cards save. Passing it logs a one-time notice.
|
|
65
|
+
*/
|
|
57
66
|
downloadFilename?: string;
|
|
58
67
|
/**
|
|
59
68
|
* Host hook for persisting the composite gallery PNG. When provided, the save
|
|
60
69
|
* action calls `onSaveImage(blob, suggestedName)` instead of triggering a
|
|
61
70
|
* browser `<a download>` — letting embedded hosts (Tauri, Electron, WebView2)
|
|
62
71
|
* route the image through a native save dialog. `suggestedName` includes the
|
|
63
|
-
* `.png` extension and is
|
|
72
|
+
* `.png` extension and is the generated name (see `downloadFilename`). When omitted, the
|
|
64
73
|
* default browser download behaviour is unchanged.
|
|
65
74
|
*/
|
|
66
75
|
onSaveImage?: SaveImageHandler;
|
|
@@ -104,7 +113,8 @@ export interface GalleryOptions {
|
|
|
104
113
|
dieList?: DieListDisplayOptions;
|
|
105
114
|
/**
|
|
106
115
|
* Fix the number of columns in the gallery grid. When set, overrides the
|
|
107
|
-
* auto-computed
|
|
116
|
+
* auto-computed layout and the toolbar columns control: the columns share the
|
|
117
|
+
* full grid width, with no density-derived card size cap.
|
|
108
118
|
* Omit (default) to let the gallery auto-size cards based on die pitch.
|
|
109
119
|
*/
|
|
110
120
|
columns?: number;
|
|
@@ -160,6 +170,18 @@ export interface GalleryController {
|
|
|
160
170
|
* `undefined` to clear it once the offered analysis has been run.
|
|
161
171
|
*/
|
|
162
172
|
setFindingsNotice(notice: FindingsNotice | undefined): void;
|
|
173
|
+
/**
|
|
174
|
+
* Set the number of grid columns, as the toolbar's Columns control does: the
|
|
175
|
+
* columns share the full grid width. Pass `undefined` to return to the
|
|
176
|
+
* automatic layout, which sizes cards by die pitch.
|
|
177
|
+
*/
|
|
178
|
+
setColumns(columns: number | undefined): void;
|
|
179
|
+
/**
|
|
180
|
+
* The bin colours every card draws, resolved once over the whole gallery with
|
|
181
|
+
* the palette currently chosen — for a host surface of its own (a table
|
|
182
|
+
* swatch, an export). Hard and soft bins are separate maps.
|
|
183
|
+
*/
|
|
184
|
+
getBinColors(): BinColors;
|
|
163
185
|
/**
|
|
164
186
|
* Opens the built-in end-user guide window — the same action the help
|
|
165
187
|
* toolbar button performs, but callable directly. Works regardless of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as go,resolveTestNumber as mo,findTestDef as ho,collectMetadataValues as bo}from"../renderer/buildView.js";import{metadataCategoricalValue as yo}from"../core/metadata.js";import{resolveBinColorsByWafer as wo,binColorWarning as vo,mixedPassBinsWarning as xo}from"../renderer/binColors.js";import{itemPassBins as Co}from"../core/passBins.js";import{NO_DATA_FILL as So}from"../renderer/colorMap.js";import{metadataValueColor as Mo}from"../renderer/colorMap.js";import{resolveCanvasTheme as Do}from"./canvasTheme.js";import{ICONS as $e}from"./icons.js";import{SHADOW as We,LEADING as Xe,TRACKING as Bo,controlStyle as ko,wireControlHover as ht,SPACE as v,EDGE_GUTTER as oe,MAP_CHROME_INSET as Eo,RADIUS as z,FONT as O,CLR as m,sevColor as ln,MODE_LABELS as Oo,BIN_LEGEND_MODES as rn,STACKED_MODES as be,Z_ABOVE as dn,applyOverlayZ as To,getTooltip as Lo,hideTooltip as cn,createToolbarHelpers as $o,buildModeMenuEl as Wo,openDetachWindow as Ro,openFloatingWindow as Io,openModal as Ao,openReportModal as Po,copyWmapThemeTokens as Ho,syncWmapPopupTheme as Fo,openUserGuideWindow as jo,makePaletteBtn as Vo,makeLogScaleBtn as zo,makeLegendStyleBtn as No,makeOverlaysBtn as _o,makeOrientationBtn as Go,menuLayerFor as fn,saveImageBlob as Ko,markMenuTrigger as Re,wireMenuA11y as un,wireExpandToggle as pn,wireTooltip as gn,requestedPassFailDisplay as mn,overlayMenuRows as qo,anyOverlayActive as Uo,logWmapVersionOnce as Xo,buildDataModeEntries as Zo,metadataKeyHasData as Yo,metadataModeEntry as Qo}from"./toolbar.js";import{waferDisplayLabel as Ie}from"../core/waferLabel.js";import{sortBinsForDisplay as Jo}from"../stats/binPareto.js";import{diePassStatus as ei}from"../core/dies.js";import{aggregateValues as ti,aggregateBinCounts as hn}from"../core/aggregates.js";import{renderWaferMap as ni,renderWaferMapCard as bn,toPublicViewOptions as yn}from"./renderWaferMap.js";import{classifyChanged as oi,COLOR_KEYS as ii}from"./renderWaferMap.js";import{buildWaferMap as ai,getTestPassStatus as wn,isParametricTest as bt,getDieTestValue as si}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ze}from"../stats/analyzeWaferMap.js";import{collectWarnings as li,buildWarningsMenuEl as ri,severityOf as di}from"./warnings.js";import{compareNatural as vn}from"../core/utils.js";import{createSummaryPanelEl as yt,buildMetadataStripRow as ci,buildCompactMetadataRows as xn,metadataEntries as Cn,renderLotSummaryContent as fi}from"./summaryPanel.js";import{renderLotSummaryReportHtml as ui}from"../stats/renderSummaryReport.js";import{prettyKey as pi}from"../stats/facets.js";import{mergeTestDefs as gi}from"../stats/mergeTestDefs.js";import{getDieKey as mi,hasPosition as hi}from"../core/dies.js";function ie(u){const x=new Set;return u.filter(p=>x.has(p.bin)?!1:(x.add(p.bin),!0))}const wt=12;function bi(u,x,p){let I=x;if(x.length>wt){const C=x.slice(0,wt-1),L=x.slice(wt-1),N=L.reduce((F,ae)=>F+ae.count,0);I=[...C,{color:m.label,count:N,label:`Other (${L.length} bins)`}]}const A=u.createElement("div");Object.assign(A.style,{display:"flex",columnGap:"1px",width:"100%",height:"8px",borderRadius:z.control,overflow:"hidden",border:`1px solid ${m.menuBorder}`,boxSizing:"border-box",marginTop:v.xs,flexShrink:"0"}),A.setAttribute("role","img"),A.setAttribute("aria-label",`Population split: ${I.map(C=>`${C.label} ${Ye(C.count/p*100)}`).join(", ")}`);for(const C of I){const L=C.count/p*100,N=u.createElement("div");Object.assign(N.style,{flex:`${L} 1 0`,minWidth:L>0?"2px":"0",background:C.color}),gn(N,`${C.label} \xB7 ${C.count.toLocaleString()} dies \xB7 ${Ye(L)}`),A.appendChild(N)}return A}function Ye(u){return u>0&&u<.1?"<0.1%":`${u.toFixed(1)}%`}function Sn(u,x,p){const I=new Map;let A=0,C=0;for(const L of u){const N=p?new Set(p(L)):void 0;for(const F of L.dies){if(F.partial||F.edgeExcluded)continue;const ae=x(F);ae!==void 0&&(I.set(ae,(I.get(ae)??0)+1),A++,N&&ei(F,N)&&C++)}}return{counts:I,total:A,pass:C}}function Mn(u,x){const p=u.ownerDocument.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:`${v.xxs} ${v.xs}`,borderRadius:z.control});const I=u.ownerDocument.createElement("span");Object.assign(I.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:x.color,border:x.isActive?`2px solid ${m.iconActive}`:`1px solid ${m.menuBorder}`,borderRadius:z.control,boxSizing:"border-box"});const A=u.ownerDocument.createElement("span");if(A.textContent=x.label,Object.assign(A.style,{fontWeight:x.isActive?"700":"400",color:x.isActive?m.iconActive:m.text,whiteSpace:"nowrap"}),p.appendChild(I),p.appendChild(A),x.count!==void 0){const C=u.ownerDocument.createElement("span");if(C.textContent=x.count.toLocaleString(),Object.assign(C.style,{color:x.isActive?m.iconActive:m.text,fontWeight:x.isActive?"700":"400",whiteSpace:"nowrap"}),p.appendChild(C),x.percent!==void 0){const L=u.ownerDocument.createElement("span");L.textContent=Ye(x.percent),Object.assign(L.style,{color:m.label,whiteSpace:"nowrap"}),p.appendChild(L)}}p.setAttribute("role","button"),p.setAttribute("aria-pressed",x.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=m.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=m.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",x.onClick),p.addEventListener("keydown",C=>{(C.key==="Enter"||C.key===" ")&&(C.preventDefault(),x.onClick())}),u.appendChild(p)}export function renderWaferGallery(u,x,p={}){Xo();const I=6,A=p.downloadFilename??"wafer-gallery";let C=p.columns;const L=p.showHelpButton??!1,N=p.userGuideExtension,F=p.insights?.enabled??!1,ae=To(p.zIndex),ce=p.summaryPanel,Qe=e=>[...Co(e)],vt=()=>w.flatMap(e=>e?[e.ringCount??4]:[]),Je=()=>vt()[0]??4;function Dn(e){const t=[...new Set(e)].sort((n,o)=>n-o);return t.length<2?null:{code:"ring-count-mixed",severity:"warning",message:`These wafers were built with different ring counts (${t.join(", ")}). Each card and each wafer's findings use their own; the lot's ring yield in the Summary panel, report and Insights uses ${e[0]} rings.`}}let j=p.lotStatsSummary,ye=p.viewOptions?.legendPosition??"default",Ae=p.perCardLegend??!1;function we(){const e=d.plotMode??"hardBin";return rn.has(e)?null:d.colorbarRangeMode==="data"?"Each map has its own value range, so it keeps its own colour bar":"These wafers have no shared colour bar for value mode, so each map keeps its own"}function xt(){const e=Ae||we()!==null;for(const t of S)t&&t.setOptions({showLegend:e})}let d={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},S=[],se=[],fe=[],T=[],w=x.map(e=>typeof e=="function"?null:e);function Ct(){return gi(w)}function ue(){if(w.some(e=>e?.testDefs?.length))return Ct().defs}let et=0,Pe=0;const _=new Map;let Bn=0,P=null,ve=null,St=new Set,h=null,kn={};function Mt(e){return w[e]?.statsSummary??j?.perWafer.find(t=>t.waferIndex===e)?.summary}function tt(){return!!(w.some(e=>e?.statsSummary?.findings.length)||j?.perWafer.some(e=>e.summary.findings.length))}const En=Lo(),pe=$o(En),{makeBtn:Q,setActive:xe,makeSep:G,makeMenuRow:On,makeMenuSection:Tn,makeDropdown:Dt,closeOpenMenu:He,getOpenMenu:Ce,setOpenMenu:Se}=pe;u.ownerDocument.addEventListener("click",He,!0);const Bt=()=>cn();window.addEventListener("blur",Bt);let kt=p.findingsNotice;function Et(e){St=new Set(e);const t=[...W.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((o,l)=>{const a=St.has(l);o.style.outline=a?`3px solid ${m.findingHighlight}`:"",o.style.outlineOffset=a?"-3px":"",a&&n===void 0&&(n=o)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function Ot(){Et([])}function Tt(){for(const e of S)e&&e.clearSelection()}function nt(e,t){const n=new Set(e),o=t??S.map((l,a)=>a);for(const l of o){const a=T[l],s=S[l];if(!a||!s)continue;const r=a.dies.filter(i=>n.has(mi(i)));s.setSelection(r)}}function Ln(){const e=[];for(let t=0;t<w.length;t++){const n=w[t];if(!n)continue;const o=Mt(t)?.findings??[];o.length&&e.push({index:t,item:n,unusualCount:o.filter(l=>l.severity==="unusual").length,notableCount:o.filter(l=>l.severity==="notable").length,totalCount:o.length})}return e}function $n(e){const t=T[e]??w[e];t&&Le(e,t)}function Wn(e){const t=Mt(e)?.findings??[];if(t.length)return{total:t.length,unusual:t.filter(n=>n.severity==="unusual").length,notable:t.filter(n=>n.severity==="notable").length}}function Rn(){const e=ie(w.flatMap(n=>n?.hbinDefs??[])),t=ie(w.flatMap(n=>n?.sbinDefs??[]));Po(ui({items:w.map((n,o)=>({label:Ie(n,o),wafer:n?.wafer,dies:n?.dies,passBins:Qe(n),statsSummary:n?.statsSummary})),hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:ue(),ringCount:Je()}),{anchor:u})}function In(){if(!h)return;h.innerHTML="";const e=Ln();if(w.length>0){const n=u.ownerDocument.createElement("div"),o=e.length,l=w.filter(Boolean).length;n.textContent=o===0?`No findings on any of the ${l} wafers`:`${o} of ${l} wafer${l===1?"":"s"} with findings`,Object.assign(n.style,{fontSize:O.body,color:m.label,marginBottom:v.md}),h.appendChild(n)}if(e.length>0){const n=u.ownerDocument.createElement("button");n.type="button",n.textContent="Summary report",Object.assign(n.style,{...ko("outlined"),marginBottom:v.lg,display:"block",width:"100%",textAlign:"left"}),ht(n),n.addEventListener("click",Rn),h.appendChild(n)}if(e.length===0){const n=u.ownerDocument.createElement("div");Object.assign(n.style,{color:m.icon,fontSize:O.body,padding:"4px 0"}),n.textContent="No findings on any wafer.",h.appendChild(n)}else for(const{index:n,item:o,unusualCount:l,notableCount:a,totalCount:s}of e){const r=l?"unusual":a?"notable":"info",i=l+a||s,c=u.ownerDocument.createElement("button");c.type="button",Object.assign(c.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:v.xs,border:"none",borderLeft:`3px solid ${ln(r)}`,borderRadius:z.control,background:m.bgHover,cursor:"pointer",fontSize:O.body,textAlign:"left",boxSizing:"border-box"}),c.addEventListener("mouseover",()=>{c.style.background=m.bgActive}),c.addEventListener("mouseout",()=>{c.style.background=m.bgHover});const f=u.ownerDocument.createElement("span");f.textContent=Ie(o,n),Object.assign(f.style,{color:m.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const b=u.ownerDocument.createElement("span");b.textContent=String(i),c.setAttribute("aria-label",`${Ie(o,n)} \u2014 ${i} finding${i===1?"":"s"}${l?`, ${l} unusual`:""} \u2014 view wafer`),Object.assign(b.style,{marginLeft:v.sm,flexShrink:"0",background:ln(r),color:"#fff",borderRadius:z.container,padding:"1px 5px",fontSize:O.body,fontWeight:"600"}),c.appendChild(f),c.appendChild(b),c.addEventListener("click",()=>Le(n,o)),h.appendChild(c)}const t=u.ownerDocument.createElement("div");t.style.height="12px",h.appendChild(t)}function V(){if(h)if(j){const e=ie(w.flatMap(n=>n?.hbinDefs??[])),t=ie(w.flatMap(n=>n?.sbinDefs??[]));fi(h,{lotSummary:j,items:w,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:ue(),ringCount:Je(),binColors:d.binColors,plotMode:d.plotMode??"hardBin",fallbackFormat:d.fallbackFormat,activeFindingId:ve,warnings:p.warnings?.display??!0?J:[],findingsFilter:kn,findingsNotice:kt,onFindingsFilterChange:V,onSaveText:p.onSaveText,onFindingClick:(n,o)=>{ve===n.id?ot():Pn(n,o),V()},onWaferClick:$n,findingsFor:Wn,dieListOptions:p.dieList})}else In()}function An(e){const t=e.highlight;return t?.kind==="wafer"&&t.waferIndices?.length?t.waferIndices:null}function Lt(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}let Fe=[];function $t(){if(Fe.length!==0){for(const e of Fe)S[e]?.setOptions({plotMode:d.plotMode,activeTest:d.activeTest});Fe=[]}}function ot(){ve=null,Ot(),Tt(),$t(),E({highlightBin:void 0},{fireCallback:!1})}function Pn(e,t){if(ve===e.id){ot();return}ve=e.id,t.style.background=m.bgActive,t.style.fontWeight="600",$t();const{kind:n,index:o}=e.variable;if(n==="test"){const a=o??0,s=ue();if(s===void 0||s.some(i=>i.testNumber===a))E({plotMode:"value",activeTest:a,highlightBin:void 0},{fireCallback:!1});else{E({highlightBin:void 0},{fireCallback:!1});const c=be.has(d.plotMode??"hardBin")?null:An(e);if(c){for(const f of c)S[f]?.setOptions({plotMode:"value",activeTest:a});Fe=[...c]}}}else n==="softBin"?E({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):E({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1});Ot(),Tt();const l=e.highlight;if(l.kind==="wafer"){Et(l.waferIndices);const a=Lt(e);for(const s of l.waferIndices){const c=T[s]?.statsSummary?.findings.find(f=>Lt(f)===a)?.highlight?.dieKeys;c?.length&&nt(c,[s])}}else l.kind==="bin"?l.dieKeys?.length&&nt(l.dieKeys):(l.kind==="region"||l.kind==="dies")&&l.dieKeys?.length&&nt(l.dieKeys)}function le(){if(!P)return;const e=!!h;P.style.display=(j||tt())&&e&&!Ee?"flex":"none";const t=h?h.style.display!=="none":!1;(j?.hasNotableFindings||w.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?P.style.color=m.findingIndicator:P.dataset.active||(P.style.color=m.icon)}const $=u.ownerDocument.createElement("div");$.dataset.wmapToolbar="gallery",Object.assign($.style,{flexShrink:"0",marginLeft:"auto",display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:z.control,padding:"0",boxShadow:We.panel,flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const Wt=()=>{const e=Ce();e&&(e.remove(),Se(null)),Re(X,!1)},X=Q("mode","Plot mode",()=>{if(Ce()){Wt();return}const e=w.flatMap(y=>y?.dies??[]),t=ue(),{testEntries:n,binEntries:o,stackedEntries:l}=Zo(e,t,{includeStacked:!0}),a=w.filter(Boolean).length,s=y=>{if(y===void 0)return a;let R=0;for(const de of w)de?.dies?.some(U=>wn(U,y)!==void 0||U.testValues?.[y]!==void 0)&&R++;return R},r=a<2?n:n.map(y=>{const R=s(y.activeTest);return R===a?y:{...y,label:`${y.label} \u2014 ${R} of ${a} wafers`}}),i=d.plotMode??"hardBin",c=d.activeTest??0;function f(y){return y.plotMode!==i?!1:y.plotMode==="value"?c===(y.activeTest??0):y.plotMode==="metadata"?d.activeMetadataKey===y.activeMetadataKey:!0}function b(y,R){y.activeTest!==void 0?E({plotMode:"value",activeTest:y.activeTest,activeMetadataKey:void 0,logScale:y.logScale}):y.activeMetadataKey!==void 0?E({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:y.activeMetadataKey,passFailDisplay:"off"}):E({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),R.remove(),Se(null),Re(X,!1)}const k=new Set,D=w.flatMap(y=>y?.metadataFields??[]).filter(y=>!k.has(y.key)&&k.add(y.key)).filter(y=>Yo(e,y.key)).map(Qo),M=Wo(X.getBoundingClientRect(),r,o,l,f,b,{makeMenuRow:On,makeMenuSection:Tn},i,X.ownerDocument.defaultView??window,D);fn(X).appendChild(M),Se(M),Re(X,!0),un(M,X,Wt)});Re(X,!1);const Hn=()=>T.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:Fn,sync:Rt}=Vo(pe,()=>({...d,plotMode:d.plotMode??"hardBin"}),Hn,e=>E(e));Rt();const jn=x.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function je(){const e=ue(),{testNumber:t}=mo(d.activeTest??0,e);return{testNumber:t,td:ho(e,t)}}function It(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=je();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function Me(){if((d.plotMode??"hardBin")!=="value")return!1;const{td:e}=je();return e!==void 0&&!bt(e)}function Vn(){if((d.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=je();return w.some(n=>n?.dies?.some(o=>wn(o,e,t)!==void 0))}function zn(e,t){if(!t||!bt(t))return;const n=t.limitLow!==void 0||t.limitHigh!==void 0;if((mn(d)==="spec"&&n?"spec":d.colorbarRangeMode??"spec")==="spec"&&n)return;let a=1/0,s=-1/0;for(const r of w)if(r)for(const i of r.dies){const c=si(i,e);c!==void 0&&(c<a&&(a=c),c>s&&(s=c))}if(isFinite(a))return a===s?[a,a+1]:[a,s]}function At(){if((d.plotMode??"hardBin")!=="metadata")return;const e=d.activeMetadataKey;if(!e)return;const t=new Set;for(const n of w)if(n)for(const o of bo(n.dies,e))t.add(o);return{key:e,values:[...t].sort(vn)}}function it(){const e=At();if(!(e===void 0&&d.metadataValueOrder===void 0)){d={...d,metadataValueOrder:e};for(const t of S)t&&t.setOptions({metadataValueOrder:e})}}function at(){if((d.plotMode??"hardBin")!=="value")return;const{testNumber:e,td:t}=je(),n=zn(e,t),o=n?{test:e,range:n}:void 0;d={...d,valueRange:o};for(const l of S)l&&l.setOptions({valueRange:o})}let st=!1;function Nn(){if(st)return;st=!0,(u.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{st=!1,at(),it(),Ht()})}let Pt=[];function De(){const e=ie(w.flatMap(l=>l?.hbinDefs??[])),t=ie(w.flatMap(l=>l?.sbinDefs??[])),{colors:n,mixedHardBins:o}=wo(w.flatMap(l=>l?[{dies:l.dies,passBins:Qe(l)}]:[]),{binColorScheme:d.binColorScheme,useDefinedBinColors:d.useDefinedBinColors,hbinDefs:e,sbinDefs:t});return Pt=o,n}function Ht(){const e=De();d={...d,binColors:e};for(const t of S)t&&t.setOptions({binColors:e});Be()}const _n=_o(pe,()=>qo(d,jn,{functionalActive:Me(),hasLimits:It()&&!Me(),hasRecorded:Vn()&&!Me(),binMode:(d.plotMode??"hardBin")==="hardBin"||(d.plotMode??"hardBin")==="softBin"},e=>E(e)),()=>Uo(d)),{btn:Gn,sync:Ft}=No(pe,()=>({plotMode:d.plotMode,legendPosition:ye}),e=>{ye=e;for(const t of S)t&&t.setOptions({legendPosition:ye})},{get:()=>Ae,set:e=>{Ae=e,xt()},blockedReason:we});Ft();const Kn=[{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"}],jt=Dt("aggr","Aggregation method",()=>Kn,()=>d.aggregationMethod??"mean",e=>E({aggregationMethod:e}));function Vt(){const e=d.plotMode==="stackedValues";jt.style.display=e?"":"none"}Vt();const{btn:qn,sync:zt}=zo(pe,()=>({...d,functionalActive:Me()}),e=>E(e));zt();const Ve=Q("specRange","Colorbar range: spec limits",()=>{const e=d.colorbarRangeMode==="data"?"spec":"data";E({colorbarRangeMode:e})});function Nt(){const e=(d.plotMode??"hardBin")==="value"&&It()&&mn(d)==="off"&&!Me();Ve.style.display=e?"":"none";const t=(d.colorbarRangeMode??"spec")==="spec";xe(Ve,t),Ve.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}Nt();const Un=Go(pe,()=>d,e=>E(e)),Xn=Q("downloadAll","Download gallery PNG",fo),Zn=Dt("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"}],()=>C!=null?String(C):"auto",e=>ao(e==="auto"?void 0:Number(e))),B=u.ownerDocument.createElement("div");Object.assign(B.style,{display:"inline-flex",alignItems:"center",gap:"0"}),$.appendChild(B),B.appendChild(X),B.appendChild(Fn),B.appendChild(jt),B.appendChild(qn),B.appendChild(Ve),B.appendChild(G()),B.appendChild(_n),B.appendChild(G()),B.appendChild(Gn),B.appendChild(G()),B.appendChild(Un),B.appendChild(G()),B.appendChild(Zn),B.appendChild(G()),B.appendChild(Xn),(j||tt())&&(P=Q("findings","Summary panel",()=>{if(!h)return;const e=h.style.display!=="none";e||V(),h.style.display=e?"none":"flex",xe(P,!e),le()}),$.appendChild(G()),$.appendChild(P));let K=null,ze=null,J=[],_t=!1;function Be(){const e=li({lotStatsSummary:j,result:{warnings:[...w.flatMap(n=>n?.warnings??[]),...Ct().warnings]},extra:[d.binColors&&vo(d.binColors,d.plotMode),xo(Pt),Dn(vt())].filter(n=>!!n)}),t=e.length!==J.length||e.some((n,o)=>n.code!==J[o]?.code||n.message!==J[o]?.message);J=e,(t||!_t)&&(_t=!0,p.warnings?.onWarning?.(e)),Yn()}function Yn(){if(!K||!ze)return;const e=J.length,t=e>0;if(K.style.display=t?"flex":"none",ze.style.display=t?"":"none",!t)return;const n=di(J[0]),o=`${e} data ${e===1?"warning":"warnings"}`;K.style.color=n==="error"?m.errText:m.warnText,K.ariaLabel=n==="error"?`${o} \u2014 some wafers may be positionally wrong`:o}(p.warnings?.display??!0)&&(ze=G(),K=Q("warning","Data warnings",()=>{const e=Ce();if(He(new MouseEvent("click")),e)return;const t=ri(K.getBoundingClientRect(),J,K.ownerDocument.defaultView??window);fn(u).appendChild(t),Se(t),un(t,K,()=>He(new MouseEvent("click")))}),Re(K,!1),$.appendChild(ze),$.appendChild(K)),Be();let re=null;F&&(re=Q("analysis","Insights",()=>{qt(!Ee)}),re.dataset.wmapInsightsBtn="1",$.appendChild(G()),$.appendChild(re));function Gt(){import("./userGuideHtml.js").then(e=>jo({buildWaferMap:ai,renderWaferMap:ni,renderWaferGallery,analyzeWaferMap:Ze},e.USER_GUIDE_HTML,N,u))}L&&($.appendChild(G()),$.appendChild(Q("help","User guide",()=>Gt())));const ge=u.ownerDocument.createElement("div");ge.dataset.wmapGalleryMeta="1",Object.assign(ge.style,{flex:"1",minWidth:"0",overflow:"hidden",display:"flex",alignItems:"center",padding:`${v.sm} ${v.lg}`,fontSize:O.sub,lineHeight:Xe.none,boxSizing:"border-box"});const Ne=u.ownerDocument.createElement("div");Object.assign(Ne.style,{background:m.canvasBg,display:"flex",alignItems:"stretch",gap:v.lg,paddingBottom:v.lg,minWidth:"0"});const ee=u.ownerDocument.createElement("div");ee.dataset.wmapGalleryLegend="1",Object.assign(ee.style,{display:"flex",flexDirection:"column",gap:v.sm,background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:z.container,padding:`${v.sm} ${v.lg}`,marginBottom:v.lg,boxShadow:We.panel,fontSize:O.body,lineHeight:Xe.none,boxSizing:"border-box",width:"100%",minWidth:"0"});const q=u.ownerDocument.createElement("div");Object.assign(q.style,{display:"flex",flexDirection:"row",alignItems:"flex-start"});let me=null,ke=null,Kt=null;function Qn(){return F?me?Promise.resolve(me):(Kt??=import("./insightsTab.js").then(({createInsightsTab:e})=>(me=e({getItems:()=>w,getLotStats:()=>j,getBinColors:()=>d.binColors??De(),getRingCount:Je,defaultView:p.insights?.defaultView,onOpenGuide:void 0,showMetadataStrip:!1,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,ownerDocument:u.ownerDocument,openWafer:(t,n,o)=>{const l=w[t];if(!l)return;let a=null;const s=Ao({title:n,onClose:()=>a?.destroy(),anchor:u});en(s,n,l.wafer.metadata??void 0),a=ft(s.contentWrap,l,o)}}),ke=me.el,ke.style.display="none",u.appendChild(ke),me)),Kt):Promise.resolve(null)}let Ee=!1;function qt(e){F&&(Ee=e,ke&&(ke.style.display=e?"flex":"none"),q.style.display=e?"none":"flex",B.style.display=e?"none":"inline-flex",$.style.display="inline-flex",re&&(xe(re,e),re.innerHTML=e?$e.wafer:$e.analysis,re.ariaLabel=e?"Back to gallery view":"Insights"),le(),Ke(),e&&Qn().then(t=>{!t||!Ee||(t.el.style.display="flex",t.render())}))}F&&p.insights?.defaultOpen&&queueMicrotask(()=>qt(!0));const Jn=4,lt=240,Ut=480,eo=720,to=1.25;let Z=Ut;function Xt(e){const t=I*2+110+2;let n=null;for(const o of e){if(o==null||!o.dies?.length)continue;const l=o.dies[0].width;if(!(l>0))continue;const a=o.wafer.radius*2*(Jn/l),s=Math.ceil(a+t);(n==null||s>n)&&(n=s)}return n}function no(e){const t=Xt(e);return t==null?lt:Math.min(Z,Math.max(lt,t))}function oo(e){const t=Xt(e);if(t==null)return!1;const n=Math.min(eo,Math.max(Ut,t));return n<=Z?!1:(Z=n,!0)}function io(){for(const e of Array.from(W.children))e.classList.contains("wmap-gallery-card")&&(e.style.maxWidth=`${Z}px`,e.style.maxHeight=`${Z}px`)}let _e=lt,Zt=0;function Yt(e){const t=oo(e);if(t&&io(),C!=null){t&&Ge();return}const n=no(e);n>_e&&(_e=n),Ge()}function ao(e){C=e,Ge()}function rt(e){return`repeat(${e}, minmax(0, ${Z}px))`}function Qt(e){W.style.gridTemplateColumns!==e&&(W.style.gridTemplateColumns=e)}function Ge(){if(C!=null){Qt(rt(C));return}const e=Math.max(1,Zt),t=12,n=W.clientWidth||0,o=a=>(n-t*(a-1))/a;let l=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){const a=Math.min(Z,_e*to),s=r=>{let i=0;for(;i<e&&o(i+1)>=r;)i++;return i};l=s(a)||s(_e)||1}Qt(rt(l))}const W=u.ownerDocument.createElement("div");if(Object.assign(W.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:rt(1),gap:v.xl,paddingLeft:oe,paddingRight:oe,justifyContent:"start",alignContent:"start",isolation:"isolate"}),ce?.placement){const e=ce.placement;h=yt(e,oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.display="flex",h.style.flexDirection="column"}else if(j||tt()){const e=!!ce?.defaultOpen;h=yt("right",oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display=e?"flex":"none",V()}le(),h?.style.display!=="none"&&P&&xe(P,!0),(ce?.placement??"right")==="left"?(h&&q.appendChild(h),q.appendChild(W)):(q.appendChild(W),h&&q.appendChild(h));const Oe=u.ownerDocument.createElement("div");Object.assign(Oe.style,{position:"sticky",top:"0",display:"flex",flexDirection:"column",paddingLeft:oe,paddingRight:oe,paddingTop:oe,zIndex:"1",background:m.menuBg}),Ne.appendChild(ge),Ne.appendChild($),Oe.appendChild(Ne),Oe.appendChild(ee),u.appendChild(Oe),u.appendChild(q);function Ke(){ee.innerHTML="";const e=d.plotMode??"hardBin",t=!Ee&&rn.has(e),n=T.filter(g=>g!=null),o=n.find(g=>g.isLotStack),l=ci(n.map(g=>({metadata:g.wafer.metadata??void 0})),o?{lotSize:o.lotSize??n.length,aggrMethod:o.aggrMethod}:void 0),a=e==="metadata",s=d.activeMetadataKey,r=t&&!a?Sn(n,g=>(e==="softBin"?g.sbin:g.hbin)??void 0,Qe):{counts:new Map,total:0,pass:0},i=t&&!a?d.binColors??De():void 0,c=i?e==="softBin"?i.pass.soft:i.pass.hard:new Set,f=Jo(r.counts.entries(),c).map(([g])=>g),b=t&&a&&s?Sn(n,g=>yo(g.metadata?.[s])):{counts:new Map,total:0,pass:0},k=a?At()?.values:void 0,D=t&&a?(k??[...b.counts.keys()].sort(vn)).filter(g=>b.counts.has(g)):[];if(ge.innerHTML="",l&&ge.appendChild(l),ge.style.display=l?"flex":"none",!f.length&&!D.length){ee.style.display="none";return}ee.style.display="flex";const M=u.ownerDocument.createElement("div");Object.assign(M.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:`${v.sm} ${v.xl}`,maxHeight:"86px",overflowY:"auto",overflowX:"hidden"}),ee.appendChild(M);const y=d.highlightBin,R=T.flatMap(g=>g?.metadataFields??[]).find(g=>g.key===s),de=a?R?.label??(s?pi(s):"Metadata"):Oo[e],U=u.ownerDocument.createElement("span");if(U.textContent=de,Object.assign(U.style,{fontSize:O.body,fontWeight:"700",letterSpacing:Bo,textTransform:"uppercase",color:m.label,flexShrink:"0"}),M.appendChild(U),!a&&r.total>0){const g=r.pass,H=g/r.total*100,te=u.ownerDocument.createElement("span");te.textContent=`Yield ${Ye(H)}`,Object.assign(te.style,{fontSize:O.body,fontWeight:"700",color:m.value,whiteSpace:"nowrap",flexShrink:"0"});const ne=u.ownerDocument.createElement("span");ne.textContent=`${g.toLocaleString()} / ${r.total.toLocaleString()} dies`,Object.assign(ne.style,{fontSize:O.body,color:m.label,whiteSpace:"nowrap",flexShrink:"0"}),M.appendChild(te),M.appendChild(ne)}if(a){const g=d.highlightMetadataValue;D.forEach((H,te)=>{const ne=g===H,Ue=R?.values?.find(mt=>mt.value===H),po=Ue?.color??Mo(te),sn=b.counts.get(H)??0;Mn(M,{color:po,isActive:ne,label:Ue?.label??H,count:sn,percent:b.total>0?sn/b.total*100:void 0,onClick:()=>{const mt=d.highlightMetadataValue===H?void 0:H;E({highlightMetadataValue:mt})}})});return}const ut=e==="softBin"?T.flatMap(g=>g?.sbinDefs??[]):T.flatMap(g=>g?.hbinDefs??[]),nn=new Set,pt=[];for(const g of ut)nn.has(g.bin)||(nn.add(g.bin),pt.push(g));const gt=pt.length>0?new Map(pt.map(g=>[g.bin,g])):null,on=i??d.binColors??De(),uo=e==="softBin"?on.soft:on.hard,an=g=>uo.get(g)??So;for(const g of f){const H=y===g,te=gt?.get(g),ne=r.counts.get(g)??0;Mn(M,{color:an(g),isActive:H,label:te?.name?`${g} \xB7 ${te.name}`:`Bin ${g}`,count:ne,percent:r.total>0?ne/r.total*100:void 0,onClick:()=>{const Ue=d.highlightBin===g?void 0:g;E({highlightBin:Ue})}})}r.total>0&&f.length>1&&ee.appendChild(bi(u.ownerDocument,[...r.counts.entries()].sort(([,g],[,H])=>H-g).map(([g,H])=>({color:an(g),count:H,label:gt?.get(g)?.name?`${g} \xB7 ${gt.get(g).name}`:`Bin ${g}`})),r.total))}function Te(e){const t=w.filter(r=>r!==null);if(!t.length)return[];const n=t.map(r=>r.dies.filter(hi)),o=t[0].wafer,l=t.length,a=o.metadata?{...o,metadata:(({wafer:r,waferId:i,...c})=>c)(o.metadata)}:o;function s(r,i){return{...r,stats:{...r.stats,isLotStack:!0,aggregationMethod:i,lotSize:l}}}if(e==="stackedValues"){const r=ue();let i=r?.filter(bt);if(r!==void 0&&i?.length===0)return[];if(r?.length||(i=go(t.flatMap(b=>b.dies)).map(b=>({testNumber:b,name:`Test ${b}`}))),!i?.length)return[];const c=d.aggregationMethod??"mean";return i.map(f=>{const b=ti(n,c,f.testNumber),k={testNumber:0,name:f.name,unit:f.unit};return{wafer:a,dies:b,testDefs:[k],label:`${f.name} \xB7 ${c}`,isLotStack:!0,aggrMethod:c,lotSize:l,statsSummary:s(Ze({wafer:a,dies:b,testDefs:[k]},{testNumbers:[0]}),c)}})}if(e==="stackedBins"){let r=ie(t.flatMap(i=>i.hbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(c=>c.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((c,f)=>c-f).map(c=>({bin:c,name:`Bin ${c}`}))),r.map(i=>{const c=hn(n,i.bin,"hard"),f=[{bin:i.bin,name:i.name}];return{wafer:a,dies:c,hbinDefs:f,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:l,statsSummary:s(Ze({wafer:a,dies:c,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let r=ie(t.flatMap(i=>i.sbinDefs??[]));return(!r||r.length===0)&&(r=[...new Set(t.flatMap(c=>c.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((c,f)=>c-f).map(c=>({bin:c,name:`Bin ${c}`}))),r.map(i=>{const c=hn(n,i.bin,"soft"),f=[{bin:i.bin,name:i.name}];return{wafer:a,dies:c,sbinDefs:f,label:`${i.bin} \xB7 ${i.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:l,statsSummary:s(Ze({wafer:a,dies:c,sbinDefs:f}),"countBin")}})}return t}function dt(e){const t=w.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:d.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}function E(e,{fireCallback:t=!0}={}){const n=Object.keys(e),o=d.plotMode,l=we()!==null;d={...d,...e};const a=d.plotMode,s=be.has(a),r=o!==void 0&&be.has(o),i=Pe>0;if("binColorScheme"in e||"useDefinedBinColors"in e){const f=De();d={...d,binColors:f},e={...e,binColors:f}}if(e.plotMode!==void 0)if(s){const f=dt(a);if(d={...d,...f},i)for(const b of S)b&&b.setOptions(e);else Y(Te(a))}else if(r){const{valueRange:f,lotSize:b,aggregationMethod:k,...D}=d;if(d=D,i)for(const M of S)M&&M.setOptions(e);else Y(w.filter(M=>M!==null))}else for(const f of S)f&&f.setOptions(e);else if(e.aggregationMethod!==void 0&&a==="stackedValues")if(i)for(const f of S)f&&f.setOptions(e);else Y(Te("stackedValues"));else for(const f of S)f&&f.setOptions(e);we()!==null!==l&&xt(),Ke(),Vt(),Ft(),Rt();const c=e.plotMode!==void 0&&e.plotMode!==o;(ii.some(f=>f in e)||c)&&V(),Be(),zt(),Nt(),at(),it(),t&&p.onViewOptionsChange?.(yn(d),n,oi(n))}function Jt(e,t,n){const o=e.createElement("div");Object.assign(o.style,{display:"flex",alignItems:"center",gap:v.xs,flex:"1",minWidth:"0"});const l=e.createElement("span");l.textContent=t,Object.assign(l.style,{fontWeight:"700",fontSize:O.sub,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(l);const a=Cn(n??{});let s=null;if(a.length>0){const r=e.createElement("span");Object.assign(r.style,{fontSize:O.body,lineHeight:Xe.none,color:m.label,flexShrink:"0"}),r.textContent="\u25BE",o.appendChild(r),Object.assign(o.style,{cursor:"pointer",borderRadius:z.control}),o.addEventListener("mouseenter",()=>{o.style.background=m.bgHover}),o.addEventListener("mouseleave",()=>{o.style.background="none"}),s=e.createElement("div"),s.dataset.wmapCardMetaPanel="1",Object.assign(s.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:dn,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:We.menu,padding:`${v.md} ${v.lg}`,fontSize:O.body,display:"none"});const i=xn(n??{});i&&s.appendChild(i),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),pn(o,c=>{r.textContent=c?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(c)),s&&(s.style.display=c?"block":"none")})}return{wrap:o,metaPanel:s}}function en(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),l=Cn(n??{});if(!o||l.length===0)return;const a=o.parentElement,s=u.ownerDocument.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:v.xs,flex:"1",minWidth:"0",cursor:"pointer"}),ht(s,"bare"),a?.insertBefore(s,o),s.appendChild(o);const r=u.ownerDocument.createElement("span");Object.assign(r.style,{fontSize:O.body,lineHeight:Xe.none,color:m.label,flexShrink:"0"}),r.textContent="\u25BE",s.appendChild(r);const i=u.ownerDocument.createElement("div");i.dataset.wmapCardMetaPanel="1",Object.assign(i.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:dn,background:m.menuBg,borderBottom:`1px solid ${m.menuBorder}`,boxShadow:We.menu,padding:`${v.md} ${v.lg}`,fontSize:O.body,display:"none"});const c=xn(n??{});c&&i.appendChild(c),e.contentWrap.style.position="relative",e.contentWrap.appendChild(i),s.setAttribute("aria-expanded","false"),s.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),pn(s,f=>{r.textContent=f?"\u25B4":"\u25BE",s.setAttribute("aria-expanded",String(f)),i.style.display=f?"block":"none"})}function ct(e,t,n){const o=u.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:z.container,boxShadow:We.panel,overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:`${Z}px`,maxHeight:`${Z}px`});const l=u.ownerDocument.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",padding:`${v.md} ${v.lg} ${v.sm}`,borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:v.sm});const{wrap:a,metaPanel:s}=Jt(document,Ie(e,t),e.wafer.metadata??void 0);l.appendChild(a);const r=u.ownerDocument.createElement("button");r.dataset.wmapExpandBtn="1",r.setAttribute("aria-label","Open full view"),gn(r),r.innerHTML=$e.expand,Object.assign(r.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${m.menuBorder}`,borderRadius:z.control,background:m.panelBg,color:m.label,padding:v.xxs,cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),ht(r),l.appendChild(r),o.appendChild(l);const i=u.ownerDocument.createElement("div");Object.assign(i.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),o.appendChild(i),s&&i.appendChild(s),W.appendChild(o);const c=Ae||we()!==null,f=e.viewOptions?{...d,...e.viewOptions}:d,b=bn(i,e,{viewOptions:{...f,showLegend:c,legendPosition:ye},showTooltip:!0,padding:I,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>Le(t,e),showIdentity:!1,chromeInset:Eo});return b.setViewControlsVisible(!1),b.setSummaryVisible(!1),r.onclick=()=>Le(t,e),{card:o,ctrl:b,canvasWrapper:i,expandBtn:r}}function so(e){const t=fe[e];if(!t)return;const n=[..._.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=$e.minimize,t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>ro(n.id)):(t.innerHTML=$e.expand,t.setAttribute("aria-label","Open full view"),t.onclick=()=>Le(e,T[e]))}function Y(e){co(),Ce()?.remove(),Se(null),ot(),T=[];for(const a of S)a&&a.destroy();S=[],se=[],fe=[],Pe=0,W.innerHTML="",Zt=e.length,Yt(e.map(a=>typeof a=="function"?null:a));const t=[];for(let a=0;a<e.length;a++){const s=e[a];if(typeof s=="function"){const r=u.ownerDocument.createElement("div");r.className="wmap-gallery-card",Object.assign(r.style,{background:m.menuBg,border:`1px solid ${m.menuBorder}`,borderRadius:z.container,aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const i=u.ownerDocument.createElement("span");i.textContent="\u2026",Object.assign(i.style,{color:m.label,fontSize:"18px"}),r.appendChild(i),W.appendChild(r),T.push(null),S.push(null),se.push(null),fe.push(null),t.push({index:a,factory:s,placeholder:r}),Pe++}else{const{ctrl:r,canvasWrapper:i,expandBtn:c}=ct(s,a,e.length);T.push(s),S.push(r),se.push(i),fe.push(c)}}Ht(),Ke(),at(),it();const n=++et;let o=0;function l(){if(n!==et)return;if(o>=t.length){if(be.has(d.plotMode)){const D=d.plotMode;Y(Te(D))}return}const{index:a,factory:s,placeholder:r}=t[o++],i=s();T[a]=i,w[a]=i,Yt([i]);const{card:c,ctrl:f,canvasWrapper:b,expandBtn:k}=ct(i,a,e.length);S[a]=f,se[a]=b,fe[a]=k,Pe--,r.replaceWith(c),Ke(),Nn(),!h&&!ce?.placement&&i.statsSummary?.findings.length?(h=yt("right",oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display="none",(ce?.placement??"right")==="left"?q.insertBefore(h,W):q.appendChild(h),V(),P||(P=Q("findings","Summary panel",()=>{if(!h)return;const M=h.style.display!=="none";M||V(),h.style.display=M?"none":"flex",xe(P,!M),le()}),$.appendChild(G()),$.appendChild(P)),le()):h&&h.style.display!=="none"&&V(),le(),setTimeout(l,0)}t.length>0&&setTimeout(l,0)}if(be.has(d.plotMode)&&w.length>0){const e=dt(d.plotMode);d={...d,...e},Y(Te(d.plotMode))}else Y(x);Be();let he=0;const tn=new(u.ownerDocument.defaultView??window).ResizeObserver(()=>{if(he)return;he=(u.ownerDocument.defaultView??window).requestAnimationFrame(()=>{he=0,C==null&&Ge()})});tn.observe(W),h&&V();function lo(e,t){const n=se[e];if(!n)return;n.innerHTML="",Object.assign(n.style,{alignItems:"center",justifyContent:"center"});const o=u.ownerDocument.createElement("span");o.textContent=t?"Opened in its own window":"Opened in the wafer viewer",Object.assign(o.style,{color:m.label,fontSize:O.body,textAlign:"center",padding:"0 12px"}),n.appendChild(o)}function Le(e,t){for(const s of _.values())if(s.cardIndex===e)return;const n=Ie(t,e),o=Bn++,l=S[e]?.getOptions(),a=Ro(n);if(a){const s=a.document;s.title=n,Object.assign(s.documentElement.style,{height:"100%"}),Object.assign(s.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:O.family}),Ho(u,s.documentElement);const r=Fo(u,s.documentElement,()=>M.setOptions({})),i=s.createElement("div");i.dataset.wmapWindowBanner="1",i.textContent=n,Object.assign(i.style,{display:"none",padding:`${v.sm} ${v.xl}`,fontSize:O.body,fontWeight:"700",background:m.warnBg,color:m.warnText,borderBottom:`1px solid ${m.warnBorder}`,flexShrink:"0"}),s.body.appendChild(i);const c=s.createElement("div");Object.assign(c.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),s.body.appendChild(c);const{wrap:f,metaPanel:b}=Jt(s,n,t.wafer.metadata??void 0),k=s.createElement("div");Object.assign(k.style,{display:"flex",alignItems:"center",padding:`${v.md} ${v.lg} ${v.sm}`,borderBottom:`1px solid ${m.menuBorder}`,flexShrink:"0",gap:v.sm}),k.appendChild(f),c.appendChild(k);const D=s.createElement("div");Object.assign(D.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),b&&D.appendChild(b),c.appendChild(D);const M=ft(D,t,void 0,l),y=setInterval(()=>{a.closed&&qe(o)},400);a.addEventListener("pagehide",()=>qe(o)),_.set(o,{id:o,ctrl:M,cardIndex:e,label:n,closePollId:y,stopThemeSync:r,close:()=>{a.closed||a.close()},setTitle:R=>{s.title=R,i.textContent=R,i.style.display="block"}})}else{const s=Io({title:n,onClose:()=>qe(o),anchor:u});s.contentWrap.style.flexDirection="column",en(s,n,t.wafer.metadata??void 0);const r=ft(s.contentWrap,t,void 0,l);_.set(o,{id:o,ctrl:r,cardIndex:e,label:n,closePollId:null,close:()=>s.close(),setTitle:i=>{const c=s.box.querySelector("[data-wmap-window-title]");c&&(c.textContent=i,c.title=i)}})}S[e]?.destroy(),S[e]=null,lo(e,a!==null),so(e)}function ft(e,t,n,o){const l=t.viewOptions?{...d,...t.viewOptions}:d,a=o?{...l,...o}:l,r={...n!==void 0?{...a,plotMode:"value",activeTest:n}:a,showLegend:!0,legendPosition:ye},i=bn(e,t,{viewOptions:r,showTooltip:!0,padding:I,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showIdentity:!1});return i.setViewControlsVisible(!0),i.setSummaryVisible(!0),i.setExpandVisible(!1),i}function qe(e){const t=_.get(e);if(!t)return;_.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.();const n=t.ctrl.getOptions();if(t.ctrl.destroy(),t.cardIndex===null)return;const o=t.cardIndex,l=T[o];if(!l)return;const a={...l,viewOptions:n};T[o]=a;const{card:s,ctrl:r,canvasWrapper:i,expandBtn:c}=ct(a,o,T.length);se[o]?.parentElement?.replaceWith(s),S[o]=r,se[o]=i,fe[o]=c}function ro(e){const t=_.get(e);t&&(t.close(),qe(e))}function co(){for(const e of _.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function fo(){const e=[...W.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),o=Math.ceil(t/n),l=e[0].width,a=e[0].height,s=8,r=(u.ownerDocument.defaultView??window).devicePixelRatio||1,i=Math.round(26*r),c=Math.round(12*r),f=u.ownerDocument.createElement("canvas");f.width=n*l+(n-1)*s,f.height=o*(a+i)+(o-1)*s;const b=f.getContext("2d"),k=Do(W);b.fillStyle=k.background,b.fillRect(0,0,f.width,f.height),e.forEach((D,M)=>{const y=M%n,R=Math.floor(M/n),de=y*(l+s),U=R*(a+i+s),ut=D.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";b.fillStyle=k.surface,b.fillRect(de,U,l,i),b.fillStyle=k.text,b.font=`700 ${c}px system-ui, sans-serif`,b.textAlign="left",b.textBaseline="middle",b.fillText(ut,de+Math.round(10*r),U+i/2,l-Math.round(20*r)),b.drawImage(D,de,U+i)}),f.toBlob(D=>{D&&Ko(D,A,p.onSaveImage)})}return{setItems(e){w=e.map(n=>typeof n=="function"?null:n);const t=d.plotMode;if(be.has(t))if(e.some(o=>typeof o=="function"))Y(e);else{const o=dt(t);d={...d,...o},Y(Te(t))}else Y(e)},setOptions(e){E(e,{fireCallback:!1})},getOptions(){return yn(d)},setFindingsNotice(e){kt=e,V()},setLotStatsSummary(e){j=e,Be(),h&&V(),le()},openUserGuide:Gt,destroy(){et++;for(const e of[..._.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();_.clear();for(const e of S)e&&e.destroy();S=[],Ce()?.remove(),tn.disconnect(),he&&((u.ownerDocument.defaultView??window).cancelAnimationFrame(he),he=0),u.ownerDocument.removeEventListener("click",He,!0),window.removeEventListener("blur",Bt),ae(),cn(),Oe.remove(),q.remove(),h?.remove(),me?.destroy()}}}
|
|
1
|
+
import{getUniqueTestNumbers as bo,resolveTestNumber as yo,findTestDef as wo,collectMetadataValues as xo}from"../renderer/buildView.js";import{metadataCategoricalValue as vo}from"../core/metadata.js";import{resolveBinColorsForMaps as Co,mergeBinDefs as Ke,binColorWarning as So,mixedPassBinsWarning as Mo}from"../renderer/binColors.js";import{itemPassBins as Do,INPUT_DEFAULT_PASS_BINS as Bo}from"../core/passBins.js";import{NO_DATA_FILL as ko}from"../renderer/colorMap.js";import{metadataValueColor as Eo}from"../renderer/colorMap.js";import{resolveCanvasTheme as Oo}from"./canvasTheme.js";import{ICONS as Te}from"./icons.js";import{SHADOW as Le,LEADING as qe,TRACKING as To,controlStyle as Lo,wireControlHover as ht,SPACE as w,EDGE_GUTTER as oe,MAP_CHROME_INSET as $o,RADIUS as N,FONT as T,CLR as g,sevColor as cn,MODE_LABELS as Wo,BIN_LEGEND_MODES as un,STACKED_MODES as ge,Z_ABOVE as fn,applyOverlayZ as Ro,getTooltip as Io,hideTooltip as pn,createToolbarHelpers as Ao,buildModeMenuEl as Po,openDetachWindow as Fo,openFloatingWindow as Ho,openModal as jo,openReportModal as Vo,copyWmapThemeTokens as zo,syncWmapPopupTheme as No,openUserGuideWindow as _o,makePaletteBtn as Go,makeLogScaleBtn as Ko,makeLegendStyleBtn as qo,makeOverlaysBtn as Uo,makeOrientationBtn as Xo,menuLayerFor as mn,saveImageBlob as gn,markMenuTrigger as $e,wireMenuA11y as hn,wireExpandToggle as bn,wireTooltip as yn,requestedPassFailDisplay as wn,overlayMenuRows as Zo,anyOverlayActive as Yo,logWmapVersionOnce as Qo,buildDataModeEntries as Jo,metadataKeyHasData as ei,metadataModeEntry as ti}from"./toolbar.js";import{waferDisplayLabel as Ue,waferIdentityLabel as ni}from"../core/waferLabel.js";import{metadataDisplayValue as oi}from"../core/metadata.js";import{withExportContext as ii,noticeDownloadFilenameChange as ai}from"./exportName.js";import{sortBinsForDisplay as li}from"../stats/binPareto.js";import{diePassStatus as si}from"../core/dies.js";import{aggregateValues as ri,aggregateBinCounts as xn}from"../core/aggregates.js";import{renderWaferMap as di,renderWaferMapCard as vn,toPublicViewOptions as Cn}from"./renderWaferMap.js";import{classifyChanged as ci,COLOR_KEYS as ui}from"./renderWaferMap.js";import{buildWaferMap as fi,getTestPassStatus as Sn,isParametricTest as bt,getDieTestValue as pi}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Xe}from"../stats/analyzeWaferMap.js";import{collectWarnings as mi,buildWarningsMenuEl as gi,severityOf as hi}from"./warnings.js";import{compareNatural as yt}from"../core/utils.js";import{createSummaryPanelEl as wt,buildMetadataStripRow as bi,buildCompactMetadataRows as Mn,metadataEntries as Dn,renderLotSummaryContent as yi,reportMapsFromItems as wi}from"./summaryPanel.js";import{renderLotReportHtml as xi}from"../stats/renderSummaryReport.js";import{prettyKey as vi}from"../stats/facets.js";import{mergeTestDefs as Ci}from"../stats/mergeTestDefs.js";import{getDieKey as Si,hasPosition as Mi}from"../core/dies.js";function Bn(u){if(typeof u!="number"||!Number.isFinite(u))return;const v=Math.round(u);return v>=1?v:void 0}const xt=12;function Di(u,v,p){let A=v;if(v.length>xt){const D=v.slice(0,xt-1),$=v.slice(xt-1),H=$.reduce((Y,j)=>Y+j.count,0);A=[...D,{color:g.label,count:H,label:`Other (${$.length} bins)`}]}const M=u.createElement("div");Object.assign(M.style,{display:"flex",columnGap:"1px",width:"100%",height:"8px",borderRadius:N.control,overflow:"hidden",border:`1px solid ${g.menuBorder}`,boxSizing:"border-box",marginTop:w.xs,flexShrink:"0"}),M.setAttribute("role","img"),M.setAttribute("aria-label",`Population split: ${A.map(D=>`${D.label} ${Ze(D.count/p*100)}`).join(", ")}`);for(const D of A){const $=D.count/p*100,H=u.createElement("div");Object.assign(H.style,{flex:`${$} 1 0`,minWidth:$>0?"2px":"0",background:D.color}),yn(H,`${D.label} \xB7 ${D.count.toLocaleString()} dies \xB7 ${Ze($)}`),M.appendChild(H)}return M}function Ze(u){return u>0&&u<.1?"<0.1%":`${u.toFixed(1)}%`}function kn(u,v,p){const A=new Map;let M=0,D=0;for(const $ of u){const H=p?new Set(p($)):void 0;for(const Y of $.dies){if(Y.partial||Y.edgeExcluded)continue;const j=v(Y);j!==void 0&&(A.set(j,(A.get(j)??0)+1),M++,H&&si(Y,H)&&D++)}}return{counts:A,total:M,pass:D}}function En(u,v){const p=u.ownerDocument.createElement("div");Object.assign(p.style,{display:"flex",alignItems:"center",gap:"5px",cursor:"pointer",userSelect:"none",padding:`${w.xxs} ${w.xs}`,borderRadius:N.control});const A=u.ownerDocument.createElement("span");Object.assign(A.style,{display:"inline-block",width:"13px",height:"13px",flexShrink:"0",background:v.color,border:v.isActive?`2px solid ${g.iconActive}`:`1px solid ${g.menuBorder}`,borderRadius:N.control,boxSizing:"border-box"});const M=u.ownerDocument.createElement("span");if(M.textContent=v.label,Object.assign(M.style,{fontWeight:v.isActive?"700":"400",color:v.isActive?g.iconActive:g.text,whiteSpace:"nowrap"}),p.appendChild(A),p.appendChild(M),v.count!==void 0){const D=u.ownerDocument.createElement("span");if(D.textContent=v.count.toLocaleString(),Object.assign(D.style,{color:v.isActive?g.iconActive:g.text,fontWeight:v.isActive?"700":"400",whiteSpace:"nowrap"}),p.appendChild(D),v.percent!==void 0){const $=u.ownerDocument.createElement("span");$.textContent=Ze(v.percent),Object.assign($.style,{color:g.label,whiteSpace:"nowrap"}),p.appendChild($)}}p.setAttribute("role","button"),p.setAttribute("aria-pressed",v.isActive?"true":"false"),p.tabIndex=0,p.addEventListener("mouseenter",()=>{p.style.background=g.bgHover}),p.addEventListener("mouseleave",()=>{p.style.background="transparent"}),p.addEventListener("focus",()=>{p.style.background=g.bgHover}),p.addEventListener("blur",()=>{p.style.background="transparent"}),p.addEventListener("click",v.onClick),p.addEventListener("keydown",D=>{(D.key==="Enter"||D.key===" ")&&(D.preventDefault(),v.onClick())}),u.appendChild(p)}export function renderWaferGallery(u,v,p={}){Qo();const A=6;let M=Bn(p.columns);const D=p.showHelpButton??!1,$=p.userGuideExtension,H=p.insights?.enabled??!1,Y=Ro(p.zIndex),j=p.summaryPanel,On=e=>[...Do(e)],vt=()=>x.flatMap(e=>e?[e.ringCount??4]:[]),Ye=()=>vt()[0]??4;function Tn(e){const t=[...new Set(e)].sort((n,o)=>n-o);return t.length<2?null:{code:"ring-count-mixed",severity:"warning",message:`These wafers were built with different ring counts (${t.join(", ")}). Each card and each wafer's findings use their own; the lot's ring yield in the Summary panel, report and Insights uses ${e[0]} rings.`}}let V=p.lotStatsSummary,he=p.viewOptions?.legendPosition??"default",We=p.perCardLegend??!1;function be(){const e=r.plotMode??"hardBin";return un.has(e)?null:r.colorbarRangeMode==="data"?"Each map has its own value range, so it keeps its own colour bar":"These wafers have no shared colour bar for value mode, so each map keeps its own"}function Ct(){const e=We||be()!==null;for(const t of S)t&&t.setOptions({showLegend:e})}let r={plotMode:"hardBin",showDieLabels:!1,showRingBoundaries:!1,showQuadrantBoundaries:!1,rotation:0,flipX:!1,flipY:!1,...p.viewOptions},S=[],ie=[],re=[],L=[];const Re=ii(()=>{const e=L.filter(n=>n!=null);return{lots:[...new Set(e.map(n=>oi(n.wafer.metadata?.lot)).filter(n=>n!==void 0))].sort(yt),...e.length===1?{wafer:ni(e[0])}:{waferCount:e.length}}},p.onSaveImage,p.onSaveText);ai(p.downloadFilename);let x=v.map(e=>typeof e=="function"?null:e);function St(){return Ci(x)}function ye(){if(x.some(e=>e?.testDefs?.length))return St().defs}let Qe=0,Ie=0;const _=new Map;let Ln=0,P=null,we=null,Mt=new Set,h=null,$n={};function Dt(e){return x[e]?.statsSummary??V?.perWafer.find(t=>t.waferIndex===e)?.summary}function Je(){return!!(x.some(e=>e?.statsSummary?.findings.length)||V?.perWafer.some(e=>e.summary.findings.length))}const Wn=Io(),de=Ao(Wn),{makeBtn:Q,setActive:xe,makeSep:G,makeMenuRow:Rn,makeMenuSection:In,makeDropdown:Bt,closeOpenMenu:Ae,getOpenMenu:ve,setOpenMenu:Ce}=de;u.ownerDocument.addEventListener("click",Ae,!0);const kt=()=>pn();window.addEventListener("blur",kt);let Et=p.findingsNotice;function Ot(e){Mt=new Set(e);const t=[...R.querySelectorAll(".wmap-gallery-card")];let n;t.forEach((o,d)=>{const i=Mt.has(d);o.style.outline=i?`3px solid ${g.findingHighlight}`:"",o.style.outlineOffset=i?"-3px":"",i&&n===void 0&&(n=o)}),n?.scrollIntoView?.({behavior:"smooth",block:"nearest"})}function Tt(){Ot([])}function Lt(){for(const e of S)e&&e.clearSelection()}function et(e,t){const n=new Set(e),o=t??S.map((d,i)=>i);for(const d of o){const i=L[d],l=S[d];if(!i||!l)continue;const s=i.dies.filter(a=>n.has(Si(a)));l.setSelection(s)}}function An(){const e=[];for(let t=0;t<x.length;t++){const n=x[t];if(!n)continue;const o=Dt(t)?.findings??[];o.length&&e.push({index:t,item:n,unusualCount:o.filter(d=>d.severity==="unusual").length,notableCount:o.filter(d=>d.severity==="notable").length,totalCount:o.length})}return e}function Pn(e){const t=L[e]??x[e];t&&Oe(e,t)}function Fn(e){const t=Dt(e)?.findings??[];if(t.length)return{total:t.length,unusual:t.filter(n=>n.severity==="unusual").length,notable:t.filter(n=>n.severity==="notable").length}}function Hn(){Vo(xi(wi(x,Bo,Ye())),{anchor:u})}function jn(){if(!h)return;h.innerHTML="";const e=An();if(x.length>0){const n=u.ownerDocument.createElement("div"),o=e.length,d=x.filter(Boolean).length;n.textContent=o===0?`No findings on any of the ${d} wafers`:`${o} of ${d} wafer${d===1?"":"s"} with findings`,Object.assign(n.style,{fontSize:T.body,color:g.label,marginBottom:w.md}),h.appendChild(n)}if(e.length>0){const n=u.ownerDocument.createElement("button");n.type="button",n.textContent="Summary report",Object.assign(n.style,{...Lo("outlined"),marginBottom:w.lg,display:"block",width:"100%",textAlign:"left"}),ht(n),n.addEventListener("click",Hn),h.appendChild(n)}if(e.length===0){const n=u.ownerDocument.createElement("div");Object.assign(n.style,{color:g.icon,fontSize:T.body,padding:"4px 0"}),n.textContent="No findings on any wafer.",h.appendChild(n)}else for(const{index:n,item:o,unusualCount:d,notableCount:i,totalCount:l}of e){const s=d?"unusual":i?"notable":"info",a=d+i||l,c=u.ownerDocument.createElement("button");c.type="button",Object.assign(c.style,{display:"flex",alignItems:"center",justifyContent:"space-between",width:"100%",padding:"5px 8px",marginBottom:w.xs,border:"none",borderLeft:`3px solid ${cn(s)}`,borderRadius:N.control,background:g.bgHover,cursor:"pointer",fontSize:T.body,textAlign:"left",boxSizing:"border-box"}),c.addEventListener("mouseover",()=>{c.style.background=g.bgActive}),c.addEventListener("mouseout",()=>{c.style.background=g.bgHover});const f=u.ownerDocument.createElement("span");f.textContent=Ue(o,n),Object.assign(f.style,{color:g.iconHover,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});const b=u.ownerDocument.createElement("span");b.textContent=String(a),c.setAttribute("aria-label",`${Ue(o,n)} \u2014 ${a} finding${a===1?"":"s"}${d?`, ${d} unusual`:""} \u2014 view wafer`),Object.assign(b.style,{marginLeft:w.sm,flexShrink:"0",background:cn(s),color:"#fff",borderRadius:N.container,padding:"1px 5px",fontSize:T.body,fontWeight:"600"}),c.appendChild(f),c.appendChild(b),c.addEventListener("click",()=>Oe(n,o)),h.appendChild(c)}const t=u.ownerDocument.createElement("div");t.style.height="12px",h.appendChild(t)}function z(){if(h)if(V){const e=Ke(x.map(n=>n?.hbinDefs)),t=Ke(x.map(n=>n?.sbinDefs));yi(h,{lotSummary:V,items:x,hbinDefs:e.length?e:void 0,sbinDefs:t.length?t:void 0,testDefs:ye(),ringCount:Ye(),binColors:r.binColors,plotMode:r.plotMode??"hardBin",fallbackFormat:r.fallbackFormat,activeFindingId:we,warnings:p.warnings?.display??!0?J:[],findingsFilter:$n,findingsNotice:Et,onFindingsFilterChange:z,onSaveText:Re.onSaveText,onFindingClick:(n,o)=>{we===n.id?tt():zn(n,o),z()},onWaferClick:Pn,findingsFor:Fn,dieListOptions:p.dieList})}else jn()}function Vn(e){const t=e.highlight;return t?.kind==="wafer"&&t.waferIndices?.length?t.waferIndices:null}function $t(e){return[e.variable.kind,e.variable.index??"",e.variable.bin??"",e.comparison.family,e.comparison.left,e.effect.direction].join("|")}let Pe=[];function Wt(){if(Pe.length!==0){for(const e of Pe)S[e]?.setOptions({plotMode:r.plotMode,activeTest:r.activeTest});Pe=[]}}function tt(){we=null,Tt(),Lt(),Wt(),O({highlightBin:void 0},{fireCallback:!1})}function zn(e,t){if(we===e.id){tt();return}we=e.id,t.style.background=g.bgActive,t.style.fontWeight="600",Wt();const{kind:n,index:o}=e.variable;if(n==="test"){const i=o??0,l=ye();if(l===void 0||l.some(a=>a.testNumber===i))O({plotMode:"value",activeTest:i,highlightBin:void 0},{fireCallback:!1});else{O({highlightBin:void 0},{fireCallback:!1});const c=ge.has(r.plotMode??"hardBin")?null:Vn(e);if(c){for(const f of c)S[f]?.setOptions({plotMode:"value",activeTest:i});Pe=[...c]}}}else n==="softBin"?O({plotMode:"softBin",highlightBin:void 0},{fireCallback:!1}):O({plotMode:"hardBin",highlightBin:void 0},{fireCallback:!1});Tt(),Lt();const d=e.highlight;if(d.kind==="wafer"){Ot(d.waferIndices);const i=$t(e);for(const l of d.waferIndices){const c=L[l]?.statsSummary?.findings.find(f=>$t(f)===i)?.highlight?.dieKeys;c?.length&&et(c,[l])}}else d.kind==="bin"?d.dieKeys?.length&&et(d.dieKeys):(d.kind==="region"||d.kind==="dies")&&d.dieKeys?.length&&et(d.dieKeys)}function ae(){if(!P)return;const e=!!h;P.style.display=(V||Je())&&e&&!Be?"flex":"none";const t=h?h.style.display!=="none":!1;(V?.hasNotableFindings||x.some(o=>o?.statsSummary?.hasNotableFindings))&&!t?P.style.color=g.findingIndicator:P.dataset.active||(P.style.color=g.icon)}const W=u.ownerDocument.createElement("div");W.dataset.wmapToolbar="gallery",Object.assign(W.style,{flexShrink:"0",marginLeft:"auto",display:"inline-flex",flexDirection:"row",alignItems:"center",gap:"0",background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.control,padding:"0",boxShadow:Le.panel,flexWrap:"wrap",minWidth:"0",overflowX:"auto"});const Rt=()=>{const e=ve();e&&(e.remove(),Ce(null)),$e(X,!1)},X=Q("mode","Plot mode",()=>{if(ve()){Rt();return}const e=x.flatMap(y=>y?.dies??[]),t=ye(),{testEntries:n,binEntries:o,stackedEntries:d}=Jo(e,t,{includeStacked:!0}),i=x.filter(Boolean).length,l=y=>{if(y===void 0)return i;let I=0;for(const se of x)se?.dies?.some(U=>Sn(U,y)!==void 0||U.testValues?.[y]!==void 0)&&I++;return I},s=i<2?n:n.map(y=>{const I=l(y.activeTest);return I===i?y:{...y,label:`${y.label} \u2014 ${I} of ${i} wafers`}}),a=r.plotMode??"hardBin",c=r.activeTest??0;function f(y){return y.plotMode!==a?!1:y.plotMode==="value"?c===(y.activeTest??0):y.plotMode==="metadata"?r.activeMetadataKey===y.activeMetadataKey:!0}function b(y,I){y.activeTest!==void 0?O({plotMode:"value",activeTest:y.activeTest,activeMetadataKey:void 0,logScale:y.logScale}):y.activeMetadataKey!==void 0?O({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:y.activeMetadataKey,passFailDisplay:"off"}):O({plotMode:y.plotMode,activeTest:void 0,activeMetadataKey:void 0,passFailDisplay:"off"}),I.remove(),Ce(null),$e(X,!1)}const E=new Set,B=x.flatMap(y=>y?.metadataFields??[]).filter(y=>!E.has(y.key)&&E.add(y.key)).filter(y=>ei(e,y.key)).map(ti),C=Po(X.getBoundingClientRect(),s,o,d,f,b,{makeMenuRow:Rn,makeMenuSection:In},a,X.ownerDocument.defaultView??window,B);mn(X).appendChild(C),Ce(C),$e(X,!0),hn(C,X,Rt)});$e(X,!1);const Nn=()=>L.flatMap(e=>e?[...e.hbinDefs??[],...e.sbinDefs??[]]:[]).some(e=>e.color),{btn:_n,sync:It}=Go(de,()=>({...r,plotMode:r.plotMode??"hardBin"}),Nn,e=>O(e));It();const Gn=v.some(e=>typeof e!="function"&&(e.reticles?.length??0)>0);function Fe(){const e=ye(),{testNumber:t}=yo(r.activeTest??0,e);return{testNumber:t,td:wo(e,t)}}function At(){if((r.plotMode??"hardBin")!=="value")return!1;const{td:e}=Fe();return e!==void 0&&(e.limitLow!==void 0||e.limitHigh!==void 0)}function Se(){if((r.plotMode??"hardBin")!=="value")return!1;const{td:e}=Fe();return e!==void 0&&!bt(e)}function Kn(){if((r.plotMode??"hardBin")!=="value")return!1;const{testNumber:e,td:t}=Fe();return x.some(n=>n?.dies?.some(o=>Sn(o,e,t)!==void 0))}function qn(e,t){if(!t||!bt(t))return;const n=t.limitLow!==void 0||t.limitHigh!==void 0;if((wn(r)==="spec"&&n?"spec":r.colorbarRangeMode??"spec")==="spec"&&n)return;let i=1/0,l=-1/0;for(const s of x)if(s)for(const a of s.dies){const c=pi(a,e);c!==void 0&&(c<i&&(i=c),c>l&&(l=c))}if(isFinite(i))return i===l?[i,i+1]:[i,l]}function Pt(){if((r.plotMode??"hardBin")!=="metadata")return;const e=r.activeMetadataKey;if(!e)return;const t=new Set;for(const n of x)if(n)for(const o of xo(n.dies,e))t.add(o);return{key:e,values:[...t].sort(yt)}}function nt(){const e=Pt();if(!(e===void 0&&r.metadataValueOrder===void 0)){r={...r,metadataValueOrder:e};for(const t of S)t&&t.setOptions({metadataValueOrder:e})}}function ot(){if((r.plotMode??"hardBin")!=="value")return;const{testNumber:e,td:t}=Fe(),n=qn(e,t),o=n?{test:e,range:n}:void 0;r={...r,valueRange:o};for(const d of S)d&&d.setOptions({valueRange:o})}let it=!1;function Un(){if(it)return;it=!0,(u.ownerDocument.defaultView?.requestAnimationFrame??(t=>setTimeout(()=>t(0),0)))(()=>{it=!1,ot(),nt(),Ht()})}let Ft=[];function ce(){const{colors:e,mixedHardBins:t}=Co(x.filter(n=>n!=null),{binColorScheme:r.binColorScheme,useDefinedBinColors:r.useDefinedBinColors});return Ft=t,e}function Ht(){const e=ce();r={...r,binColors:e};for(const t of S)t&&t.setOptions({binColors:e});Me()}const Xn=Uo(de,()=>Zo(r,Gn,{functionalActive:Se(),hasLimits:At()&&!Se(),hasRecorded:Kn()&&!Se(),binMode:(r.plotMode??"hardBin")==="hardBin"||(r.plotMode??"hardBin")==="softBin"},e=>O(e)),()=>Yo(r)),{btn:Zn,sync:jt}=qo(de,()=>({plotMode:r.plotMode,legendPosition:he}),e=>{he=e;for(const t of S)t&&t.setOptions({legendPosition:he})},{get:()=>We,set:e=>{We=e,Ct()},blockedReason:be});jt();const Yn=[{value:"mean",label:"Mean"},{value:"median",label:"Median"},{value:"stddev",label:"Std Dev"},{value:"min",label:"Min"},{value:"max",label:"Max"},{value:"count",label:"Count"}],Vt=Bt("aggr","Aggregation method",()=>Yn,()=>r.aggregationMethod??"mean",e=>O({aggregationMethod:e}));function zt(){const e=r.plotMode==="stackedValues";Vt.style.display=e?"":"none"}zt();const{btn:Qn,sync:Nt}=Ko(de,()=>({...r,functionalActive:Se()}),e=>O(e));Nt();const He=Q("specRange","Colorbar range: spec limits",()=>{const e=r.colorbarRangeMode==="data"?"spec":"data";O({colorbarRangeMode:e})});function _t(){const e=(r.plotMode??"hardBin")==="value"&&At()&&wn(r)==="off"&&!Se();He.style.display=e?"":"none";const t=(r.colorbarRangeMode??"spec")==="spec";xe(He,t),He.ariaLabel=t?"Colorbar range: spec limits (click for data range)":"Colorbar range: data range (click for spec limits)"}_t();const Jn=Xo(de,()=>r,e=>O(e)),eo=Q("downloadAll","Download gallery PNG",mo),to=Bt("columns","Columns",()=>[{value:"auto",label:"Auto"},{value:"1",label:"1 column"},{value:"2",label:"2 columns"},{value:"3",label:"3 columns"},{value:"4",label:"4 columns"},{value:"5",label:"5 columns"}],()=>M!=null?String(M):"auto",e=>en(e==="auto"?void 0:Number(e))),k=u.ownerDocument.createElement("div");Object.assign(k.style,{display:"inline-flex",alignItems:"center",gap:"0"}),W.appendChild(k),k.appendChild(X),k.appendChild(_n),k.appendChild(Vt),k.appendChild(Qn),k.appendChild(He),k.appendChild(G()),k.appendChild(Xn),k.appendChild(G()),k.appendChild(Zn),k.appendChild(G()),k.appendChild(Jn),k.appendChild(G()),k.appendChild(to),k.appendChild(G()),k.appendChild(eo),(V||Je())&&(P=Q("findings","Summary panel",()=>{if(!h)return;const e=h.style.display!=="none";e||z(),h.style.display=e?"none":"flex",xe(P,!e),ae()}),W.appendChild(G()),W.appendChild(P));let K=null,je=null,J=[],Gt=!1;function Me(){const e=mi({lotStatsSummary:V,result:{warnings:[...x.flatMap(n=>n?.warnings??[]),...St().warnings]},extra:[r.binColors&&So(r.binColors,r.plotMode),Mo(Ft),Tn(vt())].filter(n=>!!n)}),t=e.length!==J.length||e.some((n,o)=>n.code!==J[o]?.code||n.message!==J[o]?.message);J=e,(t||!Gt)&&(Gt=!0,p.warnings?.onWarning?.(e)),no()}function no(){if(!K||!je)return;const e=J.length,t=e>0;if(K.style.display=t?"flex":"none",je.style.display=t?"":"none",!t)return;const n=hi(J[0]),o=`${e} data ${e===1?"warning":"warnings"}`;K.style.color=n==="error"?g.errText:g.warnText,K.ariaLabel=n==="error"?`${o} \u2014 some wafers may be positionally wrong`:o}(p.warnings?.display??!0)&&(je=G(),K=Q("warning","Data warnings",()=>{const e=ve();if(Ae(new MouseEvent("click")),e)return;const t=gi(K.getBoundingClientRect(),J,K.ownerDocument.defaultView??window);mn(u).appendChild(t),Ce(t),hn(t,K,()=>Ae(new MouseEvent("click")))}),$e(K,!1),W.appendChild(je),W.appendChild(K)),Me();let le=null;H&&(le=Q("analysis","Insights",()=>{Ut(!Be)}),le.dataset.wmapInsightsBtn="1",W.appendChild(G()),W.appendChild(le));function Kt(){import("./userGuideHtml.js").then(e=>_o({buildWaferMap:fi,renderWaferMap:di,renderWaferGallery,analyzeWaferMap:Xe},e.USER_GUIDE_HTML,$,u))}D&&(W.appendChild(G()),W.appendChild(Q("help","User guide",()=>Kt())));const ue=u.ownerDocument.createElement("div");ue.dataset.wmapGalleryMeta="1",Object.assign(ue.style,{flex:"1",minWidth:"0",overflow:"hidden",display:"flex",alignItems:"center",padding:`${w.sm} ${w.lg}`,fontSize:T.sub,lineHeight:qe.none,boxSizing:"border-box"});const Ve=u.ownerDocument.createElement("div");Object.assign(Ve.style,{background:g.canvasBg,display:"flex",alignItems:"stretch",gap:w.lg,paddingBottom:w.lg,minWidth:"0"});const ee=u.ownerDocument.createElement("div");ee.dataset.wmapGalleryLegend="1",Object.assign(ee.style,{display:"flex",flexDirection:"column",gap:w.sm,background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.container,padding:`${w.sm} ${w.lg}`,marginBottom:w.lg,boxShadow:Le.panel,fontSize:T.body,lineHeight:qe.none,boxSizing:"border-box",width:"100%",minWidth:"0"});const q=u.ownerDocument.createElement("div");Object.assign(q.style,{display:"flex",flexDirection:"row",alignItems:"flex-start"});let fe=null,De=null,qt=null;function oo(){return H?fe?Promise.resolve(fe):(qt??=import("./insightsTab.js").then(({createInsightsTab:e})=>(fe=e({getItems:()=>x,getLotStats:()=>V,getBinColors:()=>r.binColors??ce(),getRingCount:Ye,defaultView:p.insights?.defaultView,onOpenGuide:void 0,showMetadataStrip:!1,onSaveImage:Re.onSaveImage,onSaveText:Re.onSaveText,ownerDocument:u.ownerDocument,openWafer:(t,n,o)=>{const d=x[t];if(!d)return;let i=null;const l=jo({title:n,onClose:()=>i?.destroy(),anchor:u});on(l,n,d.wafer.metadata??void 0),i=ut(l.contentWrap,d,o)}}),De=fe.el,De.style.display="none",u.appendChild(De),fe)),qt):Promise.resolve(null)}let Be=!1;function Ut(e){H&&(Be=e,De&&(De.style.display=e?"flex":"none"),q.style.display=e?"none":"flex",k.style.display=e?"none":"inline-flex",W.style.display="inline-flex",le&&(xe(le,e),le.innerHTML=e?Te.wafer:Te.analysis,le.ariaLabel=e?"Back to gallery view":"Insights"),ae(),Ne(),e&&oo().then(t=>{!t||!Be||(t.el.style.display="flex",t.render())}))}H&&p.insights?.defaultOpen&&queueMicrotask(()=>Ut(!0));const io=4,at=240,Xt=480,ao=720,lo=1.25;let pe=Xt;function Zt(e){const t=A*2+110+2;let n=null;for(const o of e){if(o==null||!o.dies?.length)continue;const d=o.dies[0].width;if(!(d>0))continue;const i=o.wafer.radius*2*(io/d),l=Math.ceil(i+t);(n==null||l>n)&&(n=l)}return n}function so(e){const t=Zt(e);return t==null?at:Math.min(pe,Math.max(at,t))}function ro(e){const t=Zt(e);if(t==null)return!1;const n=Math.min(ao,Math.max(Xt,t));return n<=pe?!1:(pe=n,!0)}function lt(){return M!=null?"none":`${pe}px`}function Yt(){const e=lt();for(const t of Array.from(R.children))t.classList.contains("wmap-gallery-card")&&(t.style.maxWidth=e,t.style.maxHeight=e)}let ze=at,Qt=0;function Jt(e){if(ro(e)&&Yt(),M==null){const n=so(e);n>ze&&(ze=n)}rt()}function en(e){M=Bn(e),Yt(),rt()}function st(e){return`repeat(${e}, minmax(0, ${M!=null?"1fr":`${pe}px`}))`}function tn(e){R.style.gridTemplateColumns!==e&&(R.style.gridTemplateColumns=e)}function rt(){if(M!=null){tn(st(M));return}const e=Math.max(1,Qt),t=12,n=R.clientWidth||0,o=i=>(n-t*(i-1))/i;let d=Math.max(1,Math.ceil(Math.sqrt(e)));if(n>0){const i=Math.min(pe,ze*lo),l=s=>{let a=0;for(;a<e&&o(a+1)>=s;)a++;return a};d=l(i)||l(ze)||1}tn(st(d))}const R=u.ownerDocument.createElement("div");if(Object.assign(R.style,{flex:"1 1 0",minWidth:"0",display:"grid",gridTemplateColumns:st(1),gap:w.xl,paddingLeft:oe,paddingRight:oe,justifyContent:"start",alignContent:"start",isolation:"isolate"}),j?.placement){const e=j.placement;h=wt(e,oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.display="flex",h.style.flexDirection="column"}else if(V||Je()){const e=!!j?.defaultOpen;h=wt("right",oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display=e?"flex":"none",z()}ae(),h?.style.display!=="none"&&P&&xe(P,!0),(j?.placement??"right")==="left"?(h&&q.appendChild(h),q.appendChild(R)):(q.appendChild(R),h&&q.appendChild(h));const ke=u.ownerDocument.createElement("div");Object.assign(ke.style,{position:"sticky",top:"0",display:"flex",flexDirection:"column",paddingLeft:oe,paddingRight:oe,paddingTop:oe,zIndex:"1",background:g.menuBg}),Ve.appendChild(ue),Ve.appendChild(W),ke.appendChild(Ve),ke.appendChild(ee),u.appendChild(ke),u.appendChild(q);function Ne(){ee.innerHTML="";const e=r.plotMode??"hardBin",t=!Be&&un.has(e),n=L.filter(m=>m!=null),o=n.find(m=>m.isLotStack),d=bi(n.map(m=>({metadata:m.wafer.metadata??void 0})),o?{lotSize:o.lotSize??n.length,aggrMethod:o.aggrMethod}:void 0),i=e==="metadata",l=r.activeMetadataKey,s=t&&!i?kn(n,m=>(e==="softBin"?m.sbin:m.hbin)??void 0,On):{counts:new Map,total:0,pass:0},a=t&&!i?r.binColors??ce():void 0,c=a?e==="softBin"?a.pass.soft:a.pass.hard:new Set,f=li(s.counts.entries(),c).map(([m])=>m),b=t&&i&&l?kn(n,m=>vo(m.metadata?.[l])):{counts:new Map,total:0,pass:0},E=i?Pt()?.values:void 0,B=t&&i?(E??[...b.counts.keys()].sort(yt)).filter(m=>b.counts.has(m)):[];if(ue.innerHTML="",d&&ue.appendChild(d),ue.style.display=d?"flex":"none",!f.length&&!B.length){ee.style.display="none";return}ee.style.display="flex";const C=u.ownerDocument.createElement("div");Object.assign(C.style,{display:"flex",flexWrap:"wrap",alignItems:"center",gap:`${w.sm} ${w.xl}`,maxHeight:"86px",overflowY:"auto",overflowX:"hidden"}),ee.appendChild(C);const y=r.highlightBin,I=L.flatMap(m=>m?.metadataFields??[]).find(m=>m.key===l),se=i?I?.label??(l?vi(l):"Metadata"):Wo[e],U=u.ownerDocument.createElement("span");if(U.textContent=se,Object.assign(U.style,{fontSize:T.body,fontWeight:"700",letterSpacing:To,textTransform:"uppercase",color:g.label,flexShrink:"0"}),C.appendChild(U),!i&&s.total>0){const m=s.pass,F=m/s.total*100,te=u.ownerDocument.createElement("span");te.textContent=`Yield ${Ze(F)}`,Object.assign(te.style,{fontSize:T.body,fontWeight:"700",color:g.value,whiteSpace:"nowrap",flexShrink:"0"});const ne=u.ownerDocument.createElement("span");ne.textContent=`${m.toLocaleString()} / ${s.total.toLocaleString()} dies`,Object.assign(ne.style,{fontSize:T.body,color:g.label,whiteSpace:"nowrap",flexShrink:"0"}),C.appendChild(te),C.appendChild(ne)}if(i){const m=r.highlightMetadataValue;B.forEach((F,te)=>{const ne=m===F,Ge=I?.values?.find(gt=>gt.value===F),ho=Ge?.color??Eo(te),dn=b.counts.get(F)??0;En(C,{color:ho,isActive:ne,label:Ge?.label??F,count:dn,percent:b.total>0?dn/b.total*100:void 0,onClick:()=>{const gt=r.highlightMetadataValue===F?void 0:F;O({highlightMetadataValue:gt})}})});return}const ft=e==="softBin"?L.flatMap(m=>m?.sbinDefs??[]):L.flatMap(m=>m?.hbinDefs??[]),ln=new Set,pt=[];for(const m of ft)ln.has(m.bin)||(ln.add(m.bin),pt.push(m));const mt=pt.length>0?new Map(pt.map(m=>[m.bin,m])):null,sn=a??r.binColors??ce(),go=e==="softBin"?sn.soft:sn.hard,rn=m=>go.get(m)??ko;for(const m of f){const F=y===m,te=mt?.get(m),ne=s.counts.get(m)??0;En(C,{color:rn(m),isActive:F,label:te?.name?`${m} \xB7 ${te.name}`:`Bin ${m}`,count:ne,percent:s.total>0?ne/s.total*100:void 0,onClick:()=>{const Ge=r.highlightBin===m?void 0:m;O({highlightBin:Ge})}})}s.total>0&&f.length>1&&ee.appendChild(Di(u.ownerDocument,[...s.counts.entries()].sort(([,m],[,F])=>F-m).map(([m,F])=>({color:rn(m),count:F,label:mt?.get(m)?.name?`${m} \xB7 ${mt.get(m).name}`:`Bin ${m}`})),s.total))}function Ee(e){const t=x.filter(s=>s!==null);if(!t.length)return[];const n=t.map(s=>s.dies.filter(Mi)),o=t[0].wafer,d=t.length,i=o.metadata?{...o,metadata:(({wafer:s,waferId:a,...c})=>c)(o.metadata)}:o;function l(s,a){return{...s,stats:{...s.stats,isLotStack:!0,aggregationMethod:a,lotSize:d}}}if(e==="stackedValues"){const s=ye();let a=s?.filter(bt);if(s!==void 0&&a?.length===0)return[];if(s?.length||(a=bo(t.flatMap(b=>b.dies)).map(b=>({testNumber:b,name:`Test ${b}`}))),!a?.length)return[];const c=r.aggregationMethod??"mean";return a.map(f=>{const b=ri(n,c,f.testNumber),E={testNumber:0,name:f.name,unit:f.unit};return{wafer:i,dies:b,testDefs:[E],label:`${f.name} \xB7 ${c}`,isLotStack:!0,aggrMethod:c,lotSize:d,statsSummary:l(Xe({wafer:i,dies:b,testDefs:[E]},{testNumbers:[0]}),c)}})}if(e==="stackedBins"){let s=Ke(t.map(a=>a?.hbinDefs));return(!s||s.length===0)&&(s=[...new Set(t.flatMap(c=>c.dies.map(f=>f.hbin).filter(f=>f!=null)))].sort((c,f)=>c-f).map(c=>({bin:c,name:`Bin ${c}`}))),s.map(a=>{const c=xn(n,a.bin,"hard"),f=[{bin:a.bin,name:a.name}];return{wafer:i,dies:c,hbinDefs:f,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:l(Xe({wafer:i,dies:c,hbinDefs:f}),"countBin")}})}if(e==="stackedSoftBins"){let s=Ke(t.map(a=>a?.sbinDefs));return(!s||s.length===0)&&(s=[...new Set(t.flatMap(c=>c.dies.map(f=>f.sbin).filter(f=>f!=null)))].sort((c,f)=>c-f).map(c=>({bin:c,name:`Bin ${c}`}))),s.map(a=>{const c=xn(n,a.bin,"soft"),f=[{bin:a.bin,name:a.name}];return{wafer:i,dies:c,sbinDefs:f,label:`${a.bin} \xB7 ${a.name}`,isLotStack:!0,aggrMethod:"countBin",lotSize:d,statsSummary:l(Xe({wafer:i,dies:c,sbinDefs:f}),"countBin")}})}return t}function dt(e){const t=x.length;return e==="stackedBins"||e==="stackedSoftBins"?{valueRange:[0,t],lotSize:t}:e==="stackedValues"?{aggregationMethod:r.aggregationMethod??"mean",valueRange:void 0,lotSize:void 0}:{}}function O(e,{fireCallback:t=!0}={}){const n=Object.keys(e),o=r.plotMode,d=be()!==null;r={...r,...e};const i=r.plotMode,l=ge.has(i),s=o!==void 0&&ge.has(o),a=Ie>0;if("binColorScheme"in e||"useDefinedBinColors"in e){const f=ce();r={...r,binColors:f},e={...e,binColors:f}}if(e.plotMode!==void 0)if(l){const f=dt(i);if(r={...r,...f},a)for(const b of S)b&&b.setOptions(e);else Z(Ee(i))}else if(s){const{valueRange:f,lotSize:b,aggregationMethod:E,...B}=r;if(r=B,a)for(const C of S)C&&C.setOptions(e);else Z(x.filter(C=>C!==null))}else for(const f of S)f&&f.setOptions(e);else if(e.aggregationMethod!==void 0&&i==="stackedValues")if(a)for(const f of S)f&&f.setOptions(e);else Z(Ee("stackedValues"));else for(const f of S)f&&f.setOptions(e);be()!==null!==d&&Ct(),Ne(),zt(),jt(),It();const c=e.plotMode!==void 0&&e.plotMode!==o;(ui.some(f=>f in e)||c)&&z(),Me(),Nt(),_t(),ot(),nt(),t&&p.onViewOptionsChange?.(Cn(r),n,ci(n))}function nn(e,t,n){const o=e.createElement("div");Object.assign(o.style,{display:"flex",alignItems:"center",gap:w.xs,flex:"1",minWidth:"0"});const d=e.createElement("span");d.textContent=t,Object.assign(d.style,{fontWeight:"700",fontSize:T.sub,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}),o.appendChild(d);const i=Dn(n??{});let l=null;if(i.length>0){const s=e.createElement("span");Object.assign(s.style,{fontSize:T.body,lineHeight:qe.none,color:g.label,flexShrink:"0"}),s.textContent="\u25BE",o.appendChild(s),Object.assign(o.style,{cursor:"pointer",borderRadius:N.control}),o.addEventListener("mouseenter",()=>{o.style.background=g.bgHover}),o.addEventListener("mouseleave",()=>{o.style.background="none"}),l=e.createElement("div"),l.dataset.wmapCardMetaPanel="1",Object.assign(l.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:fn,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:Le.menu,padding:`${w.md} ${w.lg}`,fontSize:T.body,display:"none"});const a=Mn(n??{});a&&l.appendChild(a),o.setAttribute("aria-expanded","false"),o.setAttribute("aria-label",`Wafer info for ${t||"this card"}. Click to expand.`),bn(o,c=>{s.textContent=c?"\u25B4":"\u25BE",o.setAttribute("aria-expanded",String(c)),l&&(l.style.display=c?"block":"none")})}return{wrap:o,metaPanel:l}}function on(e,t,n){const o=e.box.querySelector("[data-wmap-window-title]"),d=Dn(n??{});if(!o||d.length===0)return;const i=o.parentElement,l=u.ownerDocument.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",gap:w.xs,flex:"1",minWidth:"0",cursor:"pointer"}),ht(l,"bare"),i?.insertBefore(l,o),l.appendChild(o);const s=u.ownerDocument.createElement("span");Object.assign(s.style,{fontSize:T.body,lineHeight:qe.none,color:g.label,flexShrink:"0"}),s.textContent="\u25BE",l.appendChild(s);const a=u.ownerDocument.createElement("div");a.dataset.wmapCardMetaPanel="1",Object.assign(a.style,{position:"absolute",top:"0",left:"0",right:"0",zIndex:fn,background:g.menuBg,borderBottom:`1px solid ${g.menuBorder}`,boxShadow:Le.menu,padding:`${w.md} ${w.lg}`,fontSize:T.body,display:"none"});const c=Mn(n??{});c&&a.appendChild(c),e.contentWrap.style.position="relative",e.contentWrap.appendChild(a),l.setAttribute("aria-expanded","false"),l.setAttribute("aria-label",`Wafer info for ${t}. Click to expand.`),bn(l,f=>{s.textContent=f?"\u25B4":"\u25BE",l.setAttribute("aria-expanded",String(f)),a.style.display=f?"block":"none"})}function ct(e,t,n){const o=u.ownerDocument.createElement("div");o.className="wmap-gallery-card",Object.assign(o.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.container,boxShadow:Le.panel,overflow:"hidden",display:"flex",flexDirection:"column",position:"relative",aspectRatio:"1",maxWidth:lt(),maxHeight:lt()});const d=u.ownerDocument.createElement("div");Object.assign(d.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:w.sm});const{wrap:i,metaPanel:l}=nn(document,Ue(e,t),e.wafer.metadata??void 0);d.appendChild(i);const s=u.ownerDocument.createElement("button");s.dataset.wmapExpandBtn="1",s.setAttribute("aria-label","Open full view"),yn(s),s.innerHTML=Te.expand,Object.assign(s.style,{display:"flex",alignItems:"center",justifyContent:"center",border:`1px solid ${g.menuBorder}`,borderRadius:N.control,background:g.panelBg,color:g.label,padding:w.xxs,cursor:"pointer",flexShrink:"0",width:"22px",height:"22px"}),ht(s),d.appendChild(s),o.appendChild(d);const a=u.ownerDocument.createElement("div");Object.assign(a.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),o.appendChild(a),l&&a.appendChild(l),R.appendChild(o);const c=We||be()!==null,f=e.viewOptions?{...r,...e.viewOptions}:r,b=vn(a,e,{viewOptions:{...f,showLegend:c,legendPosition:he},showTooltip:!0,padding:A,statsSummary:e.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:e.onClick,onSelect:e.onSelect,onExpand:()=>Oe(t,e),showIdentity:!1,chromeInset:$o});return b.setViewControlsVisible(!1),b.setSummaryVisible(!1),s.onclick=()=>Oe(t,e),{card:o,ctrl:b,canvasWrapper:a,expandBtn:s}}function co(e){const t=re[e];if(!t)return;const n=[..._.values()].find(o=>o.cardIndex===e);n?(t.innerHTML=Te.minimize,t.setAttribute("aria-label","Reattach to gallery"),t.onclick=()=>fo(n.id)):(t.innerHTML=Te.expand,t.setAttribute("aria-label","Open full view"),t.onclick=()=>Oe(e,L[e]))}function Z(e){po(),ve()?.remove(),Ce(null),tt(),L=[];for(const i of S)i&&i.destroy();S=[],ie=[],re=[],Ie=0,R.innerHTML="",Qt=e.length,Jt(e.map(i=>typeof i=="function"?null:i));const t=[];for(let i=0;i<e.length;i++){const l=e[i];if(typeof l=="function"){const s=u.ownerDocument.createElement("div");s.className="wmap-gallery-card",Object.assign(s.style,{background:g.menuBg,border:`1px solid ${g.menuBorder}`,borderRadius:N.container,aspectRatio:"1",display:"flex",alignItems:"center",justifyContent:"center"});const a=u.ownerDocument.createElement("span");a.textContent="\u2026",Object.assign(a.style,{color:g.label,fontSize:"18px"}),s.appendChild(a),R.appendChild(s),L.push(null),S.push(null),ie.push(null),re.push(null),t.push({index:i,factory:l,placeholder:s}),Ie++}else{const{ctrl:s,canvasWrapper:a,expandBtn:c}=ct(l,i,e.length);L.push(l),S.push(s),ie.push(a),re.push(c)}}Ht(),Ne(),ot(),nt();const n=++Qe;let o=0;function d(){if(n!==Qe)return;if(o>=t.length){if(ge.has(r.plotMode)){const B=r.plotMode;Z(Ee(B))}return}const{index:i,factory:l,placeholder:s}=t[o++],a=l();L[i]=a,x[i]=a,Jt([a]);const{card:c,ctrl:f,canvasWrapper:b,expandBtn:E}=ct(a,i,e.length);S[i]=f,ie[i]=b,re[i]=E,Ie--,s.replaceWith(c),Ne(),Un(),!h&&!j?.placement&&a.statsSummary?.findings.length?(h=wt("right",oe,u.ownerDocument),h.style.maxHeight="calc(100vh - 80px)",h.style.position="sticky",h.style.top="8px",h.style.flexDirection="column",h.style.display="none",(j?.placement??"right")==="left"?q.insertBefore(h,R):q.appendChild(h),z(),P||(P=Q("findings","Summary panel",()=>{if(!h)return;const C=h.style.display!=="none";C||z(),h.style.display=C?"none":"flex",xe(P,!C),ae()}),W.appendChild(G()),W.appendChild(P)),ae()):h&&h.style.display!=="none"&&z(),ae(),setTimeout(d,0)}t.length>0&&setTimeout(d,0)}if(ge.has(r.plotMode)&&x.length>0){const e=dt(r.plotMode);r={...r,...e},Z(Ee(r.plotMode))}else Z(v);Me();let me=0;const an=new(u.ownerDocument.defaultView??window).ResizeObserver(()=>{if(me)return;me=(u.ownerDocument.defaultView??window).requestAnimationFrame(()=>{me=0,M==null&&rt()})});an.observe(R),h&&z();function uo(e,t){const n=ie[e];if(!n)return;n.innerHTML="",Object.assign(n.style,{alignItems:"center",justifyContent:"center"});const o=u.ownerDocument.createElement("span");o.textContent=t?"Opened in its own window":"Opened in the wafer viewer",Object.assign(o.style,{color:g.label,fontSize:T.body,textAlign:"center",padding:"0 12px"}),n.appendChild(o)}function Oe(e,t){for(const l of _.values())if(l.cardIndex===e)return;const n=Ue(t,e),o=Ln++,d=S[e]?.getOptions(),i=Fo(n);if(i){const l=i.document;l.title=n,Object.assign(l.documentElement.style,{height:"100%"}),Object.assign(l.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:T.family}),zo(u,l.documentElement);const s=No(u,l.documentElement,()=>C.setOptions({})),a=l.createElement("div");a.dataset.wmapWindowBanner="1",a.textContent=n,Object.assign(a.style,{display:"none",padding:`${w.sm} ${w.xl}`,fontSize:T.body,fontWeight:"700",background:g.warnBg,color:g.warnText,borderBottom:`1px solid ${g.warnBorder}`,flexShrink:"0"}),l.body.appendChild(a);const c=l.createElement("div");Object.assign(c.style,{flex:"1",minHeight:"0",display:"flex",flexDirection:"column"}),l.body.appendChild(c);const{wrap:f,metaPanel:b}=nn(l,n,t.wafer.metadata??void 0),E=l.createElement("div");Object.assign(E.style,{display:"flex",alignItems:"center",padding:`${w.md} ${w.lg} ${w.sm}`,borderBottom:`1px solid ${g.menuBorder}`,flexShrink:"0",gap:w.sm}),E.appendChild(f),c.appendChild(E);const B=l.createElement("div");Object.assign(B.style,{position:"relative",flex:"1",minHeight:"0",overflow:"hidden",display:"flex",flexDirection:"column"}),b&&B.appendChild(b),c.appendChild(B);const C=ut(B,t,void 0,d),y=setInterval(()=>{i.closed&&_e(o)},400);i.addEventListener("pagehide",()=>_e(o)),_.set(o,{id:o,ctrl:C,cardIndex:e,label:n,closePollId:y,stopThemeSync:s,close:()=>{i.closed||i.close()},setTitle:I=>{l.title=I,a.textContent=I,a.style.display="block"}})}else{const l=Ho({title:n,onClose:()=>_e(o),anchor:u});l.contentWrap.style.flexDirection="column",on(l,n,t.wafer.metadata??void 0);const s=ut(l.contentWrap,t,void 0,d);_.set(o,{id:o,ctrl:s,cardIndex:e,label:n,closePollId:null,close:()=>l.close(),setTitle:a=>{const c=l.box.querySelector("[data-wmap-window-title]");c&&(c.textContent=a,c.title=a)}})}S[e]?.destroy(),S[e]=null,uo(e,i!==null),co(e)}function ut(e,t,n,o){const d=t.viewOptions?{...r,...t.viewOptions}:r,i=o?{...d,...o}:d,s={...n!==void 0?{...i,plotMode:"value",activeTest:n}:i,showLegend:!0,legendPosition:he},a=vn(e,t,{viewOptions:s,showTooltip:!0,padding:A,statsSummary:t.statsSummary,onSaveImage:p.onSaveImage,onSaveText:p.onSaveText,onClick:t.onClick,onSelect:t.onSelect,showExpandButton:!1,showIdentity:!1});return a.setViewControlsVisible(!0),a.setSummaryVisible(!0),a.setExpandVisible(!1),a}function _e(e){const t=_.get(e);if(!t||(_.delete(e),t.closePollId!=null&&clearInterval(t.closePollId),t.stopThemeSync?.(),t.ctrl.destroy(),t.cardIndex===null))return;const n=t.cardIndex,o=L[n];if(!o)return;const{card:d,ctrl:i,canvasWrapper:l,expandBtn:s}=ct(o,n,L.length);ie[n]?.parentElement?.replaceWith(d),S[n]=i,ie[n]=l,re[n]=s}function fo(e){const t=_.get(e);t&&(t.close(),_e(e))}function po(){for(const e of _.values())e.cardIndex!==null&&(e.cardIndex=null,e.setTitle(`${e.label} \u2014 unlinked from gallery`))}function mo(){const e=[...R.querySelectorAll("canvas")];if(!e.length)return;const t=e.length,n=Math.ceil(Math.sqrt(t)),o=Math.ceil(t/n),d=e[0].width,i=e[0].height,l=8,s=(u.ownerDocument.defaultView??window).devicePixelRatio||1,a=Math.round(26*s),c=Math.round(12*s),f=u.ownerDocument.createElement("canvas");f.width=n*d+(n-1)*l,f.height=o*(i+a)+(o-1)*l;const b=f.getContext("2d"),E=Oo(R);b.fillStyle=E.background,b.fillRect(0,0,f.width,f.height),e.forEach((B,C)=>{const y=C%n,I=Math.floor(C/n),se=y*(d+l),U=I*(i+a+l),ft=B.closest(".wmap-gallery-card")?.querySelector("span")?.textContent??"";b.fillStyle=E.surface,b.fillRect(se,U,d,a),b.fillStyle=E.text,b.font=`700 ${c}px system-ui, sans-serif`,b.textAlign="left",b.textBaseline="middle",b.fillText(ft,se+Math.round(10*s),U+a/2,d-Math.round(20*s)),b.drawImage(B,se,U+a)}),f.toBlob(B=>{if(!B)return;if(p.downloadFilename!=null){gn(B,p.downloadFilename,p.onSaveImage);return}const C=S.find(y=>y!=null)?.getExportTitle();gn(B,["gallery",C].filter(Boolean).join(" "),Re.onSaveImage)})}return{setItems(e){x=e.map(n=>typeof n=="function"?null:n);const t=r.plotMode;if(ge.has(t))if(e.some(o=>typeof o=="function"))Z(e);else{const o=dt(t);r={...r,...o},Z(Ee(t))}else Z(e)},setOptions(e){O(e,{fireCallback:!1})},getOptions(){return Cn(r)},setFindingsNotice(e){Et=e,z()},setColumns(e){en(e)},getBinColors(){return r.binColors??ce()},setLotStatsSummary(e){V=e,Me(),h&&z(),ae()},openUserGuide:Kt,destroy(){Qe++;for(const e of[..._.values()])e.closePollId!=null&&clearInterval(e.closePollId),e.close(),e.ctrl.destroy();_.clear();for(const e of S)e&&e.destroy();S=[],ve()?.remove(),an.disconnect(),me&&((u.ownerDocument.defaultView??window).cancelAnimationFrame(me),me=0),u.ownerDocument.removeEventListener("click",Ae,!0),window.removeEventListener("blur",kt),Y(),pn(),ke.remove(),q.remove(),h?.remove(),fe?.destroy()}}}
|
|
@@ -217,14 +217,21 @@ export interface RenderOptions extends ForwardedDrawOptions {
|
|
|
217
217
|
showIdentity?: boolean;
|
|
218
218
|
/** Optional precomputed wafer-level stats summary. Enables the summary panel toggle button in the toolbar. */
|
|
219
219
|
statsSummary?: StatsSummary;
|
|
220
|
-
/**
|
|
220
|
+
/**
|
|
221
|
+
* Name for the map's PNG download, without extension. When omitted, the PNG
|
|
222
|
+
* is named for its lot, wafer and map title (`LOT123_W05_hard-bin.png`); CSV
|
|
223
|
+
* exports are always named that way. See docs/api.md §5.4.5.
|
|
224
|
+
*
|
|
225
|
+
* **Changes in 0.31.0:** this becomes a prefix for every file the map saves,
|
|
226
|
+
* with the lot, wafer and content appended. Passing it logs a one-time notice.
|
|
227
|
+
*/
|
|
221
228
|
downloadFilename?: string;
|
|
222
229
|
/**
|
|
223
230
|
* Host hook for persisting the rendered PNG. When provided, the toolbar's save
|
|
224
231
|
* action calls `onSaveImage(blob, suggestedName)` instead of triggering a
|
|
225
232
|
* browser `<a download>` — letting embedded hosts (Tauri, Electron, WebView2)
|
|
226
233
|
* route the image through a native save dialog. `suggestedName` includes the
|
|
227
|
-
* `.png` extension and is
|
|
234
|
+
* `.png` extension and is the generated name (see `downloadFilename`). When omitted, the
|
|
228
235
|
* default browser download behaviour is unchanged.
|
|
229
236
|
*/
|
|
230
237
|
onSaveImage?: SaveImageHandler;
|
|
@@ -350,6 +357,19 @@ export interface WaferMapController {
|
|
|
350
357
|
resetZoom(): void;
|
|
351
358
|
/** Replace the current stats summary used by the built-in Summary panel. */
|
|
352
359
|
setStatsSummary(summary: StatsSummary | undefined): void;
|
|
360
|
+
/**
|
|
361
|
+
* Close the Summary panel if it is open; no-op if it is closed or the map has
|
|
362
|
+
* none. For a host that needs the map's full width back — loading a new file,
|
|
363
|
+
* opening its own dialog, moving to a narrower layout. The user reopens it from
|
|
364
|
+
* the toolbar's Summary button.
|
|
365
|
+
*/
|
|
366
|
+
closeSummaryPanel(): void;
|
|
367
|
+
/**
|
|
368
|
+
* The bin colours this map draws, with the palette currently chosen — for a
|
|
369
|
+
* host surface of its own (a table swatch, an export). Inside a gallery these
|
|
370
|
+
* are the gallery-wide colours. Hard and soft bins are separate maps.
|
|
371
|
+
*/
|
|
372
|
+
getBinColors(): BinColors;
|
|
353
373
|
/**
|
|
354
374
|
* Opens the built-in end-user guide window — the same action the help
|
|
355
375
|
* toolbar button performs, but callable directly. Works regardless of
|
|
@@ -439,6 +459,8 @@ export interface CardController extends WaferMapController {
|
|
|
439
459
|
setViewControlsVisible(visible: boolean): void;
|
|
440
460
|
/** Show or hide the expand toolbar button. */
|
|
441
461
|
setExpandVisible(visible: boolean): void;
|
|
462
|
+
/** The map's title as a file-name content part — the gallery names its composite PNG by it. */
|
|
463
|
+
getExportTitle(): string;
|
|
442
464
|
}
|
|
443
465
|
/** @internal The public view of a card's options: everything but the gallery's shared state. */
|
|
444
466
|
export declare function toPublicViewOptions(opts: CardViewOptions): WaferViewOptions;
|