@ni/nimble-components 32.7.0 → 32.7.2

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.
@@ -31748,8 +31748,24 @@ so this becomes the fallback color for the slot */ ''}
31748
31748
  return joinable($pos.nodeBefore, $pos.nodeAfter) &&
31749
31749
  $pos.parent.canReplace(index, index + 1);
31750
31750
  }
31751
+ function canAppendWithSubstitutedLinebreaks(a, b) {
31752
+ if (!b.content.size)
31753
+ a.type.compatibleContent(b.type);
31754
+ let match = a.contentMatchAt(a.childCount);
31755
+ let { linebreakReplacement } = a.type.schema;
31756
+ for (let i = 0; i < b.childCount; i++) {
31757
+ let child = b.child(i);
31758
+ let type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type;
31759
+ match = match.matchType(type);
31760
+ if (!match)
31761
+ return false;
31762
+ if (!a.type.allowsMarks(child.marks))
31763
+ return false;
31764
+ }
31765
+ return match.validEnd;
31766
+ }
31751
31767
  function joinable(a, b) {
31752
- return !!(a && b && !a.isLeaf && a.canAppend(b));
31768
+ return !!(a && b && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b));
31753
31769
  }
31754
31770
  /**
31755
31771
  Find an ancestor of the given position that can be joined to the
@@ -31782,8 +31798,31 @@ so this becomes the fallback color for the slot */ ''}
31782
31798
  }
31783
31799
  }
31784
31800
  function join(tr, pos, depth) {
31785
- let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true);
31786
- tr.step(step);
31801
+ let convertNewlines = null;
31802
+ let { linebreakReplacement } = tr.doc.type.schema;
31803
+ let $before = tr.doc.resolve(pos - depth), beforeType = $before.node().type;
31804
+ if (linebreakReplacement && beforeType.inlineContent) {
31805
+ let pre = beforeType.whitespace == "pre";
31806
+ let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement);
31807
+ if (pre && !supportLinebreak)
31808
+ convertNewlines = false;
31809
+ else if (!pre && supportLinebreak)
31810
+ convertNewlines = true;
31811
+ }
31812
+ let mapFrom = tr.steps.length;
31813
+ if (convertNewlines === false) {
31814
+ let $after = tr.doc.resolve(pos + depth);
31815
+ replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom);
31816
+ }
31817
+ if (beforeType.inlineContent)
31818
+ clearIncompatible(tr, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null);
31819
+ let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos - depth);
31820
+ tr.step(new ReplaceStep(start, mapping.map(pos + depth, -1), Slice.empty, true));
31821
+ if (convertNewlines === true) {
31822
+ let $full = tr.doc.resolve(start);
31823
+ replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length);
31824
+ }
31825
+ return tr;
31787
31826
  }
31788
31827
  /**
31789
31828
  Try to find a point where a node of the given type can be inserted
@@ -32267,7 +32306,8 @@ so this becomes the fallback color for the slot */ ''}
32267
32306
  return tr.delete($from.before(depth), $to.after(depth));
32268
32307
  }
32269
32308
  for (let d = 1; d <= $from.depth && d <= $to.depth; d++) {
32270
- if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d)
32309
+ if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d &&
32310
+ $from.start(d - 1) == $to.start(d - 1) && $from.node(d - 1).canReplace($from.index(d - 1), $to.index(d - 1)))
32271
32311
  return tr.delete($from.before(d), to);
32272
32312
  }
32273
32313
  tr.delete(from, to);
@@ -34860,16 +34900,17 @@ so this becomes the fallback color for the slot */ ''}
34860
34900
  // some cases they will be split more often than would appear
34861
34901
  // necessary.
34862
34902
  class MarkViewDesc extends ViewDesc {
34863
- constructor(parent, mark, dom, contentDOM) {
34903
+ constructor(parent, mark, dom, contentDOM, spec) {
34864
34904
  super(parent, [], dom, contentDOM);
34865
34905
  this.mark = mark;
34906
+ this.spec = spec;
34866
34907
  }
34867
34908
  static create(parent, mark, inline, view) {
34868
34909
  let custom = view.nodeViews[mark.type.name];
34869
34910
  let spec = custom && custom(mark, view, inline);
34870
34911
  if (!spec || !spec.dom)
34871
34912
  spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs);
34872
- return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom);
34913
+ return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom, spec);
34873
34914
  }
