@wafertools/wafermap 0.32.0 → 0.34.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 +7 -7
- package/CHANGELOG.md +374 -1
- package/README.md +5 -5
- package/dist/packages/canvas-adapter/chartPopulation.d.ts +15 -10
- package/dist/packages/canvas-adapter/chartPopulation.js +1 -1
- package/dist/packages/canvas-adapter/charts/barPanel.d.ts +7 -0
- package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
- package/dist/packages/canvas-adapter/charts/binCluster.d.ts +7 -1
- package/dist/packages/canvas-adapter/charts/binCluster.js +1 -1
- package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
- package/dist/packages/canvas-adapter/charts/capability.js +1 -1
- package/dist/packages/canvas-adapter/charts/chartShell.d.ts +57 -15
- package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
- package/dist/packages/canvas-adapter/charts/correlation.js +1 -2
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.d.ts +2 -0
- package/dist/packages/canvas-adapter/charts/groupedBarPlot.js +1 -1
- package/dist/packages/canvas-adapter/charts/histogram.d.ts +16 -0
- package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
- package/dist/packages/canvas-adapter/charts/palette.d.ts +2 -0
- package/dist/packages/canvas-adapter/charts/palette.js +1 -1
- package/dist/packages/canvas-adapter/charts/plotChart.d.ts +27 -0
- package/dist/packages/canvas-adapter/charts/plotChart.js +1 -0
- package/dist/packages/canvas-adapter/charts/pointInteractions.d.ts +45 -0
- package/dist/packages/canvas-adapter/charts/pointInteractions.js +1 -0
- package/dist/packages/canvas-adapter/charts/regionYieldDiagram.d.ts +2 -0
- package/dist/packages/canvas-adapter/charts/regionYieldDiagram.js +1 -1
- package/dist/packages/canvas-adapter/charts/scatter.d.ts +19 -0
- package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
- package/dist/packages/canvas-adapter/charts/sweep.d.ts +12 -0
- package/dist/packages/canvas-adapter/charts/sweep.js +1 -1
- package/dist/packages/canvas-adapter/charts/testPassRate.d.ts +7 -0
- package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
- package/dist/packages/canvas-adapter/charts/trend.d.ts +11 -0
- package/dist/packages/canvas-adapter/charts/trend.js +1 -1
- package/dist/packages/canvas-adapter/confirmDialog.d.ts +13 -0
- package/dist/packages/canvas-adapter/confirmDialog.js +1 -0
- package/dist/packages/canvas-adapter/dataTab.d.ts +131 -0
- package/dist/packages/canvas-adapter/dataTab.js +1 -0
- package/dist/packages/canvas-adapter/dieList.d.ts +39 -4
- package/dist/packages/canvas-adapter/dieList.js +6 -7
- package/dist/packages/canvas-adapter/drilldown.d.ts +20 -3
- package/dist/packages/canvas-adapter/drilldown.js +1 -1
- package/dist/packages/canvas-adapter/guideWindow.d.ts +96 -0
- package/dist/packages/canvas-adapter/guideWindow.js +1 -0
- package/dist/packages/canvas-adapter/identityHeader.d.ts +16 -0
- package/dist/packages/canvas-adapter/identityHeader.js +1 -1
- package/dist/packages/canvas-adapter/index.d.ts +3 -3
- package/dist/packages/canvas-adapter/index.js +1 -1
- package/dist/packages/canvas-adapter/insightsTab.d.ts +73 -54
- package/dist/packages/canvas-adapter/insightsTab.js +1 -1
- package/dist/packages/canvas-adapter/maplessSummary.d.ts +2 -2
- package/dist/packages/canvas-adapter/plotEditor.d.ts +29 -0
- package/dist/packages/canvas-adapter/plotEditor.js +1 -0
- package/dist/packages/canvas-adapter/plotItems.d.ts +32 -0
- package/dist/packages/canvas-adapter/plotItems.js +1 -0
- package/dist/packages/canvas-adapter/plotModal.d.ts +30 -0
- package/dist/packages/canvas-adapter/plotModal.js +1 -0
- package/dist/packages/canvas-adapter/plotStore.d.ts +52 -0
- package/dist/packages/canvas-adapter/plotStore.js +1 -0
- package/dist/packages/canvas-adapter/plotTab.d.ts +30 -0
- package/dist/packages/canvas-adapter/plotTab.js +1 -0
- package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +3 -2
- package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
- package/dist/packages/canvas-adapter/renderWaferMap.d.ts +51 -2
- package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
- package/dist/packages/canvas-adapter/summaryPanel.d.ts +49 -11
- package/dist/packages/canvas-adapter/summaryPanel.js +2 -3
- package/dist/packages/canvas-adapter/summaryRail.d.ts +7 -0
- package/dist/packages/canvas-adapter/summaryRail.js +1 -0
- package/dist/packages/canvas-adapter/sweepEditor.d.ts +17 -0
- package/dist/packages/canvas-adapter/sweepEditor.js +1 -0
- package/dist/packages/canvas-adapter/tableExport.d.ts +22 -0
- package/dist/packages/canvas-adapter/tableExport.js +3 -0
- package/dist/packages/canvas-adapter/toCanvas.js +1 -1
- package/dist/packages/canvas-adapter/toolbar.d.ts +74 -93
- 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 +409 -51
- package/dist/packages/canvas-adapter/version.d.ts +2 -2
- package/dist/packages/canvas-adapter/version.js +1 -1
- package/dist/packages/canvas-adapter/viewSwitch.d.ts +13 -0
- package/dist/packages/canvas-adapter/viewSwitch.js +1 -0
- package/dist/packages/canvas-adapter/virtualTable.d.ts +44 -0
- package/dist/packages/canvas-adapter/virtualTable.js +1 -0
- package/dist/packages/core/aggregates.d.ts +6 -0
- package/dist/packages/core/aggregates.js +1 -1
- package/dist/packages/core/classify.d.ts +3 -2
- package/dist/packages/core/classify.js +1 -1
- package/dist/packages/core/compact.d.ts +205 -0
- package/dist/packages/core/compact.js +3 -0
- package/dist/packages/core/passBins.d.ts +23 -4
- package/dist/packages/core/passBins.js +1 -1
- package/dist/packages/core/ringCount.d.ts +22 -0
- package/dist/packages/core/ringCount.js +1 -0
- package/dist/packages/core/tableCsv.d.ts +43 -0
- package/dist/packages/core/tableCsv.js +3 -0
- package/dist/packages/renderer/axisTicks.d.ts +14 -0
- package/dist/packages/renderer/axisTicks.js +1 -1
- package/dist/packages/renderer/binColors.d.ts +6 -6
- package/dist/packages/renderer/binColors.js +1 -1
- package/dist/packages/renderer/buildView.d.ts +27 -2
- package/dist/packages/renderer/buildView.js +1 -1
- package/dist/packages/renderer/buildWaferMap.js +1 -1
- package/dist/packages/renderer/compactView.d.ts +22 -0
- package/dist/packages/renderer/compactView.js +1 -0
- package/dist/packages/renderer/xyIndicator.d.ts +27 -0
- package/dist/packages/renderer/xyIndicator.js +1 -0
- package/dist/packages/stats/analyzeWaferLot.d.ts +28 -0
- package/dist/packages/stats/analyzeWaferLot.js +1 -1
- package/dist/packages/stats/analyzeWaferMap.d.ts +36 -1
- package/dist/packages/stats/analyzeWaferMap.js +1 -1
- package/dist/packages/stats/binPareto.d.ts +1 -1
- package/dist/packages/stats/binPareto.js +1 -1
- package/dist/packages/stats/binRows.d.ts +38 -0
- package/dist/packages/stats/binRows.js +1 -0
- package/dist/packages/stats/filterFindings.d.ts +25 -0
- package/dist/packages/stats/filterFindings.js +1 -1
- package/dist/packages/stats/findingText.d.ts +9 -0
- package/dist/packages/stats/findingText.js +2 -0
- package/dist/packages/stats/histogram.d.ts +27 -0
- package/dist/packages/stats/histogram.js +1 -1
- package/dist/packages/stats/index.d.ts +2 -0
- package/dist/packages/stats/index.js +1 -1
- package/dist/packages/stats/lotDrift.d.ts +16 -0
- package/dist/packages/stats/lotDrift.js +1 -0
- package/dist/packages/stats/lotPattern.d.ts +33 -0
- package/dist/packages/stats/lotPattern.js +1 -0
- package/dist/packages/stats/math.d.ts +60 -6
- package/dist/packages/stats/math.js +1 -1
- package/dist/packages/stats/patternClassification.d.ts +32 -1
- package/dist/packages/stats/patternClassification.js +1 -1
- package/dist/packages/stats/plotData.d.ts +258 -0
- package/dist/packages/stats/plotData.js +1 -0
- package/dist/packages/stats/plotId.d.ts +3 -0
- package/dist/packages/stats/plotId.js +1 -0
- package/dist/packages/stats/plotSpec.d.ts +119 -0
- package/dist/packages/stats/plotSpec.js +4 -0
- package/dist/packages/stats/presentation.d.ts +44 -0
- package/dist/packages/stats/presentation.js +1 -0
- package/dist/packages/stats/regions.d.ts +15 -0
- package/dist/packages/stats/regions.js +1 -1
- package/dist/packages/stats/renderSummaryReport.d.ts +23 -5
- package/dist/packages/stats/renderSummaryReport.js +32 -27
- package/dist/packages/stats/reportHtml.d.ts +54 -9
- package/dist/packages/stats/reportHtml.js +145 -55
- package/dist/packages/stats/scatter.d.ts +6 -0
- package/dist/packages/stats/scatter.js +1 -1
- package/dist/packages/stats/sweep.d.ts +37 -1
- package/dist/packages/stats/sweep.js +1 -1
- package/dist/packages/stats/sweepText.d.ts +14 -0
- package/dist/packages/stats/sweepText.js +1 -0
- package/dist/packages/stats/sweepXFromName.d.ts +14 -0
- package/dist/packages/stats/sweepXFromName.js +1 -1
- package/dist/packages/stats/synthesis.d.ts +76 -0
- package/dist/packages/stats/synthesis.js +2 -0
- package/dist/packages/stats/testPassRate.d.ts +6 -0
- package/dist/packages/stats/testPassRate.js +1 -1
- package/dist/packages/stats/trend.js +1 -1
- package/dist/packages/stats/types.d.ts +2 -2
- package/dist/packages/stats/yield.d.ts +15 -6
- package/dist/packages/stats/yield.js +1 -1
- package/dist/packages/stats/yieldRows.d.ts +31 -0
- package/dist/packages/stats/yieldRows.js +1 -0
- package/llms.txt +16 -4
- package/package.json +3 -3
- package/dist/packages/stats/findingsNarrative.d.ts +0 -3
- package/dist/packages/stats/findingsNarrative.js +0 -1
|
@@ -320,6 +320,12 @@ export type SaveImageHandler = (blob: Blob, suggestedName: string) => void | Pro
|
|
|
320
320
|
* @param onSaveImage optional host hook; when present, bypasses `<a download>`
|
|
321
321
|
*/
|
|
322
322
|
export declare function saveImageBlob(blob: Blob, filename: string, onSaveImage?: SaveImageHandler): void;
|
|
323
|
+
/**
|
|
324
|
+
* Keeps a control out of printed output. Buttons that act on the screen (Edit, Delete, Save as PNG, Expand) are
|
|
325
|
+
* meaningless on paper and push the content they sit beside out of place. A single rule, added to the document once, that
|
|
326
|
+
* only matches elements carrying the attribute, so it cannot affect anything it was not asked to.
|
|
327
|
+
*/
|
|
328
|
+
export declare function markNoPrint(el: HTMLElement): void;
|
|
323
329
|
/**
|
|
324
330
|
* The browser's default save: a `<a download>` click. The one copy, used when
|
|
325
331
|
* no host hook is supplied — by `saveImageBlob`, `saveTextFile`, and the
|
|
@@ -330,10 +336,39 @@ export declare function downloadBlob(blob: Blob, filename: string): void;
|
|
|
330
336
|
* Host hook for saving a text file (CSV, etc). Mirrors `SaveImageHandler` —
|
|
331
337
|
* when provided, `saveTextFile` calls this instead of triggering a browser
|
|
332
338
|
* `<a download>`, letting embedded hosts (Tauri, Electron, WebView2) route
|
|
333
|
-
* the text through a native save dialog. Receives the
|
|
339
|
+
* the text through a native save dialog. Receives the content, a
|
|
334
340
|
* `suggestedName` (already includes its extension), and the `mimeType`.
|
|
335
|
-
|
|
336
|
-
|
|
341
|
+
*
|
|
342
|
+
* **The content is a `string`, or a `Blob` for a large table.** A table of a
|
|
343
|
+
* few million cells or more is written in pieces and handed over as a `Blob`
|
|
344
|
+
* (see `exportCsv`), because one string that size can exceed the engine's
|
|
345
|
+
* string limit and doubles the memory in use while it is joined. A host must
|
|
346
|
+
* handle both: for a file, write `blob.stream()`; to read it, `await blob.text()`.
|
|
347
|
+
*/
|
|
348
|
+
export type SaveTextHandler = (text: string | Blob, suggestedName: string, mimeType: string) => void | Promise<void>;
|
|
349
|
+
/**
|
|
350
|
+
* A callback for "a panel just opened or closed beside the map in this box": widens the box by the
|
|
351
|
+
* room the panel took when it opens, and gives it back when it closes. Pass it to whatever
|
|
352
|
+
* renders the map inside `handle`. Only changes of state call it, since the room is measured at
|
|
353
|
+
* the moment the map loses it.
|
|
354
|
+
*/
|
|
355
|
+
export declare function roomForPanel(handle: OverlayHandle): (open: boolean, widthPx: number) => void;
|
|
356
|
+
/**
|
|
357
|
+
* Show what the compact-layout detector saw, for a person to read and send back: counts and
|
|
358
|
+
* scores only (see `diagnoseMpwLayout`), in a box they can read first, copy, or save as a
|
|
359
|
+
* file. Saving goes through the host's `onSaveText`, the one route that works in a desktop
|
|
360
|
+
* webview; the clipboard may not, so a failed copy says so and leaves the text selectable.
|
|
361
|
+
*/
|
|
362
|
+
export declare function openCompactDiagnostics(dies: readonly {
|
|
363
|
+
x?: number | null;
|
|
364
|
+
y?: number | null;
|
|
365
|
+
}[], reticles: readonly ({
|
|
366
|
+
width: number;
|
|
367
|
+
height: number;
|
|
368
|
+
} | undefined)[], opts: {
|
|
369
|
+
anchor: HTMLElement;
|
|
370
|
+
onSaveText?: SaveTextHandler;
|
|
371
|
+
}): OverlayHandle;
|
|
337
372
|
/**
|
|
338
373
|
* Persist a text file (e.g. a CSV export). Routes through the host
|
|
339
374
|
* `onSaveText` hook when provided; otherwise falls back to a browser
|
|
@@ -346,7 +381,7 @@ export type SaveTextHandler = (text: string, suggestedName: string, mimeType: st
|
|
|
346
381
|
* @param mimeType e.g. `'text/csv'`
|
|
347
382
|
* @param onSaveText optional host hook; when present, bypasses `<a download>`
|
|
348
383
|
*/
|
|
349
|
-
export declare function saveTextFile(text: string, filename: string, mimeType: string, onSaveText?: SaveTextHandler): void;
|
|
384
|
+
export declare function saveTextFile(text: string | Blob, filename: string, mimeType: string, onSaveText?: SaveTextHandler): void;
|
|
350
385
|
/**
|
|
351
386
|
* Run `fn` on the next animation frame, falling back to a macrotask in
|
|
352
387
|
* environments without `requestAnimationFrame` (e.g. JSDOM under tests).
|
|
@@ -602,6 +637,12 @@ export type CheckMenuRow = {
|
|
|
602
637
|
* missing feature, and the user has no way to learn the condition.
|
|
603
638
|
*/
|
|
604
639
|
disabledHint?: string;
|
|
640
|
+
/**
|
|
641
|
+
* Close the menu after this row is clicked. For an action that opens something of its own
|
|
642
|
+
* (a dialog), which the menu would otherwise stay open on top of. Toggles keep the menu open
|
|
643
|
+
* so several can be set in one visit.
|
|
644
|
+
*/
|
|
645
|
+
closeMenu?: boolean;
|
|
605
646
|
/**
|
|
606
647
|
* Marks a row that *does* something rather than holding a state — "Clear
|
|
607
648
|
* overlays", "Reset orientation". Rendered as a plain `menuitem` with no
|
|
@@ -687,6 +728,16 @@ export interface OverlayOptions {
|
|
|
687
728
|
* where printing must target `iframe.contentWindow.print()`.
|
|
688
729
|
*/
|
|
689
730
|
printable?: boolean | (() => void);
|
|
731
|
+
/**
|
|
732
|
+
* Show the Maximize button, and honour the F shortcut. Default `true`. A small confirmation has nothing to gain from
|
|
733
|
+
* filling the window, and a Maximize button on it is a control that does nothing useful.
|
|
734
|
+
*/
|
|
735
|
+
maximizable?: boolean;
|
|
736
|
+
/**
|
|
737
|
+
* The element to focus once the overlay has opened. Default: its close button. A confirmation names its safe answer
|
|
738
|
+
* here, so a stray Enter cannot be the thing that confirms.
|
|
739
|
+
*/
|
|
740
|
+
initialFocus?: () => HTMLElement | null | undefined;
|
|
690
741
|
}
|
|
691
742
|
export interface OverlayHandle {
|
|
692
743
|
/** null in 'window' mode — there is no backdrop to block the page. */
|
|
@@ -701,6 +752,14 @@ export interface OverlayHandle {
|
|
|
701
752
|
/** Replace the box's natural height (see `OverlayOptions.boxSize`) — applied
|
|
702
753
|
* now unless maximized or minimized, and restored to from either. */
|
|
703
754
|
setNaturalHeight: (height: string) => void;
|
|
755
|
+
/**
|
|
756
|
+
* Make room for `px` of extra content beside what the box already holds, by widening it, and
|
|
757
|
+
* return the function that takes that room back. Capped so the box stays on screen (a window is
|
|
758
|
+
* moved left if it would run off the edge), so it may give less than asked. Does nothing while
|
|
759
|
+
* maximised or collapsed, and releasing leaves a width the user has dragged the box to since.
|
|
760
|
+
* For a panel that opens beside a map, so the map keeps its size instead of giving it up.
|
|
761
|
+
*/
|
|
762
|
+
reserveWidth: (px: number) => () => void;
|
|
704
763
|
}
|
|
705
764
|
/** Create and open a resizable, maximizable, exclusive expand modal — dims and
|
|
706
765
|
* blocks the rest of the page. See `openFloatingWindow` for the non-modal form. */
|
|
@@ -797,6 +856,8 @@ export interface OverlayFlags {
|
|
|
797
856
|
showDieLabels?: boolean;
|
|
798
857
|
showReticle?: boolean;
|
|
799
858
|
showXYIndicator?: boolean;
|
|
859
|
+
/** Unset means "while zoomed", the default; see `WaferViewOptions.showAxes`. */
|
|
860
|
+
showAxes?: boolean;
|
|
800
861
|
passFailDisplay?: 'off' | 'spec' | 'test';
|
|
801
862
|
/**
|
|
802
863
|
* Moved here from the Colour scheme menu, where it had been the one entry
|
|
@@ -829,7 +890,14 @@ export declare function overlayMenuRows(flags: OverlayFlags, reticleEnabled: boo
|
|
|
829
890
|
hasLimits: boolean;
|
|
830
891
|
hasRecorded: boolean;
|
|
831
892
|
binMode: boolean;
|
|
832
|
-
}, apply: (patch: OverlayFlags) => void
|
|
893
|
+
}, apply: (patch: OverlayFlags) => void,
|
|
894
|
+
/** The compact layout toggle, for a host that offers it (a single map). */
|
|
895
|
+
compact?: {
|
|
896
|
+
on: boolean;
|
|
897
|
+
offered: boolean;
|
|
898
|
+
onChange: (on: boolean) => void;
|
|
899
|
+
onDiagnostics: () => void;
|
|
900
|
+
}): CheckMenuRow[];
|
|
833
901
|
/** Whether any overlay is on — the Overlays button's "active" state. Shared for
|
|
834
902
|
* the same reason as the rows: it enumerates the same five flags. */
|
|
835
903
|
export declare function anyOverlayActive(flags: OverlayFlags): boolean;
|
|
@@ -884,93 +952,6 @@ export declare function makeOrientationBtn(helpers: ToolbarHelpers, getOpts: ()
|
|
|
884
952
|
rotation?: 0 | 90 | 180 | 270;
|
|
885
953
|
flipX?: boolean;
|
|
886
954
|
flipY?: boolean;
|
|
955
|
+
showXYIndicator?: boolean;
|
|
887
956
|
}) => void): HTMLButtonElement;
|
|
888
|
-
type GuideApi = {
|
|
889
|
-
buildWaferMap: unknown;
|
|
890
|
-
renderWaferMap: unknown;
|
|
891
|
-
renderWaferGallery: unknown;
|
|
892
|
-
analyzeWaferMap: unknown;
|
|
893
|
-
};
|
|
894
|
-
/**
|
|
895
|
-
* Host-supplied content inserted into wmap's own embedded user-guide window,
|
|
896
|
-
* so a host app's own documentation and wmap's reference live behind one
|
|
897
|
-
* help button instead of two separate ones.
|
|
898
|
-
*/
|
|
899
|
-
export interface UserGuideExtension {
|
|
900
|
-
/**
|
|
901
|
-
* Host-provided HTML, inserted before wmap's own guide content. Static
|
|
902
|
-
* content only — must not contain `<script>` tags. wmap re-executes
|
|
903
|
-
* exactly one inline script (its own live-demo bootstrap, always the
|
|
904
|
-
* last element in `html`) by finding the content div's first
|
|
905
|
-
* `<script>` in document order; a `<script>` in this HTML would be
|
|
906
|
-
* found instead, silently breaking wmap's own live demos.
|
|
907
|
-
*/
|
|
908
|
-
html: string;
|
|
909
|
-
/**
|
|
910
|
-
* Overrides the window's title text (default `'Wafer Map — User Guide'`).
|
|
911
|
-
* Use this when the host's own content should frame the whole document —
|
|
912
|
-
* wmap's own `<h1>` stays as-is further down the page, so the result
|
|
913
|
-
* reads as one combined guide with the host's section first, not a title
|
|
914
|
-
* rewrite.
|
|
915
|
-
*/
|
|
916
|
-
title?: string;
|
|
917
|
-
}
|
|
918
|
-
/**
|
|
919
|
-
* Open the embedded user-guide window and populate its live demos. Closes any
|
|
920
|
-
* previously open guide window first (at most one may be open at a time).
|
|
921
|
-
* `api` must contain the four library functions the guide demos call at runtime.
|
|
922
|
-
* `html` is USER_GUIDE_HTML — passed in so toolbar.ts has no dependency on userGuideHtml.ts.
|
|
923
|
-
* `extension`, when provided, prepends host content and/or overrides the window title — see `UserGuideExtension`.
|
|
924
|
-
*
|
|
925
|
-
* Opens a real, separate window when available (draggable outside the host
|
|
926
|
-
* window's own bounds), falling back to the in-page floating window when
|
|
927
|
-
* `window.open` is blocked/unavailable — silently returns `null` in some
|
|
928
|
-
* embedded WebViews (Tauri, Electron, WebView2), same gap `openDetachWindow`
|
|
929
|
-
* exists for. Unlike gallery card detach, this doesn't go through
|
|
930
|
-
* `setDetachWindowOpener` — that opener's contract is scoped to per-wafer
|
|
931
|
-
* detach windows a host may have built specifically for that shape of
|
|
932
|
-
* content, and reusing it silently for the guide would broaden it without
|
|
933
|
-
* documentation.
|
|
934
|
-
*/
|
|
935
|
-
export declare function openUserGuideWindow(api: GuideApi, html: string, extension?: UserGuideExtension, anchor?: Element): void;
|
|
936
|
-
/**
|
|
937
|
-
* Opens wmap's own guide window with no live `WaferMapController`/
|
|
938
|
-
* `GalleryController` required — `WaferMapController.openUserGuide()`/
|
|
939
|
-
* `GalleryController.openUserGuide()` are thin wrappers around this exact
|
|
940
|
-
* same call (see their own `openGuideWindow` closures in `renderWaferMap.ts`/
|
|
941
|
-
* `renderWaferGallery.ts`), built from the library's own top-level functions
|
|
942
|
-
* rather than anything derived from a specific render — so a host with
|
|
943
|
-
* nothing rendered yet (e.g. an empty-state "Help" menu, before any file is
|
|
944
|
-
* loaded) can reach the same guide, with the same `extension` content, the
|
|
945
|
-
* same way. Prefer the controller method when one exists — this is for the
|
|
946
|
-
* gap it can't cover.
|
|
947
|
-
*
|
|
948
|
-
* `renderWaferMap`/`renderWaferGallery` are dynamically imported (like
|
|
949
|
-
* `USER_GUIDE_HTML` below) since `toolbar.ts` is itself imported BY both of
|
|
950
|
-
* them — a static import here would cycle back.
|
|
951
|
-
*/
|
|
952
|
-
export declare function openWaferMapGuide(extension?: UserGuideExtension, anchor?: Element): void;
|
|
953
|
-
/**
|
|
954
|
-
* Opens report HTML (from `renderSummaryReportHtml`/`renderLotSummaryReportHtml`)
|
|
955
|
-
* in an in-app modal — no host-registered `setReportOpener` required just to
|
|
956
|
-
* *view* a report. `setReportOpener`/`openHtmlReport` remain available as an
|
|
957
|
-
* "Open as full page" action inside this modal (its header's print button, plus
|
|
958
|
-
* a link in the toolbar strip below it), for a host that wants the report as a
|
|
959
|
-
* real separate page — to keep it open outside this modal, or as a fallback if
|
|
960
|
-
* in-app printing misbehaves on a given platform.
|
|
961
|
-
*
|
|
962
|
-
* The report HTML is a complete standalone document (its own `<style>`, its own
|
|
963
|
-
* `<!DOCTYPE html>`) — rendered via `<iframe srcdoc>` rather than parsed apart
|
|
964
|
-
* and inserted into the modal's own DOM (the way the guide's `buildGuideContent`
|
|
965
|
-
* does it). This keeps the report's stylesheet naturally isolated from the host
|
|
966
|
-
* page with no parsing, and lets `iframe.contentWindow.print()` scope printing
|
|
967
|
-
* to just the report — `openOverlay`'s sibling-hiding print stylesheet (built
|
|
968
|
-
* for content that lives directly in the host document, like the guide) isn't
|
|
969
|
-
* needed here and wouldn't reach into the iframe's own document anyway.
|
|
970
|
-
*/
|
|
971
|
-
export declare function openReportModal(html: string, opts?: {
|
|
972
|
-
anchor?: Element;
|
|
973
|
-
ownerDocument?: Document;
|
|
974
|
-
}): OverlayHandle;
|
|
975
|
-
export {};
|
|
976
957
|
//# sourceMappingURL=toolbar.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{getUniqueTestNumbers as ke}from"../renderer/buildView.js";import{dieHasValues as Ee}from"../core/dieTable.js";import{dieHasTestData as Ce}from"../renderer/buildWaferMap.js";import{testLabel as re,isDerivedTest as Le,DERIVED_MARK as ce,DERIVED_KEY as de}from"../renderer/testLabel.js";import{prettyKey as Ae}from"../core/utils.js";import{listBinColorSchemes as Me,listValueColorSchemes as Se}from"../renderer/colorSchemes.js";import{ICONS as W}from"./icons.js";import{WMAP_VERSION as Be,WMAP_BUILD_TIME as De}from"./version.js";import{openHtmlReport as Te}from"../stats/renderFindingsReport.js";import{buildWaferMap as He}from"../renderer/buildWaferMap.js";import{analyzeWaferMap as Ie}from"../stats/analyzeWaferMap.js";let ue=!1;export function logWmapVersionOnce(){ue||(ue=!0,console.log(`[wmap] v${Be} (built ${De})`))}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,t)=>`var(--wmap-${e}, ${t})`,K="var(--wmap-font-size, 12px)",$e="var(--wmap-density, 1)",F=e=>`calc(${e}px * ${$e})`;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:F(2),xs:F(4),sm:F(6),md:F(8),lg:F(10),xl:F(12),xxl:F(16),xxxl:F(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(${K} - 1px)`,body:K,sub:`calc(${K} + 1px)`,heading:`calc(${K} + 3px)`,stat:`calc(${K} + 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(),r=o?parseFloat(o):NaN;return(Number.isFinite(r)?r: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",k("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 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 r=n.getPropertyValue(`--wmap-${o}`).trim();r&&t.style.setProperty(`--wmap-${o}`,r)}}export function syncWmapPopupTheme(e,t,n){const o=()=>{copyWmapThemeTokens(e,t),n?.()},r=new window.MutationObserver(o);r.observe(e,{attributes:!0,attributeFilter:["style","class"]}),r.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const s=window.matchMedia("(prefers-color-scheme: dark)");return s.addEventListener("change",o),()=>{r.disconnect(),s.removeEventListener("change",o)}}let ae=null;export function setDetachWindowOpener(e){ae=e}export function openDetachWindow(e){return ae?ae(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}downloadBlob(e,o)}export function downloadBlob(e,t){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=t,o.click(),URL.revokeObjectURL(n)}export function saveTextFile(e,t,n,o){if(o){o(e,t,n);return}downloadBlob(new Blob([e],{type:n}),t)}const Oe='[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 r=t();if(r.length===0)return;const s=e.ownerDocument.activeElement,p=s?r.indexOf(s):-1;switch(o.key){case"ArrowDown":o.preventDefault(),r[p<0||p===r.length-1?0:p+1].focus();break;case"ArrowUp":o.preventDefault(),r[p<=0?r.length-1:p-1].focus();break;case"Home":o.preventDefault(),r[0].focus();break;case"End":o.preventDefault(),r[r.length-1].focus();break;case"Enter":case" ":p>=0&&(o.preventDefault(),r[p].click());break;case"Escape":case"Tab":o.preventDefault(),n();break}})}function J(e,t,n){const o=()=>Array.from(e.querySelectorAll(Oe));wireListNavigation(e,o,()=>{n(),t?.focus()});const r=o()[0];r&&nextFrame(()=>r.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 pe=new WeakMap;export function menuLayerFor(e){const t=overlayRootFor(e),n=pe.get(t);if(n&&n.isConnected)return n;const r=e.ownerDocument.createElement("div");return r.dataset.wmapMenuLayer="1",Object.assign(r.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),t.appendChild(r),pe.set(t,r),r}const se=new WeakMap;export function getTooltip(e=document){const t=se.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_ABOVE2,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),se.set(e,n)),e.body.appendChild(n),n}export function hideTooltip(e=document){const t=se.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,r={}){const s=menuLayerFor(t);e.parentElement!==s&&s.appendChild(e);const p=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const i=e.offsetWidth,b=e.offsetHeight,d=8,l=p.innerWidth,y=p.innerHeight;let a=n+14,f=o-8;a+i+d>l&&(a=n-i-6);const x=t.getBoundingClientRect();if(!r.followPointer&&x.height>0&&x.height<=y*.4&&f<x.bottom&&f+b>x.top&&a<x.right&&a+i>x.left){const u=x.bottom+d,h=x.top-b-d;u+b+d<=y?f=u:h>=d&&(f=h)}f+b+d>y&&(f=y-b-d),f<d&&(f=d),e.style.left=`${a}px`,e.style.top=`${f}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 r=p=>{const i=o();if(!i)return;const b=getTooltip(e.ownerDocument);if(b.textContent=i,b.style.display="block",p)positionTooltip(b,e,p.clientX,p.clientY);else{const d=e.getBoundingClientRect();positionTooltip(b,e,d.left+d.width/2,d.top)}},s=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",r),e.addEventListener("mouseleave",s),e.addEventListener("focus",()=>r()),e.addEventListener("blur",s)}export function buildDataModeEntries(e,t,n){const o=e.some(Ce),r=e.some(Ee),s=e.some(l=>l.hbin!=null),p=e.some(l=>l.sbin!=null),i=o?t!==void 0?t.map(l=>({plotMode:"value",activeTest:l.testNumber,label:l.unit?`${re(l,l.testNumber)} (${l.unit})`:re(l,l.testNumber),logScale:l.logScale,...Le(l)?{derived:!0}:{}})):ke(e).map(l=>({plotMode:"value",activeTest:l,label:re(void 0,l)})):[],b=[...s?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...p?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],d=n.includeStacked?[...r?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...s?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...p?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:i,binEntries:b,stackedEntries:d}}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??Ae(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",r=>r.stopPropagation()),o.addEventListener("mousedown",r=>r.stopPropagation()),o.addEventListener("keydown",r=>r.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,r,s,p,i,b=window,d=[]){const{makeMenuRow:l,makeMenuSection:y}=p,a=document.createElement("div"),f=180,c=e.left+f<=(b.innerWidth??1/0)?e.left:Math.max(4,e.right-f);if(Object.assign(a.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${c}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(a.appendChild(y("Test Value")),t.length<=INLINE_TEST_LIMIT)for(const m of t)a.appendChild(l(m.label,r(m),!0,u=>{u.stopPropagation(),s(m,a)}));else{const m=i==="value",u=l(MODE_LABELS.value+" \u25B6",m,!1,g=>{g.stopPropagation(),A(),S(),g.detail===0&&T()});u.setAttribute("aria-haspopup","menu"),u.style.display="flex",u.style.justifyContent="space-between",u.style.alignItems="center";let h=null,w=null;const A=()=>{w!==null&&(clearTimeout(w),w=null)},E=g=>{const B=g.target;B&&(u.contains(B)||h?.contains(B))||C()},C=()=>{A(),h?.remove(),h=null,b.document.removeEventListener("click",E),u.setAttribute("aria-expanded","false")},T=()=>{const g=h?.querySelector('input, [role="menuitemradio"]');g&&nextFrame(()=>g.focus(),b)},D=()=>{A(),w=setTimeout(C,300)},S=()=>{if(h)return;const g=u.getBoundingClientRect(),B=160,V=320,I=g.right+2+B<=(b.innerWidth??1/0)?g.right+2:Math.max(4,g.left-2-B),Y=Math.min(g.top-4,Math.max(4,(b.innerHeight??1/0)-V-4));if(h=document.createElement("div"),h.setAttribute("data-wmap-submenu",""),h.setAttribute("role","menu"),Object.assign(h.style,{position:"fixed",top:`${Y}px`,left:`${I}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${B}px`,maxHeight:`${V}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),t.length>MENU_SEARCH_THRESHOLD){const L=makeMenuSearchBox(U=>{for(const O of $)O.row.style.display=O.label.includes(U)?"":"none"},"Filter tests\u2026");Object.assign(L.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),h.appendChild(L)}const $=[],M=t.some(L=>L.derived);for(const L of t){const U=l(L.label,r(L),!1,O=>{O.stopPropagation(),C(),s(L,a)},M?{derived:L.derived===!0}:void 0);$.push({row:U,label:L.label.toLowerCase()}),h.appendChild(U)}if(M){const L=b.document.createElement("div");L.setAttribute("role","presentation"),L.textContent=`${ce} ${de}`,Object.assign(L.style,{padding:"6px 14px",fontSize:FONT.meta,color:CLR.label,borderTop:`1px solid ${CLR.menuBorder}`,marginTop:"4px",whiteSpace:"nowrap"}),h.appendChild(L)}h.addEventListener("mouseenter",A),h.addEventListener("mouseleave",D),wireListNavigation(h,()=>$.filter(L=>L.row.style.display!=="none").map(L=>L.row),()=>{C(),u.focus()}),(a.parentElement??b.document.body).appendChild(h),b.document.addEventListener("click",E),u.setAttribute("aria-expanded","true")};a.addEventListener("keydown",g=>{g.key==="Escape"&&C()}),u.addEventListener("mouseenter",()=>{A(),S()}),u.addEventListener("mouseleave",D),a.appendChild(u)}if(n.length){a.appendChild(y("Bins"));for(const m of n)a.appendChild(l(m.label,r(m),!1,u=>{u.stopPropagation(),s(m,a)}))}if(d.length){a.appendChild(y("Metadata"));for(const m of d)a.appendChild(l(m.label,r(m),!1,u=>{u.stopPropagation(),s(m,a)}))}if(o.length){a.appendChild(y("Lot Aggregation"));for(const m of o)a.appendChild(l(m.label,r(m),!1,u=>{u.stopPropagation(),s(m,a)}))}return a.setAttribute("role","menu"),a.setAttribute("aria-label","Plot mode"),a}export function markMenuTrigger(e,t){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",t?"true":"false")}export function wireMenuA11y(e,t,n){J(e,t,n)}export function wireExpandToggle(e,t){const n=e.ownerDocument;let o=!1;function r(d){o!==d&&(o=d,t(o))}function s(){r(!1)}function p(){r(!o),o&&n.addEventListener("click",s,{once:!0})}const i=d=>{d.stopPropagation(),p()},b=d=>{d.key==="Enter"||d.key===" "?(d.preventDefault(),p()):d.key==="Escape"&&s()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",i),e.addEventListener("keydown",b),{isOpen:()=>o,close:s,destroy(){e.removeEventListener("click",i),e.removeEventListener("keydown",b),n.removeEventListener("click",s)}}}export function buildCheckMenuEl(e,t,n,o=window){const{makeMenuSection:r}=n,s=o.document,p=s.createElement("div"),i=168,d=e.left+i<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-i);Object.assign(p.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:`${i}px`,padding:"4px 0",pointerEvents:"auto"});for(const l of t)if("section"in l)p.appendChild(r(l.section));else{const y=l.enabled!==!1;if(!y&&!l.disabledHint)continue;const a=s.createElement("div");l.action?a.setAttribute("role","menuitem"):(a.setAttribute("role","menuitemcheckbox"),a.setAttribute("aria-checked",l.active?"true":"false")),a.tabIndex=-1,y||(a.setAttribute("aria-disabled","true"),wireTooltip(a,l.disabledHint)),Object.assign(a.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:y?"pointer":"default",color:y?l.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:l.active?"700":"400",background:l.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const f=s.createElement("span");Object.assign(f.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:l.active?"visible":"hidden"}),f.textContent=l.action?"":"\u2713",f.setAttribute("aria-hidden","true");const x=s.createElement("span");x.textContent=l.label,a.appendChild(f),a.appendChild(x),y?(a.addEventListener("mouseenter",()=>{l.active||(a.style.background=CLR.menuHover)}),a.addEventListener("mouseleave",()=>{a.style.background=l.active?CLR.menuActive:"transparent"}),a.addEventListener("focus",()=>{l.active||(a.style.background=CLR.menuHover)}),a.addEventListener("blur",()=>{a.style.background=l.active?CLR.menuActive:"transparent"}),a.addEventListener("click",c=>{c.stopPropagation(),l.onClick(c)})):a.addEventListener("click",c=>{c.stopPropagation()}),p.appendChild(a)}return p}export function createToolbarHelpers(e){const t=e.ownerDocument;let n=null;const o=a=>menuLayerFor(a);function r(a,f,x){const c=t.createElement("button");return c.innerHTML=W[a],c.type="button",c.ariaLabel=f,Object.assign(c.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"}),c.addEventListener("mouseenter",m=>{c.dataset.active||(c.style.background=CLR.bgHover,c.style.color=CLR.iconHover),e.textContent=c.ariaLabel??f,e.style.display="block",positionTooltip(e,c,m.clientX,m.clientY)}),c.addEventListener("mousemove",m=>{e.style.display==="block"&&positionTooltip(e,c,m.clientX,m.clientY)}),c.addEventListener("mouseleave",()=>{c.dataset.active||(c.style.background="transparent",c.style.color=CLR.icon),e.style.display="none"}),c.addEventListener("click",()=>{e.style.display="none",x()}),c}function s(a,f){f?(a.dataset.active="1",a.style.background=CLR.bgActive,a.style.color=CLR.iconActive):(delete a.dataset.active,a.style.background="transparent",a.style.color=CLR.icon)}function p(){const a=t.createElement("div");return Object.assign(a.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),a}function i(a,f,x,c,m){const u=t.createElement("div");if(m){const h=t.createElement("span");h.textContent=m.derived?ce:"",h.setAttribute("aria-hidden","true"),Object.assign(h.style,{display:"inline-block",width:"1.1em"}),u.append(h,a),m.derived&&u.setAttribute("aria-label",`${a} \u2014 ${de.toLowerCase()}`)}else u.textContent=a;return u.setAttribute("role","menuitemradio"),u.setAttribute("aria-checked",f?"true":"false"),u.tabIndex=-1,Object.assign(u.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"}),u.addEventListener("mouseenter",()=>{f||(u.style.background=CLR.menuHover)}),u.addEventListener("mouseleave",()=>{u.style.background=f?CLR.menuActive:"transparent"}),u.addEventListener("focus",()=>{f||(u.style.background=CLR.menuHover)}),u.addEventListener("blur",()=>{u.style.background=f?CLR.menuActive:"transparent"}),u.addEventListener("click",c),u}function b(a){const f=t.createElement("div");return f.textContent=a,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 d(a,f,x,c,m){const u=()=>{n&&(n.remove(),n=null),h.setAttribute("aria-expanded","false")},h=r(a,f,()=>{if(n){u();return}const w=t.createElement("div"),A=h.getBoundingClientRect(),E=h.ownerDocument.defaultView??window,C=148,D=A.left+C<=(E.innerWidth??1/0)?A.left:Math.max(4,A.right-C);Object.assign(w.style,{position:"fixed",top:`${A.bottom+4}px`,left:`${D}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${C}px`,padding:"4px 0",pointerEvents:"auto"});for(const S of x()){const g=t.createElement("div");g.textContent=S.label,g.dataset.wmapDropdownValue=S.value;const B=S.value===c();g.setAttribute("role","menuitemradio"),g.setAttribute("aria-checked",B?"true":"false"),g.tabIndex=-1,Object.assign(g.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:B?CLR.iconActive:CLR.text,fontWeight:B?"700":"400",background:B?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const V=()=>{S.value!==c()&&(g.style.background=CLR.menuHover)},z=()=>{g.style.background=S.value===c()?CLR.menuActive:"transparent"};g.addEventListener("mouseenter",V),g.addEventListener("mouseleave",z),g.addEventListener("focus",V),g.addEventListener("blur",z),g.addEventListener("click",I=>{I.stopPropagation(),m(S.value),u()}),w.appendChild(g)}w.setAttribute("role","menu"),w.setAttribute("aria-label",f),o(h).appendChild(w),n=w,h.setAttribute("aria-expanded","true"),J(w,h,u)});return h.setAttribute("aria-haspopup","menu"),h.setAttribute("aria-expanded","false"),h}function l(a,f,x,c){function m(){return buildCheckMenuEl(h.getBoundingClientRect(),x().map(w=>"section"in w?w:{...w,onClick:A=>{w.onClick(A),c(h);const E=n;if(!E)return;const C=m();C.setAttribute("role","menu"),C.setAttribute("aria-label",f),E.replaceWith(C),n=C,J(C,h,u)}}),{makeMenuSection:b},h.ownerDocument.defaultView??window)}const u=()=>{n&&(n.remove(),n=null),h.setAttribute("aria-expanded","false")},h=r(a,f,()=>{if(n){u();return}const w=m();w.setAttribute("role","menu"),w.setAttribute("aria-label",f),o(h).appendChild(w),n=w,h.setAttribute("aria-expanded","true"),J(w,h,u)});return h.setAttribute("aria-haspopup","menu"),h.setAttribute("aria-expanded","false"),c(h),h}function y(a){const f=a.target?.closest?.("[data-wmap-submenu]");if(n&&!n.contains(a.target)&&!f&&(n.remove(),n=null,a.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const c of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))c.setAttribute("aria-expanded","false")}return{makeBtn:r,setActive:s,makeSep:p,makeMenuRow:i,makeMenuSection:b,makeDropdown:d,makeCheckMenuBtn:l,closeOpenMenu:y,getOpenMenu:()=>n,setOpenMenu:a=>{n=a}}}const Re=7e3;let We=0;function fe(){return Re+ ++We}const ze=32,_e=6;let Ne=0;function Pe(){return Ne++%_e*ze}function Fe(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 me(e){const t=e.mode==="modal",n=e.ownerDocument??document,o=n.defaultView??window,r=n.body.style.overflow;t&&(n.body.style.overflow="hidden");let s=null;t&&(s=n.createElement("div"),s.id="wmap-modal-backdrop",Object.assign(s.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 p=n.activeElement,i=n.createElement("div");i.className=t?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",i.setAttribute("role","dialog"),t&&i.setAttribute("aria-modal","true"),i.setAttribute("aria-label",e.title??"Expanded wafer map"),i.tabIndex=-1;const b=e.boxSize?.width??"min(90vw, 700px)";let d=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(i.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:b,height:d,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:t?Z_ABOVE2:String(fe())}),!t){const v=Pe();Object.assign(i.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+v}px`,left:`${Math.round(o.innerWidth*.08)+v}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 y={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 v=n.createElement("span");v.textContent=e.title,v.title=e.title,v.dataset.wmapWindowTitle="1",Object.assign(v.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),l.appendChild(v)}const a=n.createElement("div");a.style.flex="1",l.appendChild(a);let f=null;t||(f=n.createElement("button"),f.type="button",f.innerHTML=W.collapse,f.setAttribute("aria-label","Collapse"),wireTooltip(f),Object.assign(f.style,y),wireControlHover(f),f.addEventListener("click",()=>S(!E)),l.appendChild(f));let x=null;e.printable&&(x=n.createElement("button"),x.type="button",x.innerHTML=W.print,x.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(x),Object.assign(x.style,y),wireControlHover(x),x.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),l.appendChild(x));const c=n.createElement("button");c.type="button",c.innerHTML=W.maximize,c.setAttribute("aria-label","Maximize (F)"),wireTooltip(c),Object.assign(c.style,y),wireControlHover(c),c.addEventListener("click",()=>A(!u));const m=n.createElement("button");m.type="button",m.innerHTML=W.close,m.setAttribute("aria-label","Close (Esc)"),wireTooltip(m),Object.assign(m.style,y),wireControlHover(m),m.addEventListener("click",I),l.appendChild(c),l.appendChild(m);let u=!1,h="",w="";function A(v){u=v,c.innerHTML=u?W.minimize:W.maximize,c.setAttribute("aria-label",u?"Restore (F)":"Maximize (F)"),f&&(f.style.display=u?"none":""),M.style.display=u?"none":"block",u?(i.style.borderRadius="0",i.style.width="100vw",i.style.height="100vh",t||(h=i.style.top,w=i.style.left,i.style.top="0",i.style.left="0")):(i.style.borderRadius="12px",i.style.width=b,i.style.height=d,t||(i.style.top=h,i.style.left=w)),e.onMaximizeChange?.(u,i)}let E=!1,C="",T="";const D=220;function S(v){E=v,f.innerHTML=E?W.uncollapse:W.collapse,f.setAttribute("aria-label",E?"Show contents":"Collapse"),M.style.display=E?"none":"block",E?(C=i.style.height,T=i.style.width,i.style.minHeight="0",i.style.height="auto",i.style.minWidth="0",i.style.width=`${D}px`,c.disabled=!0,c.style.opacity="0.4",c.style.cursor="default",$.style.display="none"):(i.style.minHeight="240px",i.style.height=C||d,i.style.minWidth="320px",i.style.width=T||b,c.disabled=!1,c.style.opacity="1",c.style.cursor="pointer",$.style.display="flex")}function g(){const v=n.body.style.userSelect;return n.body.style.userSelect="none",()=>{n.body.style.userSelect=v}}t||(l.style.cursor="move",l.addEventListener("pointerdown",v=>{if(u||v.target.closest('button, [role="button"]'))return;v.preventDefault();const H=g(),_=v.clientX,N=v.clientY,R=i.offsetTop,P=i.offsetLeft,ne=o.innerHeight-l.offsetHeight,oe=o.innerWidth-40,Q=40-i.offsetWidth;l.setPointerCapture(v.pointerId);const q=X=>{const ie=Math.min(Math.max(R+(X.clientY-N),0),ne),we=Math.min(Math.max(P+(X.clientX-_),Q),oe);i.style.top=`${ie}px`,i.style.left=`${we}px`},G=X=>{H(),l.releasePointerCapture(X.pointerId),l.removeEventListener("pointermove",q),l.removeEventListener("pointerup",G)};l.addEventListener("pointermove",q),l.addEventListener("pointerup",G)}));const B='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function V(v){const H=Array.from(i.querySelectorAll(B)).filter(P=>P.offsetParent!==null||P===n.activeElement);if(H.length===0){v.preventDefault(),i.focus();return}const _=H[0],N=H[H.length-1],R=n.activeElement;v.shiftKey&&(R===_||!i.contains(R))?(v.preventDefault(),N.focus()):!v.shiftKey&&R===N&&(v.preventDefault(),_.focus())}const z=v=>{if(v.key==="Escape"){I();return}if(t&&(v.key==="e"||v.key==="E")){I();return}if(t&&v.key==="Tab"){V(v);return}(v.key==="f"||v.key==="F")&&!E&&A(!u)};function I(){t?n.removeEventListener("keydown",z):i.removeEventListener("keydown",z),te.remove(),ge(),hideTooltip(n),reparentTooltip(n.body),s?s.remove():i.remove(),t&&(n.body.style.overflow=r),p?.focus?.(),e.onClose()}function Y(){t||(i.style.zIndex=String(fe()))}const $=n.createElement("div");Object.assign($.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const M=n.createElement("div");M.tabIndex=0,M.setAttribute("role","separator"),M.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(M.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),M.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>',M.style.color=CLR.label;const L=320,U=240,O=20;function Z(v,H){const _=o.innerWidth-i.offsetLeft,N=o.innerHeight-i.offsetTop,R=Math.min(Math.max(i.offsetWidth+v,L),_),P=Math.min(Math.max(i.offsetHeight+H,U),N);i.style.width=`${R}px`,i.style.height=`${P}px`}M.addEventListener("keydown",v=>{if(!(u||E))switch(v.key){case"ArrowRight":v.preventDefault(),Z(O,0);break;case"ArrowLeft":v.preventDefault(),Z(-O,0);break;case"ArrowDown":v.preventDefault(),Z(0,O);break;case"ArrowUp":v.preventDefault(),Z(0,-O);break}}),M.addEventListener("pointerdown",v=>{if(u||E)return;v.preventDefault();const H=g(),_=v.clientX,N=v.clientY,R=i.offsetWidth,P=i.offsetHeight,ne=o.innerWidth-i.offsetLeft,oe=o.innerHeight-i.offsetTop;M.setPointerCapture(v.pointerId);const Q=G=>{const X=Math.min(Math.max(R+(G.clientX-_),L),ne),ie=Math.min(Math.max(P+(G.clientY-N),U),oe);i.style.width=`${X}px`,i.style.height=`${ie}px`},q=G=>{H(),M.releasePointerCapture(G.pointerId),M.removeEventListener("pointermove",Q),M.removeEventListener("pointerup",q)};M.addEventListener("pointermove",Q),M.addEventListener("pointerup",q)}),i.appendChild(l),i.appendChild($),i.appendChild(M);const ee=e.anchor?overlayRootFor(e.anchor):n.body;s?(s.appendChild(i),ee.appendChild(s)):ee.appendChild(i);const ge=Fe(n,ee),te=n.createElement("style");te.textContent=`@media print{
|
|
1
|
+
import{getUniqueTestNumbers as we}from"../renderer/buildView.js";import{dieHasValues as ke}from"../core/dieTable.js";import{dieHasTestData as Ee}from"../renderer/buildWaferMap.js";import{testLabel as ae,isDerivedTest as Ce,DERIVED_MARK as ce,DERIVED_KEY as de}from"../renderer/testLabel.js";import{prettyKey as Le}from"../core/utils.js";import{diagnoseMpwLayout as Ae,formatMpwDiagnostics as Me}from"../core/compact.js";import{listBinColorSchemes as Se,listValueColorSchemes as Be}from"../renderer/colorSchemes.js";import{ICONS as R}from"./icons.js";import{WMAP_VERSION as ue,WMAP_BUILD_TIME as De}from"./version.js";let pe=!1;export function logWmapVersionOnce(){pe||(pe=!0,console.log(`[wmap] v${ue} (built ${De})`))}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,t)=>`var(--wmap-${e}, ${t})`,Q="var(--wmap-font-size, 12px)",Te="var(--wmap-density, 1)",F=e=>`calc(${e}px * ${Te})`;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:F(2),xs:F(4),sm:F(6),md:F(8),lg:F(10),xl:F(12),xxl:F(16),xxxl:F(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(${Q} - 1px)`,body:Q,sub:`calc(${Q} + 1px)`,heading:`calc(${Q} + 3px)`,stat:`calc(${Q} + 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(),a=o?parseFloat(o):NaN;return(Number.isFinite(a)?a: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",k("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 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 a=n.getPropertyValue(`--wmap-${o}`).trim();a&&t.style.setProperty(`--wmap-${o}`,a)}}export function syncWmapPopupTheme(e,t,n){const o=()=>{copyWmapThemeTokens(e,t),n?.()},a=new window.MutationObserver(o);a.observe(e,{attributes:!0,attributeFilter:["style","class"]}),a.observe(document.documentElement,{attributes:!0,attributeFilter:["style","class"]});const l=window.matchMedia("(prefers-color-scheme: dark)");return l.addEventListener("change",o),()=>{a.disconnect(),l.removeEventListener("change",o)}}let re=null;export function setDetachWindowOpener(e){re=e}export function openDetachWindow(e){return re?re(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}downloadBlob(e,o)}export function markNoPrint(e){e.setAttribute("data-wmap-noprint","1");const t=e.ownerDocument;if(!t.getElementById("wmap-noprint-style")){const n=t.createElement("style");n.id="wmap-noprint-style",n.textContent="@media print{[data-wmap-noprint]{display:none!important}}",t.head.appendChild(n)}}export function downloadBlob(e,t){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=t,o.click(),URL.revokeObjectURL(n)}export function roomForPanel(e){let t=null;return(n,o)=>{t?.(),t=n?e.reserveWidth(o):null}}export function openCompactDiagnostics(e,t,n){const o=Me(Ae(e,t),ue),a=n.anchor.ownerDocument,l=openModal({title:"Layout diagnostics",anchor:n.anchor,ownerDocument:a,onClose:()=>{},boxSize:{width:"min(680px, 94vw)",height:"min(480px, 90vh)"}}),x=l.contentWrap;Object.assign(x.style,{flexDirection:"column",padding:"14px 16px",gap:"10px",boxSizing:"border-box"});const i=a.createElement("p");i.textContent="This is everything the compact layout looked at. It holds counts and scores only: no die positions, bins, test values or wafer names. If the layout was not detected the way you expect, send it to whoever supports this software.",Object.assign(i.style,{margin:"0",fontSize:FONT.body,color:CLR.text,lineHeight:"1.4"});const f=a.createElement("textarea");f.value=o,f.readOnly=!0,f.setAttribute("aria-label","Layout diagnostics"),Object.assign(f.style,{flex:"1",minHeight:"0",resize:"none",fontFamily:"ui-monospace, monospace",fontSize:FONT.body,padding:"8px",border:`1px solid ${CLR.separator}`,borderRadius:RADIUS.control,color:CLR.text,background:CLR.menuBg});const u=a.createElement("div");Object.assign(u.style,{display:"flex",gap:"8px",alignItems:"center"});const s=a.createElement("span");s.setAttribute("role","status"),Object.assign(s.style,{fontSize:FONT.body,color:CLR.text});const C=(y,p)=>{const m=a.createElement("button");return m.type="button",m.textContent=y,Object.assign(m.style,controlStyle("outlined"),{padding:"5px 12px",color:CLR.text}),wireControlHover(m,"outlined"),m.addEventListener("click",p),m},r=C("Copy",()=>{const y=a.defaultView,p=()=>{f.focus(),f.select();let m=!1;try{m=a.execCommand("copy")}catch{m=!1}s.textContent=m?"Copied":"Copying is not available here. Select the text, or save it as a file."};y?.navigator.clipboard?y.navigator.clipboard.writeText(o).then(()=>{s.textContent="Copied"},p):p()}),d=C("Save as file",()=>{saveTextFile(o,"wafermap-layout-diagnostics.txt","text/plain",n.onSaveText),s.textContent=n.onSaveText?"":"Saved"});return u.append(r,d,s),x.append(i,f,u),f.focus(),f.select(),l}export function saveTextFile(e,t,n,o){if(o){o(e,t,n);return}downloadBlob(typeof e=="string"?new Blob([e],{type:n}):e,t)}const He='[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 a=t();if(a.length===0)return;const l=e.ownerDocument.activeElement,x=l?a.indexOf(l):-1;switch(o.key){case"ArrowDown":o.preventDefault(),a[x<0||x===a.length-1?0:x+1].focus();break;case"ArrowUp":o.preventDefault(),a[x<=0?a.length-1:x-1].focus();break;case"Home":o.preventDefault(),a[0].focus();break;case"End":o.preventDefault(),a[a.length-1].focus();break;case"Enter":case" ":x>=0&&(o.preventDefault(),a[x].click());break;case"Escape":case"Tab":o.preventDefault(),n();break}})}function te(e,t,n){const o=()=>Array.from(e.querySelectorAll(He));wireListNavigation(e,o,()=>{n(),t?.focus()});const a=o()[0];a&&nextFrame(()=>a.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 fe=new WeakMap;export function menuLayerFor(e){const t=overlayRootFor(e),n=fe.get(t);if(n&&n.isConnected)return n;const a=e.ownerDocument.createElement("div");return a.dataset.wmapMenuLayer="1",Object.assign(a.style,{position:"fixed",inset:"0",zIndex:Z_MENU,pointerEvents:"none"}),t.appendChild(a),fe.set(t,a),a}const se=new WeakMap;export function getTooltip(e=document){const t=se.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_ABOVE2,display:"none",fontFamily:FONT.family,boxShadow:SHADOW.menu}),se.set(e,n)),e.body.appendChild(n),n}export function hideTooltip(e=document){const t=se.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,a={}){const l=menuLayerFor(t);e.parentElement!==l&&l.appendChild(e);const x=e.ownerDocument.defaultView??window;e.style.left="0",e.style.top="0";const i=e.offsetWidth,f=e.offsetHeight,u=8,s=x.innerWidth,C=x.innerHeight;let r=n+14,d=o-8;r+i+u>s&&(r=n-i-6);const y=t.getBoundingClientRect();if(!a.followPointer&&y.height>0&&y.height<=C*.4&&d<y.bottom&&d+f>y.top&&r<y.right&&r+i>y.left){const h=y.bottom+u,c=y.top-f-u;h+f+u<=C?d=h:c>=u&&(d=c)}d+f+u>C&&(d=C-f-u),d<u&&(d=u),e.style.left=`${r}px`,e.style.top=`${d}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 a=x=>{const i=o();if(!i)return;const f=getTooltip(e.ownerDocument);if(f.textContent=i,f.style.display="block",x)positionTooltip(f,e,x.clientX,x.clientY);else{const u=e.getBoundingClientRect();positionTooltip(f,e,u.left+u.width/2,u.top)}},l=()=>hideTooltip(e.ownerDocument);e.addEventListener("mousemove",a),e.addEventListener("mouseleave",l),e.addEventListener("focus",()=>a()),e.addEventListener("blur",l)}export function buildDataModeEntries(e,t,n){const o=e.some(Ee),a=e.some(ke),l=e.some(s=>s.hbin!=null),x=e.some(s=>s.sbin!=null),i=o?t!==void 0?t.map(s=>({plotMode:"value",activeTest:s.testNumber,label:s.unit?`${ae(s,s.testNumber)} (${s.unit})`:ae(s,s.testNumber),logScale:s.logScale,...Ce(s)?{derived:!0}:{}})):we(e).map(s=>({plotMode:"value",activeTest:s,label:ae(void 0,s)})):[],f=[...l?[{plotMode:"hardBin",label:MODE_LABELS.hardBin}]:[],...x?[{plotMode:"softBin",label:MODE_LABELS.softBin}]:[]],u=n.includeStacked?[...a?[{plotMode:"stackedValues",label:MODE_LABELS.stackedValues}]:[],...l?[{plotMode:"stackedBins",label:MODE_LABELS.stackedBins}]:[],...x?[{plotMode:"stackedSoftBins",label:MODE_LABELS.stackedSoftBins}]:[]]:[];return{testEntries:i,binEntries:f,stackedEntries:u}}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??Le(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",a=>a.stopPropagation()),o.addEventListener("mousedown",a=>a.stopPropagation()),o.addEventListener("keydown",a=>a.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,a,l,x,i,f=window,u=[]){const{makeMenuRow:s,makeMenuSection:C}=x,r=document.createElement("div"),d=180,p=e.left+d<=(f.innerWidth??1/0)?e.left:Math.max(4,e.right-d);if(Object.assign(r.style,{position:"fixed",top:`${e.bottom+4}px`,left:`${p}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${d}px`,padding:"4px 0",pointerEvents:"auto"}),t.length)if(r.appendChild(C("Test Value")),t.length<=INLINE_TEST_LIMIT)for(const m of t)r.appendChild(s(m.label,a(m),!0,h=>{h.stopPropagation(),l(m,r)}));else{const m=i==="value",h=s(MODE_LABELS.value+" \u25B6",m,!1,g=>{g.stopPropagation(),L(),D(),g.detail===0&&Z()});h.setAttribute("aria-haspopup","menu"),h.style.display="flex",h.style.justifyContent="space-between",h.style.alignItems="center";let c=null,E=null;const L=()=>{E!==null&&(clearTimeout(E),E=null)},H=g=>{const A=g.target;A&&(h.contains(A)||c?.contains(A))||w()},w=()=>{L(),c?.remove(),c=null,f.document.removeEventListener("click",H),h.setAttribute("aria-expanded","false")},Z=()=>{const g=c?.querySelector('input, [role="menuitemradio"]');g&&nextFrame(()=>g.focus(),f)},N=()=>{L(),E=setTimeout(w,300)},D=()=>{if(c)return;const g=h.getBoundingClientRect(),A=160,_=320,$=g.right+2+A<=(f.innerWidth??1/0)?g.right+2:Math.max(4,g.left-2-A),j=Math.min(g.top-4,Math.max(4,(f.innerHeight??1/0)-_-4));if(c=document.createElement("div"),c.setAttribute("data-wmap-submenu",""),c.setAttribute("role","menu"),Object.assign(c.style,{position:"fixed",top:`${j}px`,left:`${$}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_ABOVE,minWidth:`${A}px`,maxHeight:`${_}px`,overflowY:"auto",padding:"4px 0",pointerEvents:"auto"}),t.length>MENU_SEARCH_THRESHOLD){const v=makeMenuSearchBox(Y=>{for(const X of V)X.row.style.display=X.label.includes(Y)?"":"none"},"Filter tests\u2026");Object.assign(v.style,{position:"sticky",top:"0",zIndex:"1",background:CLR.menuBg}),c.appendChild(v)}const V=[],W=t.some(v=>v.derived);for(const v of t){const Y=s(v.label,a(v),!1,X=>{X.stopPropagation(),w(),l(v,r)},W?{derived:v.derived===!0}:void 0);V.push({row:Y,label:v.label.toLowerCase()}),c.appendChild(Y)}if(W){const v=f.document.createElement("div");v.setAttribute("role","presentation"),v.textContent=`${ce} ${de}`,Object.assign(v.style,{padding:"6px 14px",fontSize:FONT.meta,color:CLR.label,borderTop:`1px solid ${CLR.menuBorder}`,marginTop:"4px",whiteSpace:"nowrap"}),c.appendChild(v)}c.addEventListener("mouseenter",L),c.addEventListener("mouseleave",N),wireListNavigation(c,()=>V.filter(v=>v.row.style.display!=="none").map(v=>v.row),()=>{w(),h.focus()}),(r.parentElement??f.document.body).appendChild(c),f.document.addEventListener("click",H),h.setAttribute("aria-expanded","true")};r.addEventListener("keydown",g=>{g.key==="Escape"&&w()}),h.addEventListener("mouseenter",()=>{L(),D()}),h.addEventListener("mouseleave",N),r.appendChild(h)}if(n.length){r.appendChild(C("Bins"));for(const m of n)r.appendChild(s(m.label,a(m),!1,h=>{h.stopPropagation(),l(m,r)}))}if(u.length){r.appendChild(C("Metadata"));for(const m of u)r.appendChild(s(m.label,a(m),!1,h=>{h.stopPropagation(),l(m,r)}))}if(o.length){r.appendChild(C("Lot Aggregation"));for(const m of o)r.appendChild(s(m.label,a(m),!1,h=>{h.stopPropagation(),l(m,r)}))}return r.setAttribute("role","menu"),r.setAttribute("aria-label","Plot mode"),r}export function markMenuTrigger(e,t){e.setAttribute("aria-haspopup","menu"),e.setAttribute("aria-expanded",t?"true":"false")}export function wireMenuA11y(e,t,n){te(e,t,n)}export function wireExpandToggle(e,t){const n=e.ownerDocument;let o=!1;function a(u){o!==u&&(o=u,t(o))}function l(){a(!1)}function x(){a(!o),o&&n.addEventListener("click",l,{once:!0})}const i=u=>{u.stopPropagation(),x()},f=u=>{u.key==="Enter"||u.key===" "?(u.preventDefault(),x()):u.key==="Escape"&&l()};return e.setAttribute("role","button"),e.tabIndex<0&&(e.tabIndex=0),e.addEventListener("click",i),e.addEventListener("keydown",f),{isOpen:()=>o,close:l,destroy(){e.removeEventListener("click",i),e.removeEventListener("keydown",f),n.removeEventListener("click",l)}}}export function buildCheckMenuEl(e,t,n,o=window){const{makeMenuSection:a}=n,l=o.document,x=l.createElement("div"),i=168,u=e.left+i<=(o.innerWidth??1/0)?e.left:Math.max(4,e.right-i);Object.assign(x.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:`${i}px`,padding:"4px 0",pointerEvents:"auto"});for(const s of t)if("section"in s)x.appendChild(a(s.section));else{const C=s.enabled!==!1;if(!C&&!s.disabledHint)continue;const r=l.createElement("div");s.action?r.setAttribute("role","menuitem"):(r.setAttribute("role","menuitemcheckbox"),r.setAttribute("aria-checked",s.active?"true":"false")),r.tabIndex=-1,C||(r.setAttribute("aria-disabled","true"),wireTooltip(r,s.disabledHint)),Object.assign(r.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"6px 14px",fontSize:FONT.body,cursor:C?"pointer":"default",color:C?s.active?CLR.iconActive:CLR.text:CLR.label,fontWeight:s.active?"700":"400",background:s.active?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const d=l.createElement("span");Object.assign(d.style,{width:"12px",flexShrink:"0",color:CLR.iconActive,visibility:s.active?"visible":"hidden"}),d.textContent=s.action?"":"\u2713",d.setAttribute("aria-hidden","true");const y=l.createElement("span");y.textContent=s.label,r.appendChild(d),r.appendChild(y),C?(r.addEventListener("mouseenter",()=>{s.active||(r.style.background=CLR.menuHover)}),r.addEventListener("mouseleave",()=>{r.style.background=s.active?CLR.menuActive:"transparent"}),r.addEventListener("focus",()=>{s.active||(r.style.background=CLR.menuHover)}),r.addEventListener("blur",()=>{r.style.background=s.active?CLR.menuActive:"transparent"}),r.addEventListener("click",p=>{p.stopPropagation(),s.onClick(p)})):r.addEventListener("click",p=>{p.stopPropagation()}),x.appendChild(r)}return x}export function createToolbarHelpers(e){const t=e.ownerDocument;let n=null;const o=r=>menuLayerFor(r);function a(r,d,y){const p=t.createElement("button");return p.innerHTML=R[r],p.type="button",p.ariaLabel=d,Object.assign(p.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"}),p.addEventListener("mouseenter",m=>{p.dataset.active||(p.style.background=CLR.bgHover,p.style.color=CLR.iconHover),e.textContent=p.ariaLabel??d,e.style.display="block",positionTooltip(e,p,m.clientX,m.clientY)}),p.addEventListener("mousemove",m=>{e.style.display==="block"&&positionTooltip(e,p,m.clientX,m.clientY)}),p.addEventListener("mouseleave",()=>{p.dataset.active||(p.style.background="transparent",p.style.color=CLR.icon),e.style.display="none"}),p.addEventListener("click",()=>{e.style.display="none",y()}),p}function l(r,d){d?(r.dataset.active="1",r.style.background=CLR.bgActive,r.style.color=CLR.iconActive):(delete r.dataset.active,r.style.background="transparent",r.style.color=CLR.icon)}function x(){const r=t.createElement("div");return Object.assign(r.style,{width:"1px",height:"18px",background:CLR.separator,margin:"0 2px",flexShrink:"0"}),r}function i(r,d,y,p,m){const h=t.createElement("div");if(m){const c=t.createElement("span");c.textContent=m.derived?ce:"",c.setAttribute("aria-hidden","true"),Object.assign(c.style,{display:"inline-block",width:"1.1em"}),h.append(c,r),m.derived&&h.setAttribute("aria-label",`${r} \u2014 ${de.toLowerCase()}`)}else h.textContent=r;return h.setAttribute("role","menuitemradio"),h.setAttribute("aria-checked",d?"true":"false"),h.tabIndex=-1,Object.assign(h.style,{padding:`6px 14px 6px ${y?"26px":"14px"}`,fontSize:FONT.body,cursor:"pointer",color:d?CLR.iconActive:CLR.text,fontWeight:d?"700":"400",background:d?CLR.menuActive:"transparent",whiteSpace:"nowrap"}),h.addEventListener("mouseenter",()=>{d||(h.style.background=CLR.menuHover)}),h.addEventListener("mouseleave",()=>{h.style.background=d?CLR.menuActive:"transparent"}),h.addEventListener("focus",()=>{d||(h.style.background=CLR.menuHover)}),h.addEventListener("blur",()=>{h.style.background=d?CLR.menuActive:"transparent"}),h.addEventListener("click",p),h}function f(r){const d=t.createElement("div");return d.textContent=r,d.setAttribute("role","presentation"),Object.assign(d.style,{padding:"5px 14px 2px",fontSize:FONT.body,fontWeight:"600",letterSpacing:TRACKING,color:CLR.label,textTransform:"uppercase",pointerEvents:"none",userSelect:"none"}),d}function u(r,d,y,p,m){const h=()=>{n&&(n.remove(),n=null),c.setAttribute("aria-expanded","false")},c=a(r,d,()=>{if(n){h();return}const E=t.createElement("div"),L=c.getBoundingClientRect(),H=c.ownerDocument.defaultView??window,w=148,N=L.left+w<=(H.innerWidth??1/0)?L.left:Math.max(4,L.right-w);Object.assign(E.style,{position:"fixed",top:`${L.bottom+4}px`,left:`${N}px`,background:CLR.menuBg,border:`1px solid ${CLR.menuBorder}`,borderRadius:RADIUS.control,boxShadow:SHADOW.menu,zIndex:Z_BASE,minWidth:`${w}px`,padding:"4px 0",pointerEvents:"auto"});for(const D of y()){const g=t.createElement("div");g.textContent=D.label,g.dataset.wmapDropdownValue=D.value;const A=D.value===p();g.setAttribute("role","menuitemradio"),g.setAttribute("aria-checked",A?"true":"false"),g.tabIndex=-1,Object.assign(g.style,{padding:"6px 14px",fontSize:FONT.body,cursor:"pointer",color:A?CLR.iconActive:CLR.text,fontWeight:A?"700":"400",background:A?CLR.menuActive:"transparent",whiteSpace:"nowrap"});const _=()=>{D.value!==p()&&(g.style.background=CLR.menuHover)},G=()=>{g.style.background=D.value===p()?CLR.menuActive:"transparent"};g.addEventListener("mouseenter",_),g.addEventListener("mouseleave",G),g.addEventListener("focus",_),g.addEventListener("blur",G),g.addEventListener("click",$=>{$.stopPropagation(),m(D.value),h()}),E.appendChild(g)}E.setAttribute("role","menu"),E.setAttribute("aria-label",d),o(c).appendChild(E),n=E,c.setAttribute("aria-expanded","true"),te(E,c,h)});return c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded","false"),c}function s(r,d,y,p){function m(){return buildCheckMenuEl(c.getBoundingClientRect(),y().map(E=>"section"in E?E:{...E,onClick:L=>{E.closeMenu&&h(),E.onClick(L),p(c);const H=n;if(!H)return;const w=m();w.setAttribute("role","menu"),w.setAttribute("aria-label",d),H.replaceWith(w),n=w,te(w,c,h)}}),{makeMenuSection:f},c.ownerDocument.defaultView??window)}const h=()=>{n&&(n.remove(),n=null),c.setAttribute("aria-expanded","false")},c=a(r,d,()=>{if(n){h();return}const E=m();E.setAttribute("role","menu"),E.setAttribute("aria-label",d),o(c).appendChild(E),n=E,c.setAttribute("aria-expanded","true"),te(E,c,h)});return c.setAttribute("aria-haspopup","menu"),c.setAttribute("aria-expanded","false"),p(c),c}function C(r){const d=r.target?.closest?.("[data-wmap-submenu]");if(n&&!n.contains(r.target)&&!d&&(n.remove(),n=null,r.target?.getAttribute?.("aria-haspopup")!=="menu"))for(const p of document.querySelectorAll('[aria-haspopup="menu"][aria-expanded="true"]'))p.setAttribute("aria-expanded","false")}return{makeBtn:a,setActive:l,makeSep:x,makeMenuRow:i,makeMenuSection:f,makeDropdown:u,makeCheckMenuBtn:s,closeOpenMenu:C,getOpenMenu:()=>n,setOpenMenu:r=>{n=r}}}const Oe=7e3;let Ie=0;function me(){return Oe+ ++Ie}const Re=32,$e=6;let We=0;function ze(){return We++%$e*Re}function Pe(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 be(e){const t=e.mode==="modal",n=e.ownerDocument??document,o=n.defaultView??window,a=n.body.style.overflow;t&&(n.body.style.overflow="hidden");let l=null;t&&(l=n.createElement("div"),l.id="wmap-modal-backdrop",Object.assign(l.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 x=n.activeElement,i=n.createElement("div");i.className=t?"wmap-modal-box wmap-overlay-box":"wmap-window-box wmap-overlay-box",i.setAttribute("role","dialog"),t&&i.setAttribute("aria-modal","true"),i.setAttribute("aria-label",e.title??"Expanded wafer map"),i.tabIndex=-1;let f=e.boxSize?.width??"min(90vw, 700px)",u=e.boxSize?.height??"min(90vh, 700px)";if(Object.assign(i.style,{position:"relative",background:CLR.menuBg,borderRadius:RADIUS.container,overflow:"hidden",display:"flex",flexDirection:"column",width:f,height:u,boxShadow:SHADOW.modal,minWidth:"320px",minHeight:"240px",maxWidth:"100vw",maxHeight:"100vh",zIndex:t?Z_ABOVE2:String(me())}),!t){const b=ze();Object.assign(i.style,{position:"fixed",top:`${Math.round(o.innerHeight*.08)+b}px`,left:`${Math.round(o.innerWidth*.08)+b}px`})}const s=n.createElement("div");Object.assign(s.style,{display:"flex",alignItems:"center",gap:SPACE.sm,padding:"10px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const C={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 b=n.createElement("span");b.textContent=e.title,b.title=e.title,b.dataset.wmapWindowTitle="1",Object.assign(b.style,{fontWeight:"700",fontSize:"14px",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",minWidth:"0"}),s.appendChild(b)}const r=n.createElement("div");r.style.flex="1",s.appendChild(r);let d=null;t||(d=n.createElement("button"),d.type="button",d.innerHTML=R.collapse,d.setAttribute("aria-label","Collapse"),wireTooltip(d),Object.assign(d.style,C),wireControlHover(d),d.addEventListener("click",()=>g(!w)),s.appendChild(d));let y=null;e.printable&&(y=n.createElement("button"),y.type="button",y.innerHTML=R.print,y.setAttribute("aria-label","Print / Save as PDF"),wireTooltip(y),Object.assign(y.style,C),wireControlHover(y),y.addEventListener("click",()=>{typeof e.printable=="function"?e.printable():o.print()}),s.appendChild(y));const p=n.createElement("button");p.type="button",p.innerHTML=R.maximize,p.setAttribute("aria-label","Maximize (F)"),wireTooltip(p),Object.assign(p.style,C),wireControlHover(p),p.addEventListener("click",()=>H(!c));const m=n.createElement("button");m.type="button",m.innerHTML=R.close,m.setAttribute("aria-label","Close (Esc)"),wireTooltip(m),Object.assign(m.style,C),wireControlHover(m),m.addEventListener("click",j);const h=e.maximizable!==!1;h&&s.appendChild(p),s.appendChild(m);let c=!1,E="",L="";function H(b){c=b,p.innerHTML=c?R.minimize:R.maximize,p.setAttribute("aria-label",c?"Restore (F)":"Maximize (F)"),d&&(d.style.display=c?"none":""),v.style.display=c?"none":"block",c?(i.style.borderRadius="0",i.style.width="100vw",i.style.height="100vh",t||(E=i.style.top,L=i.style.left,i.style.top="0",i.style.left="0")):(i.style.borderRadius="12px",i.style.width=f,i.style.height=u,t||(i.style.top=E,i.style.left=L)),e.onMaximizeChange?.(c,i)}let w=!1,Z="",N="";const D=220;function g(b){w=b,d.innerHTML=w?R.uncollapse:R.collapse,d.setAttribute("aria-label",w?"Show contents":"Collapse"),v.style.display=w?"none":"block",w?(Z=i.style.height,N=i.style.width,i.style.minHeight="0",i.style.height="auto",i.style.minWidth="0",i.style.width=`${D}px`,p.disabled=!0,p.style.opacity="0.4",p.style.cursor="default",W.style.display="none"):(i.style.minHeight="240px",i.style.height=Z||u,i.style.minWidth="320px",i.style.width=N||f,p.disabled=!1,p.style.opacity="1",p.style.cursor="pointer",W.style.display="flex")}function A(){const b=n.body.style.userSelect;return n.body.style.userSelect="none",()=>{n.body.style.userSelect=b}}t||(s.style.cursor="move",s.addEventListener("pointerdown",b=>{if(c||b.target.closest('button, [role="button"]'))return;b.preventDefault();const M=A(),S=b.clientX,B=b.clientY,T=i.offsetTop,O=i.offsetLeft,q=o.innerHeight-s.offsetHeight,z=o.innerWidth-40,I=40-i.offsetWidth;s.setPointerCapture(b.pointerId);const P=K=>{const ie=Math.min(Math.max(T+(K.clientY-B),0),q),ge=Math.min(Math.max(O+(K.clientX-S),I),z);i.style.top=`${ie}px`,i.style.left=`${ge}px`},U=K=>{M(),s.releasePointerCapture(K.pointerId),s.removeEventListener("pointermove",P),s.removeEventListener("pointerup",U)};s.addEventListener("pointermove",P),s.addEventListener("pointerup",U)}));const _='button,[href],input,select,textarea,[tabindex]:not([tabindex="-1"]),[role="menuitem"],[role="menuitemradio"],[role="menuitemcheckbox"]';function G(b){const M=Array.from(i.querySelectorAll(_)).filter(O=>O.offsetParent!==null||O===n.activeElement);if(M.length===0){b.preventDefault(),i.focus();return}const S=M[0],B=M[M.length-1],T=n.activeElement;b.shiftKey&&(T===S||!i.contains(T))?(b.preventDefault(),B.focus()):!b.shiftKey&&T===B&&(b.preventDefault(),S.focus())}const $=b=>{if(b.key==="Escape"){j();return}if(t&&(b.key==="e"||b.key==="E")){j();return}if(t&&b.key==="Tab"){G(b);return}h&&(b.key==="f"||b.key==="F")&&!w&&H(!c)};function j(){t?n.removeEventListener("keydown",$):i.removeEventListener("keydown",$),oe.remove(),xe(),hideTooltip(n),reparentTooltip(n.body),l?l.remove():i.remove(),t&&(n.body.style.overflow=a),x?.focus?.(),e.onClose()}function V(){t||(i.style.zIndex=String(me()))}const W=n.createElement("div");Object.assign(W.style,{flex:"1",minHeight:"0",minWidth:"0",display:"flex",overflow:"hidden"});const v=n.createElement("div");v.tabIndex=0,v.setAttribute("role","separator"),v.setAttribute("aria-label","Resize window (arrow keys, or drag)"),Object.assign(v.style,{position:"absolute",right:"0",bottom:"0",width:"16px",height:"16px",cursor:"nwse-resize",touchAction:"none"}),v.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>',v.style.color=CLR.label;const Y=320,X=240,J=20;function ee(b,M){const S=o.innerWidth-i.offsetLeft,B=o.innerHeight-i.offsetTop,T=Math.min(Math.max(i.offsetWidth+b,Y),S),O=Math.min(Math.max(i.offsetHeight+M,X),B);i.style.width=`${T}px`,i.style.height=`${O}px`}v.addEventListener("keydown",b=>{if(!(c||w))switch(b.key){case"ArrowRight":b.preventDefault(),ee(J,0);break;case"ArrowLeft":b.preventDefault(),ee(-J,0);break;case"ArrowDown":b.preventDefault(),ee(0,J);break;case"ArrowUp":b.preventDefault(),ee(0,-J);break}}),v.addEventListener("pointerdown",b=>{if(c||w)return;b.preventDefault();const M=A(),S=b.clientX,B=b.clientY,T=i.offsetWidth,O=i.offsetHeight,q=o.innerWidth-i.offsetLeft,z=o.innerHeight-i.offsetTop;v.setPointerCapture(b.pointerId);const I=U=>{const K=Math.min(Math.max(T+(U.clientX-S),Y),q),ie=Math.min(Math.max(O+(U.clientY-B),X),z);i.style.width=`${K}px`,i.style.height=`${ie}px`},P=U=>{M(),v.releasePointerCapture(U.pointerId),v.removeEventListener("pointermove",I),v.removeEventListener("pointerup",P)};v.addEventListener("pointermove",I),v.addEventListener("pointerup",P)}),i.appendChild(s),i.appendChild(W),i.appendChild(v);const ne=e.anchor?overlayRootFor(e.anchor):n.body;l?(l.appendChild(i),ne.appendChild(l)):ne.appendChild(i);const xe=Pe(n,ne),oe=n.createElement("style");oe.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(te),reparentTooltip(i),t?(s.addEventListener("click",v=>{v.target===s&&I()}),n.addEventListener("keydown",z)):(i.addEventListener("keydown",z),i.addEventListener("mousedown",Y),Y()),nextFrame(()=>(m.isConnected?m:i).focus(),o);function ye(v){d=v,!u&&!E&&(i.style.height=v)}return{backdrop:s,box:i,contentWrap:$,close:I,bringToFront:Y,setNaturalHeight:ye}}export function openModal(e){return me({...e,mode:"modal"})}export function openFloatingWindow(e){return me({...e,mode:"window"})}const le=new WeakSet;export function openReparentedModal(e,t={}){if(e.length===0||e.some(r=>le.has(r)))return null;const n=e.map(r=>({el:r,parent:r.parentElement,next:r.nextSibling})),o=openModal({ownerDocument:t.ownerDocument,title:t.title,boxSize:t.boxSize,anchor:t.anchor??e[0],onClose:()=>{for(const r of n){if(le.delete(r.el),!r.parent)continue;const s=r.next&&r.next.parentNode===r.parent?r.next:null;r.parent.insertBefore(r.el,s)}t.onClosed?.()}});for(const r of n)le.add(r.el),o.contentWrap.appendChild(r.el);return o}export function makePaletteBtn(e,t,n,o){const r=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const p=t(),i=[];if(p.plotMode==="hardBin"||p.plotMode==="softBin"){const b=p.binColorScheme??"default";i.push({section:"Bin colours"});for(const d of Me())i.push({label:d.label,active:b===d.name,onClick:()=>o({binColorScheme:d.name})});if(n()){const d=p.useDefinedBinColors??!0;i.push({section:"Bin definitions"}),i.push({label:"Use colours from bin definitions",active:d,onClick:()=>o({useDefinedBinColors:!d})})}}else{const b=p.valueColorScheme??"default";i.push({section:"Value colours"});for(const l of Se())i.push({label:l.label,active:b===l.name,onClick:()=>o({valueColorScheme:l.name})});const d=p.reverseValueScheme??!1;i.push({section:"Direction"}),i.push({label:"Reverse gradient",active:d,onClick:()=>o({reverseValueScheme:!d})})}return i},()=>{});function s(){r.style.display=t().plotMode==="metadata"?"none":""}return{btn:r,sync:s}}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)},r=>o({passFailDisplay:r})),{label:"Mark failing dies",active:!!e.markFailingDies,enabled:n.binMode,disabledHint:n.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,t){if(e.functionalActive)return[];const n=[];return e.hasLimits&&n.push({label:"Limit 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 r(){const s=t(),p=s.plotMode,i=p==="value"||p==="stackedValues";o.style.display=i&&requestedPassFailDisplay(s)==="off"&&!s.functionalActive?"":"none",e.setActive(o,!!s.logScale)}return{btn:o,sync:r}}const je=[{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 r=e.makeCheckMenuBtn("legend","Legend style",()=>{const p=t().legendPosition??"default",i=[];let b=!0;if(o){const d=o.blockedReason();b=d?!0:o.get(),i.push({label:"Legend on each map",active:b,enabled:!d,disabledHint:d??void 0,onClick:()=>o.set(!o.get())})}if(be(t().plotMode)){o&&i.push({section:"Position on each map"});for(const d of je)i.push({label:d.label,active:b&&p===d.value,enabled:b,disabledHint:b?void 0:'Turn on "Legend on each map" to position it',onClick:()=>n(d.value)})}return i},()=>{});function s(){r.style.display=o||be(t().plotMode)?"":"none"}return{btn:r,sync:s}}function be(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})},{section:""},{label:"Reset orientation",active:!1,action:!0,enabled:!!(t().rotation||t().flipX||t().flipY),disabledHint:"Already in the original orientation",onClick:()=>n({rotation:0,flipX:!1,flipY:!1})}],o=>{const{rotation:r,flipX:s,flipY:p}=t();e.setActive(o,!!(r||s||p))})}let j=null;const he=40,Ve=he+8;function Ue(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 r=e.createElement("span");r.setAttribute("role","status"),r.setAttribute("aria-live","polite"),r.style.cssText=`font-size:12px;color:${CLR.label};min-width:44px;text-align:center;flex-shrink:0;white-space:nowrap;`;function s(x,c){const m=e.createElement("button");return m.type="button",m.textContent=x,m.setAttribute("aria-label",c),m.disabled=!0,m.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;`,m.addEventListener("mouseenter",()=>{m.disabled||(m.style.background=CLR.bgHover)}),m.addEventListener("mouseleave",()=>{m.style.background="none"}),m}const p=s("\u25B2","Previous match"),i=s("\u25BC","Next match");let b=[],d=-1;function l(){const x=b.length===0;p.disabled=x,i.disabled=x,p.style.opacity=x?"0.4":"",i.style.opacity=x?"0.4":""}function y(){for(const x of b)x.parentNode?.replaceChild(e.createTextNode(x.textContent??""),x);t.normalize(),b=[],d=-1}function a(x){if(b.length===0)return;d>=0&&(b[d].style.outline="none"),d=(x%b.length+b.length)%b.length;const c=b[d];c.style.outline=`2px solid ${CLR.iconActive}`,c.style.outlineOffset="1px",c.scrollIntoView({behavior:"smooth",block:"center"}),r.textContent=`${d+1}/${b.length}`}function f(x){y();const c=x.trim();if(!c){r.textContent="",l();return}const m=c.toLowerCase(),u=e.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode(A){const E=A.parentElement;return!E||E.closest("script,style,.wmap-guide-toc")?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}}),h=[];let w;for(;w=u.nextNode();)h.push(w);for(const A of h){const E=A.textContent??"",C=E.toLowerCase();if(!C.includes(m))continue;const T=e.createDocumentFragment();let D=0,S=C.indexOf(m);for(;S!==-1;){S>D&&T.appendChild(e.createTextNode(E.slice(D,S)));const g=e.createElement("mark");g.textContent=E.slice(S,S+c.length),T.appendChild(g),b.push(g),D=S+c.length,S=C.indexOf(m,D)}D<E.length&&T.appendChild(e.createTextNode(E.slice(D))),A.parentNode?.replaceChild(T,A)}l(),b.length===0?r.textContent="No matches":a(0)}return o.addEventListener("input",()=>f(o.value)),o.addEventListener("keydown",x=>{x.key==="Enter"?(x.preventDefault(),a(d+(x.shiftKey?-1:1))):x.key==="Escape"&&(o.value?(o.value="",f("")):o.blur())}),p.addEventListener("click",()=>a(d-1)),i.addEventListener("click",()=>a(d+1)),n.append(o,r,p,i),n}function Ge(e,t,n){const o=[...t.querySelectorAll("h2[id]")];if(o.length<2)return;for(const c of t.querySelectorAll("h1[id],h2[id],h3[id],h4[id]"))c.style.scrollMarginTop=`${Ve}px`;const r=e.createElement("div");r.classList.add("wmap-guide-toc"),r.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 s=e.createElement("div");s.style.cssText=`display:flex;align-items:center;gap:4px;height:${he}px;padding:0 12px;box-sizing:border-box;`;const p=e.createElement("span");p.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>',p.style.cssText=`display:inline-flex;transition:transform ${MOTION.base};flex-shrink:0;`;const i=e.createElement("button");i.type="button";const b="wmap-guide-toc-panel";i.setAttribute("aria-expanded","false"),i.setAttribute("aria-controls",b),i.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 d=e.createElement("span");d.textContent=`Contents (${o.length})`,i.append(p,d),i.addEventListener("mouseenter",()=>{i.style.background=CLR.bgHover}),i.addEventListener("mouseleave",()=>{i.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?s.append(i,Ue(e,t),l):s.append(i,l);const y=e.createElement("div");y.id=b,y.hidden=!0,y.style.cssText="padding:2px 12px 12px;max-height:min(60vh,440px);overflow-y:auto;";const a=/^\s*\d+(?:\.\d+)*\.\s+/;for(const c of t.querySelectorAll("h2[id],h3[id],h4[id]")){const m=c.firstChild;m?.nodeType===Node.TEXT_NODE&&(m.textContent=(m.textContent??"").replace(a,""))}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 c of o){const m=e.createElement("li");m.style.cssText="break-inside:avoid;";const u=e.createElement("a");u.href=`#${c.id}`,u.textContent=c.textContent??"",u.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;`,u.addEventListener("mouseenter",()=>{u.style.background=CLR.bgHover}),u.addEventListener("mouseleave",()=>{u.style.background="none"}),u.addEventListener("click",h=>{h.preventDefault(),x.close(),c.scrollIntoView({behavior:"smooth",block:"start"})}),m.appendChild(u),f.appendChild(m)}y.appendChild(f);const x=wireExpandToggle(i,c=>{y.hidden=!c,i.setAttribute("aria-expanded",String(c)),p.style.transform=c?"rotate(180deg)":"none"});r.append(s,y),t.prepend(r)}function xe(e,t,n,o,r){const s=t,p=s.__wmapDemoApi;s.__wmapDemoApi=o;const i=e.createElement("div");return i.classList.add("wmap-guide-content"),i.innerHTML=n,Ge(e,i,r),{content:i,restoreApi:()=>{s.__wmapDemoApi===o&&(s.__wmapDemoApi=p)}}}function ve(e,t){const n=t,o=e.querySelector("script");if(o){const r=e.ownerDocument.createElement("script");r.textContent=o.textContent,e.appendChild(r);const s=e.querySelector(".wmap-guide");return s&&n.__wmapPopulateGuideDemos?.(s),n.__wmapDestroyGuideDemos}}function Xe(e,t,n,o){const r=o?.ownerDocument??document,s=r.defaultView??window,{content:p,restoreApi:i}=xe(r,s,t,n,!0);Object.assign(p.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"});let b;const d=openFloatingWindow({title:e,anchor:o,ownerDocument:r,printable:!0,onMaximizeChange:l=>{p.style.setProperty("--wmap-guide-reading-width",l?"1000px":"720px")},onClose:()=>{j===d&&(j=null),b?.(),i()}});return d.contentWrap.appendChild(p),b=ve(p,s),d}function Ye(e,t,n,o){const r=e.document;r.title=t,Object.assign(r.documentElement.style,{height:"100%"}),Object.assign(r.body.style,{margin:"0",height:"100vh",overflow:"hidden",display:"flex",flexDirection:"column",fontFamily:FONT.family}),copyWmapThemeTokens(document.documentElement,r.documentElement);const s=syncWmapPopupTheme(document.documentElement,r.documentElement),{content:p,restoreApi:i}=xe(r,e,n,o,!1);Object.assign(p.style,{flex:"1",overflow:"auto",minHeight:"0",minWidth:"0"}),r.body.appendChild(p);const b=ve(p,e);let d=!1;const l=()=>{if(!d){d=!0,clearInterval(y),s();try{b?.()}catch{}i(),j===a&&(j=null)}},y=setInterval(()=>{e.closed&&l()},400);e.addEventListener("pagehide",l);const a={close:()=>{e.closed||e.close(),l()}};return a}export function openUserGuideWindow(e,t,n,o){j&&(j.close(),j=null);const r=n?.title??"Wafer Map \u2014 User Guide",s=(n?.html??"")+t,i=(o?.ownerDocument.defaultView??window).open("","_blank","width=800,height=820");j=i?Ye(i,r,s,e):Xe(r,s,e,o)}export function openWaferMapGuide(e,t){Promise.all([import("./userGuideHtml.js"),import("./renderWaferMap.js"),import("./renderWaferGallery.js")]).then(([n,o,r])=>{openUserGuideWindow({buildWaferMap:He,renderWaferMap:o.renderWaferMap,renderWaferGallery:r.renderWaferGallery,analyzeWaferMap:Ie},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 r=n.createElement("div");Object.assign(r.style,{display:"flex",justifyContent:"flex-end",padding:"6px 14px",borderBottom:`1px solid ${CLR.menuBorder}`,flexShrink:"0"});const s=n.createElement("button");s.type="button",wireControlHover(s,"bare"),s.textContent="Open as full page \u2197",Object.assign(s.style,{border:"none",background:"none",color:CLR.iconActive,cursor:"pointer",fontSize:FONT.body,textDecoration:"underline",padding:"0"}),s.addEventListener("click",()=>Te(e)),r.appendChild(s);const p=openModal({title:"Summary report",anchor:t?.anchor,ownerDocument:n,printable:()=>o.contentWindow?.print(),onClose:()=>{}});return p.contentWrap.style.flexDirection="column",p.contentWrap.appendChild(r),p.contentWrap.appendChild(o),p}
|
|
9
|
+
}`,n.head.appendChild(oe),reparentTooltip(i),t?(l.addEventListener("click",b=>{b.target===l&&j()}),n.addEventListener("keydown",$)):(i.addEventListener("keydown",$),i.addEventListener("mousedown",V),V()),nextFrame(()=>(e.initialFocus?.()??(m.isConnected?m:i)).focus(),o);function ve(b){u=b,!c&&!w&&(i.style.height=b)}function ye(b){const M=()=>{};if(c||w||!(b>0))return M;const S=i.getBoundingClientRect(),B=Math.min(S.width+b,o.innerWidth*.96);if(!(B>S.width+.5))return M;const T=i.style.width,O=f,q=i.style.left,z=`${Math.round(B)}px`;i.style.width=z,f=z;let I=null;if(!t){const P=S.left+B-o.innerWidth;P>0&&(I=`${Math.max(0,Math.round(S.left-P-8))}px`,i.style.left=I)}return()=>{i.style.width===z&&!c&&!w&&(i.style.width=T),f===z&&(f=O),I!==null&&i.style.left===I&&(i.style.left=q)}}return{backdrop:l,box:i,contentWrap:W,close:j,bringToFront:V,setNaturalHeight:ve,reserveWidth:ye}}export function openModal(e){return be({...e,mode:"modal"})}export function openFloatingWindow(e){return be({...e,mode:"window"})}const le=new WeakSet;export function openReparentedModal(e,t={}){if(e.length===0||e.some(a=>le.has(a)))return null;const n=e.map(a=>({el:a,parent:a.parentElement,next:a.nextSibling})),o=openModal({ownerDocument:t.ownerDocument,title:t.title,boxSize:t.boxSize,anchor:t.anchor??e[0],onClose:()=>{for(const a of n){if(le.delete(a.el),!a.parent)continue;const l=a.next&&a.next.parentNode===a.parent?a.next:null;a.parent.insertBefore(a.el,l)}t.onClosed?.()}});for(const a of n)le.add(a.el),o.contentWrap.appendChild(a.el);return o}export function makePaletteBtn(e,t,n,o){const a=e.makeCheckMenuBtn("palette","Colour scheme",()=>{const x=t(),i=[];if(x.plotMode==="hardBin"||x.plotMode==="softBin"){const f=x.binColorScheme??"default";i.push({section:"Bin colours"});for(const u of Se())i.push({label:u.label,active:f===u.name,onClick:()=>o({binColorScheme:u.name})});if(n()){const u=x.useDefinedBinColors??!0;i.push({section:"Bin definitions"}),i.push({label:"Use colours from bin definitions",active:u,onClick:()=>o({useDefinedBinColors:!u})})}}else{const f=x.valueColorScheme??"default";i.push({section:"Value colours"});for(const s of Be())i.push({label:s.label,active:f===s.name,onClick:()=>o({valueColorScheme:s.name})});const u=x.reverseValueScheme??!1;i.push({section:"Direction"}),i.push({label:"Reverse gradient",active:u,onClick:()=>o({reverseValueScheme:!u})})}return i},()=>{});function l(){a.style.display=t().plotMode==="metadata"?"none":""}return{btn:a,sync:l}}export function requestedPassFailDisplay(e){return e.passFailDisplay??"off"}export function overlayMenuRows(e,t,n,o,a){const l=a?.on?{enabled:!1,disabledHint:"Not drawn in the compact layout"}:void 0;return[...a?[{label:"Compact layout",active:a.on,enabled:a.offered||a.on,disabledHint:"Needs a repeating multi-project layout",onClick:()=>a.onChange(!a.on)},{label:"Layout diagnostics",active:!1,action:!0,closeMenu:!0,onClick:()=>a.onDiagnostics()},{section:""}]:[],{label:"Ring boundaries",active:!!e.showRingBoundaries,...l,onClick:()=>o({showRingBoundaries:!e.showRingBoundaries})},{label:"Quadrant lines",active:!!e.showQuadrantBoundaries,...l,onClick:()=>o({showQuadrantBoundaries:!e.showQuadrantBoundaries})},{label:"Die labels",active:!!e.showDieLabels,onClick:()=>o({showDieLabels:!e.showDieLabels})},{label:"Reticle grid",active:!!e.showReticle,enabled:a?.on?!1:t,...l?{disabledHint:l.disabledHint}:{},onClick:()=>o({showReticle:!e.showReticle})},{label:"XY indicator",active:!!e.showXYIndicator,onClick:()=>o({showXYIndicator:!e.showXYIndicator})},{label:"Axis labels",active:!!e.showAxes,onClick:()=>o({showAxes:!e.showAxes})},...passFailMenuRows({...n,display:requestedPassFailDisplay(e)},x=>o({passFailDisplay:x})),{label:"Mark failing dies",active:!!e.markFailingDies,enabled:n.binMode,disabledHint:n.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,showAxes:void 0,passFailDisplay:"off",markFailingDies:!1})}]}export function anyOverlayActive(e){return!!(e.showRingBoundaries||e.showQuadrantBoundaries||e.showDieLabels||e.showReticle||e.showXYIndicator||e.showAxes===!0||e.markFailingDies||requestedPassFailDisplay(e)!=="off")}export function passFailMenuRows(e,t){if(e.functionalActive)return[];const n=[];return e.hasLimits&&n.push({label:"Limit 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 a(){const l=t(),x=l.plotMode,i=x==="value"||x==="stackedValues";o.style.display=i&&requestedPassFailDisplay(l)==="off"&&!l.functionalActive?"":"none",e.setActive(o,!!l.logScale)}return{btn:o,sync:a}}const Fe=[{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 a=e.makeCheckMenuBtn("legend","Legend style",()=>{const x=t().legendPosition??"default",i=[];let f=!0;if(o){const u=o.blockedReason();f=u?!0:o.get(),i.push({label:"Legend on each map",active:f,enabled:!u,disabledHint:u??void 0,onClick:()=>o.set(!o.get())})}if(he(t().plotMode)){o&&i.push({section:"Position on each map"});for(const u of Fe)i.push({label:u.label,active:f&&x===u.value,enabled:f,disabledHint:f?void 0:'Turn on "Legend on each map" to position it',onClick:()=>n(u.value)})}return i},()=>{});function l(){a.style.display=o||he(t().plotMode)?"":"none"}return{btn:a,sync:l}}function he(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){const o=a=>n({...a,showXYIndicator:!0});return e.makeCheckMenuBtn("orient","Orientation",()=>[{section:"Rotate"},{label:"Rotate 90\xB0 clockwise",active:!1,onClick:()=>{const a=t().rotation??0;o({rotation:ROTATIONS[(ROTATIONS.indexOf(a)+1)%4]})}},{section:"Flip"},{label:"Flip horizontal",active:!!t().flipX,onClick:()=>o({flipX:!t().flipX})},{label:"Flip vertical",active:!!t().flipY,onClick:()=>o({flipY:!t().flipY})},{section:""},{label:"Reset orientation",active:!1,action:!0,enabled:!!(t().rotation||t().flipX||t().flipY),disabledHint:"Already in the original orientation",onClick:()=>n({rotation:0,flipX:!1,flipY:!1})}],a=>{const{rotation:l,flipX:x,flipY:i}=t();e.setActive(a,!!(l||x||i))})}
|