@ni/spright-components 1.0.8 → 1.0.9

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.
@@ -16278,7 +16278,7 @@
16278
16278
 
16279
16279
  /**
16280
16280
  * Do not edit directly
16281
- * Generated on Fri, 31 May 2024 15:10:22 GMT
16281
+ * Generated on Mon, 03 Jun 2024 22:13:03 GMT
16282
16282
  */
16283
16283
 
16284
16284
  const Information100DarkUi = "#a46eff";
@@ -52912,9 +52912,9 @@ img.ProseMirror-separator {
52912
52912
  strong: {
52913
52913
  parseDOM: [
52914
52914
  { tag: "strong" },
52915
- { tag: "b", getAttrs: (node) => node.style.fontWeight != "normal" && null },
52915
+ { tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null },
52916
52916
  { style: "font-weight=400", clearMark: m => m.type.name == "strong" },
52917
- { style: "font-weight", getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
52917
+ { style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
52918
52918
  ],
52919
52919
  toDOM() { return ["strong"]; }
52920
52920
  },
@@ -53168,6 +53168,7 @@ img.ProseMirror-separator {
53168
53168
  code_inline: { mark: "code", noCloseToken: true }
53169
53169
  });
53170
53170
 
53171
+ const blankMark = { open: "", close: "", mixable: true };
53171
53172
  /**
53172
53173
  A specification for serializing a ProseMirror document as
53173
53174
  Markdown/CommonMark text.
@@ -53375,6 +53376,18 @@ img.ProseMirror-separator {
53375
53376
  }
53376
53377
  }
53377
53378
  /**
53379
+ @internal
53380
+ */
53381
+ getMark(name) {
53382
+ let info = this.marks[name];
53383
+ if (!info) {
53384
+ if (this.options.strict !== false)
53385
+ throw new Error(`Mark type \`${name}\` not supported by Markdown renderer`);
53386
+ info = blankMark;
53387
+ }
53388
+ return info;
53389
+ }
53390
+ /**
53378
53391
  Render a block, prefixing each line with `delim`, and the first
53379
53392
  line in `firstDelim`. `node` should be the node that is closed at
53380
53393
  the end of the block, and `f` is a function that renders the
@@ -53439,9 +53452,22 @@ img.ProseMirror-separator {
53439
53452
  Render the given node as a block.
53440
53453
  */
53441
53454
  render(node, parent, index) {
53442
- if (!this.nodes[node.type.name])
53443
- throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
53444
- this.nodes[node.type.name](this, node, parent, index);
53455
+ if (this.nodes[node.type.name]) {
53456
+ this.nodes[node.type.name](this, node, parent, index);
53457
+ }
53458
+ else {
53459
+ if (this.options.strict !== false) {
53460
+ throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
53461
+ }
53462
+ else if (!node.type.isLeaf) {
53463
+ if (node.type.inlineContent)
53464
+ this.renderInline(node);
53465
+ else
53466
+ this.renderContent(node);
53467
+ if (node.isBlock)
53468
+ this.closeBlock(node);
53469
+ }
53470
+ }
53445
53471
  }
53446
53472
  /**
53447
53473
  Render the contents of `parent` as block nodes.
@@ -53472,7 +53498,7 @@ img.ProseMirror-separator {
53472
53498
  // If whitespace has to be expelled from the node, adjust
53473
53499
  // leading and trailing accordingly.
53474
53500
  if (node && node.isText && marks.some(mark => {
53475
- let info = this.marks[mark.type.name];
53501
+ let info = this.getMark(mark.type.name);
53476
53502
  return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
53477
53503
  })) {
53478
53504
  let [_, lead, rest] = /^(\s*)(.*)$/m.exec(node.text);
@@ -53484,7 +53510,7 @@ img.ProseMirror-separator {
53484
53510
  }
53485
53511
  }
53486
53512
  if (node && node.isText && marks.some(mark => {
53487
- let info = this.marks[mark.type.name];
53513
+ let info = this.getMark(mark.type.name);
53488
53514
  return info && info.expelEnclosingWhitespace &&
53489
53515
  (index == parent.childCount - 1 || !mark.isInSet(parent.child(index + 1).marks));
53490
53516
  })) {
@@ -53497,7 +53523,7 @@ img.ProseMirror-separator {
53497
53523
  }
53498
53524
  }
53499
53525
  let inner = marks.length ? marks[marks.length - 1] : null;
53500
- let noEsc = inner && this.marks[inner.type.name].escape === false;
53526
+ let noEsc = inner && this.getMark(inner.type.name).escape === false;
53501
53527
  let len = marks.length - (noEsc ? 1 : 0);
53502
53528
  // Try to reorder 'mixable' marks, such as em and strong, which
53503
53529
  // in Markdown may be opened and closed in different order, so
@@ -53505,11 +53531,11 @@ img.ProseMirror-separator {
53505
53531
  // active.
53506
53532
  outer: for (let i = 0; i < len; i++) {
53507
53533
  let mark = marks[i];
53508
- if (!this.marks[mark.type.name].mixable)
53534
+ if (!this.getMark(mark.type.name).mixable)
53509
53535
  break;
53510
53536
  for (let j = 0; j < active.length; j++) {
53511
53537
  let other = active[j];
53512
- if (!this.marks[other.type.name].mixable)
53538
+ if (!this.getMark(other.type.name).mixable)
53513
53539
  break;
53514
53540
  if (mark.eq(other)) {
53515
53541
  if (i > j)
@@ -53615,7 +53641,7 @@ img.ProseMirror-separator {
53615
53641
  Get the markdown string for a given opening or closing mark.
53616
53642
  */
53617
53643
  markString(mark, open, parent, index) {
53618
- let info = this.marks[mark.type.name];
53644
+ let info = this.getMark(mark.type.name);
53619
53645
  let value = open ? info.open : info.close;
53620
53646
  return typeof value == "string" ? value : value(this, mark, parent, index);
53621
53647
  }
@@ -76724,7 +76750,7 @@ img.ProseMirror-separator {
76724
76750
  /**
76725
76751
  * Prerendering prepares render-ready dies data to be used by the rendering module
76726
76752
  */
76727
- let Prerendering$1 = class Prerendering {
76753
+ class Prerendering {
76728
76754
  get labelsFontSize() {
76729
76755
  return this._labelsFontSize;
76730
76756
  }
@@ -76831,12 +76857,12 @@ img.ProseMirror-separator {
76831
76857
  rgbColor = new ColorRGBA64(rgbColor.r, rgbColor.g, rgbColor.b, this.calculateOpacity(dieTags, highlightedTags));
76832
76858
  return rgbColor.toStringWebRGBA();
76833
76859
  }
76834
- };
76860
+ }
76835
76861
 
76836
76862
  /**
76837
76863
  * Data Manager uses Computations and Prerendering modules in order and exposes the results
76838
76864
  */
76839
- let DataManager$1 = class DataManager {
76865
+ class DataManager {
76840
76866
  get containerDimensions() {
76841
76867
  return this.computations.containerDimensions;
76842
76868
  }
@@ -76873,7 +76899,7 @@ img.ProseMirror-separator {
76873
76899
  constructor(wafermap) {
76874
76900
  this.wafermap = wafermap;
76875
76901
  this.computations = new Computations$1(wafermap);
76876
- this.prerendering = new Prerendering$1(wafermap);
76902
+ this.prerendering = new Prerendering(wafermap);
76877
76903
  }
76878
76904
  updateContainerDimensions() {
76879
76905
  this.computations.updateContainerDimensions();
@@ -76897,258 +76923,6 @@ img.ProseMirror-separator {
76897
76923
  updateDataMap() {
76898
76924
  this.dataMap = new Map(this.wafermap.dies.map(die => [`${die.x}_${die.y}`, die]));
76899
76925
  }
76900
- };
76901
-
76902
- /**
76903
- * Computations calculates and stores different measures which are used in the Wafermap
76904
- */
76905
- class Computations {
76906
- get containerDimensions() {
76907
- return this._containerDimensions;
76908
- }
76909
- get dieDimensions() {
76910
- return this._dieDimensions;
76911
- }
76912
- get margin() {
76913
- return this._margin;
76914
- }
76915
- get horizontalScale() {
76916
- return this._horizontalScale;
76917
- }
76918
- get verticalScale() {
76919
- return this._verticalScale;
76920
- }
76921
- constructor(wafermap) {
76922
- this.wafermap = wafermap;
76923
- this.defaultPadding = 0;
76924
- this.baseMarginPercentage = 0.04;
76925
- }
76926
- update() {
76927
- const canvasDimensions = {
76928
- width: this.wafermap.canvasWidth,
76929
- height: this.wafermap.canvasHeight
76930
- };
76931
- const canvasDiameter = Math.min(canvasDimensions.width, canvasDimensions.height);
76932
- const canvasMargin = {
76933
- top: (canvasDimensions.height - canvasDiameter) / 2,
76934
- right: (canvasDimensions.width - canvasDiameter) / 2,
76935
- bottom: (canvasDimensions.height - canvasDiameter) / 2,
76936
- left: (canvasDimensions.width - canvasDiameter) / 2
76937
- };
76938
- const baseMargin = {
76939
- top: canvasDiameter * this.baseMarginPercentage,
76940
- right: canvasDiameter * this.baseMarginPercentage,
76941
- bottom: canvasDiameter * this.baseMarginPercentage,
76942
- left: canvasDiameter * this.baseMarginPercentage
76943
- };
76944
- this._margin = this.calculateMarginAddition(baseMargin, canvasMargin);
76945
- this._containerDimensions = this.calculateContainerDimensions(canvasDimensions, this._margin);
76946
- const containerDiameter = Math.min(this._containerDimensions.width, this._containerDimensions.height);
76947
- const gridDimensions = this.gridDimensionsValidAndDefined()
76948
- ? this.calculateGridDimensionsFromBoundingBox()
76949
- : this.calculateGridDimensionsFromDies();
76950
- // this scale is used for positioning the dies on the canvas
76951
- const originLocation = this.wafermap.originLocation;
76952
- this._horizontalScale = this.createHorizontalScale(originLocation, gridDimensions, containerDiameter);
76953
- // this scale is used for positioning the dies on the canvas
76954
- this._verticalScale = this.createVerticalScale(originLocation, gridDimensions, containerDiameter);
76955
- this._dieDimensions = {
76956
- width: Math.abs(this._horizontalScale(0) - this._horizontalScale(1)),
76957
- height: Math.abs(this._verticalScale(0) - this._verticalScale(1))
76958
- };
76959
- }
76960
- gridDimensionsValidAndDefined() {
76961
- return (!this.wafermap.validity.invalidGridDimensions
76962
- && typeof this.wafermap.gridMinX === 'number'
76963
- && typeof this.wafermap.gridMinY === 'number'
76964
- && typeof this.wafermap.gridMaxX === 'number'
76965
- && typeof this.wafermap.gridMinX === 'number');
76966
- }
76967
- calculateGridDimensionsFromBoundingBox() {
76968
- const gridDimensions = { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
76969
- if (typeof this.wafermap.gridMaxY === 'number'
76970
- && typeof this.wafermap.gridMinY === 'number'
76971
- && typeof this.wafermap.gridMaxX === 'number'
76972
- && typeof this.wafermap.gridMinX === 'number') {
76973
- gridDimensions.origin.x = this.wafermap.gridMinX;
76974
- gridDimensions.origin.y = this.wafermap.gridMinY;
76975
- gridDimensions.rows = this.wafermap.gridMaxY - this.wafermap.gridMinY + 1;
76976
- gridDimensions.cols = this.wafermap.gridMaxX - this.wafermap.gridMinX + 1;
76977
- }
76978
- return gridDimensions;
76979
- }
76980
- calculateGridDimensionsFromDies() {
76981
- if (this.wafermap.diesTable === undefined) {
76982
- return { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
76983
- }
76984
- const colIndex = this.wafermap.diesTable
76985
- .getChild('colIndex')
76986
- .toArray();
76987
- const rowIndex = this.wafermap.diesTable
76988
- .getChild('rowIndex')
76989
- .toArray();
76990
- const minPoint = { x: colIndex[0], y: rowIndex[0] };
76991
- const maxPoint = { x: colIndex[0], y: rowIndex[0] };
76992
- // will replace iterating with arquero after fixing issues: https://github.com/uwdata/arquero/pull/346
76993
- for (let i = 0; i < colIndex.length; i++) {
76994
- if (colIndex[i] < minPoint.x) {
76995
- minPoint.x = colIndex[i];
76996
- }
76997
- if (colIndex[i] > maxPoint.x) {
76998
- maxPoint.x = colIndex[i];
76999
- }
77000
- if (rowIndex[i] < minPoint.y) {
77001
- minPoint.y = rowIndex[i];
77002
- }
77003
- if (rowIndex[i] > maxPoint.y) {
77004
- maxPoint.y = rowIndex[i];
77005
- }
77006
- }
77007
- return {
77008
- origin: minPoint,
77009
- rows: maxPoint.y - minPoint.y + 1,
77010
- cols: maxPoint.x - minPoint.x + 1
77011
- };
77012
- }
77013
- calculateContainerDimensions(canvasDimensions, margin) {
77014
- return {
77015
- width: canvasDimensions.width - margin.left - margin.right,
77016
- height: canvasDimensions.height - margin.top - margin.bottom
77017
- };
77018
- }
77019
- createHorizontalScale(originLocation, grid, containerWidth) {
77020
- const scale = linear();
77021
- if (originLocation === WaferMapOriginLocation.bottomLeft
77022
- || originLocation === WaferMapOriginLocation.topLeft) {
77023
- return scale
77024
- .domain([grid.origin.x, grid.origin.x + grid.cols])
77025
- .range([0, containerWidth]);
77026
- }
77027
- return scale
77028
- .domain([grid.origin.x - 1, grid.origin.x + grid.cols - 1])
77029
- .range([containerWidth, 0]);
77030
- }
77031
- createVerticalScale(originLocation, grid, containerHeight) {
77032
- const scale = linear();
77033
- // html canvas has top-left origin https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#the_grid
77034
- // we need to flip the vertical scale
77035
- if (originLocation === WaferMapOriginLocation.bottomLeft
77036
- || originLocation === WaferMapOriginLocation.bottomRight) {
77037
- return scale
77038
- .domain([grid.origin.y - 1, grid.origin.y + grid.rows - 1])
77039
- .range([containerHeight, 0]);
77040
- }
77041
- return scale
77042
- .domain([grid.origin.y, grid.origin.y + grid.rows])
77043
- .range([0, containerHeight]);
77044
- }
77045
- calculateMarginAddition(baseMargin, addedMargin) {
77046
- return {
77047
- top: baseMargin.top + addedMargin.top,
77048
- right: baseMargin.right + addedMargin.right,
77049
- bottom: baseMargin.bottom + addedMargin.bottom,
77050
- left: baseMargin.left + addedMargin.left
77051
- };
77052
- }
77053
- }
77054
-
77055
- /**
77056
- * Prerendering prepares render-ready dies data to be used by the rendering module
77057
- */
77058
- class Prerendering {
77059
- get labelsFontSize() {
77060
- return this._labelsFontSize;
77061
- }
77062
- get colorScale() {
77063
- return this._colorScale;
77064
- }
77065
- constructor(wafermap) {
77066
- this.wafermap = wafermap;
77067
- this.fontSizeFactor = 0.8;
77068
- this.colorScaleResolution = 10;
77069
- }
77070
- update() {
77071
- this._labelsFontSize = this.calculateLabelsFontSize(this.wafermap.experimentalDataManager.dieDimensions, this.wafermap.maxCharacters);
77072
- this._colorScale = this.calculateColorScale();
77073
- }
77074
- calculateColorScale() {
77075
- if (this.wafermap.colorScaleMode === WaferMapColorScaleMode.linear) {
77076
- const values = this.wafermap.colorScale.values.map(item => +item);
77077
- const d3ColorScale = linear()
77078
- .domain(values)
77079
- .range(this.wafermap.colorScale.colors);
77080
- let min = values[0];
77081
- let max = values[0];
77082
- values.forEach(value => {
77083
- if (value < min) {
77084
- min = value;
77085
- }
77086
- if (value > max) {
77087
- max = value;
77088
- }
77089
- });
77090
- // the linear color scale will not be infinite but will be limited by the color scale resolution
77091
- const valueSamples = ticks(min, max, values.length * this.colorScaleResolution);
77092
- return valueSamples.map(value => {
77093
- return {
77094
- color: d3ColorScale(value),
77095
- value
77096
- };
77097
- });
77098
- }
77099
- // ordinal color categories have to be sorted by value
77100
- return this.wafermap.colorScale.colors
77101
- .map((color, index) => {
77102
- return {
77103
- color,
77104
- value: +this.wafermap.colorScale.values[index]
77105
- };
77106
- })
77107
- .sort((a, b) => a.value - b.value);
77108
- }
77109
- calculateLabelsFontSize(dieDimensions, maxCharacters) {
77110
- return Math.min(dieDimensions.height, (dieDimensions.width / (Math.max(2, maxCharacters) * 0.5))
77111
- * this.fontSizeFactor);
77112
- }
77113
- }
77114
-
77115
- /**
77116
- * Data Manager uses Computations and Prerendering modules in order and exposes the results
77117
- */
77118
- class DataManager {
77119
- get containerDimensions() {
77120
- return this.computations.containerDimensions;
77121
- }
77122
- get dieDimensions() {
77123
- return this.computations.dieDimensions;
77124
- }
77125
- get margin() {
77126
- return this.computations.margin;
77127
- }
77128
- get horizontalScale() {
77129
- return this.computations.horizontalScale;
77130
- }
77131
- get verticalScale() {
77132
- return this.computations.verticalScale;
77133
- }
77134
- get labelsFontSize() {
77135
- return this.prerendering.labelsFontSize;
77136
- }
77137
- get colorScale() {
77138
- return this.prerendering.colorScale;
77139
- }
77140
- constructor(wafermap) {
77141
- this.wafermap = wafermap;
77142
- this.computations = new Computations(wafermap);
77143
- this.prerendering = new Prerendering(wafermap);
77144
- }
77145
- updateComputations() {
77146
- this.computations.update();
77147
- this.prerendering.update();
77148
- }
77149
- updatePrerendering() {
77150
- this.prerendering.update();
77151
- }
77152
76926
  }
77153
76927
 
77154
76928
  /**
@@ -77307,8 +77081,7 @@ img.ProseMirror-separator {
77307
77081
  this.updateQueued = false;
77308
77082
  }
77309
77083
  get requiresEventsUpdate() {
77310
- return (this.isTracked('highlightedTags')
77311
- || this.isTracked('canvasWidth')
77084
+ return (this.isTracked('canvasWidth')
77312
77085
  || this.isTracked('canvasHeight')
77313
77086
  || this.isTracked('originLocation')
77314
77087
  || this.isTracked('gridMinX')
@@ -77317,15 +77090,35 @@ img.ProseMirror-separator {
77317
77090
  || this.isTracked('gridMaxY')
77318
77091
  || this.isTracked('dies')
77319
77092
  || this.isTracked('maxCharacters')
77093
+ || this.isTracked('highlightedTags')
77320
77094
  || this.isTracked('colorScale')
77321
77095
  || this.isTracked('colorScaleMode')
77322
77096
  || this.isTracked('dieLabelsHidden')
77323
77097
  || this.isTracked('dieLabelsSuffix')
77324
77098
  || this.isTracked('transform'));
77325
77099
  }
77100
+ get requiresWorkerWaferSetup() {
77101
+ return (this.isTracked('canvasWidth')
77102
+ || this.isTracked('canvasHeight')
77103
+ || this.isTracked('originLocation')
77104
+ || this.isTracked('gridMinX')
77105
+ || this.isTracked('gridMaxX')
77106
+ || this.isTracked('gridMinY')
77107
+ || this.isTracked('gridMaxY')
77108
+ || this.isTracked('dies')
77109
+ || this.isTracked('maxCharacters')
77110
+ || this.isTracked('highlightedTags')
77111
+ || this.isTracked('colorScale')
77112
+ || this.isTracked('colorScaleMode')
77113
+ || this.isTracked('dieLabelsHidden')
77114
+ || this.isTracked('dieLabelsSuffix'));
77115
+ }
77326
77116
  get requiresContainerDimensionsUpdate() {
77327
77117
  return this.isTracked('canvasWidth') || this.isTracked('canvasHeight');
77328
77118
  }
77119
+ get requiresComponentResizeUpdate() {
77120
+ return this.isTracked('canvasWidth') || this.isTracked('canvasHeight');
77121
+ }
77329
77122
  get requiresScalesUpdate() {
77330
77123
  return (this.isTracked('originLocation')
77331
77124
  || this.isTracked('gridMinX')
@@ -77334,6 +77127,14 @@ img.ProseMirror-separator {
77334
77127
  || this.isTracked('gridMaxY')
77335
77128
  || this.isTracked('dies'));
77336
77129
  }
77130
+ get requiresInputDataUpdate() {
77131
+ return (this.isTracked('originLocation')
77132
+ || this.isTracked('gridMinX')
77133
+ || this.isTracked('gridMaxX')
77134
+ || this.isTracked('gridMinY')
77135
+ || this.isTracked('gridMaxY')
77136
+ || this.isTracked('dies'));
77137
+ }
77337
77138
  get requiresLabelsFontSizeUpdate() {
77338
77139
  return this.isTracked('maxCharacters');
77339
77140
  }
@@ -77344,6 +77145,14 @@ img.ProseMirror-separator {
77344
77145
  || this.isTracked('dieLabelsHidden')
77345
77146
  || this.isTracked('dieLabelsSuffix'));
77346
77147
  }
77148
+ get requiresColorAndTextUpdate() {
77149
+ return (this.isTracked('maxCharacters')
77150
+ || this.isTracked('highlightedTags')
77151
+ || this.isTracked('colorScale')
77152
+ || this.isTracked('colorScaleMode')
77153
+ || this.isTracked('dieLabelsHidden')
77154
+ || this.isTracked('dieLabelsSuffix'));
77155
+ }
77347
77156
  get requiresDrawnWaferUpdate() {
77348
77157
  return this.isTracked('transform');
77349
77158
  }
@@ -78374,7 +78183,7 @@ img.ProseMirror-separator {
78374
78183
  }
78375
78184
 
78376
78185
  // eslint-disable-next-line no-template-curly-in-string
78377
- const workerCode = "var MatrixRenderer = (function (exports) {\n 'use strict';\n\n /**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n const proxyMarker = Symbol(\"Comlink.proxy\");\n const createEndpoint = Symbol(\"Comlink.endpoint\");\n const releaseProxy = Symbol(\"Comlink.releaseProxy\");\n const finalizer = Symbol(\"Comlink.finalizer\");\n const throwMarker = Symbol(\"Comlink.thrown\");\n const isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n /**\n * Internal transfer handle to handle objects marked to proxy.\n */\n const proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n };\n /**\n * Internal transfer handler to handle thrown exceptions.\n */\n const throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n };\n /**\n * Allows customizing the serialization of certain values.\n */\n const transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n ]);\n function isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n }\n function expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n }\n function isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n }\n function closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n }\n function wrap(ep, target) {\n return createProxy(ep, [], target);\n }\n function throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n }\n function releaseEndpoint(ep) {\n return requestResponseMessage(ep, {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n }\n const proxyCounter = new WeakMap();\n const proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\n function registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n }\n function unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n }\n function createProxy(ep, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n }\n function myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n }\n function processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n }\n const transferCache = new WeakMap();\n function transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n }\n function proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n }\n function toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n }\n function fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n }\n function requestResponseMessage(ep, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n ep.addEventListener(\"message\", function l(ev) {\n if (!ev.data || !ev.data.id || ev.data.id !== id) {\n return;\n }\n ep.removeEventListener(\"message\", l);\n resolve(ev.data);\n });\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n }\n function generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n }\n\n /**\n * MatrixRenderer class is meant to be used within a Web Worker context,\n * using Comlink to facilitate communication between the main thread and the worker.\n * The MatrixRenderer class manages a matrix of dies, once an instance of MatrixRenderer is created,\n * it is exposed to the main thread using Comlink's `expose` method.\n * This setup is used in the wafer-map component to perform heavy computational duties\n */\n class MatrixRenderer {\n constructor() {\n this.columnIndexes = Int32Array.from([]);\n this.rowIndexes = Int32Array.from([]);\n this.values = Float64Array.from([]);\n this.scaledColumnIndex = Float64Array.from([]);\n this.scaledRowIndex = Float64Array.from([]);\n this.columnIndexPositions = Int32Array.from([]);\n this.scaleX = 1;\n this.scaleY = 1;\n this.baseX = 1;\n this.baseY = 1;\n this.dieDimensions = { width: 1, height: 1 };\n this.transform = { k: 1, x: 0, y: 0 };\n this.smallestMarginPossible = 20;\n this.margin = {\n top: this.smallestMarginPossible,\n right: this.smallestMarginPossible,\n bottom: this.smallestMarginPossible,\n left: this.smallestMarginPossible\n };\n }\n calculateXScaledIndex(columnIndex) {\n return this.scaleX * columnIndex + this.baseX + this.margin.left;\n }\n calculateYScaledIndex(rowIndex) {\n return this.scaleY * rowIndex + this.baseY + this.margin.top;\n }\n setColumnIndexes(columnIndexes) {\n this.columnIndexes = columnIndexes;\n if (columnIndexes.length === 0 || this.columnIndexes[0] === undefined) {\n return;\n }\n const scaledColumnIndex = [\n this.calculateXScaledIndex(this.columnIndexes[0])\n ];\n const columnPositions = [0];\n let prev = this.columnIndexes[0];\n for (let i = 1; i < this.columnIndexes.length; i++) {\n const xIndex = this.columnIndexes[i];\n if (xIndex && xIndex !== prev) {\n const scaledX = this.calculateXScaledIndex(this.columnIndexes[i]);\n scaledColumnIndex.push(scaledX);\n columnPositions.push(i);\n prev = xIndex;\n }\n }\n this.scaledColumnIndex = Float64Array.from(scaledColumnIndex);\n this.columnIndexPositions = Int32Array.from(columnPositions);\n }\n setRowIndexes(rowIndexesBuffer) {\n this.rowIndexes = rowIndexesBuffer;\n this.scaledRowIndex = new Float64Array(this.rowIndexes.length);\n for (let i = 0; i < this.rowIndexes.length; i++) {\n this.scaledRowIndex[i] = this.calculateYScaledIndex(this.rowIndexes[i]);\n }\n }\n setMargin(margin) {\n this.margin = margin;\n }\n setCanvasCorners(topLeft, bottomRight) {\n this.topLeftCanvasCorner = topLeft;\n this.bottomRightCanvasCorner = bottomRight;\n }\n setDiesDimensions(data) {\n this.dieDimensions = { width: data.width, height: data.height };\n }\n setScaling(scaleX, scaleY) {\n this.scaleX = scaleX;\n this.scaleY = scaleY;\n }\n setBases(baseX, baseY) {\n this.baseX = baseX;\n this.baseY = baseY;\n }\n setTransform(transform) {\n this.transform = transform;\n }\n setCanvas(canvas) {\n this.canvas = canvas;\n this.context = canvas.getContext('2d');\n }\n getMatrix() {\n return {\n columnIndexes: this.columnIndexes,\n rowIndexes: this.rowIndexes,\n values: this.values\n };\n }\n emptyMatrix() {\n this.columnIndexes = Int32Array.from([]);\n this.rowIndexes = Int32Array.from([]);\n this.values = Float64Array.from([]);\n }\n scaleCanvas() {\n this.context.translate(this.transform.x, this.transform.y);\n this.context.scale(this.transform.k, this.transform.k);\n }\n updateMatrix(data) {\n this.columnIndexes = Int32Array.from(data.columnIndexes);\n this.rowIndexes = Int32Array.from(data.rowIndexes);\n this.values = Float64Array.from(data.values);\n }\n setCanvasDimensions(data) {\n this.canvas.width = data.width;\n this.canvas.height = data.height;\n }\n getCanvasDimensions() {\n return {\n width: this.canvas.width,\n height: this.canvas.height\n };\n }\n clearCanvas() {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n drawWafer() {\n this.context.restore();\n this.context.save();\n this.clearCanvas();\n this.scaleCanvas();\n if (this.topLeftCanvasCorner === undefined\n || this.bottomRightCanvasCorner === undefined) {\n throw new Error('Canvas corners are not set');\n }\n for (let i = 0; i < this.scaledColumnIndex.length; i++) {\n const scaledX = this.scaledColumnIndex[i];\n if (!(scaledX >= this.topLeftCanvasCorner.x\n && scaledX < this.bottomRightCanvasCorner.x)) {\n continue;\n }\n // columnIndexPositions is used to get chunks to determine the start and end index of the column, it looks something like [0, 1, 4, 9, 12]\n // This means that the first column has a start index of 0 and an end index of 1, the second column has a start index of 1 and an end index of 4, and so on\n // scaledRowIndex is used when we reach the end of the columnIndexPositions, when columnIndexPositions is [0, 1, 4, 9, 12], scaledRowIndex is 13\n const columnEndIndex = this.columnIndexPositions[i + 1] !== undefined\n ? this.columnIndexPositions[i + 1]\n : this.scaledRowIndex.length;\n for (let columnStartIndex = this.columnIndexPositions[i]; columnStartIndex < columnEndIndex; columnStartIndex++) {\n const scaledY = this.scaledRowIndex[columnStartIndex];\n if (!(scaledY >= this.topLeftCanvasCorner.y\n && scaledY < this.bottomRightCanvasCorner.y)) {\n continue;\n }\n // Fill style is temporary green for all dies, will be replaced with a color based on the value of the die in a future implementation\n this.context.fillStyle = 'Green';\n this.context.fillRect(scaledX, scaledY, this.dieDimensions.width, this.dieDimensions.height);\n }\n }\n }\n }\n expose(MatrixRenderer);\n\n exports.MatrixRenderer = MatrixRenderer;\n\n return exports;\n\n})({});\n";
78186
+ const workerCode = "var MatrixRenderer = (function (exports) {\n 'use strict';\n\n /**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n const proxyMarker = Symbol(\"Comlink.proxy\");\n const createEndpoint = Symbol(\"Comlink.endpoint\");\n const releaseProxy = Symbol(\"Comlink.releaseProxy\");\n const finalizer = Symbol(\"Comlink.finalizer\");\n const throwMarker = Symbol(\"Comlink.thrown\");\n const isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n /**\n * Internal transfer handle to handle objects marked to proxy.\n */\n const proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n };\n /**\n * Internal transfer handler to handle thrown exceptions.\n */\n const throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n };\n /**\n * Allows customizing the serialization of certain values.\n */\n const transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n ]);\n function isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n }\n function expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n }\n function isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n }\n function closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n }\n function wrap(ep, target) {\n return createProxy(ep, [], target);\n }\n function throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n }\n function releaseEndpoint(ep) {\n return requestResponseMessage(ep, {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n }\n const proxyCounter = new WeakMap();\n const proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\n function registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n }\n function unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n }\n function createProxy(ep, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n }\n function myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n }\n function processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n }\n const transferCache = new WeakMap();\n function transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n }\n function proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n }\n function toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n }\n function fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n }\n function requestResponseMessage(ep, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n ep.addEventListener(\"message\", function l(ev) {\n if (!ev.data || !ev.data.id || ev.data.id !== id) {\n return;\n }\n ep.removeEventListener(\"message\", l);\n resolve(ev.data);\n });\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n }\n function generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n }\n\n /**\n * MatrixRenderer class is meant to be used within a Web Worker context,\n * using Comlink to facilitate communication between the main thread and the worker.\n * The MatrixRenderer class manages a matrix of dies, once an instance of MatrixRenderer is created,\n * it is exposed to the main thread using Comlink's `expose` method.\n * This setup is used in the wafer-map component to perform heavy computational duties\n */\n class MatrixRenderer {\n constructor() {\n this.values = Float64Array.from([]);\n this.scaledColumnIndices = Float64Array.from([]);\n this.scaledRowIndices = Float64Array.from([]);\n this.columnIndicesPositions = Int32Array.from([]);\n this.renderConfig = {\n dieDimensions: {\n width: 0,\n height: 0\n },\n margin: {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0\n },\n verticalCoefficient: 1,\n horizontalCoefficient: 1,\n horizontalConstant: 0,\n verticalConstant: 0,\n labelsFontSize: 0,\n colorScale: []\n };\n this.transformConfig = {\n transform: {\n k: 1,\n x: 0,\n y: 0\n },\n topLeftCanvasCorner: {\n x: 0,\n y: 0\n },\n bottomRightCanvasCorner: {\n x: 0,\n y: 0\n }\n };\n }\n calculateHorizontalScaledIndices(columnIndex) {\n return (this.renderConfig.horizontalCoefficient * columnIndex\n + this.renderConfig.horizontalConstant\n + this.renderConfig.margin.left);\n }\n calculateVerticalScaledIndices(rowIndex) {\n return (this.renderConfig.verticalCoefficient * rowIndex\n + this.renderConfig.verticalConstant\n + this.renderConfig.margin.top);\n }\n setColumnIndices(columnIndices) {\n if (columnIndices.length === 0 || columnIndices[0] === undefined) {\n return;\n }\n const scaledColumnIndex = [\n this.calculateHorizontalScaledIndices(columnIndices[0])\n ];\n const columnPositions = [0];\n let prev = columnIndices[0];\n for (let i = 1; i < columnIndices.length; i++) {\n const xIndex = columnIndices[i];\n if (xIndex && xIndex !== prev) {\n const scaledX = this.calculateHorizontalScaledIndices(columnIndices[i]);\n scaledColumnIndex.push(scaledX);\n columnPositions.push(i);\n prev = xIndex;\n }\n }\n this.scaledColumnIndices = Float64Array.from(scaledColumnIndex);\n this.columnIndicesPositions = Int32Array.from(columnPositions);\n }\n setRowIndices(rowIndices) {\n this.scaledRowIndices = new Float64Array(rowIndices.length);\n for (let i = 0; i < rowIndices.length; i++) {\n this.scaledRowIndices[i] = this.calculateVerticalScaledIndices(rowIndices[i]);\n }\n }\n setRenderConfig(renderConfig) {\n this.renderConfig = renderConfig;\n }\n setTransformConfig(transformData) {\n this.transformConfig = transformData;\n }\n setCanvas(canvas) {\n this.canvas = canvas;\n this.context = canvas.getContext('2d');\n }\n scaleCanvas() {\n this.context.translate(this.transformConfig.transform.x, this.transformConfig.transform.y);\n this.context.scale(this.transformConfig.transform.k, this.transformConfig.transform.k);\n }\n setCanvasDimensions(data) {\n this.canvas.width = data.width;\n this.canvas.height = data.height;\n }\n getCanvasDimensions() {\n return {\n width: this.canvas.width,\n height: this.canvas.height\n };\n }\n clearCanvas() {\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n }\n drawWafer() {\n this.context.restore();\n this.context.save();\n this.clearCanvas();\n this.scaleCanvas();\n for (let i = 0; i < this.scaledColumnIndices.length; i++) {\n const scaledX = this.scaledColumnIndices[i];\n if (!(scaledX >= this.transformConfig.topLeftCanvasCorner.x\n && scaledX < this.transformConfig.bottomRightCanvasCorner.x)) {\n continue;\n }\n // columnIndexPositions is used to get chunks to determine the start and end index of the column, it looks something like [0, 1, 4, 9, 12]\n // This means that the first column has a start index of 0 and an end index of 1, the second column has a start index of 1 and an end index of 4, and so on\n // scaledRowIndices is used when we reach the end of the columnIndexPositions, when columnIndexPositions is [0, 1, 4, 9, 12], scaledRowIndices is 13\n const columnEndIndex = this.columnIndicesPositions[i + 1] !== undefined\n ? this.columnIndicesPositions[i + 1]\n : this.scaledRowIndices.length;\n for (let columnStartIndex = this.columnIndicesPositions[i]; columnStartIndex < columnEndIndex; columnStartIndex++) {\n const scaledY = this.scaledRowIndices[columnStartIndex];\n if (!(scaledY >= this.transformConfig.topLeftCanvasCorner.y\n && scaledY < this.transformConfig.bottomRightCanvasCorner.y)) {\n continue;\n }\n // Fill style is temporary green for all dies, will be replaced with a color based on the value of the die in a future implementation\n this.context.fillStyle = 'Green';\n this.context.fillRect(scaledX, scaledY, this.renderConfig.dieDimensions.width, this.renderConfig.dieDimensions.height);\n }\n }\n }\n }\n expose(MatrixRenderer);\n\n exports.MatrixRenderer = MatrixRenderer;\n\n return exports;\n\n})({});\n";
78378
78187
 
78379
78188
  let url;
78380
78189
  /**
@@ -78404,66 +78213,45 @@ img.ProseMirror-separator {
78404
78213
  constructor(wafermap) {
78405
78214
  this.wafermap = wafermap;
78406
78215
  }
78407
- async setupWafer() {
78216
+ async setupWafer(snapshot) {
78408
78217
  if (this.matrixRenderer === undefined) {
78409
78218
  const { matrixRenderer } = await createMatrixRenderer();
78410
78219
  this.matrixRenderer = matrixRenderer;
78411
78220
  const offscreenCanvas = this.wafermap.workerCanvas.transferControlToOffscreen();
78412
78221
  await this.matrixRenderer.setCanvas(transfer(offscreenCanvas, [offscreenCanvas]));
78413
78222
  }
78414
- await this.matrixRenderer.setCanvasDimensions({
78415
- width: this.wafermap.canvasWidth ?? 0,
78416
- height: this.wafermap.canvasHeight ?? 0
78417
- });
78418
- await this.matrixRenderer.setDiesDimensions(this.wafermap.experimentalDataManager.dieDimensions);
78419
- const scaleX = this.wafermap.experimentalDataManager.horizontalScale(1)
78420
- - this.wafermap.experimentalDataManager.horizontalScale(0);
78421
- const scaleY = this.wafermap.experimentalDataManager.verticalScale(1)
78422
- - this.wafermap.experimentalDataManager.verticalScale(0);
78423
- await this.matrixRenderer.setScaling(scaleX, scaleY);
78424
- await this.matrixRenderer.setBases(this.wafermap.experimentalDataManager.horizontalScale(0), this.wafermap.experimentalDataManager.verticalScale(0));
78425
- await this.matrixRenderer.setMargin(this.wafermap.experimentalDataManager.margin);
78426
- if (this.wafermap.diesTable === undefined) {
78427
- await this.matrixRenderer.setColumnIndexes(Int32Array.from([]));
78428
- await this.matrixRenderer.setRowIndexes(Int32Array.from([]));
78429
- return;
78430
- }
78431
- const columnIndexes = this.wafermap.diesTable
78432
- .getChild('colIndex')
78433
- .toArray();
78434
- await this.matrixRenderer.setColumnIndexes(columnIndexes);
78435
- const rowIndexes = this.wafermap.diesTable
78436
- .getChild('rowIndex')
78437
- .toArray();
78438
- await this.matrixRenderer.setRowIndexes(rowIndexes);
78439
- }
78440
- async drawWafer() {
78441
- await this.matrixRenderer.setTransform(this.wafermap.transform);
78442
- const topLeftCanvasCorner = this.wafermap.transform.invert([0, 0]);
78443
- const bottomRightCanvasCorner = this.wafermap.transform.invert([
78444
- this.wafermap.canvasWidth,
78445
- this.wafermap.canvasHeight
78223
+ await this.matrixRenderer.setCanvasDimensions(snapshot.canvasDimensions);
78224
+ await this.matrixRenderer.setRenderConfig(snapshot.renderConfig);
78225
+ await this.matrixRenderer.setColumnIndices(snapshot.columnIndices);
78226
+ await this.matrixRenderer.setRowIndices(snapshot.rowIndices);
78227
+ }
78228
+ async drawWafer(snapshot) {
78229
+ const topLeftCanvasCorner = snapshot.transform.invert([0, 0]);
78230
+ const bottomRightCanvasCorner = snapshot.transform.invert([
78231
+ snapshot.canvasDimensions.width,
78232
+ snapshot.canvasDimensions.height
78446
78233
  ]);
78447
- await this.matrixRenderer.setCanvasCorners({
78448
- x: topLeftCanvasCorner[0]
78449
- - this.wafermap.experimentalDataManager.dieDimensions.width,
78450
- y: topLeftCanvasCorner[1]
78451
- - this.wafermap.experimentalDataManager.dieDimensions.height
78452
- }, {
78453
- x: bottomRightCanvasCorner[0],
78454
- y: bottomRightCanvasCorner[1]
78234
+ await this.matrixRenderer.setTransformConfig({
78235
+ transform: snapshot.transform,
78236
+ topLeftCanvasCorner: {
78237
+ x: topLeftCanvasCorner[0] - snapshot.dieDimensions.width,
78238
+ y: topLeftCanvasCorner[1] - snapshot.dieDimensions.height
78239
+ },
78240
+ bottomRightCanvasCorner: {
78241
+ x: bottomRightCanvasCorner[0],
78242
+ y: bottomRightCanvasCorner[1]
78243
+ }
78455
78244
  });
78456
78245
  await this.matrixRenderer.drawWafer();
78457
- this.renderHover();
78458
78246
  }
78459
78247
  renderHover() {
78460
- if (this.wafermap.experimentalDataManager.dieDimensions === undefined
78248
+ if (this.wafermap.computations.dieDimensions === undefined
78461
78249
  || this.wafermap.transform === undefined) {
78462
78250
  return;
78463
78251
  }
78464
- this.wafermap.hoverWidth = this.wafermap.experimentalDataManager.dieDimensions.width
78252
+ this.wafermap.hoverWidth = this.wafermap.computations.dieDimensions.width
78465
78253
  * this.wafermap.transform.k;
78466
- this.wafermap.hoverHeight = this.wafermap.experimentalDataManager.dieDimensions.height
78254
+ this.wafermap.hoverHeight = this.wafermap.computations.dieDimensions.height
78467
78255
  * this.wafermap.transform.k;
78468
78256
  this.wafermap.hoverOpacity = this.wafermap.hoverDie === undefined
78469
78257
  ? HoverDieOpacity.hide
@@ -78472,17 +78260,17 @@ img.ProseMirror-separator {
78472
78260
  }
78473
78261
  calculateHoverTransform() {
78474
78262
  if (this.wafermap.hoverDie !== undefined) {
78475
- const scaledX = this.wafermap.experimentalDataManager.horizontalScale(this.wafermap.hoverDie.x);
78263
+ const scaledX = this.wafermap.computations.horizontalScale(this.wafermap.hoverDie.x);
78476
78264
  if (scaledX === undefined) {
78477
78265
  return '';
78478
78266
  }
78479
- const scaledY = this.wafermap.experimentalDataManager.verticalScale(this.wafermap.hoverDie.y);
78267
+ const scaledY = this.wafermap.computations.verticalScale(this.wafermap.hoverDie.y);
78480
78268
  if (scaledY === undefined) {
78481
78269
  return '';
78482
78270
  }
78483
78271
  const transformedPoint = this.wafermap.transform.apply([
78484
- scaledX + this.wafermap.experimentalDataManager.margin.left,
78485
- scaledY + this.wafermap.experimentalDataManager.margin.top
78272
+ scaledX + this.wafermap.computations.margin.left,
78273
+ scaledY + this.wafermap.computations.margin.top
78486
78274
  ]);
78487
78275
  return `translate(${transformedPoint[0]}, ${transformedPoint[1]})`;
78488
78276
  }
@@ -78642,10 +78430,8 @@ img.ProseMirror-separator {
78642
78430
  ? Math.ceil
78643
78431
  : Math.floor;
78644
78432
  // go to x and y scale to get the x,y values of the die.
78645
- const x = xRoundFunction(this.wafermap.experimentalDataManager.horizontalScale.invert(mousePosition.x
78646
- - this.wafermap.experimentalDataManager.margin.left));
78647
- const y = yRoundFunction(this.wafermap.experimentalDataManager.verticalScale.invert(mousePosition.y
78648
- - this.wafermap.experimentalDataManager.margin.top));
78433
+ const x = xRoundFunction(this.wafermap.computations.horizontalScale.invert(mousePosition.x - this.wafermap.computations.margin.left));
78434
+ const y = yRoundFunction(this.wafermap.computations.verticalScale.invert(mousePosition.y - this.wafermap.computations.margin.top));
78649
78435
  return { x, y };
78650
78436
  }
78651
78437
  return undefined;
@@ -78704,6 +78490,237 @@ img.ProseMirror-separator {
78704
78490
  }
78705
78491
  }
78706
78492
 
78493
+ /**
78494
+ * Computations calculates and stores different measures which are used in the Wafermap
78495
+ */
78496
+ class Computations {
78497
+ get horizontalScale() {
78498
+ return this._horizontalScale;
78499
+ }
78500
+ get verticalScale() {
78501
+ return this._verticalScale;
78502
+ }
78503
+ get containerDimensions() {
78504
+ return this._containerDimensions;
78505
+ }
78506
+ get dieDimensions() {
78507
+ return this._dieDimensions;
78508
+ }
78509
+ get margin() {
78510
+ return this._margin;
78511
+ }
78512
+ get verticalCoefficient() {
78513
+ return this._verticalCoefficient;
78514
+ }
78515
+ get horizontalCoefficient() {
78516
+ return this._horizontalCoefficient;
78517
+ }
78518
+ get horizontalConstant() {
78519
+ return this._horizontalConstant;
78520
+ }
78521
+ get verticalConstant() {
78522
+ return this._verticalConstant;
78523
+ }
78524
+ get labelsFontSize() {
78525
+ return this._labelsFontSize;
78526
+ }
78527
+ get colorScale() {
78528
+ return this._colorScale;
78529
+ }
78530
+ constructor(wafermap) {
78531
+ this.wafermap = wafermap;
78532
+ this.baseMarginPercentage = 0.04;
78533
+ this.fontSizeFactor = 0.8;
78534
+ this.colorScaleResolution = 10;
78535
+ }
78536
+ componentResizeUpdate() {
78537
+ const canvasDimensions = {
78538
+ width: this.wafermap.canvasWidth,
78539
+ height: this.wafermap.canvasHeight
78540
+ };
78541
+ const canvasDiameter = Math.min(canvasDimensions.width, canvasDimensions.height);
78542
+ const canvasMargin = {
78543
+ top: (canvasDimensions.height - canvasDiameter) / 2,
78544
+ right: (canvasDimensions.width - canvasDiameter) / 2,
78545
+ bottom: (canvasDimensions.height - canvasDiameter) / 2,
78546
+ left: (canvasDimensions.width - canvasDiameter) / 2
78547
+ };
78548
+ const baseMargin = {
78549
+ top: canvasDiameter * this.baseMarginPercentage,
78550
+ right: canvasDiameter * this.baseMarginPercentage,
78551
+ bottom: canvasDiameter * this.baseMarginPercentage,
78552
+ left: canvasDiameter * this.baseMarginPercentage
78553
+ };
78554
+ this._margin = this.calculateMarginAddition(baseMargin, canvasMargin);
78555
+ this._containerDimensions = this.calculateContainerDimensions(canvasDimensions, this.margin);
78556
+ this.inputDataUpdate();
78557
+ }
78558
+ inputDataUpdate() {
78559
+ if (this._containerDimensions === undefined) {
78560
+ this.componentResizeUpdate();
78561
+ return;
78562
+ }
78563
+ const containerDiameter = Math.min(this._containerDimensions.width, this._containerDimensions.height);
78564
+ const gridDimensions = this.gridDimensionsValidAndDefined()
78565
+ ? this.calculateGridDimensionsFromBoundingBox()
78566
+ : this.calculateGridDimensionsFromDies();
78567
+ // this scale is used for positioning the dies on the canvas
78568
+ const originLocation = this.wafermap.originLocation;
78569
+ this._horizontalScale = this.createHorizontalScale(originLocation, gridDimensions, containerDiameter);
78570
+ // this scale is used for positioning the dies on the canvas
78571
+ this._verticalScale = this.createVerticalScale(originLocation, gridDimensions, containerDiameter);
78572
+ this._horizontalCoefficient = this._horizontalScale(1) - this._horizontalScale(0);
78573
+ this._verticalCoefficient = this._verticalScale(1) - this._verticalScale(0);
78574
+ this._horizontalConstant = this._horizontalScale(0);
78575
+ this._verticalConstant = this._verticalScale(0);
78576
+ this._dieDimensions = {
78577
+ width: Math.abs(this._horizontalScale(0) - this._horizontalScale(1)),
78578
+ height: Math.abs(this._verticalScale(0) - this._verticalScale(1))
78579
+ };
78580
+ this.colorAndTextUpdate();
78581
+ }
78582
+ colorAndTextUpdate() {
78583
+ if (this._dieDimensions === undefined) {
78584
+ this.inputDataUpdate();
78585
+ return;
78586
+ }
78587
+ this._labelsFontSize = this.calculateLabelsFontSize(this._dieDimensions, this.wafermap.maxCharacters);
78588
+ this._colorScale = this.calculateColorScale();
78589
+ }
78590
+ gridDimensionsValidAndDefined() {
78591
+ return (!this.wafermap.validity.invalidGridDimensions
78592
+ && typeof this.wafermap.gridMinX === 'number'
78593
+ && typeof this.wafermap.gridMinY === 'number'
78594
+ && typeof this.wafermap.gridMaxX === 'number'
78595
+ && typeof this.wafermap.gridMinX === 'number');
78596
+ }
78597
+ calculateGridDimensionsFromBoundingBox() {
78598
+ const gridDimensions = { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
78599
+ if (typeof this.wafermap.gridMaxY === 'number'
78600
+ && typeof this.wafermap.gridMinY === 'number'
78601
+ && typeof this.wafermap.gridMaxX === 'number'
78602
+ && typeof this.wafermap.gridMinX === 'number') {
78603
+ gridDimensions.origin.x = this.wafermap.gridMinX;
78604
+ gridDimensions.origin.y = this.wafermap.gridMinY;
78605
+ gridDimensions.rows = this.wafermap.gridMaxY - this.wafermap.gridMinY + 1;
78606
+ gridDimensions.cols = this.wafermap.gridMaxX - this.wafermap.gridMinX + 1;
78607
+ }
78608
+ return gridDimensions;
78609
+ }
78610
+ calculateGridDimensionsFromDies() {
78611
+ if (this.wafermap.diesTable === undefined) {
78612
+ return { origin: { x: 0, y: 0 }, rows: 0, cols: 0 };
78613
+ }
78614
+ const colIndex = this.wafermap.diesTable
78615
+ .getChild('colIndex')
78616
+ .toArray();
78617
+ const rowIndex = this.wafermap.diesTable
78618
+ .getChild('rowIndex')
78619
+ .toArray();
78620
+ const minPoint = { x: colIndex[0], y: rowIndex[0] };
78621
+ const maxPoint = { x: colIndex[0], y: rowIndex[0] };
78622
+ // will replace iterating with arquero after fixing issues: https://github.com/uwdata/arquero/pull/346
78623
+ for (let i = 0; i < colIndex.length; i++) {
78624
+ if (colIndex[i] < minPoint.x) {
78625
+ minPoint.x = colIndex[i];
78626
+ }
78627
+ if (colIndex[i] > maxPoint.x) {
78628
+ maxPoint.x = colIndex[i];
78629
+ }
78630
+ if (rowIndex[i] < minPoint.y) {
78631
+ minPoint.y = rowIndex[i];
78632
+ }
78633
+ if (rowIndex[i] > maxPoint.y) {
78634
+ maxPoint.y = rowIndex[i];
78635
+ }
78636
+ }
78637
+ return {
78638
+ origin: minPoint,
78639
+ rows: maxPoint.y - minPoint.y + 1,
78640
+ cols: maxPoint.x - minPoint.x + 1
78641
+ };
78642
+ }
78643
+ calculateContainerDimensions(canvasDimensions, margin) {
78644
+ return {
78645
+ width: canvasDimensions.width - margin.left - margin.right,
78646
+ height: canvasDimensions.height - margin.top - margin.bottom
78647
+ };
78648
+ }
78649
+ createHorizontalScale(originLocation, grid, containerWidth) {
78650
+ const scale = linear();
78651
+ if (originLocation === WaferMapOriginLocation.bottomLeft
78652
+ || originLocation === WaferMapOriginLocation.topLeft) {
78653
+ return scale
78654
+ .domain([grid.origin.x, grid.origin.x + grid.cols])
78655
+ .range([0, containerWidth]);
78656
+ }
78657
+ return scale
78658
+ .domain([grid.origin.x - 1, grid.origin.x + grid.cols - 1])
78659
+ .range([containerWidth, 0]);
78660
+ }
78661
+ createVerticalScale(originLocation, grid, containerHeight) {
78662
+ const scale = linear();
78663
+ // html canvas has top-left origin https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#the_grid
78664
+ // we need to flip the vertical scale
78665
+ if (originLocation === WaferMapOriginLocation.bottomLeft
78666
+ || originLocation === WaferMapOriginLocation.bottomRight) {
78667
+ return scale
78668
+ .domain([grid.origin.y - 1, grid.origin.y + grid.rows - 1])
78669
+ .range([containerHeight, 0]);
78670
+ }
78671
+ return scale
78672
+ .domain([grid.origin.y, grid.origin.y + grid.rows])
78673
+ .range([0, containerHeight]);
78674
+ }
78675
+ calculateMarginAddition(baseMargin, addedMargin) {
78676
+ return {
78677
+ top: baseMargin.top + addedMargin.top,
78678
+ right: baseMargin.right + addedMargin.right,
78679
+ bottom: baseMargin.bottom + addedMargin.bottom,
78680
+ left: baseMargin.left + addedMargin.left
78681
+ };
78682
+ }
78683
+ calculateColorScale() {
78684
+ if (this.wafermap.colorScaleMode === WaferMapColorScaleMode.linear) {
78685
+ const values = this.wafermap.colorScale.values.map(item => +item);
78686
+ const d3ColorScale = linear()
78687
+ .domain(values)
78688
+ .range(this.wafermap.colorScale.colors);
78689
+ let min = values[0];
78690
+ let max = values[0];
78691
+ values.forEach(value => {
78692
+ if (value < min) {
78693
+ min = value;
78694
+ }
78695
+ if (value > max) {
78696
+ max = value;
78697
+ }
78698
+ });
78699
+ // the linear color scale will not be infinite but will be limited by the color scale resolution
78700
+ const valueSamples = ticks(min, max, values.length * this.colorScaleResolution);
78701
+ return valueSamples.map(value => {
78702
+ return {
78703
+ color: d3ColorScale(value),
78704
+ value
78705
+ };
78706
+ });
78707
+ }
78708
+ // ordinal color categories have to be sorted by value
78709
+ return this.wafermap.colorScale.colors
78710
+ .map((color, index) => {
78711
+ return {
78712
+ color,
78713
+ value: +this.wafermap.colorScale.values[index]
78714
+ };
78715
+ })
78716
+ .sort((a, b) => a.value - b.value);
78717
+ }
78718
+ calculateLabelsFontSize(dieDimensions, maxCharacters) {
78719
+ return Math.min(dieDimensions.height, (dieDimensions.width / (Math.max(2, maxCharacters) * 0.5))
78720
+ * this.fontSizeFactor);
78721
+ }
78722
+ }
78723
+
78707
78724
  /**
78708
78725
  * A nimble-styled WaferMap
78709
78726
  */
@@ -78725,8 +78742,8 @@ img.ProseMirror-separator {
78725
78742
  this.dieLabelsHidden = false;
78726
78743
  this.dieLabelsSuffix = '';
78727
78744
  this.colorScaleMode = WaferMapColorScaleMode.linear;
78728
- this.experimentalDataManager = new DataManager(this.asRequiredFieldsWaferMap);
78729
- this.dataManager = new DataManager$1(this.asRequiredFieldsWaferMap);
78745
+ this.computations = new Computations(this.asRequiredFieldsWaferMap);
78746
+ this.dataManager = new DataManager(this.asRequiredFieldsWaferMap);
78730
78747
  this.workerRenderer = new WorkerRenderer(this.asRequiredFieldsWaferMap);
78731
78748
  this.renderer = new RenderingModule(this.asRequiredFieldsWaferMap);
78732
78749
  /**
@@ -78795,24 +78812,22 @@ img.ProseMirror-separator {
78795
78812
  return;
78796
78813
  }
78797
78814
  if (this.waferMapUpdateTracker.requiresEventsUpdate) {
78798
- if (this.waferMapUpdateTracker.requiresContainerDimensionsUpdate
78799
- || this.waferMapUpdateTracker.requiresScalesUpdate) {
78800
- this.experimentalDataManager.updateComputations();
78801
- await this.workerRenderer.setupWafer();
78802
- await this.workerRenderer.drawWafer();
78815
+ if (this.waferMapUpdateTracker.requiresComponentResizeUpdate) {
78816
+ this.computations.componentResizeUpdate();
78803
78817
  }
78804
- else if (this.waferMapUpdateTracker.requiresLabelsFontSizeUpdate
78805
- || this.waferMapUpdateTracker.requiresDiesRenderInfoUpdate) {
78806
- this.experimentalDataManager.updatePrerendering();
78807
- await this.workerRenderer.drawWafer();
78818
+ else if (this.waferMapUpdateTracker.requiresInputDataUpdate) {
78819
+ this.computations.inputDataUpdate();
78808
78820
  }
78809
- else if (this.waferMapUpdateTracker.requiresDrawnWaferUpdate) {
78810
- await this.workerRenderer.drawWafer();
78821
+ else if (this.waferMapUpdateTracker.requiresColorAndTextUpdate) {
78822
+ this.computations.colorAndTextUpdate();
78811
78823
  }
78824
+ const snapshot = this.createSnapshot();
78825
+ if (this.waferMapUpdateTracker.requiresWorkerWaferSetup) {
78826
+ await this.workerRenderer.setupWafer(snapshot);
78827
+ }
78828
+ await this.workerRenderer.drawWafer(snapshot);
78812
78829
  }
78813
- else if (this.waferMapUpdateTracker.requiresRenderHoverUpdate) {
78814
- this.workerRenderer.renderHover();
78815
- }
78830
+ this.workerRenderer.renderHover();
78816
78831
  }
78817
78832
  /**
78818
78833
  * @internal
@@ -78859,6 +78874,44 @@ img.ProseMirror-separator {
78859
78874
  isExperimentalUpdate() {
78860
78875
  return this.diesTable !== undefined;
78861
78876
  }
78877
+ createSnapshot() {
78878
+ const canvasDimensions = {
78879
+ width: this.canvasWidth ?? 0,
78880
+ height: this.canvasHeight ?? 0
78881
+ };
78882
+ const renderConfig = {
78883
+ dieDimensions: this.computations.dieDimensions,
78884
+ margin: this.computations.margin,
78885
+ verticalCoefficient: this.computations.verticalCoefficient,
78886
+ horizontalCoefficient: this.computations.horizontalCoefficient,
78887
+ horizontalConstant: this.computations.horizontalConstant,
78888
+ verticalConstant: this.computations.verticalConstant,
78889
+ labelsFontSize: this.computations.labelsFontSize,
78890
+ colorScale: this.computations.colorScale
78891
+ };
78892
+ const dieDimensions = this.computations.dieDimensions;
78893
+ const transform = this.transform;
78894
+ if (this.diesTable === undefined) {
78895
+ return {
78896
+ canvasDimensions,
78897
+ renderConfig,
78898
+ dieDimensions,
78899
+ transform,
78900
+ columnIndices: Int32Array.from([]),
78901
+ rowIndices: Int32Array.from([])
78902
+ };
78903
+ }
78904
+ const columnIndices = this.diesTable.getChild('colIndex').toArray();
78905
+ const rowIndices = this.diesTable.getChild('rowIndex').toArray();
78906
+ return {
78907
+ canvasDimensions,
78908
+ renderConfig,
78909
+ columnIndices,
78910
+ rowIndices,
78911
+ dieDimensions,
78912
+ transform
78913
+ };
78914
+ }
78862
78915
  validate() {
78863
78916
  this.waferMapValidator.validateGridDimensions();
78864
78917
  this.waferMapValidator.validateDiesTableSchema();