34874
34915
  parseRule() {
34875
34916
  if ((this.dirty & NODE_DIRTY) || this.mark.type.spec.reparseInView)
@@ -34901,6 +34942,11 @@ so this becomes the fallback color for the slot */ ''}
34901
34942
  copy.children = nodes;
34902
34943
  return copy;
34903
34944
  }
34945
+ destroy() {
34946
+ if (this.spec.destroy)
34947
+ this.spec.destroy();
34948
+ super.destroy();
34949
+ }
34904
34950
  }
34905
34951
  // Node view descs are the main, most common type of view desc, and
34906
34952
  // correspond to an actual node in the document. Unlike mark descs,
@@ -35220,7 +35266,7 @@ so this becomes the fallback color for the slot */ ''}
35220
35266
  update(node, outerDeco, innerDeco, view) {
35221
35267
  if (this.dirty == NODE_DIRTY)
35222
35268
  return false;
35223
- if (this.spec.update) {
35269
+ if (this.spec.update && (this.node.type == node.type || this.spec.multiType)) {
35224
35270
  let result = this.spec.update(node, outerDeco, innerDeco);
35225
35271
  if (result)
35226
35272
  this.updateInner(node, outerDeco, innerDeco, view);
@@ -36621,6 +36667,7 @@ so this becomes the fallback color for the slot */ ''}
36621
36667
  function detachedDoc() {
36622
36668
  return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title"));
36623
36669
  }
36670
+ let _policy = null;
36624
36671
  function maybeWrapTrusted(html) {
36625
36672
  let trustedTypes = window.trustedTypes;
36626
36673
  if (!trustedTypes)
@@ -36628,7 +36675,9 @@ so this becomes the fallback color for the slot */ ''}
36628
36675
  // With the require-trusted-types-for CSP, Chrome will block
36629
36676
  // innerHTML, even on a detached document. This wraps the string in
36630
36677
  // a way that makes the browser allow us to use its parser again.
36631
- return trustedTypes.createPolicy("detachedDocument", { createHTML: (s) => s }).createHTML(html);
36678
+ if (!_policy)
36679
+ _policy = trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
36680
+ return _policy.createHTML(html);
36632
36681
  }
36633
36682
  function readHTML(html) {
36634
36683
  let metas = /^(\s*<meta [^>]*>)*/.exec(html);
@@ -36779,9 +36828,7 @@ so this becomes the fallback color for the slot */ ''}
36779
36828
  // and handling them eagerly tends to corrupt the input.
36780
36829
  if (android && chrome && event.keyCode == 13)
36781
36830
  return;
36782
- if (view.domObserver.selectionChanged(view.domSelectionRange()))
36783
- view.domObserver.flush();
36784
- else if (event.keyCode != 229)
36831
+ if (event.keyCode != 229)
36785
36832
  view.domObserver.forceFlush();
36786
36833
  // On iOS, if we preventDefault enter key presses, the virtual
36787
36834
  // keyboard gets confused. So the hack here is to set a flag that
@@ -38303,9 +38350,6 @@ so this becomes the fallback color for the slot */ ''}
38303
38350
  this.queue.push(mut);
38304
38351
  return this.queue;
38305
38352
  }
38306
- selectionChanged(sel) {
38307
- return !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(this.view) && !this.ignoreSelectionChange(sel);
38308
- }
38309
38353
  flush() {
38310
38354
  let { view } = this;
38311
38355
  if (!view.docView || this.flushingSoon > -1)
@@ -38313,7 +38357,8 @@ so this becomes the fallback color for the slot */ ''}
38313
38357
  let mutations = this.pendingRecords();
38314
38358
  if (mutations.length)
38315
38359
  this.queue = [];
38316
- let sel = view.domSelectionRange(), newSel = this.selectionChanged(sel);
38360
+ let sel = view.domSelectionRange();
38361
+ let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
38317
38362
  let from = -1, to = -1, typeOver = false, added = [];
38318
38363
  if (view.editable) {
38319
38364
  for (let i = 0; i < mutations.length; i++) {
@@ -40089,10 +40134,7 @@ so this becomes the fallback color for the slot */ ''}
40089
40134
  if (!$pos.parent.canReplace(index, index + 1) || !(after.isTextblock || canJoin(state.doc, $pos.pos)))
40090
40135
  return false;
40091
40136
  if (dispatch)
40092
- dispatch(state.tr
40093
- .clearIncompatible($pos.pos, before.type, before.contentMatchAt(before.childCount))
40094
- .join($pos.pos)
40095
- .scrollIntoView());
40137
+ dispatch(state.tr.join($pos.pos).scrollIntoView());
40096
40138
  return true;
40097
40139
  }
