@gemx-dev/clarity-visualize 0.8.62 → 0.8.64

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.
@@ -69,105 +69,6 @@ function __generator(thisArg, body) {
69
69
  }
70
70
  }
71
71
 
72
- var _a$1;
73
- var DataHelper = /** @class */ (function () {
74
- function DataHelper(state) {
75
- var _this = this;
76
- this.regionMap = {};
77
- this.regions = {};
78
- this.metrics = {};
79
- this.lean = false;
80
- this.reset = function () {
81
- _this.metrics = {};
82
- _this.lean = false;
83
- _this.regions = {};
84
- _this.regionMap = {};
85
- };
86
- this.metric = function (event) {
87
- var _a;
88
- if (_this.state.options.metadata) {
89
- var metricMarkup = [];
90
- var regionMarkup = [];
91
- // Copy over metrics for future reference
92
- for (var m in event.data) {
93
- var eventType = typeof event.data[m];
94
- if (eventType === "number" || (event.event === 1 /* Data.Event.Dimension */ && m === 37 /* Data.Dimension.InteractionNextPaint */.toString())) {
95
- if (!(m in _this.metrics)) {
96
- _this.metrics[m] = 0;
97
- }
98
- var key = parseInt(m, 10);
99
- var value = eventType === "object" ? Number((_a = event.data[m]) === null || _a === void 0 ? void 0 : _a[0]) : event.data[m];
100
- if (m in DataHelper.METRIC_MAP && (DataHelper.METRIC_MAP[m].unit === "html-price" || DataHelper.METRIC_MAP[m].unit === "ld-price")) {
101
- _this.metrics[m] = value;
102
- }
103
- else {
104
- _this.metrics[m] += value;
105
- }
106
- _this.lean = key === 1 /* Data.Metric.Playback */ && value === 0 ? true : _this.lean;
107
- }
108
- }
109
- for (var entry in _this.metrics) {
110
- if (entry in DataHelper.METRIC_MAP) {
111
- var m = _this.metrics[entry];
112
- var map = DataHelper.METRIC_MAP[entry];
113
- var unit = "unit" in map ? map.unit : "" /* Data.Constant.Empty */;
114
- metricMarkup.push("<li><h2>".concat(_this.value(m, unit), "<span>").concat(_this.key(unit), "</span></h2>").concat(map.name, "</li>"));
115
- }
116
- }
117
- // Append region information to metadata
118
- for (var name_1 in _this.regions) {
119
- var r = _this.regions[name_1];
120
- var className = (r.visibility === 10 /* Layout.RegionVisibility.Visible */ ? "visible" : (r.interaction === 20 /* Layout.InteractionState.Clicked */ ? "clicked" : "" /* Data.Constant.Empty */));
121
- regionMarkup.push("<span class=\"".concat(className, "\">").concat(name_1, "</span>"));
122
- }
123
- _this.state.options.metadata.innerHTML = "<ul>".concat(metricMarkup.join("" /* Data.Constant.Empty */), "</ul><div>").concat(regionMarkup.join("" /* Data.Constant.Empty */), "</div>");
124
- }
125
- };
126
- this.key = function (unit) {
127
- switch (unit) {
128
- case "html-price":
129
- case "ld-price":
130
- case "cls":
131
- return "" /* Data.Constant.Empty */;
132
- default: return unit;
133
- }
134
- };
135
- this.value = function (num, unit) {
136
- switch (unit) {
137
- case "KB": return Math.round(num / 1024);
138
- case "s": return Math.round(num / 10) / 100;
139
- case "cls": return num / 1000;
140
- case "html-price": return num / 100;
141
- default: return num;
142
- }
143
- };
144
- this.state = state;
145
- }
146
- DataHelper.prototype.region = function (event) {
147
- var data = event.data;
148
- for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
149
- var r = data_1[_i];
150
- if (!(r.name in this.regions)) {
151
- this.regions[r.name] = { interaction: r.interaction, visibility: r.visibility };
152
- }
153
- this.regionMap[r.id] = r.name;
154
- }
155
- };
156
- DataHelper.METRIC_MAP = (_a$1 = {},
157
- _a$1[2 /* Data.Metric.TotalBytes */] = { name: "Total Bytes", unit: "KB" },
158
- _a$1[4 /* Data.Metric.TotalCost */] = { name: "Total Cost", unit: "ms" },
159
- _a$1[3 /* Data.Metric.LayoutCost */] = { name: "Layout Cost", unit: "ms" },
160
- _a$1[8 /* Data.Metric.LargestPaint */] = { name: "LCP", unit: "s" },
161
- _a$1[9 /* Data.Metric.CumulativeLayoutShift */] = { name: "CLS", unit: "cls" },
162
- _a$1[7 /* Data.Metric.LongTaskCount */] = { name: "Long Tasks" },
163
- _a$1[24 /* Data.Metric.CartTotal */] = { name: "Cart Total", unit: "html-price" },
164
- _a$1[13 /* Data.Metric.ProductPrice */] = { name: "Product Price", unit: "ld-price" },
165
- _a$1[6 /* Data.Metric.ThreadBlockedTime */] = { name: "Thread Blocked", unit: "ms" },
166
- _a$1[37 /* Data.Dimension.InteractionNextPaint */] = { name: "INP", unit: "ms" },
167
- _a$1);
168
- return DataHelper;
169
- }());
170
-
171
72
  // tslint:disable: no-bitwise
