clarity-js 0.6.33 → 0.6.36

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.
@@ -56,9 +56,8 @@ var dimension = /*#__PURE__*/Object.freeze({
56
56
  var metadata$1 = /*#__PURE__*/Object.freeze({
57
57
  __proto__: null,
58
58
  get data () { return data$2; },
59
- get callback () { return callback; },
59
+ get callbacks () { return callbacks; },
60
60
  get start () { return start$9; },
61
- get userAgentData () { return userAgentData; },
62
61
  get stop () { return stop$8; },
63
62
  get metadata () { return metadata; },
64
63
  get id () { return id; },
@@ -85,6 +84,7 @@ var config$1 = {
85
84
  regions: [],
86
85
  extract: [],
87
86
  cookies: [],
87
+ fraud: [],
88
88
  report: null,
89
89
  upload: null,
90
90
  fallback: null,
@@ -107,11 +107,11 @@ function time(ts) {
107
107
  ts = ts ? ts : performance.now();
108
108
  return Math.max(Math.round(ts - startTime), 0);
109
109
  }
110
- function stop$C() {
110
+ function stop$B() {
111
111
  startTime = 0;
112
112
  }
113
113
 
114
- var version$1 = "0.6.33";
114
+ var version$1 = "0.6.36";
115
115
 
116
116
  // tslint:disable: no-bitwise
117
117
  function hash (input) {
@@ -138,9 +138,9 @@ var buffer = null;
138
138
  var update$2 = false;
139
139
  function start$E() {
140
140
  update$2 = false;
141
- reset$p();
141
+ reset$o();
142
142
  }
143
- function reset$p() {
143
+ function reset$o() {
144
144
  // Baseline state holds the previous values - if it is updated in the current payload,
145
145
  // reset the state to current value after sending the previous state
146
146
  if (update$2) {
@@ -202,25 +202,25 @@ function visibility(t, visible) {
202
202
  }
203
203
  update$2 = true;
204
204
  }
205
- function compute$d() {
205
+ function compute$c() {
206
206
  if (update$2) {
207
207
  encode$1(4 /* Baseline */);
208
208
  }
209
209
  }
210
- function stop$B() {
211
- reset$p();
210
+ function stop$A() {
211
+ reset$o();
212
212
  }
213
213
 
214
214
  var baseline = /*#__PURE__*/Object.freeze({
215
215
  __proto__: null,
216
216
  get state () { return state$9; },
217
217
  start: start$E,
218
- reset: reset$p,
218
+ reset: reset$o,
219
219
  track: track$7,
220
220
  activity: activity,
221
221
  visibility: visibility,
222
- compute: compute$d,
223
- stop: stop$B
222
+ compute: compute$c,
223
+ stop: stop$A
224
224
  });
225
225
 
226
226
  var data$j = null;
@@ -244,20 +244,19 @@ function start$D() {
244
244
  updates$3 = {};
245
245
  count$1(5 /* InvokeCount */);
246
246
  }
247
- function stop$A() {
247
+ function stop$z() {
248
248
  data$i = {};
249
249
  updates$3 = {};
250
250
  }
251
- function count$1(metric, increment) {
252
- if (increment === void 0) { increment = 1; }
251
+ function count$1(metric) {
253
252
  if (!(metric in data$i)) {
254
253
  data$i[metric] = 0;
255
254
  }
256
255
  if (!(metric in updates$3)) {
257
256
  updates$3[metric] = 0;
258
257
  }
259
- data$i[metric] += increment;
260
- updates$3[metric] += increment;
258
+ data$i[metric]++;
259
+ updates$3[metric]++;
261
260
  }
262
261
  function sum(metric, value) {
263
262
  if (value !== null) {
@@ -283,10 +282,10 @@ function max(metric, value) {
283
282
  }
284
283
  }
285
284
  }
286
- function compute$c() {
285
+ function compute$b() {
287
286
  encode$1(0 /* Metric */);
288
287
  }
289
- function reset$o() {
288
+ function reset$n() {
290
289
  updates$3 = {};
291
290
  }
292
291
 
@@ -305,7 +304,7 @@ function start$C() {
305
304
  interval = 60000 /* PingInterval */;
306
305
  last = 0;
307
306
  }
308
- function reset$n() {
307
+ function reset$m() {
309
308
  if (timeout$6) {
310
309
  clearTimeout(timeout$6);
311
310
  }
@@ -323,7 +322,7 @@ function ping() {
323
322
  suspend();
324
323
  }
325
324
  }
326
- function stop$z() {
325
+ function stop$y() {
327
326
  clearTimeout(timeout$6);
328
327
  last = 0;
329
328
  interval = 0;
@@ -333,15 +332,15 @@ var ping$1 = /*#__PURE__*/Object.freeze({
333
332
  __proto__: null,
334
333
  get data () { return data$h; },
335
334
  start: start$C,
336
- reset: reset$n,
337
- stop: stop$z
335
+ reset: reset$m,
336
+ stop: stop$y
338
337
  });
339
338
 
340
339
  var data$g = null;
341
340
  function start$B() {
342
341
  data$g = {};
343
342
  }
344
- function stop$y() {
343
+ function stop$x() {
345
344
  data$g = {};
346
345
  }
347
346
  function track$6(event, time) {
@@ -361,10 +360,10 @@ function track$6(event, time) {
361
360
  }
362
361
  }
363
362
  }
364
- function compute$b() {
363
+ function compute$a() {
365
364
  encode$1(36 /* Summary */);
366
365
  }
367
- function reset$m() {
366
+ function reset$l() {
368
367
  data$g = {};
369
368
  }
370
369
 
@@ -372,10 +371,10 @@ var summary = /*#__PURE__*/Object.freeze({
372
371
  __proto__: null,
373
372
  get data () { return data$g; },
374
373
  start: start$B,
375
- stop: stop$y,
374
+ stop: stop$x,
376
375
  track: track$6,
377
- compute: compute$b,
378
- reset: reset$m
376
+ compute: compute$a,
377
+ reset: reset$l
379
378
  });
380
379
 
381
380
  var data$f = null;
@@ -403,7 +402,7 @@ function upgrade(key) {
403
402
  encode$1(3 /* Upgrade */);
404
403
  }
405
404
  }
406
- function stop$x() {
405
+ function stop$w() {
407
406
  data$f = null;
408
407
  }
409
408
 
@@ -412,12 +411,12 @@ var upgrade$1 = /*#__PURE__*/Object.freeze({
412
411
  get data () { return data$f; },
413
412
  start: start$A,
414
413
  upgrade: upgrade,
415
- stop: stop$x
414
+ stop: stop$w
416
415
  });
417
416
 
418
417
  var data$e = null;
419
418
  function start$z() {
420
- reset$l();
419
+ reset$k();
421
420
  }
422
421
  function set(variable, value) {
423
422
  var values = typeof value === "string" /* String */ ? [value] : value;
@@ -445,14 +444,14 @@ function log$2(variable, value) {
445
444
  data$e[variable] = validValues;
446
445
  }
447
446
  }
448
- function compute$a() {
447
+ function compute$9() {
449
448
  encode$1(34 /* Variable */);
450
449
  }
451
- function reset$l() {
450
+ function reset$k() {
452
451
  data$e = {};
453
452
  }
454
- function stop$w() {
455
- reset$l();
453
+ function stop$v() {
454
+ reset$k();
456
455
  }
457
456
 
458
457
  var variable = /*#__PURE__*/Object.freeze({
@@ -461,9 +460,9 @@ var variable = /*#__PURE__*/Object.freeze({
461
460
  start: start$z,
462
461
  set: set,
463
462
  identify: identify,
464
- compute: compute$a,
465
- reset: reset$l,
466
- stop: stop$w
463
+ compute: compute$9,
464
+ reset: reset$k,
465
+ stop: stop$v
467
466
  });
468
467
 
469
468
  /*! *****************************************************************************
@@ -583,20 +582,20 @@ function start$y() {
583
582
  start$D();
584
583
  modules$1.forEach(function (x) { return measure(x.start)(); });
585
584
  }
586
- function stop$v() {
585
+ function stop$u() {
587
586
  // Stop modules in the reverse order of their initialization
588
587
  // The ordering below should respect inter-module dependency.
589
588
  // E.g. if upgrade depends on upload, then upgrade needs to end before upload.
590
589
  // Similarly, if upload depends on metadata, upload needs to end before metadata.
591
590
  modules$1.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
592
- stop$A();
591
+ stop$z();
593
592
  }
594
- function compute$9() {
595
- compute$a();
596
- compute$d();
597
- compute$2();
593
+ function compute$8() {
594
+ compute$9();
598
595
  compute$c();
596
+ compute$2();
599
597
  compute$b();
598
+ compute$a();
600
599
  compute$3();
601
600
  compute$4();
602
601
  }
@@ -697,6 +696,24 @@ function mutate(array, start, end) {
697
696
  }
698
697
  }
699
698
 
699
+ var history$5 = [];
700
+ var data$d;
701
+ function start$x() {
702
+ history$5 = [];
703
+ max(26 /* Automation */, navigator.webdriver ? 1 /* True */ : 0 /* False */);
704
+ }
705
+ function check$4(id, target, input) {
706
+ // Compute hash for fraud detection. Hash is computed only if input meets the minimum length criteria
707
+ if (id !== null && input && input.length >= 5 /* WordLength */) {
708
+ data$d = { id: id, target: target, hash: hash(input) };
709
+ // Only encode this event if we haven't already reported this hash
710
+ if (history$5.indexOf(data$d.hash) < 0) {
711
+ history$5.push(data$d.hash);
712
+ encode$2(41 /* Fraud */);
713
+ }
714
+ }
715
+ }
716
+
700
717
  var TAGS = ["DIV", "TR", "P", "LI", "UL", "A", "BUTTON"];
701
718
  function selector (input, beta) {
702
719
  if (beta === void 0) { beta = false; }
@@ -781,7 +798,7 @@ function resume$1() {
781
798
  }
782
799
  }
783
800
  }
784
- function reset$k() {
801
+ function reset$j() {
785
802
  tracker = {};
786
803
  queuedTasks = [];
787
804
  activeTask = null;
@@ -851,20 +868,20 @@ function state$8(timer) {
851
868
  // If this task is no longer being tracked, send stop message to the caller
852
869
  return 2 /* Stop */;
853
870
  }
854
- function start$x(timer) {
871
+ function start$w(timer) {
855
872
  tracker[key(timer)] = { start: performance.now(), calls: 0, yield: 30 /* LongTask */ };
856
873
  }
857
- function restart$1(timer) {
874
+ function restart$2(timer) {
858
875
  var id = key(timer);
859
876
  if (tracker && tracker[id]) {
860
877
  var c = tracker[id].calls;
861
878
  var y = tracker[id].yield;
862
- start$x(timer);
879
+ start$w(timer);
863
880
  tracker[id].calls = c + 1;
864
881
  tracker[id].yield = y;
865
882
  }
866
883
  }
867
- function stop$u(timer) {
884
+ function stop$t(timer) {
868
885
  var end = performance.now();
869
886
  var id = key(timer);
870
887
  var duration = end - tracker[id].start;
@@ -884,12 +901,12 @@ function suspend$1(timer) {
884
901
  case 0:
885
902
  id = key(timer);
886
903
  if (!(id in tracker)) return [3 /*break*/, 2];
887
- stop$u(timer);
904
+ stop$t(timer);
888
905
  _a = tracker[id];
889
906
  return [4 /*yield*/, wait()];
890
907
  case 1:
891
908
  _a.yield = (_b.sent()).timeRemaining();
892
- restart$1(timer);
909
+ restart$2(timer);
893
910
  _b.label = 2;
894
911
  case 2:
895
912
  // After we are done with suspending task, ensure that we are still operating in the right context
@@ -996,91 +1013,13 @@ function tokenize (tokens) {
996
1013
  return output;
997
1014
  }
998
1015
 
999
- var data$d = [];
1000
- var enabled = false;
1001
- var observer$2 = null;
1002
- function start$w() {
1003
- reset$j();
1004
- observer$2 = null;
1005
- enabled = window["ResizeObserver"] ? true : false;
1006
- }
1007
- function compute$8(id) {
1008
- if (enabled === false) {
1009
- return;
1010
- }
1011
- observer$2 = observer$2 === null ? new ResizeObserver(handler$4) : observer$2;
1012
- if (observer$2) {
1013
- var value = getValue(id);
1014
- // If this is the first time computing size for this node, go ahead and wire up ResizeObserver
1015
- // In all other cases, value.metadata.size will be null or an array with two elements [width, height]
1016
- // And, in those cases, we will skip through the following section and not attach the observer
1017
- if (value && value.metadata.size !== null && value.metadata.size.length === 0) {
1018
- var node = getNode(id);
1019
- if (node && node.nodeType === Node.ELEMENT_NODE) {
1020
- var e = node;
1021
- var r = e.getBoundingClientRect();
1022
- value.metadata.size = [Math.floor(r.width * 100 /* BoxPrecision */), Math.floor(r.height * 100 /* BoxPrecision */)];
1023
- observer$2.observe(e);
1024
- }
1025
- }
1026
- }
1027
- }
1028
- function handler$4(entries) {
1029
- window.requestAnimationFrame(function () {
1030
- for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
1031
- var entry = entries_1[_i];
1032
- var target = entry.target;
1033
- var id = target ? getId(target) : null;
1034
- if (id) {
1035
- var v = getValue(id);
1036
- var s = v.metadata.size;
1037
- var b = entry.borderBoxSize;
1038
- var w = null;
1039
- var h = null;
1040
- // Check if browser supports borderBoxSize property on ResizeObserverEntry object
1041
- // Otherwise, fall back to using getBoundingClientRect() to be cross browser compatible
1042
- // Reference: https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/borderBoxSize
1043
- if (b && b.length > 0) {
1044
- w = Math.floor(b[0].inlineSize * 100 /* BoxPrecision */);
1045
- h = Math.floor(b[0].blockSize * 100 /* BoxPrecision */);
1046
- }
1047
- else {
1048
- var r = target.getBoundingClientRect();
1049
- w = Math.floor(r.width * 100 /* BoxPrecision */);
1050
- h = Math.floor(r.height * 100 /* BoxPrecision */);
1051
- }
1052
- // Capture new width & height only if they are different from what we have in in-memory cache
1053
- if (w !== s[0] && h !== s[1]) {
1054
- s = [w, h];
1055
- data$d.push({ id: id, width: w, height: h });
1056
- }
1057
- }
1058
- }
1059
- // Schedule encode only when we have at least one valid data entry
1060
- if (data$d.length > 0) {
1061
- encode$4(37 /* Box */);
1062
- }
1063
- });
1064
- }
1065
- function reset$j() {
1066
- data$d = [];
1067
- }
1068
- function stop$t() {
1069
- reset$j();
1070
- if (observer$2) {
1071
- observer$2.disconnect();
1072
- observer$2 = null;
1073
- }
1074
- enabled = false;
1075
- }
1076
-
1077
1016
  function encode$4 (type, timer, ts) {
1078
1017
  if (timer === void 0) { timer = null; }
1079
1018
  if (ts === void 0) { ts = null; }
1080
1019
  return __awaiter(this, void 0, void 0, function () {
1081
- var eventTime, tokens, _a, d, _i, _b, r, b, _c, b_1, entry, values, _d, values_1, value, state, data, active, suspend, privacy, mangle, keys, _e, keys_1, key, size, factor, attr;
1082
- return __generator(this, function (_f) {
1083
- switch (_f.label) {
1020
+ var eventTime, tokens, _a, d, _i, _b, r, values, _c, values_1, value, state, data, active, suspend, privacy, mangle, keys, _d, keys_1, key, box, factor, attr;
1021
+ return __generator(this, function (_e) {
1022
+ switch (_e.label) {
1084
1023
  case 0:
1085
1024
  eventTime = ts || time();
1086
1025
  tokens = [eventTime, type];
@@ -1088,18 +1027,17 @@ function encode$4 (type, timer, ts) {
1088
1027
  switch (_a) {
1089
1028
  case 8 /* Document */: return [3 /*break*/, 1];
1090
1029
  case 7 /* Region */: return [3 /*break*/, 2];
1091
- case 37 /* Box */: return [3 /*break*/, 3];
1092
- case 5 /* Discover */: return [3 /*break*/, 4];
1093
- case 6 /* Mutation */: return [3 /*break*/, 4];
1030
+ case 5 /* Discover */: return [3 /*break*/, 3];
1031
+ case 6 /* Mutation */: return [3 /*break*/, 3];
1094
1032
  }
1095
- return [3 /*break*/, 11];
1033
+ return [3 /*break*/, 10];
1096
1034
  case 1:
1097
1035
  d = data$c;
1098
1036
  tokens.push(d.width);
1099
1037
  tokens.push(d.height);
1100
1038
  track$7(type, d.width, d.height);
1101
1039
  queue(tokens);
1102
- return [3 /*break*/, 11];
1040
+ return [3 /*break*/, 10];
1103
1041
  case 2:
1104
1042
  for (_i = 0, _b = state$1; _i < _b.length; _i++) {
1105
1043
  r = _b[_i];
@@ -1111,39 +1049,28 @@ function encode$4 (type, timer, ts) {
1111
1049
  queue(tokens);
1112
1050
  }
1113
1051
  reset$6();
1114
- return [3 /*break*/, 11];
1052
+ return [3 /*break*/, 10];
1115
1053
  case 3:
1116
- b = data$d;
1117
- for (_c = 0, b_1 = b; _c < b_1.length; _c++) {
1118
- entry = b_1[_c];
1119
- tokens.push(entry.id);
1120
- tokens.push(entry.width);
1121
- tokens.push(entry.height);
1122
- }
1123
- reset$j();
1124
- queue(tokens);
1125
- return [3 /*break*/, 11];
1126
- case 4:
1127
1054
  // Check if we are operating within the context of the current page
1128
1055
  if (state$8(timer) === 2 /* Stop */) {
1129
- return [3 /*break*/, 11];
1056
+ return [3 /*break*/, 10];
1130
1057
  }
1131
1058
  values = updates$2();
1132
- if (!(values.length > 0)) return [3 /*break*/, 10];
1133
- _d = 0, values_1 = values;
1134
- _f.label = 5;
1135
- case 5:
1136
- if (!(_d < values_1.length)) return [3 /*break*/, 9];
1137
- value = values_1[_d];
1059
+ if (!(values.length > 0)) return [3 /*break*/, 9];
1060
+ _c = 0, values_1 = values;
1061
+ _e.label = 4;
1062
+ case 4:
1063
+ if (!(_c < values_1.length)) return [3 /*break*/, 8];
1064
+ value = values_1[_c];
1138
1065
  state = state$8(timer);
1139
- if (!(state === 0 /* Wait */)) return [3 /*break*/, 7];
1066
+ if (!(state === 0 /* Wait */)) return [3 /*break*/, 6];
1140
1067
  return [4 /*yield*/, suspend$1(timer)];
1068
+ case 5:
1069
+ state = _e.sent();
1070
+ _e.label = 6;
1141
1071
  case 6:
1142
- state = _f.sent();
1143
- _f.label = 7;
1144
- case 7:
1145
1072
  if (state === 2 /* Stop */) {
1146
- return [3 /*break*/, 9];
1073
+ return [3 /*break*/, 8];
1147
1074
  }
1148
1075
  data = value.data;
1149
1076
  active = value.metadata.active;
@@ -1151,13 +1078,12 @@ function encode$4 (type, timer, ts) {
1151
1078
  privacy = value.metadata.privacy;
1152
1079
  mangle = shouldMangle(value);
1153
1080
  keys = active ? ["tag", "attributes", "value"] : ["tag"];
1154
- compute$8(value.id);
1155
- for (_e = 0, keys_1 = keys; _e < keys_1.length; _e++) {
1156
- key = keys_1[_e];
1081
+ for (_d = 0, keys_1 = keys; _d < keys_1.length; _d++) {
1082
+ key = keys_1[_d];
1157
1083
  if (data[key]) {
1158
1084
  switch (key) {
1159
1085
  case "tag":
1160
- size = value.metadata.size;
1086
+ box = size$1(value);
1161
1087
  factor = mangle ? -1 : 1;
1162
1088
  tokens.push(value.id * factor);
1163
1089
  if (value.parent && active) {
@@ -1167,8 +1093,8 @@ function encode$4 (type, timer, ts) {
1167
1093
  tokens.push(value.previous);
1168
1094
  }
1169
1095
  tokens.push(suspend ? "*M" /* SuspendMutationTag */ : data[key]);
1170
- if (size && size.length === 2) {
1171
- tokens.push("" + "#" /* Box */ + str$1(size[0]) + "." + str$1(size[1]));
1096
+ if (box && box.length === 2) {
1097
+ tokens.push("" + "#" /* Box */ + str$1(box[0]) + "." + str$1(box[1]));
1172
1098
  }
1173
1099
  break;
1174
1100
  case "attributes":
@@ -1179,23 +1105,24 @@ function encode$4 (type, timer, ts) {
1179
1105
  }
1180
1106
  break;
1181
1107
  case "value":
1108
+ check$4(value.metadata.fraud, value.id, data[key]);
1182
1109
  tokens.push(scrub(data[key], data.tag, privacy, mangle));
1183
1110
  break;
1184
1111
  }
1185
1112
  }
1186
1113
  }
1187
- _f.label = 8;
1114
+ _e.label = 7;
1115
+ case 7:
1116
+ _c++;
1117
+ return [3 /*break*/, 4];
1188
1118
  case 8:
1189
- _d++;
1190
- return [3 /*break*/, 5];
1191
- case 9:
1192
1119
  if (type === 6 /* Mutation */) {
1193
1120
  activity(eventTime);
1194
1121
  }
1195
1122
  queue(tokenize(tokens), !config$1.lean);
1196
- _f.label = 10;
1197
- case 10: return [3 /*break*/, 11];
1198
- case 11: return [2 /*return*/];
1123
+ _e.label = 9;
1124
+ case 9: return [3 /*break*/, 10];
1125
+ case 10: return [2 /*return*/];
1199
1126
  }
1200
1127
  });
1201
1128
  });
@@ -1204,6 +1131,15 @@ function shouldMangle(value) {
1204
1131
  var privacy = value.metadata.privacy;
1205
1132
  return value.data.tag === "*T" /* TextTag */ && !(privacy === 0 /* None */ || privacy === 1 /* Sensitive */);
1206
1133
  }
1134
+ function size$1(value) {
1135
+ if (value.metadata.size !== null && value.metadata.size.length === 0) {
1136
+ var img = getNode(value.id);
1137
+ if (img) {
1138
+ return [Math.floor(img.offsetWidth * 100 /* BoxPrecision */), Math.floor(img.offsetHeight * 100 /* BoxPrecision */)];
1139
+ }
1140
+ }
1141
+ return value.metadata.size;
1142
+ }
1207
1143
  function str$1(input) {
1208
1144
  return input.toString(36);
1209
1145
  }
@@ -1312,7 +1248,8 @@ function handler$3(event, root, evt) {
1312
1248
  context: context(a),
1313
1249
  text: text(t),
1314
1250
  link: a ? a.href : null,
1315
- hash: null
1251
+ hash: null,
1252
+ trust: evt.isTrusted ? 1 /* True */ : 0 /* False */
1316
1253
  }
1317
1254
  });
1318
1255
  schedule$1(encode$3.bind(this, event));
@@ -1411,18 +1348,12 @@ function recompute$6(evt) {
1411
1348
  var input = target(evt);
1412
1349
  var value = get(input);
1413
1350
  if (input && input.type && value) {
1414
- var v = void 0;
1351
+ var v = input.value;
1415
1352
  switch (input.type) {
1416
1353
  case "radio":
1417
1354
  case "checkbox":
1418
1355
  v = input.checked ? "true" : "false";
1419
1356
  break;
1420
- case "range":
1421
- v = input.value;
1422
- break;
1423
- default:
1424
- v = scrub(input.value, "input", value.metadata.privacy);
1425
- break;
1426
1357
  }
1427
1358
  var data = { target: input, value: v };
1428
1359
  // 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.
@@ -1832,7 +1763,7 @@ function num$1(input, scale) {
1832
1763
  return null;
1833
1764
  }
1834
1765
 
1835
- var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror"];
1766
+ var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror", "data-drupal-form-submit-last"];
1836
1767
  var newlineRegex = /[\r\n]+/g;
1837
1768
  function processNode (node, source) {
1838
1769
  var child = null;
@@ -2097,37 +2028,46 @@ function start$j() {
2097
2028
  timeout$1 = null;
2098
2029
  activePeriod = 0;
2099
2030
  history$4 = {};
2031
+ // Some popular open source libraries, like styled-components, optimize performance
2032
+ // by injecting CSS using insertRule API vs. appending text node. A side effect of
2033
+ // using javascript API is that it doesn't trigger DOM mutation and therefore we
2034
+ // need to override the insertRule API and listen for changes manually.
2100
2035
  if (insertRule === null) {
2101
2036
  insertRule = CSSStyleSheet.prototype.insertRule;
2037
+ CSSStyleSheet.prototype.insertRule = function () {
2038
+ if (active()) {
2039
+ schedule(this.ownerNode);
2040
+ }
2041
+ return insertRule.apply(this, arguments);
2042
+ };
2102
2043
  }
2103
2044
  if (deleteRule === null) {
2104
2045
  deleteRule = CSSStyleSheet.prototype.deleteRule;
2046
+ CSSStyleSheet.prototype.deleteRule = function () {
2047
+ if (active()) {
2048
+ schedule(this.ownerNode);
2049
+ }
2050
+ return deleteRule.apply(this, arguments);
2051
+ };
2105
2052
  }
2106
- if (attachShadow === null) {
2107
- attachShadow = Element.prototype.attachShadow;
2108
- }
2109
- // Some popular open source libraries, like styled-components, optimize performance
2110
- // by injecting CSS using insertRule API vs. appending text node. A side effect of
2111
- // using javascript API is that it doesn't trigger DOM mutation and therefore we
2112
- // need to override the insertRule API and listen for changes manually.
2113
- CSSStyleSheet.prototype.insertRule = function () {
2114
- schedule(this.ownerNode);
2115
- return insertRule.apply(this, arguments);
2116
- };
2117
- CSSStyleSheet.prototype.deleteRule = function () {
2118
- schedule(this.ownerNode);
2119
- return deleteRule.apply(this, arguments);
2120
- };
2121
2053
  // Add a hook to attachShadow API calls
2122
2054
  // In case we are unable to add a hook and browser throws an exception,
2123
2055
  // reset attachShadow variable and resume processing like before
2124
- try {
2125
- Element.prototype.attachShadow = function () {
2126
- return schedule(attachShadow.apply(this, arguments));
2127
- };
2128
- }
2129
- catch (_a) {
2130
- attachShadow = null;
2056
+ if (attachShadow === null) {
2057
+ attachShadow = Element.prototype.attachShadow;
2058
+ try {
2059
+ Element.prototype.attachShadow = function () {
2060
+ if (active()) {
2061
+ return schedule(attachShadow.apply(this, arguments));
2062
+ }
2063
+ else {
2064
+ return attachShadow.apply(this, arguments);
2065
+ }
2066
+ };
2067
+ }
2068
+ catch (_a) {
2069
+ attachShadow = null;
2070
+ }
2131
2071
  }
2132
2072
  }
2133
2073
  function observe$2(node) {
@@ -2163,21 +2103,6 @@ function stop$h() {
2163
2103
  }
2164
2104
  }
2165
2105
  observers = [];
2166
- // Restoring original insertRule
2167
- if (insertRule !== null) {
2168
- CSSStyleSheet.prototype.insertRule = insertRule;
2169
- insertRule = null;
2170
- }
2171
- // Restoring original deleteRule
2172
- if (deleteRule !== null) {
2173
- CSSStyleSheet.prototype.deleteRule = deleteRule;
2174
- deleteRule = null;
2175
- }
2176
- // Restoring original attachShadow
2177
- if (attachShadow != null) {
2178
- Element.prototype.attachShadow = attachShadow;
2179
- attachShadow = null;
2180
- }
2181
2106
  history$4 = {};
2182
2107
  mutations = [];
2183
2108
  queue$2 = [];
@@ -2193,7 +2118,7 @@ function handle$1(m) {
2193
2118
  track$6(6 /* Mutation */, now);
2194
2119
  mutations.push({ time: now, mutations: m });
2195
2120
  schedule$1(process$2, 1 /* High */).then(function () {
2196
- measure(compute$7)();
2121
+ setTimeout(compute$7);
2197
2122
  measure(compute$6)();
2198
2123
  });
2199
2124
  }
@@ -2204,7 +2129,7 @@ function process$2() {
2204
2129
  switch (_b.label) {
2205
2130
  case 0:
2206
2131
  timer = { id: id(), cost: 3 /* LayoutCost */ };
2207
- start$x(timer);
2132
+ start$w(timer);
2208
2133
  _b.label = 1;
2209
2134
  case 1:
2210
2135
  if (!(mutations.length > 0)) return [3 /*break*/, 8];
@@ -2259,7 +2184,7 @@ function process$2() {
2259
2184
  _b.sent();
2260
2185
  return [3 /*break*/, 1];
2261
2186
  case 8:
2262
- stop$u(timer);
2187
+ stop$t(timer);
2263
2188
  return [2 /*return*/];
2264
2189
  }
2265
2190
  });
@@ -2386,10 +2311,6 @@ function generate(target, type) {
2386
2311
  }
2387
2312
 
2388
2313
  var index = 1;
2389
- // Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#%3Cinput%3E_types
2390
- var DISALLOWED_TYPES = ["password", "hidden", "email", "tel"];
2391
- var DISALLOWED_NAMES = ["addr", "cell", "code", "dob", "email", "mob", "name", "phone", "secret", "social", "ssn", "tel", "zip", "pass", "card", "account", "cvv", "ccv"];
2392
- var DISALLOWED_MATCH = ["address", "password", "contact"];
2393
2314
  var nodes = [];
2394
2315
  var values = [];
2395
2316
  var updateMap = [];
@@ -2397,10 +2318,13 @@ var hashMap = {};
2397
2318
  var override = [];
2398
2319
  var unmask = [];
2399
2320
  var updatedFragments = {};
2321
+ var maskText = [];
2322
+ var maskDisable = [];
2400
2323
  // The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
2401
2324
  var idMap = null; // Maps node => id.
2402
2325
  var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
2403
2326
  var privacyMap = null; // Maps node => Privacy (enum)
2327
+ var fraudMap = null; // Maps node => FraudId (number)
2404
2328
  function start$i() {
2405
2329
  reset$7();
2406
2330
  parse$1(document, true);
@@ -2416,9 +2340,12 @@ function reset$7() {
2416
2340
  hashMap = {};
2417
2341
  override = [];
2418
2342
  unmask = [];
2343
+ maskText = "password,secret,pass,social,ssn,name,code,dob,cell,mob,contact,hidden,account,cvv,ccv,email,tel,phone,address,addr,card,zip" /* Text */.split("," /* Comma */);
2344
+ maskDisable = "radio,checkbox,range,button,reset,submit" /* Disable */.split("," /* Comma */);
2419
2345
  idMap = new WeakMap();
2420
2346
  iframeMap = new WeakMap();
2421
2347
  privacyMap = new WeakMap();
2348
+ fraudMap = new WeakMap();
2422
2349
  }
2423
2350
  // We parse new root nodes for any regions or masked nodes in the beginning (document) and
2424
2351
  // later whenever there are new additions or modifications to DOM (mutations)
@@ -2436,6 +2363,7 @@ function parse$1(root, init) {
2436
2363
  if ("querySelectorAll" in root) {
2437
2364
  config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "" + x[0]); }); }); // Regions
2438
2365
  config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* TextImage */); }); }); // Masked Elements
2366
+ config$1.fraud.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Check
2439
2367
  unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* None */); }); }); // Unmasked Elements
2440
2368
  }
2441
2369
  }
@@ -2459,19 +2387,18 @@ function add(node, parent, data, source) {
2459
2387
  var id = getId(node, true);
2460
2388
  var parentId = parent ? getId(parent) : null;
2461
2389
  var previousId = getPreviousId(node);
2462
- var privacy = config$1.content ? 1 /* Sensitive */ : 2 /* Text */;
2463
2390
  var parentValue = null;
2464
2391
  var regionId = exists(node) ? id : null;
2465
2392
  var fragmentId = null;
2393
+ var fraudId = fraudMap.has(node) ? fraudMap.get(node) : null;
2394
+ var privacyId = config$1.content ? 1 /* Sensitive */ : 2 /* Text */;
2466
2395
  if (parentId >= 0 && values[parentId]) {
2467
2396
  parentValue = values[parentId];
2468
2397
  parentValue.children.push(id);
2469
2398
  regionId = regionId === null ? parentValue.region : regionId;
2470
2399
  fragmentId = parentValue.fragment;
2471
- privacy = parentValue.metadata.privacy;
2400
+ fraudId = fraudId === null ? parentValue.metadata.fraud : fraudId;
2472
2401
  }
2473
- // Check to see if this particular node should be masked or not
2474
- privacy = getPrivacy(node, data, parentValue, privacy);
2475
2402
  // If there's an explicit region attribute set on the element, use it to mark a region on the page
2476
2403
  if (data.attributes && "data-clarity-region" /* RegionData */ in data.attributes) {
2477
2404
  observe$1(node, data.attributes["data-clarity-region" /* RegionData */]);
@@ -2487,11 +2414,12 @@ function add(node, parent, data, source) {
2487
2414
  selector: null,
2488
2415
  hash: null,
2489
2416
  region: regionId,
2490
- metadata: { active: true, suspend: false, privacy: privacy, position: null, size: null },
2417
+ metadata: { active: true, suspend: false, privacy: privacyId, position: null, fraud: fraudId, size: null },
2491
2418
  fragment: fragmentId,
2492
2419
  };
2420
+ privacy(node, values[id], parentValue);
2493
2421
  updateSelector(values[id]);
2494
- size(values[id], parentValue);
2422
+ size(values[id]);
2495
2423
  track$4(id, source, values[id].fragment);
2496
2424
  }
2497
2425
  function update$1(node, parent, data, source) {
@@ -2571,75 +2499,61 @@ function iframe(node) {
2571
2499
  var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
2572
2500
  return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
2573
2501
  }
2574
- function getPrivacy(node, data, parent, privacy) {
2575
- var attributes = data.attributes;
2502
+ function privacy(node, value, parent) {
2503
+ var data = value.data;
2504
+ var metadata = value.metadata;
2505
+ var current = metadata.privacy;
2506
+ var attributes = data.attributes || {};
2576
2507
  var tag = data.tag.toUpperCase();
2577
- // If this node was explicitly configured to contain sensitive content, use that information and return the value
2578
- if (privacyMap.has(node)) {
2579
- return privacyMap.get(node);
2580
- }
2581
- // If it's a text node belonging to a STYLE or TITLE tag;
2582
- // Or, the text node belongs to one of SCRUB_EXCEPTIONS
2583
- // then reset the privacy setting to ensure we capture the content
2584
- if (tag === "*T" /* TextTag */ && parent && parent.data) {
2585
- var path = parent.selector ? parent.selector[0 /* Stable */] : "" /* Empty */;
2586
- privacy = parent.data.tag === "STYLE" /* StyleTag */ || parent.data.tag === "TITLE" /* TitleTag */ ? 0 /* None */ : privacy;
2587
- for (var _i = 0, override_1 = override; _i < override_1.length; _i++) {
2588
- var entry = override_1[_i];
2589
- if (path.indexOf(entry) >= 0) {
2590
- privacy = 0 /* None */;
2591
- break;
2592
- }
2593
- }
2594
- }
2595
- // Do not proceed if attributes are missing for the node
2596
- if (attributes === null || attributes === undefined) {
2597
- return privacy;
2598
- }
2599
- // Look up for sensitive fields
2600
- if ("class" /* Class */ in attributes && privacy === 1 /* Sensitive */) {
2601
- for (var _a = 0, DISALLOWED_MATCH_1 = DISALLOWED_MATCH; _a < DISALLOWED_MATCH_1.length; _a++) {
2602
- var match = DISALLOWED_MATCH_1[_a];
2603
- if (attributes["class" /* Class */].indexOf(match) >= 0) {
2604
- privacy = 2 /* Text */;
2605
- break;
2606
- }
2607
- }
2608
- }
2609
- // Check for disallowed list of fields (e.g. address, phone, etc.) only if the input node is not already masked
2610
- if (tag === "INPUT" /* InputTag */) {
2611
- if (privacy === 0 /* None */) {
2612
- var field = "" /* Empty */;
2613
- // Be aggressive in looking up any attribute (id, class, name, etc.) for disallowed names
2614
- for (var _b = 0, _c = Object.keys(attributes); _b < _c.length; _b++) {
2615
- var attribute = _c[_b];
2616
- field += attributes[attribute].toLowerCase();
2617
- }
2618
- for (var _d = 0, DISALLOWED_NAMES_1 = DISALLOWED_NAMES; _d < DISALLOWED_NAMES_1.length; _d++) {
2619
- var name_1 = DISALLOWED_NAMES_1[_d];
2620
- if (field.indexOf(name_1) >= 0) {
2621
- privacy = 2 /* Text */;
2622
- break;
2623
- }
2624
- }
2625
- }
2626
- else if (privacy === 1 /* Sensitive */) {
2627
- // Mask all input fields with an exception of type=submit; since they do not accept user input
2628
- privacy = attributes && attributes["type" /* Type */] === "submit" /* Submit */ ? 0 /* None */ : 2 /* Text */;
2629
- }
2630
- }
2631
- // Check for disallowed list of types (e.g. password, email, etc.) and set the masked property appropriately
2632
- if ("type" /* Type */ in attributes && DISALLOWED_TYPES.indexOf(attributes["type" /* Type */]) >= 0) {
2633
- privacy = 2 /* Text */;
2634
- }
2635
- // Following two conditions supersede any of the above. If there are explicit instructions to mask / unmask a field, we honor that.
2636
- if ("data-clarity-mask" /* MaskData */ in attributes) {
2637
- privacy = 3 /* TextImage */;
2508
+ switch (true) {
2509
+ case "data-clarity-mask" /* MaskData */ in attributes:
2510
+ metadata.privacy = 3 /* TextImage */;
2511
+ break;
2512
+ case "data-clarity-unmask" /* UnmaskData */ in attributes:
2513
+ metadata.privacy = 0 /* None */;
2514
+ break;
2515
+ case privacyMap.has(node):
2516
+ // If this node was explicitly configured to contain sensitive content, honor that privacy setting
2517
+ metadata.privacy = privacyMap.get(node);
2518
+ break;
2519
+ case fraudMap.has(node):
2520
+ // If this node was explicitly configured to be evaluated for fraud, then also mask content
2521
+ metadata.privacy = 2 /* Text */;
2522
+ break;
2523
+ case tag === "*T" /* TextTag */:
2524
+ // If it's a text node belonging to a STYLE or TITLE tag or one of SCRUB_EXCEPTIONS, then capture content
2525
+ var pTag = parent && parent.data ? parent.data.tag : "" /* Empty */;
2526
+ var pSelector_1 = parent && parent.selector ? parent.selector[0 /* Stable */] : "" /* Empty */;
2527
+ metadata.privacy = pTag === "STYLE" /* StyleTag */ || pTag === "TITLE" /* TitleTag */ || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* None */ : current;
2528
+ break;
2529
+ case "type" /* Type */ in attributes:
2530
+ // If this node has an explicit type assigned to it, go through masking rules to determine right privacy setting
2531
+ metadata.privacy = inspect(attributes["type" /* Type */], metadata);
2532
+ break;
2533
+ case tag === "INPUT" /* InputTag */ && current === 0 /* None */:
2534
+ // If even default privacy setting is to not mask, we still scan through input fields for any sensitive information
2535
+ var field_1 = "" /* Empty */;
2536
+ Object.keys(attributes).forEach(function (x) { return field_1 += attributes[x].toLowerCase(); });
2537
+ metadata.privacy = inspect(field_1, metadata);
2538
+ break;
2539
+ case current === 1 /* Sensitive */ && tag === "INPUT" /* InputTag */:
2540
+ // If it's a button or an input option, make an exception to disable masking
2541
+ metadata.privacy = maskDisable.indexOf(attributes["type" /* Type */]) >= 0 ? 0 /* None */ : current;
2542
+ break;
2543
+ case current === 1 /* Sensitive */:
2544
+ // In a mode where we mask sensitive information by default, look through class names to aggressively mask content
2545
+ metadata.privacy = inspect(attributes["class" /* Class */], metadata);
2546
+ break;
2547
+ default:
2548
+ metadata.privacy = parent ? parent.metadata.privacy : metadata.privacy;
2549
+ break;
2638
2550
  }
2639
- if ("data-clarity-unmask" /* UnmaskData */ in attributes) {
2640
- privacy = 0 /* None */;
2551
+ }
2552
+ function inspect(input, metadata) {
2553
+ if (input && maskText.some(function (x) { return input.indexOf(x) >= 0; })) {
2554
+ return 2 /* Text */;
2641
2555
  }
2642
- return privacy;
2556
+ return metadata.privacy;
2643
2557
  }
2644
2558
  function diff(a, b, field) {
2645
2559
  if (typeof a[field] === "object" && typeof b[field] === "object") {
@@ -2727,17 +2641,9 @@ function remove(id, source) {
2727
2641
  track$4(id, source);
2728
2642
  }
2729
2643
  }
2730
- function size(value, parent) {
2731
- var data = value.data;
2732
- var tag = data.tag;
2733
- // If this element is a text node, is masked, and longer than configured length, then track box model for the parent element
2734
- var isLongText = tag === "*T" /* TextTag */ && data.value && data.value.length > 15 /* ResizeObserverThreshold */;
2735
- var isMasked = value.metadata.privacy === 2 /* Text */ || value.metadata.privacy === 3 /* TextImage */;
2736
- if (isLongText && isMasked && parent && parent.metadata.size === null) {
2737
- parent.metadata.size = [];
2738
- }
2644
+ function size(value) {
2739
2645
  // If this element is a image node, and is masked, then track box model for the current element
2740
- if (data.tag === "IMG" /* ImageTag */ && value.metadata.privacy === 3 /* TextImage */) {
2646
+ if (value.data.tag === "IMG" /* ImageTag */ && value.metadata.privacy === 3 /* TextImage */) {
2741
2647
  value.metadata.size = [];
2742
2648
  }
2743
2649
  }
@@ -2946,18 +2852,23 @@ function link(node) {
2946
2852
  }
2947
2853
  return null;
2948
2854
  }
2949
- function metadata$2(node, event) {
2855
+ function metadata$2(node, event, text) {
2856
+ if (text === void 0) { text = null; }
2950
2857
  // If the node is null, we return a reserved value for id: 0. Valid assignment of id begins from 1+.
2951
2858
  var output = { id: 0, hash: null, privacy: 2 /* Text */, node: node };
2952
2859
  if (node) {
2953
2860
  var value = get(node);
2954
2861
  if (value !== null) {
2862
+ var metadata_1 = value.metadata;
2955
2863
  output.id = value.id;
2956
2864
  output.hash = value.hash;
2957
- output.privacy = value.metadata.privacy;
2865
+ output.privacy = metadata_1.privacy;
2958
2866
  if (value.region) {
2959
2867
  track$3(value.region, event);
2960
2868
  }
2869
+ if (metadata_1.fraud) {
2870
+ check$4(metadata_1.fraud, value.id, text || value.data.value);
2871
+ }
2961
2872
  }
2962
2873
  }
2963
2874
  return output;
@@ -2996,7 +2907,7 @@ function encode$3 (type) {
2996
2907
  case 9 /* Click */:
2997
2908
  for (_b = 0, _c = state$7; _b < _c.length; _b++) {
2998
2909
  entry = _c[_b];
2999
- cTarget = metadata$2(entry.data.target, entry.event);
2910
+ cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
3000
2911
  tokens = [entry.time, entry.event];
3001
2912
  cHash = cTarget.hash.join("." /* Dot */);
3002
2913
  tokens.push(cTarget.id);
@@ -3010,6 +2921,7 @@ function encode$3 (type) {
3010
2921
  tokens.push(scrub(entry.data.text, "click", cTarget.privacy));
3011
2922
  tokens.push(entry.data.link);
3012
2923
  tokens.push(cHash);
2924
+ tokens.push(entry.data.trust);
3013
2925
  queue(tokens);
3014
2926
  track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
3015
2927
  }
@@ -3045,10 +2957,10 @@ function encode$3 (type) {
3045
2957
  case 27 /* Input */:
3046
2958
  for (_f = 0, _g = state$5; _f < _g.length; _f++) {
3047
2959
  entry = _g[_f];
3048
- iTarget = metadata$2(entry.data.target, entry.event);
2960
+ iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
3049
2961
  tokens = [entry.time, entry.event];
3050
2962
  tokens.push(iTarget.id);
3051
- tokens.push(entry.data.value);
2963
+ tokens.push(scrub(entry.data.value, "input", iTarget.privacy));
3052
2964
  queue(tokens);
3053
2965
  }
3054
2966
  reset$f();
@@ -3223,7 +3135,7 @@ function queue(tokens, transmit) {
3223
3135
  // We enrich the data going out with the existing upload. In these cases, call to upload comes with 'transmit' set to false.
3224
3136
  if (transmit && timeout === null) {
3225
3137
  if (type !== 25 /* Ping */) {
3226
- reset$n();
3138
+ reset$m();
3227
3139
  }
3228
3140
  timeout = setTimeout(upload, gap);
3229
3141
  queuedTime = now;
@@ -3259,7 +3171,7 @@ function upload(final) {
3259
3171
  // Otherwise you run a risk of infinite loop.
3260
3172
  compute$6();
3261
3173
  compute$5();
3262
- compute$9();
3174
+ compute$8();
3263
3175
  last = final === true;
3264
3176
  e = JSON.stringify(envelope(last));
3265
3177
  a = "[" + analysis.join() + "]";
@@ -3451,14 +3363,6 @@ function handler(error) {
3451
3363
  stack: e.stack,
3452
3364
  source: error["filename"]
3453
3365
  };
3454
- // In certain cases, ResizeObserver could lead to flood of benign errors - especially when video element is involved.
3455
- // Reference Chromium issue: https://bugs.chromium.org/p/chromium/issues/detail?id=809574
3456
- // Even though it doesn't impact user experience, or show up in console, it can still flood error reporting through on error
3457
- // To mitigate that, we turn off Clarity's ResizeObserver on getting the first instance of this error
3458
- if (e.message.indexOf("ResizeObserver" /* ResizeObserver */) >= 0) {
3459
- stop$t();
3460
- return false;
3461
- }
3462
3366
  encode$2(31 /* ScriptError */);
3463
3367
  }
3464
3368
  return true;
@@ -3488,6 +3392,14 @@ function encode$2 (type) {
3488
3392
  queue(tokens, false);
3489
3393
  }
3490
3394
  break;
3395
+ case 41 /* Fraud */:
3396
+ if (data$d) {
3397
+ tokens.push(data$d.id);
3398
+ tokens.push(data$d.target);
3399
+ tokens.push(data$d.hash);
3400
+ queue(tokens, false);
3401
+ }
3402
+ break;
3491
3403
  }
3492
3404
  return [2 /*return*/];
3493
3405
  });
@@ -3678,7 +3590,7 @@ function encode$1 (event) {
3678
3590
  tokens.push(b.data.activityTime);
3679
3591
  queue(tokens, false);
3680
3592
  }
3681
- reset$p();
3593
+ reset$o();
3682
3594
  break;
3683
3595
  case 25 /* Ping */:
3684
3596
  tokens.push(data$h.gap);
@@ -3711,7 +3623,7 @@ function encode$1 (event) {
3711
3623
  tokens.push(v);
3712
3624
  tokens.push(data$e[v]);
3713
3625
  }
3714
- reset$l();
3626
+ reset$k();
3715
3627
  queue(tokens, false);
3716
3628
  }
3717
3629
  break;
@@ -3726,7 +3638,7 @@ function encode$1 (event) {
3726
3638
  // However, for data over the wire, we round it off to milliseconds precision.
3727
3639
  tokens.push(Math.round(updates$3[m]));
3728
3640
  }
3729
- reset$o();
3641
+ reset$n();
3730
3642
  queue(tokens, false);
3731
3643
  }
3732
3644
  break;
@@ -3752,7 +3664,7 @@ function encode$1 (event) {
3752
3664
  tokens.push(key);
3753
3665
  tokens.push([].concat.apply([], data$g[e]));
3754
3666
  }
3755
- reset$m();
3667
+ reset$l();
3756
3668
  queue(tokens, false);
3757
3669
  }
3758
3670
  break;
@@ -3838,10 +3750,9 @@ function reset$3() {
3838
3750
  }
3839
3751
 
3840
3752
  var data$2 = null;
3841
- var callback = null;
3753
+ var callbacks = [];
3842
3754
  var rootDomain = null;
3843
3755
  function start$9() {
3844
- callback = null;
3845
3756
  rootDomain = null;
3846
3757
  var ua = navigator && "userAgent" in navigator ? navigator.userAgent : "" /* Empty */;
3847
3758
  var title = document && document.title ? document.title : "" /* Empty */;
@@ -3867,7 +3778,6 @@ function start$9() {
3867
3778
  log(17 /* DocumentDirection */, document.dir);
3868
3779
  if (navigator) {
3869
3780
  log(9 /* Language */, navigator.userLanguage || navigator.language);
3870
- max(26 /* Automation */, navigator.webdriver ? 1 /* True */ : 0 /* False */);
3871
3781
  userAgentData();
3872
3782
  }
3873
3783
  // Metrics
@@ -3908,7 +3818,6 @@ function userAgentData() {
3908
3818
  }
3909
3819
  }
3910
3820
  function stop$8() {
3911
- callback = null;
3912
3821
  rootDomain = null;
3913
3822
  data$2 = null;
3914
3823
  }
@@ -3918,10 +3827,7 @@ function metadata(cb, wait) {
3918
3827
  // Immediately invoke the callback if the caller explicitly doesn't want to wait for the upgrade confirmation
3919
3828
  cb(data$2, !config$1.lean);
3920
3829
  }
3921
- else {
3922
- // Save the callback for future reference; so we can inform the caller when page gets upgraded and we have a valid playback flag
3923
- callback = cb;
3924
- }
3830
+ callbacks.push({ callback: cb, wait: wait });
3925
3831
  }
3926
3832
  function id() {
3927
3833
  return data$2 ? [data$2.userId, data$2.sessionId, data$2.pageNum].join("." /* Dot */) : "" /* Empty */;
@@ -3947,13 +3853,20 @@ function tab() {
3947
3853
  }
3948
3854
  function save() {
3949
3855
  var ts = Math.round(Date.now());
3950
- var upgrade = config$1.lean ? 0 /* False */ : 1 /* True */;
3951
3856
  var upload = config$1.upload && typeof config$1.upload === "string" /* String */ ? config$1.upload.replace("https://" /* HTTPS */, "" /* Empty */) : "" /* Empty */;
3952
- if (upgrade && callback) {
3953
- callback(data$2, !config$1.lean);
3954
- }
3857
+ var upgrade = config$1.lean ? 0 /* False */ : 1 /* True */;
3858
+ processCallback(upgrade);
3955
3859
  setCookie("_clsk" /* SessionKey */, [data$2.sessionId, ts, data$2.pageNum, upgrade, upload].join("|" /* Pipe */), 1 /* SessionExpire */);
3956
3860
  }
3861
+ function processCallback(upgrade) {
3862
+ if (callbacks.length > 0) {
3863
+ callbacks.forEach(function (x) {
3864
+ if (x.callback && (!x.wait || upgrade)) {
3865
+ x.callback(data$2, !config$1.lean);
3866
+ }
3867
+ });
3868
+ }
3869
+ }
3957
3870
  function supported(target, api) {
3958
3871
  try {
3959
3872
  return !!target[api];
@@ -4213,23 +4126,23 @@ function start$7() {
4213
4126
  // Add a proxy to history.pushState function
4214
4127
  if (pushState === null) {
4215
4128
  pushState = history.pushState;
4216
- }
4217
- history.pushState = function () {
4218
- if (check$1()) {
4129
+ history.pushState = function () {
4219
4130
  pushState.apply(this, arguments);
4220
- compute$1();
4221
- }
4222
- };
4131
+ if (active() && check$1()) {
4132
+ compute$1();
4133
+ }
4134
+ };
4135
+ }
4223
4136
  // Add a proxy to history.replaceState function
4224
4137
  if (replaceState === null) {
4225
4138
  replaceState = history.replaceState;
4226
- }
4227
- history.replaceState = function () {
4228
- if (check$1()) {
4139
+ history.replaceState = function () {
4229
4140
  replaceState.apply(this, arguments);
4230
- compute$1();
4231
- }
4232
- };
4141
+ if (active() && check$1()) {
4142
+ compute$1();
4143
+ }
4144
+ };
4145
+ }
4233
4146
  }
4234
4147
  function check$1() {
4235
4148
  if (count++ > 20 /* CallStackDepth */) {
@@ -4243,23 +4156,17 @@ function compute$1() {
4243
4156
  if (url !== getCurrentUrl()) {
4244
4157
  // If the url changed, start tracking it as a new page
4245
4158
  stop();
4246
- window.setTimeout(start, 250 /* RestartDelay */);
4159
+ window.setTimeout(restart$1, 250 /* RestartDelay */);
4247
4160
  }
4248
4161
  }
4162
+ function restart$1() {
4163
+ start();
4164
+ max(29 /* SinglePage */, 1 /* True */);
4165
+ }
4249
4166
  function getCurrentUrl() {
4250
4167
  return location.href ? location.href.replace(location.hash, "" /* Empty */) : location.href;
4251
4168
  }
4252
4169
  function stop$6() {
4253
- // Restore original function definition of history.pushState
4254
- if (pushState !== null) {
4255
- history.pushState = pushState;
4256
- pushState = null;
4257
- }
4258
- // Restore original function definition of history.replaceState
4259
- if (replaceState !== null) {
4260
- history.replaceState = replaceState;
4261
- replaceState = null;
4262
- }
4263
4170
  url = null;
4264
4171
  count = 0;
4265
4172
  }
@@ -4268,7 +4175,7 @@ var status = false;
4268
4175
  function start$6() {
4269
4176
  status = true;
4270
4177
  start$F();
4271
- reset$k();
4178
+ reset$j();
4272
4179
  reset$1();
4273
4180
  reset$2();
4274
4181
  start$7();
@@ -4277,8 +4184,8 @@ function stop$5() {
4277
4184
  stop$6();
4278
4185
  reset$2();
4279
4186
  reset$1();
4280
- reset$k();
4281
- stop$C();
4187
+ reset$j();
4188
+ stop$B();
4282
4189
  status = false;
4283
4190
  }
4284
4191
  function active() {
@@ -4332,6 +4239,7 @@ function restart() {
4332
4239
  }
4333
4240
 
4334
4241
  function start$5() {
4242
+ start$x();
4335
4243
  start$e();
4336
4244
  start$d();
4337
4245
  }
@@ -4359,14 +4267,14 @@ function discover() {
4359
4267
  case 0:
4360
4268
  ts = time();
4361
4269
  timer = { id: id(), cost: 3 /* LayoutCost */ };
4362
- start$x(timer);
4270
+ start$w(timer);
4363
4271
  return [4 /*yield*/, traverse(document, timer, 0 /* Discover */)];
4364
4272
  case 1:
4365
4273
  _a.sent();
4366
4274
  return [4 /*yield*/, encode$4(5 /* Discover */, timer, ts)];
4367
4275
  case 2:
4368
4276
  _a.sent();
4369
- stop$u(timer);
4277
+ stop$t(timer);
4370
4278
  return [2 /*return*/];
4371
4279
  }
4372
4280
  });
@@ -4381,13 +4289,11 @@ function start$3() {
4381
4289
  start$i();
4382
4290
  start$j();
4383
4291
  start$4();
4384
- start$w();
4385
4292
  }
4386
4293
  function stop$3() {
4387
4294
  stop$f();
4388
4295
  stop$g();
4389
4296
  stop$h();
4390
- stop$t();
4391
4297
  end();
4392
4298
  }
4393
4299
 
@@ -4515,7 +4421,11 @@ function process(entries) {
4515
4421
  compute(entry);
4516
4422
  break;
4517
4423
  case "resource" /* Resource */:
4518
- log(4 /* NetworkHosts */, host(entry.name));
4424
+ var name_1 = entry.name;
4425
+ log(4 /* NetworkHosts */, host(name_1));
4426
+ if (name_1 === config$1.upload || name_1 === config$1.fallback) {
4427
+ max(28 /* UploadTime */, entry.duration);
4428
+ }
4519
4429
  break;
4520
4430
  case "longtask" /* LongTask */:
4521
4431
  count$1(7 /* LongTaskCount */);
@@ -4538,6 +4448,11 @@ function process(entries) {
4538
4448
  break;
4539
4449
  }
4540
4450
  }
4451
+ if (performance && "memory" /* Memory */ in performance && performance["memory" /* Memory */].usedJSHeapSize) {
4452
+ // Track consumed memory (MBs) where "memory" API is available
4453
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory
4454
+ max(30 /* UsedMemory */, Math.abs(performance["memory" /* Memory */].usedJSHeapSize / 1048576 /* MegaByte */));
4455
+ }
4541
4456
  }
4542
4457
  function stop$2() {
4543
4458
  if (observer) {
@@ -4599,7 +4514,7 @@ function stop() {
4599
4514
  if (active()) {
4600
4515
  // Stop modules in the reverse order of their initialization
4601
4516
  modules.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
4602
- stop$v();
4517
+ stop$u();
4603
4518
  stop$5();
4604
4519
  }
4605
4520
  }