clarity-visualize 0.7.57 → 0.7.59

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.
@@ -15,7 +15,7 @@ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
15
  PERFORMANCE OF THIS SOFTWARE.
16
16
  ***************************************************************************** */
17
17
 
18
- function __awaiter(thisArg, _arguments, P, generator) {
18
+ function __awaiter$1(thisArg, _arguments, P, generator) {
19
19
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
20
20
  return new (P || (P = Promise))(function (resolve, reject) {
21
21
  function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
@@ -25,7 +25,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
25
25
  });
26
26
  }
27
27
 
28
- function __generator(thisArg, body) {
28
+ function __generator$1(thisArg, body) {
29
29
  var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
30
30
  return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
31
31
  function verb(n) { return function (v) { return step([n, v]); }; }
@@ -152,6 +152,51 @@ var DataHelper = /** @class */ (function () {
152
152
  return DataHelper;
153
153
  }());
154
154
 
155
+ var config$2 = {
156
+ projectId: null,
157
+ delay: 1 * 1000 /* Time.Second */,
158
+ lean: false,
159
+ track: true,
160
+ content: true,
161
+ drop: [],
162
+ mask: [],
163
+ unmask: [],
164
+ regions: [],
165
+ cookies: [],
166
+ fraud: true,
167
+ checksum: [],
168
+ report: null,
169
+ upload: null,
170
+ fallback: null,
171
+ upgrade: null,
172
+ action: null,
173
+ dob: null,
174
+ delayDom: false,
175
+ throttleDom: true,
176
+ conversions: false,
177
+ longTask: 30,
178
+ includeSubdomains: true,
179
+ };
180
+
181
+ function api(method) {
182
+ // Zone.js, a popular package for Angular, overrides native browser APIs which can lead to inconsistent state for single page applications.
183
+ // Example issue: https://github.com/angular/angular/issues/31712
184
+ // As a work around, we ensuring Clarity access APIs outside of Zone (and use native implementation instead)
185
+ return window["Zone" /* Constant.Zone */] && "__symbol__" /* Constant.Symbol */ in window["Zone" /* Constant.Zone */] ? window["Zone" /* Constant.Zone */]["__symbol__" /* Constant.Symbol */](method) : method;
186
+ }
187
+
188
+ var startTime = 0;
189
+ // event.timestamp is number of milliseconds elapsed since the document was loaded
190
+ // since iframes can be loaded later the event timestamp is not the same as performance.now()
191
+ // converting everything to absolute time by adding timeorigin of the event view
192
+ // to synchronize times before calculating the difference with start time
193
+ function time$1(event) {
194
+ if (event === void 0) { event = null; }
195
+ var ts = event && event.timeStamp > 0 ? event.timeStamp : performance.now();
196
+ var origin = event && event.view ? event.view.performance.timeOrigin : performance.timeOrigin;
197
+ return Math.max(Math.round(ts + origin - startTime), 0);
198
+ }
199
+
155
200
  // tslint:disable: no-bitwise
156
201
  function hash (input, precision) {
157
202
  if (precision === void 0) { precision = null; }
@@ -173,6 +218,359 @@ function hash (input, precision) {
173
218
  return (precision ? hash % Math.pow(2, precision) : hash).toString(36);
174
219
  }
175
220
 
221
+ var catchallRegex = /\S/gi;
222
+ var unicodeRegex = true;
223
+ var digitRegex = null;
224
+ var letterRegex = null;
225
+ var currencyRegex = null;
226
+ function text$1(value, hint, privacy, mangle, type) {
227
+ if (mangle === void 0) { mangle = false; }
228
+ if (value) {
229
+ if (hint == "input" && (type === "checkbox" || type === "radio")) {
230
+ return value;
231
+ }
232
+ switch (privacy) {
233
+ case 0 /* Privacy.None */:
234
+ return value;
235
+ case 1 /* Privacy.Sensitive */:
236
+ switch (hint) {
237
+ case "*T" /* Layout.Constant.TextTag */:
238
+ case "value":
239
+ case "placeholder":
240
+ case "click":
241
+ return redact$1(value);
242
+ case "input":
243
+ case "change":
244
+ return mangleToken(value);
245
+ }
246
+ return value;
247
+ case 2 /* Privacy.Text */:
248
+ case 3 /* Privacy.TextImage */:
249
+ switch (hint) {
250
+ case "*T" /* Layout.Constant.TextTag */:
251
+ case "data-" /* Layout.Constant.DataAttribute */:
252
+ return mangle ? mangleText(value) : mask(value);
253
+ case "src":
254
+ case "srcset":
255
+ case "title":
256
+ case "alt":
257
+ return privacy === 3 /* Privacy.TextImage */ ? "" /* Data.Constant.Empty */ : value;
258
+ case "value":
259
+ case "click":
260
+ case "input":
261
+ case "change":
262
+ return mangleToken(value);
263
+ case "placeholder":
264
+ return mask(value);
265
+ }
266
+ break;
267
+ case 4 /* Privacy.Exclude */:
268
+ switch (hint) {
269
+ case "*T" /* Layout.Constant.TextTag */:
270
+ case "data-" /* Layout.Constant.DataAttribute */:
271
+ return mangle ? mangleText(value) : mask(value);
272
+ case "value":
273
+ case "input":
274
+ case "click":
275
+ case "change":
276
+ return Array(5 /* Data.Setting.WordLength */).join("\u2022" /* Data.Constant.Mask */);
277
+ case "checksum":
278
+ return "" /* Data.Constant.Empty */;
279
+ }
280
+ break;
281
+ case 5 /* Privacy.Snapshot */:
282
+ switch (hint) {
283
+ case "*T" /* Layout.Constant.TextTag */:
284
+ case "data-" /* Layout.Constant.DataAttribute */:
285
+ return scrub(value, "\u25AA" /* Data.Constant.Letter */, "\u25AB" /* Data.Constant.Digit */);
286
+ case "value":
287
+ case "input":
288
+ case "click":
289
+ case "change":
290
+ return Array(5 /* Data.Setting.WordLength */).join("\u2022" /* Data.Constant.Mask */);
291
+ case "checksum":
292
+ case "src":
293
+ case "srcset":
294
+ case "alt":
295
+ case "title":
296
+ return "" /* Data.Constant.Empty */;
297
+ }
298
+ break;
299
+ }
300
+ }
301
+ return value;
302
+ }
303
+ function url$1(input, electron) {
304
+ if (electron === void 0) { electron = false; }
305
+ // Replace the URL for Electron apps so we don't send back file:/// URL
306
+ if (electron) {
307
+ return "".concat("https://" /* Data.Constant.HTTPS */).concat("Electron" /* Data.Constant.Electron */);
308
+ }
309
+ var drop = config$2.drop;
310
+ if (drop && drop.length > 0 && input && input.indexOf("?") > 0) {
311
+ var _a = input.split("?"), path = _a[0], query = _a[1];
312
+ var swap_1 = "*na*" /* Data.Constant.Dropped */;
313
+ return path + "?" + query.split("&").map(function (p) { return drop.some(function (x) { return p.indexOf("".concat(x, "=")) === 0; }) ? "".concat(p.split("=")[0], "=").concat(swap_1) : p; }).join("&");
314
+ }
315
+ return input;
316
+ }
317
+ function mangleText(value) {
318
+ var trimmed = value.trim();
319
+ if (trimmed.length > 0) {
320
+ var first = trimmed[0];
321
+ var index = value.indexOf(first);
322
+ var prefix = value.substr(0, index);
323
+ var suffix = value.substr(index + trimmed.length);
324
+ return "".concat(prefix).concat(trimmed.length.toString(36)).concat(suffix);
325
+ }
326
+ return value;
327
+ }
328
+ function mask(value) {
329
+ return value.replace(catchallRegex, "\u2022" /* Data.Constant.Mask */);
330
+ }
331
+ function scrub(value, letter, digit) {
332
+ regex(); // Initialize regular expressions
333
+ return value ? value.replace(letterRegex, letter).replace(digitRegex, digit) : value;
334
+ }
335
+ function mangleToken(value) {
336
+ var length = ((Math.floor(value.length / 5 /* Data.Setting.WordLength */) + 1) * 5 /* Data.Setting.WordLength */);
337
+ var output = "" /* Layout.Constant.Empty */;
338
+ for (var i = 0; i < length; i++) {
339
+ output += i > 0 && i % 5 /* Data.Setting.WordLength */ === 0 ? " " /* Data.Constant.Space */ : "\u2022" /* Data.Constant.Mask */;
340
+ }
341
+ return output;
342
+ }
343
+ function regex() {
344
+ // Initialize unicode regex, if supported by the browser
345
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
346
+ if (unicodeRegex && digitRegex === null) {
347
+ try {
348
+ digitRegex = new RegExp("\\p{N}", "gu");
349
+ letterRegex = new RegExp("\\p{L}", "gu");
350
+ currencyRegex = new RegExp("\\p{Sc}", "gu");
351
+ }
352
+ catch (_a) {
353
+ unicodeRegex = false;
354
+ }
355
+ }
356
+ }
357
+ function redact$1(value) {
358
+ var spaceIndex = -1;
359
+ var gap = 0;
360
+ var hasDigit = false;
361
+ var hasEmail = false;
362
+ var hasWhitespace = false;
363
+ var array = null;
364
+ regex(); // Initialize regular expressions
365
+ for (var i = 0; i < value.length; i++) {
366
+ var c = value.charCodeAt(i);
367
+ hasDigit = hasDigit || (c >= 48 /* Data.Character.Zero */ && c <= 57 /* Data.Character.Nine */); // Check for digits in the current word
368
+ hasEmail = hasEmail || c === 64 /* Data.Character.At */; // Check for @ sign anywhere within the current word
369
+ hasWhitespace = c === 9 /* Data.Character.Tab */ || c === 10 /* Data.Character.NewLine */ || c === 13 /* Data.Character.Return */ || c === 32 /* Data.Character.Blank */;
370
+ // Process each word as an individual token to redact any sensitive information
371
+ if (i === 0 || i === value.length - 1 || hasWhitespace) {
372
+ // Performance optimization: Lazy load string -> array conversion only when required
373
+ if (hasDigit || hasEmail) {
374
+ if (array === null) {
375
+ array = value.split("" /* Data.Constant.Empty */);
376
+ }
377
+ // Work on a token at a time so we don't have to apply regex to a larger string
378
+ var token = value.substring(spaceIndex + 1, hasWhitespace ? i : i + 1);
379
+ // Check if unicode regex is supported, otherwise fallback to calling mask function on this token
380
+ if (unicodeRegex && currencyRegex !== null) {
381
+ // Do not redact information if the token contains a currency symbol
382
+ token = token.match(currencyRegex) ? token : scrub(token, "\u25AA" /* Data.Constant.Letter */, "\u25AB" /* Data.Constant.Digit */);
383
+ }
384
+ else {
385
+ token = mask(token);
386
+ }
387
+ // Merge token back into array at the right place
388
+ array.splice(spaceIndex + 1 - gap, token.length, token);
389
+ gap += token.length - 1;
390
+ }
391
+ // Reset digit and email flags after every word boundary, except the beginning of string
392
+ if (hasWhitespace) {
393
+ hasDigit = false;
394
+ hasEmail = false;
395
+ spaceIndex = i;
396
+ }
397
+ }
398
+ }
399
+ return array ? array.join("" /* Data.Constant.Empty */) : value;
400
+ }
401
+ var buffer = null;
402
+ function track$8(event, x, y, time) {
403
+ switch (event) {
404
+ case 8 /* Event.Document */:
405
+ buffer.docWidth = x;
406
+ buffer.docHeight = y;
407
+ break;
408
+ case 11 /* Event.Resize */:
409
+ buffer.screenWidth = x;
410
+ buffer.screenHeight = y;
411
+ break;
412
+ case 10 /* Event.Scroll */:
413
+ buffer.scrollX = x;
414
+ buffer.scrollY = y;
415
+ buffer.scrollTime = time;
416
+ break;
417
+ default:
418
+ buffer.pointerX = x;
419
+ buffer.pointerY = y;
420
+ break;
421
+ }
422
+ }
423
+ function activity(t) {
424
+ buffer.activityTime = t;
425
+ }
426
+ function visibility(t, visible) {
427
+ buffer.visible = visible === "visible" ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */;
428
+ if (!buffer.visible) {
429
+ activity(t);
430
+ }
431
+ }
432
+
433
+ var data$i = null;
434
+ var updates$3 = null;
435
+ function count$1(metric) {
436
+ if (!(metric in data$i)) {
437
+ data$i[metric] = 0;
438
+ }
439
+ if (!(metric in updates$3)) {
440
+ updates$3[metric] = 0;
441
+ }
442
+ data$i[metric]++;
443
+ updates$3[metric]++;
444
+ }
445
+ function sum(metric, value) {
446
+ if (value !== null) {
447
+ if (!(metric in data$i)) {
448
+ data$i[metric] = 0;
449
+ }
450
+ if (!(metric in updates$3)) {
451
+ updates$3[metric] = 0;
452
+ }
453
+ data$i[metric] += value;
454
+ updates$3[metric] += value;
455
+ }
456
+ }
457
+ function max(metric, value) {
458
+ // Ensure that we do not process null or NaN values
459
+ if (value !== null && isNaN(value) === false) {
460
+ if (!(metric in data$i)) {
461
+ data$i[metric] = 0;
462
+ }
463
+ if (value > data$i[metric] || data$i[metric] === 0) {
464
+ updates$3[metric] = value;
465
+ data$i[metric] = value;
466
+ }
467
+ }
468
+ }
469
+
470
+ function setTimeout$1(handler, timeout, event) {
471
+ return window.setTimeout(measure(handler), timeout, event);
472
+ }
473
+ function clearTimeout$1(handle) {
474
+ return window.clearTimeout(handle);
475
+ }
476
+
477
+ var data$g = null;
478
+ function track$7(event, time) {
479
+ if (!(event in data$g)) {
480
+ data$g[event] = [[time, 0]];
481
+ }
482
+ else {
483
+ var e = data$g[event];
484
+ var last = e[e.length - 1];
485
+ // Add a new entry only if the new event occurs after configured interval
486
+ // Otherwise, extend the duration of the previous entry
487
+ if (time - last[0] > 100 /* Setting.SummaryInterval */) {
488
+ data$g[event].push([time, 0]);
489
+ }
490
+ else {
491
+ last[1] = time - last[0];
492
+ }
493
+ }
494
+ }
495
+
496
+ /******************************************************************************
497
+ Copyright (c) Microsoft Corporation.
498
+
499
+ Permission to use, copy, modify, and/or distribute this software for any
500
+ purpose with or without fee is hereby granted.
501
+
502
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
503
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
504
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
505
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
506
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
507
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
508
+ PERFORMANCE OF THIS SOFTWARE.
509
+ ***************************************************************************** */
510
+
511
+ function __awaiter(thisArg, _arguments, P, generator) {
512
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
513
+ return new (P || (P = Promise))(function (resolve, reject) {
514
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
515
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
516
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
517
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
518
+ });
519
+ }
520
+
521
+ function __generator(thisArg, body) {
522
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
523
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
524
+ function verb(n) { return function (v) { return step([n, v]); }; }
525
+ function step(op) {
526
+ if (f) throw new TypeError("Generator is already executing.");
527
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
528
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
529
+ if (y = 0, t) op = [op[0] & 2, t.value];
530
+ switch (op[0]) {
531
+ case 0: case 1: t = op; break;
532
+ case 4: _.label++; return { value: op[1], done: false };
533
+ case 5: _.label++; y = op[1]; op = [0]; continue;
534
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
535
+ default:
536
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
537
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
538
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
539
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
540
+ if (t[2]) _.ops.pop();
541
+ _.trys.pop(); continue;
542
+ }
543
+ op = body.call(thisArg, _);
544
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
545
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
546
+ }
547
+ }
548
+
549
+ var history$5 = [];
550
+ var data$d;
551
+ function start$A() {
552
+ history$5 = [];
553
+ max(26 /* Metric.Automation */, navigator.webdriver ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */);
554
+ try {
555
+ // some sites (unintentionally) overwrite the window.self property, so we also check for the main window object
556
+ max(31 /* Metric.Iframed */, window.top == window.self || window.top == window ? 1 /* IframeStatus.TopFrame */ : 2 /* IframeStatus.Iframe */);
557
+ }
558
+ catch (ex) {
559
+ max(31 /* Metric.Iframed */, 0 /* IframeStatus.Unknown */);
560
+ }
561
+ }
562
+ function check$4(id, target, input) {
563
+ // Compute hash for fraud detection, if enabled. Hash is computed only if input meets the minimum length criteria
564
+ if (id !== null && input && input.length >= 5 /* Setting.WordLength */) {
565
+ data$d = { id: id, target: target, checksum: hash(input, 28 /* Setting.ChecksumPrecision */) };
566
+ // Only encode this event if we haven't already reported this hash
567
+ if (history$5.indexOf(data$d.checksum) < 0) {
568
+ history$5.push(data$d.checksum);
569
+ encode$2(41 /* Event.Fraud */);
570
+ }
571
+ }
572
+ }
573
+
176
574
  var excludeClassNames = "load,active,fixed,visible,focus,show,collaps,animat" /* Constant.ExcludeClassNames */.split("," /* Constant.Comma */);
177
575
  var selectorMap = {};
178
576
  function reset$n() {
@@ -270,9 +668,68 @@ var selector = /*#__PURE__*/Object.freeze({
270
668
  var index = 1;
271
669
  var nodesMap = null; // Maps id => node to retrieve further node details using id.
272
670
  var values = [];
671
+ var updateMap = [];
273
672
  var hashMap = {};
673
+ var override = [];
674
+ var unmask = [];
675
+ var maskText = [];
676
+ var maskExclude = [];
677
+ var maskDisable = [];
678
+ var maskTags = [];
274
679
  // The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
275
680
  var idMap = null; // Maps node => id.
681
+ var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
682
+ var privacyMap = null; // Maps node => Privacy (enum)
683
+ var fraudMap = null; // Maps node => FraudId (number)
684
+ function start$z() {
685
+ reset$m();
686
+ parse$1(document, true);
687
+ }
688
+ function stop$x() {
689
+ reset$m();
690
+ }
691
+ function reset$m() {
692
+ index = 1;
693
+ values = [];
694
+ updateMap = [];
695
+ hashMap = {};
696
+ override = [];
697
+ unmask = [];
698
+ maskText = "address,password,contact" /* Mask.Text */.split("," /* Constant.Comma */);
699
+ maskExclude = "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.split("," /* Constant.Comma */);
700
+ maskDisable = "radio,checkbox,range,button,reset,submit" /* Mask.Disable */.split("," /* Constant.Comma */);
701
+ maskTags = "INPUT,SELECT,TEXTAREA" /* Mask.Tags */.split("," /* Constant.Comma */);
702
+ nodesMap = new Map();
703
+ idMap = new WeakMap();
704
+ iframeMap = new WeakMap();
705
+ privacyMap = new WeakMap();
706
+ fraudMap = new WeakMap();
707
+ reset$n();
708
+ }
709
+ // We parse new root nodes for any regions or masked nodes in the beginning (document) and
710
+ // later whenever there are new additions or modifications to DOM (mutations)
711
+ function parse$1(root, init) {
712
+ if (init === void 0) { init = false; }
713
+ // Wrap selectors in a try / catch block.
714
+ // It's possible for script to receive invalid selectors, e.g. "'#id'" with extra quotes, and cause the code below to fail
715
+ try {
716
+ // Parse unmask configuration into separate query selectors and override tokens as part of initialization
717
+ if (init) {
718
+ config$2.unmask.forEach(function (x) { return x.indexOf("!" /* Constant.Bang */) < 0 ? unmask.push(x) : override.push(x.substr(1)); });
719
+ }
720
+ // Since mutations may happen on leaf nodes too, e.g. text nodes, which may not support all selector APIs.
721
+ // We ensure that the root note supports querySelectorAll API before executing the code below to identify new regions.
722
+ if ("querySelectorAll" in root) {
723
+ config$2.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "".concat(x[0])); }); }); // Regions
724
+ config$2.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* Privacy.TextImage */); }); }); // Masked Elements
725
+ config$2.checksum.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Checksum Check
726
+ unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* Privacy.None */); }); }); // Unmasked Elements
727
+ }
728
+ }
729
+ catch (e) {
730
+ log$1(5 /* Code.Selector */, 1 /* Severity.Warning */, e ? e.name : null);
731
+ }
732
+ }
276
733
  function getId(node, autogen) {
277
734
  if (autogen === void 0) { autogen = false; }
278
735
  if (node === null) {
@@ -285,9 +742,228 @@ function getId(node, autogen) {
285
742
  }
286
743
  return id ? id : null;
287
744
  }
745
+ function add(node, parent, data, source) {
746
+ var id = getId(node, true);
747
+ var parentId = parent ? getId(parent) : null;
748
+ var previousId = getPreviousId(node);
749
+ var parentValue = null;
750
+ var regionId = exists(node) ? id : null;
751
+ var fraudId = fraudMap.has(node) ? fraudMap.get(node) : null;
752
+ var privacyId = 1 /* Privacy.Sensitive */ /* Privacy.TextImage */;
753
+ if (parentId >= 0 && values[parentId]) {
754
+ parentValue = values[parentId];
755
+ parentValue.children.push(id);
756
+ regionId = regionId === null ? parentValue.region : regionId;
757
+ fraudId = fraudId === null ? parentValue.metadata.fraud : fraudId;
758
+ privacyId = parentValue.metadata.privacy;
759
+ }
760
+ // If there's an explicit region attribute set on the element, use it to mark a region on the page
761
+ if (data.attributes && "data-clarity-region" /* Constant.RegionData */ in data.attributes) {
762
+ observe$1(node, data.attributes["data-clarity-region" /* Constant.RegionData */]);
763
+ regionId = id;
764
+ }
765
+ nodesMap.set(id, node);
766
+ values[id] = {
767
+ id: id,
768
+ parent: parentId,
769
+ previous: previousId,
770
+ children: [],
771
+ data: data,
772
+ selector: null,
773
+ hash: null,
774
+ region: regionId,
775
+ metadata: { active: true, suspend: false, privacy: privacyId, position: null, fraud: fraudId, size: null },
776
+ };
777
+ privacy(node, values[id], parentValue);
778
+ updateSelector(values[id]);
779
+ updateImageSize(values[id]);
780
+ track$6(id, source);
781
+ }
782
+ function update$1(node, parent, data, source) {
783
+ var id = getId(node);
784
+ var parentId = parent ? getId(parent) : null;
785
+ var previousId = getPreviousId(node);
786
+ var changed = false;
787
+ var parentChanged = false;
788
+ if (id in values) {
789
+ var value = values[id];
790
+ value.metadata.active = true;
791
+ // Handle case where internal ordering may have changed
792
+ if (value.previous !== previousId) {
793
+ changed = true;
794
+ value.previous = previousId;
795
+ }
796
+ // Handle case where parent might have been updated
797
+ if (value.parent !== parentId) {
798
+ changed = true;
799
+ var oldParentId = value.parent;
800
+ value.parent = parentId;
801
+ // Move this node to the right location under new parent
802
+ if (parentId !== null && parentId >= 0) {
803
+ var childIndex = previousId === null ? 0 : values[parentId].children.indexOf(previousId) + 1;
804
+ values[parentId].children.splice(childIndex, 0, id);
805
+ // Update region after the move
806
+ value.region = exists(node) ? id : values[parentId].region;
807
+ }
808
+ else {
809
+ // Mark this element as deleted if the parent has been updated to null
810
+ remove(id, source);
811
+ }
812
+ // Remove reference to this node from the old parent
813
+ if (oldParentId !== null && oldParentId >= 0) {
814
+ var nodeIndex = values[oldParentId].children.indexOf(id);
815
+ if (nodeIndex >= 0) {
816
+ values[oldParentId].children.splice(nodeIndex, 1);
817
+ }
818
+ }
819
+ parentChanged = true;
820
+ }
821
+ // Update data
822
+ for (var key in data) {
823
+ if (diff(value["data"], data, key)) {
824
+ changed = true;
825
+ value["data"][key] = data[key];
826
+ }
827
+ }
828
+ // Update selector
829
+ updateSelector(value);
830
+ track$6(id, source, changed, parentChanged);
831
+ }
832
+ }
833
+ function sameorigin(node) {
834
+ var output = false;
835
+ if (node.nodeType === Node.ELEMENT_NODE && node.tagName === "IFRAME" /* Constant.IFrameTag */) {
836
+ var frame = node;
837
+ // To determine if the iframe is same-origin or not, we try accessing it's contentDocument.
838
+ // If the browser throws an exception, we assume it's cross-origin and move on.
839
+ // However, if we do a get a valid document object back, we assume the contents are accessible and iframe is same-origin.
840
+ try {
841
+ var doc = frame.contentDocument;
842
+ if (doc) {
843
+ iframeMap.set(frame.contentDocument, frame);
844
+ output = true;
845
+ }
846
+ }
847
+ catch ( /* do nothing */_a) { /* do nothing */ }
848
+ }
849
+ return output;
850
+ }
851
+ function iframe(node) {
852
+ var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
853
+ return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
854
+ }
855
+ function privacy(node, value, parent) {
856
+ var _a;
857
+ var data = value.data;
858
+ var metadata = value.metadata;
859
+ var current = metadata.privacy;
860
+ var attributes = data.attributes || {};
861
+ var tag = data.tag.toUpperCase();
862
+ switch (true) {
863
+ case maskTags.indexOf(tag) >= 0:
864
+ var type = attributes["type" /* Constant.Type */];
865
+ var meta_1 = "" /* Constant.Empty */;
866
+ var excludedPrivacyAttributes_1 = ["class" /* Constant.Class */, "style" /* Constant.Style */];
867
+ Object.keys(attributes)
868
+ .filter(function (x) { return !excludedPrivacyAttributes_1.includes(x); })
869
+ .forEach(function (x) { return (meta_1 += attributes[x].toLowerCase()); });
870
+ var exclude = maskExclude.some(function (x) { return meta_1.indexOf(x) >= 0; });
871
+ // Regardless of privacy mode, always mask off user input from input boxes or drop downs with two exceptions:
872
+ // (1) The node is detected to be one of the excluded fields, in which case we drop everything
873
+ // (2) The node's type is one of the allowed types (like checkboxes)
874
+ metadata.privacy = tag === "INPUT" /* Constant.InputTag */ && maskDisable.indexOf(type) >= 0 ? current : (exclude ? 4 /* Privacy.Exclude */ : 2 /* Privacy.Text */);
875
+ break;
876
+ case "data-clarity-mask" /* Constant.MaskData */ in attributes:
877
+ metadata.privacy = 3 /* Privacy.TextImage */;
878
+ break;
879
+ case "data-clarity-unmask" /* Constant.UnmaskData */ in attributes:
880
+ metadata.privacy = 0 /* Privacy.None */;
881
+ break;
882
+ case privacyMap.has(node):
883
+ // If this node was explicitly configured to contain sensitive content, honor that privacy setting
884
+ metadata.privacy = privacyMap.get(node);
885
+ break;
886
+ case fraudMap.has(node):
887
+ // If this node was explicitly configured to be evaluated for fraud, then also mask content
888
+ metadata.privacy = 2 /* Privacy.Text */;
889
+ break;
890
+ case tag === "*T" /* Constant.TextTag */:
891
+ // If it's a text node belonging to a STYLE or TITLE tag or one of scrub exceptions, then capture content
892
+ var pTag = parent && parent.data ? parent.data.tag : "" /* Constant.Empty */;
893
+ var pSelector_1 = parent && parent.selector ? parent.selector[1 /* Selector.Default */] : "" /* Constant.Empty */;
894
+ var tags = ["STYLE" /* Constant.StyleTag */, "TITLE" /* Constant.TitleTag */, "svg:style" /* Constant.SvgStyle */];
895
+ metadata.privacy = tags.includes(pTag) || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* Privacy.None */ : current;
896
+ break;
897
+ case current === 1 /* Privacy.Sensitive */:
898
+ // In a mode where we mask sensitive information by default, look through class names to aggressively mask content
899
+ metadata.privacy = inspect(attributes["class" /* Constant.Class */], maskText, metadata);
900
+ break;
901
+ case tag === "IMG" /* Constant.ImageTag */:
902
+ // Mask images with blob src as it is not publicly available anyway.
903
+ if ((_a = attributes.src) === null || _a === void 0 ? void 0 : _a.startsWith('blob:')) {
904
+ metadata.privacy = 3 /* Privacy.TextImage */;
905
+ }
906
+ break;
907
+ }
908
+ }
909
+ function inspect(input, lookup, metadata) {
910
+ if (input && lookup.some(function (x) { return input.indexOf(x) >= 0; })) {
911
+ return 2 /* Privacy.Text */;
912
+ }
913
+ return metadata.privacy;
914
+ }
915
+ function diff(a, b, field) {
916
+ if (typeof a[field] === "object" && typeof b[field] === "object") {
917
+ for (var key in a[field]) {
918
+ if (a[field][key] !== b[field][key]) {
919
+ return true;
920
+ }
921
+ }
922
+ for (var key in b[field]) {
923
+ if (b[field][key] !== a[field][key]) {
924
+ return true;
925
+ }
926
+ }
927
+ return false;
928
+ }
929
+ return a[field] !== b[field];
930
+ }
931
+ function position(parent, child) {
932
+ child.metadata.position = 1;
933
+ var idx = parent ? parent.children.indexOf(child.id) : -1;
934
+ while (idx-- > 0) {
935
+ var sibling = values[parent.children[idx]];
936
+ if (child.data.tag === sibling.data.tag) {
937
+ child.metadata.position = sibling.metadata.position + 1;
938
+ break;
939
+ }
940
+ }
941
+ return child.metadata.position;
942
+ }
943
+ function updateSelector(value) {
944
+ var parent = value.parent && value.parent in values ? values[value.parent] : null;
945
+ var prefix = parent ? parent.selector : null;
946
+ var d = value.data;
947
+ var p = position(parent, value);
948
+ var s = { id: value.id, tag: d.tag, prefix: prefix, position: p, attributes: d.attributes };
949
+ value.selector = [get$1(s, 0 /* Selector.Alpha */), get$1(s, 1 /* Selector.Beta */)];
950
+ value.hash = value.selector.map(function (x) { return x ? hash(x) : null; });
951
+ value.hash.forEach(function (h) { return hashMap[h] = value.id; });
952
+ }
953
+ function hashText(hash) {
954
+ var id = lookup(hash);
955
+ var node = getNode(id);
956
+ return node !== null && node.textContent !== null ? node.textContent.substr(0, 25 /* Setting.ClickText */) : '';
957
+ }
288
958
  function getNode(id) {
289
959
  return nodesMap.has(id) ? nodesMap.get(id) : null;
290
960
  }
961
+ function getValue(id) {
962
+ if (id in values) {
963
+ return values[id];
964
+ }
965
+ return null;
966
+ }
291
967
  function get$2(node) {
292
968
  var id = getId(node);
293
969
  return id in values ? values[id] : null;
@@ -295,6 +971,2870 @@ function get$2(node) {
295
971
  function lookup(hash) {
296
972
  return hash in hashMap ? hashMap[hash] : null;
297
973
  }
974
+ function has(node) {
975
+ return nodesMap.has(getId(node));
976
+ }
977
+ function updates$2() {
978
+ var output = [];
979
+ for (var _i = 0, updateMap_1 = updateMap; _i < updateMap_1.length; _i++) {
980
+ var id = updateMap_1[_i];
981
+ if (id in values) {
982
+ output.push(values[id]);
983
+ }
984
+ }
985
+ updateMap = [];
986
+ return output;
987
+ }
988
+ function remove(id, source) {
989
+ if (id in values) {
990
+ var value = values[id];
991
+ value.metadata.active = false;
992
+ value.parent = null;
993
+ track$6(id, source);
994
+ // Clean up node references for removed nodes
995
+ removeNodeFromNodesMap(id);
996
+ }
997
+ }
998
+ function removeNodeFromNodesMap(id) {
999
+ // Shadow dom roots shouldn't be deleted,
1000
+ // we should keep listening to the mutations there even they're not rendered in the DOM.
1001
+ if (nodesMap.get(id).nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
1002
+ return;
1003
+ }
1004
+ nodesMap.delete(id);
1005
+ var value = id in values ? values[id] : null;
1006
+ if (value && value.children) {
1007
+ for (var _i = 0, _a = value.children; _i < _a.length; _i++) {
1008
+ var childId = _a[_i];
1009
+ removeNodeFromNodesMap(childId);
1010
+ }
1011
+ }
1012
+ }
1013
+ function updateImageSize(value) {
1014
+ // If this element is a image node, and is masked, then track box model for the current element
1015
+ if (value.data.tag === "IMG" /* Constant.ImageTag */ && value.metadata.privacy === 3 /* Privacy.TextImage */) {
1016
+ var img_1 = getNode(value.id);
1017
+ // We will not capture the natural image dimensions until it loads.
1018
+ if (img_1 && (!img_1.complete || img_1.naturalWidth === 0)) {
1019
+ // This will trigger mutation to update the original width and height after image loads.
1020
+ bind(img_1, 'load', function () {
1021
+ img_1.setAttribute('data-clarity-loaded', "".concat(shortid()));
1022
+ });
1023
+ }
1024
+ value.metadata.size = [];
1025
+ }
1026
+ }
1027
+ function getPreviousId(node) {
1028
+ var id = null;
1029
+ // Some nodes may not have an ID by design since Clarity skips over tags like SCRIPT, NOSCRIPT, META, COMMENTS, etc..
1030
+ // In that case, we keep going back and check for their sibling until we find a sibling with ID or no more sibling nodes are left.
1031
+ while (id === null && node.previousSibling) {
1032
+ id = getId(node.previousSibling);
1033
+ node = node.previousSibling;
1034
+ }
1035
+ return id;
1036
+ }
1037
+ function track$6(id, source, changed, parentChanged) {
1038
+ if (changed === void 0) { changed = true; }
1039
+ if (parentChanged === void 0) { parentChanged = false; }
1040
+ // Keep track of the order in which mutations happened, they may not be sequential
1041
+ // Edge case: If an element is added later on, and pre-discovered element is moved as a child.
1042
+ // In that case, we need to reorder the pre-discovered element in the update list to keep visualization consistent.
1043
+ var uIndex = updateMap.indexOf(id);
1044
+ if (uIndex >= 0 && source === 1 /* Source.ChildListAdd */ && parentChanged) {
1045
+ updateMap.splice(uIndex, 1);
1046
+ updateMap.push(id);
1047
+ }
1048
+ else if (uIndex === -1 && changed) {
1049
+ updateMap.push(id);
1050
+ }
1051
+ }
1052
+
1053
+ var dom$1 = /*#__PURE__*/Object.freeze({
1054
+ __proto__: null,
1055
+ add: add,
1056
+ get: get$2,
1057
+ getId: getId,
1058
+ getNode: getNode,
1059
+ getValue: getValue,
1060
+ has: has,
1061
+ hashText: hashText,
1062
+ iframe: iframe,
1063
+ lookup: lookup,
1064
+ parse: parse$1,
1065
+ sameorigin: sameorigin,
1066
+ start: start$z,
1067
+ stop: stop$x,
1068
+ update: update$1,
1069
+ updates: updates$2
1070
+ });
1071
+
1072
+ // Track the start time to be able to compute duration at the end of the task
1073
+ var idleTimeout = 5000;
1074
+ var tracker = {};
1075
+ var queuedTasks = [];
1076
+ var activeTask = null;
1077
+ var pauseTask = null;
1078
+ function schedule$1(task, priority) {
1079
+ if (priority === void 0) { priority = 0 /* Priority.Normal */; }
1080
+ return __awaiter(this, void 0, void 0, function () {
1081
+ var _i, queuedTasks_1, q, promise;
1082
+ return __generator(this, function (_a) {
1083
+ // If this task is already scheduled, skip it
1084
+ for (_i = 0, queuedTasks_1 = queuedTasks; _i < queuedTasks_1.length; _i++) {
1085
+ q = queuedTasks_1[_i];
1086
+ if (q.task === task) {
1087
+ return [2 /*return*/];
1088
+ }
1089
+ }
1090
+ promise = new Promise(function (resolve) {
1091
+ var insert = priority === 1 /* Priority.High */ ? "unshift" : "push";
1092
+ // Queue this task for asynchronous execution later
1093
+ // We also store a unique page identifier (id) along with the task to ensure
1094
+ // ensure that we do not accidentally execute this task in context of a different page
1095
+ queuedTasks[insert]({ task: task, resolve: resolve, id: id() });
1096
+ });
1097
+ // If there is no active task running, and Clarity is not in pause state,
1098
+ // invoke the first task in the queue synchronously. This ensures that we don't yield the thread during unload event
1099
+ if (activeTask === null && pauseTask === null) {
1100
+ run();
1101
+ }
1102
+ return [2 /*return*/, promise];
1103
+ });
1104
+ });
1105
+ }
1106
+ function run() {
1107
+ var entry = queuedTasks.shift();
1108
+ if (entry) {
1109
+ activeTask = entry;
1110
+ entry.task().then(function () {
1111
+ // Bail out if the context in which this task was operating is different from the current page
1112
+ // An example scenario where task could span across pages is Single Page Applications (SPA)
1113
+ // A task that started on page #1, but completes on page #2
1114
+ if (entry.id !== id()) {
1115
+ return;
1116
+ }
1117
+ entry.resolve();
1118
+ activeTask = null; // Reset active task back to null now that the promise is resolved
1119
+ run();
1120
+ }).catch(function (error) {
1121
+ // If one of the scheduled tasks failed, log, recover and continue processing rest of the tasks
1122
+ if (entry.id !== id()) {
1123
+ return;
1124
+ }
1125
+ if (error) {
1126
+ log$1(0 /* Code.RunTask */, 1 /* Severity.Warning */, error.name, error.message, error.stack);
1127
+ }
1128
+ activeTask = null;
1129
+ run();
1130
+ });
1131
+ }
1132
+ }
1133
+ function state$a(timer) {
1134
+ var id = key(timer);
1135
+ if (id in tracker) {
1136
+ var elapsed = performance.now() - tracker[id].start;
1137
+ return (elapsed > tracker[id].yield) ? 0 /* Task.Wait */ : 1 /* Task.Run */;
1138
+ }
1139
+ // If this task is no longer being tracked, send stop message to the caller
1140
+ return 2 /* Task.Stop */;
1141
+ }
1142
+ function start$y(timer) {
1143
+ tracker[key(timer)] = { start: performance.now(), calls: 0, yield: config$2.longTask };
1144
+ }
1145
+ function restart$2(timer) {
1146
+ var id = key(timer);
1147
+ if (tracker && tracker[id]) {
1148
+ var c = tracker[id].calls;
1149
+ var y = tracker[id].yield;
1150
+ start$y(timer);
1151
+ tracker[id].calls = c + 1;
1152
+ tracker[id].yield = y;
1153
+ }
1154
+ }
1155
+ function stop$w(timer) {
1156
+ var end = performance.now();
1157
+ var id = key(timer);
1158
+ var duration = end - tracker[id].start;
1159
+ sum(timer.cost, duration);
1160
+ count$1(5 /* Metric.InvokeCount */);
1161
+ // For the first execution, which is synchronous, time is automatically counted towards TotalDuration.
1162
+ // However, for subsequent asynchronous runs, we need to manually update TotalDuration metric.
1163
+ if (tracker[id].calls > 0) {
1164
+ sum(4 /* Metric.TotalCost */, duration);
1165
+ }
1166
+ }
1167
+ function suspend$1(timer) {
1168
+ return __awaiter(this, void 0, void 0, function () {
1169
+ var id, _a;
1170
+ return __generator(this, function (_b) {
1171
+ switch (_b.label) {
1172
+ case 0:
1173
+ id = key(timer);
1174
+ if (!(id in tracker)) return [3 /*break*/, 2];
1175
+ stop$w(timer);
1176
+ _a = tracker[id];
1177
+ return [4 /*yield*/, wait()];
1178
+ case 1:
1179
+ _a.yield = (_b.sent()).timeRemaining();
1180
+ restart$2(timer);
1181
+ _b.label = 2;
1182
+ case 2:
1183
+ // After we are done with suspending task, ensure that we are still operating in the right context
1184
+ // If the task is still being tracked, continue running the task, otherwise ask caller to stop execution
1185
+ return [2 /*return*/, id in tracker ? 1 /* Task.Run */ : 2 /* Task.Stop */];
1186
+ }
1187
+ });
1188
+ });
1189
+ }
1190
+ function key(timer) {
1191
+ return "".concat(timer.id, ".").concat(timer.cost);
1192
+ }
1193
+ function wait() {
1194
+ return __awaiter(this, void 0, void 0, function () {
1195
+ return __generator(this, function (_a) {
1196
+ switch (_a.label) {
1197
+ case 0:
1198
+ return [3 /*break*/, 2];
1199
+ case 1:
1200
+ _a.sent();
1201
+ _a.label = 2;
1202
+ case 2: return [2 /*return*/, new Promise(function (resolve) {
1203
+ requestIdleCallback(resolve, { timeout: idleTimeout });
1204
+ })];
1205
+ }
1206
+ });
1207
+ });
1208
+ }
1209
+ // Use native implementation of requestIdleCallback if it exists.
1210
+ // Otherwise, fall back to a custom implementation using requestAnimationFrame & MessageChannel.
1211
+ // While it's not possible to build a perfect polyfill given the nature of this API, the following code attempts to get close.
1212
+ // Background context: requestAnimationFrame invokes the js code right before: style, layout and paint computation within the frame.
1213
+ // This means, that any code that runs as part of requestAnimationFrame will by default be blocking in nature. Not what we want.
1214
+ // For non-blocking behavior, We need to know when browser has finished painting. This can be accomplished in two different ways (hacks):
1215
+ // (1) Use MessageChannel to pass the message, and browser will receive the message right after paint event has occured.
1216
+ // (2) Use setTimeout call within requestAnimationFrame. This also works, but there's a risk that browser may throttle setTimeout calls.
1217
+ // Given this information, we are currently using (1) from above. More information on (2) as well as some additional context is below:
1218
+ // https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Performance_best_practices_for_Firefox_fe_engineers
1219
+ function requestIdleCallbackPolyfill(callback, options) {
1220
+ var startTime = performance.now();
1221
+ var channel = new MessageChannel();
1222
+ var incoming = channel.port1;
1223
+ var outgoing = channel.port2;
1224
+ incoming.onmessage = function (event) {
1225
+ var currentTime = performance.now();
1226
+ var elapsed = currentTime - startTime;
1227
+ var duration = currentTime - event.data;
1228
+ if (duration > config$2.longTask && elapsed < options.timeout) {
1229
+ requestAnimationFrame(function () { outgoing.postMessage(currentTime); });
1230
+ }
1231
+ else {
1232
+ var didTimeout_1 = elapsed > options.timeout;
1233
+ callback({
1234
+ didTimeout: didTimeout_1,
1235
+ timeRemaining: function () { return didTimeout_1 ? config$2.longTask : Math.max(0, config$2.longTask - duration); }
1236
+ });
1237
+ }
1238
+ };
1239
+ requestAnimationFrame(function () { outgoing.postMessage(performance.now()); });
1240
+ }
1241
+ var requestIdleCallback = window["requestIdleCallback"] || requestIdleCallbackPolyfill;
1242
+
1243
+ // Following code takes an array of tokens and transforms it to optimize for repeating tokens and make it efficient to send over the wire
1244
+ // The way it works is that it iterate over all tokens and checks if the current token was already seen in the tokens array so far
1245
+ // If so, it replaces the token with its reference (index). This helps us save bytes by not repeating the same value twice.
1246
+ // E.g. If tokens array is: ["hello", "world", "coding", "language", "world", "language", "example"]
1247
+ // Then the resulting tokens array after following code execution would be: ["hello", "world", "coding", "language", [1, 3], "example"]
1248
+ // Where [1,3] points to tokens[1] => "world" and tokens[3] => "language"
1249
+ function tokenize (tokens) {
1250
+ var output = [];
1251
+ var lookup = {};
1252
+ var pointer = 0;
1253
+ var reference = null;
1254
+ for (var i = 0; i < tokens.length; i++) {
1255
+ // Only optimize for string values
1256
+ if (typeof tokens[i] === "string" /* Constant.String */) {
1257
+ var token = tokens[i];
1258
+ var index = lookup[token] || -1;
1259
+ if (index >= 0) {
1260
+ if (reference) {
1261
+ reference.push(index);
1262
+ }
1263
+ else {
1264
+ reference = [index];
1265
+ output.push(reference);
1266
+ pointer++;
1267
+ }
1268
+ }
1269
+ else {
1270
+ reference = null;
1271
+ output.push(token);
1272
+ lookup[token] = pointer++;
1273
+ }
1274
+ }
1275
+ else {
1276
+ // If the value is anything other than string, append it as it is to the output array
1277
+ // And, also increment the pointer to stay in sync with output array
1278
+ reference = null;
1279
+ output.push(tokens[i]);
1280
+ pointer++;
1281
+ }
1282
+ }
1283
+ return output;
1284
+ }
1285
+
1286
+ var data$c;
1287
+ function reset$k() {
1288
+ data$c = null;
1289
+ }
1290
+ function start$x() {
1291
+ reset$k();
1292
+ compute$9();
1293
+ }
1294
+ function compute$9() {
1295
+ var body = document.body;
1296
+ var d = document.documentElement;
1297
+ var bodyClientWidth = body ? body.clientWidth : null;
1298
+ var bodyScrollWidth = body ? body.scrollWidth : null;
1299
+ var bodyOffsetWidth = body ? body.offsetWidth : null;
1300
+ var documentClientWidth = d ? d.clientWidth : null;
1301
+ var documentScrollWidth = d ? d.scrollWidth : null;
1302
+ var documentOffsetWidth = d ? d.offsetWidth : null;
1303
+ var width = Math.max(bodyClientWidth, bodyScrollWidth, bodyOffsetWidth, documentClientWidth, documentScrollWidth, documentOffsetWidth);
1304
+ var bodyClientHeight = body ? body.clientHeight : null;
1305
+ var bodyScrollHeight = body ? body.scrollHeight : null;
1306
+ var bodyOffsetHeight = body ? body.offsetHeight : null;
1307
+ var documentClientHeight = d ? d.clientHeight : null;
1308
+ var documentScrollHeight = d ? d.scrollHeight : null;
1309
+ var documentOffsetHeight = d ? d.offsetHeight : null;
1310
+ var height = Math.max(bodyClientHeight, bodyScrollHeight, bodyOffsetHeight, documentClientHeight, documentScrollHeight, documentOffsetHeight);
1311
+ // Check that width or height has changed from before, and also that width & height are not null values
1312
+ if ((data$c === null || width !== data$c.width || height !== data$c.height) && width !== null && height !== null) {
1313
+ data$c = { width: width, height: height };
1314
+ encode$4(8 /* Event.Document */);
1315
+ }
1316
+ }
1317
+ compute$9.dn = 19 /* FunctionNames.DocumentCompute */;
1318
+
1319
+ var state$9 = [];
1320
+ function start$w() {
1321
+ reset$j();
1322
+ }
1323
+ function observe$c(root) {
1324
+ bind(root, "change", recompute$8, true);
1325
+ }
1326
+ function recompute$8(evt) {
1327
+ var element = target(evt);
1328
+ if (element) {
1329
+ var value = element.value;
1330
+ var checksum = value && value.length >= 5 /* Setting.WordLength */ && config$2.fraud && "password,secret,pass,social,ssn,code,hidden" /* Mask.Exclude */.indexOf(element.type) === -1 ? hash(value, 28 /* Setting.ChecksumPrecision */) : "" /* Constant.Empty */;
1331
+ state$9.push({ time: time$1(evt), event: 42 /* Event.Change */, data: { target: target(evt), type: element.type, value: value, checksum: checksum } });
1332
+ schedule$1(encode$3.bind(this, 42 /* Event.Change */));
1333
+ }
1334
+ }
1335
+ recompute$8.dn = 5 /* FunctionNames.ChangeRecompute */;
1336
+ function reset$j() {
1337
+ state$9 = [];
1338
+ }
1339
+
1340
+ function offset(element) {
1341
+ var output = { x: 0, y: 0 };
1342
+ // Walk up the chain to ensure we compute offset distance correctly
1343
+ // In case where we may have nested IFRAMEs, we keep walking up until we get to the top most parent page
1344
+ if (element && element.offsetParent) {
1345
+ do {
1346
+ var parent_1 = element.offsetParent;
1347
+ var frame = parent_1 === null ? iframe(element.ownerDocument) : null;
1348
+ output.x += element.offsetLeft;
1349
+ output.y += element.offsetTop;
1350
+ element = frame ? frame : parent_1;
1351
+ } while (element);
1352
+ }
1353
+ return output;
1354
+ }
1355
+
1356
+ var UserInputTags = ["input", "textarea", "radio", "button", "canvas"];
1357
+ var state$8 = [];
1358
+ function start$v() {
1359
+ reset$i();
1360
+ }
1361
+ function observe$b(root) {
1362
+ bind(root, "click", handler$3.bind(this, 9 /* Event.Click */, root), true);
1363
+ }
1364
+ function handler$3(event, root, evt) {
1365
+ var frame = iframe(root);
1366
+ var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1367
+ var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
1368
+ var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
1369
+ // In case of iframe, we adjust (x,y) to be relative to top parent's origin
1370
+ if (frame) {
1371
+ var distance = offset(frame);
1372
+ x = x ? x + Math.round(distance.x) : x;
1373
+ y = y ? y + Math.round(distance.y) : y;
1374
+ }
1375
+ var t = target(evt);
1376
+ // Find nearest anchor tag (<a/>) parent if current target node is part of one
1377
+ // If present, we use the returned link element to populate text and link properties below
1378
+ var a = link(t);
1379
+ // Get layout rectangle for the target element
1380
+ var l = layout$1(t);
1381
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
1382
+ // This property helps differentiate between a keyboard navigation vs. pointer click
1383
+ // In case of a keyboard navigation, we use center of target element as (x,y)
1384
+ if (evt.detail === 0 && l) {
1385
+ x = Math.round(l.x + (l.w / 2));
1386
+ y = Math.round(l.y + (l.h / 2));
1387
+ }
1388
+ var eX = l ? Math.max(Math.floor(((x - l.x) / l.w) * 32767 /* Setting.ClickPrecision */), 0) : 0;
1389
+ var eY = l ? Math.max(Math.floor(((y - l.y) / l.h) * 32767 /* Setting.ClickPrecision */), 0) : 0;
1390
+ // Check for null values before processing this event
1391
+ if (x !== null && y !== null) {
1392
+ state$8.push({
1393
+ time: time$1(evt),
1394
+ event: event,
1395
+ data: {
1396
+ target: t,
1397
+ x: x,
1398
+ y: y,
1399
+ eX: eX,
1400
+ eY: eY,
1401
+ button: evt.button,
1402
+ reaction: reaction(t),
1403
+ context: context(a),
1404
+ text: text(t),
1405
+ link: a ? a.href : null,
1406
+ hash: null,
1407
+ trust: evt.isTrusted ? 1 /* BooleanFlag.True */ : 0 /* BooleanFlag.False */
1408
+ }
1409
+ });
1410
+ schedule$1(encode$3.bind(this, event));
1411
+ }
1412
+ }
1413
+ handler$3.dn = 6 /* FunctionNames.ClickHandler */;
1414
+ function link(node) {
1415
+ while (node && node !== document) {
1416
+ if (node.nodeType === Node.ELEMENT_NODE) {
1417
+ var element = node;
1418
+ if (element.tagName === "A") {
1419
+ return element;
1420
+ }
1421
+ }
1422
+ node = node.parentNode;
1423
+ }
1424
+ return null;
1425
+ }
1426
+ function text(element) {
1427
+ var output = null;
1428
+ if (element) {
1429
+ // Grab text using "textContent" for most HTMLElements, however, use "value" for HTMLInputElements and "alt" for HTMLImageElement.
1430
+ var t = element.textContent || String(element.value || '') || element.alt;
1431
+ if (t) {
1432
+ // Replace multiple occurrence of space characters with a single white space
1433
+ // Also, trim any spaces at the beginning or at the end of string
1434
+ // Finally, send only first few characters as specified by the Setting
1435
+ output = t.replace(/\s+/g, " " /* Constant.Space */).trim().substr(0, 25 /* Setting.ClickText */);
1436
+ }
1437
+ }
1438
+ return output;
1439
+ }
1440
+ function reaction(element) {
1441
+ if (element.nodeType === Node.ELEMENT_NODE) {
1442
+ var tag = element.tagName.toLowerCase();
1443
+ if (UserInputTags.indexOf(tag) >= 0) {
1444
+ return 0 /* BooleanFlag.False */;
1445
+ }
1446
+ }
1447
+ return 1 /* BooleanFlag.True */;
1448
+ }
1449
+ function layout$1(element) {
1450
+ var box = null;
1451
+ var de = document.documentElement;
1452
+ if (typeof element.getBoundingClientRect === "function") {
1453
+ // getBoundingClientRect returns rectangle relative positioning to viewport
1454
+ var rect = element.getBoundingClientRect();
1455
+ if (rect && rect.width > 0 && rect.height > 0) {
1456
+ // Add viewport's scroll position to rectangle to get position relative to document origin
1457
+ // Also: using Math.floor() instead of Math.round() because in Edge,
1458
+ // getBoundingClientRect returns partial pixel values (e.g. 162.5px) and Chrome already
1459
+ // floors the value (e.g. 162px). This keeps consistent behavior across browsers.
1460
+ box = {
1461
+ x: Math.floor(rect.left + ("pageXOffset" in window ? window.pageXOffset : de.scrollLeft)),
1462
+ y: Math.floor(rect.top + ("pageYOffset" in window ? window.pageYOffset : de.scrollTop)),
1463
+ w: Math.floor(rect.width),
1464
+ h: Math.floor(rect.height)
1465
+ };
1466
+ }
1467
+ }
1468
+ return box;
1469
+ }
1470
+ function context(a) {
1471
+ if (a && a.hasAttribute("target" /* Constant.Target */)) {
1472
+ switch (a.getAttribute("target" /* Constant.Target */)) {
1473
+ case "_blank" /* Constant.Blank */: return 1 /* BrowsingContext.Blank */;
1474
+ case "_parent" /* Constant.Parent */: return 2 /* BrowsingContext.Parent */;
1475
+ case "_top" /* Constant.Top */: return 3 /* BrowsingContext.Top */;
1476
+ }
1477
+ }
1478
+ return 0 /* BrowsingContext.Self */;
1479
+ }
1480
+ function reset$i() {
1481
+ state$8 = [];
1482
+ }
1483
+
1484
+ var state$7 = [];
1485
+ function start$u() {
1486
+ reset$h();
1487
+ }
1488
+ function observe$a(root) {
1489
+ bind(root, "cut", recompute$7.bind(this, 0 /* Clipboard.Cut */), true);
1490
+ bind(root, "copy", recompute$7.bind(this, 1 /* Clipboard.Copy */), true);
1491
+ bind(root, "paste", recompute$7.bind(this, 2 /* Clipboard.Paste */), true);
1492
+ }
1493
+ function recompute$7(action, evt) {
1494
+ state$7.push({ time: time$1(evt), event: 38 /* Event.Clipboard */, data: { target: target(evt), action: action } });
1495
+ schedule$1(encode$3.bind(this, 38 /* Event.Clipboard */));
1496
+ }
1497
+ recompute$7.dn = 7 /* FunctionNames.ClipboardRecompute */;
1498
+ function reset$h() {
1499
+ state$7 = [];
1500
+ }
1501
+
1502
+ var timeout$6 = null;
1503
+ var state$6 = [];
1504
+ function start$t() {
1505
+ reset$g();
1506
+ }
1507
+ function observe$9(root) {
1508
+ bind(root, "input", recompute$6, true);
1509
+ }
1510
+ function recompute$6(evt) {
1511
+ var input = target(evt);
1512
+ var value = get$2(input);
1513
+ if (input && input.type && value) {
1514
+ var v = input.value;
1515
+ var t = input.type;
1516
+ switch (input.type) {
1517
+ case "radio":
1518
+ case "checkbox":
1519
+ v = input.checked ? "true" : "false";
1520
+ break;
1521
+ }
1522
+ var data = { target: input, value: v, type: t };
1523
+ // If last entry in the queue is for the same target node as the current one, remove it so we can later swap it with current data.
1524
+ if (state$6.length > 0 && (state$6[state$6.length - 1].data.target === data.target)) {
1525
+ state$6.pop();
1526
+ }
1527
+ state$6.push({ time: time$1(evt), event: 27 /* Event.Input */, data: data });
1528
+ clearTimeout$1(timeout$6);
1529
+ timeout$6 = setTimeout$1(process$7, 1000 /* Setting.InputLookAhead */, 27 /* Event.Input */);
1530
+ }
1531
+ }
1532
+ recompute$6.dn = 9 /* FunctionNames.InputRecompute */;
1533
+ function process$7(event) {
1534
+ schedule$1(encode$3.bind(this, event));
1535
+ }
1536
+ function reset$g() {
1537
+ state$6 = [];
1538
+ }
1539
+
1540
+ var state$5 = [];
1541
+ var timeout$5 = null;
1542
+ var hasPrimaryTouch = false;
1543
+ var primaryTouchId = 0;
1544
+ var activeTouchPointIds = new Set();
1545
+ function start$s() {
1546
+ reset$f();
1547
+ }
1548
+ function observe$8(root) {
1549
+ bind(root, "mousedown", mouse.bind(this, 13 /* Event.MouseDown */, root), true);
1550
+ bind(root, "mouseup", mouse.bind(this, 14 /* Event.MouseUp */, root), true);
1551
+ bind(root, "mousemove", mouse.bind(this, 12 /* Event.MouseMove */, root), true);
1552
+ bind(root, "wheel", mouse.bind(this, 15 /* Event.MouseWheel */, root), true);
1553
+ bind(root, "dblclick", mouse.bind(this, 16 /* Event.DoubleClick */, root), true);
1554
+ bind(root, "touchstart", touch.bind(this, 17 /* Event.TouchStart */, root), true);
1555
+ bind(root, "touchend", touch.bind(this, 18 /* Event.TouchEnd */, root), true);
1556
+ bind(root, "touchmove", touch.bind(this, 19 /* Event.TouchMove */, root), true);
1557
+ bind(root, "touchcancel", touch.bind(this, 20 /* Event.TouchCancel */, root), true);
1558
+ }
1559
+ function mouse(event, root, evt) {
1560
+ var frame = iframe(root);
1561
+ var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1562
+ var x = "pageX" in evt ? Math.round(evt.pageX) : ("clientX" in evt ? Math.round(evt["clientX"] + d.scrollLeft) : null);
1563
+ var y = "pageY" in evt ? Math.round(evt.pageY) : ("clientY" in evt ? Math.round(evt["clientY"] + d.scrollTop) : null);
1564
+ // In case of iframe, we adjust (x,y) to be relative to top parent's origin
1565
+ if (frame) {
1566
+ var distance = offset(frame);
1567
+ x = x ? x + Math.round(distance.x) : x;
1568
+ y = y ? y + Math.round(distance.y) : y;
1569
+ }
1570
+ // Check for null values before processing this event
1571
+ if (x !== null && y !== null) {
1572
+ handler$2({ time: time$1(evt), event: event, data: { target: target(evt), x: x, y: y } });
1573
+ }
1574
+ }
1575
+ mouse.dn = 10 /* FunctionNames.PointerMouse */;
1576
+ function touch(event, root, evt) {
1577
+ var frame = iframe(root);
1578
+ var d = frame ? frame.contentDocument.documentElement : document.documentElement;
1579
+ var touches = evt.changedTouches;
1580
+ var t = time$1(evt);
1581
+ if (touches) {
1582
+ for (var i = 0; i < touches.length; i++) {
1583
+ var entry = touches[i];
1584
+ var x = "clientX" in entry ? Math.round(entry["clientX"] + d.scrollLeft) : null;
1585
+ var y = "clientY" in entry ? Math.round(entry["clientY"] + d.scrollTop) : null;
1586
+ x = x && frame ? x + Math.round(frame.offsetLeft) : x;
1587
+ y = y && frame ? y + Math.round(frame.offsetTop) : y;
1588
+ // We cannot rely on identifier to determine primary touch as its value doesn't always start with 0.
1589
+ // Safari/Webkit uses the address of the UITouch object as the identifier value for each touch point.
1590
+ var id = "identifier" in entry ? entry["identifier"] : undefined;
1591
+ switch (event) {
1592
+ case 17 /* Event.TouchStart */:
1593
+ if (activeTouchPointIds.size === 0) {
1594
+ // Track presence of primary touch separately to handle scenarios when same id is repeated
1595
+ hasPrimaryTouch = true;
1596
+ primaryTouchId = id;
1597
+ }
1598
+ activeTouchPointIds.add(id);
1599
+ break;
1600
+ case 18 /* Event.TouchEnd */:
1601
+ case 20 /* Event.TouchCancel */:
1602
+ activeTouchPointIds.delete(id);
1603
+ break;
1604
+ }
1605
+ var isPrimary = hasPrimaryTouch && primaryTouchId === id;
1606
+ // Check for null values before processing this event
1607
+ if (x !== null && y !== null) {
1608
+ handler$2({ time: t, event: event, data: { target: target(evt), x: x, y: y, id: id, isPrimary: isPrimary } });
1609
+ }
1610
+ // Reset primary touch point id once touch event ends
1611
+ if (event === 20 /* Event.TouchCancel */ || event === 18 /* Event.TouchEnd */) {
1612
+ if (primaryTouchId === id) {
1613
+ hasPrimaryTouch = false;
1614
+ }
1615
+ }
1616
+ }
1617
+ }
1618
+ }
1619
+ touch.dn = 11 /* FunctionNames.PointerTouch */;
1620
+ function handler$2(current) {
1621
+ switch (current.event) {
1622
+ case 12 /* Event.MouseMove */:
1623
+ case 15 /* Event.MouseWheel */:
1624
+ case 19 /* Event.TouchMove */:
1625
+ var length_1 = state$5.length;
1626
+ var last = length_1 > 1 ? state$5[length_1 - 2] : null;
1627
+ if (last && similar$1(last, current)) {
1628
+ state$5.pop();
1629
+ }
1630
+ state$5.push(current);
1631
+ clearTimeout$1(timeout$5);
1632
+ timeout$5 = setTimeout$1(process$6, 500 /* Setting.LookAhead */, current.event);
1633
+ break;
1634
+ default:
1635
+ state$5.push(current);
1636
+ process$6(current.event);
1637
+ break;
1638
+ }
1639
+ }
1640
+ function process$6(event) {
1641
+ schedule$1(encode$3.bind(this, event));
1642
+ }
1643
+ function reset$f() {
1644
+ state$5 = [];
1645
+ }
1646
+ function similar$1(last, current) {
1647
+ var dx = last.data.x - current.data.x;
1648
+ var dy = last.data.y - current.data.y;
1649
+ var distance = Math.sqrt(dx * dx + dy * dy);
1650
+ var gap = current.time - last.time;
1651
+ var match = current.data.target === last.data.target;
1652
+ return current.event === last.event && match && distance < 20 /* Setting.Distance */ && gap < 25 /* Setting.Interval */;
1653
+ }
1654
+
1655
+ var data$b;
1656
+ var timeout$4 = null;
1657
+ var initialStateLogged = false;
1658
+ function start$r() {
1659
+ initialStateLogged = false;
1660
+ bind(window, "resize", recompute$5);
1661
+ recompute$5();
1662
+ }
1663
+ function recompute$5() {
1664
+ var de = document.documentElement;
1665
+ // window.innerWidth includes width of the scrollbar and is not a true representation of the viewport width.
1666
+ // Therefore, when possible, use documentElement's clientWidth property.
1667
+ data$b = {
1668
+ width: de && "clientWidth" in de ? Math.min(de.clientWidth, window.innerWidth) : window.innerWidth,
1669
+ height: de && "clientHeight" in de ? Math.min(de.clientHeight, window.innerHeight) : window.innerHeight,
1670
+ };
1671
+ if (initialStateLogged) {
1672
+ clearTimeout$1(timeout$4);
1673
+ timeout$4 = setTimeout$1(process$5, 500 /* Setting.LookAhead */, 11 /* Event.Resize */);
1674
+ }
1675
+ else {
1676
+ encode$3(11 /* Event.Resize */);
1677
+ initialStateLogged = true;
1678
+ }
1679
+ }
1680
+ recompute$5.dn = 12 /* FunctionNames.ResizeRecompute */;
1681
+ function process$5(event) {
1682
+ schedule$1(encode$3.bind(this, event));
1683
+ }
1684
+ function reset$e() {
1685
+ data$b = null;
1686
+ clearTimeout$1(timeout$4);
1687
+ }
1688
+
1689
+ var state$4 = [];
1690
+ var initialTop = null;
1691
+ var initialBottom = null;
1692
+ var timeout$3 = null;
1693
+ function start$q() {
1694
+ state$4 = [];
1695
+ recompute$4();
1696
+ }
1697
+ function observe$7(root) {
1698
+ var frame = iframe(root);
1699
+ var node = frame ? frame.contentWindow : (root === document ? window : root);
1700
+ bind(node, "scroll", recompute$4, true);
1701
+ }
1702
+ function recompute$4(event) {
1703
+ if (event === void 0) { event = null; }
1704
+ var w = window;
1705
+ var de = document.documentElement;
1706
+ var element = event ? target(event) : de;
1707
+ // If the target is a Document node, then identify corresponding documentElement and window for this document
1708
+ if (element && element.nodeType === Node.DOCUMENT_NODE) {
1709
+ var frame = iframe(element);
1710
+ w = frame ? frame.contentWindow : w;
1711
+ element = de = element.documentElement;
1712
+ }
1713
+ // Edge doesn't support scrollTop position on document.documentElement.
1714
+ // For cross browser compatibility, looking up pageYOffset on window if the scroll is on document.
1715
+ // And, if for some reason that is not available, fall back to looking up scrollTop on document.documentElement.
1716
+ var x = element === de && "pageXOffset" in w ? Math.round(w.pageXOffset) : Math.round(element.scrollLeft);
1717
+ var y = element === de && "pageYOffset" in w ? Math.round(w.pageYOffset) : Math.round(element.scrollTop);
1718
+ var width = window.innerWidth;
1719
+ var height = window.innerHeight;
1720
+ var xPosition = width / 3;
1721
+ var yOffset = width > height ? height * 0.15 : height * 0.2;
1722
+ var startYPosition = yOffset;
1723
+ var endYPosition = height - yOffset;
1724
+ var top = getPositionNode(xPosition, startYPosition);
1725
+ var bottom = getPositionNode(xPosition, endYPosition);
1726
+ var current = { time: time$1(event), event: 10 /* Event.Scroll */, data: { target: element, x: x, y: y, top: top, bottom: bottom } };
1727
+ // We don't send any scroll events if this is the first event and the current position is top (0,0)
1728
+ if ((event === null && x === 0 && y === 0) || (x === null || y === null)) {
1729
+ initialTop = top;
1730
+ initialBottom = bottom;
1731
+ return;
1732
+ }
1733
+ var length = state$4.length;
1734
+ var last = length > 1 ? state$4[length - 2] : null;
1735
+ if (last && similar(last, current)) {
1736
+ state$4.pop();
1737
+ }
1738
+ state$4.push(current);
1739
+ clearTimeout$1(timeout$3);
1740
+ timeout$3 = setTimeout$1(process$4, 500 /* Setting.LookAhead */, 10 /* Event.Scroll */);
1741
+ }
1742
+ recompute$4.dn = 13 /* FunctionNames.ScrollRecompute */;
1743
+ function getPositionNode(x, y) {
1744
+ var _a, _b;
1745
+ var node;
1746
+ if ("caretPositionFromPoint" in document) {
1747
+ node = (_a = document.caretPositionFromPoint(x, y)) === null || _a === void 0 ? void 0 : _a.offsetNode;
1748
+ }
1749
+ else if ("caretRangeFromPoint" in document) {
1750
+ node = (_b = document.caretRangeFromPoint(x, y)) === null || _b === void 0 ? void 0 : _b.startContainer;
1751
+ }
1752
+ if (!node) {
1753
+ node = document.elementFromPoint(x, y);
1754
+ }
1755
+ if (node && node.nodeType === Node.TEXT_NODE) {
1756
+ node = node.parentNode;
1757
+ }
1758
+ return node;
1759
+ }
1760
+ function reset$d() {
1761
+ state$4 = [];
1762
+ initialTop = null;
1763
+ initialBottom = null;
1764
+ }
1765
+ function process$4(event) {
1766
+ schedule$1(encode$3.bind(this, event));
1767
+ }
1768
+ function similar(last, current) {
1769
+ var dx = last.data.x - current.data.x;
1770
+ var dy = last.data.y - current.data.y;
1771
+ return (dx * dx + dy * dy < 20 /* Setting.Distance */ * 20 /* Setting.Distance */) && (current.time - last.time < 25 /* Setting.Interval */);
1772
+ }
1773
+ function compute$8() {
1774
+ var _a, _b;
1775
+ if (initialTop) {
1776
+ var top_1 = metadata$2(initialTop, null);
1777
+ log(31 /* Dimension.InitialScrollTop */, (_a = top_1 === null || top_1 === void 0 ? void 0 : top_1.hash) === null || _a === void 0 ? void 0 : _a.join("." /* Constant.Dot */));
1778
+ }
1779
+ if (initialBottom) {
1780
+ var bottom = metadata$2(initialBottom, null);
1781
+ log(32 /* Dimension.InitialScrollBottom */, (_b = bottom === null || bottom === void 0 ? void 0 : bottom.hash) === null || _b === void 0 ? void 0 : _b.join("." /* Constant.Dot */));
1782
+ }
1783
+ }
1784
+ compute$8.dn = 14 /* FunctionNames.ScrollCompute */;
1785
+
1786
+ var data$a = null;
1787
+ var previous = null;
1788
+ var timeout$2 = null;
1789
+ function start$p() {
1790
+ reset$c();
1791
+ }
1792
+ function observe$6(root) {
1793
+ bind(root, "selectstart", recompute$3.bind(this, root), true);
1794
+ bind(root, "selectionchange", recompute$3.bind(this, root), true);
1795
+ }
1796
+ function recompute$3(root) {
1797
+ var doc = root.nodeType === Node.DOCUMENT_NODE ? root : document;
1798
+ var current = doc.getSelection();
1799
+ // Bail out if we don't have a valid selection
1800
+ if (current === null) {
1801
+ return;
1802
+ }
1803
+ // Bail out if we got a valid selection but not valid nodes
1804
+ // In Edge, selectionchange gets fired even on interactions like right clicks and
1805
+ // can result in null anchorNode and focusNode if there was no previous selection on page
1806
+ // Also, ignore any selections that start and end at the exact same point
1807
+ if ((current.anchorNode === null && current.focusNode === null) ||
1808
+ (current.anchorNode === current.focusNode && current.anchorOffset === current.focusOffset)) {
1809
+ return;
1810
+ }
1811
+ var startNode = data$a.start ? data$a.start : null;
1812
+ if (previous !== null && data$a.start !== null && startNode !== current.anchorNode) {
1813
+ clearTimeout$1(timeout$2);
1814
+ process$3(21 /* Event.Selection */);
1815
+ }
1816
+ data$a = {
1817
+ start: current.anchorNode,
1818
+ startOffset: current.anchorOffset,
1819
+ end: current.focusNode,
1820
+ endOffset: current.focusOffset
1821
+ };
1822
+ previous = current;
1823
+ clearTimeout$1(timeout$2);
1824
+ timeout$2 = setTimeout$1(process$3, 500 /* Setting.LookAhead */, 21 /* Event.Selection */);
1825
+ }
1826
+ recompute$3.dn = 15 /* FunctionNames.SelectionRecompute */;
1827
+ function process$3(event) {
1828
+ schedule$1(encode$3.bind(this, event));
1829
+ }
1830
+ function reset$c() {
1831
+ previous = null;
1832
+ data$a = { start: 0, startOffset: 0, end: 0, endOffset: 0 };
1833
+ }
1834
+
1835
+ var state$3 = [];
1836
+ function start$o() {
1837
+ reset$b();
1838
+ }
1839
+ function observe$5(root) {
1840
+ bind(root, "submit", recompute$2, true);
1841
+ }
1842
+ function recompute$2(evt) {
1843
+ state$3.push({ time: time$1(evt), event: 39 /* Event.Submit */, data: { target: target(evt) } });
1844
+ schedule$1(encode$3.bind(this, 39 /* Event.Submit */));
1845
+ }
1846
+ recompute$2.dn = 16 /* FunctionNames.SubmitRecompute */;
1847
+ function reset$b() {
1848
+ state$3 = [];
1849
+ }
1850
+
1851
+ var data$9;
1852
+ function start$n() {
1853
+ bind(window, "pagehide", recompute$1);
1854
+ }
1855
+ function recompute$1(evt) {
1856
+ data$9 = { name: evt.type };
1857
+ encode$3(26 /* Event.Unload */, time$1(evt));
1858
+ }
1859
+ recompute$1.dn = 17 /* FunctionNames.UnloadRecompute */;
1860
+ function reset$a() {
1861
+ data$9 = null;
1862
+ }
1863
+
1864
+ var data$8;
1865
+ function start$m() {
1866
+ bind(document, "visibilitychange", recompute);
1867
+ recompute();
1868
+ }
1869
+ function recompute(evt) {
1870
+ if (evt === void 0) { evt = null; }
1871
+ data$8 = { visible: "visibilityState" in document ? document.visibilityState : "default" };
1872
+ encode$3(28 /* Event.Visibility */, time$1(evt));
1873
+ }
1874
+ recompute.dn = 18 /* FunctionNames.VisibilityRecompute */;
1875
+ function reset$9() {
1876
+ data$8 = null;
1877
+ }
1878
+
1879
+ function start$l() {
1880
+ start$g();
1881
+ start$v();
1882
+ start$u();
1883
+ start$s();
1884
+ start$t();
1885
+ start$r();
1886
+ start$m();
1887
+ start$q();
1888
+ start$p();
1889
+ start$w();
1890
+ start$o();
1891
+ start$n();
1892
+ }
1893
+ start$l.dn = 8 /* FunctionNames.InteractionStart */;
1894
+ function observe$4(root) {
1895
+ observe$7(root);
1896
+ // Only monitor following interactions if the root node is a document
1897
+ // In case of shadow DOM, following events automatically bubble up to the parent document.
1898
+ if (root.nodeType === Node.DOCUMENT_NODE) {
1899
+ observe$b(root);
1900
+ observe$a(root);
1901
+ observe$8(root);
1902
+ observe$9(root);
1903
+ observe$6(root);
1904
+ observe$c(root);
1905
+ observe$5(root);
1906
+ }
1907
+ }
1908
+
1909
+ function traverse (root, timer, source, timestamp) {
1910
+ return __awaiter(this, void 0, void 0, function () {
1911
+ var queue, entry, next, state, subnode;
1912
+ return __generator(this, function (_a) {
1913
+ switch (_a.label) {
1914
+ case 0:
1915
+ queue = [root];
1916
+ _a.label = 1;
1917
+ case 1:
1918
+ if (!(queue.length > 0)) return [3 /*break*/, 4];
1919
+ entry = queue.shift();
1920
+ next = entry.firstChild;
1921
+ while (next) {
1922
+ queue.push(next);
1923
+ next = next.nextSibling;
1924
+ }
1925
+ state = state$a(timer);
1926
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 3];
1927
+ return [4 /*yield*/, suspend$1(timer)];
1928
+ case 2:
1929
+ state = _a.sent();
1930
+ _a.label = 3;
1931
+ case 3:
1932
+ if (state === 2 /* Task.Stop */) {
1933
+ return [3 /*break*/, 4];
1934
+ }
1935
+ subnode = processNode(entry, source, timestamp);
1936
+ if (subnode) {
1937
+ queue.push(subnode);
1938
+ }
1939
+ return [3 /*break*/, 1];
1940
+ case 4: return [2 /*return*/];
1941
+ }
1942
+ });
1943
+ });
1944
+ }
1945
+
1946
+ var observers = [];
1947
+ var mutations = [];
1948
+ var throttledMutations = {};
1949
+ var insertRule = null;
1950
+ var deleteRule = null;
1951
+ var attachShadow = null;
1952
+ var mediaInsertRule = null;
1953
+ var mediaDeleteRule = null;
1954
+ var queue$2 = [];
1955
+ var timeout$1 = null;
1956
+ var throttleDelay = null;
1957
+ var activePeriod = null;
1958
+ var history$4 = {};
1959
+ function start$k() {
1960
+ observers = [];
1961
+ queue$2 = [];
1962
+ timeout$1 = null;
1963
+ activePeriod = 0;
1964
+ history$4 = {};
1965
+ // Some popular open source libraries, like styled-components, optimize performance
1966
+ // by injecting CSS using insertRule API vs. appending text node. A side effect of
1967
+ // using javascript API is that it doesn't trigger DOM mutation and therefore we
1968
+ // need to override the insertRule API and listen for changes manually.
1969
+ if (insertRule === null) {
1970
+ insertRule = CSSStyleSheet.prototype.insertRule;
1971
+ CSSStyleSheet.prototype.insertRule = function () {
1972
+ return insertRule.apply(this, arguments);
1973
+ };
1974
+ }
1975
+ if ("CSSMediaRule" in window && mediaInsertRule === null) {
1976
+ mediaInsertRule = CSSMediaRule.prototype.insertRule;
1977
+ CSSMediaRule.prototype.insertRule = function () {
1978
+ return mediaInsertRule.apply(this, arguments);
1979
+ };
1980
+ }
1981
+ if (deleteRule === null) {
1982
+ deleteRule = CSSStyleSheet.prototype.deleteRule;
1983
+ CSSStyleSheet.prototype.deleteRule = function () {
1984
+ return deleteRule.apply(this, arguments);
1985
+ };
1986
+ }
1987
+ if ("CSSMediaRule" in window && mediaDeleteRule === null) {
1988
+ mediaDeleteRule = CSSMediaRule.prototype.deleteRule;
1989
+ CSSMediaRule.prototype.deleteRule = function () {
1990
+ return mediaDeleteRule.apply(this, arguments);
1991
+ };
1992
+ }
1993
+ // Add a hook to attachShadow API calls
1994
+ // In case we are unable to add a hook and browser throws an exception,
1995
+ // reset attachShadow variable and resume processing like before
1996
+ if (attachShadow === null) {
1997
+ attachShadow = Element.prototype.attachShadow;
1998
+ try {
1999
+ Element.prototype.attachShadow = function () {
2000
+ if (active()) ;
2001
+ else {
2002
+ return attachShadow.apply(this, arguments);
2003
+ }
2004
+ };
2005
+ }
2006
+ catch (_a) {
2007
+ attachShadow = null;
2008
+ }
2009
+ }
2010
+ }
2011
+ start$k.dn = 21 /* FunctionNames.MutationStart */;
2012
+ function observe$3(node) {
2013
+ // Create a new observer for every time a new DOM tree (e.g. root document or shadowdom root) is discovered on the page
2014
+ // In the case of shadow dom, any mutations that happen within the shadow dom are not bubbled up to the host document
2015
+ // For this reason, we need to wire up mutations every time we see a new shadow dom.
2016
+ // Also, wrap it inside a try / catch. In certain browsers (e.g. legacy Edge), observer on shadow dom can throw errors
2017
+ try {
2018
+ var m = api("MutationObserver" /* Constant.MutationObserver */);
2019
+ var observer = m in window ? new window[m](measure(handle$1)) : null;
2020
+ if (observer) {
2021
+ observer.observe(node, { attributes: true, childList: true, characterData: true, subtree: true });
2022
+ observers.push(observer);
2023
+ }
2024
+ }
2025
+ catch (e) {
2026
+ log$1(2 /* Code.MutationObserver */, 0 /* Severity.Info */, e ? e.name : null);
2027
+ }
2028
+ }
2029
+ function monitor(frame) {
2030
+ // Bind to iframe's onload event so we get notified anytime there's an update to iframe content.
2031
+ // This includes cases where iframe location is updated without explicitly updating src attribute
2032
+ // E.g. iframe.contentWindow.location.href = "new-location";
2033
+ if (has(frame) === false) {
2034
+ bind(frame, "load" /* Constant.LoadEvent */, generate.bind(this, frame, "childList" /* Constant.ChildList */), true);
2035
+ }
2036
+ }
2037
+ function active$2() {
2038
+ activePeriod = time$1() + 3000 /* Setting.MutationActivePeriod */;
2039
+ }
2040
+ function handle$1(m) {
2041
+ // Queue up mutation records for asynchronous processing
2042
+ var now = time$1();
2043
+ track$7(6 /* Event.Mutation */, now);
2044
+ mutations.push({ time: now, mutations: m });
2045
+ schedule$1(process$2, 1 /* Priority.High */).then(function () {
2046
+ setTimeout$1(compute$9);
2047
+ measure(compute$6)();
2048
+ });
2049
+ }
2050
+ handle$1.dn = 22 /* FunctionNames.MutationHandle */;
2051
+ function processMutation(timer, mutation, instance, timestamp) {
2052
+ return __awaiter(this, void 0, void 0, function () {
2053
+ var state, target, type;
2054
+ return __generator(this, function (_a) {
2055
+ switch (_a.label) {
2056
+ case 0:
2057
+ state = state$a(timer);
2058
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 2];
2059
+ return [4 /*yield*/, suspend$1(timer)];
2060
+ case 1:
2061
+ state = _a.sent();
2062
+ _a.label = 2;
2063
+ case 2:
2064
+ if (state === 2 /* Task.Stop */) {
2065
+ return [2 /*return*/];
2066
+ }
2067
+ target = mutation.target;
2068
+ type = track$5(mutation, timer, instance, timestamp) ;
2069
+ if (type && target && target.ownerDocument) {
2070
+ parse$1(target.ownerDocument);
2071
+ }
2072
+ if (type && target && target.nodeType == Node.DOCUMENT_FRAGMENT_NODE && target.host) {
2073
+ parse$1(target);
2074
+ }
2075
+ switch (type) {
2076
+ case "attributes" /* Constant.Attributes */:
2077
+ processNode(target, 3 /* Source.Attributes */, timestamp);
2078
+ break;
2079
+ case "characterData" /* Constant.CharacterData */:
2080
+ processNode(target, 4 /* Source.CharacterData */, timestamp);
2081
+ break;
2082
+ case "childList" /* Constant.ChildList */:
2083
+ processNodeList(mutation.addedNodes, 1 /* Source.ChildListAdd */, timer, timestamp);
2084
+ processNodeList(mutation.removedNodes, 2 /* Source.ChildListRemove */, timer, timestamp);
2085
+ break;
2086
+ }
2087
+ return [2 /*return*/];
2088
+ }
2089
+ });
2090
+ });
2091
+ }
2092
+ function process$2() {
2093
+ return __awaiter(this, void 0, void 0, function () {
2094
+ var timer, record, instance, _i, _a, mutation, processedMutations, _b, _c, key, throttledMutationToProcess;
2095
+ return __generator(this, function (_d) {
2096
+ switch (_d.label) {
2097
+ case 0:
2098
+ timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
2099
+ start$y(timer);
2100
+ _d.label = 1;
2101
+ case 1:
2102
+ if (!(mutations.length > 0)) return [3 /*break*/, 3];
2103
+ record = mutations.shift();
2104
+ instance = time$1();
2105
+ for (_i = 0, _a = record.mutations; _i < _a.length; _i++) {
2106
+ mutation = _a[_i];
2107
+ processMutation(timer, mutation, instance, record.time);
2108
+ }
2109
+ return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, record.time)];
2110
+ case 2:
2111
+ _d.sent();
2112
+ return [3 /*break*/, 1];
2113
+ case 3:
2114
+ processedMutations = false;
2115
+ for (_b = 0, _c = Object.keys(throttledMutations); _b < _c.length; _b++) {
2116
+ key = _c[_b];
2117
+ throttledMutationToProcess = throttledMutations[key];
2118
+ delete throttledMutations[key];
2119
+ processMutation(timer, throttledMutationToProcess.mutation, time$1(), throttledMutationToProcess.timestamp);
2120
+ processedMutations = true;
2121
+ }
2122
+ if (Object.keys(throttledMutations).length > 0) {
2123
+ processThrottledMutations();
2124
+ }
2125
+ if (!(Object.keys(throttledMutations).length === 0 && processedMutations)) return [3 /*break*/, 5];
2126
+ return [4 /*yield*/, encode$4(6 /* Event.Mutation */, timer, time$1())];
2127
+ case 4:
2128
+ _d.sent();
2129
+ _d.label = 5;
2130
+ case 5:
2131
+ stop$w(timer);
2132
+ return [2 /*return*/];
2133
+ }
2134
+ });
2135
+ });
2136
+ }
2137
+ function track$5(m, timer, instance, timestamp) {
2138
+ var value = m.target ? get$2(m.target.parentNode) : null;
2139
+ // Check if the parent is already discovered and that the parent is not the document root
2140
+ if (value && value.data.tag !== "HTML" /* Constant.HTML */) {
2141
+ // calculate inactive period based on the timestamp of the mutation not when the mutation is processed
2142
+ var inactive = timestamp > activePeriod;
2143
+ var target = get$2(m.target);
2144
+ var element = target && target.selector ? target.selector.join() : m.target.nodeName;
2145
+ var parent_1 = value.selector ? value.selector.join() : "" /* Constant.Empty */;
2146
+ // We use selector, instead of id, to determine the key (signature for the mutation) because in some cases
2147
+ // repeated mutations can cause elements to be destroyed and then recreated as new DOM nodes
2148
+ // In those cases, IDs will change however the selector (which is relative to DOM xPath) remains the same
2149
+ var key = [parent_1, element, m.attributeName, names(m.addedNodes), names(m.removedNodes)].join();
2150
+ // Initialize an entry if it doesn't already exist
2151
+ history$4[key] = key in history$4 ? history$4[key] : [0, instance];
2152
+ var h = history$4[key];
2153
+ // Lookup any pending nodes queued up for removal, and process them now if we suspended a mutation before
2154
+ if (inactive === false && h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
2155
+ processNodeList(h[2], 2 /* Source.ChildListRemove */, timer, timestamp);
2156
+ }
2157
+ // Update the counter
2158
+ h[0] = inactive ? (h[1] === instance ? h[0] : h[0] + 1) : 1;
2159
+ h[1] = instance;
2160
+ // Return updated mutation type based on if we have already hit the threshold or not
2161
+ if (h[0] >= 10 /* Setting.MutationSuspendThreshold */) {
2162
+ // Store a reference to removedNodes so we can process them later
2163
+ // when we resume mutations again on user interactions
2164
+ h[2] = m.removedNodes;
2165
+ if (instance > timestamp + 3000 /* Setting.MutationActivePeriod */) {
2166
+ return m.type;
2167
+ }
2168
+ // we only store the most recent mutation for a given key if it is being throttled
2169
+ throttledMutations[key] = { mutation: m, timestamp: timestamp };
2170
+ return "throttle" /* Constant.Throttle */;
2171
+ }
2172
+ }
2173
+ return m.type;
2174
+ }
2175
+ function names(nodes) {
2176
+ var output = [];
2177
+ for (var i = 0; nodes && i < nodes.length; i++) {
2178
+ output.push(nodes[i].nodeName);
2179
+ }
2180
+ return output.join();
2181
+ }
2182
+ function processNodeList(list, source, timer, timestamp) {
2183
+ return __awaiter(this, void 0, void 0, function () {
2184
+ var length, i, state;
2185
+ return __generator(this, function (_a) {
2186
+ switch (_a.label) {
2187
+ case 0:
2188
+ length = list ? list.length : 0;
2189
+ i = 0;
2190
+ _a.label = 1;
2191
+ case 1:
2192
+ if (!(i < length)) return [3 /*break*/, 6];
2193
+ if (!(source === 1 /* Source.ChildListAdd */)) return [3 /*break*/, 2];
2194
+ traverse(list[i], timer, source, timestamp);
2195
+ return [3 /*break*/, 5];
2196
+ case 2:
2197
+ state = state$a(timer);
2198
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 4];
2199
+ return [4 /*yield*/, suspend$1(timer)];
2200
+ case 3:
2201
+ state = _a.sent();
2202
+ _a.label = 4;
2203
+ case 4:
2204
+ if (state === 2 /* Task.Stop */) {
2205
+ return [3 /*break*/, 6];
2206
+ }
2207
+ processNode(list[i], source, timestamp);
2208
+ _a.label = 5;
2209
+ case 5:
2210
+ i++;
2211
+ return [3 /*break*/, 1];
2212
+ case 6: return [2 /*return*/];
2213
+ }
2214
+ });
2215
+ });
2216
+ }
2217
+ function processThrottledMutations() {
2218
+ if (throttleDelay) {
2219
+ clearTimeout$1(throttleDelay);
2220
+ }
2221
+ throttleDelay = setTimeout$1(function () { schedule$1(process$2, 1 /* Priority.High */); }, 33 /* Setting.LookAhead */);
2222
+ }
2223
+ function schedule(node) {
2224
+ // Only schedule manual trigger for this node if it's not already in the queue
2225
+ if (queue$2.indexOf(node) < 0) {
2226
+ queue$2.push(node);
2227
+ }
2228
+ // Cancel any previous trigger before scheduling a new one.
2229
+ // It's common for a webpage to call multiple synchronous "insertRule" / "deleteRule" calls.
2230
+ // And in those cases we do not wish to monitor changes multiple times for the same node.
2231
+ if (timeout$1) {
2232
+ clearTimeout$1(timeout$1);
2233
+ }
2234
+ timeout$1 = setTimeout$1(function () { trigger$2(); }, 33 /* Setting.LookAhead */);
2235
+ return node;
2236
+ }
2237
+ function trigger$2() {
2238
+ for (var _i = 0, queue_1 = queue$2; _i < queue_1.length; _i++) {
2239
+ var node = queue_1[_i];
2240
+ // Generate a mutation for this node only if it still exists
2241
+ if (node) {
2242
+ var shadowRoot = node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
2243
+ // Skip re-processing shadowRoot if it was already discovered
2244
+ if (shadowRoot && has(node)) {
2245
+ continue;
2246
+ }
2247
+ generate(node, shadowRoot ? "childList" /* Constant.ChildList */ : "characterData" /* Constant.CharacterData */);
2248
+ }
2249
+ }
2250
+ queue$2 = [];
2251
+ }
2252
+ function generate(target, type) {
2253
+ measure(handle$1)([{
2254
+ addedNodes: [target],
2255
+ attributeName: null,
2256
+ attributeNamespace: null,
2257
+ nextSibling: null,
2258
+ oldValue: null,
2259
+ previousSibling: null,
2260
+ removedNodes: [],
2261
+ target: target,
2262
+ type: type
2263
+ }]);
2264
+ }
2265
+ generate.dn = 23 /* FunctionNames.MutationGenerate */;
2266
+
2267
+ var digitsRegex = /[^0-9\.]/g;
2268
+ /* JSON+LD (Linked Data) Recursive Parser */
2269
+ function ld(json) {
2270
+ for (var _i = 0, _a = Object.keys(json); _i < _a.length; _i++) {
2271
+ var key = _a[_i];
2272
+ var value = json[key];
2273
+ if (key === "@type" /* JsonLD.Type */ && typeof value === "string") {
2274
+ value = value.toLowerCase();
2275
+ /* Normalizations */
2276
+ value = value.indexOf("article" /* JsonLD.Article */) >= 0 || value.indexOf("posting" /* JsonLD.Posting */) >= 0 ? "article" /* JsonLD.Article */ : value;
2277
+ switch (value) {
2278
+ case "article" /* JsonLD.Article */:
2279
+ case "recipe" /* JsonLD.Recipe */:
2280
+ log(5 /* Dimension.SchemaType */, json[key]);
2281
+ log(8 /* Dimension.AuthorName */, json["creator" /* JsonLD.Creator */]);
2282
+ log(18 /* Dimension.Headline */, json["headline" /* JsonLD.Headline */]);
2283
+ break;
2284
+ case "product" /* JsonLD.Product */:
2285
+ log(5 /* Dimension.SchemaType */, json[key]);
2286
+ log(10 /* Dimension.ProductName */, json["name" /* JsonLD.Name */]);
2287
+ log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
2288
+ if (json["brand" /* JsonLD.Brand */]) {
2289
+ log(6 /* Dimension.ProductBrand */, json["brand" /* JsonLD.Brand */]["name" /* JsonLD.Name */]);
2290
+ }
2291
+ break;
2292
+ case "aggregaterating" /* JsonLD.AggregateRating */:
2293
+ if (json["ratingValue" /* JsonLD.RatingValue */]) {
2294
+ max(11 /* Metric.RatingValue */, num$1(json["ratingValue" /* JsonLD.RatingValue */], 100 /* Setting.RatingScale */));
2295
+ max(18 /* Metric.BestRating */, num$1(json["bestRating" /* JsonLD.BestRating */]));
2296
+ max(19 /* Metric.WorstRating */, num$1(json["worstRating" /* JsonLD.WorstRating */]));
2297
+ }
2298
+ max(12 /* Metric.RatingCount */, num$1(json["ratingCount" /* JsonLD.RatingCount */]));
2299
+ max(17 /* Metric.ReviewCount */, num$1(json["reviewCount" /* JsonLD.ReviewCount */]));
2300
+ break;
2301
+ case "offer" /* JsonLD.Offer */:
2302
+ log(7 /* Dimension.ProductAvailability */, json["availability" /* JsonLD.Availability */]);
2303
+ log(14 /* Dimension.ProductCondition */, json["itemCondition" /* JsonLD.ItemCondition */]);
2304
+ log(13 /* Dimension.ProductCurrency */, json["priceCurrency" /* JsonLD.PriceCurrency */]);
2305
+ log(12 /* Dimension.ProductSku */, json["sku" /* JsonLD.Sku */]);
2306
+ max(13 /* Metric.ProductPrice */, num$1(json["price" /* JsonLD.Price */]));
2307
+ break;
2308
+ case "brand" /* JsonLD.Brand */:
2309
+ log(6 /* Dimension.ProductBrand */, json["name" /* JsonLD.Name */]);
2310
+ break;
2311
+ }
2312
+ }
2313
+ // Continue parsing nested objects
2314
+ if (value !== null && typeof (value) === "object" /* Constant.Object */) {
2315
+ ld(value);
2316
+ }
2317
+ }
2318
+ }
2319
+ function num$1(input, scale) {
2320
+ if (scale === void 0) { scale = 1; }
2321
+ if (input !== null) {
2322
+ switch (typeof input) {
2323
+ case "number" /* Constant.Number */: return Math.round(input * scale);
2324
+ case "string" /* Constant.String */: return Math.round(parseFloat(input.replace(digitsRegex, "" /* Constant.Empty */)) * scale);
2325
+ }
2326
+ }
2327
+ return null;
2328
+ }
2329
+
2330
+ var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror", "data-drupal-form-submit-last", "aria-label"];
2331
+ var newlineRegex = /[\r\n]+/g;
2332
+ function processNode (node, source, timestamp) {
2333
+ var _a;
2334
+ var child = null;
2335
+ // Do not track this change if we are attempting to remove a node before discovering it
2336
+ if (source === 2 /* Source.ChildListRemove */ && has(node) === false) {
2337
+ return child;
2338
+ }
2339
+ // Special handling for text nodes that belong to style nodes
2340
+ if (source !== 0 /* Source.Discover */ &&
2341
+ node.nodeType === Node.TEXT_NODE &&
2342
+ node.parentElement &&
2343
+ node.parentElement.tagName === "STYLE") {
2344
+ node = node.parentNode;
2345
+ }
2346
+ var add = has(node) === false;
2347
+ var call = add ? "add" : "update";
2348
+ var parent = node.parentElement ? node.parentElement : null;
2349
+ var insideFrame = node.ownerDocument !== document;
2350
+ switch (node.nodeType) {
2351
+ case Node.DOCUMENT_TYPE_NODE:
2352
+ parent = insideFrame && node.parentNode ? iframe(node.parentNode) : parent;
2353
+ var docTypePrefix = insideFrame ? "iframe:" /* Constant.IFramePrefix */ : "" /* Constant.Empty */;
2354
+ var doctype = node;
2355
+ var docName = doctype.name ? doctype.name : "HTML" /* Constant.HTML */;
2356
+ var docAttributes = { name: docName, publicId: doctype.publicId, systemId: doctype.systemId };
2357
+ var docData = { tag: docTypePrefix + "*D" /* Constant.DocumentTag */, attributes: docAttributes };
2358
+ dom$1[call](node, parent, docData, source);
2359
+ break;
2360
+ case Node.DOCUMENT_NODE:
2361
+ // We check for regions in the beginning when discovering document and
2362
+ // later whenever there are new additions or modifications to DOM (mutations)
2363
+ if (node === document)
2364
+ parse$1(document);
2365
+ checkDocumentStyles(node, timestamp);
2366
+ observe$2(node);
2367
+ break;
2368
+ case Node.DOCUMENT_FRAGMENT_NODE:
2369
+ var shadowRoot = node;
2370
+ if (shadowRoot.host) {
2371
+ parse$1(shadowRoot);
2372
+ var type = typeof (shadowRoot.constructor);
2373
+ if (type === "function" /* Constant.Function */ && shadowRoot.constructor.toString().indexOf("[native code]" /* Constant.NativeCode */) >= 0) {
2374
+ observe$2(shadowRoot);
2375
+ // See: https://wicg.github.io/construct-stylesheets/ for more details on adoptedStyleSheets.
2376
+ // At the moment, we are only able to capture "open" shadow DOM nodes. If they are closed, they are not accessible.
2377
+ // In future we may decide to proxy "attachShadow" call to gain access, but at the moment, we don't want to
2378
+ // cause any unintended side effect to the page. We will re-evaluate after we gather more real world data on this.
2379
+ var style = "" /* Constant.Empty */;
2380
+ var fragmentData = { tag: "*S" /* Constant.ShadowDomTag */, attributes: { style: style } };
2381
+ dom$1[call](node, shadowRoot.host, fragmentData, source);
2382
+ }
2383
+ else {
2384
+ // If the browser doesn't support shadow DOM natively, we detect that, and send appropriate tag back.
2385
+ // The differentiation is important because we don't have to observe pollyfill shadow DOM nodes,
2386
+ // the same way we observe real shadow DOM nodes (encapsulation provided by the browser).
2387
+ dom$1[call](node, shadowRoot.host, { tag: "*P" /* Constant.PolyfillShadowDomTag */, attributes: {} }, source);
2388
+ }
2389
+ checkDocumentStyles(node, timestamp);
2390
+ }
2391
+ break;
2392
+ case Node.TEXT_NODE:
2393
+ // In IE11 TEXT_NODE doesn't expose a valid parentElement property. Instead we need to lookup parentNode property.
2394
+ parent = parent ? parent : node.parentNode;
2395
+ // Account for this text node only if we are tracking the parent node
2396
+ // We do not wish to track text nodes for ignored parent nodes, like script tags
2397
+ // Also, we do not track text nodes for STYLE tags
2398
+ // The only exception is when we receive a mutation to remove the text node, in that case
2399
+ // parent will be null, but we can still process the node by checking it's an update call.
2400
+ if (call === "update" || (parent && has(parent) && parent.tagName !== "STYLE" && parent.tagName !== "NOSCRIPT")) {
2401
+ var textData = { tag: "*T" /* Constant.TextTag */, value: node.nodeValue };
2402
+ dom$1[call](node, parent, textData, source);
2403
+ }
2404
+ break;
2405
+ case Node.ELEMENT_NODE:
2406
+ var element = node;
2407
+ var tag = element.tagName;
2408
+ var attributes = getAttributes(element);
2409
+ // In some cases, external libraries like vue-fragment, can modify parentNode property to not be in sync with the DOM
2410
+ // For correctness, we first look at parentElement and if it not present then fall back to using parentNode
2411
+ parent = node.parentElement ? node.parentElement : (node.parentNode ? node.parentNode : null);
2412
+ // If we encounter a node that is part of SVG namespace, prefix the tag with SVG_PREFIX
2413
+ if (element.namespaceURI === "http://www.w3.org/2000/svg" /* Constant.SvgNamespace */) {
2414
+ tag = "svg:" /* Constant.SvgPrefix */ + tag;
2415
+ }
2416
+ switch (tag) {
2417
+ case "HTML":
2418
+ parent = insideFrame && parent ? iframe(parent) : parent;
2419
+ var htmlPrefix = insideFrame ? "iframe:" /* Constant.IFramePrefix */ : "" /* Constant.Empty */;
2420
+ var htmlData = { tag: htmlPrefix + tag, attributes: attributes };
2421
+ dom$1[call](node, parent, htmlData, source);
2422
+ break;
2423
+ case "SCRIPT":
2424
+ if ("type" /* Constant.Type */ in attributes && attributes["type" /* Constant.Type */] === "application/ld+json" /* Constant.JsonLD */) {
2425
+ try {
2426
+ ld(JSON.parse(element.text.replace(newlineRegex, "" /* Constant.Empty */)));
2427
+ }
2428
+ catch ( /* do nothing */_b) { /* do nothing */ }
2429
+ }
2430
+ break;
2431
+ case "NOSCRIPT":
2432
+ // keeping the noscript tag but ignoring its contents. Some HTML markup relies on having these tags
2433
+ // to maintain parity with the original css view, but we don't want to execute any noscript in Clarity
2434
+ var noscriptData = { tag: tag, attributes: {}, value: '' };
2435
+ dom$1[call](node, parent, noscriptData, source);
2436
+ break;
2437
+ case "META":
2438
+ var key = ("property" /* Constant.Property */ in attributes ?
2439
+ "property" /* Constant.Property */ :
2440
+ ("name" /* Constant.Name */ in attributes ? "name" /* Constant.Name */ : null));
2441
+ if (key && "content" /* Constant.Content */ in attributes) {
2442
+ var content = attributes["content" /* Constant.Content */];
2443
+ switch (attributes[key]) {
2444
+ case "og:title" /* Constant.ogTitle */:
2445
+ log(20 /* Dimension.MetaTitle */, content);
2446
+ break;
2447
+ case "og:type" /* Constant.ogType */:
2448
+ log(19 /* Dimension.MetaType */, content);
2449
+ break;
2450
+ case "generator" /* Constant.Generator */:
2451
+ log(21 /* Dimension.Generator */, content);
2452
+ break;
2453
+ }
2454
+ }
2455
+ break;
2456
+ case "HEAD":
2457
+ var head = { tag: tag, attributes: attributes };
2458
+ var l = insideFrame && ((_a = node.ownerDocument) === null || _a === void 0 ? void 0 : _a.location) ? node.ownerDocument.location : location;
2459
+ head.attributes["*B" /* Constant.Base */] = l.protocol + "//" + l.host + l.pathname;
2460
+ dom$1[call](node, parent, head, source);
2461
+ break;
2462
+ case "BASE":
2463
+ // Override the auto detected base path to explicit value specified in this tag
2464
+ var baseHead = get$2(node.parentElement);
2465
+ if (baseHead) {
2466
+ // We create "a" element so we can generate protocol and hostname for relative paths like "/path/"
2467
+ var a = document.createElement("a");
2468
+ a.href = attributes["href"];
2469
+ baseHead.data.attributes["*B" /* Constant.Base */] = a.protocol + "//" + a.host + a.pathname;
2470
+ }
2471
+ break;
2472
+ case "STYLE":
2473
+ var styleData = { tag: tag, attributes: attributes, value: getStyleValue(element) };
2474
+ dom$1[call](node, parent, styleData, source);
2475
+ break;
2476
+ case "IFRAME":
2477
+ var iframe$1 = node;
2478
+ var frameData = { tag: tag, attributes: attributes };
2479
+ if (sameorigin(iframe$1)) {
2480
+ monitor(iframe$1);
2481
+ frameData.attributes["*O" /* Constant.SameOrigin */] = "true";
2482
+ if (iframe$1.contentDocument && iframe$1.contentWindow && iframe$1.contentDocument.readyState !== "loading") {
2483
+ child = iframe$1.contentDocument;
2484
+ }
2485
+ }
2486
+ dom$1[call](node, parent, frameData, source);
2487
+ break;
2488
+ case "LINK":
2489
+ // for links that aren't electron style sheets we can process them normally
2490
+ var linkData = { tag: tag, attributes: attributes };
2491
+ dom$1[call](node, parent, linkData, source);
2492
+ break;
2493
+ case "VIDEO":
2494
+ case "AUDIO":
2495
+ case "SOURCE":
2496
+ // Ignoring any base64 src attribute for media elements to prevent big unused tokens to be sent and shock the network
2497
+ if ("src" /* Constant.Src */ in attributes && attributes["src" /* Constant.Src */].startsWith("data:")) {
2498
+ attributes["src" /* Constant.Src */] = "";
2499
+ }
2500
+ var mediaTag = { tag: tag, attributes: attributes };
2501
+ dom$1[call](node, parent, mediaTag, source);
2502
+ break;
2503
+ default:
2504
+ var data = { tag: tag, attributes: attributes };
2505
+ if (element.shadowRoot) {
2506
+ child = element.shadowRoot;
2507
+ }
2508
+ dom$1[call](node, parent, data, source);
2509
+ break;
2510
+ }
2511
+ break;
2512
+ }
2513
+ return child;
2514
+ }
2515
+ function observe$2(root) {
2516
+ if (has(root)) {
2517
+ return;
2518
+ }
2519
+ observe$3(root); // Observe mutations for this root node
2520
+ observe$4(root); // Observe interactions for this root node
2521
+ }
2522
+ function getStyleValue(style) {
2523
+ // Call trim on the text content to ensure we do not process white spaces ( , \n, \r\n, \t, etc.)
2524
+ // Also, check if stylesheet has any data-* attribute, if so process rules instead of looking up text
2525
+ // Additionally, check if style node has an id - if so it's at a high risk to have experienced dynamic
2526
+ // style updates which would make the textContent out of date with its true style contribution.
2527
+ var value = style.textContent ? style.textContent.trim() : "" /* Constant.Empty */;
2528
+ var dataset = style.dataset ? Object.keys(style.dataset).length : 0;
2529
+ if (value.length === 0 || dataset > 0 || style.id.length > 0) {
2530
+ value = getCssRules(style.sheet);
2531
+ }
2532
+ return value;
2533
+ }
2534
+ function getCssRules(sheet) {
2535
+ var value = "" /* Constant.Empty */;
2536
+ var cssRules = null;
2537
+ // Firefox throws a SecurityError when trying to access cssRules of a stylesheet from a different domain
2538
+ try {
2539
+ cssRules = sheet ? sheet.cssRules : [];
2540
+ }
2541
+ catch (e) {
2542
+ log$1(1 /* Code.CssRules */, 1 /* Severity.Warning */, e ? e.name : null);
2543
+ if (e && e.name !== "SecurityError") {
2544
+ throw e;
2545
+ }
2546
+ }
2547
+ if (cssRules !== null) {
2548
+ for (var i = 0; i < cssRules.length; i++) {
2549
+ value += cssRules[i].cssText;
2550
+ }
2551
+ }
2552
+ return value;
2553
+ }
2554
+ function getAttributes(element) {
2555
+ var output = {};
2556
+ var attributes = element.attributes;
2557
+ if (attributes && attributes.length > 0) {
2558
+ for (var i = 0; i < attributes.length; i++) {
2559
+ var name_1 = attributes[i].name;
2560
+ if (IGNORE_ATTRIBUTES.indexOf(name_1) < 0) {
2561
+ output[name_1] = attributes[i].value;
2562
+ }
2563
+ }
2564
+ }
2565
+ // For INPUT tags read the dynamic "value" property if an explicit "value" attribute is not set
2566
+ if (element.tagName === "INPUT" /* Constant.InputTag */ && !("value" /* Constant.Value */ in output) && element.value) {
2567
+ output["value" /* Constant.Value */] = element.value;
2568
+ }
2569
+ return output;
2570
+ }
2571
+
2572
+ var sheetUpdateState = [];
2573
+ var sheetAdoptionState = [];
2574
+ var replace = null;
2575
+ var replaceSync = null;
2576
+ var styleSheetId = 'claritySheetId';
2577
+ var styleSheetPageNum = 'claritySheetNum';
2578
+ var styleSheetMap = {};
2579
+ function start$j() {
2580
+ if (replace === null) {
2581
+ replace = CSSStyleSheet.prototype.replace;
2582
+ CSSStyleSheet.prototype.replace = function () {
2583
+ return replace.apply(this, arguments);
2584
+ };
2585
+ }
2586
+ if (replaceSync === null) {
2587
+ replaceSync = CSSStyleSheet.prototype.replaceSync;
2588
+ CSSStyleSheet.prototype.replaceSync = function () {
2589
+ return replaceSync.apply(this, arguments);
2590
+ };
2591
+ }
2592
+ }
2593
+ function checkDocumentStyles(documentNode, timestamp) {
2594
+ timestamp = timestamp || time$1();
2595
+ if (!(documentNode === null || documentNode === void 0 ? void 0 : documentNode.adoptedStyleSheets)) {
2596
+ // if we don't have adoptedStyledSheets on the Node passed to us, we can short circuit.
2597
+ return;
2598
+ }
2599
+ max(36 /* Metric.ConstructedStyles */, 1);
2600
+ var currentStyleSheets = [];
2601
+ for (var _i = 0, _a = documentNode.adoptedStyleSheets; _i < _a.length; _i++) {
2602
+ var styleSheet = _a[_i];
2603
+ var pageNum = data$2.pageNum;
2604
+ // If we haven't seen this style sheet on this page yet, we create a reference to it for the visualizer.
2605
+ // For SPA or times in which Clarity restarts on a given page, our visualizer would lose context
2606
+ // on the previously created style sheet for page N-1.
2607
+ // Then we synthetically call replaceSync with its contents to bootstrap it
2608
+ if (styleSheet[styleSheetPageNum] !== pageNum) {
2609
+ styleSheet[styleSheetPageNum] = pageNum;
2610
+ styleSheet[styleSheetId] = shortid();
2611
+ trackStyleChange(timestamp, styleSheet[styleSheetId], 0 /* StyleSheetOperation.Create */);
2612
+ trackStyleChange(timestamp, styleSheet[styleSheetId], 2 /* StyleSheetOperation.ReplaceSync */, getCssRules(styleSheet));
2613
+ }
2614
+ currentStyleSheets.push(styleSheet[styleSheetId]);
2615
+ }
2616
+ var documentId = getId(documentNode, true);
2617
+ if (!styleSheetMap[documentId]) {
2618
+ styleSheetMap[documentId] = [];
2619
+ }
2620
+ if (!arraysEqual(currentStyleSheets, styleSheetMap[documentId])) {
2621
+ // Using -1 to signify the root document node as we don't track that as part of our nodeMap
2622
+ trackStyleAdoption(timestamp, documentNode == document ? -1 : getId(documentNode), 3 /* StyleSheetOperation.SetAdoptedStyles */, currentStyleSheets);
2623
+ styleSheetMap[documentId] = currentStyleSheets;
2624
+ }
2625
+ }
2626
+ function reset$8() {
2627
+ sheetAdoptionState = [];
2628
+ sheetUpdateState = [];
2629
+ }
2630
+ function trackStyleChange(time, id, operation, cssRules) {
2631
+ sheetUpdateState.push({
2632
+ time: time,
2633
+ event: 46 /* Event.StyleSheetUpdate */,
2634
+ data: {
2635
+ id: id,
2636
+ operation: operation,
2637
+ cssRules: cssRules
2638
+ }
2639
+ });
2640
+ encode$4(46 /* Event.StyleSheetUpdate */);
2641
+ }
2642
+ function trackStyleAdoption(time, id, operation, newIds) {
2643
+ sheetAdoptionState.push({
2644
+ time: time,
2645
+ event: 45 /* Event.StyleSheetAdoption */,
2646
+ data: {
2647
+ id: id,
2648
+ operation: operation,
2649
+ newIds: newIds
2650
+ }
2651
+ });
2652
+ encode$4(45 /* Event.StyleSheetAdoption */);
2653
+ }
2654
+ function arraysEqual(a, b) {
2655
+ if (a.length !== b.length) {
2656
+ return false;
2657
+ }
2658
+ return a.every(function (value, index) { return value === b[index]; });
2659
+ }
2660
+
2661
+ var state$2 = [];
2662
+ var elementAnimate = null;
2663
+ var animationPlay = null;
2664
+ var animationPause = null;
2665
+ var animationCommitStyles = null;
2666
+ var animationCancel = null;
2667
+ var animationFinish = null;
2668
+ function start$i() {
2669
+ if (window["Animation"] &&
2670
+ window["Animation"].prototype &&
2671
+ window["KeyframeEffect"] &&
2672
+ window["KeyframeEffect"].prototype &&
2673
+ window["KeyframeEffect"].prototype.getKeyframes &&
2674
+ window["KeyframeEffect"].prototype.getTiming) {
2675
+ reset$7();
2676
+ overrideAnimationHelper(animationPlay, "play");
2677
+ overrideAnimationHelper(animationPause, "pause");
2678
+ overrideAnimationHelper(animationCommitStyles, "commitStyles");
2679
+ overrideAnimationHelper(animationCancel, "cancel");
2680
+ overrideAnimationHelper(animationFinish, "finish");
2681
+ if (elementAnimate === null) {
2682
+ elementAnimate = Element.prototype.animate;
2683
+ Element.prototype.animate = function () {
2684
+ var createdAnimation = elementAnimate.apply(this, arguments);
2685
+ return createdAnimation;
2686
+ };
2687
+ }
2688
+ if (document.getAnimations) {
2689
+ for (var _i = 0, _a = document.getAnimations(); _i < _a.length; _i++) {
2690
+ var animation = _a[_i];
2691
+ if (animation.playState === "finished") ;
2692
+ else if (animation.playState === "paused" || animation.playState === "idle") ;
2693
+ else if (animation.playState === "running") ;
2694
+ }
2695
+ }
2696
+ }
2697
+ }
2698
+ function reset$7() {
2699
+ state$2 = [];
2700
+ }
2701
+ function overrideAnimationHelper(functionToOverride, name) {
2702
+ if (functionToOverride === null) {
2703
+ functionToOverride = Animation.prototype[name];
2704
+ Animation.prototype[name] = function () {
2705
+ return functionToOverride.apply(this, arguments);
2706
+ };
2707
+ }
2708
+ }
2709
+
2710
+ function encode$4 (type, timer, ts) {
2711
+ if (timer === void 0) { timer = null; }
2712
+ if (ts === void 0) { ts = null; }
2713
+ return __awaiter(this, void 0, void 0, function () {
2714
+ var eventTime, tokens, _a, d, _i, _b, r, _c, _d, entry, _e, _f, entry, _g, _h, entry, values, _j, values_1, value, state, data, active, suspend, privacy, mangle, keys, _k, keys_1, key, box, factor, attr;
2715
+ return __generator(this, function (_l) {
2716
+ switch (_l.label) {
2717
+ case 0:
2718
+ eventTime = ts || time$1();
2719
+ tokens = [eventTime, type];
2720
+ _a = type;
2721
+ switch (_a) {
2722
+ case 8 /* Event.Document */: return [3 /*break*/, 1];
2723
+ case 7 /* Event.Region */: return [3 /*break*/, 2];
2724
+ case 45 /* Event.StyleSheetAdoption */: return [3 /*break*/, 3];
2725
+ case 46 /* Event.StyleSheetUpdate */: return [3 /*break*/, 3];
2726
+ case 44 /* Event.Animation */: return [3 /*break*/, 4];
2727
+ case 5 /* Event.Discover */: return [3 /*break*/, 5];
2728
+ case 6 /* Event.Mutation */: return [3 /*break*/, 5];
2729
+ }
2730
+ return [3 /*break*/, 12];
2731
+ case 1:
2732
+ d = data$c;
2733
+ tokens.push(d.width);
2734
+ tokens.push(d.height);
2735
+ track$8(type, d.width, d.height);
2736
+ return [3 /*break*/, 12];
2737
+ case 2:
2738
+ for (_i = 0, _b = state$1; _i < _b.length; _i++) {
2739
+ r = _b[_i];
2740
+ tokens = [r.time, 7 /* Event.Region */];
2741
+ tokens.push(r.data.id);
2742
+ tokens.push(r.data.interaction);
2743
+ tokens.push(r.data.visibility);
2744
+ tokens.push(r.data.name);
2745
+ }
2746
+ reset$6();
2747
+ return [3 /*break*/, 12];
2748
+ case 3:
2749
+ for (_c = 0, _d = sheetAdoptionState; _c < _d.length; _c++) {
2750
+ entry = _d[_c];
2751
+ tokens = [entry.time, entry.event];
2752
+ tokens.push(entry.data.id);
2753
+ tokens.push(entry.data.operation);
2754
+ tokens.push(entry.data.newIds);
2755
+ }
2756
+ for (_e = 0, _f = sheetUpdateState; _e < _f.length; _e++) {
2757
+ entry = _f[_e];
2758
+ tokens = [entry.time, entry.event];
2759
+ tokens.push(entry.data.id);
2760
+ tokens.push(entry.data.operation);
2761
+ tokens.push(entry.data.cssRules);
2762
+ }
2763
+ reset$8();
2764
+ return [3 /*break*/, 12];
2765
+ case 4:
2766
+ for (_g = 0, _h = state$2; _g < _h.length; _g++) {
2767
+ entry = _h[_g];
2768
+ tokens = [entry.time, entry.event];
2769
+ tokens.push(entry.data.id);
2770
+ tokens.push(entry.data.operation);
2771
+ tokens.push(entry.data.keyFrames);
2772
+ tokens.push(entry.data.timing);
2773
+ tokens.push(entry.data.timeline);
2774
+ tokens.push(entry.data.targetId);
2775
+ }
2776
+ reset$7();
2777
+ return [3 /*break*/, 12];
2778
+ case 5:
2779
+ // Check if we are operating within the context of the current page
2780
+ if (state$a(timer) === 2 /* Task.Stop */) {
2781
+ return [3 /*break*/, 12];
2782
+ }
2783
+ values = updates$2();
2784
+ if (!(values.length > 0)) return [3 /*break*/, 11];
2785
+ _j = 0, values_1 = values;
2786
+ _l.label = 6;
2787
+ case 6:
2788
+ if (!(_j < values_1.length)) return [3 /*break*/, 10];
2789
+ value = values_1[_j];
2790
+ state = state$a(timer);
2791
+ if (!(state === 0 /* Task.Wait */)) return [3 /*break*/, 8];
2792
+ return [4 /*yield*/, suspend$1(timer)];
2793
+ case 7:
2794
+ state = _l.sent();
2795
+ _l.label = 8;
2796
+ case 8:
2797
+ if (state === 2 /* Task.Stop */) {
2798
+ return [3 /*break*/, 10];
2799
+ }
2800
+ data = value.data;
2801
+ active = value.metadata.active;
2802
+ suspend = value.metadata.suspend;
2803
+ privacy = value.metadata.privacy;
2804
+ mangle = shouldMangle(value);
2805
+ keys = active ? ["tag", "attributes", "value"] : ["tag"];
2806
+ for (_k = 0, keys_1 = keys; _k < keys_1.length; _k++) {
2807
+ key = keys_1[_k];
2808
+ if (data[key]) {
2809
+ switch (key) {
2810
+ case "tag":
2811
+ box = size(value);
2812
+ factor = mangle ? -1 : 1;
2813
+ tokens.push(value.id * factor);
2814
+ if (value.parent && active) {
2815
+ tokens.push(value.parent);
2816
+ if (value.previous) {
2817
+ tokens.push(value.previous);
2818
+ }
2819
+ }
2820
+ tokens.push(suspend ? "*M" /* Constant.SuspendMutationTag */ : data[key]);
2821
+ if (box && box.length === 2) {
2822
+ tokens.push("".concat("#" /* Constant.Hash */).concat(str$1(box[0]), ".").concat(str$1(box[1])));
2823
+ }
2824
+ break;
2825
+ case "attributes":
2826
+ for (attr in data[key]) {
2827
+ if (data[key][attr] !== undefined) {
2828
+ tokens.push(attribute(attr, data[key][attr], privacy));
2829
+ }
2830
+ }
2831
+ break;
2832
+ case "value":
2833
+ check$4(value.metadata.fraud, value.id, data[key]);
2834
+ tokens.push(text$1(data[key], data.tag, privacy, mangle));
2835
+ break;
2836
+ }
2837
+ }
2838
+ }
2839
+ _l.label = 9;
2840
+ case 9:
2841
+ _j++;
2842
+ return [3 /*break*/, 6];
2843
+ case 10:
2844
+ if (type === 6 /* Event.Mutation */) {
2845
+ activity(eventTime);
2846
+ }
2847
+ queue(tokenize(tokens));
2848
+ _l.label = 11;
2849
+ case 11: return [3 /*break*/, 12];
2850
+ case 12: return [2 /*return*/];
2851
+ }
2852
+ });
2853
+ });
2854
+ }
2855
+ function shouldMangle(value) {
2856
+ var privacy = value.metadata.privacy;
2857
+ return value.data.tag === "*T" /* Constant.TextTag */ && !(privacy === 0 /* Privacy.None */ || privacy === 1 /* Privacy.Sensitive */);
2858
+ }
2859
+ function size(value) {
2860
+ if (value.metadata.size !== null && value.metadata.size.length === 0) {
2861
+ var img = getNode(value.id);
2862
+ if (img) {
2863
+ return [Math.floor(img.offsetWidth * 100 /* Setting.BoxPrecision */), Math.floor(img.offsetHeight * 100 /* Setting.BoxPrecision */)];
2864
+ }
2865
+ }
2866
+ return value.metadata.size;
2867
+ }
2868
+ function str$1(input) {
2869
+ return input.toString(36);
2870
+ }
2871
+ function attribute(key, value, privacy) {
2872
+ return "".concat(key, "=").concat(text$1(value, key.indexOf("data-" /* Constant.DataAttribute */) === 0 ? "data-" /* Constant.DataAttribute */ : key, privacy));
2873
+ }
2874
+
2875
+ var state$1 = [];
2876
+ var regionMap = null; // Maps region nodes => region name
2877
+ var regions = {};
2878
+ var queue$1 = [];
2879
+ var watch = false;
2880
+ var observer$1 = null;
2881
+ function start$h() {
2882
+ reset$6();
2883
+ observer$1 = null;
2884
+ regionMap = new WeakMap();
2885
+ regions = {};
2886
+ queue$1 = [];
2887
+ watch = window["IntersectionObserver"] ? true : false;
2888
+ }
2889
+ function observe$1(node, name) {
2890
+ if (regionMap.has(node) === false) {
2891
+ regionMap.set(node, name);
2892
+ observer$1 = observer$1 === null && watch ? new IntersectionObserver(handler$1, {
2893
+ // Get notified as intersection continues to change
2894
+ // This allows us to process regions that get partially hidden during the lifetime of the page
2895
+ // See: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
2896
+ // By default, intersection observers only fire an event when even a single pixel is visible and not thereafter.
2897
+ threshold: [0, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
2898
+ }) : observer$1;
2899
+ if (observer$1 && node && node.nodeType === Node.ELEMENT_NODE) {
2900
+ observer$1.observe(node);
2901
+ }
2902
+ }
2903
+ }
2904
+ function exists(node) {
2905
+ // Check if regionMap is not null before looking up a node
2906
+ // Since, dom module stops after region module, it's possible that we may set regionMap to be null
2907
+ // and still attempt to call exists on a late coming DOM mutation (or addition), effectively causing a script error
2908
+ return regionMap && regionMap.has(node);
2909
+ }
2910
+ function track$3(id, event) {
2911
+ var node = getNode(id);
2912
+ var data = id in regions ? regions[id] : { id: id, visibility: 0 /* RegionVisibility.Rendered */, interaction: 16 /* InteractionState.None */, name: regionMap.get(node) };
2913
+ // Determine the interaction state based on incoming event
2914
+ var interaction = 16 /* InteractionState.None */;
2915
+ switch (event) {
2916
+ case 9 /* Event.Click */:
2917
+ interaction = 20 /* InteractionState.Clicked */;
2918
+ break;
2919
+ case 27 /* Event.Input */:
2920
+ interaction = 30 /* InteractionState.Input */;
2921
+ break;
2922
+ }
2923
+ // Process updates to this region, if applicable
2924
+ process$1(node, data, interaction, data.visibility);
2925
+ }
2926
+ function compute$6() {
2927
+ // Process any regions where we couldn't resolve an "id" for at the time of last intersection observer event
2928
+ // This could happen in cases where elements are not yet processed by Clarity's virtual DOM but browser reports a change, regardless.
2929
+ // For those cases we add them to the queue and re-process them below
2930
+ var q = [];
2931
+ for (var _i = 0, queue_1 = queue$1; _i < queue_1.length; _i++) {
2932
+ var r = queue_1[_i];
2933
+ var id = getId(r.node);
2934
+ if (id) {
2935
+ r.state.data.id = id;
2936
+ regions[id] = r.state.data;
2937
+ state$1.push(r.state);
2938
+ }
2939
+ else {
2940
+ q.push(r);
2941
+ }
2942
+ }
2943
+ queue$1 = q;
2944
+ // Schedule encode only when we have at least one valid data entry
2945
+ if (state$1.length > 0) {
2946
+ encode$4(7 /* Event.Region */);
2947
+ }
2948
+ }
2949
+ compute$6.dn = 24 /* FunctionNames.RegionCompute */;
2950
+ function handler$1(entries) {
2951
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
2952
+ var entry = entries_1[_i];
2953
+ var target = entry.target;
2954
+ var rect = entry.boundingClientRect;
2955
+ var overlap = entry.intersectionRect;
2956
+ var viewport = entry.rootBounds;
2957
+ // Only capture regions that have non-zero width or height to avoid tracking and sending regions
2958
+ // that cannot ever be seen by the user. In some cases, websites will have a multiple copy of the same region
2959
+ // like search box - one for desktop, and another for mobile. In those cases, CSS media queries determine which one should be visible.
2960
+ // Also, if these regions ever become non-zero width or height (through AJAX, user action or orientation change) - we will automatically start monitoring them from that point onwards
2961
+ if (regionMap.has(target) && rect.width + rect.height > 0 && viewport.width > 0 && viewport.height > 0) {
2962
+ var id = target ? getId(target) : null;
2963
+ var data = id in regions ? regions[id] : { id: id, name: regionMap.get(target), interaction: 16 /* InteractionState.None */, visibility: 0 /* RegionVisibility.Rendered */ };
2964
+ // For regions that have relatively smaller area, we look at intersection ratio and see the overlap relative to element's area
2965
+ // However, for larger regions, area of regions could be bigger than viewport and therefore comparison is relative to visible area
2966
+ var viewportRatio = overlap ? (overlap.width * overlap.height * 1.0) / (viewport.width * viewport.height) : 0;
2967
+ var visible = viewportRatio > 0.05 /* Setting.ViewportIntersectionRatio */ || entry.intersectionRatio > 0.8 /* Setting.IntersectionRatio */;
2968
+ // If an element is either visible or was visible and has been scrolled to the end
2969
+ // i.e. Scrolled to end is determined by if the starting position of the element + the window height is more than the total element height.
2970
+ // starting position is relative to the viewport - so Intersection observer returns a negative value for rect.top to indicate that the element top is above the viewport
2971
+ var scrolledToEnd = (visible || data.visibility == 10 /* RegionVisibility.Visible */) && Math.abs(rect.top) + viewport.height > rect.height;
2972
+ // Process updates to this region, if applicable
2973
+ process$1(target, data, data.interaction, (scrolledToEnd ?
2974
+ 13 /* RegionVisibility.ScrolledToEnd */ :
2975
+ (visible ? 10 /* RegionVisibility.Visible */ : 0 /* RegionVisibility.Rendered */)));
2976
+ // Stop observing this element now that we have already received scrolled signal
2977
+ if (data.visibility >= 13 /* RegionVisibility.ScrolledToEnd */ && observer$1) {
2978
+ observer$1.unobserve(target);
2979
+ }
2980
+ }
2981
+ }
2982
+ if (state$1.length > 0) {
2983
+ encode$4(7 /* Event.Region */);
2984
+ }
2985
+ }
2986
+ function process$1(n, d, s, v) {
2987
+ // Check if received a state that supersedes existing state
2988
+ var updated = s > d.interaction || v > d.visibility;
2989
+ d.interaction = s > d.interaction ? s : d.interaction;
2990
+ d.visibility = v > d.visibility ? v : d.visibility;
2991
+ // If the corresponding node is already discovered, update the internal state
2992
+ // Otherwise, track it in a queue to reprocess later.
2993
+ if (d.id) {
2994
+ if ((d.id in regions && updated) || !(d.id in regions)) {
2995
+ regions[d.id] = d;
2996
+ state$1.push(clone$1(d));
2997
+ }
2998
+ }
2999
+ else {
3000
+ // Get the time before adding to queue to ensure accurate event time
3001
+ queue$1.push({ node: n, state: clone$1(d) });
3002
+ }
3003
+ }
3004
+ function clone$1(r) {
3005
+ return { time: time$1(), data: { id: r.id, interaction: r.interaction, visibility: r.visibility, name: r.name } };
3006
+ }
3007
+ function reset$6() {
3008
+ state$1 = [];
3009
+ }
3010
+
3011
+ function target(evt) {
3012
+ var path = evt.composed && evt.composedPath ? evt.composedPath() : null;
3013
+ var node = (path && path.length > 0 ? path[0] : evt.target);
3014
+ active$2(); // Mark active periods of time so mutations can continue uninterrupted
3015
+ return node && node.nodeType === Node.DOCUMENT_NODE ? node.documentElement : node;
3016
+ }
3017
+ function metadata$2(node, event, text) {
3018
+ if (text === void 0) { text = null; }
3019
+ // If the node is null, we return a reserved value for id: 0. Valid assignment of id begins from 1+.
3020
+ var output = { id: 0, hash: null, privacy: 2 /* Privacy.Text */, node: node };
3021
+ if (node) {
3022
+ var value = get$2(node);
3023
+ if (value !== null) {
3024
+ var metadata_1 = value.metadata;
3025
+ output.id = value.id;
3026
+ output.hash = value.hash;
3027
+ output.privacy = metadata_1.privacy;
3028
+ if (value.region) {
3029
+ track$3(value.region, event);
3030
+ }
3031
+ if (metadata_1.fraud) {
3032
+ check$4(metadata_1.fraud, value.id, text || value.data.value);
3033
+ }
3034
+ }
3035
+ }
3036
+ return output;
3037
+ }
3038
+
3039
+ function encode$3 (type, ts) {
3040
+ if (ts === void 0) { ts = null; }
3041
+ return __awaiter(this, void 0, void 0, function () {
3042
+ var t, tokens, _i, _a, entry, pTarget, _b, _c, entry, cTarget, cHash, _d, _e, entry, target, r, u, _f, _g, entry, iTarget, s, startTarget, endTarget, _h, _j, entry, sTarget, top_1, bottom, sTopHash, sBottomHash, _k, _l, entry, target, _m, _o, entry, target, _p, _q, entry, v;
3043
+ return __generator(this, function (_r) {
3044
+ t = ts || time$1();
3045
+ tokens = [t, type];
3046
+ switch (type) {
3047
+ case 13 /* Event.MouseDown */:
3048
+ case 14 /* Event.MouseUp */:
3049
+ case 12 /* Event.MouseMove */:
3050
+ case 15 /* Event.MouseWheel */:
3051
+ case 16 /* Event.DoubleClick */:
3052
+ case 17 /* Event.TouchStart */:
3053
+ case 18 /* Event.TouchEnd */:
3054
+ case 19 /* Event.TouchMove */:
3055
+ case 20 /* Event.TouchCancel */:
3056
+ for (_i = 0, _a = state$5; _i < _a.length; _i++) {
3057
+ entry = _a[_i];
3058
+ pTarget = metadata$2(entry.data.target, entry.event);
3059
+ if (pTarget.id > 0) {
3060
+ tokens = [entry.time, entry.event];
3061
+ tokens.push(pTarget.id);
3062
+ tokens.push(entry.data.x);
3063
+ tokens.push(entry.data.y);
3064
+ if (entry.data.id !== undefined) {
3065
+ tokens.push(entry.data.id);
3066
+ if (entry.data.isPrimary !== undefined) {
3067
+ tokens.push(entry.data.isPrimary.toString());
3068
+ }
3069
+ }
3070
+ track$8(entry.event, entry.data.x, entry.data.y);
3071
+ }
3072
+ }
3073
+ reset$f();
3074
+ break;
3075
+ case 9 /* Event.Click */:
3076
+ for (_b = 0, _c = state$8; _b < _c.length; _b++) {
3077
+ entry = _c[_b];
3078
+ cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
3079
+ tokens = [entry.time, entry.event];
3080
+ cHash = cTarget.hash ? cTarget.hash.join("." /* Constant.Dot */) : "" /* Constant.Empty */;
3081
+ tokens.push(cTarget.id);
3082
+ tokens.push(entry.data.x);
3083
+ tokens.push(entry.data.y);
3084
+ tokens.push(entry.data.eX);
3085
+ tokens.push(entry.data.eY);
3086
+ tokens.push(entry.data.button);
3087
+ tokens.push(entry.data.reaction);
3088
+ tokens.push(entry.data.context);
3089
+ tokens.push(text$1(entry.data.text, "click", cTarget.privacy));
3090
+ tokens.push(url$1(entry.data.link));
3091
+ tokens.push(cHash);
3092
+ tokens.push(entry.data.trust);
3093
+ track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
3094
+ }
3095
+ reset$i();
3096
+ break;
3097
+ case 38 /* Event.Clipboard */:
3098
+ for (_d = 0, _e = state$7; _d < _e.length; _d++) {
3099
+ entry = _e[_d];
3100
+ tokens = [entry.time, entry.event];
3101
+ target = metadata$2(entry.data.target, entry.event);
3102
+ if (target.id > 0) {
3103
+ tokens.push(target.id);
3104
+ tokens.push(entry.data.action);
3105
+ }
3106
+ }
3107
+ reset$h();
3108
+ break;
3109
+ case 11 /* Event.Resize */:
3110
+ r = data$b;
3111
+ tokens.push(r.width);
3112
+ tokens.push(r.height);
3113
+ track$8(type, r.width, r.height);
3114
+ reset$e();
3115
+ break;
3116
+ case 26 /* Event.Unload */:
3117
+ u = data$9;
3118
+ tokens.push(u.name);
3119
+ reset$a();
3120
+ break;
3121
+ case 27 /* Event.Input */:
3122
+ for (_f = 0, _g = state$6; _f < _g.length; _f++) {
3123
+ entry = _g[_f];
3124
+ iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
3125
+ tokens = [entry.time, entry.event];
3126
+ tokens.push(iTarget.id);
3127
+ tokens.push(text$1(entry.data.value, "input", iTarget.privacy, false, entry.data.type));
3128
+ }
3129
+ reset$g();
3130
+ break;
3131
+ case 21 /* Event.Selection */:
3132
+ s = data$a;
3133
+ if (s) {
3134
+ startTarget = metadata$2(s.start, type);
3135
+ endTarget = metadata$2(s.end, type);
3136
+ tokens.push(startTarget.id);
3137
+ tokens.push(s.startOffset);
3138
+ tokens.push(endTarget.id);
3139
+ tokens.push(s.endOffset);
3140
+ reset$c();
3141
+ }
3142
+ break;
3143
+ case 10 /* Event.Scroll */:
3144
+ for (_h = 0, _j = state$4; _h < _j.length; _h++) {
3145
+ entry = _j[_h];
3146
+ sTarget = metadata$2(entry.data.target, entry.event);
3147
+ top_1 = metadata$2(entry.data.top, entry.event);
3148
+ bottom = metadata$2(entry.data.bottom, entry.event);
3149
+ sTopHash = (top_1 === null || top_1 === void 0 ? void 0 : top_1.hash) ? top_1.hash.join("." /* Constant.Dot */) : "" /* Constant.Empty */;
3150
+ sBottomHash = (bottom === null || bottom === void 0 ? void 0 : bottom.hash) ? bottom.hash.join("." /* Constant.Dot */) : "" /* Constant.Empty */;
3151
+ if (sTarget.id > 0) {
3152
+ tokens = [entry.time, entry.event];
3153
+ tokens.push(sTarget.id);
3154
+ tokens.push(entry.data.x);
3155
+ tokens.push(entry.data.y);
3156
+ tokens.push(sTopHash);
3157
+ tokens.push(sBottomHash);
3158
+ track$8(entry.event, entry.data.x, entry.data.y, entry.time);
3159
+ }
3160
+ }
3161
+ reset$d();
3162
+ break;
3163
+ case 42 /* Event.Change */:
3164
+ for (_k = 0, _l = state$9; _k < _l.length; _k++) {
3165
+ entry = _l[_k];
3166
+ tokens = [entry.time, entry.event];
3167
+ target = metadata$2(entry.data.target, entry.event);
3168
+ if (target.id > 0) {
3169
+ tokens = [entry.time, entry.event];
3170
+ tokens.push(target.id);
3171
+ tokens.push(entry.data.type);
3172
+ tokens.push(text$1(entry.data.value, "change", target.privacy));
3173
+ tokens.push(text$1(entry.data.checksum, "checksum", target.privacy));
3174
+ }
3175
+ }
3176
+ reset$j();
3177
+ break;
3178
+ case 39 /* Event.Submit */:
3179
+ for (_m = 0, _o = state$3; _m < _o.length; _m++) {
3180
+ entry = _o[_m];
3181
+ tokens = [entry.time, entry.event];
3182
+ target = metadata$2(entry.data.target, entry.event);
3183
+ if (target.id > 0) {
3184
+ tokens.push(target.id);
3185
+ }
3186
+ }
3187
+ reset$b();
3188
+ break;
3189
+ case 22 /* Event.Timeline */:
3190
+ for (_p = 0, _q = updates$1; _p < _q.length; _p++) {
3191
+ entry = _q[_p];
3192
+ tokens = [entry.time, entry.event];
3193
+ tokens.push(entry.data.type);
3194
+ tokens.push(entry.data.hash);
3195
+ tokens.push(entry.data.x);
3196
+ tokens.push(entry.data.y);
3197
+ tokens.push(entry.data.reaction);
3198
+ tokens.push(entry.data.context);
3199
+ }
3200
+ reset$5();
3201
+ break;
3202
+ case 28 /* Event.Visibility */:
3203
+ v = data$8;
3204
+ tokens.push(v.visible);
3205
+ visibility(t, v.visible);
3206
+ reset$9();
3207
+ break;
3208
+ }
3209
+ return [2 /*return*/];
3210
+ });
3211
+ });
3212
+ }
3213
+
3214
+ var state$b = [];
3215
+ var updates$1 = [];
3216
+ function start$g() {
3217
+ state$b = [];
3218
+ reset$5();
3219
+ }
3220
+ function reset$5() {
3221
+ updates$1 = [];
3222
+ }
3223
+ function track$2(time, event, hash, x, y, reaction, context) {
3224
+ if (reaction === void 0) { reaction = 1 /* BooleanFlag.True */; }
3225
+ if (context === void 0) { context = 0 /* BrowsingContext.Self */; }
3226
+ state$b.push({
3227
+ time: time,
3228
+ event: 22 /* Event.Timeline */,
3229
+ data: {
3230
+ type: event,
3231
+ hash: hash,
3232
+ x: x,
3233
+ y: y,
3234
+ reaction: reaction,
3235
+ context: context
3236
+ }
3237
+ });
3238
+ // Since timeline only keeps the data for configured time, we still want to continue tracking these values
3239
+ // as part of the baseline. For instance, in a scenario where last scroll happened 5s ago.
3240
+ // We would still need to capture the last scroll position as part of the baseline event, even when timeline will be empty.
3241
+ track$8(event, x, y);
3242
+ }
3243
+ function queue(tokens, transmit) {
3244
+ }
3245
+
3246
+ var history$3 = {};
3247
+ var data$7;
3248
+ function start$e() {
3249
+ bind(window, "error", handler);
3250
+ history$3 = {};
3251
+ }
3252
+ function handler(error) {
3253
+ var e = error["error"] || error;
3254
+ // While rare, it's possible for code to fail repeatedly during the lifetime of the same page
3255
+ // In those cases, we only want to log the failure first few times and not spam logs with redundant information.
3256
+ if (!(e.message in history$3)) {
3257
+ history$3[e.message] = 0;
3258
+ }
3259
+ if (history$3[e.message]++ >= 5 /* Setting.ScriptErrorLimit */) {
3260
+ return true;
3261
+ }
3262
+ // Send back information only if the handled error has valid information
3263
+ if (e && e.message) {
3264
+ data$7 = {
3265
+ message: e.message,
3266
+ line: error["lineno"],
3267
+ column: error["colno"],
3268
+ stack: e.stack,
3269
+ source: error["filename"]
3270
+ };
3271
+ encode$2(31 /* Event.ScriptError */);
3272
+ }
3273
+ return true;
3274
+ }
3275
+ handler.dn = 4 /* FunctionNames.ScriptHandler */;
3276
+
3277
+ function encode$2 (type) {
3278
+ return __awaiter(this, void 0, void 0, function () {
3279
+ var tokens;
3280
+ return __generator(this, function (_a) {
3281
+ tokens = [time$1(), type];
3282
+ switch (type) {
3283
+ case 31 /* Event.ScriptError */:
3284
+ tokens.push(data$7.message);
3285
+ tokens.push(data$7.line);
3286
+ tokens.push(data$7.column);
3287
+ tokens.push(data$7.stack);
3288
+ tokens.push(url$1(data$7.source));
3289
+ break;
3290
+ case 33 /* Event.Log */:
3291
+ if (data$6) {
3292
+ tokens.push(data$6.code);
3293
+ tokens.push(data$6.name);
3294
+ tokens.push(data$6.message);
3295
+ tokens.push(data$6.stack);
3296
+ tokens.push(data$6.severity);
3297
+ }
3298
+ break;
3299
+ case 41 /* Event.Fraud */:
3300
+ if (data$d) {
3301
+ tokens.push(data$d.id);
3302
+ tokens.push(data$d.target);
3303
+ tokens.push(data$d.checksum);
3304
+ }
3305
+ break;
3306
+ }
3307
+ return [2 /*return*/];
3308
+ });
3309
+ });
3310
+ }
3311
+
3312
+ var history$2 = {};
3313
+ var data$6;
3314
+ function start$d() {
3315
+ history$2 = {};
3316
+ }
3317
+ function log$1(code, severity, name, message, stack) {
3318
+ if (name === void 0) { name = null; }
3319
+ if (message === void 0) { message = null; }
3320
+ if (stack === void 0) { stack = null; }
3321
+ var key = name ? "".concat(name, "|").concat(message) : "";
3322
+ // While rare, it's possible for code to fail repeatedly during the lifetime of the same page
3323
+ // In those cases, we only want to log the failure once and not spam logs with redundant information.
3324
+ if (code in history$2 && history$2[code].indexOf(key) >= 0) {
3325
+ return;
3326
+ }
3327
+ data$6 = { code: code, name: name, message: message, stack: stack, severity: severity };
3328
+ // Maintain history of errors in memory to avoid sending redundant information
3329
+ if (code in history$2) {
3330
+ history$2[code].push(key);
3331
+ }
3332
+ else {
3333
+ history$2[code] = [key];
3334
+ }
3335
+ encode$2(33 /* Event.Log */);
3336
+ }
3337
+
3338
+ var data$4;
3339
+ function trigger(reason) {
3340
+ data$4.check = reason;
3341
+ // limit the dimensions we collect, but we don't need to stop Clarity entirely if we hit the limit
3342
+ if (reason !== 5 /* Check.Collection */) {
3343
+ clear();
3344
+ }
3345
+ }
3346
+
3347
+ var data$3 = null;
3348
+ var updates = null;
3349
+ var limited = false;
3350
+ function log(dimension, value) {
3351
+ // Check valid value before moving ahead
3352
+ if (value) {
3353
+ // Ensure received value is casted into a string if it wasn't a string to begin with
3354
+ value = "".concat(value);
3355
+ if (!(dimension in data$3)) {
3356
+ data$3[dimension] = [];
3357
+ }
3358
+ if (data$3[dimension].indexOf(value) < 0) {
3359
+ // Limit check to ensure we have a cap on number of dimensions we can collect
3360
+ if (data$3[dimension].length > 128 /* Setting.CollectionLimit */) {
3361
+ if (!limited) {
3362
+ limited = true;
3363
+ trigger(5 /* Check.Collection */);
3364
+ }
3365
+ return;
3366
+ }
3367
+ data$3[dimension].push(value);
3368
+ // If this is a new value, track it as part of updates object
3369
+ // This allows us to only send back new values in subsequent payloads
3370
+ if (!(dimension in updates)) {
3371
+ updates[dimension] = [];
3372
+ }
3373
+ updates[dimension].push(value);
3374
+ }
3375
+ }
3376
+ }
3377
+
3378
+ var data$2 = null;
3379
+ var rootDomain = null;
3380
+ function id() {
3381
+ return data$2 ? [data$2.userId, data$2.sessionId, data$2.pageNum].join("." /* Constant.Dot */) : "" /* Constant.Empty */;
3382
+ }
3383
+ function clear() {
3384
+ // Clear any stored information in the cookie that tracks session information so we can restart fresh the next time
3385
+ setCookie("_clsk" /* Constant.SessionKey */, "" /* Constant.Empty */, 0);
3386
+ }
3387
+ function supported(target, api) {
3388
+ try {
3389
+ return !!target[api];
3390
+ }
3391
+ catch (_a) {
3392
+ return false;
3393
+ }
3394
+ }
3395
+ function shortid() {
3396
+ var id = Math.floor(Math.random() * Math.pow(2, 32));
3397
+ if (window && window.crypto && window.crypto.getRandomValues && Uint32Array) {
3398
+ id = window.crypto.getRandomValues(new Uint32Array(1))[0];
3399
+ }
3400
+ return id.toString(36);
3401
+ }
3402
+ function getCookie(key, limit) {
3403
+ var _a;
3404
+ if (limit === void 0) { limit = false; }
3405
+ if (supported(document, "cookie" /* Constant.Cookie */)) {
3406
+ var cookies = document.cookie.split(";" /* Constant.Semicolon */);
3407
+ if (cookies) {
3408
+ for (var i = 0; i < cookies.length; i++) {
3409
+ var pair = cookies[i].split("=" /* Constant.Equals */);
3410
+ if (pair.length > 1 && pair[0] && pair[0].trim() === key) {
3411
+ // Some browsers automatically url encode cookie values if they are not url encoded.
3412
+ // We therefore encode and decode cookie values ourselves.
3413
+ // For backwards compatability we need to consider 3 cases:
3414
+ // * Cookie was previously not encoded by Clarity and browser did not encode it
3415
+ // * Cookie was previously not encoded by Clarity and browser encoded it once or more
3416
+ // * Cookie was previously encoded by Clarity and browser did not encode it
3417
+ var _b = decodeCookieValue(pair[1]), isEncoded = _b[0], decodedValue = _b[1];
3418
+ while (isEncoded) {
3419
+ _a = decodeCookieValue(decodedValue), isEncoded = _a[0], decodedValue = _a[1];
3420
+ }
3421
+ // If we are limiting cookies, check if the cookie value is limited
3422
+ if (limit) {
3423
+ return decodedValue.endsWith("".concat("~" /* Constant.Tilde */, "1"))
3424
+ ? decodedValue.substring(0, decodedValue.length - 2)
3425
+ : null;
3426
+ }
3427
+ return decodedValue;
3428
+ }
3429
+ }
3430
+ }
3431
+ }
3432
+ return null;
3433
+ }
3434
+ function decodeCookieValue(value) {
3435
+ try {
3436
+ var decodedValue = decodeURIComponent(value);
3437
+ return [decodedValue != value, decodedValue];
3438
+ }
3439
+ catch (_a) {
3440
+ }
3441
+ return [false, value];
3442
+ }
3443
+ function encodeCookieValue(value) {
3444
+ return encodeURIComponent(value);
3445
+ }
3446
+ function setCookie(key, value, time) {
3447
+ // only write cookies if we are currently in a cookie writing mode (and they are supported)
3448
+ // OR if we are trying to write an empty cookie (i.e. clear the cookie value out)
3449
+ if (((navigator && navigator.cookieEnabled) || supported(document, "cookie" /* Constant.Cookie */))) {
3450
+ // Some browsers automatically url encode cookie values if they are not url encoded.
3451
+ // We therefore encode and decode cookie values ourselves.
3452
+ var encodedValue = encodeCookieValue(value);
3453
+ var expiry = new Date();
3454
+ expiry.setDate(expiry.getDate() + time);
3455
+ var expires = expiry ? "expires=" /* Constant.Expires */ + expiry.toUTCString() : "" /* Constant.Empty */;
3456
+ var cookie = "".concat(key, "=").concat(encodedValue).concat(";" /* Constant.Semicolon */).concat(expires).concat(";path=/" /* Constant.Path */);
3457
+ try {
3458
+ // Attempt to get the root domain only once and fall back to writing cookie on the current domain.
3459
+ if (rootDomain === null) {
3460
+ var hostname = location.hostname ? location.hostname.split("." /* Constant.Dot */) : [];
3461
+ // Walk backwards on a domain and attempt to set a cookie, until successful
3462
+ for (var i = hostname.length - 1; i >= 0; i--) {
3463
+ rootDomain = ".".concat(hostname[i]).concat(rootDomain ? rootDomain : "" /* Constant.Empty */);
3464
+ // We do not wish to attempt writing a cookie on the absolute last part of the domain, e.g. .com or .net.
3465
+ // So we start attempting after second-last part, e.g. .domain.com (PASS) or .co.uk (FAIL)
3466
+ if (i < hostname.length - 1) {
3467
+ // Write the cookie on the current computed top level domain
3468
+ document.cookie = "".concat(cookie).concat(";" /* Constant.Semicolon */).concat("domain=" /* Constant.Domain */).concat(rootDomain);
3469
+ // Once written, check if the cookie exists and its value matches exactly with what we intended to set
3470
+ // Checking for exact value match helps us eliminate a corner case where the cookie may already be present with a different value
3471
+ // If the check is successful, no more action is required and we can return from the function since rootDomain cookie is already set
3472
+ // If the check fails, continue with the for loop until we can successfully set and verify the cookie
3473
+ if (getCookie(key) === value) {
3474
+ return;
3475
+ }
3476
+ }
3477
+ }
3478
+ // Finally, if we were not successful and gone through all the options, play it safe and reset rootDomain to be empty
3479
+ // This forces our code to fall back to always writing cookie to the current domain
3480
+ rootDomain = "" /* Constant.Empty */;
3481
+ }
3482
+ }
3483
+ catch (_a) {
3484
+ rootDomain = "" /* Constant.Empty */;
3485
+ }
3486
+ document.cookie = rootDomain ? "".concat(cookie).concat(";" /* Constant.Semicolon */).concat("domain=" /* Constant.Domain */).concat(rootDomain) : cookie;
3487
+ }
3488
+ }
3489
+ function report(e) {
3490
+ return e;
3491
+ }
3492
+
3493
+ // tslint:disable-next-line: ban-types
3494
+ function measure (method) {
3495
+ return function () {
3496
+ var start = performance.now();
3497
+ try {
3498
+ method.apply(this, arguments);
3499
+ }
3500
+ catch (ex) {
3501
+ throw report(ex);
3502
+ }
3503
+ var duration = performance.now() - start;
3504
+ sum(4 /* Metric.TotalCost */, duration);
3505
+ if (duration > config$2.longTask) {
3506
+ count$1(7 /* Metric.LongTaskCount */);
3507
+ max(6 /* Metric.ThreadBlockedTime */, duration);
3508
+ log$1(9 /* Code.FunctionExecutionTime */, 0 /* Severity.Info */, "".concat(method.dn || method.name, "-").concat(duration));
3509
+ }
3510
+ };
3511
+ }
3512
+
3513
+ var bindings = [];
3514
+ function bind(target, event, listener, capture) {
3515
+ if (capture === void 0) { capture = false; }
3516
+ listener = measure(listener);
3517
+ // Wrapping following lines inside try / catch to cover edge cases where we might try to access an inaccessible element.
3518
+ // E.g. Iframe may start off as same-origin but later turn into cross-origin, and the following lines will throw an exception.
3519
+ try {
3520
+ target[api("addEventListener" /* Constant.AddEventListener */)](event, listener, capture);
3521
+ bindings.push({ event: event, target: target, listener: listener, capture: capture });
3522
+ }
3523
+ catch ( /* do nothing */_a) { /* do nothing */ }
3524
+ }
3525
+
3526
+ var status = false;
3527
+ function active() {
3528
+ return status;
3529
+ }
3530
+
3531
+ function start$5() {
3532
+ start$A();
3533
+ start$e();
3534
+ start$d();
3535
+ }
3536
+ start$5.dn = 3 /* FunctionNames.DiagnosticStart */;
3537
+
3538
+ function start$4() {
3539
+ schedule$1(discover, 1 /* Priority.High */).then(function () {
3540
+ measure(compute$9)();
3541
+ measure(compute$6)();
3542
+ measure(compute$8)();
3543
+ });
3544
+ }
3545
+ function discover() {
3546
+ return __awaiter(this, void 0, void 0, function () {
3547
+ var ts, timer;
3548
+ return __generator(this, function (_a) {
3549
+ switch (_a.label) {
3550
+ case 0:
3551
+ ts = time$1();
3552
+ timer = { id: id(), cost: 3 /* Metric.LayoutCost */ };
3553
+ start$y(timer);
3554
+ return [4 /*yield*/, traverse(document, timer, 0 /* Source.Discover */, ts)];
3555
+ case 1:
3556
+ _a.sent();
3557
+ checkDocumentStyles(document, ts);
3558
+ return [4 /*yield*/, encode$4(5 /* Event.Discover */, timer, ts)];
3559
+ case 2:
3560
+ _a.sent();
3561
+ stop$w(timer);
3562
+ return [2 /*return*/];
3563
+ }
3564
+ });
3565
+ });
3566
+ }
3567
+
3568
+ function start$3() {
3569
+ // The order below is important
3570
+ // and is determined by interdependencies of modules
3571
+ start$x();
3572
+ start$h();
3573
+ start$z();
3574
+ {
3575
+ start$k();
3576
+ }
3577
+ start$4();
3578
+ start$j();
3579
+ start$i();
3580
+ }
3581
+ start$3.dn = 20 /* FunctionNames.LayoutStart */;
3582
+
3583
+ function encode (type) {
3584
+ return __awaiter(this, void 0, void 0, function () {
3585
+ var t, tokens;
3586
+ return __generator(this, function (_a) {
3587
+ t = time$1();
3588
+ tokens = [t, type];
3589
+ switch (type) {
3590
+ case 29 /* Event.Navigation */:
3591
+ tokens.push(data.fetchStart);
3592
+ tokens.push(data.connectStart);
3593
+ tokens.push(data.connectEnd);
3594
+ tokens.push(data.requestStart);
3595
+ tokens.push(data.responseStart);
3596
+ tokens.push(data.responseEnd);
3597
+ tokens.push(data.domInteractive);
3598
+ tokens.push(data.domComplete);
3599
+ tokens.push(data.loadEventStart);
3600
+ tokens.push(data.loadEventEnd);
3601
+ tokens.push(data.redirectCount);
3602
+ tokens.push(data.size);
3603
+ tokens.push(data.type);
3604
+ tokens.push(data.protocol);
3605
+ tokens.push(data.encodedSize);
3606
+ tokens.push(data.decodedSize);
3607
+ reset();
3608
+ break;
3609
+ }
3610
+ return [2 /*return*/];
3611
+ });
3612
+ });
3613
+ }
3614
+
3615
+ var data = null;
3616
+ function reset() {
3617
+ data = null;
3618
+ }
3619
+ function compute(entry) {
3620
+ data = {
3621
+ fetchStart: Math.round(entry.fetchStart),
3622
+ connectStart: Math.round(entry.connectStart),
3623
+ connectEnd: Math.round(entry.connectEnd),
3624
+ requestStart: Math.round(entry.requestStart),
3625
+ responseStart: Math.round(entry.responseStart),
3626
+ responseEnd: Math.round(entry.responseEnd),
3627
+ domInteractive: Math.round(entry.domInteractive),
3628
+ domComplete: Math.round(entry.domComplete),
3629
+ loadEventStart: Math.round(entry.loadEventStart),
3630
+ loadEventEnd: Math.round(entry.loadEventEnd),
3631
+ redirectCount: Math.round(entry.redirectCount),
3632
+ size: entry.transferSize ? entry.transferSize : 0,
3633
+ type: entry.type,
3634
+ protocol: entry.nextHopProtocol,
3635
+ encodedSize: entry.encodedBodySize ? entry.encodedBodySize : 0,
3636
+ decodedSize: entry.decodedBodySize ? entry.decodedBodySize : 0
3637
+ };
3638
+ encode(29 /* Event.Navigation */);
3639
+ }
3640
+
3641
+ // Estimate variables to keep track of interactions
3642
+ var interactionCountEstimate = 0;
3643
+ var minKnownInteractionId = Infinity;
3644
+ var maxKnownInteractionId = 0;
3645
+ var prevInteractionCount = 0; // Used to track interaction count between pages
3646
+ var MAX_INTERACTIONS_TO_CONSIDER = 10; // Maximum number of interactions we consider for INP
3647
+ var DEFAULT_DURATION_THRESHOLD = 40; // Threshold to ignore very short interactions
3648
+ // List to store the longest interaction events
3649
+ var longestInteractionList = [];
3650
+ // Map to track interactions by their ID, ensuring we handle duplicates
3651
+ var longestInteractionMap = new Map();
3652
+ /**
3653
+ * Update the approx number of interactions estimate count if the interactionCount is not supported.
3654
+ * The difference between `maxKnownInteractionId` and `minKnownInteractionId` gives us a rough range of how many interactions have occurred.
3655
+ * Dividing by 7 helps approximate the interaction count more accurately, since interaction IDs are spread out across a large range.
3656
+ */
3657
+ var countInteractions = function (entry) {
3658
+ if ('interactionCount' in performance) {
3659
+ interactionCountEstimate = performance.interactionCount;
3660
+ return;
3661
+ }
3662
+ if (entry.interactionId) {
3663
+ minKnownInteractionId = Math.min(minKnownInteractionId, entry.interactionId);
3664
+ maxKnownInteractionId = Math.max(maxKnownInteractionId, entry.interactionId);
3665
+ interactionCountEstimate = maxKnownInteractionId
3666
+ ? (maxKnownInteractionId - minKnownInteractionId) / 7 + 1
3667
+ : 0;
3668
+ }
3669
+ };
3670
+ var getInteractionCount = function () {
3671
+ return interactionCountEstimate || 0;
3672
+ };
3673
+ var getInteractionCountForNavigation = function () {
3674
+ return getInteractionCount() - prevInteractionCount;
3675
+ };
3676
+ /**
3677
+ * Estimates the 98th percentile (P98) of the longest interactions by selecting
3678
+ * the candidate interaction based on the current interaction count.
3679
+ * Dividing by 50 is a heuristic to estimate the 98th percentile (P98) interaction.
3680
+ * This assumes one out of every 50 interactions represents the P98 interaction.
3681
+ * By dividing the total interaction count by 50, we get an index to approximate
3682
+ * the slowest 2% of interactions, helping identify a likely P98 candidate.
3683
+ */
3684
+ var estimateP98LongestInteraction = function () {
3685
+ if (!longestInteractionList.length) {
3686
+ return -1;
3687
+ }
3688
+ var candidateInteractionIndex = Math.min(longestInteractionList.length - 1, Math.floor(getInteractionCountForNavigation() / 50));
3689
+ return longestInteractionList[candidateInteractionIndex].latency;
3690
+ };
3691
+ /**
3692
+ * Processes a PerformanceEventTiming entry by updating the longest interaction list.
3693
+ */
3694
+ var processInteractionEntry = function (entry) {
3695
+ // Ignore entries with 0 interactionId or very short durations
3696
+ if (!entry.interactionId || entry.duration < DEFAULT_DURATION_THRESHOLD) {
3697
+ return;
3698
+ }
3699
+ countInteractions(entry);
3700
+ var minLongestInteraction = longestInteractionList[longestInteractionList.length - 1];
3701
+ var existingInteraction = longestInteractionMap.get(entry.interactionId);
3702
+ // Either update existing, add new, or replace shortest interaction if necessary
3703
+ if (existingInteraction ||
3704
+ longestInteractionList.length < MAX_INTERACTIONS_TO_CONSIDER ||
3705
+ entry.duration > (minLongestInteraction === null || minLongestInteraction === void 0 ? void 0 : minLongestInteraction.latency)) {
3706
+ if (!existingInteraction) {
3707
+ var interaction = {
3708
+ id: entry.interactionId,
3709
+ latency: entry.duration,
3710
+ };
3711
+ longestInteractionMap.set(interaction.id, interaction);
3712
+ longestInteractionList.push(interaction);
3713
+ }
3714
+ else if (entry.duration > existingInteraction.latency) {
3715
+ existingInteraction.latency = entry.duration;
3716
+ }
3717
+ longestInteractionList.sort(function (a, b) { return b.latency - a.latency; });
3718
+ // Trim the list to the maximum number of interactions to consider
3719
+ if (longestInteractionList.length > MAX_INTERACTIONS_TO_CONSIDER) {
3720
+ longestInteractionList
3721
+ .splice(MAX_INTERACTIONS_TO_CONSIDER)
3722
+ .forEach(function (i) { return longestInteractionMap.delete(i.id); });
3723
+ }
3724
+ }
3725
+ };
3726
+
3727
+ var observer;
3728
+ var types = ["navigation" /* Constant.Navigation */, "resource" /* Constant.Resource */, "longtask" /* Constant.LongTask */, "first-input" /* Constant.FID */, "layout-shift" /* Constant.CLS */, "largest-contentful-paint" /* Constant.LCP */, "event" /* Constant.PerformanceEventTiming */];
3729
+ function start$2() {
3730
+ // Capture connection properties, if available
3731
+ if (navigator && "connection" in navigator) {
3732
+ log(27 /* Dimension.ConnectionType */, navigator["connection"]["effectiveType"]);
3733
+ }
3734
+ // Check the browser support performance observer as a pre-requisite for any performance measurement
3735
+ if (window["PerformanceObserver"] && PerformanceObserver.supportedEntryTypes) {
3736
+ // Start monitoring performance data after page has finished loading.
3737
+ // If the document.readyState is not yet complete, we intentionally call observe using a setTimeout.
3738
+ // This allows us to capture loadEventEnd on navigation timeline.
3739
+ if (document.readyState !== "complete") {
3740
+ bind(window, "load", setTimeout$1.bind(this, observe, 0));
3741
+ }
3742
+ else {
3743
+ observe();
3744
+ }
3745
+ }
3746
+ else {
3747
+ log$1(3 /* Code.PerformanceObserver */, 0 /* Severity.Info */);
3748
+ }
3749
+ }
3750
+ function observe() {
3751
+ // Some browsers will throw an error for unsupported entryType, e.g. "layout-shift"
3752
+ // In those cases, we log it as a warning and continue with rest of the Clarity processing
3753
+ try {
3754
+ if (observer) {
3755
+ observer.disconnect();
3756
+ }
3757
+ observer = new PerformanceObserver(measure(handle));
3758
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver/observe
3759
+ // "buffered" flag indicates whether buffered entries should be queued into the observer's buffer.
3760
+ // It must only be used only with the "type" option, and cannot be used with entryTypes.
3761
+ // This is why we need to individually "observe" each supported type
3762
+ for (var _i = 0, types_1 = types; _i < types_1.length; _i++) {
3763
+ var x = types_1[_i];
3764
+ if (PerformanceObserver.supportedEntryTypes.indexOf(x) >= 0) {
3765
+ // Initialize CLS with a value of zero. It's possible (and recommended) for sites to not have any cumulative layout shift.
3766
+ // In those cases, we want to still initialize the metric in Clarity
3767
+ if (x === "layout-shift" /* Constant.CLS */) {
3768
+ sum(9 /* Metric.CumulativeLayoutShift */, 0);
3769
+ }
3770
+ observer.observe({ type: x, buffered: true });
3771
+ }
3772
+ }
3773
+ }
3774
+ catch (_a) {
3775
+ log$1(3 /* Code.PerformanceObserver */, 1 /* Severity.Warning */);
3776
+ }
3777
+ }
3778
+ observe.dn = 26 /* FunctionNames.ObserverObserve */;
3779
+ function handle(entries) {
3780
+ process(entries.getEntries());
3781
+ }
3782
+ handle.dn = 27 /* FunctionNames.ObserverHandle */;
3783
+ function process(entries) {
3784
+ var visible = "visibilityState" in document ? document.visibilityState === "visible" : true;
3785
+ for (var i = 0; i < entries.length; i++) {
3786
+ var entry = entries[i];
3787
+ switch (entry.entryType) {
3788
+ case "navigation" /* Constant.Navigation */:
3789
+ compute(entry);
3790
+ break;
3791
+ case "resource" /* Constant.Resource */:
3792
+ var name_1 = entry.name;
3793
+ log(4 /* Dimension.NetworkHosts */, host(name_1));
3794
+ if (name_1 === config$2.upload || name_1 === config$2.fallback) {
3795
+ max(28 /* Metric.UploadTime */, entry.duration);
3796
+ }
3797
+ break;
3798
+ case "longtask" /* Constant.LongTask */:
3799
+ count$1(7 /* Metric.LongTaskCount */);
3800
+ break;
3801
+ case "first-input" /* Constant.FID */:
3802
+ if (visible) {
3803
+ max(10 /* Metric.FirstInputDelay */, entry["processingStart"] - entry.startTime);
3804
+ }
3805
+ break;
3806
+ case "event" /* Constant.PerformanceEventTiming */:
3807
+ if (visible && 'PerformanceEventTiming' in window && 'interactionId' in PerformanceEventTiming.prototype) {
3808
+ processInteractionEntry(entry);
3809
+ // Logging it as dimension because we're always looking for the last value.
3810
+ log(37 /* Dimension.InteractionNextPaint */, estimateP98LongestInteraction().toString());
3811
+ }
3812
+ break;
3813
+ case "layout-shift" /* Constant.CLS */:
3814
+ // Scale the value to avoid sending back floating point number
3815
+ if (visible && !entry["hadRecentInput"]) {
3816
+ sum(9 /* Metric.CumulativeLayoutShift */, entry["value"] * 1000);
3817
+ }
3818
+ break;
3819
+ case "largest-contentful-paint" /* Constant.LCP */:
3820
+ if (visible) {
3821
+ max(8 /* Metric.LargestPaint */, entry.startTime);
3822
+ }
3823
+ break;
3824
+ }
3825
+ }
3826
+ }
3827
+ function host(url) {
3828
+ var a = document.createElement("a");
3829
+ a.href = url;
3830
+ return a.host;
3831
+ }
3832
+
3833
+ function start$1() {
3834
+ reset();
3835
+ start$2();
3836
+ }
3837
+ start$1.dn = 25 /* FunctionNames.PerformanceStart */;
298
3838
 
