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.
package/build/clarity.js CHANGED
@@ -60,9 +60,8 @@ var dimension = /*#__PURE__*/Object.freeze({
60
60
  var metadata$1 = /*#__PURE__*/Object.freeze({
61
61
  __proto__: null,
62
62
  get data () { return data$2; },
63
- get callback () { return callback; },
63
+ get callbacks () { return callbacks; },
64
64
  get start () { return start$9; },
65
- get userAgentData () { return userAgentData; },
66
65
  get stop () { return stop$8; },
67
66
  get metadata () { return metadata; },
68
67
  get id () { return id; },
@@ -89,6 +88,7 @@ var config$1 = {
89
88
  regions: [],
90
89
  extract: [],
91
90
  cookies: [],
91
+ fraud: [],
92
92
  report: null,
93
93
  upload: null,
94
94
  fallback: null,
@@ -111,11 +111,11 @@ function time(ts) {
111
111
  ts = ts ? ts : performance.now();
112
112
  return Math.max(Math.round(ts - startTime), 0);
113
113
  }
114
- function stop$C() {
114
+ function stop$B() {
115
115
  startTime = 0;
116
116
  }
117
117
 
118
- var version$1 = "0.6.33";
118
+ var version$1 = "0.6.36";
119
119
 
120
120
  // tslint:disable: no-bitwise
121
121
  function hash (input) {
@@ -142,9 +142,9 @@ var buffer = null;
142
142
  var update$2 = false;
143
143
  function start$E() {
144
144
  update$2 = false;
145
- reset$p();
145
+ reset$o();
146
146
  }
147
- function reset$p() {
147
+ function reset$o() {
148
148
  // Baseline state holds the previous values - if it is updated in the current payload,
149
149
  // reset the state to current value after sending the previous state
150
150
  if (update$2) {
@@ -206,25 +206,25 @@ function visibility(t, visible) {
206
206
  }
207
207
  update$2 = true;
208
208
  }
209
- function compute$d() {
209
+ function compute$c() {
210
210
  if (update$2) {
211
211
  encode$1(4 /* Baseline */);
212
212
  }
213
213
  }
214
- function stop$B() {
215
- reset$p();
214
+ function stop$A() {
215
+ reset$o();
216
216
  }
217
217
 
218
218
  var baseline = /*#__PURE__*/Object.freeze({
219
219
  __proto__: null,
220
220
  get state () { return state$9; },
221
221
  start: start$E,
222
- reset: reset$p,
222
+ reset: reset$o,
223
223
  track: track$7,
224
224
  activity: activity,
225
225
  visibility: visibility,
226
- compute: compute$d,
227
- stop: stop$B
226
+ compute: compute$c,
227
+ stop: stop$A
228
228
  });
229
229
 
230
230
  var data$j = null;
@@ -248,20 +248,19 @@ function start$D() {
248
248
  updates$3 = {};
249
249
  count$1(5 /* InvokeCount */);
250
250
  }
251
- function stop$A() {
251
+ function stop$z() {
252
252
  data$i = {};
253
253
  updates$3 = {};
254
254
  }
255
- function count$1(metric, increment) {
256
- if (increment === void 0) { increment = 1; }
255
+ function count$1(metric) {
257
256
  if (!(metric in data$i)) {
258
257
  data$i[metric] = 0;
259
258
  }
260
259
  if (!(metric in updates$3)) {
261
260
  updates$3[metric] = 0;
262
261
  }
263
- data$i[metric] += increment;
264
- updates$3[metric] += increment;
262
+ data$i[metric]++;
263
+ updates$3[metric]++;
265
264
  }
266
265
  function sum(metric, value) {
267
266
  if (value !== null) {
@@ -287,10 +286,10 @@ function max(metric, value) {
287
286
  }
288
287
  }
289
288
  }
290
- function compute$c() {
289
+ function compute$b() {
291
290
  encode$1(0 /* Metric */);
292
291
  }
293
- function reset$o() {
292
+ function reset$n() {
294
293
  updates$3 = {};
295
294
  }
296
295
 
@@ -309,7 +308,7 @@ function start$C() {
309
308
  interval = 60000 /* PingInterval */;
310
309
  last = 0;
311
310
  }
312
- function reset$n() {
311
+ function reset$m() {
313
312
  if (timeout$6) {
314
313
  clearTimeout(timeout$6);
315
314
  }
@@ -327,7 +326,7 @@ function ping() {
327
326
  suspend();
328
327
  }
329
328
  }
330
- function stop$z() {
329
+ function stop$y() {
331
330
  clearTimeout(timeout$6);
332
331
  last = 0;
333
332
  interval = 0;
@@ -337,15 +336,15 @@ var ping$1 = /*#__PURE__*/Object.freeze({
337
336
  __proto__: null,
338
337
  get data () { return data$h; },
339
338
  start: start$C,
340
- reset: reset$n,
341
- stop: stop$z
339
+ reset: reset$m,
340
+ stop: stop$y
342
341
  });
343
342
 
344
343
  var data$g = null;
345
344
  function start$B() {
346
345
  data$g = {};
347
346
  }
348
- function stop$y() {
347
+ function stop$x() {
349
348
  data$g = {};
350
349
  }
351
350
  function track$6(event, time) {
@@ -365,10 +364,10 @@ function track$6(event, time) {
365
364
  }
366
365
  }
367
366
  }
368
- function compute$b() {
367
+ function compute$a() {
369
368
  encode$1(36 /* Summary */);
370
369
  }
371
- function reset$m() {
370
+ function reset$l() {
372
371
  data$g = {};
373
372
  }
374
373
 
@@ -376,10 +375,10 @@ var summary = /*#__PURE__*/Object.freeze({
376
375
  __proto__: null,
377
376
  get data () { return data$g; },
378
377
  start: start$B,
379
- stop: stop$y,
378
+ stop: stop$x,
380
379
  track: track$6,
381
- compute: compute$b,
382
- reset: reset$m
380
+ compute: compute$a,
381
+ reset: reset$l
383
382
  });
384
383
 
385
384
  var data$f = null;
@@ -407,7 +406,7 @@ function upgrade(key) {
407
406
  encode$1(3 /* Upgrade */);
408
407
  }
409
408
  }
410
- function stop$x() {
409
+ function stop$w() {
411
410
  data$f = null;
412
411
  }
413
412
 
@@ -416,12 +415,12 @@ var upgrade$1 = /*#__PURE__*/Object.freeze({
416
415
  get data () { return data$f; },
417
416
  start: start$A,
418
417
  upgrade: upgrade,
419
- stop: stop$x
418
+ stop: stop$w
420
419
  });
421
420
 
422
421
  var data$e = null;
423
422
  function start$z() {
424
- reset$l();
423
+ reset$k();
425
424
  }
426
425
  function set(variable, value) {
427
426
  var values = typeof value === "string" /* String */ ? [value] : value;
@@ -449,14 +448,14 @@ function log$2(variable, value) {
449
448
  data$e[variable] = validValues;
450
449
  }
451
450
  }
452
- function compute$a() {
451
+ function compute$9() {
453
452
  encode$1(34 /* Variable */);
454
453
  }
455
- function reset$l() {
454
+ function reset$k() {
456
455
  data$e = {};
457
456
  }
458
- function stop$w() {
459
- reset$l();
457
+ function stop$v() {
458
+ reset$k();
460
459
  }
461
460
 
462
461
  var variable = /*#__PURE__*/Object.freeze({
@@ -465,9 +464,9 @@ var variable = /*#__PURE__*/Object.freeze({
465
464
  start: start$z,
466
465
  set: set,
467
466
  identify: identify,
468
- compute: compute$a,
469
- reset: reset$l,
470
- stop: stop$w
467
+ compute: compute$9,
468
+ reset: reset$k,
469
+ stop: stop$v
471
470
  });
472
471
 
473
472
  /*! *****************************************************************************
@@ -587,20 +586,20 @@ function start$y() {
587
586
  start$D();
588
587
  modules$1.forEach(function (x) { return measure(x.start)(); });
589
588
  }
590
- function stop$v() {
589
+ function stop$u() {
591
590
  // Stop modules in the reverse order of their initialization
592
591
  // The ordering below should respect inter-module dependency.
593
592
  // E.g. if upgrade depends on upload, then upgrade needs to end before upload.
594
593
  // Similarly, if upload depends on metadata, upload needs to end before metadata.
595
594
  modules$1.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
596
- stop$A();
595
+ stop$z();
597
596
  }
598
- function compute$9() {
599
- compute$a();
600
- compute$d();
601
- compute$2();
597
+ function compute$8() {
598
+ compute$9();
602
599
  compute$c();
600
+ compute$2();
603
601
  compute$b();
602
+ compute$a();
604
603
  compute$3();
605
604
  compute$4();
606
605
  }
@@ -701,6 +700,24 @@ function mutate(array, start, end) {
701
700
  }
702
701
  }
703
702
 
703
+ var history$5 = [];
704
+ var data$d;
705
+ function start$x() {
706
+ history$5 = [];
707
+ max(26 /* Automation */, navigator.webdriver ? 1 /* True */ : 0 /* False */);
708
+ }
709
+ function check$4(id, target, input) {
710
+ // Compute hash for fraud detection. Hash is computed only if input meets the minimum length criteria
711
+ if (id !== null && input && input.length >= 5 /* WordLength */) {
712
+ data$d = { id: id, target: target, hash: hash(input) };
713
+ // Only encode this event if we haven't already reported this hash
714
+ if (history$5.indexOf(data$d.hash) < 0) {
715
+ history$5.push(data$d.hash);
716
+ encode$2(41 /* Fraud */);
717
+ }
718
+ }
719
+ }
720
+
704
721
  var TAGS = ["DIV", "TR", "P", "LI", "UL", "A", "BUTTON"];
705
722
  function selector (input, beta) {
706
723
  if (beta === void 0) { beta = false; }
@@ -785,7 +802,7 @@ function resume$1() {
785
802
  }
786
803
  }
787
804
  }
788
- function reset$k() {
805
+ function reset$j() {
789
806
  tracker = {};
790
807
  queuedTasks = [];
791
808
  activeTask = null;
@@ -855,20 +872,20 @@ function state$8(timer) {
855
872
  // If this task is no longer being tracked, send stop message to the caller
856
873
  return 2 /* Stop */;
857
874
  }
858
- function start$x(timer) {
875
+ function start$w(timer) {
859
876
  tracker[key(timer)] = { start: performance.now(), calls: 0, yield: 30 /* LongTask */ };
860
877
  }
861
- function restart$1(timer) {
878
+ function restart$2(timer) {
862
879
  var id = key(timer);
863
880
  if (tracker && tracker[id]) {
864
881
  var c = tracker[id].calls;
865
882
  var y = tracker[id].yield;
866
- start$x(timer);
883
+ start$w(timer);
867
884
  tracker[id].calls = c + 1;
868
885
  tracker[id].yield = y;
869
886
  }
870
887
  }
871
- function stop$u(timer) {
888
+ function stop$t(timer) {
872
889
  var end = performance.now();
873
890
  var id = key(timer);
874
891
  var duration = end - tracker[id].start;
@@ -888,12 +905,12 @@ function suspend$1(timer) {
888
905
  case 0:
889
906
  id = key(timer);
890
907
  if (!(id in tracker)) return [3 /*break*/, 2];
891
- stop$u(timer);
908
+ stop$t(timer);
892
909
  _a = tracker[id];
893
910
  return [4 /*yield*/, wait()];
894
911
  case 1:
895
912
  _a.yield = (_b.sent()).timeRemaining();
896
- restart$1(timer);
913
+ restart$2(timer);
897
914
  _b.label = 2;
898
915
  case 2:
899
916
  // After we are done with suspending task, ensure that we are still operating in the right context
@@ -1000,91 +1017,13 @@ function tokenize (tokens) {
1000
1017
  return output;
1001
1018
  }
1002
1019
 
1003
- var data$d = [];
1004
- var enabled = false;
1005
- var observer$2 = null;
1006
- function start$w() {
1007
- reset$j();
1008
- observer$2 = null;
1009
- enabled = window["ResizeObserver"] ? true : false;
1010
- }
1011
- function compute$8(id) {
1012
- if (enabled === false) {
1013
- return;
1014
- }
1015
- observer$2 = observer$2 === null ? new ResizeObserver(handler$4) : observer$2;
1016
- if (observer$2) {
1017
- var value = getValue(id);
1018
- // If this is the first time computing size for this node, go ahead and wire up ResizeObserver
1019
- // In all other cases, value.metadata.size will be null or an array with two elements [width, height]
1020
- // And, in those cases, we will skip through the following section and not attach the observer
1021
- if (value && value.metadata.size !== null && value.metadata.size.length === 0) {
1022
- var node = getNode(id);
1023
- if (node && node.nodeType === Node.ELEMENT_NODE) {
1024
- var e = node;
1025
- var r = e.getBoundingClientRect();
1026
- value.metadata.size = [Math.floor(r.width * 100 /* BoxPrecision */), Math.floor(r.height * 100 /* BoxPrecision */)];
1027
- observer$2.observe(e);
1028
- }
1029
- }
1030
- }
1031
- }
1032
- function handler$4(entries) {
1033
- window.requestAnimationFrame(function () {
1034
- for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
1035
- var entry = entries_1[_i];
1036
- var target = entry.target;
1037
- var id = target ? getId(target) : null;
1038
- if (id) {
1039
- var v = getValue(id);
1040
- var s = v.metadata.size;
1041
- var b = entry.borderBoxSize;
1042
- var w = null;
1043
- var h = null;
1044
- // Check if browser supports borderBoxSize property on ResizeObserverEntry object
1045
- // Otherwise, fall back to using getBoundingClientRect() to be cross browser compatible
1046
- // Reference: https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserverEntry/borderBoxSize
1047
- if (b && b.length > 0) {
1048
- w = Math.floor(b[0].inlineSize * 100 /* BoxPrecision */);
1049
- h = Math.floor(b[0].blockSize * 100 /* BoxPrecision */);
1050
- }
1051
- else {
1052
- var r = target.getBoundingClientRect();
1053
- w = Math.floor(r.width * 100 /* BoxPrecision */);
1054
- h = Math.floor(r.height * 100 /* BoxPrecision */);
1055
- }
1056
- // Capture new width & height only if they are different from what we have in in-memory cache
1057
- if (w !== s[0] && h !== s[1]) {
1058
- s = [w, h];
1059
- data$d.push({ id: id, width: w, height: h });
1060
- }
1061
- }
1062
- }
1063
- // Schedule encode only when we have at least one valid data entry
1064
- if (data$d.length > 0) {
1065
- encode$4(37 /* Box */);
1066
- }
1067
- });
1068
- }
1069
- function reset$j() {
1070
- data$d = [];
1071
- }
1072
- function stop$t() {
1073
- reset$j();
1074
- if (observer$2) {
1075
- observer$2.disconnect();
1076
- observer$2 = null;
1077
- }
1078
- enabled = false;
1079
- }
1080
-
1081
1020
  function encode$4 (type, timer, ts) {
1082
1021
  if (timer === void 0) { timer = null; }
1083
1022
  if (ts === void 0) { ts = null; }
1084
1023
  return __awaiter(this, void 0, void 0, function () {
1085
- 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;
1086
- return __generator(this, function (_f) {
1087
- switch (_f.label) {
1024
+ 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;
1025
+ return __generator(this, function (_e) {
1026
+ switch (_e.label) {
1088
1027
  case 0:
1089
1028
  eventTime = ts || time();
1090
1029
  tokens = [eventTime, type];
@@ -1092,18 +1031,17 @@ function encode$4 (type, timer, ts) {
1092
1031
  switch (_a) {
1093
1032
  case 8 /* Document */: return [3 /*break*/, 1];
1094
1033
  case 7 /* Region */: return [3 /*break*/, 2];
1095
- case 37 /* Box */: return [3 /*break*/, 3];
1096
- case 5 /* Discover */: return [3 /*break*/, 4];
1097
- case 6 /* Mutation */: return [3 /*break*/, 4];
1034
+ case 5 /* Discover */: return [3 /*break*/, 3];
1035
+ case 6 /* Mutation */: return [3 /*break*/, 3];
1098
1036
  }
1099
- return [3 /*break*/, 11];
1037
+ return [3 /*break*/, 10];
1100
1038
  case 1:
1101
1039
  d = data$c;
1102
1040
  tokens.push(d.width);
1103
1041
  tokens.push(d.height);
1104
1042
  track$7(type, d.width, d.height);
1105
1043
  queue(tokens);
1106
- return [3 /*break*/, 11];
1044
+ return [3 /*break*/, 10];
1107
1045
  case 2:
1108
1046
  for (_i = 0, _b = state$1; _i < _b.length; _i++) {
1109
1047
  r = _b[_i];
@@ -1115,39 +1053,28 @@ function encode$4 (type, timer, ts) {
1115
1053
  queue(tokens);
1116
1054
  }
1117
1055
  reset$6();
1118
- return [3 /*break*/, 11];
1056
+ return [3 /*break*/, 10];
1119
1057
  case 3:
1120
- b = data$d;
1121
- for (_c = 0, b_1 = b; _c < b_1.length; _c++) {
1122
- entry = b_1[_c];
1123
- tokens.push(entry.id);
1124
- tokens.push(entry.width);
1125
- tokens.push(entry.height);
1126
- }
1127
- reset$j();
1128
- queue(tokens);
1129
- return [3 /*break*/, 11];
1130
- case 4:
1131
1058
  // Check if we are operating within the context of the current page
1132
1059
  if (state$8(timer) === 2 /* Stop */) {
1133
- return [3 /*break*/, 11];
1060
+ return [3 /*break*/, 10];
1134
1061
  }
1135
1062
  values = updates$2();
1136
- if (!(values.length > 0)) return [3 /*break*/, 10];
1137
- _d = 0, values_1 = values;
1138
- _f.label = 5;
1139
- case 5:
1140
- if (!(_d < values_1.length)) return [3 /*break*/, 9];
1141
- value = values_1[_d];
1063
+ if (!(values.length > 0)) return [3 /*break*/, 9];
1064
+ _c = 0, values_1 = values;
1065
+ _e.label = 4;
1066
+ case 4:
1067
+ if (!(_c < values_1.length)) return [3 /*break*/, 8];
1068
+ value = values_1[_c];
1142
1069
  state = state$8(timer);
1143
- if (!(state === 0 /* Wait */)) return [3 /*break*/, 7];
1070
+ if (!(state === 0 /* Wait */)) return [3 /*break*/, 6];
1144
1071
  return [4 /*yield*/, suspend$1(timer)];
1072
+ case 5:
1073
+ state = _e.sent();
1074
+ _e.label = 6;
1145
1075
  case 6:
1146
- state = _f.sent();
1147
- _f.label = 7;
1148
- case 7:
1149
1076
  if (state === 2 /* Stop */) {
1150
- return [3 /*break*/, 9];
1077
+ return [3 /*break*/, 8];
1151
1078
  }
1152
1079
  data = value.data;
1153
1080
  active = value.metadata.active;
@@ -1155,13 +1082,12 @@ function encode$4 (type, timer, ts) {
1155
1082
  privacy = value.metadata.privacy;
1156
1083
  mangle = shouldMangle(value);
1157
1084
  keys = active ? ["tag", "attributes", "value"] : ["tag"];
1158
- compute$8(value.id);
1159
- for (_e = 0, keys_1 = keys; _e < keys_1.length; _e++) {
1160
- key = keys_1[_e];
1085
+ for (_d = 0, keys_1 = keys; _d < keys_1.length; _d++) {
1086
+ key = keys_1[_d];
1161
1087
  if (data[key]) {
1162
1088
  switch (key) {
1163
1089
  case "tag":
1164
- size = value.metadata.size;
1090
+ box = size$1(value);
1165
1091
  factor = mangle ? -1 : 1;
1166
1092
  tokens.push(value.id * factor);
1167
1093
  if (value.parent && active) {
@@ -1171,8 +1097,8 @@ function encode$4 (type, timer, ts) {
1171
1097
  tokens.push(value.previous);
1172
1098
  }
1173
1099
  tokens.push(suspend ? "*M" /* SuspendMutationTag */ : data[key]);
1174
- if (size && size.length === 2) {
1175
- tokens.push("" + "#" /* Box */ + str$1(size[0]) + "." + str$1(size[1]));
1100
+ if (box && box.length === 2) {
1101
+ tokens.push("" + "#" /* Box */ + str$1(box[0]) + "." + str$1(box[1]));
1176
1102
  }
1177
1103
  break;
1178
1104
  case "attributes":
@@ -1183,23 +1109,24 @@ function encode$4 (type, timer, ts) {
1183
1109
  }
1184
1110
  break;
1185
1111
  case "value":
1112
+ check$4(value.metadata.fraud, value.id, data[key]);
1186
1113
  tokens.push(scrub(data[key], data.tag, privacy, mangle));
1187
1114
  break;
1188
1115
  }
1189
1116
  }
1190
1117
  }
1191
- _f.label = 8;
1118
+ _e.label = 7;
1119
+ case 7:
1120
+ _c++;
1121
+ return [3 /*break*/, 4];
1192
1122
  case 8:
1193
- _d++;
1194
- return [3 /*break*/, 5];
1195
- case 9:
1196
1123
  if (type === 6 /* Mutation */) {
1197
1124
  activity(eventTime);
1198
1125
  }
1199
1126
  queue(tokenize(tokens), !config$1.lean);
1200
- _f.label = 10;
1201
- case 10: return [3 /*break*/, 11];
1202
- case 11: return [2 /*return*/];
1127
+ _e.label = 9;
1128
+ case 9: return [3 /*break*/, 10];
1129
+ case 10: return [2 /*return*/];
1203
1130
  }
1204
1131
  });
1205
1132
  });
@@ -1208,6 +1135,15 @@ function shouldMangle(value) {
1208
1135
  var privacy = value.metadata.privacy;
1209
1136
  return value.data.tag === "*T" /* TextTag */ && !(privacy === 0 /* None */ || privacy === 1 /* Sensitive */);
1210
1137
  }
1138
+ function size$1(value) {
1139
+ if (value.metadata.size !== null && value.metadata.size.length === 0) {
1140
+ var img = getNode(value.id);
1141
+ if (img) {
1142
+ return [Math.floor(img.offsetWidth * 100 /* BoxPrecision */), Math.floor(img.offsetHeight * 100 /* BoxPrecision */)];
1143
+ }
1144
+ }
1145
+ return value.metadata.size;
1146
+ }
1211
1147
  function str$1(input) {
1212
1148
  return input.toString(36);
1213
1149
  }
@@ -1316,7 +1252,8 @@ function handler$3(event, root, evt) {
1316
1252
  context: context(a),
1317
1253
  text: text(t),
1318
1254
  link: a ? a.href : null,
1319
- hash: null
1255
+ hash: null,
1256
+ trust: evt.isTrusted ? 1 /* True */ : 0 /* False */
1320
1257
  }
1321
1258
  });
1322
1259
  schedule$1(encode$3.bind(this, event));
@@ -1415,18 +1352,12 @@ function recompute$6(evt) {
1415
1352
  var input = target(evt);
1416
1353
  var value = get(input);
1417
1354
  if (input && input.type && value) {
1418
- var v = void 0;
1355
+ var v = input.value;
1419
1356
  switch (input.type) {
1420
1357
  case "radio":
1421
1358
  case "checkbox":
1422
1359
  v = input.checked ? "true" : "false";
1423
1360
  break;
1424
- case "range":
1425
- v = input.value;
1426
- break;
1427
- default:
1428
- v = scrub(input.value, "input", value.metadata.privacy);
1429
- break;
1430
1361
  }
1431
1362
  var data = { target: input, value: v };
1432
1363
  // 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.
@@ -1836,7 +1767,7 @@ function num$1(input, scale) {
1836
1767
  return null;
1837
1768
  }
1838
1769
 
1839
- var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror"];
1770
+ var IGNORE_ATTRIBUTES = ["title", "alt", "onload", "onfocus", "onerror", "data-drupal-form-submit-last"];
1840
1771
  var newlineRegex = /[\r\n]+/g;
1841
1772
  function processNode (node, source) {
1842
1773
  var child = null;
@@ -2101,37 +2032,46 @@ function start$j() {
2101
2032
  timeout$1 = null;
2102
2033
  activePeriod = 0;
2103
2034
  history$4 = {};
2035
+ // Some popular open source libraries, like styled-components, optimize performance
2036
+ // by injecting CSS using insertRule API vs. appending text node. A side effect of
2037
+ // using javascript API is that it doesn't trigger DOM mutation and therefore we
2038
+ // need to override the insertRule API and listen for changes manually.
2104
2039
  if (insertRule === null) {
2105
2040
  insertRule = CSSStyleSheet.prototype.insertRule;
2041
+ CSSStyleSheet.prototype.insertRule = function () {
2042
+ if (active()) {
2043
+ schedule(this.ownerNode);
2044
+ }
2045
+ return insertRule.apply(this, arguments);
2046
+ };
2106
2047
  }
2107
2048
  if (deleteRule === null) {
2108
2049
  deleteRule = CSSStyleSheet.prototype.deleteRule;
2050
+ CSSStyleSheet.prototype.deleteRule = function () {
2051
+ if (active()) {
2052
+ schedule(this.ownerNode);
2053
+ }
2054
+ return deleteRule.apply(this, arguments);
2055
+ };
2109
2056
  }
2110
- if (attachShadow === null) {
2111
- attachShadow = Element.prototype.attachShadow;
2112
- }
2113
- // Some popular open source libraries, like styled-components, optimize performance
2114
- // by injecting CSS using insertRule API vs. appending text node. A side effect of
2115
- // using javascript API is that it doesn't trigger DOM mutation and therefore we
2116
- // need to override the insertRule API and listen for changes manually.
2117
- CSSStyleSheet.prototype.insertRule = function () {
2118
- schedule(this.ownerNode);
2119
- return insertRule.apply(this, arguments);
2120
- };
2121
- CSSStyleSheet.prototype.deleteRule = function () {
2122
- schedule(this.ownerNode);
2123
- return deleteRule.apply(this, arguments);
2124
- };
2125
2057
  // Add a hook to attachShadow API calls
2126
2058
  // In case we are unable to add a hook and browser throws an exception,
2127
2059
  // reset attachShadow variable and resume processing like before
2128
- try {
2129
- Element.prototype.attachShadow = function () {
2130
- return schedule(attachShadow.apply(this, arguments));
2131
- };
2132
- }
2133
- catch (_a) {
2134
- attachShadow = null;
2060
+ if (attachShadow === null) {
2061
+ attachShadow = Element.prototype.attachShadow;
2062
+ try {
2063
+ Element.prototype.attachShadow = function () {
2064
+ if (active()) {
2065
+ return schedule(attachShadow.apply(this, arguments));
2066
+ }
2067
+ else {
2068
+ return attachShadow.apply(this, arguments);
2069
+ }
2070
+ };
2071
+ }
2072
+ catch (_a) {
2073
+ attachShadow = null;
2074
+ }
2135
2075
  }
2136
2076
  }
2137
2077
  function observe$2(node) {
@@ -2167,21 +2107,6 @@ function stop$h() {
2167
2107
  }
2168
2108
  }
2169
2109
  observers = [];
2170
- // Restoring original insertRule
2171
- if (insertRule !== null) {
2172
- CSSStyleSheet.prototype.insertRule = insertRule;
2173
- insertRule = null;
2174
- }
2175
- // Restoring original deleteRule
2176
- if (deleteRule !== null) {
2177
- CSSStyleSheet.prototype.deleteRule = deleteRule;
2178
- deleteRule = null;
2179
- }
2180
- // Restoring original attachShadow
2181
- if (attachShadow != null) {
2182
- Element.prototype.attachShadow = attachShadow;
2183
- attachShadow = null;
2184
- }
2185
2110
  history$4 = {};
2186
2111
  mutations = [];
2187
2112
  queue$2 = [];
@@ -2197,7 +2122,7 @@ function handle$1(m) {
2197
2122
  track$6(6 /* Mutation */, now);
2198
2123
  mutations.push({ time: now, mutations: m });
2199
2124
  schedule$1(process$2, 1 /* High */).then(function () {
2200
- measure(compute$7)();
2125
+ setTimeout(compute$7);
2201
2126
  measure(compute$6)();
2202
2127
  });
2203
2128
  }
@@ -2208,7 +2133,7 @@ function process$2() {
2208
2133
  switch (_b.label) {
2209
2134
  case 0:
2210
2135
  timer = { id: id(), cost: 3 /* LayoutCost */ };
2211
- start$x(timer);
2136
+ start$w(timer);
2212
2137
  _b.label = 1;
2213
2138
  case 1:
2214
2139
  if (!(mutations.length > 0)) return [3 /*break*/, 8];
@@ -2263,7 +2188,7 @@ function process$2() {
2263
2188
  _b.sent();
2264
2189
  return [3 /*break*/, 1];
2265
2190
  case 8:
2266
- stop$u(timer);
2191
+ stop$t(timer);
2267
2192
  return [2 /*return*/];
2268
2193
  }
2269
2194
  });
@@ -2390,10 +2315,6 @@ function generate(target, type) {
2390
2315
  }
2391
2316
 
2392
2317
  var index = 1;
2393
- // Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#%3Cinput%3E_types
2394
- var DISALLOWED_TYPES = ["password", "hidden", "email", "tel"];
2395
- var DISALLOWED_NAMES = ["addr", "cell", "code", "dob", "email", "mob", "name", "phone", "secret", "social", "ssn", "tel", "zip", "pass", "card", "account", "cvv", "ccv"];
2396
- var DISALLOWED_MATCH = ["address", "password", "contact"];
2397
2318
  var nodes = [];
2398
2319
  var values = [];
2399
2320
  var updateMap = [];
@@ -2401,10 +2322,13 @@ var hashMap = {};
2401
2322
  var override = [];
2402
2323
  var unmask = [];
2403
2324
  var updatedFragments = {};
2325
+ var maskText = [];
2326
+ var maskDisable = [];
2404
2327
  // The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced
2405
2328
  var idMap = null; // Maps node => id.
2406
2329
  var iframeMap = null; // Maps iframe's contentDocument => parent iframe element
2407
2330
  var privacyMap = null; // Maps node => Privacy (enum)
2331
+ var fraudMap = null; // Maps node => FraudId (number)
2408
2332
  function start$i() {
2409
2333
  reset$7();
2410
2334
  parse$1(document, true);
@@ -2420,9 +2344,12 @@ function reset$7() {
2420
2344
  hashMap = {};
2421
2345
  override = [];
2422
2346
  unmask = [];
2347
+ 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 */);
2348
+ maskDisable = "radio,checkbox,range,button,reset,submit" /* Disable */.split("," /* Comma */);
2423
2349
  idMap = new WeakMap();
2424
2350
  iframeMap = new WeakMap();
2425
2351
  privacyMap = new WeakMap();
2352
+ fraudMap = new WeakMap();
2426
2353
  }
2427
2354
  // We parse new root nodes for any regions or masked nodes in the beginning (document) and
2428
2355
  // later whenever there are new additions or modifications to DOM (mutations)
@@ -2440,6 +2367,7 @@ function parse$1(root, init) {
2440
2367
  if ("querySelectorAll" in root) {
2441
2368
  config$1.regions.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return observe$1(e, "" + x[0]); }); }); // Regions
2442
2369
  config$1.mask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 3 /* TextImage */); }); }); // Masked Elements
2370
+ config$1.fraud.forEach(function (x) { return root.querySelectorAll(x[1]).forEach(function (e) { return fraudMap.set(e, x[0]); }); }); // Fraud Check
2443
2371
  unmask.forEach(function (x) { return root.querySelectorAll(x).forEach(function (e) { return privacyMap.set(e, 0 /* None */); }); }); // Unmasked Elements
2444
2372
  }
2445
2373
  }
@@ -2463,19 +2391,18 @@ function add(node, parent, data, source) {
2463
2391
  var id = getId(node, true);
2464
2392
  var parentId = parent ? getId(parent) : null;
2465
2393
  var previousId = getPreviousId(node);
2466
- var privacy = config$1.content ? 1 /* Sensitive */ : 2 /* Text */;
2467
2394
  var parentValue = null;
2468
2395
  var regionId = exists(node) ? id : null;
2469
2396
  var fragmentId = null;
2397
+ var fraudId = fraudMap.has(node) ? fraudMap.get(node) : null;
2398
+ var privacyId = config$1.content ? 1 /* Sensitive */ : 2 /* Text */;
2470
2399
  if (parentId >= 0 && values[parentId]) {
2471
2400
  parentValue = values[parentId];
2472
2401
  parentValue.children.push(id);
2473
2402
  regionId = regionId === null ? parentValue.region : regionId;
2474
2403
  fragmentId = parentValue.fragment;
2475
- privacy = parentValue.metadata.privacy;
2404
+ fraudId = fraudId === null ? parentValue.metadata.fraud : fraudId;
2476
2405
  }
2477
- // Check to see if this particular node should be masked or not
2478
- privacy = getPrivacy(node, data, parentValue, privacy);
2479
2406
  // If there's an explicit region attribute set on the element, use it to mark a region on the page
2480
2407
  if (data.attributes && "data-clarity-region" /* RegionData */ in data.attributes) {
2481
2408
  observe$1(node, data.attributes["data-clarity-region" /* RegionData */]);
@@ -2491,11 +2418,12 @@ function add(node, parent, data, source) {
2491
2418
  selector: null,
2492
2419
  hash: null,
2493
2420
  region: regionId,
2494
- metadata: { active: true, suspend: false, privacy: privacy, position: null, size: null },
2421
+ metadata: { active: true, suspend: false, privacy: privacyId, position: null, fraud: fraudId, size: null },
2495
2422
  fragment: fragmentId,
2496
2423
  };
2424
+ privacy(node, values[id], parentValue);
2497
2425
  updateSelector(values[id]);
2498
- size(values[id], parentValue);
2426
+ size(values[id]);
2499
2427
  track$4(id, source, values[id].fragment);
2500
2428
  }
2501
2429
  function update$1(node, parent, data, source) {
@@ -2575,75 +2503,61 @@ function iframe(node) {
2575
2503
  var doc = node.nodeType === Node.DOCUMENT_NODE ? node : null;
2576
2504
  return doc && iframeMap.has(doc) ? iframeMap.get(doc) : null;
2577
2505
  }
2578
- function getPrivacy(node, data, parent, privacy) {
2579
- var attributes = data.attributes;
2506
+ function privacy(node, value, parent) {
2507
+ var data = value.data;
2508
+ var metadata = value.metadata;
2509
+ var current = metadata.privacy;
2510
+ var attributes = data.attributes || {};
2580
2511
  var tag = data.tag.toUpperCase();
2581
- // If this node was explicitly configured to contain sensitive content, use that information and return the value
2582
- if (privacyMap.has(node)) {
2583
- return privacyMap.get(node);
2584
- }
2585
- // If it's a text node belonging to a STYLE or TITLE tag;
2586
- // Or, the text node belongs to one of SCRUB_EXCEPTIONS
2587
- // then reset the privacy setting to ensure we capture the content
2588
- if (tag === "*T" /* TextTag */ && parent && parent.data) {
2589
- var path = parent.selector ? parent.selector[0 /* Stable */] : "" /* Empty */;
2590
- privacy = parent.data.tag === "STYLE" /* StyleTag */ || parent.data.tag === "TITLE" /* TitleTag */ ? 0 /* None */ : privacy;
2591
- for (var _i = 0, override_1 = override; _i < override_1.length; _i++) {
2592
- var entry = override_1[_i];
2593
- if (path.indexOf(entry) >= 0) {
2594
- privacy = 0 /* None */;
2595
- break;
2596
- }
2597
- }
2598
- }
2599
- // Do not proceed if attributes are missing for the node
2600
- if (attributes === null || attributes === undefined) {
2601
- return privacy;
2602
- }
2603
- // Look up for sensitive fields
2604
- if ("class" /* Class */ in attributes && privacy === 1 /* Sensitive */) {
2605
- for (var _a = 0, DISALLOWED_MATCH_1 = DISALLOWED_MATCH; _a < DISALLOWED_MATCH_1.length; _a++) {
2606
- var match = DISALLOWED_MATCH_1[_a];
2607
- if (attributes["class" /* Class */].indexOf(match) >= 0) {
2608
- privacy = 2 /* Text */;
2609
- break;
2610
- }
2611
- }
2612
- }
2613
- // Check for disallowed list of fields (e.g. address, phone, etc.) only if the input node is not already masked
2614
- if (tag === "INPUT" /* InputTag */) {
2615
- if (privacy === 0 /* None */) {
2616
- var field = "" /* Empty */;
2617
- // Be aggressive in looking up any attribute (id, class, name, etc.) for disallowed names
2618
- for (var _b = 0, _c = Object.keys(attributes); _b < _c.length; _b++) {
2619
- var attribute = _c[_b];
2620
- field += attributes[attribute].toLowerCase();
2621
- }
2622
- for (var _d = 0, DISALLOWED_NAMES_1 = DISALLOWED_NAMES; _d < DISALLOWED_NAMES_1.length; _d++) {
2623
- var name_1 = DISALLOWED_NAMES_1[_d];
2624
- if (field.indexOf(name_1) >= 0) {
2625
- privacy = 2 /* Text */;
2626
- break;
2627
- }
2628
- }
2629
- }
2630
- else if (privacy === 1 /* Sensitive */) {
2631
- // Mask all input fields with an exception of type=submit; since they do not accept user input
2632
- privacy = attributes && attributes["type" /* Type */] === "submit" /* Submit */ ? 0 /* None */ : 2 /* Text */;
2633
- }
2634
- }
2635
- // Check for disallowed list of types (e.g. password, email, etc.) and set the masked property appropriately
2636
- if ("type" /* Type */ in attributes && DISALLOWED_TYPES.indexOf(attributes["type" /* Type */]) >= 0) {
2637
- privacy = 2 /* Text */;
2638
- }
2639
- // Following two conditions supersede any of the above. If there are explicit instructions to mask / unmask a field, we honor that.
2640
- if ("data-clarity-mask" /* MaskData */ in attributes) {
2641
- privacy = 3 /* TextImage */;
2512
+ switch (true) {
2513
+ case "data-clarity-mask" /* MaskData */ in attributes:
2514
+ metadata.privacy = 3 /* TextImage */;
2515
+ break;
2516
+ case "data-clarity-unmask" /* UnmaskData */ in attributes:
2517
+ metadata.privacy = 0 /* None */;
2518
+ break;
2519
+ case privacyMap.has(node):
2520
+ // If this node was explicitly configured to contain sensitive content, honor that privacy setting
2521
+ metadata.privacy = privacyMap.get(node);
2522
+ break;
2523
+ case fraudMap.has(node):
2524
+ // If this node was explicitly configured to be evaluated for fraud, then also mask content
2525
+ metadata.privacy = 2 /* Text */;
2526
+ break;
2527
+ case tag === "*T" /* TextTag */:
2528
+ // If it's a text node belonging to a STYLE or TITLE tag or one of SCRUB_EXCEPTIONS, then capture content
2529
+ var pTag = parent && parent.data ? parent.data.tag : "" /* Empty */;
2530
+ var pSelector_1 = parent && parent.selector ? parent.selector[0 /* Stable */] : "" /* Empty */;
2531
+ metadata.privacy = pTag === "STYLE" /* StyleTag */ || pTag === "TITLE" /* TitleTag */ || override.some(function (x) { return pSelector_1.indexOf(x) >= 0; }) ? 0 /* None */ : current;
2532
+ break;
2533
+ case "type" /* Type */ in attributes:
2534
+ // If this node has an explicit type assigned to it, go through masking rules to determine right privacy setting
2535
+ metadata.privacy = inspect(attributes["type" /* Type */], metadata);
2536
+ break;
2537
+ case tag === "INPUT" /* InputTag */ && current === 0 /* None */:
2538
+ // If even default privacy setting is to not mask, we still scan through input fields for any sensitive information
2539
+ var field_1 = "" /* Empty */;
2540
+ Object.keys(attributes).forEach(function (x) { return field_1 += attributes[x].toLowerCase(); });
2541
+ metadata.privacy = inspect(field_1, metadata);
2542
+ break;
2543
+ case current === 1 /* Sensitive */ && tag === "INPUT" /* InputTag */:
2544
+ // If it's a button or an input option, make an exception to disable masking
2545
+ metadata.privacy = maskDisable.indexOf(attributes["type" /* Type */]) >= 0 ? 0 /* None */ : current;
2546
+ break;
2547
+ case current === 1 /* Sensitive */:
2548
+ // In a mode where we mask sensitive information by default, look through class names to aggressively mask content
2549
+ metadata.privacy = inspect(attributes["class" /* Class */], metadata);
2550
+ break;
2551
+ default:
2552
+ metadata.privacy = parent ? parent.metadata.privacy : metadata.privacy;
2553
+ break;
2642
2554
  }
2643
- if ("data-clarity-unmask" /* UnmaskData */ in attributes) {
2644
- privacy = 0 /* None */;
2555
+ }
2556
+ function inspect(input, metadata) {
2557
+ if (input && maskText.some(function (x) { return input.indexOf(x) >= 0; })) {
2558
+ return 2 /* Text */;
2645
2559
  }
2646
- return privacy;
2560
+ return metadata.privacy;
2647
2561
  }
2648
2562
  function diff(a, b, field) {
2649
2563
  if (typeof a[field] === "object" && typeof b[field] === "object") {
@@ -2731,17 +2645,9 @@ function remove(id, source) {
2731
2645
  track$4(id, source);
2732
2646
  }
2733
2647
  }
2734
- function size(value, parent) {
2735
- var data = value.data;
2736
- var tag = data.tag;
2737
- // If this element is a text node, is masked, and longer than configured length, then track box model for the parent element
2738
- var isLongText = tag === "*T" /* TextTag */ && data.value && data.value.length > 15 /* ResizeObserverThreshold */;
2739
- var isMasked = value.metadata.privacy === 2 /* Text */ || value.metadata.privacy === 3 /* TextImage */;
2740
- if (isLongText && isMasked && parent && parent.metadata.size === null) {
2741
- parent.metadata.size = [];
2742
- }
2648
+ function size(value) {
2743
2649
  // If this element is a image node, and is masked, then track box model for the current element
2744
- if (data.tag === "IMG" /* ImageTag */ && value.metadata.privacy === 3 /* TextImage */) {
2650
+ if (value.data.tag === "IMG" /* ImageTag */ && value.metadata.privacy === 3 /* TextImage */) {
2745
2651
  value.metadata.size = [];
2746
2652
  }
2747
2653
  }
@@ -2950,18 +2856,23 @@ function link(node) {
2950
2856
  }
2951
2857
  return null;
2952
2858
  }
2953
- function metadata$2(node, event) {
2859
+ function metadata$2(node, event, text) {
2860
+ if (text === void 0) { text = null; }
2954
2861
  // If the node is null, we return a reserved value for id: 0. Valid assignment of id begins from 1+.
2955
2862
  var output = { id: 0, hash: null, privacy: 2 /* Text */, node: node };
2956
2863
  if (node) {
2957
2864
  var value = get(node);
2958
2865
  if (value !== null) {
2866
+ var metadata_1 = value.metadata;
2959
2867
  output.id = value.id;
2960
2868
  output.hash = value.hash;
2961
- output.privacy = value.metadata.privacy;
2869
+ output.privacy = metadata_1.privacy;
2962
2870
  if (value.region) {
2963
2871
  track$3(value.region, event);
2964
2872
  }
2873
+ if (metadata_1.fraud) {
2874
+ check$4(metadata_1.fraud, value.id, text || value.data.value);
2875
+ }
2965
2876
  }
2966
2877
  }
2967
2878
  return output;
@@ -3000,7 +2911,7 @@ function encode$3 (type) {
3000
2911
  case 9 /* Click */:
3001
2912
  for (_b = 0, _c = state$7; _b < _c.length; _b++) {
3002
2913
  entry = _c[_b];
3003
- cTarget = metadata$2(entry.data.target, entry.event);
2914
+ cTarget = metadata$2(entry.data.target, entry.event, entry.data.text);
3004
2915
  tokens = [entry.time, entry.event];
3005
2916
  cHash = cTarget.hash.join("." /* Dot */);
3006
2917
  tokens.push(cTarget.id);
@@ -3014,6 +2925,7 @@ function encode$3 (type) {
3014
2925
  tokens.push(scrub(entry.data.text, "click", cTarget.privacy));
3015
2926
  tokens.push(entry.data.link);
3016
2927
  tokens.push(cHash);
2928
+ tokens.push(entry.data.trust);
3017
2929
  queue(tokens);
3018
2930
  track$2(entry.time, entry.event, cHash, entry.data.x, entry.data.y, entry.data.reaction, entry.data.context);
3019
2931
  }
@@ -3049,10 +2961,10 @@ function encode$3 (type) {
3049
2961
  case 27 /* Input */:
3050
2962
  for (_f = 0, _g = state$5; _f < _g.length; _f++) {
3051
2963
  entry = _g[_f];
3052
- iTarget = metadata$2(entry.data.target, entry.event);
2964
+ iTarget = metadata$2(entry.data.target, entry.event, entry.data.value);
3053
2965
  tokens = [entry.time, entry.event];
3054
2966
  tokens.push(iTarget.id);
3055
- tokens.push(entry.data.value);
2967
+ tokens.push(scrub(entry.data.value, "input", iTarget.privacy));
3056
2968
  queue(tokens);
3057
2969
  }
3058
2970
  reset$f();
@@ -3227,7 +3139,7 @@ function queue(tokens, transmit) {
3227
3139
  // We enrich the data going out with the existing upload. In these cases, call to upload comes with 'transmit' set to false.
3228
3140
  if (transmit && timeout === null) {
3229
3141
  if (type !== 25 /* Ping */) {
3230
- reset$n();
3142
+ reset$m();
3231
3143
  }
3232
3144
  timeout = setTimeout(upload, gap);
3233
3145
  queuedTime = now;
@@ -3263,7 +3175,7 @@ function upload(final) {
3263
3175
  // Otherwise you run a risk of infinite loop.
3264
3176
  compute$6();
3265
3177
  compute$5();
3266
- compute$9();
3178
+ compute$8();
3267
3179
  last = final === true;
3268
3180
  e = JSON.stringify(envelope(last));
3269
3181
  a = "[" + analysis.join() + "]";
@@ -3455,14 +3367,6 @@ function handler(error) {
3455
3367
  stack: e.stack,
3456
3368
  source: error["filename"]
3457
3369
  };
3458
- // In certain cases, ResizeObserver could lead to flood of benign errors - especially when video element is involved.
3459
- // Reference Chromium issue: https://bugs.chromium.org/p/chromium/issues/detail?id=809574
3460
- // Even though it doesn't impact user experience, or show up in console, it can still flood error reporting through on error
3461
- // To mitigate that, we turn off Clarity's ResizeObserver on getting the first instance of this error
3462
- if (e.message.indexOf("ResizeObserver" /* ResizeObserver */) >= 0) {
3463
- stop$t();
3464
- return false;
3465
- }
3466
3370
  encode$2(31 /* ScriptError */);
3467
3371
  }
3468
3372
  return true;
@@ -3492,6 +3396,14 @@ function encode$2 (type) {
3492
3396
  queue(tokens, false);
3493
3397
  }
3494
3398
  break;
3399
+ case 41 /* Fraud */:
3400
+ if (data$d) {
3401
+ tokens.push(data$d.id);
3402
+ tokens.push(data$d.target);
3403
+ tokens.push(data$d.hash);
3404
+ queue(tokens, false);
3405
+ }
3406
+ break;
3495
3407
  }
3496
3408
  return [2 /*return*/];
3497
3409
  });
@@ -3682,7 +3594,7 @@ function encode$1 (event) {
3682
3594
  tokens.push(b.data.activityTime);
3683
3595
  queue(tokens, false);
3684
3596
  }
3685
- reset$p();
3597
+ reset$o();
3686
3598
  break;
3687
3599
  case 25 /* Ping */:
3688
3600
  tokens.push(data$h.gap);
@@ -3715,7 +3627,7 @@ function encode$1 (event) {
3715
3627
  tokens.push(v);
3716
3628
  tokens.push(data$e[v]);
3717
3629
  }
3718
- reset$l();
3630
+ reset$k();
3719
3631
  queue(tokens, false);
3720
3632
  }
3721
3633
  break;
@@ -3730,7 +3642,7 @@ function encode$1 (event) {
3730
3642
  // However, for data over the wire, we round it off to milliseconds precision.
3731
3643
  tokens.push(Math.round(updates$3[m]));
3732
3644
  }
3733
- reset$o();
3645
+ reset$n();
3734
3646
  queue(tokens, false);
3735
3647
  }
3736
3648
  break;
@@ -3756,7 +3668,7 @@ function encode$1 (event) {
3756
3668
  tokens.push(key);
3757
3669
  tokens.push([].concat.apply([], data$g[e]));
3758
3670
  }
3759
- reset$m();
3671
+ reset$l();
3760
3672
  queue(tokens, false);
3761
3673
  }
3762
3674
  break;
@@ -3842,10 +3754,9 @@ function reset$3() {
3842
3754
  }
3843
3755
 
3844
3756
  var data$2 = null;
3845
- var callback = null;
3757
+ var callbacks = [];
3846
3758
  var rootDomain = null;
3847
3759
  function start$9() {
3848
- callback = null;
3849
3760
  rootDomain = null;
3850
3761
  var ua = navigator && "userAgent" in navigator ? navigator.userAgent : "" /* Empty */;
3851
3762
  var title = document && document.title ? document.title : "" /* Empty */;
@@ -3871,7 +3782,6 @@ function start$9() {
3871
3782
  log(17 /* DocumentDirection */, document.dir);
3872
3783
  if (navigator) {
3873
3784
  log(9 /* Language */, navigator.userLanguage || navigator.language);
3874
- max(26 /* Automation */, navigator.webdriver ? 1 /* True */ : 0 /* False */);
3875
3785
  userAgentData();
3876
3786
  }
3877
3787
  // Metrics
@@ -3912,7 +3822,6 @@ function userAgentData() {
3912
3822
  }
3913
3823
  }
3914
3824
  function stop$8() {
3915
- callback = null;
3916
3825
  rootDomain = null;
3917
3826
  data$2 = null;
3918
3827
  }
@@ -3922,10 +3831,7 @@ function metadata(cb, wait) {
3922
3831
  // Immediately invoke the callback if the caller explicitly doesn't want to wait for the upgrade confirmation
3923
3832
  cb(data$2, !config$1.lean);
3924
3833
  }
3925
- else {
3926
- // Save the callback for future reference; so we can inform the caller when page gets upgraded and we have a valid playback flag
3927
- callback = cb;
3928
- }
3834
+ callbacks.push({ callback: cb, wait: wait });
3929
3835
  }
3930
3836
  function id() {
3931
3837
  return data$2 ? [data$2.userId, data$2.sessionId, data$2.pageNum].join("." /* Dot */) : "" /* Empty */;
@@ -3951,13 +3857,20 @@ function tab() {
3951
3857
  }
3952
3858
  function save() {
3953
3859
  var ts = Math.round(Date.now());
3954
- var upgrade = config$1.lean ? 0 /* False */ : 1 /* True */;
3955
3860
  var upload = config$1.upload && typeof config$1.upload === "string" /* String */ ? config$1.upload.replace("https://" /* HTTPS */, "" /* Empty */) : "" /* Empty */;
3956
- if (upgrade && callback) {
3957
- callback(data$2, !config$1.lean);
3958
- }
3861
+ var upgrade = config$1.lean ? 0 /* False */ : 1 /* True */;
3862
+ processCallback(upgrade);
3959
3863
  setCookie("_clsk" /* SessionKey */, [data$2.sessionId, ts, data$2.pageNum, upgrade, upload].join("|" /* Pipe */), 1 /* SessionExpire */);
3960
3864
  }
3865
+ function processCallback(upgrade) {
3866
+ if (callbacks.length > 0) {
3867
+ callbacks.forEach(function (x) {
3868
+ if (x.callback && (!x.wait || upgrade)) {
3869
+ x.callback(data$2, !config$1.lean);
3870
+ }
3871
+ });
3872
+ }
3873
+ }
3961
3874
  function supported(target, api) {
3962
3875
  try {
3963
3876
  return !!target[api];
@@ -4217,23 +4130,23 @@ function start$7() {
4217
4130
  // Add a proxy to history.pushState function
4218
4131
  if (pushState === null) {
4219
4132
  pushState = history.pushState;
4220
- }
4221
- history.pushState = function () {
4222
- if (check$1()) {
4133
+ history.pushState = function () {
4223
4134
  pushState.apply(this, arguments);
4224
- compute$1();
4225
- }
4226
- };
4135
+ if (active() && check$1()) {
4136
+ compute$1();
4137
+ }
4138
+ };
4139
+ }
4227
4140
  // Add a proxy to history.replaceState function
4228
4141
  if (replaceState === null) {
4229
4142
  replaceState = history.replaceState;
4230
- }
4231
- history.replaceState = function () {
4232
- if (check$1()) {
4143
+ history.replaceState = function () {
4233
4144
  replaceState.apply(this, arguments);
4234
- compute$1();
4235
- }
4236
- };
4145
+ if (active() && check$1()) {
4146
+ compute$1();
4147
+ }
4148
+ };
4149
+ }
4237
4150
  }
4238
4151
  function check$1() {
4239
4152
  if (count++ > 20 /* CallStackDepth */) {
@@ -4247,23 +4160,17 @@ function compute$1() {
4247
4160
  if (url !== getCurrentUrl()) {
4248
4161
  // If the url changed, start tracking it as a new page
4249
4162
  stop();
4250
- window.setTimeout(start, 250 /* RestartDelay */);
4163
+ window.setTimeout(restart$1, 250 /* RestartDelay */);
4251
4164
  }
4252
4165
  }
4166
+ function restart$1() {
4167
+ start();
4168
+ max(29 /* SinglePage */, 1 /* True */);
4169
+ }
4253
4170
  function getCurrentUrl() {
4254
4171
  return location.href ? location.href.replace(location.hash, "" /* Empty */) : location.href;
4255
4172
  }
4256
4173
  function stop$6() {
4257
- // Restore original function definition of history.pushState
4258
- if (pushState !== null) {
4259
- history.pushState = pushState;
4260
- pushState = null;
4261
- }
4262
- // Restore original function definition of history.replaceState
4263
- if (replaceState !== null) {
4264
- history.replaceState = replaceState;
4265
- replaceState = null;
4266
- }
4267
4174
  url = null;
4268
4175
  count = 0;
4269
4176
  }
@@ -4272,7 +4179,7 @@ var status = false;
4272
4179
  function start$6() {
4273
4180
  status = true;
4274
4181
  start$F();
4275
- reset$k();
4182
+ reset$j();
4276
4183
  reset$1();
4277
4184
  reset$2();
4278
4185
  start$7();
@@ -4281,8 +4188,8 @@ function stop$5() {
4281
4188
  stop$6();
4282
4189
  reset$2();
4283
4190
  reset$1();
4284
- reset$k();
4285
- stop$C();
4191
+ reset$j();
4192
+ stop$B();
4286
4193
  status = false;
4287
4194
  }
4288
4195
  function active() {
@@ -4336,6 +4243,7 @@ function restart() {
4336
4243
  }
4337
4244
 
4338
4245
  function start$5() {
4246
+ start$x();
4339
4247
  start$e();
4340
4248
  start$d();
4341
4249
  }
@@ -4363,14 +4271,14 @@ function discover() {
4363
4271
  case 0:
4364
4272
  ts = time();
4365
4273
  timer = { id: id(), cost: 3 /* LayoutCost */ };
4366
- start$x(timer);
4274
+ start$w(timer);
4367
4275
  return [4 /*yield*/, traverse(document, timer, 0 /* Discover */)];
4368
4276
  case 1:
4369
4277
  _a.sent();
4370
4278
  return [4 /*yield*/, encode$4(5 /* Discover */, timer, ts)];
4371
4279
  case 2:
4372
4280
  _a.sent();
4373
- stop$u(timer);
4281
+ stop$t(timer);
4374
4282
  return [2 /*return*/];
4375
4283
  }
4376
4284
  });
@@ -4385,13 +4293,11 @@ function start$3() {
4385
4293
  start$i();
4386
4294
  start$j();
4387
4295
  start$4();
4388
- start$w();
4389
4296
  }
4390
4297
  function stop$3() {
4391
4298
  stop$f();
4392
4299
  stop$g();
4393
4300
  stop$h();
4394
- stop$t();
4395
4301
  end();
4396
4302
  }
4397
4303
 
@@ -4519,7 +4425,11 @@ function process(entries) {
4519
4425
  compute(entry);
4520
4426
  break;
4521
4427
  case "resource" /* Resource */:
4522
- log(4 /* NetworkHosts */, host(entry.name));
4428
+ var name_1 = entry.name;
4429
+ log(4 /* NetworkHosts */, host(name_1));
4430
+ if (name_1 === config$1.upload || name_1 === config$1.fallback) {
4431
+ max(28 /* UploadTime */, entry.duration);
4432
+ }
4523
4433
  break;
4524
4434
  case "longtask" /* LongTask */:
4525
4435
  count$1(7 /* LongTaskCount */);
@@ -4542,6 +4452,11 @@ function process(entries) {
4542
4452
  break;
4543
4453
  }
4544
4454
  }
4455
+ if (performance && "memory" /* Memory */ in performance && performance["memory" /* Memory */].usedJSHeapSize) {
4456
+ // Track consumed memory (MBs) where "memory" API is available
4457
+ // Reference: https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory
4458
+ max(30 /* UsedMemory */, Math.abs(performance["memory" /* Memory */].usedJSHeapSize / 1048576 /* MegaByte */));
4459
+ }
4545
4460
  }
4546
4461
  function stop$2() {
4547
4462
  if (observer) {
@@ -4603,7 +4518,7 @@ function stop() {
4603
4518
  if (active()) {
4604
4519
  // Stop modules in the reverse order of their initialization
4605
4520
  modules.slice().reverse().forEach(function (x) { return measure(x.stop)(); });
4606
- stop$v();
4521
+ stop$u();
4607
4522
  stop$5();
4608
4523
  }
4609
4524
  }