40098
40140
  function deleteBarrier(state, $cut, dispatch, dir) {
@@ -40110,9 +40152,10 @@ so this becomes the fallback color for the slot */ ''}
40110
40152
  wrap = Fragment.from(conn[i].create(null, wrap));
40111
40153
  wrap = Fragment.from(before.copy(wrap));
40112
40154
  let tr = state.tr.step(new ReplaceAroundStep($cut.pos - 1, end, $cut.pos, end, new Slice(wrap, 1, 0), conn.length, true));
40113
- let joinAt = end + 2 * conn.length;
40114
- if (canJoin(tr.doc, joinAt))
40115
- tr.join(joinAt);
40155
+ let $joinAt = tr.doc.resolve(end + 2 * conn.length);
40156
+ if ($joinAt.nodeAfter && $joinAt.nodeAfter.type == before.type &&
40157
+ canJoin(tr.doc, $joinAt.pos))
40158
+ tr.join($joinAt.pos);
40116
40159
  dispatch(tr.scrollIntoView());
40117
40160
  }
40118
40161
  return true;
@@ -55758,84 +55801,8 @@ img.ProseMirror-separator {
55758
55801
  },
55759
55802
  });
55760
55803
 
55761
- /**
55762
- * This extension allows you to create list items.
55763
- * @see https://www.tiptap.dev/api/nodes/list-item
55764
- */
55765
- const ListItem = Node$1.create({
55766
- name: 'listItem',
55767
- addOptions() {
55768
- return {
55769
- HTMLAttributes: {},
55770
- bulletListTypeName: 'bulletList',
55771
- orderedListTypeName: 'orderedList',
55772
- };
55773
- },
55774
- content: 'paragraph block*',
55775
- defining: true,
55776
- parseHTML() {
55777
- return [
55778
- {
55779
- tag: 'li',
55780
- },
55781
- ];
55782
- },
55783
- renderHTML({ HTMLAttributes }) {
55784
- return ['li', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
55785
- },
55786
- addKeyboardShortcuts() {
55787
- return {
55788
- Enter: () => this.editor.commands.splitListItem(this.name),
55789
- Tab: () => this.editor.commands.sinkListItem(this.name),
55790
- 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
55791
- };
55792
- },
55793
- });
55794
-
55795
- /**
55796
- * This extension allows you to create text styles. It is required by default
55797
- * for the `textColor` and `backgroundColor` extensions.
55798
- * @see https://www.tiptap.dev/api/marks/text-style
55799
- */
55800
- const TextStyle = Mark.create({
55801
- name: 'textStyle',
55802
- priority: 101,
55803
- addOptions() {
55804
- return {
55805
- HTMLAttributes: {},
55806
- };
55807
- },
55808
- parseHTML() {
55809
- return [
55810
- {
55811
- tag: 'span',
55812
- getAttrs: element => {
55813
- const hasStyles = element.hasAttribute('style');
55814
- if (!hasStyles) {
55815
- return false;
55816
- }
55817
- return {};
55818
- },
55819
- },
55820
- ];
55821
- },
55822
- renderHTML({ HTMLAttributes }) {
55823
- return ['span', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
55824
- },
55825
- addCommands() {
55826
- return {
55827
- removeEmptyTextStyle: () => ({ state, commands }) => {
55828
- const attributes = getMarkAttributes(state, this.type);
55829
- const hasStyles = Object.entries(attributes).some(([, value]) => !!value);
55830
- if (hasStyles) {
55831
- return true;
55832
- }
55833
- return commands.unsetMark(this.name);
55834
- },
55835
- };
55836
- },
55837
- });
55838
-
55804
+ const ListItemName$1 = 'listItem';
55805
+ const TextStyleName$1 = 'textStyle';
55839
55806
  /**
55840
55807
  * Matches a bullet list to a dash or asterisk.
55841
55808
  */
@@ -55872,7 +55839,7 @@ img.ProseMirror-separator {
55872
55839
  return {
55873
55840
  toggleBulletList: () => ({ commands, chain }) => {
55874
55841
  if (this.options.keepAttributes) {
55875
- return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItem.name, this.editor.getAttributes(TextStyle.name)).run();
55842
+ return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName$1, this.editor.getAttributes(TextStyleName$1)).run();
55876
55843
  }
55877
55844
  return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
55878
55845
  },
@@ -55894,7 +55861,7 @@ img.ProseMirror-separator {
55894
55861
  type: this.type,
55895
55862
  keepMarks: this.options.keepMarks,
55896
55863
  keepAttributes: this.options.keepAttributes,
55897
- getAttributes: () => { return this.editor.getAttributes(TextStyle.name); },
55864
+ getAttributes: () => { return this.editor.getAttributes(TextStyleName$1); },
55898
55865
  editor: this.editor,
55899
55866
  });
55900
55867
  }
