@wafertools/wafermap 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +10 -2
- package/CHANGELOG.md +366 -0
- package/README.md +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/boxplot.d.ts +8 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/correlation.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/histogram.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/regionYieldDiagram.d.ts +0 -1
- package/dist/packages/canvas-adapter/charts/scatter.d.ts +6 -1
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.d.ts +7 -0
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/hitGrid.d.ts +22 -0
- package/dist/packages/canvas-adapter/hitGrid.js +1 -0
- package/dist/packages/canvas-adapter/index.d.ts +1 -0
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.d.ts +24 -2
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.d.ts +8 -1
- package/dist/packages/canvas-adapter/maplessSummary.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +45 -1
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +15 -5
- 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 +46 -11
- 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 +27 -16
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/warnings.d.ts +25 -0
- package/dist/packages/canvas-adapter/warnings.js +1 -1
- package/dist/packages/core/dies.d.ts +11 -0
- package/dist/packages/core/dies.js +1 -1
- package/dist/packages/renderer/binColors.d.ts +80 -0
- package/dist/packages/renderer/binColors.js +1 -0
- package/dist/packages/renderer/buildView.d.ts +82 -6
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.d.ts +8 -2
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/colorMap.d.ts +16 -15
- package/dist/packages/renderer/colorMap.js +1 -1
- package/dist/packages/renderer/colorSchemes.d.ts +57 -25
- package/dist/packages/renderer/colorSchemes.js +1 -1
- package/dist/packages/renderer/index.d.ts +3 -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/histogram.d.ts +28 -1
- package/dist/packages/stats/histogram.js +1 -1
- package/dist/packages/stats/population.d.ts +23 -0
- package/dist/packages/stats/population.js +1 -0
- package/dist/packages/stats/renderFindingsReport.js +10 -10
- package/dist/packages/stats/renderSummaryReport.js +22 -22
- package/dist/packages/stats/yield.js +1 -1
- package/package.json +5 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
import{fontPx as _t}from"./toolbar.js";import{findTestDef as Re,buildMapTitle as _e}from"../renderer/buildView.js";import{affineInvert as Je,affineVector as Ce}from"../core/transforms.js";import{compareNatural as Ze}from"../core/utils.js";import{getColorScheme as Be}from"../renderer/colorSchemes.js";import{SPEC_PASS_FILL as Pe,SPEC_FAIL_LOW as je,SPEC_FAIL_HIGH as We,contrastTextColor as De}from"../renderer/colorMap.js";import{fmt as Oe,fmtColorbarAxis as Qe}from"../renderer/fmt.js";import{resolveCanvasTheme as ve}from"./canvasTheme.js";function Ie(m,e,F,M,h){m.moveTo(e,F+h*M),m.lineTo(e-M*.9,F-h*M*.6),m.lineTo(e+M*.9,F-h*M*.6),m.closePath()}const to=new Set(["value","stackedValues","stackedBins","stackedSoftBins"]),eo=new Set(["hardBin","softBin","metadata"]),Z=()=>`${_t(-2)}px system-ui, sans-serif`,Fe=3,Ut=2,oo=6,no=20,so=()=>`600 ${_t()}px system-ui, sans-serif`,Kt=()=>`${_t(-1)}px system-ui, sans-serif`,lo=()=>`600 ${_t(-1)}px system-ui, sans-serif`,qt=128,io=()=>`${_t(-2)}px system-ui, sans-serif`,Ne=4,D=17,Y=11;export const BIN_LEGEND_W=110,BIN_LEGEND_W_COMPACT=64,BIN_LEGEND_ADAPT_COMPACT=280,BIN_LEGEND_ADAPT_FLOATING=180,BIN_LEGEND_MIN_CANVAS_W=150,BIN_LEGEND_MIN_CANVAS_H=120;const zt=28,mt=5,ut=8,ao=15;export function toCanvas(m,e,F={}){const M=ve(m.parentElement??m),{padding:h=16,showColorbar:H=!0,markFailingDies:X=!1,colorbarWidth:P=16,background:pt=M.background,legendPosition:j="default",legendOffset:xt,showAxes:Mt=!1,diePitchMm:G,viewport:q,activeBin:N,hoverBin:z,fallbackFormat:St,topClearance:Q=0,minRightReserve:ct,hbinDefs:yt,sbinDefs:st,metadataFields:bt,showTitle:rt=!0}=F,O=Math.floor(m.clientWidth||m.width),E=Math.floor(m.clientHeight||m.height),Lt=O>=BIN_LEGEND_MIN_CANVAS_W&&E>=BIN_LEGEND_MIN_CANVAS_H,kt=H&&Lt&&to.has(e.plotMode)&&e.passFailDisplay==="off",ft=H&&Lt&&eo.has(e.plotMode),tt=H&&Lt&&e.plotMode==="value"&&(e.passFailDisplay==="spec"&&e.specCounts!==void 0||e.passFailDisplay==="test"&&e.passFailCounts!==void 0),ht=ft||tt,Ct=ft&&e.plotMode!=="metadata"&&e.binCounts?[...e.binCounts.entries()].sort(([o],[c])=>o-c):[],Bt=ft&&e.plotMode==="metadata"&&e.metadataCounts?[...e.metadataColorMap?.keys()??[...e.metadataCounts.keys()].sort(Ze)].map(o=>[o,e.metadataCounts.get(o)??0]):[],et=[];if(tt&&e.passFailDisplay==="test"){const o=e.passFailCounts;et.push({key:-1,color:Pe,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),et.push({key:-2,color:We,label:"Fail",compactLabel:"Fail",count:o.fail,tooltip:`Fail \xB7 ${o.fail} dies`})}else if(tt){const o=e.specCounts,c=Re(e.testDefs,e.activeTest);et.push({key:-1,color:Pe,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),c?.limitHigh!==void 0&&et.push({key:-2,color:We,label:"Fail high",compactLabel:"Fail hi",count:o.failHigh,tooltip:`Fail high \xB7 ${o.failHigh} dies`}),c?.limitLow!==void 0&&et.push({key:-3,color:je,label:"Fail low",compactLabel:"Fail lo",count:o.failLow,tooltip:`Fail low \xB7 ${o.failLow} dies`})}const S=tt?et.length:e.plotMode==="metadata"?Bt.length:Ct.length,L=(m.ownerDocument.defaultView??window).devicePixelRatio??1;if(O<=0||E<=0)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const $=j!=="default"?j:O<BIN_LEGEND_ADAPT_FLOATING?"floating":O<BIN_LEGEND_ADAPT_COMPACT?"compact":"default",re=$==="default"||$==="compact",fe=$==="left",Zt=$==="bottom",Pt=$==="top",Wt=$==="floating",Dt=$==="compact"||$==="floating"?BIN_LEGEND_W_COMPACT:BIN_LEGEND_W,he=Math.floor((E-2*h)/D),de=S>he?he-1:S,ge=ht&&Zt?de*D:0,jt=ht&&Pt?de*D:0,Qt=e.plotMode==="stackedBins"||e.plotMode==="stackedSoftBins",vt=Re(e.testDefs,e.activeTest),Ee=Qt?"Count":vt?.name??(e.activeTest!=null?`Test ${e.activeTest}`:void 0),we=Qt?void 0:vt?.unit,[Ot,It]=e.valueRange,{tickFmt:Ye}=Qe(It,Ee,we,St),Ft=e.allIntegerValues?o=>String(Math.round(o)):Ye;let te=0;if(kt){const o=m.getContext("2d");o.font=Z();const c=[Ft(Ot),Ft(It)];Ot<0&&c.push(Ft(-Math.max(Math.abs(Ot),Math.abs(It))));for(const s of c)te=Math.max(te,o.measureText(s).width)}const me=Math.max(no,Math.ceil(te)+Fe+Ut+oo-h),ee=kt?P+me+8:ht&&re?Dt:0,oe=ht&&fe?Dt:0,ne=Mt?32:0,Nt=Mt?36:0,He=ct!=null?Math.max(ee,ct):ee,Xe=O-2*h-He-Nt-oe,ue=E-2*h-ne-ge-jt;m.width=Math.round(O*L),m.height=Math.round(E*L);const t=m.getContext("2d");t.scale(L,L),t.fillStyle=pt,t.fillRect(0,0,O,E);const V=e.hoverPoints;if(!V.length)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const Et=e.rectangles[0],se=Et?Et.width/2:0,le=Et?Et.height/2:0,wt=e.dieBounds,pe=(wt?.minX??0)-se,$e=(wt?.maxX??0)+se,Ge=(wt?.minY??0)-le,xe=(wt?.maxY??0)+le,Me=$e-pe,ye=xe-Ge;let ot,nt,k;if(q)({originX:ot,originY:nt,ppm:k}=q);else{const c=e.notchDir,s=c&&c.y>.1?13:0,a=c&&c.y<-.1?13:0,r=c&&c.x<-.1?13:0,f=c&&c.x>.1?13:0,d=Xe-r-f,i=ue-Q-s-a;k=Math.min(d/Me,i/ye),ot=h+Nt+oe+r+(d-Me*k)/2-pe*k,nt=h+Q+jt+s+(i-ye*k)/2+xe*k}const Yt=q?.snapDist??Math.max(se,le,1)*1.5,Ht=ot+e.waferCenter.x*k,Ve=nt-e.waferCenter.y*k,ie=e.waferRadius*k,lt=o=>{const c=Math.abs(o-Ve);return c>=ie?0:Math.sqrt(ie*ie-c*c)},it=(o,c,s,a,r,f,d=so(),i=M.text)=>{if(!o)return;t.save(),t.fillStyle=i,t.font=d,t.textAlign=a,t.textBaseline=r;const p=a==="right"?c-f:f-c;let l=o;if(p>8&&t.measureText(l).width>p){for(;l.length>1&&t.measureText(l+"\u2026").width>p;)l=l.slice(0,-1);l=l+"\u2026"}p>8&&t.fillText(l,c,s),t.restore()};if(t.save(),t.setTransform(k*L,0,0,-k*L,ot*L,nt*L),e.rectangles.length>0){const o=new Map;for(const s of e.rectangles){const a=String(s.fill);let r=o.get(a);r||(r=[],o.set(a,r)),r.push(s)}for(const[s,a]of o){t.beginPath();for(const r of a)t.rect(r.x-r.width/2,r.y-r.height/2,r.width,r.height);t.fillStyle=s,t.fill()}t.strokeStyle="rgba(0,0,0,0.18)",t.lineWidth=.5/(k*L),t.beginPath();for(const s of e.rectangles)t.rect(s.x-s.width/2,s.y-s.height/2,s.width,s.height);if(t.stroke(),X){const s=e.rectangles.filter(a=>a.binFail);if(s.length>0){const a=new Map;for(const r of s){const f=De(String(r.fill));let d=a.get(f);d||(d=[],a.set(f,d)),d.push(r)}t.save(),t.lineCap="butt";for(const[r,f]of a){t.strokeStyle=r,t.globalAlpha=.55,t.lineWidth=Math.max(.6/(k*L),Math.min(f[0].width,f[0].height)*.1);for(const d of f){const i=d.width/2,p=d.height/2,l=Math.max(1.6/(k*L),Math.min(d.width,d.height)/3);t.save(),t.beginPath(),t.rect(d.x-i,d.y-p,d.width,d.height),t.clip(),t.beginPath();for(let y=-(i+p);y<=i+p;y+=l)t.moveTo(d.x-i+y,d.y-p),t.lineTo(d.x-i+y+d.height,d.y+p);t.stroke(),t.restore()}}t.restore()}}const c=e.rectangles.filter(s=>s.specMark);if(c.length>0){const s=new Map;for(const r of c){const f=De(String(r.fill)),d=`${r.specMark}|${f}`;let i=s.get(d);i||(i=[],s.set(d,i)),i.push(r)}const a=2.5/(k*L);t.lineJoin="round";for(const[r,f]of s){const[d,i]=r.split("|"),p=i==="#000000"?"#ffffff":"#000000",l=d==="failHigh"?1:-1,y=Math.min(f[0].width,f[0].height),w=Math.max(2.5/(k*L),y*.3);t.beginPath();for(const A of f)Ie(t,A.x,A.y,w,l);t.strokeStyle=p,t.lineWidth=a,t.stroke(),t.fillStyle=i,t.fill()}}}for(const o of e.overlays){t.beginPath();for(const c of o.points){for(let s=0;s<c.length;s++)s===0?t.moveTo(c[s].x,c[s].y):t.lineTo(c[s].x,c[s].y);o.closed&&t.closePath()}o.fill&&!o.fill.startsWith("rgba(0,0,0,0)")&&(t.fillStyle=o.fill,t.fill()),o.kind==="ring-boundary"||o.kind==="quadrant-boundary"||o.kind==="reticle"?(t.strokeStyle="rgba(0,0,0,0.45)",t.lineWidth=3/(k*L),t.stroke(),t.strokeStyle="rgba(255,255,255,0.8)",t.lineWidth=1/(k*L),t.stroke()):(t.strokeStyle=o.lineColor,t.lineWidth=o.lineWidth/(k*L),t.stroke())}if(t.restore(),e.notchDir){const o=ot+e.waferCenter.x*k,c=nt-e.waferCenter.y*k,s=e.notchDir.x,a=-e.notchDir.y,r=e.waferRadius*k,f=4,d=9,i=5,p=o+s*(r+f),l=c+a*(r+f),y=p+s*d,w=l+a*d,A={x:-a,y:s},W=h+Nt+oe,U=O-h-ee,K=h+Q+jt,_=E-h-ge-ne;t.save(),t.beginPath(),t.rect(W,K,U-W,_-K),t.clip(),t.beginPath(),t.moveTo(p,l),t.lineTo(y+A.x*i,w+A.y*i),t.lineTo(y-A.x*i,w-A.y*i),t.closePath(),t.fillStyle=M.text,t.fill(),t.restore()}t.save(),t.textAlign="center",t.textBaseline="middle";let be=0;if(e.rectangles.length>0){let o=1;for(const f of e.texts)f.role!=="indicator"&&f.text.length>o&&(o=f.text.length);const c=e.rectangles[0].width*k,s=e.rectangles[0].height*k,a=Math.min(c,s),r=c/o;be=Math.max(8,Math.min(64,Math.round(Math.min(a*.55,r*1.8))))}for(const o of e.texts){const c=ot+o.x*k,s=nt-o.y*k;t.font=`${o.role==="indicator"?o.fontSize:be}px system-ui, sans-serif`,t.fillStyle=o.color,t.fillText(o.text,c,s)}if(t.restore(),Mt&&co(t,O,E,ot,nt,k,h,ne,Nt,G,e.gridToScreen,e.rotation,M),kt){const o=Be(e.colorScheme),c=me,s=ue-Q,a=Math.round(s*.75),r=h+Q+Math.round((s-a)/2),f=O-h-P-c,d=Ot,i=It,p=i-d,l=e.plotMode==="stackedSoftBins"?st:yt,{primary:y,secondary:w}=rt?_e(e,St,l):{primary:"",secondary:""};if(rt){const n=Math.max(r-6,h+Q+11),b=Ht+Math.max(lt(n),lt(n-12))+8;it(y,O-h,n,"right","bottom",b)}let A=r+a+4;const W=n=>Ht+Math.max(lt(n),lt(n+12))+8,U=e.logScale&&d>0?Math.log10(d):0,K=e.logScale&&i>0?Math.log10(i)-U:1,_=n=>e.logScale?(1-(Math.log10(n)-U)/K)*a:(1-(n-d)/p)*a;for(let n=0;n<qt;n++){const b=1-n/(qt-1),u=r+n/qt*a,g=a/qt+1;t.fillStyle=o.forValue(b),t.fillRect(f,u,P,g)}t.strokeStyle="rgba(0,0,0,0.25)",t.lineWidth=.5,t.strokeRect(f,r,P,a),t.fillStyle=M.text,t.font=Z(),t.textAlign="left",t.strokeStyle="rgba(0,0,0,0.35)",t.lineWidth=.5;const C=Fe,Rt=36,v=14,I=e.logScale&&K>0?ro(d,i,a,Rt,v,U,K):e.allIntegerValues?(()=>{const n=Math.max(1,Jt(p*Rt/a)),b=[],u=Math.ceil(d/n)*n;for(let g=u;g<=i+n*1e-6;g+=n){const B=(1-(g-d)/p)*a;B>v&&B<a-v&&b.push(Math.round(g))}return b})():(()=>{const n=p>0?Jt(p*Rt/a):0,b=[];if(n>0){const u=Math.ceil(d/n)*n;for(let g=u;g<=i+n*1e-6;g+=n){const B=(1-(g-d)/p)*a;B>v&&B<a-v&&b.push(g)}}return b})(),R=vt,x=Qt,T=Ft;t.textBaseline="middle";for(const n of I){const b=r+_(n);t.beginPath(),t.moveTo(f+P,b),t.lineTo(f+P+C,b),t.stroke(),t.fillText(T(n),f+P+C+Ut,b)}if(t.beginPath(),t.moveTo(f+P,r),t.lineTo(f+P+C,r),t.stroke(),t.textBaseline="top",t.fillText(T(i),f+P+C+Ut,r),t.beginPath(),t.moveTo(f+P,r+a),t.lineTo(f+P+C,r+a),t.stroke(),t.textBaseline="bottom",t.fillText(T(d),f+P+C+Ut,r+a),!x&&R&&(R.limitLow!==void 0||R.limitHigh!==void 0)){const n=[],b=e.colorbarRangeMode==="spec";for(const[u,g]of[[R.limitLow,"LSL"],[R.limitHigh,"USL"]]){if(u===void 0||e.logScale&&u<=0)continue;const B=_(u);!b&&(B<-v||B>a+v)||n.push({value:u,label:g,py:Math.max(0,Math.min(a,B))})}if(n.length>0){t.save(),t.font=Z(),t.textAlign="right",t.textBaseline="middle";for(const{py:u,label:g}of n){const B=r+u;b||(t.strokeStyle="rgba(255,255,255,0.85)",t.lineWidth=3,t.beginPath(),t.moveTo(f,B),t.lineTo(f+P,B),t.stroke(),t.strokeStyle="rgba(0,0,0,0.7)",t.lineWidth=1,t.beginPath(),t.moveTo(f,B),t.lineTo(f+P,B),t.stroke()),t.fillStyle=M.text,t.fillText(g,f-3,B);const dt=g==="USL"?-1:1,gt=4,Tt=f-3-t.measureText(g).width-gt-4;t.beginPath(),Ie(t,Tt,B,gt,dt),t.strokeStyle="#fff",t.lineWidth=2,t.lineJoin="round",t.stroke(),t.fillStyle=M.text,t.fill()}t.restore()}}if(!x){const n=e.logScale?"log\u2081\u2080":e.logScaleRequested?"linear \u2014 log n/a":null;n&&(t.save(),t.fillStyle=M.text,t.font=lo(),t.textAlign="right",t.textBaseline="top",t.fillText(n,O-h,A),t.restore(),A+=15)}rt&&w&&it(w,O-h,A,"right","top",W(A),Kt(),M.text)}const ae=[];let J;if(ht){const o=Be(e.colorScheme),c=$==="compact",s=e.plotMode==="softBin"?st:yt,a=s?new Map(s.map(l=>[l.bin,l])):null,r=l=>{const y=a?.get(l);return(e.colorScheme==="custom"?y?.color:void 0)??o.forBin(l)},f=(l,y)=>{const w=t.measureText(l).width,A=c?0:t.measureText(String(y)).width,W=Y+mt+w+(A?zt:0);return{labelWidth:w,countWidth:A,totalWidth:W}},d=bt?.find(l=>l.key===e.activeMetadataKey),i=tt?et.map(l=>{const y=c?l.compactLabel:l.label;return{key:l.key,color:l.color,count:l.count,label:y,tooltipLabel:l.tooltip,...f(y,l.count)}}):e.plotMode==="metadata"?Bt.map(([l,y])=>{const A=d?.values?.find(K=>K.value===l)?.label??l,W=c?l:A,U=e.metadataColorMap?.get(l)??"#d6d9dd";return{key:l,color:U,count:y,label:W,tooltipLabel:`${A} \xB7 ${y} dies`,...f(W,y)}}):Ct.map(([l,y])=>{const w=a?.get(l),A=w?.name?`${l} \xB7 ${w.name}`:`Bin ${l}`,W=c?String(l):A;return{key:l,color:r(l),count:y,label:W,tooltipLabel:`${A} \xB7 ${y} dies`,...f(W,y)}}),p=O-h*2;if(i.length>0){const l=Math.max(1,Math.floor((E-2*h)/D));let y=i.length,w=1,A=y*D,W=[],U=0;const K=Zt||Pt;if(K){const I=Math.max(...i.map(x=>x.totalWidth)),R=Math.max(1,Math.min(i.length,Math.floor((p+8)/(I+8))));for(let x=R;x>=1;x--){const T=Math.ceil(i.length/x);if(T>l)continue;const n=new Array(x).fill(0);for(let u=0;u<i.length;u++){const g=u%x;n[g]=Math.max(n[g],i[u].totalWidth)}if(n.reduce((u,g)=>u+g,0)+(x-1)*8<=p||x===1){w=x,W=n,y=T,A=T*D;break}}}else y=Math.min(i.length,l),A=y*D,i.length>l&&(U=i.length-(l-1)),W=[Dt];let _,C;if(Wt){const I=Math.max(...i.map(g=>Y+mt+t.measureText(g.label).width+zt)),R=Math.ceil(I);W=[R];const x=rt?ao:0,T=R+ut*2,n=A+x+ut*2,b=xt?.x??0,u=xt?.y??0;_=Math.min(Math.max(O-h-T+b,h),O-h-T),C=Math.min(Math.max(E-h-n+u,h),E-h-n),J={x:_,y:C,w:T,h:n},t.save(),t.globalAlpha=.92,t.fillStyle=M.surface,t.fillRect(_,C,T,n),t.globalAlpha=1,t.strokeStyle=M.axisLine,t.lineWidth=1,t.strokeRect(_,C,T,n),t.restore(),_+=ut,C+=ut+x}else Zt?(_=h,C=E-h-A):Pt?(_=h,C=h+Q):fe?(_=h+4,C=h+Math.round((E-2*h-A)/2)):(_=O-h-Dt+4,C=h+Math.round((E-2*h-A)/2));if(rt){const I=e.plotMode==="softBin"?st:yt,{primary:R,secondary:x}=_e(e,St,I),T=6,n=g=>Ht-Math.max(lt(g),lt(g-12))-8,b=g=>re?O-h:n(g),u=Wt?J.y+J.h:C+A;if(Pt){const g=u+T;it(R,_,g,"left","top",Ht-Math.max(lt(g),lt(g+12))-8),x&&it(x,_,g+16,"left","top",n(g+16),Kt(),M.text)}else if(Wt)it(R,J.x+ut,J.y+ut,"left","top",J.x+J.w-ut),x&&it(x,J.x,u+T,"left","top",J.x+J.w,Kt(),M.text);else{const g=Math.max(C-T,h+Q+12);if(it(R,_,g,"left","bottom",b(g)),x){const B=u+T;it(x,_,B,"left","top",b(B),Kt(),M.text)}}}t.save(),t.font=Z();const Rt=K?8:0,v=(I,R)=>{if(t.measureText(I).width<=R)return I;let x=0,T=I.length;const n="\u2026",b=t.measureText(n).width;for(;x<T;){const u=x+T+1>>1;t.measureText(I.slice(0,u)).width+b<=R?x=u:T=u-1}return x===0?n:I.slice(0,x)+n};if(K){let I=0;for(let R=0;R<y;R++){let x=_;for(let T=0;T<w;T++){const n=i[I++];if(!n)break;const b=n.key===N,u=!b&&n.key===z,g=x,B=x+Y+mt,dt=C+R*D+D/2,gt=C+R*D+Math.round((D-Y)/2),Tt=W[T]-Y-mt-zt;u&&(t.fillStyle=M.hoverRow,t.fillRect(x,C+R*D,W[T],D)),t.fillStyle=n.color,t.fillRect(g,gt,Y,Y),t.strokeStyle=b?M.accent:"rgba(0,0,0,0.25)",t.lineWidth=b?2:.75,t.strokeRect(g,gt,Y,Y),t.fillStyle=b?M.accent:M.text,t.font=b?`bold ${Z()}`:Z(),t.textAlign="left",t.textBaseline="middle",t.fillText(v(n.label,Tt),B,dt),t.fillStyle=M.textMuted,t.font=Z(),t.textAlign="right",t.fillText(String(n.count),x+W[T]-2,dt),ae.push({bin:n.key,x,y:C+R*D,w:W[T],h:D,label:n.tooltipLabel}),x+=W[T]+Rt}}}else{const I=W[0],R=$!=="compact",x=I-Y-mt-(R?zt:0),T=_+I-2;let n=i;U>0&&(n=i.slice(0,l-1));let b=C;for(const u of n){const g=u.key===N,B=!g&&u.key===z,dt=_,gt=_+Y+mt,Tt=b+D/2,Ae=b+Math.round((D-Y)/2),ze=u.label;B&&(t.fillStyle=M.hoverRow,t.fillRect(_-3,b,I+3,D)),t.fillStyle=u.color,t.fillRect(dt,Ae,Y,Y),t.strokeStyle=g?M.accent:"rgba(0,0,0,0.25)",t.lineWidth=g?2:.75,t.strokeRect(dt,Ae,Y,Y),t.fillStyle=g?M.accent:M.text,t.font=g?`bold ${Z()}`:Z(),t.textAlign="left",t.textBaseline="middle",t.fillText(v(ze,x),gt,Tt),(R||Wt)&&(t.fillStyle=M.textMuted,t.font=Z(),t.textAlign="right",t.fillText(String(u.count),T,Tt)),ae.push({bin:u.key,x:_,y:b,w:I,h:D,label:u.tooltipLabel}),b+=D}U>0&&(t.fillStyle=M.textMuted,t.font=Z(),t.textAlign="left",t.textBaseline="middle",t.fillText(`+ ${U} more`,_+Y+mt,b+D/2))}}i.length>0&&t.restore()}const Ue={originX:ot,originY:nt,ppm:k,snapDist:Yt},Te=e.rectangles[0]?.width??1,Se=e.rectangles[0]?.height??1,Xt=Te*1.5,$t=Se*1.5,at=e.dieBounds,Gt=at?at.minX:V.length?Math.min(...V.map(o=>o.x)):0,Vt=at?at.minY:V.length?Math.min(...V.map(o=>o.y)):0,Ke=at?at.maxX:V.length?Math.max(...V.map(o=>o.x)):1,qe=at?at.maxY:V.length?Math.max(...V.map(o=>o.y)):1,At=Math.max(1,Math.ceil((Ke-Gt)/Xt)+1),ce=Math.max(1,Math.ceil((qe-Vt)/$t)+1),Le=Array.from({length:At*ce},()=>[]);for(let o=0;o<V.length;o++){const c=Math.floor((V[o].x-Gt)/Xt),s=Math.floor((V[o].y-Vt)/$t),a=Math.max(0,Math.min(At-1,c)),r=Math.max(0,Math.min(ce-1,s));Le[r*At+a].push(o)}function ke(o,c,s){const a=Math.max(0,Math.floor((o-s-Gt)/Xt)),r=Math.min(At-1,Math.floor((o+s-Gt)/Xt)),f=Math.max(0,Math.floor((c-s-Vt)/$t)),d=Math.min(ce-1,Math.floor((c+s-Vt)/$t)),i=[];for(let p=f;p<=d;p++)for(let l=a;l<=r;l++)for(const y of Le[p*At+l])i.push(y);return i}return{hitTarget:{getDieAtPoint(o,c){const s=(o-ot)/k,a=(nt-c)/k,r=Math.max(Te,Se);for(const i of ke(s,a,r)){const p=e.rectangles[i];if(p&&Math.abs(s-p.x)<=p.width/2&&Math.abs(a-p.y)<=p.height/2)return e.dies[i]??null}let f=null,d=Yt*Yt;for(const i of ke(s,a,Yt)){const p=V[i].x-s,l=V[i].y-a,y=p*p+l*l;y<d&&(d=y,f=e.dies[i]??null)}return f}},viewport:Ue,binLegendRows:ae,legendBox:J}}function co(m,e,F,M,h,H,X,P,pt,j,xt,Mt,G){m.save(),m.font=io(),m.fillStyle=G.text,m.strokeStyle=G.axisLine,m.lineWidth=.5;const q=F-P+4,N=X+pt-4,z=Je(xt),St=Ce(z,1,0),Q=Ce(z,0,1),ct=1e-9;function yt(S){return j?Math.abs(S.y)<ct&&Math.abs(S.x)>ct?{pitch:j.x,sign:Math.sign(S.x)}:Math.abs(S.x)<ct&&Math.abs(S.y)>ct?{pitch:j.y,sign:Math.sign(S.y)}:null:null}const st=yt(St),bt=yt(Q);function rt(S){return st?Math.round(S*st.sign/st.pitch):S}function O(S){return bt?Math.round(S*bt.sign/bt.pitch):S}function E(S){if(!S)return Jt(50/H);const L=50/(S*H);return Math.max(1,Math.round(L))*S}const Lt=st?.pitch,kt=bt?.pitch,ft=E(Lt),tt=E(kt);m.textAlign="center",m.textBaseline="top";const ht=Math.ceil((X-M)/H/ft)*ft,Ct=(e-X-M)/H;for(let S=ht;S<=Ct;S+=ft){const L=M+S*H;if(L<X||L>e-X)continue;m.beginPath(),m.moveTo(L,q-Ne),m.lineTo(L,q),m.stroke();const $=j?String(rt(S)):Oe(S);m.fillText($,L,q+2)}m.textAlign="right",m.textBaseline="middle";const Bt=Math.ceil((h-(F-X))/H/tt)*tt,et=(h-X)/H;for(let S=Bt;S<=et;S+=tt){const L=h-S*H;if(L<X||L>F-X)continue;m.beginPath(),m.moveTo(N,L),m.lineTo(N+Ne,L),m.stroke();const $=j?String(O(S)):Oe(S);m.fillText($,N-2,L)}m.restore()}function Jt(m){const e=Math.pow(10,Math.floor(Math.log10(m))),F=m/e;return(F<1.5?1:F<3.5?2:F<7.5?5:10)*e}function ro(m,e,F,M,h,H,X){const P=[],pt=X;if(pt<1){const G=Jt((e-m)*M/F);if(G>0){const q=Math.ceil(m/G)*G;for(let N=q;N<=e+G*1e-6;N+=G){if(N<=m||N>=e)continue;const z=(1-(Math.log10(N)-H)/X)*F;z>h&&z<F-h&&P.push(N)}}return P}const j=pt<3?[1,2,5]:[1],xt=Math.floor(Math.log10(m)),Mt=Math.ceil(Math.log10(e));for(let G=xt;G<=Mt;G++)for(const q of j){const N=q*Math.pow(10,G);if(N<=m||N>=e)continue;const z=(1-(Math.log10(N)-H)/X)*F;z>h&&z<F-h&&P.push(N)}return P}export{fmt,fmtColorbarAxis}from"../renderer/fmt.js";
|
|
1
|
+
import{fontPx as Ct}from"./toolbar.js";import{findTestDef as Re,buildMapTitle as Ce}from"../renderer/buildView.js";import{affineInvert as ze,affineVector as _e}from"../core/transforms.js";import{compareNatural as Je}from"../core/utils.js";import{resolveValueColorFn as Ze}from"../renderer/colorSchemes.js";import{NO_DATA_FILL as je}from"../renderer/colorMap.js";import{SPEC_PASS_FILL as Be,SPEC_FAIL_LOW as Qe,SPEC_FAIL_HIGH as Pe,contrastTextColor as We}from"../renderer/colorMap.js";import{fmt as De,fmtColorbarAxis as ve}from"../renderer/fmt.js";import{resolveCanvasTheme as to}from"./canvasTheme.js";import{hitGridDims as eo}from"./hitGrid.js";function Oe(m,e,I,M,h){m.moveTo(e,I+h*M),m.lineTo(e-M*.9,I-h*M*.6),m.lineTo(e+M*.9,I-h*M*.6),m.closePath()}const oo=new Set(["value","stackedValues","stackedBins","stackedSoftBins"]),no=new Set(["hardBin","softBin","metadata"]),Z=()=>`${Ct(-2)}px system-ui, sans-serif`,Fe=3,Gt=2,so=6,lo=20,io=()=>`600 ${Ct()}px system-ui, sans-serif`,Vt=()=>`${Ct(-1)}px system-ui, sans-serif`,ao=()=>`600 ${Ct(-1)}px system-ui, sans-serif`,Ut=128,co=()=>`${Ct(-2)}px system-ui, sans-serif`,Ie=4,D=17,w=11;export const BIN_LEGEND_W=110,BIN_LEGEND_W_COMPACT=64,BIN_LEGEND_ADAPT_COMPACT=280,BIN_LEGEND_ADAPT_FLOATING=180,BIN_LEGEND_MIN_CANVAS_W=150,BIN_LEGEND_MIN_CANVAS_H=120;const Kt=28,mt=5,ut=8,ro=15;export function toCanvas(m,e,I={}){const M=to(m.parentElement??m),{padding:h=16,showColorbar:H=!0,markFailingDies:X=!1,colorbarWidth:P=16,background:pt=M.background,legendPosition:j="default",legendOffset:xt,showAxes:Mt=!1,diePitchMm:V,viewport:q,activeBin:N,hoverBin:z,fallbackFormat:St,topClearance:Q=0,minRightReserve:ct,hbinDefs:yt,sbinDefs:st,metadataFields:bt,showTitle:rt=!0}=I,O=Math.floor(m.clientWidth||m.width),E=Math.floor(m.clientHeight||m.height),Lt=O>=BIN_LEGEND_MIN_CANVAS_W&&E>=BIN_LEGEND_MIN_CANVAS_H,kt=H&&Lt&&oo.has(e.plotMode)&&e.passFailDisplay==="off",ft=H&&Lt&&no.has(e.plotMode),tt=H&&Lt&&e.plotMode==="value"&&(e.passFailDisplay==="spec"&&e.specCounts!==void 0||e.passFailDisplay==="test"&&e.passFailCounts!==void 0),ht=ft||tt,_t=ft&&e.plotMode!=="metadata"&&e.binCounts?[...e.binCounts.entries()].sort(([o],[c])=>o-c):[],Bt=ft&&e.plotMode==="metadata"&&e.metadataCounts?[...e.metadataColorMap?.keys()??[...e.metadataCounts.keys()].sort(Je)].map(o=>[o,e.metadataCounts.get(o)??0]):[],et=[];if(tt&&e.passFailDisplay==="test"){const o=e.passFailCounts;et.push({key:-1,color:Be,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),et.push({key:-2,color:Pe,label:"Fail",compactLabel:"Fail",count:o.fail,tooltip:`Fail \xB7 ${o.fail} dies`})}else if(tt){const o=e.specCounts,c=Re(e.testDefs,e.activeTest);et.push({key:-1,color:Be,label:"Pass",compactLabel:"Pass",count:o.pass,tooltip:`Pass \xB7 ${o.pass} dies`}),c?.limitHigh!==void 0&&et.push({key:-2,color:Pe,label:"Fail high",compactLabel:"Fail hi",count:o.failHigh,tooltip:`Fail high \xB7 ${o.failHigh} dies`}),c?.limitLow!==void 0&&et.push({key:-3,color:Qe,label:"Fail low",compactLabel:"Fail lo",count:o.failLow,tooltip:`Fail low \xB7 ${o.failLow} dies`})}const S=tt?et.length:e.plotMode==="metadata"?Bt.length:_t.length,L=(m.ownerDocument.defaultView??window).devicePixelRatio??1;if(O<=0||E<=0)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const $=j!=="default"?j:O<BIN_LEGEND_ADAPT_FLOATING?"floating":O<BIN_LEGEND_ADAPT_COMPACT?"compact":"default",re=$==="default"||$==="compact",fe=$==="left",zt=$==="bottom",Pt=$==="top",Wt=$==="floating",Dt=$==="compact"||$==="floating"?BIN_LEGEND_W_COMPACT:BIN_LEGEND_W,he=Math.floor((E-2*h)/D),de=S>he?he-1:S,ge=ht&&zt?de*D:0,Jt=ht&&Pt?de*D:0,Zt=e.plotMode==="stackedBins"||e.plotMode==="stackedSoftBins",jt=Re(e.testDefs,e.activeTest),Ne=Zt?"Count":jt?.name??(e.activeTest!=null?`Test ${e.activeTest}`:void 0),Ee=Zt?void 0:jt?.unit,[Ot,Ft]=e.valueRange,{tickFmt:Ye}=ve(Ft,Ne,Ee,St),It=e.allIntegerValues?o=>String(Math.round(o)):Ye;let Qt=0;if(kt){const o=m.getContext("2d");o.font=Z();const c=[It(Ot),It(Ft)];Ot<0&&c.push(It(-Math.max(Math.abs(Ot),Math.abs(Ft))));for(const s of c)Qt=Math.max(Qt,o.measureText(s).width)}const me=Math.max(lo,Math.ceil(Qt)+Fe+Gt+so-h),vt=kt?P+me+8:ht&&re?Dt:0,te=ht&&fe?Dt:0,ee=Mt?32:0,Nt=Mt?36:0,we=ct!=null?Math.max(vt,ct):vt,He=O-2*h-we-Nt-te,ue=E-2*h-ee-ge-Jt;m.width=Math.round(O*L),m.height=Math.round(E*L);const t=m.getContext("2d");t.scale(L,L),t.fillStyle=pt,t.fillRect(0,0,O,E);const G=e.hoverPoints;if(!G.length)return{hitTarget:{getDieAtPoint:()=>null},viewport:{originX:0,originY:0,ppm:1,snapDist:1},binLegendRows:[]};const Et=e.rectangles[0],oe=Et?Et.width/2:0,ne=Et?Et.height/2:0,Yt=e.dieBounds,pe=(Yt?.minX??0)-oe,Xe=(Yt?.maxX??0)+oe,$e=(Yt?.minY??0)-ne,xe=(Yt?.maxY??0)+ne,Me=Xe-pe,ye=xe-$e;let ot,nt,k;if(q)({originX:ot,originY:nt,ppm:k}=q);else{const c=e.notchDir,s=c&&c.y>.1?13:0,a=c&&c.y<-.1?13:0,r=c&&c.x<-.1?13:0,f=c&&c.x>.1?13:0,d=He-r-f,i=ue-Q-s-a;k=Math.min(d/Me,i/ye),ot=h+Nt+te+r+(d-Me*k)/2-pe*k,nt=h+Q+Jt+s+(i-ye*k)/2+xe*k}const wt=q?.snapDist??Math.max(oe,ne,1)*1.5,Ht=ot+e.waferCenter.x*k,Ge=nt-e.waferCenter.y*k,se=e.waferRadius*k,lt=o=>{const c=Math.abs(o-Ge);return c>=se?0:Math.sqrt(se*se-c*c)},it=(o,c,s,a,r,f,d=io(),i=M.text)=>{if(!o)return;t.save(),t.fillStyle=i,t.font=d,t.textAlign=a,t.textBaseline=r;const p=a==="right"?c-f:f-c;let l=o;if(p>8&&t.measureText(l).width>p){for(;l.length>1&&t.measureText(l+"\u2026").width>p;)l=l.slice(0,-1);l=l+"\u2026"}p>8&&t.fillText(l,c,s),t.restore()};if(t.save(),t.setTransform(k*L,0,0,-k*L,ot*L,nt*L),e.rectangles.length>0){const o=new Map;for(const s of e.rectangles){const a=String(s.fill);let r=o.get(a);r||(r=[],o.set(a,r)),r.push(s)}for(const[s,a]of o){t.beginPath();for(const r of a)t.rect(r.x-r.width/2,r.y-r.height/2,r.width,r.height);t.fillStyle=s,t.fill()}t.strokeStyle="rgba(0,0,0,0.18)",t.lineWidth=.5/(k*L),t.beginPath();for(const s of e.rectangles)t.rect(s.x-s.width/2,s.y-s.height/2,s.width,s.height);if(t.stroke(),X){const s=e.rectangles.filter(a=>a.binFail);if(s.length>0){const a=new Map;for(const r of s){const f=We(String(r.fill));let d=a.get(f);d||(d=[],a.set(f,d)),d.push(r)}t.save(),t.lineCap="butt";for(const[r,f]of a){t.strokeStyle=r,t.globalAlpha=.55,t.lineWidth=Math.max(.6/(k*L),Math.min(f[0].width,f[0].height)*.1);for(const d of f){const i=d.width/2,p=d.height/2,l=Math.max(1.6/(k*L),Math.min(d.width,d.height)/3);t.save(),t.beginPath(),t.rect(d.x-i,d.y-p,d.width,d.height),t.clip(),t.beginPath();for(let b=-(i+p);b<=i+p;b+=l)t.moveTo(d.x-i+b,d.y-p),t.lineTo(d.x-i+b+d.height,d.y+p);t.stroke(),t.restore()}}t.restore()}}const c=e.rectangles.filter(s=>s.specMark);if(c.length>0){const s=new Map;for(const r of c){const f=We(String(r.fill)),d=`${r.specMark}|${f}`;let i=s.get(d);i||(i=[],s.set(d,i)),i.push(r)}const a=2.5/(k*L);t.lineJoin="round";for(const[r,f]of s){const[d,i]=r.split("|"),p=i==="#000000"?"#ffffff":"#000000",l=d==="failHigh"?1:-1,b=Math.min(f[0].width,f[0].height),Y=Math.max(2.5/(k*L),b*.3);t.beginPath();for(const A of f)Oe(t,A.x,A.y,Y,l);t.strokeStyle=p,t.lineWidth=a,t.stroke(),t.fillStyle=i,t.fill()}}}for(const o of e.overlays){t.beginPath();for(const c of o.points){for(let s=0;s<c.length;s++)s===0?t.moveTo(c[s].x,c[s].y):t.lineTo(c[s].x,c[s].y);o.closed&&t.closePath()}o.fill&&!o.fill.startsWith("rgba(0,0,0,0)")&&(t.fillStyle=o.fill,t.fill()),o.kind==="ring-boundary"||o.kind==="quadrant-boundary"||o.kind==="reticle"?(t.strokeStyle="rgba(0,0,0,0.45)",t.lineWidth=3/(k*L),t.stroke(),t.strokeStyle="rgba(255,255,255,0.8)",t.lineWidth=1/(k*L),t.stroke()):(t.strokeStyle=o.lineColor,t.lineWidth=o.lineWidth/(k*L),t.stroke())}if(t.restore(),e.notchDir){const o=ot+e.waferCenter.x*k,c=nt-e.waferCenter.y*k,s=e.notchDir.x,a=-e.notchDir.y,r=e.waferRadius*k,f=4,d=9,i=5,p=o+s*(r+f),l=c+a*(r+f),b=p+s*d,Y=l+a*d,A={x:-a,y:s},W=h+Nt+te,U=O-h-vt,K=h+Q+Jt,C=E-h-ge-ee;t.save(),t.beginPath(),t.rect(W,K,U-W,C-K),t.clip(),t.beginPath(),t.moveTo(p,l),t.lineTo(b+A.x*i,Y+A.y*i),t.lineTo(b-A.x*i,Y-A.y*i),t.closePath(),t.fillStyle=M.text,t.fill(),t.restore()}t.save(),t.textAlign="center",t.textBaseline="middle";let be=0;if(e.rectangles.length>0){let o=1;for(const f of e.texts)f.role!=="indicator"&&f.text.length>o&&(o=f.text.length);const c=e.rectangles[0].width*k,s=e.rectangles[0].height*k,a=Math.min(c,s),r=c/o;be=Math.max(8,Math.min(64,Math.round(Math.min(a*.55,r*1.8))))}for(const o of e.texts){const c=ot+o.x*k,s=nt-o.y*k;t.font=`${o.role==="indicator"?o.fontSize:be}px system-ui, sans-serif`,t.fillStyle=o.color,t.fillText(o.text,c,s)}if(t.restore(),Mt&&fo(t,O,E,ot,nt,k,h,ee,Nt,V,e.gridToScreen,e.rotation,M),kt){const o=Ze(e.valueColorScheme,e.reverseValueScheme),c=me,s=ue-Q,a=Math.round(s*.75),r=h+Q+Math.round((s-a)/2),f=O-h-P-c,d=Ot,i=Ft,p=i-d,l=e.plotMode==="stackedSoftBins"?st:yt,{primary:b,secondary:Y}=rt?Ce(e,St,l):{primary:"",secondary:""};if(rt){const n=Math.max(r-6,h+Q+11),y=Ht+Math.max(lt(n),lt(n-12))+8;it(b,O-h,n,"right","bottom",y)}let A=r+a+4;const W=n=>Ht+Math.max(lt(n),lt(n+12))+8,U=e.logScale&&d>0?Math.log10(d):0,K=e.logScale&&i>0?Math.log10(i)-U:1,C=n=>e.logScale?(1-(Math.log10(n)-U)/K)*a:(1-(n-d)/p)*a;for(let n=0;n<Ut;n++){const y=1-n/(Ut-1),u=r+n/Ut*a,g=a/Ut+1;t.fillStyle=o(y),t.fillRect(f,u,P,g)}t.strokeStyle="rgba(0,0,0,0.25)",t.lineWidth=.5,t.strokeRect(f,r,P,a),t.fillStyle=M.text,t.font=Z(),t.textAlign="left",t.strokeStyle="rgba(0,0,0,0.35)",t.lineWidth=.5;const _=Fe,Rt=36,v=14,F=e.logScale&&K>0?ho(d,i,a,Rt,v,U,K):e.allIntegerValues?(()=>{const n=Math.max(1,qt(p*Rt/a)),y=[],u=Math.ceil(d/n)*n;for(let g=u;g<=i+n*1e-6;g+=n){const B=(1-(g-d)/p)*a;B>v&&B<a-v&&y.push(Math.round(g))}return y})():(()=>{const n=p>0?qt(p*Rt/a):0,y=[];if(n>0){const u=Math.ceil(d/n)*n;for(let g=u;g<=i+n*1e-6;g+=n){const B=(1-(g-d)/p)*a;B>v&&B<a-v&&y.push(g)}}return y})(),R=jt,x=Zt,T=It;t.textBaseline="middle";for(const n of F){const y=r+C(n);t.beginPath(),t.moveTo(f+P,y),t.lineTo(f+P+_,y),t.stroke(),t.fillText(T(n),f+P+_+Gt,y)}if(t.beginPath(),t.moveTo(f+P,r),t.lineTo(f+P+_,r),t.stroke(),t.textBaseline="top",t.fillText(T(i),f+P+_+Gt,r),t.beginPath(),t.moveTo(f+P,r+a),t.lineTo(f+P+_,r+a),t.stroke(),t.textBaseline="bottom",t.fillText(T(d),f+P+_+Gt,r+a),!x&&R&&(R.limitLow!==void 0||R.limitHigh!==void 0)){const n=[],y=e.colorbarRangeMode==="spec";for(const[u,g]of[[R.limitLow,"LSL"],[R.limitHigh,"USL"]]){if(u===void 0||e.logScale&&u<=0)continue;const B=C(u);!y&&(B<-v||B>a+v)||n.push({value:u,label:g,py:Math.max(0,Math.min(a,B))})}if(n.length>0){t.save(),t.font=Z(),t.textAlign="right",t.textBaseline="middle";for(const{py:u,label:g}of n){const B=r+u;y||(t.strokeStyle="rgba(255,255,255,0.85)",t.lineWidth=3,t.beginPath(),t.moveTo(f,B),t.lineTo(f+P,B),t.stroke(),t.strokeStyle="rgba(0,0,0,0.7)",t.lineWidth=1,t.beginPath(),t.moveTo(f,B),t.lineTo(f+P,B),t.stroke()),t.fillStyle=M.text,t.fillText(g,f-3,B);const dt=g==="USL"?-1:1,gt=4,Tt=f-3-t.measureText(g).width-gt-4;t.beginPath(),Oe(t,Tt,B,gt,dt),t.strokeStyle="#fff",t.lineWidth=2,t.lineJoin="round",t.stroke(),t.fillStyle=M.text,t.fill()}t.restore()}}if(!x){const n=e.logScale?"log\u2081\u2080":e.logScaleRequested?"linear \u2014 log n/a":null;n&&(t.save(),t.fillStyle=M.text,t.font=ao(),t.textAlign="right",t.textBaseline="top",t.fillText(n,O-h,A),t.restore(),A+=15)}rt&&Y&&it(Y,O-h,A,"right","top",W(A),Vt(),M.text)}const le=[];let J;if(ht){const o=$==="compact",c=e.plotMode==="softBin"?st:yt,s=c?new Map(c.map(l=>[l.bin,l])):null,a=e.plotMode==="softBin"?e.binColors.soft:e.binColors.hard,r=l=>a.get(l)??je,f=(l,b)=>{const Y=t.measureText(l).width,A=o?0:t.measureText(String(b)).width,W=w+mt+Y+(A?Kt:0);return{labelWidth:Y,countWidth:A,totalWidth:W}},d=bt?.find(l=>l.key===e.activeMetadataKey),i=tt?et.map(l=>{const b=o?l.compactLabel:l.label;return{key:l.key,color:l.color,count:l.count,label:b,tooltipLabel:l.tooltip,...f(b,l.count)}}):e.plotMode==="metadata"?Bt.map(([l,b])=>{const A=d?.values?.find(K=>K.value===l)?.label??l,W=o?l:A,U=e.metadataColorMap?.get(l)??"#d6d9dd";return{key:l,color:U,count:b,label:W,tooltipLabel:`${A} \xB7 ${b} dies`,...f(W,b)}}):_t.map(([l,b])=>{const Y=s?.get(l),A=Y?.name?`${l} \xB7 ${Y.name}`:`Bin ${l}`,W=o?String(l):A;return{key:l,color:r(l),count:b,label:W,tooltipLabel:`${A} \xB7 ${b} dies`,...f(W,b)}}),p=O-h*2;if(i.length>0){const l=Math.max(1,Math.floor((E-2*h)/D));let b=i.length,Y=1,A=b*D,W=[],U=0;const K=zt||Pt;if(K){const F=Math.max(...i.map(x=>x.totalWidth)),R=Math.max(1,Math.min(i.length,Math.floor((p+8)/(F+8))));for(let x=R;x>=1;x--){const T=Math.ceil(i.length/x);if(T>l)continue;const n=new Array(x).fill(0);for(let u=0;u<i.length;u++){const g=u%x;n[g]=Math.max(n[g],i[u].totalWidth)}if(n.reduce((u,g)=>u+g,0)+(x-1)*8<=p||x===1){Y=x,W=n,b=T,A=T*D;break}}}else b=Math.min(i.length,l),A=b*D,i.length>l&&(U=i.length-(l-1)),W=[Dt];let C,_;if(Wt){const F=Math.max(...i.map(g=>w+mt+t.measureText(g.label).width+Kt)),R=Math.ceil(F);W=[R];const x=rt?ro:0,T=R+ut*2,n=A+x+ut*2,y=xt?.x??0,u=xt?.y??0;C=Math.min(Math.max(O-h-T+y,h),O-h-T),_=Math.min(Math.max(E-h-n+u,h),E-h-n),J={x:C,y:_,w:T,h:n},t.save(),t.globalAlpha=.92,t.fillStyle=M.surface,t.fillRect(C,_,T,n),t.globalAlpha=1,t.strokeStyle=M.axisLine,t.lineWidth=1,t.strokeRect(C,_,T,n),t.restore(),C+=ut,_+=ut+x}else zt?(C=h,_=E-h-A):Pt?(C=h,_=h+Q):fe?(C=h+4,_=h+Math.round((E-2*h-A)/2)):(C=O-h-Dt+4,_=h+Math.round((E-2*h-A)/2));if(rt){const F=e.plotMode==="softBin"?st:yt,{primary:R,secondary:x}=Ce(e,St,F),T=6,n=g=>Ht-Math.max(lt(g),lt(g-12))-8,y=g=>re?O-h:n(g),u=Wt?J.y+J.h:_+A;if(Pt){const g=u+T;it(R,C,g,"left","top",Ht-Math.max(lt(g),lt(g+12))-8),x&&it(x,C,g+16,"left","top",n(g+16),Vt(),M.text)}else if(Wt)it(R,J.x+ut,J.y+ut,"left","top",J.x+J.w-ut),x&&it(x,J.x,u+T,"left","top",J.x+J.w,Vt(),M.text);else{const g=Math.max(_-T,h+Q+12);if(it(R,C,g,"left","bottom",y(g)),x){const B=u+T;it(x,C,B,"left","top",y(B),Vt(),M.text)}}}t.save(),t.font=Z();const Rt=K?8:0,v=(F,R)=>{if(t.measureText(F).width<=R)return F;let x=0,T=F.length;const n="\u2026",y=t.measureText(n).width;for(;x<T;){const u=x+T+1>>1;t.measureText(F.slice(0,u)).width+y<=R?x=u:T=u-1}return x===0?n:F.slice(0,x)+n};if(K){let F=0;for(let R=0;R<b;R++){let x=C;for(let T=0;T<Y;T++){const n=i[F++];if(!n)break;const y=n.key===N,u=!y&&n.key===z,g=x,B=x+w+mt,dt=_+R*D+D/2,gt=_+R*D+Math.round((D-w)/2),Tt=W[T]-w-mt-Kt;u&&(t.fillStyle=M.hoverRow,t.fillRect(x,_+R*D,W[T],D)),t.fillStyle=n.color,t.fillRect(g,gt,w,w),t.strokeStyle=y?M.accent:"rgba(0,0,0,0.25)",t.lineWidth=y?2:.75,t.strokeRect(g,gt,w,w),t.fillStyle=y?M.accent:M.text,t.font=y?`bold ${Z()}`:Z(),t.textAlign="left",t.textBaseline="middle",t.fillText(v(n.label,Tt),B,dt),t.fillStyle=M.textMuted,t.font=Z(),t.textAlign="right",t.fillText(String(n.count),x+W[T]-2,dt),le.push({bin:n.key,x,y:_+R*D,w:W[T],h:D,label:n.tooltipLabel}),x+=W[T]+Rt}}}else{const F=W[0],R=$!=="compact",x=F-w-mt-(R?Kt:0),T=C+F-2;let n=i;U>0&&(n=i.slice(0,l-1));let y=_;for(const u of n){const g=u.key===N,B=!g&&u.key===z,dt=C,gt=C+w+mt,Tt=y+D/2,Ae=y+Math.round((D-w)/2),qe=u.label;B&&(t.fillStyle=M.hoverRow,t.fillRect(C-3,y,F+3,D)),t.fillStyle=u.color,t.fillRect(dt,Ae,w,w),t.strokeStyle=g?M.accent:"rgba(0,0,0,0.25)",t.lineWidth=g?2:.75,t.strokeRect(dt,Ae,w,w),t.fillStyle=g?M.accent:M.text,t.font=g?`bold ${Z()}`:Z(),t.textAlign="left",t.textBaseline="middle",t.fillText(v(qe,x),gt,Tt),(R||Wt)&&(t.fillStyle=M.textMuted,t.font=Z(),t.textAlign="right",t.fillText(String(u.count),T,Tt)),le.push({bin:u.key,x:C,y,w:F,h:D,label:u.tooltipLabel}),y+=D}U>0&&(t.fillStyle=M.textMuted,t.font=Z(),t.textAlign="left",t.textBaseline="middle",t.fillText(`+ ${U} more`,C+w+mt,y+D/2))}}i.length>0&&t.restore()}const Ve={originX:ot,originY:nt,ppm:k,snapDist:wt},Te=e.rectangles[0]?.width??1,Se=e.rectangles[0]?.height??1,at=e.dieBounds,Xt=at?at.minX:G.length?Math.min(...G.map(o=>o.x)):0,$t=at?at.minY:G.length?Math.min(...G.map(o=>o.y)):0,Ue=at?at.maxX:G.length?Math.max(...G.map(o=>o.x)):1,Ke=at?at.maxY:G.length?Math.max(...G.map(o=>o.y)):1,{cellW:ie,cellH:ae,nCols:At,nRows:ce}=eo(Ue-Xt,Ke-$t,Te*1.5,Se*1.5,G.length),Le=Array.from({length:At*ce},()=>[]);for(let o=0;o<G.length;o++){const c=Math.floor((G[o].x-Xt)/ie),s=Math.floor((G[o].y-$t)/ae),a=Number.isFinite(c)?Math.max(0,Math.min(At-1,c)):0,r=Number.isFinite(s)?Math.max(0,Math.min(ce-1,s)):0;Le[r*At+a].push(o)}function ke(o,c,s){const a=Math.max(0,Math.floor((o-s-Xt)/ie)),r=Math.min(At-1,Math.floor((o+s-Xt)/ie)),f=Math.max(0,Math.floor((c-s-$t)/ae)),d=Math.min(ce-1,Math.floor((c+s-$t)/ae)),i=[];for(let p=f;p<=d;p++)for(let l=a;l<=r;l++)for(const b of Le[p*At+l])i.push(b);return i}return{hitTarget:{getDieAtPoint(o,c){const s=(o-ot)/k,a=(nt-c)/k,r=Math.max(Te,Se);for(const i of ke(s,a,r)){const p=e.rectangles[i];if(p&&Math.abs(s-p.x)<=p.width/2&&Math.abs(a-p.y)<=p.height/2)return e.dies[i]??null}let f=null,d=wt*wt;for(const i of ke(s,a,wt)){const p=G[i].x-s,l=G[i].y-a,b=p*p+l*l;b<d&&(d=b,f=e.dies[i]??null)}return f}},viewport:Ve,binLegendRows:le,legendBox:J}}function fo(m,e,I,M,h,H,X,P,pt,j,xt,Mt,V){m.save(),m.font=co(),m.fillStyle=V.text,m.strokeStyle=V.axisLine,m.lineWidth=.5;const q=I-P+4,N=X+pt-4,z=ze(xt),St=_e(z,1,0),Q=_e(z,0,1),ct=1e-9;function yt(S){return j?Math.abs(S.y)<ct&&Math.abs(S.x)>ct?{pitch:j.x,sign:Math.sign(S.x)}:Math.abs(S.x)<ct&&Math.abs(S.y)>ct?{pitch:j.y,sign:Math.sign(S.y)}:null:null}const st=yt(St),bt=yt(Q);function rt(S){return st?Math.round(S*st.sign/st.pitch):S}function O(S){return bt?Math.round(S*bt.sign/bt.pitch):S}function E(S){if(!S)return qt(50/H);const L=50/(S*H);return Math.max(1,Math.round(L))*S}const Lt=st?.pitch,kt=bt?.pitch,ft=E(Lt),tt=E(kt);m.textAlign="center",m.textBaseline="top";const ht=Math.ceil((X-M)/H/ft)*ft,_t=(e-X-M)/H;for(let S=ht;S<=_t;S+=ft){const L=M+S*H;if(L<X||L>e-X)continue;m.beginPath(),m.moveTo(L,q-Ie),m.lineTo(L,q),m.stroke();const $=j?String(rt(S)):De(S);m.fillText($,L,q+2)}m.textAlign="right",m.textBaseline="middle";const Bt=Math.ceil((h-(I-X))/H/tt)*tt,et=(h-X)/H;for(let S=Bt;S<=et;S+=tt){const L=h-S*H;if(L<X||L>I-X)continue;m.beginPath(),m.moveTo(N,L),m.lineTo(N+Ie,L),m.stroke();const $=j?String(O(S)):De(S);m.fillText($,N-2,L)}m.restore()}function qt(m){const e=Math.pow(10,Math.floor(Math.log10(m))),I=m/e;return(I<1.5?1:I<3.5?2:I<7.5?5:10)*e}function ho(m,e,I,M,h,H,X){const P=[],pt=X;if(pt<1){const V=qt((e-m)*M/I);if(V>0){const q=Math.ceil(m/V)*V;for(let N=q;N<=e+V*1e-6;N+=V){if(N<=m||N>=e)continue;const z=(1-(Math.log10(N)-H)/X)*I;z>h&&z<I-h&&P.push(N)}}return P}const j=pt<3?[1,2,5]:[1],xt=Math.floor(Math.log10(m)),Mt=Math.ceil(Math.log10(e));for(let V=xt;V<=Mt;V++)for(const q of j){const N=q*Math.pow(10,V);if(N<=m||N>=e)continue;const z=(1-(Math.log10(N)-H)/X)*I;z>h&&z<I-h&&P.push(N)}return P}export{fmt,fmtColorbarAxis}from"../renderer/fmt.js";
|
|
@@ -579,6 +579,14 @@ export type CheckMenuRow = {
|
|
|
579
579
|
* missing feature, and the user has no way to learn the condition.
|
|
580
580
|
*/
|
|
581
581
|
disabledHint?: string;
|
|
582
|
+
/**
|
|
583
|
+
* Marks a row that *does* something rather than holding a state — "Clear
|
|
584
|
+
* overlays", "Reset orientation". Rendered as a plain `menuitem` with no
|
|
585
|
+
* tick: every other row here is a checkbox, and an action wearing an
|
|
586
|
+
* unchecked ✓ both looks like a toggle that is off and announces itself as
|
|
587
|
+
* one to a screen reader.
|
|
588
|
+
*/
|
|
589
|
+
action?: boolean;
|
|
582
590
|
onClick: (e: MouseEvent) => void;
|
|
583
591
|
};
|
|
584
592
|
/**
|
|
@@ -704,18 +712,35 @@ export declare function openReparentedModal(elements: HTMLElement[], opts?: Repa
|
|
|
704
712
|
* hardBin/softBin restriction (which still changes the die colours, just from
|
|
705
713
|
* a smaller scheme set).
|
|
706
714
|
*/
|
|
715
|
+
/** The colour preferences the palette menu reads and writes. */
|
|
716
|
+
export interface PaletteState {
|
|
717
|
+
plotMode: PlotMode;
|
|
718
|
+
binColorScheme?: string;
|
|
719
|
+
valueColorScheme?: string;
|
|
720
|
+
reverseValueScheme?: boolean;
|
|
721
|
+
useDefinedBinColors?: boolean;
|
|
722
|
+
}
|
|
707
723
|
/**
|
|
708
|
-
* Colour-scheme picker
|
|
709
|
-
*
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
724
|
+
* Colour-scheme picker. Lists bin palettes in `hardBin`/`softBin` and value
|
|
725
|
+
* gradients everywhere else — including the stacked modes, whose maps are
|
|
726
|
+
* values (a bin's occurrence rate per position), not bin categories. The two
|
|
727
|
+
* are separate preferences, so choosing a gradient for values leaves the bin
|
|
728
|
+
* palette alone and vice versa; nothing is reset on a mode switch.
|
|
729
|
+
*
|
|
730
|
+
* Colours that arrive with the data (`BinDef.color`) are a layer over the bin
|
|
731
|
+
* palette, not a pseudo-palette: the "Use colours from bin definitions" row
|
|
732
|
+
* appears only when some definition carries a colour, and turning it off
|
|
733
|
+
* shows the palette's own colours for those bins.
|
|
734
|
+
*
|
|
735
|
+
* "Mark failing dies" used to live here too; it is in Overlays, beside the
|
|
736
|
+
* pass/fail display rows it belongs with.
|
|
737
|
+
*/
|
|
738
|
+
export declare function makePaletteBtn(helpers: ToolbarHelpers, getState: () => PaletteState, hasDefinedBinColors: () => boolean, apply: (partial: {
|
|
739
|
+
binColorScheme?: string;
|
|
740
|
+
valueColorScheme?: string;
|
|
741
|
+
reverseValueScheme?: boolean;
|
|
742
|
+
useDefinedBinColors?: boolean;
|
|
743
|
+
}) => void): {
|
|
719
744
|
btn: HTMLButtonElement;
|
|
720
745
|
sync: () => void;
|
|
721
746
|
};
|
|
@@ -739,6 +764,15 @@ export interface OverlayFlags {
|
|
|
739
764
|
showReticle?: boolean;
|
|
740
765
|
showXYIndicator?: boolean;
|
|
741
766
|
passFailDisplay?: 'off' | 'spec' | 'test';
|
|
767
|
+
/**
|
|
768
|
+
* Moved here from the Colour scheme menu, where it had been the one entry
|
|
769
|
+
* that was not a scheme — a marker drawn over dies sitting among mutually
|
|
770
|
+
* exclusive palettes. Overlays is where its sibling already lived: the
|
|
771
|
+
* pass/fail display rows below are the same kind of judgement about the same
|
|
772
|
+
* dies, and putting the two in different menus made neither findable from the
|
|
773
|
+
* other.
|
|
774
|
+
*/
|
|
775
|
+
markFailingDies?: boolean;
|
|
742
776
|
}
|
|
743
777
|
/**
|
|
744
778
|
* The Overlays menu's rows — the five geometry toggles plus whatever
|
|
@@ -760,6 +794,7 @@ export declare function overlayMenuRows(flags: OverlayFlags, reticleEnabled: boo
|
|
|
760
794
|
functionalActive: boolean;
|
|
761
795
|
hasLimits: boolean;
|
|
762
796
|
hasRecorded: boolean;
|
|
797
|
+
binMode: boolean;
|
|
763
798
|
}, apply: (patch: OverlayFlags) => void): CheckMenuRow[];
|
|
764
799
|
/** Whether any overlay is on — the Overlays button's "active" state. Shared for
|
|
765
800
|
* the same reason as the rows: it enumerates the same five flags. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as ge}from"../renderer/buildView.js";import{dieHasTestData as ye}from"../renderer/buildWaferMap.js";import{prettyKey as we}from"../core/utils.js";import{listColorSchemes as le}from"../renderer/colorSchemes.js";import{ICONS as R}from"./icons.js";import{WMAP_VERSION as Ee,WMAP_BUILD_TIME as ke}from"./version.js";import{openHtmlReport as Le}from"../stats/renderFindingsReport.js";import{buildWaferMap as Ce}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ae}from"../stats/analyzeWaferMap.js";let ce=!1;export function logWmapVersionOnce(){ce||(ce=!0,console.log(`[wmap] v${Ee} (built ${ke})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","control-border","menu-hover","menu-active","font-family","font-size","density","panel-bg","text-muted","text","text-strong","warn-bg","warn-border","warn-text","err-bg","err-border","err-text","info-bg","info-text","selected","finding-indicator","canvas-bg","bar-fill"];const E=(e,t)=>`var(--wmap-${e}, ${t})`,X="var(--wmap-font-size, 12px)",Me="var(--wmap-density, 1)",N=e=>`calc(${e}px * ${Me})`;export function wireControlHover(e,t="outlined"){let n=null;const o=()=>{n&&(e.style.background=n.background,e.style.color=n.color)};e.addEventListener("mouseenter",()=>{e.dataset.on==="true"||e.disabled||(n||(n={background:e.style.background,color:e.style.color}),e.style.background=CLR.bgHover,e.style.color=CLR.iconHover)}),e.addEventListener("mouseleave",o),e.addEventListener("blur",o)}export function controlStyle(e,t=!1){const n={fontSize:FONT.body,cursor:"pointer",borderRadius:RADIUS.control};return e==="bare"?{...n,border:"none",background:"none",padding:"0",color:CLR.icon}:{...n,border:`1px solid ${CLR.controlBorder}`,background:e==="toggle"&&t?CLR.menuActive:"none",color:e==="toggle"&&t?CLR.iconActive:CLR.text,padding:`${SPACE.xxs} ${SPACE.lg}`}}export const SPACE={xxs:N(2),xs:N(4),sm:N(6),md:N(8),lg:N(10),xl:N(12),xxl:N(16),xxxl:N(24)},SHADOW={panel:"0 1px 4px rgba(0,0,0,0.10)",menu:"0 4px 12px rgba(0,0,0,0.15)",modal:"0 20px 60px rgba(0,0,0,0.40)"},MOTION={fast:"0.12s ease",base:"0.2s ease"},LEADING={none:"1",tight:"1.2",base:"1.45"},ALPHA={muted:"0.85",disabled:"0.4"},TRACKING="0.05em",EDGE_GUTTER=SPACE.xl,MAP_CHROME_INSET=SPACE.xs,RADIUS={control:"4px",container:"6px",pill:"999px"},FONT={family:"var(--wmap-font-family, inherit)",meta:`calc(${X} - 1px)`,body:X,sub:`calc(${X} + 1px)`,heading:`calc(${X} + 3px)`,stat:`calc(${X} + 8px)`};export function fontPx(e=0,t){const n=t?.ownerDocument??(typeof document<"u"?document:null);if(!n)return 12+e;const o=getComputedStyle(t??n.documentElement).getPropertyValue("--wmap-font-size").trim(),i=o?parseFloat(o):NaN;return(Number.isFinite(i)?i:12)+e}export const CLR={icon:E("icon","#506784"),iconHover:E("icon-hover","#2a3f5f"),iconActive:E("icon-active","#1a65ca"),bgHover:E("bg-hover","#edf0f8"),bgActive:E("bg-active","#dce8f8"),separator:E("separator","rgba(0,0,0,0.12)"),menuBg:E("surface","#fff"),menuBorder:E("border","rgba(0,0,0,0.12)"),controlBorder:E("control-border","rgba(0,0,0,0.30)"),menuHover:E("menu-hover","#f0f4fc"),menuActive:E("menu-active","#dce8f8"),canvasBg:`var(--wmap-canvas-bg, ${E("surface","#f5f5f5")})`,panelBg:E("panel-bg","#fafbfc"),label:E("text-muted","#647687"),value:E("text-strong","#1f2f43"),text:E("text","#333"),warnBg:E("warn-bg","#fffbe6"),warnBorder:E("warn-border","#f0c040"),warnText:E("warn-text","#7a5800"),errBg:E("err-bg","#fef2f2"),errBorder:E("err-border","#dc8a8a"),errText:E("err-text","#7a1c1c"),infoBg:E("info-bg","#dce8f8"),infoText:E("info-text","#334155"),findingHighlight:E("selected","#e07a20"),findingIndicator:E("finding-indicator","#b7551a"),barFill:E("bar-fill","#2a6fc0")};export function sevColor(e){return e==="unusual"?"#a84112":e==="notable"?"#8a6500":CLR.icon}export const ROTATIONS=[0,90,180,270],INLINE_TEST_LIMIT=6,MENU_SEARCH_THRESHOLD=8,DEFAULT_OVERLAY_Z=6e3,Z_BASE=`var(--wmap-z, ${DEFAULT_OVERLAY_Z})`,Z_ABOVE=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 1)`,Z_MENU=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 2)`,Z_ABOVE2=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 3)`;export function applyOverlayZ(e){if(e==null)return()=>{};const t=document.documentElement,n=t.style.getPropertyValue("--wmap-z");return t.style.setProperty("--wmap-z",String(e)),()=>{n?t.style.setProperty("--wmap-z",n):t.style.removeProperty("--wmap-z")}}export function copyWmapThemeTokens(e,t){const n=getComputedStyle(e);for(const o of WMAP_TOKEN_NAMES){const i=n.getPropertyValue(`--wmap-${o}`).trim();i&&t.style.setProperty(`--wmap-${o}`,i)}}export function syncWmapPopupTheme(e,t,n){const o=()=>{copyWmapThemeTokens(e,t),n?.()},i=new window.MutationObserver(o);i.observe(e,{attributes:!0,attributeFilter:["style","class"]}),i.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const a=window.matchMedia("(prefers-color-scheme: dark)");return a.addEventListener("change",o),()=>{i.disconnect(),a.removeEventListener("change",o)}}let oe=null;export function setDetachWindowOpener(e){oe=e}export function openDetachWindow(e){return oe?oe(e):window.open("","_blank","width=560,height=600")}export const MODE_LABELS={value:"Test Value",hardBin:"Hard Bin",softBin:"Soft Bin",stackedValues:"Stacked Test Values",stackedBins:"Stacked Hard Bins",stackedSoftBins:"Stacked Soft Bins",metadata:"Metadata"},BIN_LEGEND_MODES=new Set(["hardBin","softBin","metadata"]),STACKED_MODES=new Set(["stackedValues","stackedBins","stackedSoftBins"]);export function saveImageBlob(e,t,n){const o=`${t}.png`;if(n){n(e,o);return}const i=URL.createObjectURL(e),a=document.createElement("a");a.href=i,a.download=o,a.click(),URL.revokeObjectURL(i)}export function saveTextFile(e,t,n,o){if(o){o(e,t,n);return}const i=new Blob([e],{type:n}),a=URL.createObjectURL(i),u=document.createElement("a");u.href=a,u.download=t,u.click(),URL.revokeObjectURL(a)}const Se='[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';export function nextFrame(e,t=window){const n=t.requestAnimationFrame;typeof n=="function"?n.call(t,e):setTimeout(e,0)}export function wireListNavigation(e,t,n){e.addEventListener("keydown",o=>{const i=t();if(i.length===0)return;const a=e.ownerDocument.activeElement,u=a?i.indexOf(a):-1;switch(o.key){case"ArrowDown":o.preventDefault(),i[u<0||u===i.length-1?0:u+1].focus();break;case"ArrowUp":o.preventDefault(),i[u<=0?i.length-1:u-1].focus();break;case"Home":o.preventDefault(),i[0].focus();break;case"End":o.preventDefault(),i[i.length-1].focus();break;case"Enter":case" ":u>=0&&(o.preventDefault(),i[u].click());break;case"Escape":case"Tab":o.preventDefault(),n();break}})}function Z(e,t,n){const o=()=>Array.from(e.querySelectorAll(Se));wireListNavigation(e,o,()=>{n(),t?.focus()});const i=o()[0];i&&nextFrame(()=>i.focus())}export function overlayRootFor(e){let t=e;for(;t;){if(t.classList.contains("wmap-overlay-box")||t.tagName==="DIALOG"&&t.matches(":modal"))return t;t=t.parentElement}return e.ownerDocument.body}const de=new WeakMap;export function menuLayerFor(e){const t=overlayRootFor(e),n=de.get(t);if(n&&n.isConnected)return n;const i=e.ownerDocument.createElement("div");return i.dataset.wmapMenuLayer="1",Object.assign(i.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),t.appendChild(i),de.set(t,i),i}const ie=new WeakMap;export function getTooltip(e=document){const t=ie.get(e);if(t&&t.isConnected)return t;const n=t??e.createElement("div");return t||(Object.assign(n.style,{position:"fixed",pointerEvents:"none",background:"rgba(30, 32, 40, 0.93)",color:"#f0f0f2",border:"1px solid rgba(255,255,255,0.10)",padding:"7px 11px",borderRadius:RADIUS.control,fontSize:FONT.sub,lineHeight:LEADING.base,maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),ie.set(e,n)),e.body.appendChild(n),n}export function hideTooltip(e=document){const t=ie.get(e);t&&(t.style.display="none")}export function reparentTooltip(e){const t=e?.ownerDocument??document,n=getTooltip(t);(e??t.body).appendChild(n)}export function positionTooltip(e,t,n,o){const i=overlayRootFor(t);e.parentElement!==i&&i.appendChild(e);const a=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const u=e.offsetWidth,r=e.offsetHeight,p=8,m=a.innerWidth,l=a.innerHeight;let v=n+14,s=o-8;v+u+p>m&&(v=n-u-6);const f=t.getBoundingClientRect();if(f.height>0&&f.height<=l*.4&&s<f.bottom&&s+r>f.top&&v<f.right&&v+u>f.left){const c=f.bottom+p,b=f.top-r-p;c+r+p<=l?s=c:b>=p&&(s=b)}s+r+p>l&&(s=l-r-p),s<p&&(s=p),e.style.left=`${v}px`,e.style.top=`${s}px`}export function wireTooltip(e,t,n={}){const o=()=>(typeof t=="function"?t():t)??e.getAttribute("aria-label")??"";n.asDataPoint&&(e.tabIndex=0,e.setAttribute("role","img"),typeof t=="string"&&e.setAttribute("aria-label",t));const i=u=>{const r=o();if(!r)return;const p=getTooltip(e.ownerDocument);if(p.textContent=r,p.style.display="block",u)positionTooltip(p,e,u.clientX,u.clientY);else{const m=e.getBoundingClientRect();positionTooltip(p,e,m.left+m.width/2,m.top)}},a=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",i),e.addEventListener("mouseleave",a),e.addEventListener("focus",()=>i()),e.addEventListener("blur",a)}export function buildDataModeEntries(e,t,n){const o=e.some(ye),i=e.some(l=>l.testValues!==void 0&&Object.keys(l.testValues).length>0),a=e.some(l=>l.hbin!=null),u=e.some(l=>l.sbin!=null),r=o?t!==void 0?t.map(l=>({plotMode:"value",activeTest:l.testNumber,label:l.unit?`${l.name} (${l.unit})`:l.name,logScale:l.logScale})):ge(e).map(l=>({plotMode:"value",activeTest:l,label:`Test ${l}`})):[],p=[...a?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...u?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],m=n.includeStacked?[...i?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...a?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...u?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:r,binEntries:p,stackedEntries:m}}export function metadataKeyHasData(e,t){return e.some(n=>n.metadata?.[t]!==void 0&&n.metadata?.[t]!==null)}export function metadataModeEntry(e){return{plotMode:"metadata",activeMetadataKey:e.key,label:e.label??we(e.key)}}export function makeMenuSearchBox(e,t="Filter\u2026",n=document){const o=n.createElement("input");return o.type="text",o.placeholder=t,o.setAttribute("aria-label",t),Object.assign(o.style,{display:"block",width:"calc(100% - 20px)",margin:"2px 10px 6px",padding:`${SPACE.xs} ${SPACE.md}`,fontSize:FONT.body,boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,outline:"none"}),o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("mousedown",i=>i.stopPropagation()),o.addEventListener("keydown",i=>i.stopPropagation()),o.addEventListener("input",()=>e(o.value.trim().toLowerCase())),o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder}),queueMicrotask(()=>o.focus()),o}export function buildModeMenuEl(e,t,n,o,i,a,u,r,p=window,m=[]){const{makeMenuRow:l,makeMenuSection:v}=u,s=document.createElement("div"),f=180,d=e.left+f<=(p.innerWidth??1/0)?e.left:Math.max(4,e.right-f);if(Object.assign(s.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${d}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${f}px`,padding:"4px 0",pointerEvents:"auto"}),t.length)if(s.appendChild(v("Test Value")),t.length<=INLINE_TEST_LIMIT)for(const c of t)s.appendChild(l(c.label,i(c),!0,b=>{b.stopPropagation(),a(c,s)}));else{const c=r==="value",b=l(MODE_LABELS.value+" \u25B6",c,!1,()=>{});b.style.display="flex",b.style.justifyContent="space-between",b.style.alignItems="center";let g=null,y=null;const C=()=>{y!==null&&(clearTimeout(y),y=null)},w=()=>{C(),g?.remove(),g=null},M=()=>{C(),y=setTimeout(w,300)},T=()=>{if(g)return;const S=b.getBoundingClientRect(),A=160,k=320,U=S.right+2+A<=(p.innerWidth??1/0)?S.right+2:Math.max(4,S.left-2-A),I=Math.min(S.top-4,Math.max(4,(p.innerHeight??1/0)-k-4));if(g=document.createElement("div"),Object.assign(g.style,{position:"fixed",top:`${I}px`,left:`${U}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${A}px`,maxHeight:`${k}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),t.length>MENU_SEARCH_THRESHOLD){const B=makeMenuSearchBox(O=>{for(const L of D)L.row.style.display=L.label.includes(O)?"":"none"},"Filter tests\u2026");Object.assign(B.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),g.appendChild(B)}const D=[];for(const B of t){const O=l(B.label,i(B),!1,L=>{L.stopPropagation(),w(),a(B,s)});D.push({row:O,label:B.label.toLowerCase()}),g.appendChild(O)}g.addEventListener("mouseenter",C),g.addEventListener("mouseleave",M),(s.parentElement??p.document.body).appendChild(g),p.document.addEventListener("click",w,{once:!0})};b.addEventListener("mouseenter",()=>{C(),T()}),b.addEventListener("mouseleave",M),s.appendChild(b)}if(n.length){s.appendChild(v("Bins"));for(const c of n)s.appendChild(l(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,s)}))}if(m.length){s.appendChild(v("Metadata"));for(const c of m)s.appendChild(l(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,s)}))}if(o.length){s.appendChild(v("Lot Aggregation"));for(const c of o)s.appendChild(l(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,s)}))}return s.setAttribute("role","menu"),s.setAttribute("aria-label","Plot mode"),s}export function markMenuTrigger(e,t){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",t?"true":"false")}export function wireMenuA11y(e,t,n){Z(e,t,n)}export function wireExpandToggle(e,t){const n=e.ownerDocument;let o=!1;function i(m){o!==m&&(o=m,t(o))}function a(){i(!1)}function u(){i(!o),o&&n.addEventListener("click",a,{once:!0})}const r=m=>{m.stopPropagation(),u()},p=m=>{m.key==="Enter"||m.key===" "?(m.preventDefault(),u()):m.key==="Escape"&&a()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",r),e.addEventListener("keydown",p),{isOpen:()=>o,close:a,destroy(){e.removeEventListener("click",r),e.removeEventListener("keydown",p),n.removeEventListener("click",a)}}}export function buildCheckMenuEl(e,t,n,o=window){const{makeMenuSection:i}=n,a=o.document,u=a.createElement("div"),r=168,m=e.left+r<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-r);Object.assign(u.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${m}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${r}px`,padding:"4px 0",pointerEvents:"auto"});for(const l of t)if("section"in l)u.appendChild(i(l.section));else{const v=l.enabled!==!1;if(!v&&!l.disabledHint)continue;const s=a.createElement("div");s.setAttribute("role","menuitemcheckbox"),s.setAttribute("aria-checked",l.active?"true":"false"),s.tabIndex=-1,v||(s.setAttribute("aria-disabled","true"),wireTooltip(s,l.disabledHint)),Object.assign(s.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:v?"pointer":"default",color:v?l.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:l.active?"700":"400",background:l.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const f=a.createElement("span");Object.assign(f.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:l.active?"visible":"hidden"}),f.textContent="\u2713",f.setAttribute("aria-hidden","true");const x=a.createElement("span");x.textContent=l.label,s.appendChild(f),s.appendChild(x),v?(s.addEventListener("mouseenter",()=>{l.active||(s.style.background=CLR.menuHover)}),s.addEventListener("mouseleave",()=>{s.style.background=l.active?CLR.menuActive:"transparent"}),s.addEventListener("focus",()=>{l.active||(s.style.background=CLR.menuHover)}),s.addEventListener("blur",()=>{s.style.background=l.active?CLR.menuActive:"transparent"}),s.addEventListener("click",d=>{d.stopPropagation(),l.onClick(d)})):s.addEventListener("click",d=>{d.stopPropagation()}),u.appendChild(s)}return u}export function createToolbarHelpers(e){const t=e.ownerDocument;let n=null;const o=s=>menuLayerFor(s);function i(s,f,x){const d=t.createElement("button");return d.innerHTML=R[s],d.type="button",d.ariaLabel=f,Object.assign(d.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:RADIUS.control,background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:`background ${MOTION.fast}, color ${MOTION.fast}`,flexShrink:"0"}),d.addEventListener("mouseenter",c=>{d.dataset.active||(d.style.background=CLR.bgHover,d.style.color=CLR.iconHover),e.innerHTML=d.ariaLabel??f,e.style.display="block",positionTooltip(e,d,c.clientX,c.clientY)}),d.addEventListener("mousemove",c=>{e.style.display==="block"&&positionTooltip(e,d,c.clientX,c.clientY)}),d.addEventListener("mouseleave",()=>{d.dataset.active||(d.style.background="transparent",d.style.color=CLR.icon),e.style.display="none"}),d.addEventListener("click",()=>{e.style.display="none",x()}),d}function a(s,f){f?(s.dataset.active="1",s.style.background=CLR.bgActive,s.style.color=CLR.iconActive):(delete s.dataset.active,s.style.background="transparent",s.style.color=CLR.icon)}function u(){const s=t.createElement("div");return Object.assign(s.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),s}function r(s,f,x,d){const c=t.createElement("div");return c.textContent=s,c.setAttribute("role","menuitemradio"),c.setAttribute("aria-checked",f?"true":"false"),c.tabIndex=-1,Object.assign(c.style,{padding:`6px 14px 6px ${x?"26px":"14px"}`,fontSize:FONT.body,cursor:"pointer",color:f?CLR.iconActive:CLR.text,fontWeight:f?"700":"400",background:f?CLR.menuActive:"transparent",whiteSpace:"nowrap"}),c.addEventListener("mouseenter",()=>{f||(c.style.background=CLR.menuHover)}),c.addEventListener("mouseleave",()=>{c.style.background=f?CLR.menuActive:"transparent"}),c.addEventListener("focus",()=>{f||(c.style.background=CLR.menuHover)}),c.addEventListener("blur",()=>{c.style.background=f?CLR.menuActive:"transparent"}),c.addEventListener("click",d),c}function p(s){const f=t.createElement("div");return f.textContent=s,f.setAttribute("role","presentation"),Object.assign(f.style,{padding:"5px 14px 2px",fontSize:FONT.body,fontWeight:"600",letterSpacing:TRACKING,color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),f}function m(s,f,x,d,c){const b=()=>{n&&(n.remove(),n=null),g.setAttribute("aria-expanded","false")},g=i(s,f,()=>{if(n){b();return}const y=t.createElement("div"),C=g.getBoundingClientRect(),w=g.ownerDocument.defaultView??window,M=148,S=C.left+M<=(w.innerWidth??1/0)?C.left:Math.max(4,C.right-M);Object.assign(y.style,{position:"fixed",top:`${C.bottom+4}px`,left:`${S}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${M}px`,padding:"4px 0",pointerEvents:"auto"});for(const A of x()){const k=t.createElement("div");k.textContent=A.label,k.dataset.wmapDropdownValue=A.value;const F=A.value===d();k.setAttribute("role","menuitemradio"),k.setAttribute("aria-checked",F?"true":"false"),k.tabIndex=-1,Object.assign(k.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:F?CLR.iconActive:CLR.text,fontWeight:F?"700":"400",background:F?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const U=()=>{A.value!==d()&&(k.style.background=CLR.menuHover)},I=()=>{k.style.background=A.value===d()?CLR.menuActive:"transparent"};k.addEventListener("mouseenter",U),k.addEventListener("mouseleave",I),k.addEventListener("focus",U),k.addEventListener("blur",I),k.addEventListener("click",D=>{D.stopPropagation(),c(A.value),b()}),y.appendChild(k)}y.setAttribute("role","menu"),y.setAttribute("aria-label",f),o(g).appendChild(y),n=y,g.setAttribute("aria-expanded","true"),Z(y,g,b)});return g.setAttribute("aria-haspopup","menu"),g.setAttribute("aria-expanded","false"),g}function l(s,f,x,d){function c(){return buildCheckMenuEl(g.getBoundingClientRect(),x().map(y=>"section"in y?y:{...y,onClick:C=>{y.onClick(C),d(g);const w=n;if(!w)return;const M=c();M.setAttribute("role","menu"),M.setAttribute("aria-label",f),w.replaceWith(M),n=M,Z(M,g,b)}}),{makeMenuSection:p},g.ownerDocument.defaultView??window)}const b=()=>{n&&(n.remove(),n=null),g.setAttribute("aria-expanded","false")},g=i(s,f,()=>{if(n){b();return}const y=c();y.setAttribute("role","menu"),y.setAttribute("aria-label",f),o(g).appendChild(y),n=y,g.setAttribute("aria-expanded","true"),Z(y,g,b)});return g.setAttribute("aria-haspopup","menu"),g.setAttribute("aria-expanded","false"),d(g),g}function v(s){if(n&&!n.contains(s.target)&&(n.remove(),n=null,s.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const x of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))x.setAttribute("aria-expanded","false")}return{makeBtn:i,setActive:a,makeSep:u,makeMenuRow:r,makeMenuSection:p,makeDropdown:m,makeCheckMenuBtn:l,closeOpenMenu:v,getOpenMenu:()=>n,setOpenMenu:s=>{n=s}}}const Be=7e3;let Te=0;function ue(){return Be+ ++Te}const De=32,Oe=6;let He=0;function Ie(){return He++%Oe*De}function $e(e,t){if(t===e.body)return()=>{};let n=t;for(;n.parentElement&&n.parentElement!==e.body;)n=n.parentElement;return n===e.body?()=>{}:(n.classList.add("wmap-overlay-ancestor"),()=>n.classList.remove("wmap-overlay-ancestor"))}function pe(e){const t=e.mode==="modal",n=e.ownerDocument??document,o=n.defaultView??window,i=n.body.style.overflow;t&&(n.body.style.overflow="hidden");let a=null;t&&(a=n.createElement("div"),a.id="wmap-modal-backdrop",Object.assign(a.style,{position:"fixed",inset:"0",background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:Z_ABOVE,backdropFilter:"blur(3px)"}));const u=n.activeElement,r=n.createElement("div");r.className=t?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",r.setAttribute("role","dialog"),t&&r.setAttribute("aria-modal","true"),r.setAttribute("aria-label",e.title??"Expanded wafer map"),r.tabIndex=-1;const p=e.boxSize?.width??"min(90vw, 700px)",m=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(r.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:p,height:m,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:t?Z_ABOVE2:String(ue())}),!t){const h=Ie();Object.assign(r.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+h}px`,left:`${Math.round(o.innerWidth*.08)+h}px`})}const l=n.createElement("div");Object.assign(l.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const v={border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:LEADING.none,padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const h=n.createElement("span");h.textContent=e.title,h.title=e.title,h.dataset.wmapWindowTitle="1",Object.assign(h.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),l.appendChild(h)}const s=n.createElement("div");s.style.flex="1",l.appendChild(s);let f=null;t||(f=n.createElement("button"),f.type="button",f.innerHTML=R.windowMinimize,f.setAttribute("aria-label","Minimize"),wireTooltip(f),Object.assign(f.style,v),wireControlHover(f),f.addEventListener("click",()=>A(!w)),l.appendChild(f));let x=null;e.printable&&(x=n.createElement("button"),x.type="button",x.innerHTML=R.print,x.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(x),Object.assign(x.style,v),wireControlHover(x),x.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),l.appendChild(x));const d=n.createElement("button");d.type="button",d.innerHTML=R.maximize,d.setAttribute("aria-label","Maximize (F)"),wireTooltip(d),Object.assign(d.style,v),wireControlHover(d),d.addEventListener("click",()=>C(!b));const c=n.createElement("button");c.type="button",c.innerHTML=R.close,c.setAttribute("aria-label","Close (Esc)"),wireTooltip(c),Object.assign(c.style,v),wireControlHover(c),c.addEventListener("click",D),l.appendChild(d),l.appendChild(c);let b=!1,g="",y="";function C(h){b=h,d.innerHTML=b?R.minimize:R.maximize,d.setAttribute("aria-label",b?"Restore (F)":"Maximize (F)"),L.style.display=b?"none":"block",b?(r.style.borderRadius="0",r.style.width="100vw",r.style.height="100vh",t||(g=r.style.top,y=r.style.left,r.style.top="0",r.style.left="0")):(r.style.borderRadius="12px",r.style.width=p,r.style.height=m,t||(r.style.top=g,r.style.left=y)),e.onMaximizeChange?.(b,r)}let w=!1,M="",T="";const S=220;function A(h){w=h,f.innerHTML=w?R.windowRestore:R.windowMinimize,f.setAttribute("aria-label",w?"Restore":"Minimize"),L.style.display=w?"none":"block",w?(M=r.style.height,T=r.style.width,r.style.minHeight="0",r.style.height="auto",r.style.minWidth="0",r.style.width=`${S}px`,d.disabled=!0,d.style.opacity="0.4",d.style.cursor="default",O.style.display="none"):(r.style.minHeight="240px",r.style.height=M||m,r.style.minWidth="320px",r.style.width=T||p,d.disabled=!1,d.style.opacity="1",d.style.cursor="pointer",O.style.display="flex")}function k(){const h=n.body.style.userSelect;return n.body.style.userSelect="none",()=>{n.body.style.userSelect=h}}t||(l.style.cursor="move",l.addEventListener("pointerdown",h=>{if(b||h.target.closest('button, [role="button"]'))return;h.preventDefault();const H=k(),W=h.clientX,z=h.clientY,$=r.offsetTop,_=r.offsetLeft,ee=o.innerHeight-l.offsetHeight,te=o.innerWidth-40,K=40-r.offsetWidth;l.setPointerCapture(h.pointerId);const G=V=>{const ne=Math.min(Math.max($+(V.clientY-z),0),ee),ve=Math.min(Math.max(_+(V.clientX-W),K),te);r.style.top=`${ne}px`,r.style.left=`${ve}px`},j=V=>{H(),l.releasePointerCapture(V.pointerId),l.removeEventListener("pointermove",G),l.removeEventListener("pointerup",j)};l.addEventListener("pointermove",G),l.addEventListener("pointerup",j)}));const F='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function U(h){const H=Array.from(r.querySelectorAll(F)).filter(_=>_.offsetParent!==null||_===n.activeElement);if(H.length===0){h.preventDefault(),r.focus();return}const W=H[0],z=H[H.length-1],$=n.activeElement;h.shiftKey&&($===W||!r.contains($))?(h.preventDefault(),z.focus()):!h.shiftKey&&$===z&&(h.preventDefault(),W.focus())}const I=h=>{if(h.key==="Escape"){D();return}if(t&&(h.key==="e"||h.key==="E")){D();return}if(t&&h.key==="Tab"){U(h);return}(h.key==="f"||h.key==="F")&&!w&&C(!b)};function D(){t?n.removeEventListener("keydown",I):r.removeEventListener("keydown",I),J.remove(),xe(),hideTooltip(n),reparentTooltip(n.body),a?a.remove():r.remove(),t&&(n.body.style.overflow=i),u?.focus?.(),e.onClose()}function B(){t||(r.style.zIndex=String(ue()))}const O=n.createElement("div");Object.assign(O.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const L=n.createElement("div");L.tabIndex=0,L.setAttribute("role","separator"),L.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(L.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),L.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16" style="display:block"><path d="M15 15 L15 9 M15 15 L9 15 M15 15 L15 3 M15 15 L3 15" stroke="currentColor" stroke-width="1" opacity="0.35" fill="none"/></svg>',L.style.color=CLR.label;const ae=320,se=240,Y=20;function q(h,H){const W=o.innerWidth-r.offsetLeft,z=o.innerHeight-r.offsetTop,$=Math.min(Math.max(r.offsetWidth+h,ae),W),_=Math.min(Math.max(r.offsetHeight+H,se),z);r.style.width=`${$}px`,r.style.height=`${_}px`}L.addEventListener("keydown",h=>{if(!(b||w))switch(h.key){case"ArrowRight":h.preventDefault(),q(Y,0);break;case"ArrowLeft":h.preventDefault(),q(-Y,0);break;case"ArrowDown":h.preventDefault(),q(0,Y);break;case"ArrowUp":h.preventDefault(),q(0,-Y);break}}),L.addEventListener("pointerdown",h=>{if(b||w)return;h.preventDefault();const H=k(),W=h.clientX,z=h.clientY,$=r.offsetWidth,_=r.offsetHeight,ee=o.innerWidth-r.offsetLeft,te=o.innerHeight-r.offsetTop;L.setPointerCapture(h.pointerId);const K=j=>{const V=Math.min(Math.max($+(j.clientX-W),ae),ee),ne=Math.min(Math.max(_+(j.clientY-z),se),te);r.style.width=`${V}px`,r.style.height=`${ne}px`},G=j=>{H(),L.releasePointerCapture(j.pointerId),L.removeEventListener("pointermove",K),L.removeEventListener("pointerup",G)};L.addEventListener("pointermove",K),L.addEventListener("pointerup",G)}),r.appendChild(l),r.appendChild(O),r.appendChild(L);const Q=e.anchor?overlayRootFor(e.anchor):n.body;a?(a.appendChild(r),Q.appendChild(a)):Q.appendChild(r);const xe=$e(n,Q),J=n.createElement("style");return J.textContent=`@media print{
|
|
1
|
+
import{getUniqueTestNumbers as ve}from"../renderer/buildView.js";import{dieHasTestData as ge}from"../renderer/buildWaferMap.js";import{prettyKey as ye}from"../core/utils.js";import{listBinColorSchemes as we,listValueColorSchemes as ke}from"../renderer/colorSchemes.js";import{ICONS as $}from"./icons.js";import{WMAP_VERSION as Ee,WMAP_BUILD_TIME as Ce}from"./version.js";import{openHtmlReport as Le}from"../stats/renderFindingsReport.js";import{buildWaferMap as Ae}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Me}from"../stats/analyzeWaferMap.js";let le=!1;export function logWmapVersionOnce(){le||(le=!0,console.log(`[wmap] v${Ee} (built ${Ce})`))}export const WMAP_TOKEN_NAMES=["z","icon","icon-hover","icon-active","bg-hover","bg-active","separator","surface","border","control-border","menu-hover","menu-active","font-family","font-size","density","panel-bg","text-muted","text","text-strong","warn-bg","warn-border","warn-text","err-bg","err-border","err-text","info-bg","info-text","selected","finding-indicator","canvas-bg","bar-fill"];const k=(e,n)=>`var(--wmap-${e}, ${n})`,X="var(--wmap-font-size, 12px)",Se="var(--wmap-density, 1)",N=e=>`calc(${e}px * ${Se})`;export function wireControlHover(e,n="outlined"){let t=null;const o=()=>{t&&(e.style.background=t.background,e.style.color=t.color)};e.addEventListener("mouseenter",()=>{e.dataset.on==="true"||e.disabled||(t||(t={background:e.style.background,color:e.style.color}),e.style.background=CLR.bgHover,e.style.color=CLR.iconHover)}),e.addEventListener("mouseleave",o),e.addEventListener("blur",o)}export function controlStyle(e,n=!1){const t={fontSize:FONT.body,cursor:"pointer",borderRadius:RADIUS.control};return e==="bare"?{...t,border:"none",background:"none",padding:"0",color:CLR.icon}:{...t,border:`1px solid ${CLR.controlBorder}`,background:e==="toggle"&&n?CLR.menuActive:"none",color:e==="toggle"&&n?CLR.iconActive:CLR.text,padding:`${SPACE.xxs} ${SPACE.lg}`}}export const SPACE={xxs:N(2),xs:N(4),sm:N(6),md:N(8),lg:N(10),xl:N(12),xxl:N(16),xxxl:N(24)},SHADOW={panel:"0 1px 4px rgba(0,0,0,0.10)",menu:"0 4px 12px rgba(0,0,0,0.15)",modal:"0 20px 60px rgba(0,0,0,0.40)"},MOTION={fast:"0.12s ease",base:"0.2s ease"},LEADING={none:"1",tight:"1.2",base:"1.45"},ALPHA={muted:"0.85",disabled:"0.4"},TRACKING="0.05em",EDGE_GUTTER=SPACE.xl,MAP_CHROME_INSET=SPACE.xs,RADIUS={control:"4px",container:"6px",pill:"999px"},FONT={family:"var(--wmap-font-family, inherit)",meta:`calc(${X} - 1px)`,body:X,sub:`calc(${X} + 1px)`,heading:`calc(${X} + 3px)`,stat:`calc(${X} + 8px)`};export function fontPx(e=0,n){const t=n?.ownerDocument??(typeof document<"u"?document:null);if(!t)return 12+e;const o=getComputedStyle(n??t.documentElement).getPropertyValue("--wmap-font-size").trim(),i=o?parseFloat(o):NaN;return(Number.isFinite(i)?i:12)+e}export const CLR={icon:k("icon","#506784"),iconHover:k("icon-hover","#2a3f5f"),iconActive:k("icon-active","#1a65ca"),bgHover:k("bg-hover","#edf0f8"),bgActive:k("bg-active","#dce8f8"),separator:k("separator","rgba(0,0,0,0.12)"),menuBg:k("surface","#fff"),menuBorder:k("border","rgba(0,0,0,0.12)"),controlBorder:k("control-border","rgba(0,0,0,0.30)"),menuHover:k("menu-hover","#f0f4fc"),menuActive:k("menu-active","#dce8f8"),canvasBg:`var(--wmap-canvas-bg, ${k("surface","#f5f5f5")})`,panelBg:k("panel-bg","#fafbfc"),label:k("text-muted","#647687"),value:k("text-strong","#1f2f43"),text:k("text","#333"),warnBg:k("warn-bg","#fffbe6"),warnBorder:k("warn-border","#f0c040"),warnText:k("warn-text","#7a5800"),errBg:k("err-bg","#fef2f2"),errBorder:k("err-border","#dc8a8a"),errText:k("err-text","#7a1c1c"),infoBg:k("info-bg","#dce8f8"),infoText:k("info-text","#334155"),findingHighlight:k("selected","#e07a20"),findingIndicator:k("finding-indicator","#b7551a"),barFill:k("bar-fill","#2a6fc0")};export function sevColor(e){return e==="unusual"?"#a84112":e==="notable"?"#8a6500":CLR.icon}export const ROTATIONS=[0,90,180,270],INLINE_TEST_LIMIT=6,MENU_SEARCH_THRESHOLD=8,DEFAULT_OVERLAY_Z=6e3,Z_BASE=`var(--wmap-z, ${DEFAULT_OVERLAY_Z})`,Z_ABOVE=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 1)`,Z_MENU=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 2)`,Z_ABOVE2=`calc(var(--wmap-z, ${DEFAULT_OVERLAY_Z}) + 3)`;export function applyOverlayZ(e){if(e==null)return()=>{};const n=document.documentElement,t=n.style.getPropertyValue("--wmap-z");return n.style.setProperty("--wmap-z",String(e)),()=>{t?n.style.setProperty("--wmap-z",t):n.style.removeProperty("--wmap-z")}}export function copyWmapThemeTokens(e,n){const t=getComputedStyle(e);for(const o of WMAP_TOKEN_NAMES){const i=t.getPropertyValue(`--wmap-${o}`).trim();i&&n.style.setProperty(`--wmap-${o}`,i)}}export function syncWmapPopupTheme(e,n,t){const o=()=>{copyWmapThemeTokens(e,n),t?.()},i=new window.MutationObserver(o);i.observe(e,{attributes:!0,attributeFilter:["style","class"]}),i.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const a=window.matchMedia("(prefers-color-scheme: dark)");return a.addEventListener("change",o),()=>{i.disconnect(),a.removeEventListener("change",o)}}let oe=null;export function setDetachWindowOpener(e){oe=e}export function openDetachWindow(e){return oe?oe(e):window.open("","_blank","width=560,height=600")}export const MODE_LABELS={value:"Test Value",hardBin:"Hard Bin",softBin:"Soft Bin",stackedValues:"Stacked Test Values",stackedBins:"Stacked Hard Bins",stackedSoftBins:"Stacked Soft Bins",metadata:"Metadata"},BIN_LEGEND_MODES=new Set(["hardBin","softBin","metadata"]),STACKED_MODES=new Set(["stackedValues","stackedBins","stackedSoftBins"]);export function saveImageBlob(e,n,t){const o=`${n}.png`;if(t){t(e,o);return}const i=URL.createObjectURL(e),a=document.createElement("a");a.href=i,a.download=o,a.click(),URL.revokeObjectURL(i)}export function saveTextFile(e,n,t,o){if(o){o(e,n,t);return}const i=new Blob([e],{type:t}),a=URL.createObjectURL(i),d=document.createElement("a");d.href=a,d.download=n,d.click(),URL.revokeObjectURL(a)}const Be='[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';export function nextFrame(e,n=window){const t=n.requestAnimationFrame;typeof t=="function"?t.call(n,e):setTimeout(e,0)}export function wireListNavigation(e,n,t){e.addEventListener("keydown",o=>{const i=n();if(i.length===0)return;const a=e.ownerDocument.activeElement,d=a?i.indexOf(a):-1;switch(o.key){case"ArrowDown":o.preventDefault(),i[d<0||d===i.length-1?0:d+1].focus();break;case"ArrowUp":o.preventDefault(),i[d<=0?i.length-1:d-1].focus();break;case"Home":o.preventDefault(),i[0].focus();break;case"End":o.preventDefault(),i[i.length-1].focus();break;case"Enter":case" ":d>=0&&(o.preventDefault(),i[d].click());break;case"Escape":case"Tab":o.preventDefault(),t();break}})}function Z(e,n,t){const o=()=>Array.from(e.querySelectorAll(Be));wireListNavigation(e,o,()=>{t(),n?.focus()});const i=o()[0];i&&nextFrame(()=>i.focus())}export function overlayRootFor(e){let n=e;for(;n;){if(n.classList.contains("wmap-overlay-box")||n.tagName==="DIALOG"&&n.matches(":modal"))return n;n=n.parentElement}return e.ownerDocument.body}const ce=new WeakMap;export function menuLayerFor(e){const n=overlayRootFor(e),t=ce.get(n);if(t&&t.isConnected)return t;const i=e.ownerDocument.createElement("div");return i.dataset.wmapMenuLayer="1",Object.assign(i.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),n.appendChild(i),ce.set(n,i),i}const ie=new WeakMap;export function getTooltip(e=document){const n=ie.get(e);if(n&&n.isConnected)return n;const t=n??e.createElement("div");return n||(Object.assign(t.style,{position:"fixed",pointerEvents:"none",background:"rgba(30, 32, 40, 0.93)",color:"#f0f0f2",border:"1px solid rgba(255,255,255,0.10)",padding:"7px 11px",borderRadius:RADIUS.control,fontSize:FONT.sub,lineHeight:LEADING.base,maxWidth:"280px",maxHeight:"min(60vh, 480px)",overflow:"hidden",whiteSpace:"pre-wrap",zIndex:Z_ABOVE,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),ie.set(e,t)),e.body.appendChild(t),t}export function hideTooltip(e=document){const n=ie.get(e);n&&(n.style.display="none")}export function reparentTooltip(e){const n=e?.ownerDocument??document,t=getTooltip(n);(e??n.body).appendChild(t)}export function positionTooltip(e,n,t,o){const i=overlayRootFor(n);e.parentElement!==i&&i.appendChild(e);const a=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const d=e.offsetWidth,r=e.offsetHeight,p=8,m=a.innerWidth,s=a.innerHeight;let g=t+14,l=o-8;g+d+p>m&&(g=t-d-6);const f=n.getBoundingClientRect();if(f.height>0&&f.height<=s*.4&&l<f.bottom&&l+r>f.top&&g<f.right&&g+d>f.left){const c=f.bottom+p,b=f.top-r-p;c+r+p<=s?l=c:b>=p&&(l=b)}l+r+p>s&&(l=s-r-p),l<p&&(l=p),e.style.left=`${g}px`,e.style.top=`${l}px`}export function wireTooltip(e,n,t={}){const o=()=>(typeof n=="function"?n():n)??e.getAttribute("aria-label")??"";t.asDataPoint&&(e.tabIndex=0,e.setAttribute("role","img"),typeof n=="string"&&e.setAttribute("aria-label",n));const i=d=>{const r=o();if(!r)return;const p=getTooltip(e.ownerDocument);if(p.textContent=r,p.style.display="block",d)positionTooltip(p,e,d.clientX,d.clientY);else{const m=e.getBoundingClientRect();positionTooltip(p,e,m.left+m.width/2,m.top)}},a=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",i),e.addEventListener("mouseleave",a),e.addEventListener("focus",()=>i()),e.addEventListener("blur",a)}export function buildDataModeEntries(e,n,t){const o=e.some(ge),i=e.some(s=>s.testValues!==void 0&&Object.keys(s.testValues).length>0),a=e.some(s=>s.hbin!=null),d=e.some(s=>s.sbin!=null),r=o?n!==void 0?n.map(s=>({plotMode:"value",activeTest:s.testNumber,label:s.unit?`${s.name} (${s.unit})`:s.name,logScale:s.logScale})):ve(e).map(s=>({plotMode:"value",activeTest:s,label:`Test ${s}`})):[],p=[...a?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...d?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],m=t.includeStacked?[...i?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...a?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...d?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:r,binEntries:p,stackedEntries:m}}export function metadataKeyHasData(e,n){return e.some(t=>t.metadata?.[n]!==void 0&&t.metadata?.[n]!==null)}export function metadataModeEntry(e){return{plotMode:"metadata",activeMetadataKey:e.key,label:e.label??ye(e.key)}}export function makeMenuSearchBox(e,n="Filter\u2026",t=document){const o=t.createElement("input");return o.type="text",o.placeholder=n,o.setAttribute("aria-label",n),Object.assign(o.style,{display:"block",width:"calc(100% - 20px)",margin:"2px 10px 6px",padding:`${SPACE.xs} ${SPACE.md}`,fontSize:FONT.body,boxSizing:"border-box",background:CLR.menuBg,color:CLR.text,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,outline:"none"}),o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("mousedown",i=>i.stopPropagation()),o.addEventListener("keydown",i=>i.stopPropagation()),o.addEventListener("input",()=>e(o.value.trim().toLowerCase())),o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder}),queueMicrotask(()=>o.focus()),o}export function buildModeMenuEl(e,n,t,o,i,a,d,r,p=window,m=[]){const{makeMenuRow:s,makeMenuSection:g}=d,l=document.createElement("div"),f=180,u=e.left+f<=(p.innerWidth??1/0)?e.left:Math.max(4,e.right-f);if(Object.assign(l.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${u}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${f}px`,padding:"4px 0",pointerEvents:"auto"}),n.length)if(l.appendChild(g("Test Value")),n.length<=INLINE_TEST_LIMIT)for(const c of n)l.appendChild(s(c.label,i(c),!0,b=>{b.stopPropagation(),a(c,l)}));else{const c=r==="value",b=s(MODE_LABELS.value+" \u25B6",c,!1,()=>{});b.style.display="flex",b.style.justifyContent="space-between",b.style.alignItems="center";let v=null,y=null;const L=()=>{y!==null&&(clearTimeout(y),y=null)},w=()=>{L(),v?.remove(),v=null},M=()=>{L(),y=setTimeout(w,300)},T=()=>{if(v)return;const S=b.getBoundingClientRect(),A=160,E=320,V=S.right+2+A<=(p.innerWidth??1/0)?S.right+2:Math.max(4,S.left-2-A),O=Math.min(S.top-4,Math.max(4,(p.innerHeight??1/0)-E-4));if(v=document.createElement("div"),Object.assign(v.style,{position:"fixed",top:`${O}px`,left:`${V}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${A}px`,maxHeight:`${E}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),n.length>MENU_SEARCH_THRESHOLD){const B=makeMenuSearchBox(H=>{for(const C of D)C.row.style.display=C.label.includes(H)?"":"none"},"Filter tests\u2026");Object.assign(B.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),v.appendChild(B)}const D=[];for(const B of n){const H=s(B.label,i(B),!1,C=>{C.stopPropagation(),w(),a(B,l)});D.push({row:H,label:B.label.toLowerCase()}),v.appendChild(H)}v.addEventListener("mouseenter",L),v.addEventListener("mouseleave",M),(l.parentElement??p.document.body).appendChild(v),p.document.addEventListener("click",w,{once:!0})};b.addEventListener("mouseenter",()=>{L(),T()}),b.addEventListener("mouseleave",M),l.appendChild(b)}if(t.length){l.appendChild(g("Bins"));for(const c of t)l.appendChild(s(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,l)}))}if(m.length){l.appendChild(g("Metadata"));for(const c of m)l.appendChild(s(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,l)}))}if(o.length){l.appendChild(g("Lot Aggregation"));for(const c of o)l.appendChild(s(c.label,i(c),!1,b=>{b.stopPropagation(),a(c,l)}))}return l.setAttribute("role","menu"),l.setAttribute("aria-label","Plot mode"),l}export function markMenuTrigger(e,n){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",n?"true":"false")}export function wireMenuA11y(e,n,t){Z(e,n,t)}export function wireExpandToggle(e,n){const t=e.ownerDocument;let o=!1;function i(m){o!==m&&(o=m,n(o))}function a(){i(!1)}function d(){i(!o),o&&t.addEventListener("click",a,{once:!0})}const r=m=>{m.stopPropagation(),d()},p=m=>{m.key==="Enter"||m.key===" "?(m.preventDefault(),d()):m.key==="Escape"&&a()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",r),e.addEventListener("keydown",p),{isOpen:()=>o,close:a,destroy(){e.removeEventListener("click",r),e.removeEventListener("keydown",p),t.removeEventListener("click",a)}}}export function buildCheckMenuEl(e,n,t,o=window){const{makeMenuSection:i}=t,a=o.document,d=a.createElement("div"),r=168,m=e.left+r<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-r);Object.assign(d.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${m}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${r}px`,padding:"4px 0",pointerEvents:"auto"});for(const s of n)if("section"in s)d.appendChild(i(s.section));else{const g=s.enabled!==!1;if(!g&&!s.disabledHint)continue;const l=a.createElement("div");s.action?l.setAttribute("role","menuitem"):(l.setAttribute("role","menuitemcheckbox"),l.setAttribute("aria-checked",s.active?"true":"false")),l.tabIndex=-1,g||(l.setAttribute("aria-disabled","true"),wireTooltip(l,s.disabledHint)),Object.assign(l.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:g?"pointer":"default",color:g?s.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:s.active?"700":"400",background:s.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const f=a.createElement("span");Object.assign(f.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:s.active?"visible":"hidden"}),f.textContent=s.action?"":"\u2713",f.setAttribute("aria-hidden","true");const x=a.createElement("span");x.textContent=s.label,l.appendChild(f),l.appendChild(x),g?(l.addEventListener("mouseenter",()=>{s.active||(l.style.background=CLR.menuHover)}),l.addEventListener("mouseleave",()=>{l.style.background=s.active?CLR.menuActive:"transparent"}),l.addEventListener("focus",()=>{s.active||(l.style.background=CLR.menuHover)}),l.addEventListener("blur",()=>{l.style.background=s.active?CLR.menuActive:"transparent"}),l.addEventListener("click",u=>{u.stopPropagation(),s.onClick(u)})):l.addEventListener("click",u=>{u.stopPropagation()}),d.appendChild(l)}return d}export function createToolbarHelpers(e){const n=e.ownerDocument;let t=null;const o=l=>menuLayerFor(l);function i(l,f,x){const u=n.createElement("button");return u.innerHTML=$[l],u.type="button",u.ariaLabel=f,Object.assign(u.style,{display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px",padding:"0",border:"none",borderRadius:RADIUS.control,background:"transparent",color:CLR.icon,cursor:"pointer",pointerEvents:"auto",transition:`background ${MOTION.fast}, color ${MOTION.fast}`,flexShrink:"0"}),u.addEventListener("mouseenter",c=>{u.dataset.active||(u.style.background=CLR.bgHover,u.style.color=CLR.iconHover),e.innerHTML=u.ariaLabel??f,e.style.display="block",positionTooltip(e,u,c.clientX,c.clientY)}),u.addEventListener("mousemove",c=>{e.style.display==="block"&&positionTooltip(e,u,c.clientX,c.clientY)}),u.addEventListener("mouseleave",()=>{u.dataset.active||(u.style.background="transparent",u.style.color=CLR.icon),e.style.display="none"}),u.addEventListener("click",()=>{e.style.display="none",x()}),u}function a(l,f){f?(l.dataset.active="1",l.style.background=CLR.bgActive,l.style.color=CLR.iconActive):(delete l.dataset.active,l.style.background="transparent",l.style.color=CLR.icon)}function d(){const l=n.createElement("div");return Object.assign(l.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),l}function r(l,f,x,u){const c=n.createElement("div");return c.textContent=l,c.setAttribute("role","menuitemradio"),c.setAttribute("aria-checked",f?"true":"false"),c.tabIndex=-1,Object.assign(c.style,{padding:`6px 14px 6px ${x?"26px":"14px"}`,fontSize:FONT.body,cursor:"pointer",color:f?CLR.iconActive:CLR.text,fontWeight:f?"700":"400",background:f?CLR.menuActive:"transparent",whiteSpace:"nowrap"}),c.addEventListener("mouseenter",()=>{f||(c.style.background=CLR.menuHover)}),c.addEventListener("mouseleave",()=>{c.style.background=f?CLR.menuActive:"transparent"}),c.addEventListener("focus",()=>{f||(c.style.background=CLR.menuHover)}),c.addEventListener("blur",()=>{c.style.background=f?CLR.menuActive:"transparent"}),c.addEventListener("click",u),c}function p(l){const f=n.createElement("div");return f.textContent=l,f.setAttribute("role","presentation"),Object.assign(f.style,{padding:"5px 14px 2px",fontSize:FONT.body,fontWeight:"600",letterSpacing:TRACKING,color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),f}function m(l,f,x,u,c){const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=i(l,f,()=>{if(t){b();return}const y=n.createElement("div"),L=v.getBoundingClientRect(),w=v.ownerDocument.defaultView??window,M=148,S=L.left+M<=(w.innerWidth??1/0)?L.left:Math.max(4,L.right-M);Object.assign(y.style,{position:"fixed",top:`${L.bottom+4}px`,left:`${S}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${M}px`,padding:"4px 0",pointerEvents:"auto"});for(const A of x()){const E=n.createElement("div");E.textContent=A.label,E.dataset.wmapDropdownValue=A.value;const F=A.value===u();E.setAttribute("role","menuitemradio"),E.setAttribute("aria-checked",F?"true":"false"),E.tabIndex=-1,Object.assign(E.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:F?CLR.iconActive:CLR.text,fontWeight:F?"700":"400",background:F?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const V=()=>{A.value!==u()&&(E.style.background=CLR.menuHover)},O=()=>{E.style.background=A.value===u()?CLR.menuActive:"transparent"};E.addEventListener("mouseenter",V),E.addEventListener("mouseleave",O),E.addEventListener("focus",V),E.addEventListener("blur",O),E.addEventListener("click",D=>{D.stopPropagation(),c(A.value),b()}),y.appendChild(E)}y.setAttribute("role","menu"),y.setAttribute("aria-label",f),o(v).appendChild(y),t=y,v.setAttribute("aria-expanded","true"),Z(y,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),v}function s(l,f,x,u){function c(){return buildCheckMenuEl(v.getBoundingClientRect(),x().map(y=>"section"in y?y:{...y,onClick:L=>{y.onClick(L),u(v);const w=t;if(!w)return;const M=c();M.setAttribute("role","menu"),M.setAttribute("aria-label",f),w.replaceWith(M),t=M,Z(M,v,b)}}),{makeMenuSection:p},v.ownerDocument.defaultView??window)}const b=()=>{t&&(t.remove(),t=null),v.setAttribute("aria-expanded","false")},v=i(l,f,()=>{if(t){b();return}const y=c();y.setAttribute("role","menu"),y.setAttribute("aria-label",f),o(v).appendChild(y),t=y,v.setAttribute("aria-expanded","true"),Z(y,v,b)});return v.setAttribute("aria-haspopup","menu"),v.setAttribute("aria-expanded","false"),u(v),v}function g(l){if(t&&!t.contains(l.target)&&(t.remove(),t=null,l.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const x of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))x.setAttribute("aria-expanded","false")}return{makeBtn:i,setActive:a,makeSep:d,makeMenuRow:r,makeMenuSection:p,makeDropdown:m,makeCheckMenuBtn:s,closeOpenMenu:g,getOpenMenu:()=>t,setOpenMenu:l=>{t=l}}}const Te=7e3;let De=0;function de(){return Te+ ++De}const He=32,Ie=6;let Oe=0;function Re(){return Oe++%Ie*He}function $e(e,n){if(n===e.body)return()=>{};let t=n;for(;t.parentElement&&t.parentElement!==e.body;)t=t.parentElement;return t===e.body?()=>{}:(t.classList.add("wmap-overlay-ancestor"),()=>t.classList.remove("wmap-overlay-ancestor"))}function ue(e){const n=e.mode==="modal",t=e.ownerDocument??document,o=t.defaultView??window,i=t.body.style.overflow;n&&(t.body.style.overflow="hidden");let a=null;n&&(a=t.createElement("div"),a.id="wmap-modal-backdrop",Object.assign(a.style,{position:"fixed",inset:"0",background:"rgba(0,0,0,0.6)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:Z_ABOVE,backdropFilter:"blur(3px)"}));const d=t.activeElement,r=t.createElement("div");r.className=n?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",r.setAttribute("role","dialog"),n&&r.setAttribute("aria-modal","true"),r.setAttribute("aria-label",e.title??"Expanded wafer map"),r.tabIndex=-1;const p=e.boxSize?.width??"min(90vw, 700px)",m=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(r.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:p,height:m,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:n?Z_ABOVE2:String(de())}),!n){const h=Re();Object.assign(r.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+h}px`,left:`${Math.round(o.innerWidth*.08)+h}px`})}const s=t.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const g={border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,background:CLR.panelBg,cursor:"pointer",color:CLR.label,lineHeight:LEADING.none,padding:"0",display:"flex",alignItems:"center",justifyContent:"center",width:"28px",height:"28px"};if(e.title){const h=t.createElement("span");h.textContent=e.title,h.title=e.title,h.dataset.wmapWindowTitle="1",Object.assign(h.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),s.appendChild(h)}const l=t.createElement("div");l.style.flex="1",s.appendChild(l);let f=null;n||(f=t.createElement("button"),f.type="button",f.innerHTML=$.windowMinimize,f.setAttribute("aria-label","Minimize"),wireTooltip(f),Object.assign(f.style,g),wireControlHover(f),f.addEventListener("click",()=>A(!w)),s.appendChild(f));let x=null;e.printable&&(x=t.createElement("button"),x.type="button",x.innerHTML=$.print,x.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(x),Object.assign(x.style,g),wireControlHover(x),x.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),s.appendChild(x));const u=t.createElement("button");u.type="button",u.innerHTML=$.maximize,u.setAttribute("aria-label","Maximize (F)"),wireTooltip(u),Object.assign(u.style,g),wireControlHover(u),u.addEventListener("click",()=>L(!b));const c=t.createElement("button");c.type="button",c.innerHTML=$.close,c.setAttribute("aria-label","Close (Esc)"),wireTooltip(c),Object.assign(c.style,g),wireControlHover(c),c.addEventListener("click",D),s.appendChild(u),s.appendChild(c);let b=!1,v="",y="";function L(h){b=h,u.innerHTML=b?$.minimize:$.maximize,u.setAttribute("aria-label",b?"Restore (F)":"Maximize (F)"),C.style.display=b?"none":"block",b?(r.style.borderRadius="0",r.style.width="100vw",r.style.height="100vh",n||(v=r.style.top,y=r.style.left,r.style.top="0",r.style.left="0")):(r.style.borderRadius="12px",r.style.width=p,r.style.height=m,n||(r.style.top=v,r.style.left=y)),e.onMaximizeChange?.(b,r)}let w=!1,M="",T="";const S=220;function A(h){w=h,f.innerHTML=w?$.windowRestore:$.windowMinimize,f.setAttribute("aria-label",w?"Restore":"Minimize"),C.style.display=w?"none":"block",w?(M=r.style.height,T=r.style.width,r.style.minHeight="0",r.style.height="auto",r.style.minWidth="0",r.style.width=`${S}px`,u.disabled=!0,u.style.opacity="0.4",u.style.cursor="default",H.style.display="none"):(r.style.minHeight="240px",r.style.height=M||m,r.style.minWidth="320px",r.style.width=T||p,u.disabled=!1,u.style.opacity="1",u.style.cursor="pointer",H.style.display="flex")}function E(){const h=t.body.style.userSelect;return t.body.style.userSelect="none",()=>{t.body.style.userSelect=h}}n||(s.style.cursor="move",s.addEventListener("pointerdown",h=>{if(b||h.target.closest('button, [role="button"]'))return;h.preventDefault();const I=E(),W=h.clientX,z=h.clientY,R=r.offsetTop,_=r.offsetLeft,ee=o.innerHeight-s.offsetHeight,te=o.innerWidth-40,K=40-r.offsetWidth;s.setPointerCapture(h.pointerId);const G=U=>{const ne=Math.min(Math.max(R+(U.clientY-z),0),ee),xe=Math.min(Math.max(_+(U.clientX-W),K),te);r.style.top=`${ne}px`,r.style.left=`${xe}px`},j=U=>{I(),s.releasePointerCapture(U.pointerId),s.removeEventListener("pointermove",G),s.removeEventListener("pointerup",j)};s.addEventListener("pointermove",G),s.addEventListener("pointerup",j)}));const F='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function V(h){const I=Array.from(r.querySelectorAll(F)).filter(_=>_.offsetParent!==null||_===t.activeElement);if(I.length===0){h.preventDefault(),r.focus();return}const W=I[0],z=I[I.length-1],R=t.activeElement;h.shiftKey&&(R===W||!r.contains(R))?(h.preventDefault(),z.focus()):!h.shiftKey&&R===z&&(h.preventDefault(),W.focus())}const O=h=>{if(h.key==="Escape"){D();return}if(n&&(h.key==="e"||h.key==="E")){D();return}if(n&&h.key==="Tab"){V(h);return}(h.key==="f"||h.key==="F")&&!w&&L(!b)};function D(){n?t.removeEventListener("keydown",O):r.removeEventListener("keydown",O),J.remove(),he(),hideTooltip(t),reparentTooltip(t.body),a?a.remove():r.remove(),n&&(t.body.style.overflow=i),d?.focus?.(),e.onClose()}function B(){n||(r.style.zIndex=String(de()))}const H=t.createElement("div");Object.assign(H.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const C=t.createElement("div");C.tabIndex=0,C.setAttribute("role","separator"),C.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(C.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),C.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16" style="display:block"><path d="M15 15 L15 9 M15 15 L9 15 M15 15 L15 3 M15 15 L3 15" stroke="currentColor" stroke-width="1" opacity="0.35" fill="none"/></svg>',C.style.color=CLR.label;const ae=320,se=240,Y=20;function q(h,I){const W=o.innerWidth-r.offsetLeft,z=o.innerHeight-r.offsetTop,R=Math.min(Math.max(r.offsetWidth+h,ae),W),_=Math.min(Math.max(r.offsetHeight+I,se),z);r.style.width=`${R}px`,r.style.height=`${_}px`}C.addEventListener("keydown",h=>{if(!(b||w))switch(h.key){case"ArrowRight":h.preventDefault(),q(Y,0);break;case"ArrowLeft":h.preventDefault(),q(-Y,0);break;case"ArrowDown":h.preventDefault(),q(0,Y);break;case"ArrowUp":h.preventDefault(),q(0,-Y);break}}),C.addEventListener("pointerdown",h=>{if(b||w)return;h.preventDefault();const I=E(),W=h.clientX,z=h.clientY,R=r.offsetWidth,_=r.offsetHeight,ee=o.innerWidth-r.offsetLeft,te=o.innerHeight-r.offsetTop;C.setPointerCapture(h.pointerId);const K=j=>{const U=Math.min(Math.max(R+(j.clientX-W),ae),ee),ne=Math.min(Math.max(_+(j.clientY-z),se),te);r.style.width=`${U}px`,r.style.height=`${ne}px`},G=j=>{I(),C.releasePointerCapture(j.pointerId),C.removeEventListener("pointermove",K),C.removeEventListener("pointerup",G)};C.addEventListener("pointermove",K),C.addEventListener("pointerup",G)}),r.appendChild(s),r.appendChild(H),r.appendChild(C);const Q=e.anchor?overlayRootFor(e.anchor):t.body;a?(a.appendChild(r),Q.appendChild(a)):Q.appendChild(r);const he=$e(t,Q),J=t.createElement("style");return J.textContent=`@media print{
|
|
2
2
|
body{overflow:visible!important;height:auto!important}
|
|
3
3
|
body>*:not(.wmap-overlay-box):not(#wmap-modal-backdrop):not(.wmap-overlay-ancestor){display:none!important}
|
|
4
4
|
#wmap-modal-backdrop{position:static!important;background:none!important;backdrop-filter:none!important;display:block!important}
|
|
@@ -6,4 +6,4 @@ body>*:not(.wmap-overlay-box):not(#wmap-modal-backdrop):not(.wmap-overlay-ancest
|
|
|
6
6
|
.wmap-overlay-box>div:first-child{display:none!important}
|
|
7
7
|
.wmap-overlay-box>div:nth-child(2){display:block!important;overflow:visible!important;height:auto!important;flex:none!important;min-height:0!important;min-width:0!important}
|
|
8
8
|
.wmap-overlay-box>div:nth-child(3){display:none!important}
|
|
9
|
-
}`,n.head.appendChild(J),reparentTooltip(r),t?(a.addEventListener("click",h=>{h.target===a&&D()}),n.addEventListener("keydown",I)):(r.addEventListener("keydown",I),r.addEventListener("mousedown",B),B()),nextFrame(()=>(c.isConnected?c:r).focus(),o),{backdrop:a,box:r,contentWrap:O,close:D,bringToFront:B}}export function openModal(e){return pe({...e,mode:"modal"})}export function openFloatingWindow(e){return pe({...e,mode:"window"})}const re=new WeakSet;export function openReparentedModal(e,t={}){if(e.length===0||e.some(i=>re.has(i)))return null;const n=e.map(i=>({el:i,parent:i.parentElement,next:i.nextSibling})),o=openModal({ownerDocument:t.ownerDocument,title:t.title,boxSize:t.boxSize,anchor:e[0],onClose:()=>{for(const i of n){if(re.delete(i.el),!i.parent)continue;const a=i.next&&i.next.parentNode===i.parent?i.next:null;i.parent.insertBefore(i.el,a)}t.onClosed?.()}});for(const i of n)re.add(i.el),o.contentWrap.appendChild(i.el);return o}export function makePaletteBtn(e,t,n,o,i,a){const u=()=>t()==="hardBin"||t()==="softBin",r=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const m=u()?le().filter(s=>s.name==="default"||s.name==="accessible"):le(),l=n(),v=[];a&&v.push({section:"Scheme"}),o()&&v.push({label:"Custom",active:l==="custom",onClick:()=>i("custom")});for(const s of m)v.push({label:s.label,active:l===s.name,onClick:()=>i(s.name)});return a&&(v.push({section:"Encoding"}),v.push({label:"Mark failing dies",active:a.get(),enabled:u(),disabledHint:u()?void 0:"Available on hard/soft bin maps",onClick:()=>a.set(!a.get())})),v},()=>{});function p(){r.style.display=t()==="metadata"?"none":""}return{btn:r,sync:p}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"off"}export function overlayMenuRows(e,t,n,o){return[{label:"Ring boundaries",active:!!e.showRingBoundaries,onClick:()=>o({showRingBoundaries:!e.showRingBoundaries})},{label:"Quadrant lines",active:!!e.showQuadrantBoundaries,onClick:()=>o({showQuadrantBoundaries:!e.showQuadrantBoundaries})},{label:"Die labels",active:!!e.showDieLabels,onClick:()=>o({showDieLabels:!e.showDieLabels})},{label:"Reticle grid",active:!!e.showReticle,enabled:t,onClick:()=>o({showReticle:!e.showReticle})},{label:"XY indicator",active:!!e.showXYIndicator,onClick:()=>o({showXYIndicator:!e.showXYIndicator})},...passFailMenuRows({...n,display:requestedPassFailDisplay(e)},i=>o({passFailDisplay:i}))]}export function anyOverlayActive(e){return!!(e.showRingBoundaries||e.showQuadrantBoundaries||e.showDieLabels||e.showReticle||e.showXYIndicator||requestedPassFailDisplay(e)!=="off")}export function passFailMenuRows(e,t){if(e.functionalActive)return[];const n=[];return e.hasLimits&&n.push({label:"Spec pass/fail",active:e.display==="spec",onClick:()=>t(e.display==="spec"?"off":"spec")}),e.hasRecorded&&n.push({label:"Test pass/fail",active:e.display==="test",onClick:()=>t(e.display==="test"?"off":"test")}),n}export function makeLogScaleBtn(e,t,n){const o=e.makeBtn("logScale","Toggle log scale",()=>{n({logScale:!t().logScale})});function i(){const a=t(),u=a.plotMode,r=u==="value"||u==="stackedValues";o.style.display=r&&requestedPassFailDisplay(a)==="off"&&!a.functionalActive?"":"none",e.setActive(o,!!a.logScale)}return{btn:o,sync:i}}const Re=[{value:"default",label:"Default (right)"},{value:"compact",label:"Compact (right)"},{value:"left",label:"Left"},{value:"top",label:"Top"},{value:"bottom",label:"Bottom"},{value:"floating",label:"Floating"}];export function makeLegendStyleBtn(e,t,n,o){const i=e.makeCheckMenuBtn("legend","Legend style",()=>{const u=t().legendPosition??"default",r=[];if(fe(t().plotMode)){o&&r.push({section:"Position"});for(const p of Re)r.push({label:p.label,active:u===p.value,onClick:()=>n(p.value)})}if(o){const p=o.blockedReason();r.push({section:"Per map"}),r.push({label:"Legend on each map",active:p?!0:o.get(),enabled:!p,disabledHint:p??void 0,onClick:()=>o.set(!o.get())})}return r},()=>{});function a(){i.style.display=o||fe(t().plotMode)?"":"none"}return{btn:i,sync:a}}function fe(e){return e==="hardBin"||e==="softBin"||e==="metadata"}export function makeOverlaysBtn(e,t,n){return e.makeCheckMenuBtn("overlays","Overlays",()=>t(),o=>e.setActive(o,n()))}export function makeOrientationBtn(e,t,n){return e.makeCheckMenuBtn("orient","Orientation",()=>[{section:"Rotate"},{label:"Rotate 90\xB0 clockwise",active:!1,onClick:()=>{const o=t().rotation??0;n({rotation:ROTATIONS[(ROTATIONS.indexOf(o)+1)%4]})}},{section:"Flip"},{label:"Flip horizontal",active:!!t().flipX,onClick:()=>n({flipX:!t().flipX})},{label:"Flip vertical",active:!!t().flipY,onClick:()=>n({flipY:!t().flipY})}],o=>{const{rotation:i,flipX:a,flipY:u}=t();e.setActive(o,!!(i||a||u))})}let P=null;const me=40,We=me+8;function ze(e,t){const n=e.createElement("div");n.classList.add("wmap-guide-search"),n.style.cssText="display:flex;align-items:center;gap:2px;margin-left:10px;flex:1;min-width:80px;max-width:260px;";const o=e.createElement("input");o.type="text",o.placeholder="Search guide\u2026",o.setAttribute("aria-label","Search guide"),o.style.cssText=`flex:1;min-width:0;padding:4px 8px;font-size:12px;background:${CLR.menuBg};color:${CLR.text};border:1px solid ${CLR.menuBorder};border-radius:${RADIUS.control};outline:none;`,o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder});const i=e.createElement("span");i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.style.cssText=`font-size:12px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function a(x,d){const c=e.createElement("button");return c.type="button",c.textContent=x,c.setAttribute("aria-label",d),c.disabled=!0,c.style.cssText=`border:none;background:none;cursor:pointer;padding:4px 6px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};flex-shrink:0;opacity:0.4;`,c.addEventListener("mouseenter",()=>{c.disabled||(c.style.background=CLR.bgHover)}),c.addEventListener("mouseleave",()=>{c.style.background="none"}),c}const u=a("\u25B2","Previous match"),r=a("\u25BC","Next match");let p=[],m=-1;function l(){const x=p.length===0;u.disabled=x,r.disabled=x,u.style.opacity=x?"0.4":"",r.style.opacity=x?"0.4":""}function v(){for(const x of p)x.parentNode?.replaceChild(e.createTextNode(x.textContent??""),x);t.normalize(),p=[],m=-1}function s(x){if(p.length===0)return;m>=0&&(p[m].style.outline="none"),m=(x%p.length+p.length)%p.length;const d=p[m];d.style.outline=`2px solid ${CLR.iconActive}`,d.style.outlineOffset="1px",d.scrollIntoView({behavior:"smooth",block:"center"}),i.textContent=`${m+1}/${p.length}`}function f(x){v();const d=x.trim();if(!d){i.textContent="",l();return}const c=d.toLowerCase(),b=e.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode(C){const w=C.parentElement;return!w||w.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),g=[];let y;for(;y=b.nextNode();)g.push(y);for(const C of g){const w=C.textContent??"",M=w.toLowerCase();if(!M.includes(c))continue;const T=e.createDocumentFragment();let S=0,A=M.indexOf(c);for(;A!==-1;){A>S&&T.appendChild(e.createTextNode(w.slice(S,A)));const k=e.createElement("mark");k.textContent=w.slice(A,A+d.length),T.appendChild(k),p.push(k),S=A+d.length,A=M.indexOf(c,S)}S<w.length&&T.appendChild(e.createTextNode(w.slice(S))),C.parentNode?.replaceChild(T,C)}l(),p.length===0?i.textContent="No matches":s(0)}return o.addEventListener("input",()=>f(o.value)),o.addEventListener("keydown",x=>{x.key==="Enter"?(x.preventDefault(),s(m+(x.shiftKey?-1:1))):x.key==="Escape"&&(o.value?(o.value="",f("")):o.blur())}),u.addEventListener("click",()=>s(m-1)),r.addEventListener("click",()=>s(m+1)),n.append(o,i,u,r),n}function _e(e,t,n){const o=[...t.querySelectorAll("h2[id]")];if(o.length<2)return;for(const d of t.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))d.style.scrollMarginTop=`${We}px`;const i=e.createElement("div");i.classList.add("wmap-guide-toc"),i.style.cssText=`position:sticky;top:0;z-index:2;background:${CLR.menuBg};border-bottom:1px solid ${CLR.menuBorder};font-family:system-ui,-apple-system,"Segoe UI",sans-serif;`;const a=e.createElement("div");a.style.cssText=`display:flex;align-items:center;gap:4px;height:${me}px;padding:0 12px;box-sizing:border-box;`;const u=e.createElement("span");u.innerHTML='<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',u.style.cssText=`display:inline-flex;transition:transform ${MOTION.base};flex-shrink:0;`;const r=e.createElement("button");r.type="button";const p="wmap-guide-toc-panel";r.setAttribute("aria-expanded","false"),r.setAttribute("aria-controls",p),r.style.cssText=`display:flex;align-items:center;gap:6px;border:none;background:none;cursor:pointer;padding:6px 8px;margin:0 -8px 0 -8px;border-radius:${RADIUS.control};font-size:13px;font-weight:600;color:${CLR.text};`;const m=e.createElement("span");m.textContent=`Contents (${o.length})`,r.append(u,m),r.addEventListener("mouseenter",()=>{r.style.background=CLR.bgHover}),r.addEventListener("mouseleave",()=>{r.style.background="none"});const l=e.createElement("button");l.type="button",l.textContent="\u2191 Top",l.style.cssText=`margin-left:auto;border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};`,l.addEventListener("mouseenter",()=>{l.style.background=CLR.bgHover}),l.addEventListener("mouseleave",()=>{l.style.background="none"}),l.addEventListener("click",()=>{x.close(),t.scrollTo({top:0,behavior:"smooth"})}),n?a.append(r,ze(e,t),l):a.append(r,l);const v=e.createElement("div");v.id=p,v.hidden=!0,v.style.cssText="padding:2px 12px 12px;max-height:min(60vh,440px);overflow-y:auto;";const s=/^\s*\d+(?:\.\d+)*\.\s+/;for(const d of t.querySelectorAll("h2[id],h3[id],h4[id]")){const c=d.firstChild;c?.nodeType===Node.TEXT_NODE&&(c.textContent=(c.textContent??"").replace(s,""))}const f=e.createElement("ul");f.setAttribute("role","list"),f.style.cssText="list-style:none;margin:0;padding:0;columns:200px;column-gap:24px;";for(const d of o){const c=e.createElement("li");c.style.cssText="break-inside:avoid;";const b=e.createElement("a");b.href=`#${d.id}`,b.textContent=d.textContent??"",b.style.cssText=`display:block;padding:4px 6px;margin:0 -6px;border-radius:${RADIUS.control};font-size:12.5px;color:${CLR.iconActive};text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,b.addEventListener("mouseenter",()=>{b.style.background=CLR.bgHover}),b.addEventListener("mouseleave",()=>{b.style.background="none"}),b.addEventListener("click",g=>{g.preventDefault(),x.close(),d.scrollIntoView({behavior:"smooth",block:"start"})}),c.appendChild(b),f.appendChild(c)}v.appendChild(f);const x=wireExpandToggle(r,d=>{v.hidden=!d,r.setAttribute("aria-expanded",String(d)),u.style.transform=d?"rotate(180deg)":"none"});i.append(a,v),t.prepend(i)}function be(e,t,n,o,i){const a=t,u=a.__wmapDemoApi;a.__wmapDemoApi=o;const r=e.createElement("div");return r.classList.add("wmap-guide-content"),r.innerHTML=n,_e(e,r,i),{content:r,restoreApi:()=>{a.__wmapDemoApi===o&&(a.__wmapDemoApi=u)}}}function he(e,t){const n=t,o=e.querySelector("script");if(o){const i=e.ownerDocument.createElement("script");i.textContent=o.textContent,e.appendChild(i);const a=e.querySelector(".wmap-guide");return a&&n.__wmapPopulateGuideDemos?.(a),n.__wmapDestroyGuideDemos}}function Ne(e,t,n,o){const i=o?.ownerDocument??document,a=i.defaultView??window,{content:u,restoreApi:r}=be(i,a,t,n,!0);Object.assign(u.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let p;const m=openFloatingWindow({title:e,anchor:o,ownerDocument:i,printable:!0,onMaximizeChange:l=>{u.style.setProperty("--wmap-guide-reading-width",l?"1000px":"720px")},onClose:()=>{P===m&&(P=null),p?.(),r()}});return m.contentWrap.appendChild(u),p=he(u,a),m}function Pe(e,t,n,o){const i=e.document;i.title=t,Object.assign(i.documentElement.style,{height:"100%"}),Object.assign(i.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:FONT.family}),copyWmapThemeTokens(document.documentElement,i.documentElement);const a=syncWmapPopupTheme(document.documentElement,i.documentElement),{content:u,restoreApi:r}=be(i,e,n,o,!1);Object.assign(u.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),i.body.appendChild(u);const p=he(u,e);let m=!1;const l=()=>{if(!m){m=!0,clearInterval(v),a();try{p?.()}catch{}r(),P===s&&(P=null)}},v=setInterval(()=>{e.closed&&l()},400);e.addEventListener("pagehide",l);const s={close:()=>{e.closed||e.close(),l()}};return s}export function openUserGuideWindow(e,t,n,o){P&&(P.close(),P=null);const i=n?.title??"Wafer Map \u2014 User Guide",a=(n?.html??"")+t,r=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");P=r?Pe(r,i,a,e):Ne(i,a,e,o)}export function openWaferMapGuide(e,t){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([n,o,i])=>{openUserGuideWindow({buildWaferMap:Ce,renderWaferMap:o.renderWaferMap,renderWaferGallery:i.renderWaferGallery,analyzeWaferMap:Ae},n.USER_GUIDE_HTML,e,t)})}export function openReportModal(e,t){const n=t?.ownerDocument??document,o=n.createElement("iframe");o.srcdoc=e,o.title="Summary report",Object.assign(o.style,{border:"0",width:"100%",flex:"1",minHeight:"0",background:"#fff"});const i=n.createElement("div");Object.assign(i.style,{display:"flex",justifyContent:"flex-end",padding:"6px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const a=n.createElement("button");a.type="button",wireControlHover(a,"bare"),a.textContent="Open as full page \u2197",Object.assign(a.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:FONT.body,textDecoration:"underline",padding:"0"}),a.addEventListener("click",()=>Le(e)),i.appendChild(a);const u=openModal({title:"Summary report",anchor:t?.anchor,ownerDocument:n,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return u.contentWrap.style.flexDirection="column",u.contentWrap.appendChild(i),u.contentWrap.appendChild(o),u}
|
|
9
|
+
}`,t.head.appendChild(J),reparentTooltip(r),n?(a.addEventListener("click",h=>{h.target===a&&D()}),t.addEventListener("keydown",O)):(r.addEventListener("keydown",O),r.addEventListener("mousedown",B),B()),nextFrame(()=>(c.isConnected?c:r).focus(),o),{backdrop:a,box:r,contentWrap:H,close:D,bringToFront:B}}export function openModal(e){return ue({...e,mode:"modal"})}export function openFloatingWindow(e){return ue({...e,mode:"window"})}const re=new WeakSet;export function openReparentedModal(e,n={}){if(e.length===0||e.some(i=>re.has(i)))return null;const t=e.map(i=>({el:i,parent:i.parentElement,next:i.nextSibling})),o=openModal({ownerDocument:n.ownerDocument,title:n.title,boxSize:n.boxSize,anchor:e[0],onClose:()=>{for(const i of t){if(re.delete(i.el),!i.parent)continue;const a=i.next&&i.next.parentNode===i.parent?i.next:null;i.parent.insertBefore(i.el,a)}n.onClosed?.()}});for(const i of t)re.add(i.el),o.contentWrap.appendChild(i.el);return o}export function makePaletteBtn(e,n,t,o){const i=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const d=n(),r=[];if(d.plotMode==="hardBin"||d.plotMode==="softBin"){const p=d.binColorScheme??"default";r.push({section:"Bin colours"});for(const m of we())r.push({label:m.label,active:p===m.name,onClick:()=>o({binColorScheme:m.name})});if(t()){const m=d.useDefinedBinColors??!0;r.push({section:"Bin definitions"}),r.push({label:"Use colours from bin definitions",active:m,onClick:()=>o({useDefinedBinColors:!m})})}}else{const p=d.valueColorScheme??"default";r.push({section:"Value colours"});for(const s of ke())r.push({label:s.label,active:p===s.name,onClick:()=>o({valueColorScheme:s.name})});const m=d.reverseValueScheme??!1;r.push({section:"Direction"}),r.push({label:"Reverse gradient",active:m,onClick:()=>o({reverseValueScheme:!m})})}return r},()=>{});function a(){i.style.display=n().plotMode==="metadata"?"none":""}return{btn:i,sync:a}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"off"}export function overlayMenuRows(e,n,t,o){return[{label:"Ring boundaries",active:!!e.showRingBoundaries,onClick:()=>o({showRingBoundaries:!e.showRingBoundaries})},{label:"Quadrant lines",active:!!e.showQuadrantBoundaries,onClick:()=>o({showQuadrantBoundaries:!e.showQuadrantBoundaries})},{label:"Die labels",active:!!e.showDieLabels,onClick:()=>o({showDieLabels:!e.showDieLabels})},{label:"Reticle grid",active:!!e.showReticle,enabled:n,onClick:()=>o({showReticle:!e.showReticle})},{label:"XY indicator",active:!!e.showXYIndicator,onClick:()=>o({showXYIndicator:!e.showXYIndicator})},...passFailMenuRows({...t,display:requestedPassFailDisplay(e)},i=>o({passFailDisplay:i})),{label:"Mark failing dies",active:!!e.markFailingDies,enabled:t.binMode,disabledHint:t.binMode?void 0:"Available on hard/soft bin maps",onClick:()=>o({markFailingDies:!e.markFailingDies})},{section:""},{label:"Clear overlays",active:!1,action:!0,enabled:anyOverlayActive(e),disabledHint:"No overlays are active",onClick:()=>o({showRingBoundaries:!1,showQuadrantBoundaries:!1,showDieLabels:!1,showReticle:!1,showXYIndicator:!1,passFailDisplay:"off",markFailingDies:!1})}]}export function anyOverlayActive(e){return!!(e.showRingBoundaries||e.showQuadrantBoundaries||e.showDieLabels||e.showReticle||e.showXYIndicator||e.markFailingDies||requestedPassFailDisplay(e)!=="off")}export function passFailMenuRows(e,n){if(e.functionalActive)return[];const t=[];return e.hasLimits&&t.push({label:"Spec pass/fail",active:e.display==="spec",onClick:()=>n(e.display==="spec"?"off":"spec")}),e.hasRecorded&&t.push({label:"Test pass/fail",active:e.display==="test",onClick:()=>n(e.display==="test"?"off":"test")}),t}export function makeLogScaleBtn(e,n,t){const o=e.makeBtn("logScale","Toggle log scale",()=>{t({logScale:!n().logScale})});function i(){const a=n(),d=a.plotMode,r=d==="value"||d==="stackedValues";o.style.display=r&&requestedPassFailDisplay(a)==="off"&&!a.functionalActive?"":"none",e.setActive(o,!!a.logScale)}return{btn:o,sync:i}}const We=[{value:"default",label:"Default (right)"},{value:"compact",label:"Compact (right)"},{value:"left",label:"Left"},{value:"top",label:"Top"},{value:"bottom",label:"Bottom"},{value:"floating",label:"Floating"}];export function makeLegendStyleBtn(e,n,t,o){const i=e.makeCheckMenuBtn("legend","Legend style",()=>{const d=n().legendPosition??"default",r=[];if(pe(n().plotMode)){o&&r.push({section:"Position"});for(const p of We)r.push({label:p.label,active:d===p.value,onClick:()=>t(p.value)})}if(o){const p=o.blockedReason();r.push({section:"Per map"}),r.push({label:"Legend on each map",active:p?!0:o.get(),enabled:!p,disabledHint:p??void 0,onClick:()=>o.set(!o.get())})}return r},()=>{});function a(){i.style.display=o||pe(n().plotMode)?"":"none"}return{btn:i,sync:a}}function pe(e){return e==="hardBin"||e==="softBin"||e==="metadata"}export function makeOverlaysBtn(e,n,t){return e.makeCheckMenuBtn("overlays","Overlays",()=>n(),o=>e.setActive(o,t()))}export function makeOrientationBtn(e,n,t){return e.makeCheckMenuBtn("orient","Orientation",()=>[{section:"Rotate"},{label:"Rotate 90\xB0 clockwise",active:!1,onClick:()=>{const o=n().rotation??0;t({rotation:ROTATIONS[(ROTATIONS.indexOf(o)+1)%4]})}},{section:"Flip"},{label:"Flip horizontal",active:!!n().flipX,onClick:()=>t({flipX:!n().flipX})},{label:"Flip vertical",active:!!n().flipY,onClick:()=>t({flipY:!n().flipY})},{section:""},{label:"Reset orientation",active:!1,action:!0,enabled:!!(n().rotation||n().flipX||n().flipY),disabledHint:"Already in the original orientation",onClick:()=>t({rotation:0,flipX:!1,flipY:!1})}],o=>{const{rotation:i,flipX:a,flipY:d}=n();e.setActive(o,!!(i||a||d))})}let P=null;const fe=40,ze=fe+8;function _e(e,n){const t=e.createElement("div");t.classList.add("wmap-guide-search"),t.style.cssText="display:flex;align-items:center;gap:2px;margin-left:10px;flex:1;min-width:80px;max-width:260px;";const o=e.createElement("input");o.type="text",o.placeholder="Search guide\u2026",o.setAttribute("aria-label","Search guide"),o.style.cssText=`flex:1;min-width:0;padding:4px 8px;font-size:12px;background:${CLR.menuBg};color:${CLR.text};border:1px solid ${CLR.menuBorder};border-radius:${RADIUS.control};outline:none;`,o.addEventListener("focus",()=>{o.style.borderColor=CLR.iconActive}),o.addEventListener("blur",()=>{o.style.borderColor=CLR.menuBorder});const i=e.createElement("span");i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.style.cssText=`font-size:12px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function a(x,u){const c=e.createElement("button");return c.type="button",c.textContent=x,c.setAttribute("aria-label",u),c.disabled=!0,c.style.cssText=`border:none;background:none;cursor:pointer;padding:4px 6px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};flex-shrink:0;opacity:0.4;`,c.addEventListener("mouseenter",()=>{c.disabled||(c.style.background=CLR.bgHover)}),c.addEventListener("mouseleave",()=>{c.style.background="none"}),c}const d=a("\u25B2","Previous match"),r=a("\u25BC","Next match");let p=[],m=-1;function s(){const x=p.length===0;d.disabled=x,r.disabled=x,d.style.opacity=x?"0.4":"",r.style.opacity=x?"0.4":""}function g(){for(const x of p)x.parentNode?.replaceChild(e.createTextNode(x.textContent??""),x);n.normalize(),p=[],m=-1}function l(x){if(p.length===0)return;m>=0&&(p[m].style.outline="none"),m=(x%p.length+p.length)%p.length;const u=p[m];u.style.outline=`2px solid ${CLR.iconActive}`,u.style.outlineOffset="1px",u.scrollIntoView({behavior:"smooth",block:"center"}),i.textContent=`${m+1}/${p.length}`}function f(x){g();const u=x.trim();if(!u){i.textContent="",s();return}const c=u.toLowerCase(),b=e.createTreeWalker(n,NodeFilter.SHOW_TEXT,{acceptNode(L){const w=L.parentElement;return!w||w.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),v=[];let y;for(;y=b.nextNode();)v.push(y);for(const L of v){const w=L.textContent??"",M=w.toLowerCase();if(!M.includes(c))continue;const T=e.createDocumentFragment();let S=0,A=M.indexOf(c);for(;A!==-1;){A>S&&T.appendChild(e.createTextNode(w.slice(S,A)));const E=e.createElement("mark");E.textContent=w.slice(A,A+u.length),T.appendChild(E),p.push(E),S=A+u.length,A=M.indexOf(c,S)}S<w.length&&T.appendChild(e.createTextNode(w.slice(S))),L.parentNode?.replaceChild(T,L)}s(),p.length===0?i.textContent="No matches":l(0)}return o.addEventListener("input",()=>f(o.value)),o.addEventListener("keydown",x=>{x.key==="Enter"?(x.preventDefault(),l(m+(x.shiftKey?-1:1))):x.key==="Escape"&&(o.value?(o.value="",f("")):o.blur())}),d.addEventListener("click",()=>l(m-1)),r.addEventListener("click",()=>l(m+1)),t.append(o,i,d,r),t}function Ne(e,n,t){const o=[...n.querySelectorAll("h2[id]")];if(o.length<2)return;for(const u of n.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))u.style.scrollMarginTop=`${ze}px`;const i=e.createElement("div");i.classList.add("wmap-guide-toc"),i.style.cssText=`position:sticky;top:0;z-index:2;background:${CLR.menuBg};border-bottom:1px solid ${CLR.menuBorder};font-family:system-ui,-apple-system,"Segoe UI",sans-serif;`;const a=e.createElement("div");a.style.cssText=`display:flex;align-items:center;gap:4px;height:${fe}px;padding:0 12px;box-sizing:border-box;`;const d=e.createElement("span");d.innerHTML='<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>',d.style.cssText=`display:inline-flex;transition:transform ${MOTION.base};flex-shrink:0;`;const r=e.createElement("button");r.type="button";const p="wmap-guide-toc-panel";r.setAttribute("aria-expanded","false"),r.setAttribute("aria-controls",p),r.style.cssText=`display:flex;align-items:center;gap:6px;border:none;background:none;cursor:pointer;padding:6px 8px;margin:0 -8px 0 -8px;border-radius:${RADIUS.control};font-size:13px;font-weight:600;color:${CLR.text};`;const m=e.createElement("span");m.textContent=`Contents (${o.length})`,r.append(d,m),r.addEventListener("mouseenter",()=>{r.style.background=CLR.bgHover}),r.addEventListener("mouseleave",()=>{r.style.background="none"});const s=e.createElement("button");s.type="button",s.textContent="\u2191 Top",s.style.cssText=`margin-left:auto;border:none;background:none;cursor:pointer;padding:6px 8px;border-radius:${RADIUS.control};font-size:12px;color:${CLR.label};`,s.addEventListener("mouseenter",()=>{s.style.background=CLR.bgHover}),s.addEventListener("mouseleave",()=>{s.style.background="none"}),s.addEventListener("click",()=>{x.close(),n.scrollTo({top:0,behavior:"smooth"})}),t?a.append(r,_e(e,n),s):a.append(r,s);const g=e.createElement("div");g.id=p,g.hidden=!0,g.style.cssText="padding:2px 12px 12px;max-height:min(60vh,440px);overflow-y:auto;";const l=/^\s*\d+(?:\.\d+)*\.\s+/;for(const u of n.querySelectorAll("h2[id],h3[id],h4[id]")){const c=u.firstChild;c?.nodeType===Node.TEXT_NODE&&(c.textContent=(c.textContent??"").replace(l,""))}const f=e.createElement("ul");f.setAttribute("role","list"),f.style.cssText="list-style:none;margin:0;padding:0;columns:200px;column-gap:24px;";for(const u of o){const c=e.createElement("li");c.style.cssText="break-inside:avoid;";const b=e.createElement("a");b.href=`#${u.id}`,b.textContent=u.textContent??"",b.style.cssText=`display:block;padding:4px 6px;margin:0 -6px;border-radius:${RADIUS.control};font-size:12.5px;color:${CLR.iconActive};text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,b.addEventListener("mouseenter",()=>{b.style.background=CLR.bgHover}),b.addEventListener("mouseleave",()=>{b.style.background="none"}),b.addEventListener("click",v=>{v.preventDefault(),x.close(),u.scrollIntoView({behavior:"smooth",block:"start"})}),c.appendChild(b),f.appendChild(c)}g.appendChild(f);const x=wireExpandToggle(r,u=>{g.hidden=!u,r.setAttribute("aria-expanded",String(u)),d.style.transform=u?"rotate(180deg)":"none"});i.append(a,g),n.prepend(i)}function me(e,n,t,o,i){const a=n,d=a.__wmapDemoApi;a.__wmapDemoApi=o;const r=e.createElement("div");return r.classList.add("wmap-guide-content"),r.innerHTML=t,Ne(e,r,i),{content:r,restoreApi:()=>{a.__wmapDemoApi===o&&(a.__wmapDemoApi=d)}}}function be(e,n){const t=n,o=e.querySelector("script");if(o){const i=e.ownerDocument.createElement("script");i.textContent=o.textContent,e.appendChild(i);const a=e.querySelector(".wmap-guide");return a&&t.__wmapPopulateGuideDemos?.(a),t.__wmapDestroyGuideDemos}}function Pe(e,n,t,o){const i=o?.ownerDocument??document,a=i.defaultView??window,{content:d,restoreApi:r}=me(i,a,n,t,!0);Object.assign(d.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let p;const m=openFloatingWindow({title:e,anchor:o,ownerDocument:i,printable:!0,onMaximizeChange:s=>{d.style.setProperty("--wmap-guide-reading-width",s?"1000px":"720px")},onClose:()=>{P===m&&(P=null),p?.(),r()}});return m.contentWrap.appendChild(d),p=be(d,a),m}function Fe(e,n,t,o){const i=e.document;i.title=n,Object.assign(i.documentElement.style,{height:"100%"}),Object.assign(i.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:FONT.family}),copyWmapThemeTokens(document.documentElement,i.documentElement);const a=syncWmapPopupTheme(document.documentElement,i.documentElement),{content:d,restoreApi:r}=me(i,e,t,o,!1);Object.assign(d.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),i.body.appendChild(d);const p=be(d,e);let m=!1;const s=()=>{if(!m){m=!0,clearInterval(g),a();try{p?.()}catch{}r(),P===l&&(P=null)}},g=setInterval(()=>{e.closed&&s()},400);e.addEventListener("pagehide",s);const l={close:()=>{e.closed||e.close(),s()}};return l}export function openUserGuideWindow(e,n,t,o){P&&(P.close(),P=null);const i=t?.title??"Wafer Map \u2014 User Guide",a=(t?.html??"")+n,r=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");P=r?Fe(r,i,a,e):Pe(i,a,e,o)}export function openWaferMapGuide(e,n){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([t,o,i])=>{openUserGuideWindow({buildWaferMap:Ae,renderWaferMap:o.renderWaferMap,renderWaferGallery:i.renderWaferGallery,analyzeWaferMap:Me},t.USER_GUIDE_HTML,e,n)})}export function openReportModal(e,n){const t=n?.ownerDocument??document,o=t.createElement("iframe");o.srcdoc=e,o.title="Summary report",Object.assign(o.style,{border:"0",width:"100%",flex:"1",minHeight:"0",background:"#fff"});const i=t.createElement("div");Object.assign(i.style,{display:"flex",justifyContent:"flex-end",padding:"6px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const a=t.createElement("button");a.type="button",wireControlHover(a,"bare"),a.textContent="Open as full page \u2197",Object.assign(a.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:FONT.body,textDecoration:"underline",padding:"0"}),a.addEventListener("click",()=>Le(e)),i.appendChild(a);const d=openModal({title:"Summary report",anchor:n?.anchor,ownerDocument:t,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return d.contentWrap.style.flexDirection="column",d.contentWrap.appendChild(i),d.contentWrap.appendChild(o),d}
|