172
73
  function hash (input, precision) {
173
74
  if (precision === void 0) { precision = null; }
@@ -188,12 +89,27 @@ function hash (input, precision) {
188
89
  hash = Math.abs(hashOne + (hashTwo * 11579));
189
90
  return (precision ? hash % Math.pow(2, precision) : hash).toString(36);
190
91
  }
92
+
93
+ function __spreadArray(to, from, pack) {
94
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
95
+ if (ar || !(i in from)) {
96
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
97
+ ar[i] = from[i];
98
+ }
99
+ }
100
+ return to.concat(ar || Array.prototype.slice.call(from));
101
+ }
191
102
 
192
103
  var excludeClassNames = "load,active,fixed,visible,focus,show,collaps,animat" /* Constant.ExcludeClassNames */.split("," /* Constant.Comma */);
104
+ var extraExcludeClassNames = [];
193
105
  var selectorMap = {};
194
106
  function reset$8() {
195
107
  selectorMap = {};
196
108
  }
109
+ function config$2(classNames) {
110
+ extraExcludeClassNames = classNames || [];
111
+ console.log("[Selector] config called \u2014 extraExcludeClassNames set to: [".concat(extraExcludeClassNames.join(', '), "]"));
112
+ }
197
113
  function get$1(input, type) {
198
114
  var a = input.attributes;
199
115
  var prefix = input.prefix ? input.prefix[type] : null;
@@ -216,7 +132,13 @@ function get$1(input, type) {
216
132
  input.tag = input.tag.indexOf("svg:" /* Constant.SvgPrefix */) === 0 ? input.tag.substr("svg:" /* Constant.SvgPrefix */.length) : input.tag;
217
133
  var selector = "".concat(prefix).concat(input.tag).concat(suffix);
218
134
  var id = "id" /* Constant.Id */ in a && a["id" /* Constant.Id */].length > 0 ? a["id" /* Constant.Id */] : null;
219
- var classes = input.tag !== "BODY" /* Constant.BodyTag */ && "class" /* Constant.Class */ in a && a["class" /* Constant.Class */].length > 0 ? a["class" /* Constant.Class */].trim().split(/\s+/).filter(function (c) { return filter(c); }).join("." /* Constant.Period */) : null;
135
+ var rawClasses = "class" /* Constant.Class */ in a ? a["class" /* Constant.Class */].trim().split(/\s+/) : [];
136
+ var filteredClasses = rawClasses.filter(function (c) { return filter(c); });
137
+ var removedClasses = rawClasses.filter(function (c) { return !filter(c); });
138
+ if (removedClasses.length > 0) {
139
+ console.log("[Selector] tag=\"".concat(input.tag, "\" id=\"").concat(input.id, "\" \u2014 removed classes: [").concat(removedClasses.join(', '), "] | kept: [").concat(filteredClasses.join(', '), "] | extraExclude: [").concat(extraExcludeClassNames.join(', '), "]"));
140
+ }
141
+ var classes = input.tag !== "BODY" /* Constant.BodyTag */ && filteredClasses.length > 0 ? filteredClasses.join("." /* Constant.Period */) : null;
220
142
  if (classes && classes.length > 0) {
221
143
  if (type === 0 /* Selector.Alpha */) {
222
144
  // In Alpha mode, update selector to use class names, with relative positioning within the parent id container.
@@ -229,16 +151,19 @@ function get$1(input, type) {
229
151
  selectorMap[key].push(input.id);
230
152
  }
231
153
  selector = "".concat(key).concat("~" /* Constant.Tilde */).concat(selectorMap[key].indexOf(input.id));
154
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ get ~ selector:", selector);
232
155
  }
233
156
  else {
234
157
  // In Beta mode, we continue to look at query selectors in context of the full page
235
158
  selector = "".concat(prefix).concat(input.tag, ".").concat(classes).concat(suffix);
159
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ get ~ selector:", selector);
236
160
  }
237
161
  }
238
162
  // Update selector to use "id" field when available. There are two exceptions:
239
163
  // (1) if "id" appears to be an auto generated string token, e.g. guid or a random id containing digits
240
164
  // (2) if "id" appears inside a shadow DOM, in which case we continue to prefix up to shadow DOM to prevent conflicts
241
165
  selector = id && filter(id) ? "".concat(getDomPrefix(prefix)).concat("#" /* Constant.Hash */).concat(id) : selector;
166
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ get ~ selector:", selector);
242
167
  return selector;
243
168
  }
244
169
  }