@@ -58756,6 +58723,40 @@ img.ProseMirror-separator {
58756
58723
  },
58757
58724
  });
58758
58725
 
58726
+ /**
58727
+ * This extension allows you to create list items.
58728
+ * @see https://www.tiptap.dev/api/nodes/list-item
58729
+ */
58730
+ const ListItem = Node$1.create({
58731
+ name: 'listItem',
58732
+ addOptions() {
58733
+ return {
58734
+ HTMLAttributes: {},
58735
+ bulletListTypeName: 'bulletList',
58736
+ orderedListTypeName: 'orderedList',
58737
+ };
58738
+ },
58739
+ content: 'paragraph block*',
58740
+ defining: true,
58741
+ parseHTML() {
58742
+ return [
58743
+ {
58744
+ tag: 'li',
58745
+ },
58746
+ ];
58747
+ },
58748
+ renderHTML({ HTMLAttributes }) {
58749
+ return ['li', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0];
58750
+ },
58751
+ addKeyboardShortcuts() {
58752
+ return {
58753
+ Enter: () => this.editor.commands.splitListItem(this.name),
58754
+ Tab: () => this.editor.commands.sinkListItem(this.name),
58755
+ 'Shift-Tab': () => this.editor.commands.liftListItem(this.name),
58756
+ };
58757
+ },
58758
+ });
58759
+
58759
58760
  function findSuggestionMatch(config) {
58760
58761
  var _a;
58761
58762
  const { char, allowSpaces, allowedPrefixes, startOfLine, $position, } = config;
@@ -59162,6 +59163,8 @@ img.ProseMirror-separator {
59162
59163
  },
59163
59164
  });
59164
59165
 
59166
+ const ListItemName = 'listItem';
59167
+ const TextStyleName = 'textStyle';
59165
59168
  /**
59166
59169
  * Matches an ordered list to a 1. on input (or any number followed by a dot).
59167
59170
  */
@@ -59219,7 +59222,7 @@ img.ProseMirror-separator {
59219
59222
  return {
59220
59223
  toggleOrderedList: () => ({ commands, chain }) => {
59221
59224
  if (this.options.keepAttributes) {
59222
- return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItem.name, this.editor.getAttributes(TextStyle.name)).run();
59225
+ return chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(ListItemName, this.editor.getAttributes(TextStyleName)).run();
59223
59226
  }
59224
59227
  return commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks);
59225
59228
  },
@@ -59243,7 +59246,7 @@ img.ProseMirror-separator {
59243
59246
  type: this.type,
59244
59247
  keepMarks: this.options.keepMarks,
59245
59248
  keepAttributes: this.options.keepAttributes,
59246
- getAttributes: match => ({ start: +match[1], ...this.editor.getAttributes(TextStyle.name) }),
59249
+ getAttributes: match => ({ start: +match[1], ...this.editor.getAttributes(TextStyleName) }),
59247
59250
  joinPredicate: (match, node) => node.childCount + node.attrs.start === +match[1],
59248
59251
  editor: this.editor,
59249
59252
  });
@@ -67658,7 +67661,7 @@ focus outline in that case.
67658
67661
  return;
67659
67662
  }
67660
67663
  let offset = 0;
