@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.
Files changed (167) hide show
  1. package/AGENTS.md +7 -7
  2. package/CHANGELOG.md +374 -1
  3. package/README.md +5 -5
  4. package/dist/packages/canvas-adapter/chartPopulation.d.ts +15 -10
  5. package/dist/packages/canvas-adapter/chartPopulation.js +1 -1
  6. package/dist/packages/canvas-adapter/charts/barPanel.d.ts +7 -0
  7. package/dist/packages/canvas-adapter/charts/barPanel.js +1 -1
  8. package/dist/packages/canvas-adapter/charts/binCluster.d.ts +7 -1
  9. package/dist/packages/canvas-adapter/charts/binCluster.js +1 -1
  10. package/dist/packages/canvas-adapter/charts/boxplot.js +1 -1
  11. package/dist/packages/canvas-adapter/charts/capability.js +1 -1
  12. package/dist/packages/canvas-adapter/charts/chartShell.d.ts +57 -15
  13. package/dist/packages/canvas-adapter/charts/chartShell.js +1 -1
  14. package/dist/packages/canvas-adapter/charts/correlation.js +1 -2
  15. package/dist/packages/canvas-adapter/charts/groupedBarPlot.d.ts +2 -0
  16. package/dist/packages/canvas-adapter/charts/groupedBarPlot.js +1 -1
  17. package/dist/packages/canvas-adapter/charts/histogram.d.ts +16 -0
  18. package/dist/packages/canvas-adapter/charts/histogram.js +1 -1
  19. package/dist/packages/canvas-adapter/charts/palette.d.ts +2 -0
  20. package/dist/packages/canvas-adapter/charts/palette.js +1 -1
  21. package/dist/packages/canvas-adapter/charts/plotChart.d.ts +27 -0
  22. package/dist/packages/canvas-adapter/charts/plotChart.js +1 -0
  23. package/dist/packages/canvas-adapter/charts/pointInteractions.d.ts +45 -0
  24. package/dist/packages/canvas-adapter/charts/pointInteractions.js +1 -0
  25. package/dist/packages/canvas-adapter/charts/regionYieldDiagram.d.ts +2 -0
  26. package/dist/packages/canvas-adapter/charts/regionYieldDiagram.js +1 -1
  27. package/dist/packages/canvas-adapter/charts/scatter.d.ts +19 -0
  28. package/dist/packages/canvas-adapter/charts/scatter.js +1 -1
  29. package/dist/packages/canvas-adapter/charts/sweep.d.ts +12 -0
  30. package/dist/packages/canvas-adapter/charts/sweep.js +1 -1
  31. package/dist/packages/canvas-adapter/charts/testPassRate.d.ts +7 -0
  32. package/dist/packages/canvas-adapter/charts/testPassRate.js +1 -1
  33. package/dist/packages/canvas-adapter/charts/trend.d.ts +11 -0
  34. package/dist/packages/canvas-adapter/charts/trend.js +1 -1
  35. package/dist/packages/canvas-adapter/confirmDialog.d.ts +13 -0
  36. package/dist/packages/canvas-adapter/confirmDialog.js +1 -0
  37. package/dist/packages/canvas-adapter/dataTab.d.ts +131 -0
  38. package/dist/packages/canvas-adapter/dataTab.js +1 -0
  39. package/dist/packages/canvas-adapter/dieList.d.ts +39 -4
  40. package/dist/packages/canvas-adapter/dieList.js +6 -7
  41. package/dist/packages/canvas-adapter/drilldown.d.ts +20 -3
  42. package/dist/packages/canvas-adapter/drilldown.js +1 -1
  43. package/dist/packages/canvas-adapter/guideWindow.d.ts +96 -0
  44. package/dist/packages/canvas-adapter/guideWindow.js +1 -0
  45. package/dist/packages/canvas-adapter/identityHeader.d.ts +16 -0
  46. package/dist/packages/canvas-adapter/identityHeader.js +1 -1
  47. package/dist/packages/canvas-adapter/index.d.ts +3 -3
  48. package/dist/packages/canvas-adapter/index.js +1 -1
  49. package/dist/packages/canvas-adapter/insightsTab.d.ts +73 -54
  50. package/dist/packages/canvas-adapter/insightsTab.js +1 -1
  51. package/dist/packages/canvas-adapter/maplessSummary.d.ts +2 -2
  52. package/dist/packages/canvas-adapter/plotEditor.d.ts +29 -0
  53. package/dist/packages/canvas-adapter/plotEditor.js +1 -0
  54. package/dist/packages/canvas-adapter/plotItems.d.ts +32 -0
  55. package/dist/packages/canvas-adapter/plotItems.js +1 -0
  56. package/dist/packages/canvas-adapter/plotModal.d.ts +30 -0
  57. package/dist/packages/canvas-adapter/plotModal.js +1 -0
  58. package/dist/packages/canvas-adapter/plotStore.d.ts +52 -0
  59. package/dist/packages/canvas-adapter/plotStore.js +1 -0
  60. package/dist/packages/canvas-adapter/plotTab.d.ts +30 -0
  61. package/dist/packages/canvas-adapter/plotTab.js +1 -0
  62. package/dist/packages/canvas-adapter/renderWaferGallery.d.ts +3 -2
  63. package/dist/packages/canvas-adapter/renderWaferGallery.js +1 -1
  64. package/dist/packages/canvas-adapter/renderWaferMap.d.ts +51 -2
  65. package/dist/packages/canvas-adapter/renderWaferMap.js +1 -1
  66. package/dist/packages/canvas-adapter/summaryPanel.d.ts +49 -11
  67. package/dist/packages/canvas-adapter/summaryPanel.js +2 -3
  68. package/dist/packages/canvas-adapter/summaryRail.d.ts +7 -0
  69. package/dist/packages/canvas-adapter/summaryRail.js +1 -0
  70. package/dist/packages/canvas-adapter/sweepEditor.d.ts +17 -0
  71. package/dist/packages/canvas-adapter/sweepEditor.js +1 -0
  72. package/dist/packages/canvas-adapter/tableExport.d.ts +22 -0
  73. package/dist/packages/canvas-adapter/tableExport.js +3 -0
  74. package/dist/packages/canvas-adapter/toCanvas.js +1 -1
  75. package/dist/packages/canvas-adapter/toolbar.d.ts +74 -93
  76. package/dist/packages/canvas-adapter/toolbar.js +2 -2
  77. package/dist/packages/canvas-adapter/userGuideHtml.d.ts +1 -1
  78. package/dist/packages/canvas-adapter/userGuideHtml.js +409 -51
  79. package/dist/packages/canvas-adapter/version.d.ts +2 -2
  80. package/dist/packages/canvas-adapter/version.js +1 -1
  81. package/dist/packages/canvas-adapter/viewSwitch.d.ts +13 -0
  82. package/dist/packages/canvas-adapter/viewSwitch.js +1 -0
  83. package/dist/packages/canvas-adapter/virtualTable.d.ts +44 -0
  84. package/dist/packages/canvas-adapter/virtualTable.js +1 -0
  85. package/dist/packages/core/aggregates.d.ts +6 -0
  86. package/dist/packages/core/aggregates.js +1 -1
  87. package/dist/packages/core/classify.d.ts +3 -2
  88. package/dist/packages/core/classify.js +1 -1
  89. package/dist/packages/core/compact.d.ts +205 -0
  90. package/dist/packages/core/compact.js +3 -0
  91. package/dist/packages/core/passBins.d.ts +23 -4
  92. package/dist/packages/core/passBins.js +1 -1
  93. package/dist/packages/core/ringCount.d.ts +22 -0
  94. package/dist/packages/core/ringCount.js +1 -0
  95. package/dist/packages/core/tableCsv.d.ts +43 -0
  96. package/dist/packages/core/tableCsv.js +3 -0
  97. package/dist/packages/renderer/axisTicks.d.ts +14 -0
  98. package/dist/packages/renderer/axisTicks.js +1 -1
  99. package/dist/packages/renderer/binColors.d.ts +6 -6
  100. package/dist/packages/renderer/binColors.js +1 -1
  101. package/dist/packages/renderer/buildView.d.ts +27 -2
  102. package/dist/packages/renderer/buildView.js +1 -1
  103. package/dist/packages/renderer/buildWaferMap.js +1 -1
  104. package/dist/packages/renderer/compactView.d.ts +22 -0
  105. package/dist/packages/renderer/compactView.js +1 -0
  106. package/dist/packages/renderer/xyIndicator.d.ts +27 -0
  107. package/dist/packages/renderer/xyIndicator.js +1 -0
  108. package/dist/packages/stats/analyzeWaferLot.d.ts +28 -0
  109. package/dist/packages/stats/analyzeWaferLot.js +1 -1
  110. package/dist/packages/stats/analyzeWaferMap.d.ts +36 -1
  111. package/dist/packages/stats/analyzeWaferMap.js +1 -1
  112. package/dist/packages/stats/binPareto.d.ts +1 -1
  113. package/dist/packages/stats/binPareto.js +1 -1
  114. package/dist/packages/stats/binRows.d.ts +38 -0
  115. package/dist/packages/stats/binRows.js +1 -0
  116. package/dist/packages/stats/filterFindings.d.ts +25 -0
  117. package/dist/packages/stats/filterFindings.js +1 -1
  118. package/dist/packages/stats/findingText.d.ts +9 -0
  119. package/dist/packages/stats/findingText.js +2 -0
  120. package/dist/packages/stats/histogram.d.ts +27 -0
  121. package/dist/packages/stats/histogram.js +1 -1
  122. package/dist/packages/stats/index.d.ts +2 -0
  123. package/dist/packages/stats/index.js +1 -1
  124. package/dist/packages/stats/lotDrift.d.ts +16 -0
  125. package/dist/packages/stats/lotDrift.js +1 -0
  126. package/dist/packages/stats/lotPattern.d.ts +33 -0
  127. package/dist/packages/stats/lotPattern.js +1 -0
  128. package/dist/packages/stats/math.d.ts +60 -6
  129. package/dist/packages/stats/math.js +1 -1
  130. package/dist/packages/stats/patternClassification.d.ts +32 -1
  131. package/dist/packages/stats/patternClassification.js +1 -1
  132. package/dist/packages/stats/plotData.d.ts +258 -0
  133. package/dist/packages/stats/plotData.js +1 -0
  134. package/dist/packages/stats/plotId.d.ts +3 -0
  135. package/dist/packages/stats/plotId.js +1 -0
  136. package/dist/packages/stats/plotSpec.d.ts +119 -0
  137. package/dist/packages/stats/plotSpec.js +4 -0
  138. package/dist/packages/stats/presentation.d.ts +44 -0
  139. package/dist/packages/stats/presentation.js +1 -0
  140. package/dist/packages/stats/regions.d.ts +15 -0
  141. package/dist/packages/stats/regions.js +1 -1
  142. package/dist/packages/stats/renderSummaryReport.d.ts +23 -5
  143. package/dist/packages/stats/renderSummaryReport.js +32 -27
  144. package/dist/packages/stats/reportHtml.d.ts +54 -9
  145. package/dist/packages/stats/reportHtml.js +145 -55
  146. package/dist/packages/stats/scatter.d.ts +6 -0
  147. package/dist/packages/stats/scatter.js +1 -1
  148. package/dist/packages/stats/sweep.d.ts +37 -1
  149. package/dist/packages/stats/sweep.js +1 -1
  150. package/dist/packages/stats/sweepText.d.ts +14 -0
  151. package/dist/packages/stats/sweepText.js +1 -0
  152. package/dist/packages/stats/sweepXFromName.d.ts +14 -0
  153. package/dist/packages/stats/sweepXFromName.js +1 -1
  154. package/dist/packages/stats/synthesis.d.ts +76 -0
  155. package/dist/packages/stats/synthesis.js +2 -0
  156. package/dist/packages/stats/testPassRate.d.ts +6 -0
  157. package/dist/packages/stats/testPassRate.js +1 -1
  158. package/dist/packages/stats/trend.js +1 -1
  159. package/dist/packages/stats/types.d.ts +2 -2
  160. package/dist/packages/stats/yield.d.ts +15 -6
  161. package/dist/packages/stats/yield.js +1 -1
  162. package/dist/packages/stats/yieldRows.d.ts +31 -0
  163. package/dist/packages/stats/yieldRows.js +1 -0
  164. package/llms.txt +16 -4
  165. package/package.json +3 -3
  166. package/dist/packages/stats/findingsNarrative.d.ts +0 -3
  167. 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 raw `text`, a
339
+ * the text through a native save dialog. Receives the content, a
334
340
  * `suggestedName` (already includes its extension), and the `mimeType`.
335
- */
336
- export type SaveTextHandler = (text: string, suggestedName: string, mimeType: string) => void | Promise<void>;
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): CheckMenuRow[];
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))})}