299
3839
  var helper = { hash: hash, selector: selector, get: get$2, getNode: getNode, lookup: lookup };
300
3840
 
@@ -1137,9 +4677,9 @@ var LayoutHelper = /** @class */ (function () {
1137
4677
  break;
1138
4678
  }
1139
4679
  };
1140
- this.dom = function (event, useproxy) { return __awaiter(_this, void 0, void 0, function () {
4680
+ this.dom = function (event, useproxy) { return __awaiter$1(_this, void 0, void 0, function () {
1141
4681
  var doc;
1142
- return __generator(this, function (_a) {
4682
+ return __generator$1(this, function (_a) {
1143
4683
  switch (_a.label) {
1144
4684
  case 0:
1145
4685
  if (!event) return [3 /*break*/, 2];
@@ -1617,8 +5157,8 @@ var Visualizer = /** @class */ (function () {
1617
5157
  this._state = null;
1618
5158
  this.renderTime = 0;
1619
5159
  this.hashFoundTime = -1;
1620
- this.dom = function (event) { return __awaiter(_this, void 0, void 0, function () {
1621
- return __generator(this, function (_a) {
5160
+ this.dom = function (event) { return __awaiter$1(_this, void 0, void 0, function () {
5161
+ return __generator$1(this, function (_a) {
1622
5162
  switch (_a.label) {
1623
5163
  case 0: return [4 /*yield*/, this.layout.dom(event)];
1624
5164
  case 1:
@@ -1656,9 +5196,9 @@ var Visualizer = /** @class */ (function () {
1656
5196
  this.html = function (decoded, target, hash, useproxy, logerror, shortCircuitStrategy) {
1657
5197
  if (hash === void 0) { hash = null; }
1658
5198
  if (shortCircuitStrategy === void 0) { shortCircuitStrategy = 0 /* ShortCircuitStrategy.None */; }
1659
- return __awaiter(_this, void 0, void 0, function () {
5199
+ return __awaiter$1(_this, void 0, void 0, function () {
1660
5200
  var merged, entry, _a, domEvent, e_1;
1661
- return __generator(this, function (_b) {
5201
+ return __generator$1(this, function (_b) {
1662
5202
  switch (_b.label) {
1663
5203
  case 0:
1664
5204
  if (!(decoded && decoded.length > 0 && target)) return [3 /*break*/, 10];
@@ -1766,8 +5306,8 @@ var Visualizer = /** @class */ (function () {
1766
5306
  merged.events = merged.events.sort(_this.sortEvents);
1767
5307
  return merged;
1768
5308
  };
1769
- this.setup = function (target, options) { return __awaiter(_this, void 0, void 0, function () {
1770
- return __generator(this, function (_a) {
5309
+ this.setup = function (target, options) { return __awaiter$1(_this, void 0, void 0, function () {
5310
+ return __generator$1(this, function (_a) {
1771
5311
  switch (_a.label) {
1772
5312
  case 0:
1773
5313
  this.reset();
@@ -1791,9 +5331,9 @@ var Visualizer = /** @class */ (function () {
1791
5331
  }
1792
5332
  });
1793
5333
  }); };
1794
- this.render = function (events) { return __awaiter(_this, void 0, void 0, function () {
5334
+ this.render = function (events) { return __awaiter$1(_this, void 0, void 0, function () {
1795
5335
  var time, _i, events_1, entry, _a;
1796
- return __generator(this, function (_b) {
5336
+ return __generator$1(this, function (_b) {
1797
5337
  switch (_b.label) {
1798
5338
  case 0:
1799
5339
  if (this.state === null) {