67661
- const fallback = supportsScrollend ? () => void 0 : debounce(
67664
+ const fallback = instance.options.useScrollendEvent && supportsScrollend ? () => void 0 : debounce(
67662
67665
  targetWindow,
67663
67666
  () => {
67664
67667
  cb(offset, false);
@@ -67780,6 +67783,7 @@ focus outline in that case.
67780
67783
  isScrollingResetDelay: 150,
67781
67784
  enabled: true,
67782
67785
  isRtl: false,
67786
+ useScrollendEvent: true,
67783
67787
  ...opts2
67784
67788
  };
67785
67789
  };
@@ -83712,7 +83716,7 @@ focus outline in that case.
83712
83716
  constructor(parent, rowIndex) {
83713
83717
  this[kParent] = parent;
83714
83718
  this[kRowIndex] = rowIndex;
83715
- return new Proxy(this, new StructRowProxyHandler());
83719
+ return new Proxy(this, structRowProxyHandler);
83716
83720
  }
83717
83721
  toArray() { return Object.values(this.toJSON()); }
83718
83722
  toJSON() {
@@ -83772,10 +83776,10 @@ focus outline in that case.
83772
83776
  return row[kParent].type.children.map((f) => f.name);
83773
83777
  }
83774
83778
  has(row, key) {
83775
- return row[kParent].type.children.findIndex((f) => f.name === key) !== -1;
83779
+ return row[kParent].type.children.some((f) => f.name === key);
83776
83780
  }
83777
83781
  getOwnPropertyDescriptor(row, key) {
83778
- if (row[kParent].type.children.findIndex((f) => f.name === key) !== -1) {
83782
+ if (row[kParent].type.children.some((f) => f.name === key)) {
83779
83783
  return { writable: true, enumerable: true, configurable: true };
83780
83784
  }
83781
83785
  return;
@@ -83806,6 +83810,7 @@ focus outline in that case.
83806
83810
  return false;
83807
83811
  }
83808
83812
  }
83813
+ const structRowProxyHandler = new StructRowProxyHandler();
83809
83814
 
83810
83815
  // Licensed to the Apache Software Foundation (ASF) under one
83811
83816
  // or more contributor license agreements. See the NOTICE file
@@ -85727,7 +85732,7 @@ focus outline in that case.
85727
85732
  this.fields = (fields || []);
85728
85733
  this.metadata = metadata || new Map();
85729
85734
  if (!dictionaries) {
85730
- dictionaries = generateDictionaryMap(fields);
85735
+ dictionaries = generateDictionaryMap(this.fields);
85731
85736
  }
85732
85737
  this.dictionaries = dictionaries;
85733
85738
  this.metadataVersion = metadataVersion;
@@ -89124,13 +89129,10 @@ focus outline in that case.
89124
89129
  const { id, isDelta } = header;
89125
89130
  const { dictionaries, schema } = this;
89126
89131
  const dictionary = dictionaries.get(id);
89127
- if (isDelta || !dictionary) {
89128
- const type = schema.dictionaries.get(id);
89129
- const data = this._loadVectors(header.data, body, [type]);
89130
- return (dictionary && isDelta ? dictionary.concat(new Vector(data)) :
89131
- new Vector(data)).memoize();
89132
- }
89133
- return dictionary.memoize();
89132
+ const type = schema.dictionaries.get(id);
89133
+ const data = this._loadVectors(header.data, body, [type]);
89134
+ return (dictionary && isDelta ? dictionary.concat(new Vector(data)) :
89135
+ new Vector(data)).memoize();
89134
89136
  }
89135
89137
  _loadVectors(header, body, types) {
89136
89138
  return new VectorLoader(body, header.nodes, header.buffers, this.dictionaries, this.schema.metadataVersion).visitMany(types);
@@ -91509,7 +91511,24 @@ focus outline in that case.
91509
91511
  endpoint.close();
91510
91512
  }
91511
91513
  function wrap(ep, target) {
91512
- return createProxy(ep, [], target);
91514
+ const pendingListeners = new Map();
91515
+ ep.addEventListener("message", function handleMessage(ev) {
91516
+ const { data } = ev;
91517
+ if (!data || !data.id) {
91518
+ return;
91519
+ }
91520
+ const resolver = pendingListeners.get(data.id);
91521
+ if (!resolver) {
91522
+ return;
91523
+ }
91524
+ try {
91525
+ resolver(data);
91526
+ }
91527
+ finally {
91528
+ pendingListeners.delete(data.id);
91529
+ }
91530
+ });
91531
+ return createProxy(ep, pendingListeners, [], target);
91513
91532
  }
91514
91533
  function throwIfProxyReleased(isReleased) {
91515
91534
  if (isReleased) {
@@ -91517,7 +91536,7 @@ focus outline in that case.
91517
91536
  }
91518
91537
  }