@@ -265,6 +190,8 @@ function filter(value) {
265
190
  if (!value) {
266
191
  return false;
267
192
  } // Do not process empty strings
193
+ var excludeClassNames = getExcludeClassNames();
194
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ filter ~ excludeClassNames:", excludeClassNames);
268
195
  if (excludeClassNames.some(function (x) { return value.toLowerCase().indexOf(x) >= 0; })) {
269
196
  return false;
270
197
  }
@@ -276,9 +203,15 @@ function filter(value) {
276
203
  }
277
204
  return true;
278
205
  }
206
+ function getExcludeClassNames() {
207
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ getExcludeClassNames ~ extraExcludeClassNames:", extraExcludeClassNames);
208
+ console.log("\uD83D\uDE80 \uD83D\uDC25 ~ getExcludeClassNames ~ excludeClassNames:", excludeClassNames);
209
+ return __spreadArray(__spreadArray([], excludeClassNames, true), extraExcludeClassNames, true);
210
+ }
279
211
 
280
212
  var selector = /*#__PURE__*/Object.freeze({
281
213
  __proto__: null,
214
+ config: config$2,
282
215
  get: get$1,
283
216
  reset: reset$8
284
217
  });
@@ -314,6 +247,105 @@ function lookup(hash) {
314
247
 
315
248
  var helper = { hash: hash, selector: selector, get: get$2, getNode: getNode, lookup: lookup };
316
249
 
250
+ var _a$1;
251
+ var DataHelper = /** @class */ (function () {
252
+ function DataHelper(state) {
253
+ var _this = this;
254
+ this.regionMap = {};
255
+ this.regions = {};
256
+ this.metrics = {};
257
+ this.lean = false;
258
+ this.reset = function () {
259
+ _this.metrics = {};
260
+ _this.lean = false;
261
+ _this.regions = {};
262
+ _this.regionMap = {};
263
+ };
264
+ this.metric = function (event) {
265
+ var _a;
266
+ if (_this.state.options.metadata) {
267
+ var metricMarkup = [];
268
+ var regionMarkup = [];
269
+ // Copy over metrics for future reference
270
+ for (var m in event.data) {
271
+ var eventType = typeof event.data[m];
272
+ if (eventType === "number" || (event.event === 1 /* Data.Event.Dimension */ && m === 37 /* Data.Dimension.InteractionNextPaint */.toString())) {
273
+ if (!(m in _this.metrics)) {
274
+ _this.metrics[m] = 0;
275
+ }
276
+ var key = parseInt(m, 10);
277
+ var value = eventType === "object" ? Number((_a = event.data[m]) === null || _a === void 0 ? void 0 : _a[0]) : event.data[m];
278
+ if (m in DataHelper.METRIC_MAP && (DataHelper.METRIC_MAP[m].unit === "html-price" || DataHelper.METRIC_MAP[m].unit === "ld-price")) {
279
+ _this.metrics[m] = value;
280
+ }
281
+ else {
282
+ _this.metrics[m] += value;
283
+ }
284
+ _this.lean = key === 1 /* Data.Metric.Playback */ && value === 0 ? true : _this.lean;
285
+ }
286
+ }
287
+ for (var entry in _this.metrics) {
288
+ if (entry in DataHelper.METRIC_MAP) {
289
+ var m = _this.metrics[entry];
290
+ var map = DataHelper.METRIC_MAP[entry];
291
+ var unit = "unit" in map ? map.unit : "" /* Data.Constant.Empty */;
292
+ metricMarkup.push("<li><h2>".concat(_this.value(m, unit), "<span>").concat(_this.key(unit), "</span></h2>").concat(map.name, "</li>"));
293
+ }
294
+ }
295
+ // Append region information to metadata
296
+ for (var name_1 in _this.regions) {
297
+ var r = _this.regions[name_1];
298
+ var className = (r.visibility === 10 /* Layout.RegionVisibility.Visible */ ? "visible" : (r.interaction === 20 /* Layout.InteractionState.Clicked */ ? "clicked" : "" /* Data.Constant.Empty */));
299
+ regionMarkup.push("<span class=\"".concat(className, "\">").concat(name_1, "</span>"));
300
+ }
301
+ _this.state.options.metadata.innerHTML = "<ul>".concat(metricMarkup.join("" /* Data.Constant.Empty */), "</ul><div>").concat(regionMarkup.join("" /* Data.Constant.Empty */), "</div>");
302
+ }
303
+ };
304
+ this.key = function (unit) {
305
+ switch (unit) {
306
+ case "html-price":
307
+ case "ld-price":
308
+ case "cls":
309
+ return "" /* Data.Constant.Empty */;
310
+ default: return unit;
311
+ }
312
+ };
313
+ this.value = function (num, unit) {
314
+ switch (unit) {
315
+ case "KB": return Math.round(num / 1024);
316
+ case "s": return Math.round(num / 10) / 100;
317
+ case "cls": return num / 1000;
318
+ case "html-price": return num / 100;
319
+ default: return num;
320
+ }
321
+ };
322
+ this.state = state;
323
+ }
324
+ DataHelper.prototype.region = function (event) {
325
+ var data = event.data;
326
+ for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
327
+ var r = data_1[_i];
328
+ if (!(r.name in this.regions)) {
329
+ this.regions[r.name] = { interaction: r.interaction, visibility: r.visibility };
330
+ }
331
+ this.regionMap[r.id] = r.name;
332
+ }
333
+ };
334
+ DataHelper.METRIC_MAP = (_a$1 = {},
335
+ _a$1[2 /* Data.Metric.TotalBytes */] = { name: "Total Bytes", unit: "KB" },
336
+ _a$1[4 /* Data.Metric.TotalCost */] = { name: "Total Cost", unit: "ms" },
337
+ _a$1[3 /* Data.Metric.LayoutCost */] = { name: "Layout Cost", unit: "ms" },
338
+ _a$1[8 /* Data.Metric.LargestPaint */] = { name: "LCP", unit: "s" },
339
+ _a$1[9 /* Data.Metric.CumulativeLayoutShift */] = { name: "CLS", unit: "cls" },
340
+ _a$1[7 /* Data.Metric.LongTaskCount */] = { name: "Long Tasks" },
341
+ _a$1[24 /* Data.Metric.CartTotal */] = { name: "Cart Total", unit: "html-price" },
342
+ _a$1[13 /* Data.Metric.ProductPrice */] = { name: "Product Price", unit: "ld-price" },
343
+ _a$1[6 /* Data.Metric.ThreadBlockedTime */] = { name: "Thread Blocked", unit: "ms" },
344
+ _a$1[37 /* Data.Dimension.InteractionNextPaint */] = { name: "INP", unit: "ms" },
345
+ _a$1);
346
+ return DataHelper;
347
+ }());
348
+
317
349
  var EnrichHelper = /** @class */ (function () {
318
350
  function EnrichHelper() {
319
351
  var _this = this;
@@ -358,6 +390,10 @@ var EnrichHelper = /** @class */ (function () {
358
390
  var selectorBeta = helper.selector.get(input, 1 /* Layout.Selector.Beta */);
359
391
  d.selectorBeta = selectorBeta.length > 0 ? selectorBeta : null;
360
392
  d.hashBeta = selectorBeta.length > 0 ? helper.hash(d.selectorBeta) : null;
393
+ var rawClass = (d.attributes || {})['class'] || '';
394
+ if (rawClass.includes('gp_ls-is-cached')) {
395
+ console.log("[Enrich] id=".concat(d.id, " tag=").concat(d.tag, " | class=\"").concat(rawClass, "\" | selectorBeta=\"").concat(selectorBeta, "\" | hashBeta=").concat(d.hashBeta));
396
+ }
361
397
  /* Track state for future reference */
362
398
  node.alpha = selectorAlpha;
363
399
  node.beta = selectorBeta;
@@ -884,12 +920,28 @@ var HeatmapHelper = /** @class */ (function () {
884
920
  var points = {};
885
921
  var localMax = 0;
886
922
  var height = _this.state.window && _this.state.window.document ? _this.state.window.document.documentElement.clientHeight : 0;
923
+ // DEBUG LOG
924
+ console.group("[Heatmap] transform \u2014 total elements: ".concat(_this.data.length, ", height: ").concat(height, ", max: ").concat(_this.max));
887
925
  for (var _i = 0, _a = _this.data; _i < _a.length; _i++) {
888
926
  var element = _a[_i];
889
927
  var el = _this.layout.get(element.hash);
928
+ if (!el) {
929
+ console.warn("[Heatmap] SKIP hash=\"".concat(element.hash, "\" \u2014 element not found in DOM"));
930
+ continue;
931
+ }
932
+ if (typeof el.getBoundingClientRect !== "function") {
933
+ console.warn("[Heatmap] SKIP hash=\"".concat(element.hash, "\" \u2014 getBoundingClientRect not available"), el);
934
+ continue;
935
+ }
936
+ var r = el.getBoundingClientRect();
937
+ var isDebugHash = element.hash === "270qs0pw7";
938
+ var v = _this.visible(el, r, height, isDebugHash ? element.hash : undefined);
939
+ if (!v && _this.max !== null) {
940
+ console.warn("[Heatmap] SKIP hash=\"".concat(element.hash, "\" \u2014 not visible on re-render"), { rect: { top: r.top, left: r.left, width: r.width, height: r.height }, maxIsSet: _this.max !== null });
941
+ continue;
942
+ }
890
943
  if (el && typeof el.getBoundingClientRect === "function") {
891
- var r = el.getBoundingClientRect();
892
- var v = _this.visible(el, r, height);
944
+ console.log("[Heatmap] PROCESS hash=\"".concat(element.hash, "\" visible=").concat(v, " points=").concat(element.points), { rect: { top: r.top, left: r.left, width: r.width, height: r.height } });
893
945
  // Process clicks for only visible elements
894
946
  if (_this.max === null || v) {
895
947
  for (var i = 0; i < element.points; i++) {
@@ -898,6 +950,7 @@ var HeatmapHelper = /** @class */ (function () {
898
950
  var k = "".concat(x).concat("X" /* Constant.Separator */).concat(y).concat("X" /* Constant.Separator */).concat(v ? 1 : 0);
899
951
  points[k] = k in points ? points[k] + element.clicks[i] : element.clicks[i];
900
952
  localMax = Math.max(points[k], localMax);
953
+ console.log(" point[".concat(i, "] x=").concat(x, " y=").concat(y, " visible=").concat(v, " clicks=").concat(element.clicks[i]));
901
954
  }
902
955
  }
903
956
  }
@@ -905,6 +958,7 @@ var HeatmapHelper = /** @class */ (function () {
905
958
  // Set the max value from the firs t
906
959
  _this.max = _this.max ? _this.max : localMax;
907
960
  // Once all points are accounted for, convert everything into absolute (x, y)
961
+ var skippedInvisible = 0;
908
962
  for (var _b = 0, _c = Object.keys(points); _b < _c.length; _b++) {
909
963
  var coordinates = _c[_b];
910
964
  var parts = coordinates.split("X" /* Constant.Separator */);
@@ -912,16 +966,36 @@ var HeatmapHelper = /** @class */ (function () {
912
966
  if (parts[2] === "1") {
913
967
  output.push({ x: parseInt(parts[0], 10), y: parseInt(parts[1], 10), a: alpha });
914
968
  }
969
+ else {
970
+ skippedInvisible++;
971
+ }
915
972
  }
973
+ console.log("[Heatmap] Result \u2014 drawn: ".concat(output.length, ", skipped invisible: ").concat(skippedInvisible, ", max: ").concat(_this.max));
974
+ console.groupEnd();
916
975
  return output;
917
976
  };
918
- this.visible = function (el, r, height) {
977
+ this.visible = function (el, r, height, debugHash) {
919
978
  var doc = _this.state.window.document;
920
979
  var visibility = r.height > height ? true : false;
980
+ if (debugHash) {
981
+ console.group("[Heatmap visible] hash=".concat(debugHash, " tag=").concat(el === null || el === void 0 ? void 0 : el.tagName));
982
+ console.log(" rect: top=".concat(r.top.toFixed(1), " bottom=").concat(r.bottom.toFixed(1), " left=").concat(r.left.toFixed(1), " width=").concat(r.width.toFixed(1), " height=").concat(r.height.toFixed(1)));
983
+ console.log(" viewport height=".concat(height, " | r.height > height? ").concat(r.height > height));
984
+ }
921
985
  if (visibility === false && r.width > 0 && r.height > 0) {
986
+ var checkX = r.left + (r.width / 2);
987
+ var checkY = r.top + (r.height / 2);
988
+ if (debugHash) {
989
+ console.log(" elementsFromPoint(".concat(checkX.toFixed(1), ", ").concat(checkY.toFixed(1), ")"));
990
+ }
922
991
  while (!visibility && doc) {
923
992
  var shadowElement = null;
924
- var elements = doc.elementsFromPoint(r.left + (r.width / 2), r.top + (r.height / 2));
993
+ var elements = doc.elementsFromPoint(checkX, checkY);
994
+ if (debugHash) {
995
+ var topElements = elements.slice(0, 5).map(function (e) { return "".concat(e.tagName).concat(e.id ? '#' + e.id : '').concat(e.className ? '.' + String(e.className).trim().split(/\s+/).slice(0, 2).join('.') : ''); });
996
+ console.log(" top elements at center: [".concat(topElements.join(', '), "]"));
997
+ console.log(" is el in top elements? ".concat(elements.includes(el), " | el matches first non-canvas? ").concat(elements.find(function (e) { return !(e.tagName === "CANVAS" /* Constant.Canvas */ || (e.id && e.id.indexOf("clarity-" /* Constant.ClarityPrefix */) === 0)); }) === el));
998
+ }
925
999
  for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) {
926
1000
  var e = elements_1[_i];
927
1001
  // Ignore if top element ends up being the canvas element we added for heatmap visualization
@@ -935,7 +1009,18 @@ var HeatmapHelper = /** @class */ (function () {
935
1009
  doc = shadowElement;
936
1010
  }
937
1011
  }
938
- return visibility && r.bottom >= 0 && r.top <= height;
1012
+ else if (debugHash) {
1013
+ if (r.width === 0 || r.height === 0) {
1014
+ console.log(" SKIP elementsFromPoint \u2014 zero dimension: width=".concat(r.width, " height=").concat(r.height));
1015
+ }
1016
+ }
1017
+ var result = visibility && r.bottom >= 0 && r.top <= height;
1018
+ if (debugHash) {
1019
+ console.log(" visibility=".concat(visibility, " | r.bottom(").concat(r.bottom.toFixed(1), ") >= 0? ").concat(r.bottom >= 0, " | r.top(").concat(r.top.toFixed(1), ") <= height(").concat(height, ")? ").concat(r.top <= height));
1020
+ console.log(" => final result: ".concat(result));
1021
+ console.groupEnd();
1022
+ }
1023
+ return result;
939
1024
  };
940
1025
  this.waitForDialogs = function () { return __awaiter(_this, void 0, void 0, function () {
941
1026
  var isPortalCanvas;
@@ -1684,6 +1769,9 @@ var LayoutHelper = /** @class */ (function () {
1684
1769
  // In case of selector collision, prefer the first inserted node
1685
1770
  _this.hashMapAlpha[data.hashAlpha] = _this.get(data.hashAlpha) || parent;
1686
1771
  _this.hashMapBeta[data.hashBeta] = _this.get(data.hashBeta) || parent;
1772
+ if (data.hashBeta === '2e36mrf7c' || data.hashBeta === '19lq10ve5') {
1773
+ console.log("[Layout] addToHashMap hashBeta=".concat(data.hashBeta, " | hashAlpha=").concat(data.hashAlpha, " | tag=").concat(parent === null || parent === void 0 ? void 0 : parent.tagName));
1774
+ }
1687
1775
  };
1688
1776
  this.resize = function (el, width, height) {
1689
1777
  if (el && el.nodeType === 1 /* NodeType.ELEMENT_NODE */ && width && height) {
@@ -2312,6 +2400,11 @@ var Visualizer = /** @class */ (function () {
2312
2400
  this._state = null;
2313
2401
  this.renderTime = 0;
2314
2402
  this.hashFoundTime = -1;
2403
+ this._excludeClassNames = [];
2404
+ this.configure = function (opts) {
2405
+ _this._excludeClassNames = opts.excludeClassNames || [];
2406
+ helper.selector.configure(_this._excludeClassNames);
2407
+ };
2315
2408
  this.dom = function (event) { return __awaiter(_this, void 0, void 0, function () {
2316
2409
  return __generator(this, function (_a) {
2317
2410
  switch (_a.label) {
@@ -2348,25 +2441,33 @@ var Visualizer = /** @class */ (function () {
2348
2441
  return false;
2349
2442
  }
2350
2443
  };
2351
- this.html = function (decoded, target, portalCanvasId, hash, useproxy, logerror, shortCircuitStrategy) {
2444
+ this.html = function (decoded, target, portalCanvasId, hash, useproxy, logerror, shortCircuitStrategy, signal) {
2352
2445
  if (hash === void 0) { hash = null; }
2353
2446
  if (shortCircuitStrategy === void 0) { shortCircuitStrategy = 0 /* ShortCircuitStrategy.None */; }
2354
2447
  return __awaiter(_this, void 0, void 0, function () {
2355
- var merged, entry, _a, domEvent, e_1;
2448
+ var merged, CHUNK_BUDGET_MS, chunkStart, entry, _a, domEvent, e_1;
2356
2449
  return __generator(this, function (_b) {
2357
2450
  switch (_b.label) {
2358
2451
  case 0:
2359
- if (!(decoded && decoded.length > 0 && target)) return [3 /*break*/, 11];
2452
+ if (!(decoded && decoded.length > 0 && target)) return [3 /*break*/, 13];
2360
2453
  _b.label = 1;
2361
2454
  case 1:
2362
- _b.trys.push([1, 10, , 11]);
2455
+ _b.trys.push([1, 12, , 13]);
2363
2456
  merged = this.merge(decoded);
2457
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
2458
+ return [2 /*return*/, this];
2364
2459
  return [4 /*yield*/, this.setup(target, { version: decoded[0].envelope.version, dom: merged.dom, useproxy: useproxy, portalCanvasId: portalCanvasId })];
2365
2460
  case 2:
2366
2461
  _b.sent();
2462
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
2463
+ return [2 /*return*/, this];
2464
+ CHUNK_BUDGET_MS = 8;
2465
+ chunkStart = performance.now();
2367
2466
  _b.label = 3;
2368
2467
  case 3:
2369
- if (!(merged.events.length > 0)) return [3 /*break*/, 9];
2468
+ if (!(merged.events.length > 0)) return [3 /*break*/, 11];
2469
+ if (signal === null || signal === void 0 ? void 0 : signal.aborted)
2470
+ return [2 /*return*/, this];
2370
2471
  entry = merged.events.shift();
2371
2472
  _a = entry.event;
2372
2473
  switch (_a) {
@@ -2392,15 +2493,22 @@ var Visualizer = /** @class */ (function () {
2392
2493
  case 7:
2393
2494
  _b.sent();
2394
2495
  return [3 /*break*/, 8];
2395
- case 8: return [3 /*break*/, 3];
2396
- case 9: return [3 /*break*/, 11];
2397
- case 10:
2496
+ case 8:
2497
+ if (!(performance.now() - chunkStart >= CHUNK_BUDGET_MS)) return [3 /*break*/, 10];
2498
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 0); })];
2499
+ case 9:
2500
+ _b.sent();
2501
+ chunkStart = performance.now();
2502
+ _b.label = 10;
2503
+ case 10: return [3 /*break*/, 3];
2504
+ case 11: return [3 /*break*/, 13];
2505
+ case 12:
2398
2506
  e_1 = _b.sent();
2399
2507
  if (logerror) {
2400
2508
  logerror(e_1);
2401
2509
  }
2402
- return [3 /*break*/, 11];
2403
- case 11: return [2 /*return*/, this];
2510
+ return [3 /*break*/, 13];
2511
+ case 13: return [2 /*return*/, this];
2404
2512
  }
2405
2513
  });
2406
2514
  });
@@ -2432,6 +2540,7 @@ var Visualizer = /** @class */ (function () {
2432
2540
  decoded = decoded.sort(_this.sortPayloads);
2433
2541
  // Re-initialize enrich class if someone ends up calling merge function directly
2434
2542
  _this.enrich = _this.enrich || new EnrichHelper();
2543
+ helper.selector.configure(_this._excludeClassNames);
2435
2544
  _this.enrich.reset();
2436
2545
  // Walk through payloads and generate merged payload from an array of decoded payloads
2437
2546
  for (var _i = 0, decoded_1 = decoded; _i < decoded_1.length; _i++) {
@@ -2470,6 +2579,10 @@ var Visualizer = /** @class */ (function () {
2470
2579
  switch (_a.label) {
2471
2580
  case 0:
2472
2581
  this.reset();
2582
+ if (options.excludeClassNames) {
2583
+ this._excludeClassNames = options.excludeClassNames;
2584
+ helper.selector.configure(options.excludeClassNames);
2585
+ }
2473
2586
  // Infer options
2474
2587
  options.pointer = "pointer" in options ? options.pointer : true;
2475
2588
  options.canvas = "canvas" in options ? options.canvas : true;