91519
91538
  function releaseEndpoint(ep) {
91520
- return requestResponseMessage(ep, {
91539
+ return requestResponseMessage(ep, new Map(), {
91521
91540
  type: "RELEASE" /* MessageType.RELEASE */,
91522
91541
  }).then(() => {
91523
91542
  closeEndPoint(ep);
@@ -91544,7 +91563,7 @@ focus outline in that case.
91544
91563
  proxyFinalizers.unregister(proxy);
91545
91564
  }
91546
91565
  }
91547
- function createProxy(ep, path = [], target = function () { }) {
91566
+ function createProxy(ep, pendingListeners, path = [], target = function () { }) {
91548
91567
  let isProxyReleased = false;
91549
91568
  const proxy = new Proxy(target, {
91550
91569
  get(_target, prop) {
@@ -91553,6 +91572,7 @@ focus outline in that case.
91553
91572
  return () => {
91554
91573
  unregisterProxy(proxy);
91555
91574
  releaseEndpoint(ep);
91575
+ pendingListeners.clear();
91556
91576
  isProxyReleased = true;
91557
91577
  };
91558
91578
  }
@@ -91560,20 +91580,20 @@ focus outline in that case.
91560
91580
  if (path.length === 0) {
91561
91581
  return { then: () => proxy };
91562
91582
  }
91563
- const r = requestResponseMessage(ep, {
91583
+ const r = requestResponseMessage(ep, pendingListeners, {
91564
91584
  type: "GET" /* MessageType.GET */,
91565
91585
  path: path.map((p) => p.toString()),
91566
91586
  }).then(fromWireValue);
91567
91587
  return r.then.bind(r);
91568
91588
  }
91569
- return createProxy(ep, [...path, prop]);
91589
+ return createProxy(ep, pendingListeners, [...path, prop]);
91570
91590
  },
91571
91591
  set(_target, prop, rawValue) {
91572
91592
  throwIfProxyReleased(isProxyReleased);
91573
91593
  // FIXME: ES6 Proxy Handler `set` methods are supposed to return a
91574
91594
  // boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
91575
91595
  const [value, transferables] = toWireValue(rawValue);
91576
- return requestResponseMessage(ep, {
91596
+ return requestResponseMessage(ep, pendingListeners, {
91577
91597
  type: "SET" /* MessageType.SET */,
91578
91598
  path: [...path, prop].map((p) => p.toString()),
91579
91599
  value,
@@ -91583,16 +91603,16 @@ focus outline in that case.
91583
91603
  throwIfProxyReleased(isProxyReleased);
91584
91604
  const last = path[path.length - 1];
91585
91605
  if (last === createEndpoint) {
91586
- return requestResponseMessage(ep, {
91606
+ return requestResponseMessage(ep, pendingListeners, {
91587
91607
  type: "ENDPOINT" /* MessageType.ENDPOINT */,
91588
91608
  }).then(fromWireValue);
91589
91609
  }
91590
91610
  // We just pretend that `bind()` didn’t happen.
91591
91611
  if (last === "bind") {
91592
- return createProxy(ep, path.slice(0, -1));
91612
+ return createProxy(ep, pendingListeners, path.slice(0, -1));
91593
91613
  }
91594
91614
  const [argumentList, transferables] = processArguments(rawArgumentList);
91595
- return requestResponseMessage(ep, {
91615
+ return requestResponseMessage(ep, pendingListeners, {
91596
91616
  type: "APPLY" /* MessageType.APPLY */,
91597
91617
  path: path.map((p) => p.toString()),
91598
91618
  argumentList,
@@ -91601,7 +91621,7 @@ focus outline in that case.
91601
91621
  construct(_target, rawArgumentList) {
91602
91622
  throwIfProxyReleased(isProxyReleased);
91603
91623
  const [argumentList, transferables] = processArguments(rawArgumentList);
91604
- return requestResponseMessage(ep, {
91624
+ return requestResponseMessage(ep, pendingListeners, {
91605
91625
  type: "CONSTRUCT" /* MessageType.CONSTRUCT */,
91606
91626
  path: path.map((p) => p.toString()),
91607
91627
  argumentList,
@@ -91656,16 +91676,10 @@ focus outline in that case.
91656
91676
  return value.value;
91657
91677
  }
91658
91678
  }
91659
- function requestResponseMessage(ep, msg, transfers) {
91679
+ function requestResponseMessage(ep, pendingListeners, msg, transfers) {
91660
91680
  return new Promise((resolve) => {
91661
91681
  const id = generateUUID();
91662
- ep.addEventListener("message", function l(ev) {
91663
- if (!ev.data || !ev.data.id || ev.data.id !== id) {
91664
- return;
91665
- }
91666
- ep.removeEventListener("message", l);
91667
- resolve(ev.data);
91668
- });
91682
+ pendingListeners.set(id, resolve);
91669
91683
  if (ep.start) {
91670
91684
  ep.start();
91671
91685
  }
@@ -91679,7 +91693,7 @@ focus outline in that case.
91679
91693
  .join("-");
91680
91694
  }
91681
91695
 
91682
- 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.colorIndices = Int32Array.from([]);\n this.colors = [];\n this.colorValues = Float64Array.from([]);\n this.outsideRangeDieColor = 'rgba(218,223,236,1)';\n this.fontSizeFactor = 0.8;\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 gridMinX: 0,\n gridMaxX: 0,\n gridMinY: 0,\n gridMaxY: 0,\n labelsFontSize: 0,\n colorScale: [],\n dieLabelsSuffix: '',\n maxCharacters: 0\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 setMatrixData(columnIndices, rowIndices, valuesBuffer) {\n const scaledColumnIndex = [];\n const columnPositions = [];\n const scaledRowIndices = [];\n const values = [];\n const colorIndices = [];\n let prevXIndex;\n let dieCount = 0;\n for (let i = 0; i < columnIndices.length; i++) {\n const xIndex = columnIndices[i];\n const yIndex = rowIndices[i];\n if (this.isDieInGrid(xIndex, yIndex)) {\n if (xIndex !== prevXIndex) {\n scaledColumnIndex.push(this.calculateHorizontalScaledIndices(xIndex));\n columnPositions.push(dieCount);\n prevXIndex = xIndex;\n }\n scaledRowIndices.push(this.calculateVerticalScaledIndices(yIndex));\n const value = valuesBuffer[i];\n values.push(value);\n colorIndices.push(this.findColorIndex(value));\n dieCount += 1;\n }\n }\n this.scaledColumnIndices = Float64Array.from(scaledColumnIndex);\n this.columnIndicesPositions = Int32Array.from(columnPositions);\n this.scaledRowIndices = Float64Array.from(scaledRowIndices);\n this.values = Float64Array.from(values);\n this.colorIndices = Int32Array.from(colorIndices);\n }\n setRenderConfig(renderConfig) {\n this.renderConfig = renderConfig;\n this.colors = renderConfig.colorScale.map(marker => marker.color);\n this.colorValues = Float64Array.from(renderConfig.colorScale.map(marker => marker.value));\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 = this.colors[this.colorIndices[columnStartIndex]]\n ?? this.outsideRangeDieColor;\n this.context.fillRect(scaledX, scaledY, this.renderConfig.dieDimensions.width, this.renderConfig.dieDimensions.height);\n }\n }\n }\n drawText() {\n this.context.font = `${this.renderConfig.labelsFontSize.toString()}px sans-serif`;\n this.context.fillStyle = '#ffffff';\n this.context.textAlign = 'center';\n this.context.lineCap = 'butt';\n const approximateTextHeight = this.context.measureText('M');\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 let label = `${this.values[columnStartIndex] || 'NaN'}${this.renderConfig.dieLabelsSuffix}`;\n if (label.length >= this.renderConfig.maxCharacters) {\n label = `${label.substring(0, this.renderConfig.maxCharacters)}…`;\n }\n this.context.fillText(label, scaledX + this.renderConfig.dieDimensions.width / 2, scaledY\n + this.renderConfig.dieDimensions.height / 2\n + approximateTextHeight.width / 2, this.renderConfig.dieDimensions.width * this.fontSizeFactor);\n }\n }\n }\n isDieInGrid(x, y) {\n return (x >= this.renderConfig.gridMinX\n && x <= this.renderConfig.gridMaxX\n && y >= this.renderConfig.gridMinY\n && y <= this.renderConfig.gridMaxY);\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 findColorIndex(value) {\n let index = -1;\n if (this.colorValues.length === 0 || this.colorValues[0] >= value) {\n return index;\n }\n for (let i = 0; i < this.colorValues.length; i++) {\n if (value <= this.colorValues[i]) {\n index = i;\n break;\n }\n }\n return index;\n }\n }\n expose(MatrixRenderer);\n\n exports.MatrixRenderer = MatrixRenderer;\n\n return exports;\n\n})({});\n";
91696
+ 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 const pendingListeners = new Map();\n ep.addEventListener(\"message\", function handleMessage(ev) {\n const { data } = ev;\n if (!data || !data.id) {\n return;\n }\n const resolver = pendingListeners.get(data.id);\n if (!resolver) {\n return;\n }\n try {\n resolver(data);\n }\n finally {\n pendingListeners.delete(data.id);\n }\n });\n return createProxy(ep, pendingListeners, [], 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, new Map(), {\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, pendingListeners, 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 pendingListeners.clear();\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, pendingListeners, {\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, pendingListeners, [...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, pendingListeners, {\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, pendingListeners, {\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, pendingListeners, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, pendingListeners, {\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, pendingListeners, {\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, pendingListeners, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n pendingListeners.set(id, resolve);\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.colorIndices = Int32Array.from([]);\n this.colors = [];\n this.colorValues = Float64Array.from([]);\n this.outsideRangeDieColor = 'rgba(218,223,236,1)';\n this.fontSizeFactor = 0.8;\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 gridMinX: 0,\n gridMaxX: 0,\n gridMinY: 0,\n gridMaxY: 0,\n labelsFontSize: 0,\n colorScale: [],\n dieLabelsSuffix: '',\n maxCharacters: 0\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 setMatrixData(columnIndices, rowIndices, valuesBuffer) {\n const scaledColumnIndex = [];\n const columnPositions = [];\n const scaledRowIndices = [];\n const values = [];\n const colorIndices = [];\n let prevXIndex;\n let dieCount = 0;\n for (let i = 0; i < columnIndices.length; i++) {\n const xIndex = columnIndices[i];\n const yIndex = rowIndices[i];\n if (this.isDieInGrid(xIndex, yIndex)) {\n if (xIndex !== prevXIndex) {\n scaledColumnIndex.push(this.calculateHorizontalScaledIndices(xIndex));\n columnPositions.push(dieCount);\n prevXIndex = xIndex;\n }\n scaledRowIndices.push(this.calculateVerticalScaledIndices(yIndex));\n const value = valuesBuffer[i];\n values.push(value);\n colorIndices.push(this.findColorIndex(value));\n dieCount += 1;\n }\n }\n this.scaledColumnIndices = Float64Array.from(scaledColumnIndex);\n this.columnIndicesPositions = Int32Array.from(columnPositions);\n this.scaledRowIndices = Float64Array.from(scaledRowIndices);\n this.values = Float64Array.from(values);\n this.colorIndices = Int32Array.from(colorIndices);\n }\n setRenderConfig(renderConfig) {\n this.renderConfig = renderConfig;\n this.colors = renderConfig.colorScale.map(marker => marker.color);\n this.colorValues = Float64Array.from(renderConfig.colorScale.map(marker => marker.value));\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 = this.colors[this.colorIndices[columnStartIndex]]\n ?? this.outsideRangeDieColor;\n this.context.fillRect(scaledX, scaledY, this.renderConfig.dieDimensions.width, this.renderConfig.dieDimensions.height);\n }\n }\n }\n drawText() {\n this.context.font = `${this.renderConfig.labelsFontSize.toString()}px sans-serif`;\n this.context.fillStyle = '#ffffff';\n this.context.textAlign = 'center';\n this.context.lineCap = 'butt';\n const approximateTextHeight = this.context.measureText('M');\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 let label = `${this.values[columnStartIndex] || 'NaN'}${this.renderConfig.dieLabelsSuffix}`;\n if (label.length >= this.renderConfig.maxCharacters) {\n label = `${label.substring(0, this.renderConfig.maxCharacters)}…`;\n }\n this.context.fillText(label, scaledX + this.renderConfig.dieDimensions.width / 2, scaledY\n + this.renderConfig.dieDimensions.height / 2\n + approximateTextHeight.width / 2, this.renderConfig.dieDimensions.width * this.fontSizeFactor);\n }\n }\n }\n isDieInGrid(x, y) {\n return (x >= this.renderConfig.gridMinX\n && x <= this.renderConfig.gridMaxX\n && y >= this.renderConfig.gridMinY\n && y <= this.renderConfig.gridMaxY);\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 findColorIndex(value) {\n let index = -1;\n if (this.colorValues.length === 0 || this.colorValues[0] >= value) {\n return index;\n }\n for (let i = 0; i < this.colorValues.length; i++) {\n if (value <= this.colorValues[i]) {\n index = i;\n break;\n }\n }\n return index;\n }\n }\n expose(MatrixRenderer);\n\n exports.MatrixRenderer = MatrixRenderer;\n\n return exports;\n\n})({});\n";
91683
91697
 
91684
91698
  let url;
91685
91699
  /**