@usermaven/sdk-js 1.0.7 → 1.1.0
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/README.md +1 -2
- package/dist/npm/usermaven.cjs.js +569 -1802
- package/dist/npm/usermaven.d.ts +72 -28
- package/dist/npm/usermaven.es.js +569 -1802
- package/dist/web/lib.js +1 -1
- package/package.json +1 -1
|
@@ -174,25 +174,24 @@ function createLogger(logLevel) {
|
|
|
174
174
|
* Checks if global variable 'window' is available. If it's available,
|
|
175
175
|
* code runs in browser environment
|
|
176
176
|
*/
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
function isWindowAvailable(warnMsg) {
|
|
178
|
+
if (warnMsg === void 0) { warnMsg = undefined; }
|
|
179
|
+
var windowAvailable = !!globalThis.window;
|
|
180
|
+
if (!windowAvailable && warnMsg) {
|
|
181
|
+
getLogger().warn(warnMsg);
|
|
182
|
+
}
|
|
183
|
+
return windowAvailable;
|
|
184
184
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
185
|
/**
|
|
188
186
|
* @param msg
|
|
189
187
|
* @return {Window}
|
|
190
188
|
*/
|
|
191
|
-
function requireWindow(msg
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
189
|
+
function requireWindow(msg) {
|
|
190
|
+
if (msg === void 0) { msg = undefined; }
|
|
191
|
+
if (!isWindowAvailable()) {
|
|
192
|
+
throw new Error(msg || "window' is not available. Seems like this code runs outside browser environment. It shouldn't happen");
|
|
193
|
+
}
|
|
194
|
+
return window;
|
|
196
195
|
}
|
|
197
196
|
|
|
198
197
|
function serializeCookie(name, val, opt) {
|
|
@@ -415,1500 +414,291 @@ var getHostWithProtocol = function (host) {
|
|
|
415
414
|
}
|
|
416
415
|
};
|
|
417
416
|
|
|
418
|
-
var
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
}
|
|
417
|
+
var MemoryQueue = /** @class */ (function () {
|
|
418
|
+
function MemoryQueue() {
|
|
419
|
+
this.queue = [];
|
|
420
|
+
}
|
|
421
|
+
MemoryQueue.prototype.flush = function () {
|
|
422
|
+
var queue = this.queue;
|
|
423
|
+
this.queue = [];
|
|
424
|
+
return queue;
|
|
425
|
+
};
|
|
426
|
+
MemoryQueue.prototype.push = function () {
|
|
427
|
+
var _a;
|
|
428
|
+
var values = [];
|
|
429
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
430
|
+
values[_i] = arguments[_i];
|
|
431
|
+
}
|
|
432
|
+
(_a = this.queue).push.apply(_a, values);
|
|
433
|
+
};
|
|
434
|
+
return MemoryQueue;
|
|
435
|
+
}());
|
|
436
|
+
var LocalStorageQueue = /** @class */ (function () {
|
|
437
|
+
function LocalStorageQueue(key) {
|
|
438
|
+
this.key = key;
|
|
439
|
+
}
|
|
440
|
+
LocalStorageQueue.prototype.flush = function () {
|
|
441
|
+
var queue = this.get();
|
|
442
|
+
if (queue.length) {
|
|
443
|
+
this.set([]);
|
|
444
|
+
}
|
|
445
|
+
return queue;
|
|
446
|
+
};
|
|
447
|
+
LocalStorageQueue.prototype.push = function () {
|
|
448
|
+
var values = [];
|
|
449
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
450
|
+
values[_i] = arguments[_i];
|
|
451
|
+
}
|
|
452
|
+
var queue = this.get();
|
|
453
|
+
queue.push.apply(queue, values);
|
|
454
|
+
this.set(queue);
|
|
455
|
+
};
|
|
456
|
+
LocalStorageQueue.prototype.set = function (queue) {
|
|
457
|
+
localStorage.setItem(this.key, JSON.stringify(queue));
|
|
458
|
+
};
|
|
459
|
+
LocalStorageQueue.prototype.get = function () {
|
|
460
|
+
var data = localStorage.getItem(this.key);
|
|
461
|
+
if (data !== null && data !== "") {
|
|
462
|
+
return JSON.parse(data);
|
|
463
|
+
}
|
|
464
|
+
return [];
|
|
465
|
+
};
|
|
466
|
+
return LocalStorageQueue;
|
|
467
|
+
}());
|
|
453
468
|
|
|
454
|
-
|
|
455
|
-
var
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
469
|
+
var ObjProto = Object.prototype;
|
|
470
|
+
var toString = ObjProto.toString;
|
|
471
|
+
var hasOwnProperty = ObjProto.hasOwnProperty;
|
|
472
|
+
var ArrayProto = Array.prototype;
|
|
473
|
+
var nativeForEach = ArrayProto.forEach, nativeIsArray = Array.isArray, breaker = {};
|
|
474
|
+
var _isArray = nativeIsArray ||
|
|
475
|
+
function (obj) {
|
|
476
|
+
return toString.call(obj) === '[object Array]';
|
|
477
|
+
};
|
|
478
|
+
function _eachArray(obj, iterator, thisArg) {
|
|
479
|
+
if (Array.isArray(obj)) {
|
|
480
|
+
if (nativeForEach && obj.forEach === nativeForEach) {
|
|
481
|
+
obj.forEach(iterator, thisArg);
|
|
482
|
+
}
|
|
483
|
+
else if ('length' in obj && obj.length === +obj.length) {
|
|
484
|
+
for (var i = 0, l = obj.length; i < l; i++) {
|
|
485
|
+
if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
472
488
|
}
|
|
473
489
|
}
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// UNDERSCORE
|
|
490
|
+
}
|
|
491
|
+
}
|
|
478
492
|
// Embed part of the Underscore Library
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
if (nativeBind && func.bind === nativeBind) {
|
|
482
|
-
return nativeBind.apply(func, slice.call(arguments, 1))
|
|
483
|
-
}
|
|
484
|
-
if (!_.isFunction(func)) {
|
|
485
|
-
throw new TypeError()
|
|
486
|
-
}
|
|
487
|
-
args = slice.call(arguments, 2);
|
|
488
|
-
bound = function () {
|
|
489
|
-
if (!(this instanceof bound)) {
|
|
490
|
-
return func.apply(context, args.concat(slice.call(arguments)))
|
|
491
|
-
}
|
|
492
|
-
var ctor = {};
|
|
493
|
-
ctor.prototype = func.prototype;
|
|
494
|
-
var self = new ctor();
|
|
495
|
-
ctor.prototype = null;
|
|
496
|
-
var result = func.apply(self, args.concat(slice.call(arguments)));
|
|
497
|
-
if (Object(result) === result) {
|
|
498
|
-
return result
|
|
499
|
-
}
|
|
500
|
-
return self
|
|
501
|
-
};
|
|
502
|
-
return bound
|
|
493
|
+
var _trim = function (str) {
|
|
494
|
+
return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
|
503
495
|
};
|
|
504
|
-
|
|
505
|
-
_.bind_instance_methods = function (obj) {
|
|
496
|
+
var _bind_instance_methods = function (obj) {
|
|
506
497
|
for (var func in obj) {
|
|
507
498
|
if (typeof obj[func] === 'function') {
|
|
508
|
-
obj[func] =
|
|
499
|
+
obj[func] = obj[func].bind(obj);
|
|
509
500
|
}
|
|
510
501
|
}
|
|
511
502
|
};
|
|
512
|
-
|
|
513
503
|
/**
|
|
514
504
|
* @param {*=} obj
|
|
515
505
|
* @param {function(...*)=} iterator
|
|
516
|
-
* @param {Object=}
|
|
506
|
+
* @param {Object=} thisArg
|
|
517
507
|
*/
|
|
518
|
-
|
|
508
|
+
function _each(obj, iterator, thisArg) {
|
|
519
509
|
if (obj === null || obj === undefined) {
|
|
520
|
-
return
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if (nativeForEach && Array.isArray(obj) && obj.forEach === nativeForEach) {
|
|
513
|
+
obj.forEach(iterator, thisArg);
|
|
521
514
|
}
|
|
522
|
-
if (
|
|
523
|
-
obj.forEach(iterator, context);
|
|
524
|
-
} else if (obj.length === +obj.length) {
|
|
515
|
+
else if ('length' in obj && obj.length === +obj.length) {
|
|
525
516
|
for (var i = 0, l = obj.length; i < l; i++) {
|
|
526
|
-
if (i in obj && iterator.call(
|
|
527
|
-
return
|
|
517
|
+
if (i in obj && iterator.call(thisArg, obj[i], i) === breaker) {
|
|
518
|
+
return;
|
|
528
519
|
}
|
|
529
520
|
}
|
|
530
|
-
}
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
531
523
|
for (var key in obj) {
|
|
532
524
|
if (hasOwnProperty.call(obj, key)) {
|
|
533
|
-
if (iterator.call(
|
|
534
|
-
return
|
|
525
|
+
if (iterator.call(thisArg, obj[key], key) === breaker) {
|
|
526
|
+
return;
|
|
535
527
|
}
|
|
536
528
|
}
|
|
537
529
|
}
|
|
538
530
|
}
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
531
|
+
}
|
|
532
|
+
var _extend = function (obj) {
|
|
533
|
+
var args = [];
|
|
534
|
+
for (var _i = 1; _i < arguments.length; _i++) {
|
|
535
|
+
args[_i - 1] = arguments[_i];
|
|
536
|
+
}
|
|
537
|
+
_eachArray(args, function (source) {
|
|
543
538
|
for (var prop in source) {
|
|
544
539
|
if (source[prop] !== void 0) {
|
|
545
540
|
obj[prop] = source[prop];
|
|
546
541
|
}
|
|
547
542
|
}
|
|
548
543
|
});
|
|
549
|
-
return obj
|
|
544
|
+
return obj;
|
|
550
545
|
};
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
function (obj) {
|
|
555
|
-
return toString.call(obj) === '[object Array]'
|
|
556
|
-
};
|
|
557
|
-
|
|
546
|
+
function _includes(str, needle) {
|
|
547
|
+
return str.indexOf(needle) !== -1;
|
|
548
|
+
}
|
|
558
549
|
// from a comment on http://dbj.org/dbj/?p=286
|
|
559
550
|
// fails on only one very rare and deliberate custom object:
|
|
560
|
-
//
|
|
561
|
-
|
|
562
|
-
try {
|
|
563
|
-
return /^\s*\bfunction\b/.test(f)
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
_.include = function (obj, target) {
|
|
570
|
-
var found = false;
|
|
571
|
-
if (obj === null) {
|
|
572
|
-
return found
|
|
573
|
-
}
|
|
574
|
-
if (nativeIndexOf && obj.indexOf === nativeIndexOf) {
|
|
575
|
-
return obj.indexOf(target) != -1
|
|
576
|
-
}
|
|
577
|
-
_.each(obj, function (value) {
|
|
578
|
-
if (found || (found = value === target)) {
|
|
579
|
-
return breaker
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
return found
|
|
583
|
-
};
|
|
584
|
-
|
|
585
|
-
_.includes = function (str, needle) {
|
|
586
|
-
return str.indexOf(needle) !== -1
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
// Underscore Addons
|
|
590
|
-
_.isObject = function (obj) {
|
|
591
|
-
return obj === Object(obj) && !_.isArray(obj)
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
_.isEmptyObject = function (obj) {
|
|
595
|
-
if (_.isObject(obj)) {
|
|
596
|
-
for (var key in obj) {
|
|
597
|
-
if (hasOwnProperty.call(obj, key)) {
|
|
598
|
-
return false
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
return true
|
|
602
|
-
}
|
|
603
|
-
return false
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
_.isUndefined = function (obj) {
|
|
607
|
-
return obj === void 0
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
_.isString = function (obj) {
|
|
611
|
-
return toString.call(obj) == '[object String]'
|
|
612
|
-
};
|
|
613
|
-
|
|
614
|
-
_.isDate = function (obj) {
|
|
615
|
-
return toString.call(obj) == '[object Date]'
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
_.isNumber = function (obj) {
|
|
619
|
-
return toString.call(obj) == '[object Number]'
|
|
620
|
-
};
|
|
621
|
-
|
|
622
|
-
_.encodeDates = function (obj) {
|
|
623
|
-
_.each(obj, function (v, k) {
|
|
624
|
-
if (_.isDate(v)) {
|
|
625
|
-
obj[k] = _.formatDate(v);
|
|
626
|
-
} else if (_.isObject(v)) {
|
|
627
|
-
obj[k] = _.encodeDates(v); // recurse
|
|
628
|
-
}
|
|
629
|
-
});
|
|
630
|
-
return obj
|
|
631
|
-
};
|
|
632
|
-
|
|
633
|
-
_.timestamp = function () {
|
|
634
|
-
Date.now =
|
|
635
|
-
Date.now ||
|
|
636
|
-
function () {
|
|
637
|
-
return +new Date()
|
|
638
|
-
};
|
|
639
|
-
return Date.now()
|
|
640
|
-
};
|
|
641
|
-
|
|
642
|
-
_.formatDate = function (d) {
|
|
643
|
-
// YYYY-MM-DDTHH:MM:SS in UTC
|
|
644
|
-
function pad(n) {
|
|
645
|
-
return n < 10 ? '0' + n : n
|
|
646
|
-
}
|
|
647
|
-
return (
|
|
648
|
-
d.getUTCFullYear() +
|
|
649
|
-
'-' +
|
|
650
|
-
pad(d.getUTCMonth() + 1) +
|
|
651
|
-
'-' +
|
|
652
|
-
pad(d.getUTCDate()) +
|
|
653
|
-
'T' +
|
|
654
|
-
pad(d.getUTCHours()) +
|
|
655
|
-
':' +
|
|
656
|
-
pad(d.getUTCMinutes()) +
|
|
657
|
-
':' +
|
|
658
|
-
pad(d.getUTCSeconds())
|
|
659
|
-
)
|
|
660
|
-
};
|
|
661
|
-
|
|
662
|
-
_.safewrap = function (f) {
|
|
663
|
-
return function () {
|
|
664
|
-
try {
|
|
665
|
-
return f.apply(this, arguments)
|
|
666
|
-
} catch (e) {
|
|
667
|
-
console$1.critical('Implementation error. Please turn on debug and contact support@usermaven.com.');
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
};
|
|
671
|
-
|
|
672
|
-
_.safewrap_class = function (klass, functions) {
|
|
673
|
-
for (var i = 0; i < functions.length; i++) {
|
|
674
|
-
klass.prototype[functions[i]] = _.safewrap(klass.prototype[functions[i]]);
|
|
675
|
-
}
|
|
676
|
-
};
|
|
677
|
-
|
|
678
|
-
_.safewrap_instance_methods = function (obj) {
|
|
679
|
-
for (var func in obj) {
|
|
680
|
-
if (typeof obj[func] === 'function') {
|
|
681
|
-
obj[func] = _.safewrap(obj[func]);
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
};
|
|
685
|
-
|
|
686
|
-
_.strip_empty_properties = function (p) {
|
|
687
|
-
var ret = {};
|
|
688
|
-
_.each(p, function (v, k) {
|
|
689
|
-
if (_.isString(v) && v.length > 0) {
|
|
690
|
-
ret[k] = v;
|
|
691
|
-
}
|
|
692
|
-
});
|
|
693
|
-
return ret
|
|
694
|
-
};
|
|
695
|
-
|
|
696
|
-
// Deep copies an object.
|
|
697
|
-
// It handles cycles by replacing all references to them with `undefined`
|
|
698
|
-
// Also supports customizing native values
|
|
699
|
-
const COPY_IN_PROGRESS_ATTRIBUTE =
|
|
700
|
-
typeof Symbol !== 'undefined' ? Symbol('__deepCircularCopyInProgress__') : '__deepCircularCopyInProgress__';
|
|
701
|
-
|
|
702
|
-
function deepCircularCopy(value, customizer) {
|
|
703
|
-
if (value !== Object(value)) return customizer ? customizer(value) : value // primitive value
|
|
704
|
-
|
|
705
|
-
if (value[COPY_IN_PROGRESS_ATTRIBUTE]) return undefined
|
|
706
|
-
|
|
707
|
-
value[COPY_IN_PROGRESS_ATTRIBUTE] = true;
|
|
708
|
-
let result;
|
|
709
|
-
|
|
710
|
-
if (_.isArray(value)) {
|
|
711
|
-
result = [];
|
|
712
|
-
_.each(value, (it) => {
|
|
713
|
-
result.push(deepCircularCopy(it, customizer));
|
|
714
|
-
});
|
|
715
|
-
} else {
|
|
716
|
-
result = {};
|
|
717
|
-
_.each(value, (val, key) => {
|
|
718
|
-
if (key !== COPY_IN_PROGRESS_ATTRIBUTE) {
|
|
719
|
-
result[key] = deepCircularCopy(val, customizer);
|
|
720
|
-
}
|
|
721
|
-
});
|
|
722
|
-
}
|
|
723
|
-
delete value[COPY_IN_PROGRESS_ATTRIBUTE];
|
|
724
|
-
return result
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
_.copyAndTruncateStrings = (object, maxStringLength) =>
|
|
728
|
-
deepCircularCopy(
|
|
729
|
-
object,
|
|
730
|
-
(value) => {
|
|
731
|
-
if (typeof value === 'string' && maxStringLength !== null) {
|
|
732
|
-
value = value.slice(0, maxStringLength);
|
|
733
|
-
}
|
|
734
|
-
return value
|
|
735
|
-
});
|
|
736
|
-
|
|
737
|
-
_.base64Encode = function (data) {
|
|
738
|
-
var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
|
739
|
-
var o1,
|
|
740
|
-
o2,
|
|
741
|
-
o3,
|
|
742
|
-
h1,
|
|
743
|
-
h2,
|
|
744
|
-
h3,
|
|
745
|
-
h4,
|
|
746
|
-
bits,
|
|
747
|
-
i = 0,
|
|
748
|
-
ac = 0,
|
|
749
|
-
enc = '',
|
|
750
|
-
tmp_arr = [];
|
|
751
|
-
|
|
752
|
-
if (!data) {
|
|
753
|
-
return data
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
data = _.utf8Encode(data);
|
|
757
|
-
|
|
758
|
-
do {
|
|
759
|
-
// pack three octets into four hexets
|
|
760
|
-
o1 = data.charCodeAt(i++);
|
|
761
|
-
o2 = data.charCodeAt(i++);
|
|
762
|
-
o3 = data.charCodeAt(i++);
|
|
763
|
-
|
|
764
|
-
bits = (o1 << 16) | (o2 << 8) | o3;
|
|
765
|
-
|
|
766
|
-
h1 = (bits >> 18) & 0x3f;
|
|
767
|
-
h2 = (bits >> 12) & 0x3f;
|
|
768
|
-
h3 = (bits >> 6) & 0x3f;
|
|
769
|
-
h4 = bits & 0x3f;
|
|
770
|
-
|
|
771
|
-
// use hexets to index into b64, and append result to encoded string
|
|
772
|
-
tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
|
|
773
|
-
} while (i < data.length)
|
|
774
|
-
|
|
775
|
-
enc = tmp_arr.join('');
|
|
776
|
-
|
|
777
|
-
switch (data.length % 3) {
|
|
778
|
-
case 1:
|
|
779
|
-
enc = enc.slice(0, -2) + '==';
|
|
780
|
-
break
|
|
781
|
-
case 2:
|
|
782
|
-
enc = enc.slice(0, -1) + '=';
|
|
783
|
-
break
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
return enc
|
|
787
|
-
};
|
|
788
|
-
|
|
789
|
-
_.utf8Encode = function (string) {
|
|
790
|
-
string = (string + '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
791
|
-
|
|
792
|
-
var utftext = '',
|
|
793
|
-
start,
|
|
794
|
-
end;
|
|
795
|
-
var stringl = 0,
|
|
796
|
-
n;
|
|
797
|
-
|
|
798
|
-
start = end = 0;
|
|
799
|
-
stringl = string.length;
|
|
800
|
-
|
|
801
|
-
for (n = 0; n < stringl; n++) {
|
|
802
|
-
var c1 = string.charCodeAt(n);
|
|
803
|
-
var enc = null;
|
|
804
|
-
|
|
805
|
-
if (c1 < 128) {
|
|
806
|
-
end++;
|
|
807
|
-
} else if (c1 > 127 && c1 < 2048) {
|
|
808
|
-
enc = String.fromCharCode((c1 >> 6) | 192, (c1 & 63) | 128);
|
|
809
|
-
} else {
|
|
810
|
-
enc = String.fromCharCode((c1 >> 12) | 224, ((c1 >> 6) & 63) | 128, (c1 & 63) | 128);
|
|
811
|
-
}
|
|
812
|
-
if (enc !== null) {
|
|
813
|
-
if (end > start) {
|
|
814
|
-
utftext += string.substring(start, end);
|
|
815
|
-
}
|
|
816
|
-
utftext += enc;
|
|
817
|
-
start = end = n + 1;
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
if (end > start) {
|
|
822
|
-
utftext += string.substring(start, string.length);
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
return utftext
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
_.UUID = (function () {
|
|
829
|
-
// Time/ticks information
|
|
830
|
-
// 1*new Date() is a cross browser version of Date.now()
|
|
831
|
-
var T = function () {
|
|
832
|
-
var d = 1 * new Date(),
|
|
833
|
-
i = 0;
|
|
834
|
-
|
|
835
|
-
// this while loop figures how many browser ticks go by
|
|
836
|
-
// before 1*new Date() returns a new number, ie the amount
|
|
837
|
-
// of ticks that go by per millisecond
|
|
838
|
-
while (d == 1 * new Date()) {
|
|
839
|
-
i++;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
return d.toString(16) + i.toString(16)
|
|
843
|
-
};
|
|
844
|
-
|
|
845
|
-
// Math.Random entropy
|
|
846
|
-
var R = function () {
|
|
847
|
-
return Math.random().toString(16).replace('.', '')
|
|
848
|
-
};
|
|
849
|
-
|
|
850
|
-
// User agent entropy
|
|
851
|
-
// This function takes the user agent string, and then xors
|
|
852
|
-
// together each sequence of 8 bytes. This produces a final
|
|
853
|
-
// sequence of 8 bytes which it returns as hex.
|
|
854
|
-
var UA = function () {
|
|
855
|
-
var ua = userAgent,
|
|
856
|
-
i,
|
|
857
|
-
ch,
|
|
858
|
-
buffer = [],
|
|
859
|
-
ret = 0;
|
|
860
|
-
|
|
861
|
-
function xor(result, byte_array) {
|
|
862
|
-
var j,
|
|
863
|
-
tmp = 0;
|
|
864
|
-
for (j = 0; j < byte_array.length; j++) {
|
|
865
|
-
tmp |= buffer[j] << (j * 8);
|
|
866
|
-
}
|
|
867
|
-
return result ^ tmp
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
for (i = 0; i < ua.length; i++) {
|
|
871
|
-
ch = ua.charCodeAt(i);
|
|
872
|
-
buffer.unshift(ch & 0xff);
|
|
873
|
-
if (buffer.length >= 4) {
|
|
874
|
-
ret = xor(ret, buffer);
|
|
875
|
-
buffer = [];
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
if (buffer.length > 0) {
|
|
880
|
-
ret = xor(ret, buffer);
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
return ret.toString(16)
|
|
884
|
-
};
|
|
885
|
-
|
|
886
|
-
return function () {
|
|
887
|
-
var se = (window.screen.height * window.screen.width).toString(16);
|
|
888
|
-
return T() + '-' + R() + '-' + UA() + '-' + se + '-' + T()
|
|
889
|
-
}
|
|
890
|
-
})();
|
|
891
|
-
|
|
892
|
-
// _.isBlockedUA()
|
|
893
|
-
// This is to block various web spiders from executing our JS and
|
|
894
|
-
// sending false captureing data
|
|
895
|
-
_.isBlockedUA = function (ua) {
|
|
896
|
-
if (/(google web preview|baiduspider|yandexbot|bingbot|googlebot|yahoo! slurp)/i.test(ua)) {
|
|
897
|
-
return true
|
|
898
|
-
}
|
|
899
|
-
return false
|
|
900
|
-
};
|
|
901
|
-
|
|
902
|
-
/**
|
|
903
|
-
* @param {Object=} formdata
|
|
904
|
-
* @param {string=} arg_separator
|
|
905
|
-
*/
|
|
906
|
-
_.HTTPBuildQuery = function (formdata, arg_separator) {
|
|
907
|
-
var use_val,
|
|
908
|
-
use_key,
|
|
909
|
-
tph_arr = [];
|
|
910
|
-
|
|
911
|
-
if (_.isUndefined(arg_separator)) {
|
|
912
|
-
arg_separator = '&';
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
_.each(formdata, function (val, key) {
|
|
916
|
-
use_val = encodeURIComponent(val.toString());
|
|
917
|
-
use_key = encodeURIComponent(key);
|
|
918
|
-
tph_arr[tph_arr.length] = use_key + '=' + use_val;
|
|
919
|
-
});
|
|
920
|
-
|
|
921
|
-
return tph_arr.join(arg_separator)
|
|
922
|
-
};
|
|
923
|
-
|
|
924
|
-
_.getQueryParam = function (url, param) {
|
|
925
|
-
// Expects a raw URL
|
|
926
|
-
|
|
927
|
-
param = param.replace(/[[]/, '\\[').replace(/[\]]/, '\\]');
|
|
928
|
-
var regexS = '[\\?&]' + param + '=([^&#]*)',
|
|
929
|
-
regex = new RegExp(regexS),
|
|
930
|
-
results = regex.exec(url);
|
|
931
|
-
if (results === null || (results && typeof results[1] !== 'string' && results[1].length)) {
|
|
932
|
-
return ''
|
|
933
|
-
} else {
|
|
934
|
-
var result = results[1];
|
|
935
|
-
try {
|
|
936
|
-
result = decodeURIComponent(result);
|
|
937
|
-
} catch (err) {
|
|
938
|
-
}
|
|
939
|
-
return result.replace(/\+/g, ' ')
|
|
940
|
-
}
|
|
941
|
-
};
|
|
942
|
-
|
|
943
|
-
_.getHashParam = function (hash, param) {
|
|
944
|
-
var matches = hash.match(new RegExp(param + '=([^&]*)'));
|
|
945
|
-
return matches ? matches[1] : null
|
|
946
|
-
};
|
|
947
|
-
|
|
948
|
-
_.register_event = (function () {
|
|
949
|
-
// written by Dean Edwards, 2005
|
|
950
|
-
// with input from Tino Zijdel - crisp@xs4all.nl
|
|
951
|
-
// with input from Carl Sverre - mail@carlsverre.com
|
|
952
|
-
// http://dean.edwards.name/weblog/2005/10/add-event/
|
|
953
|
-
// https://gist.github.com/1930440
|
|
954
|
-
|
|
955
|
-
/**
|
|
956
|
-
* @param {Object} element
|
|
957
|
-
* @param {string} type
|
|
958
|
-
* @param {function(...*)} handler
|
|
959
|
-
* @param {boolean=} oldSchool
|
|
960
|
-
* @param {boolean=} useCapture
|
|
961
|
-
*/
|
|
962
|
-
var register_event = function (element, type, handler, oldSchool, useCapture) {
|
|
963
|
-
if (!element) {
|
|
964
|
-
return
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
if (element.addEventListener && !oldSchool) {
|
|
968
|
-
element.addEventListener(type, handler, !!useCapture);
|
|
969
|
-
} else {
|
|
970
|
-
var ontype = 'on' + type;
|
|
971
|
-
var old_handler = element[ontype]; // can be undefined
|
|
972
|
-
element[ontype] = makeHandler(element, handler, old_handler);
|
|
973
|
-
}
|
|
974
|
-
};
|
|
975
|
-
|
|
976
|
-
function makeHandler(element, new_handler, old_handlers) {
|
|
977
|
-
var handler = function (event) {
|
|
978
|
-
event = event || fixEvent(window.event);
|
|
979
|
-
|
|
980
|
-
// this basically happens in firefox whenever another script
|
|
981
|
-
// overwrites the onload callback and doesn't pass the event
|
|
982
|
-
// object to previously defined callbacks. All the browsers
|
|
983
|
-
// that don't define window.event implement addEventListener
|
|
984
|
-
// so the dom_loaded handler will still be fired as usual.
|
|
985
|
-
if (!event) {
|
|
986
|
-
return undefined
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
var ret = true;
|
|
990
|
-
var old_result, new_result;
|
|
991
|
-
|
|
992
|
-
if (_.isFunction(old_handlers)) {
|
|
993
|
-
old_result = old_handlers(event);
|
|
994
|
-
}
|
|
995
|
-
new_result = new_handler.call(element, event);
|
|
996
|
-
|
|
997
|
-
if (false === old_result || false === new_result) {
|
|
998
|
-
ret = false;
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
return ret
|
|
1002
|
-
};
|
|
1003
|
-
|
|
1004
|
-
return handler
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
|
-
function fixEvent(event) {
|
|
1008
|
-
if (event) {
|
|
1009
|
-
event.preventDefault = fixEvent.preventDefault;
|
|
1010
|
-
event.stopPropagation = fixEvent.stopPropagation;
|
|
1011
|
-
}
|
|
1012
|
-
return event
|
|
1013
|
-
}
|
|
1014
|
-
fixEvent.preventDefault = function () {
|
|
1015
|
-
this.returnValue = false;
|
|
1016
|
-
};
|
|
1017
|
-
fixEvent.stopPropagation = function () {
|
|
1018
|
-
this.cancelBubble = true;
|
|
1019
|
-
};
|
|
1020
|
-
|
|
1021
|
-
return register_event
|
|
1022
|
-
})();
|
|
1023
|
-
|
|
1024
|
-
_.info = {
|
|
1025
|
-
campaignParams: function () {
|
|
1026
|
-
var campaign_keywords = 'utm_source utm_medium utm_campaign utm_content utm_term gclid'.split(' '),
|
|
1027
|
-
kw = '',
|
|
1028
|
-
params = {};
|
|
1029
|
-
_.each(campaign_keywords, function (kwkey) {
|
|
1030
|
-
kw = _.getQueryParam(document$1.URL, kwkey);
|
|
1031
|
-
if (kw.length) {
|
|
1032
|
-
params[kwkey] = kw;
|
|
1033
|
-
}
|
|
1034
|
-
});
|
|
1035
|
-
|
|
1036
|
-
return params
|
|
1037
|
-
},
|
|
1038
|
-
|
|
1039
|
-
searchEngine: function (referrer) {
|
|
1040
|
-
if (referrer.search('https?://(.*)google.([^/?]*)') === 0) {
|
|
1041
|
-
return 'google'
|
|
1042
|
-
} else if (referrer.search('https?://(.*)bing.com') === 0) {
|
|
1043
|
-
return 'bing'
|
|
1044
|
-
} else if (referrer.search('https?://(.*)yahoo.com') === 0) {
|
|
1045
|
-
return 'yahoo'
|
|
1046
|
-
} else if (referrer.search('https?://(.*)duckduckgo.com') === 0) {
|
|
1047
|
-
return 'duckduckgo'
|
|
1048
|
-
} else {
|
|
1049
|
-
return null
|
|
1050
|
-
}
|
|
1051
|
-
},
|
|
1052
|
-
|
|
1053
|
-
searchInfo: function (referrer) {
|
|
1054
|
-
var search = _.info.searchEngine(referrer),
|
|
1055
|
-
param = search != 'yahoo' ? 'q' : 'p',
|
|
1056
|
-
ret = {};
|
|
1057
|
-
|
|
1058
|
-
if (search !== null) {
|
|
1059
|
-
ret['$search_engine'] = search;
|
|
1060
|
-
|
|
1061
|
-
var keyword = _.getQueryParam(referrer, param);
|
|
1062
|
-
if (keyword.length) {
|
|
1063
|
-
ret['um_keyword'] = keyword;
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
|
|
1067
|
-
return ret
|
|
1068
|
-
},
|
|
1069
|
-
|
|
1070
|
-
/**
|
|
1071
|
-
* This function detects which browser is running this script.
|
|
1072
|
-
* The order of the checks are important since many user agents
|
|
1073
|
-
* include key words used in later checks.
|
|
1074
|
-
*/
|
|
1075
|
-
browser: function (user_agent, vendor, opera) {
|
|
1076
|
-
vendor = vendor || ''; // vendor is undefined for at least IE9
|
|
1077
|
-
if (opera || _.includes(user_agent, ' OPR/')) {
|
|
1078
|
-
if (_.includes(user_agent, 'Mini')) {
|
|
1079
|
-
return 'Opera Mini'
|
|
1080
|
-
}
|
|
1081
|
-
return 'Opera'
|
|
1082
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) {
|
|
1083
|
-
return 'BlackBerry'
|
|
1084
|
-
} else if (_.includes(user_agent, 'IEMobile') || _.includes(user_agent, 'WPDesktop')) {
|
|
1085
|
-
return 'Internet Explorer Mobile'
|
|
1086
|
-
} else if (_.includes(user_agent, 'SamsungBrowser/')) {
|
|
1087
|
-
// https://developer.samsung.com/internet/user-agent-string-format
|
|
1088
|
-
return 'Samsung Internet'
|
|
1089
|
-
} else if (_.includes(user_agent, 'Edge') || _.includes(user_agent, 'Edg/')) {
|
|
1090
|
-
return 'Microsoft Edge'
|
|
1091
|
-
} else if (_.includes(user_agent, 'FBIOS')) {
|
|
1092
|
-
return 'Facebook Mobile'
|
|
1093
|
-
} else if (_.includes(user_agent, 'Chrome')) {
|
|
1094
|
-
return 'Chrome'
|
|
1095
|
-
} else if (_.includes(user_agent, 'CriOS')) {
|
|
1096
|
-
return 'Chrome iOS'
|
|
1097
|
-
} else if (_.includes(user_agent, 'UCWEB') || _.includes(user_agent, 'UCBrowser')) {
|
|
1098
|
-
return 'UC Browser'
|
|
1099
|
-
} else if (_.includes(user_agent, 'FxiOS')) {
|
|
1100
|
-
return 'Firefox iOS'
|
|
1101
|
-
} else if (_.includes(vendor, 'Apple')) {
|
|
1102
|
-
if (_.includes(user_agent, 'Mobile')) {
|
|
1103
|
-
return 'Mobile Safari'
|
|
1104
|
-
}
|
|
1105
|
-
return 'Safari'
|
|
1106
|
-
} else if (_.includes(user_agent, 'Android')) {
|
|
1107
|
-
return 'Android Mobile'
|
|
1108
|
-
} else if (_.includes(user_agent, 'Konqueror')) {
|
|
1109
|
-
return 'Konqueror'
|
|
1110
|
-
} else if (_.includes(user_agent, 'Firefox')) {
|
|
1111
|
-
return 'Firefox'
|
|
1112
|
-
} else if (_.includes(user_agent, 'MSIE') || _.includes(user_agent, 'Trident/')) {
|
|
1113
|
-
return 'Internet Explorer'
|
|
1114
|
-
} else if (_.includes(user_agent, 'Gecko')) {
|
|
1115
|
-
return 'Mozilla'
|
|
1116
|
-
} else {
|
|
1117
|
-
return ''
|
|
1118
|
-
}
|
|
1119
|
-
},
|
|
1120
|
-
|
|
1121
|
-
/**
|
|
1122
|
-
* This function detects which browser version is running this script,
|
|
1123
|
-
* parsing major and minor version (e.g., 42.1). User agent strings from:
|
|
1124
|
-
* http://www.useragentstring.com/pages/useragentstring.php
|
|
1125
|
-
*/
|
|
1126
|
-
browserVersion: function (userAgent, vendor, opera) {
|
|
1127
|
-
var browser = _.info.browser(userAgent, vendor, opera);
|
|
1128
|
-
var versionRegexs = {
|
|
1129
|
-
'Internet Explorer Mobile': /rv:(\d+(\.\d+)?)/,
|
|
1130
|
-
'Microsoft Edge': /Edge?\/(\d+(\.\d+)?)/,
|
|
1131
|
-
Chrome: /Chrome\/(\d+(\.\d+)?)/,
|
|
1132
|
-
'Chrome iOS': /CriOS\/(\d+(\.\d+)?)/,
|
|
1133
|
-
'UC Browser': /(UCBrowser|UCWEB)\/(\d+(\.\d+)?)/,
|
|
1134
|
-
Safari: /Version\/(\d+(\.\d+)?)/,
|
|
1135
|
-
'Mobile Safari': /Version\/(\d+(\.\d+)?)/,
|
|
1136
|
-
Opera: /(Opera|OPR)\/(\d+(\.\d+)?)/,
|
|
1137
|
-
Firefox: /Firefox\/(\d+(\.\d+)?)/,
|
|
1138
|
-
'Firefox iOS': /FxiOS\/(\d+(\.\d+)?)/,
|
|
1139
|
-
Konqueror: /Konqueror:(\d+(\.\d+)?)/,
|
|
1140
|
-
BlackBerry: /BlackBerry (\d+(\.\d+)?)/,
|
|
1141
|
-
'Android Mobile': /android\s(\d+(\.\d+)?)/,
|
|
1142
|
-
'Samsung Internet': /SamsungBrowser\/(\d+(\.\d+)?)/,
|
|
1143
|
-
'Internet Explorer': /(rv:|MSIE )(\d+(\.\d+)?)/,
|
|
1144
|
-
Mozilla: /rv:(\d+(\.\d+)?)/,
|
|
1145
|
-
};
|
|
1146
|
-
var regex = versionRegexs[browser];
|
|
1147
|
-
if (regex === undefined) {
|
|
1148
|
-
return null
|
|
1149
|
-
}
|
|
1150
|
-
var matches = userAgent.match(regex);
|
|
1151
|
-
if (!matches) {
|
|
1152
|
-
return null
|
|
1153
|
-
}
|
|
1154
|
-
return parseFloat(matches[matches.length - 2])
|
|
1155
|
-
},
|
|
1156
|
-
|
|
1157
|
-
os: function () {
|
|
1158
|
-
var a = userAgent;
|
|
1159
|
-
if (/Windows/i.test(a)) {
|
|
1160
|
-
if (/Phone/.test(a) || /WPDesktop/.test(a)) {
|
|
1161
|
-
return 'Windows Phone'
|
|
1162
|
-
}
|
|
1163
|
-
return 'Windows'
|
|
1164
|
-
} else if (/(iPhone|iPad|iPod)/.test(a)) {
|
|
1165
|
-
return 'iOS'
|
|
1166
|
-
} else if (/Android/.test(a)) {
|
|
1167
|
-
return 'Android'
|
|
1168
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(a)) {
|
|
1169
|
-
return 'BlackBerry'
|
|
1170
|
-
} else if (/Mac/i.test(a)) {
|
|
1171
|
-
return 'Mac OS X'
|
|
1172
|
-
} else if (/Linux/.test(a)) {
|
|
1173
|
-
return 'Linux'
|
|
1174
|
-
} else if (/CrOS/.test(a)) {
|
|
1175
|
-
return 'Chrome OS'
|
|
1176
|
-
} else {
|
|
1177
|
-
return ''
|
|
1178
|
-
}
|
|
1179
|
-
},
|
|
1180
|
-
|
|
1181
|
-
device: function (user_agent) {
|
|
1182
|
-
if (/Windows Phone/i.test(user_agent) || /WPDesktop/.test(user_agent)) {
|
|
1183
|
-
return 'Windows Phone'
|
|
1184
|
-
} else if (/iPad/.test(user_agent)) {
|
|
1185
|
-
return 'iPad'
|
|
1186
|
-
} else if (/iPod/.test(user_agent)) {
|
|
1187
|
-
return 'iPod Touch'
|
|
1188
|
-
} else if (/iPhone/.test(user_agent)) {
|
|
1189
|
-
return 'iPhone'
|
|
1190
|
-
} else if (/(BlackBerry|PlayBook|BB10)/i.test(user_agent)) {
|
|
1191
|
-
return 'BlackBerry'
|
|
1192
|
-
} else if (/Android/.test(user_agent) && !/Mobile/.test(user_agent)) {
|
|
1193
|
-
return 'Android Tablet'
|
|
1194
|
-
} else if (/Android/.test(user_agent)) {
|
|
1195
|
-
return 'Android'
|
|
1196
|
-
} else {
|
|
1197
|
-
return ''
|
|
1198
|
-
}
|
|
1199
|
-
},
|
|
1200
|
-
|
|
1201
|
-
deviceType: function (user_agent) {
|
|
1202
|
-
const device = this.device(user_agent);
|
|
1203
|
-
if (device === 'iPad' || device === 'Android Tablet') {
|
|
1204
|
-
return 'Tablet'
|
|
1205
|
-
} else if (device) {
|
|
1206
|
-
return 'Mobile'
|
|
1207
|
-
} else {
|
|
1208
|
-
return 'Desktop'
|
|
1209
|
-
}
|
|
1210
|
-
},
|
|
1211
|
-
|
|
1212
|
-
referringDomain: function (referrer) {
|
|
1213
|
-
var split = referrer.split('/');
|
|
1214
|
-
if (split.length >= 3) {
|
|
1215
|
-
return split[2]
|
|
1216
|
-
}
|
|
1217
|
-
return ''
|
|
1218
|
-
},
|
|
1219
|
-
|
|
1220
|
-
properties: function () {
|
|
1221
|
-
return _.extend(
|
|
1222
|
-
_.strip_empty_properties({
|
|
1223
|
-
$os: _.info.os(),
|
|
1224
|
-
$browser: _.info.browser(userAgent, navigator$1.vendor, window.opera),
|
|
1225
|
-
$device: _.info.device(userAgent),
|
|
1226
|
-
$device_type: _.info.deviceType(userAgent),
|
|
1227
|
-
}),
|
|
1228
|
-
{
|
|
1229
|
-
$current_url: window.location.href,
|
|
1230
|
-
$host: window.location.host,
|
|
1231
|
-
$pathname: window.location.pathname,
|
|
1232
|
-
$browser_version: _.info.browserVersion(userAgent, navigator$1.vendor, window.opera),
|
|
1233
|
-
$screen_height: window.screen.height,
|
|
1234
|
-
$screen_width: window.screen.width,
|
|
1235
|
-
$viewport_height: window.innerHeight,
|
|
1236
|
-
$viewport_width: window.innerWidth,
|
|
1237
|
-
$lib: 'web',
|
|
1238
|
-
$lib_version: Config$1.LIB_VERSION,
|
|
1239
|
-
$insert_id: Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10),
|
|
1240
|
-
$time: _.timestamp() / 1000, // epoch time in seconds
|
|
1241
|
-
}
|
|
1242
|
-
)
|
|
1243
|
-
},
|
|
1244
|
-
|
|
1245
|
-
people_properties: function () {
|
|
1246
|
-
return _.extend(
|
|
1247
|
-
_.strip_empty_properties({
|
|
1248
|
-
$os: _.info.os(),
|
|
1249
|
-
$browser: _.info.browser(userAgent, navigator$1.vendor, window.opera),
|
|
1250
|
-
}),
|
|
1251
|
-
{
|
|
1252
|
-
$browser_version: _.info.browserVersion(userAgent, navigator$1.vendor, window.opera),
|
|
1253
|
-
}
|
|
1254
|
-
)
|
|
1255
|
-
},
|
|
1256
|
-
};
|
|
1257
|
-
|
|
1258
|
-
// EXPORTS (for closure compiler)
|
|
1259
|
-
_['isObject'] = _.isObject;
|
|
1260
|
-
_['isBlockedUA'] = _.isBlockedUA;
|
|
1261
|
-
_['isEmptyObject'] = _.isEmptyObject;
|
|
1262
|
-
_['info'] = _.info;
|
|
1263
|
-
_['info']['device'] = _.info.device;
|
|
1264
|
-
_['info']['browser'] = _.info.browser;
|
|
1265
|
-
_['info']['browserVersion'] = _.info.browserVersion;
|
|
1266
|
-
_['info']['properties'] = _.info.properties;
|
|
1267
|
-
|
|
1268
|
-
var DOMAIN_MATCH_REGEX = /[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i;
|
|
1269
|
-
|
|
1270
|
-
// Methods partially borrowed from quirksmode.org/js/cookies.html
|
|
1271
|
-
const cookieStore = {
|
|
1272
|
-
get: function (name) {
|
|
1273
|
-
try {
|
|
1274
|
-
var nameEQ = name + '=';
|
|
1275
|
-
var ca = document.cookie.split(';');
|
|
1276
|
-
for (var i = 0; i < ca.length; i++) {
|
|
1277
|
-
var c = ca[i];
|
|
1278
|
-
while (c.charAt(0) == ' ') {
|
|
1279
|
-
c = c.substring(1, c.length);
|
|
1280
|
-
}
|
|
1281
|
-
if (c.indexOf(nameEQ) === 0) {
|
|
1282
|
-
return decodeURIComponent(c.substring(nameEQ.length, c.length))
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
} catch (err) {}
|
|
1286
|
-
return null
|
|
1287
|
-
},
|
|
1288
|
-
|
|
1289
|
-
parse: function (name) {
|
|
1290
|
-
var cookie;
|
|
1291
|
-
try {
|
|
1292
|
-
cookie = JSON.parse(cookieStore.get(name)) || {};
|
|
1293
|
-
} catch (err) {
|
|
1294
|
-
// noop
|
|
1295
|
-
}
|
|
1296
|
-
return cookie
|
|
1297
|
-
},
|
|
1298
|
-
|
|
1299
|
-
set: function (name, value, days, cross_subdomain, is_secure) {
|
|
1300
|
-
try {
|
|
1301
|
-
var cdomain = '',
|
|
1302
|
-
expires = '',
|
|
1303
|
-
secure = '';
|
|
1304
|
-
|
|
1305
|
-
if (cross_subdomain) {
|
|
1306
|
-
var matches = document.location.hostname.match(DOMAIN_MATCH_REGEX),
|
|
1307
|
-
domain = matches ? matches[0] : '';
|
|
1308
|
-
|
|
1309
|
-
cdomain = domain ? '; domain=.' + domain : '';
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
if (days) {
|
|
1313
|
-
var date = new Date();
|
|
1314
|
-
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
|
1315
|
-
expires = '; expires=' + date.toGMTString();
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
if (is_secure) {
|
|
1319
|
-
secure = '; secure';
|
|
1320
|
-
}
|
|
1321
|
-
|
|
1322
|
-
var new_cookie_val =
|
|
1323
|
-
name + '=' + encodeURIComponent(JSON.stringify(value)) + expires + '; path=/' + cdomain + secure;
|
|
1324
|
-
document.cookie = new_cookie_val;
|
|
1325
|
-
return new_cookie_val
|
|
1326
|
-
} catch (err) {
|
|
1327
|
-
return
|
|
1328
|
-
}
|
|
1329
|
-
},
|
|
1330
|
-
|
|
1331
|
-
remove: function (name, cross_subdomain) {
|
|
1332
|
-
try {
|
|
1333
|
-
cookieStore.set(name, '', -1, cross_subdomain);
|
|
1334
|
-
} catch (err) {
|
|
1335
|
-
return
|
|
1336
|
-
}
|
|
1337
|
-
},
|
|
1338
|
-
};
|
|
1339
|
-
|
|
1340
|
-
var _localStorage_supported = null;
|
|
1341
|
-
const localStore = {
|
|
1342
|
-
is_supported: function () {
|
|
1343
|
-
if (_localStorage_supported !== null) {
|
|
1344
|
-
return _localStorage_supported
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
var supported = true;
|
|
1348
|
-
if (window) {
|
|
1349
|
-
try {
|
|
1350
|
-
var key = '__mplssupport__',
|
|
1351
|
-
val = 'xyz';
|
|
1352
|
-
localStore.set(key, val);
|
|
1353
|
-
if (localStore.get(key) !== '"xyz"') {
|
|
1354
|
-
supported = false;
|
|
1355
|
-
}
|
|
1356
|
-
localStore.remove(key);
|
|
1357
|
-
} catch (err) {
|
|
1358
|
-
supported = false;
|
|
1359
|
-
}
|
|
1360
|
-
} else {
|
|
1361
|
-
supported = false;
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
_localStorage_supported = supported;
|
|
1365
|
-
return supported
|
|
1366
|
-
},
|
|
1367
|
-
|
|
1368
|
-
error: function (msg) {
|
|
1369
|
-
},
|
|
1370
|
-
|
|
1371
|
-
get: function (name) {
|
|
1372
|
-
try {
|
|
1373
|
-
return window.localStorage.getItem(name)
|
|
1374
|
-
} catch (err) {
|
|
1375
|
-
localStore.error(err);
|
|
1376
|
-
}
|
|
1377
|
-
return null
|
|
1378
|
-
},
|
|
1379
|
-
|
|
1380
|
-
parse: function (name) {
|
|
1381
|
-
try {
|
|
1382
|
-
return JSON.parse(localStore.get(name)) || {}
|
|
1383
|
-
} catch (err) {
|
|
1384
|
-
// noop
|
|
1385
|
-
}
|
|
1386
|
-
return null
|
|
1387
|
-
},
|
|
1388
|
-
|
|
1389
|
-
set: function (name, value) {
|
|
1390
|
-
try {
|
|
1391
|
-
window.localStorage.setItem(name, JSON.stringify(value));
|
|
1392
|
-
} catch (err) {
|
|
1393
|
-
localStore.error(err);
|
|
1394
|
-
}
|
|
1395
|
-
},
|
|
1396
|
-
|
|
1397
|
-
remove: function (name) {
|
|
1398
|
-
try {
|
|
1399
|
-
window.localStorage.removeItem(name);
|
|
1400
|
-
} catch (err) {
|
|
1401
|
-
localStore.error(err);
|
|
1402
|
-
}
|
|
1403
|
-
},
|
|
1404
|
-
};
|
|
1405
|
-
|
|
1406
|
-
// Use localstorage for most data but still use cookie for distinct_id
|
|
1407
|
-
// This solves issues with cookies having too much data in them causing headers too large
|
|
1408
|
-
// Also makes sure we don't have to send a ton of data to the server
|
|
1409
|
-
const localPlusCookieStore = {
|
|
1410
|
-
...localStore,
|
|
1411
|
-
parse: function (name) {
|
|
1412
|
-
try {
|
|
1413
|
-
let extend = {};
|
|
1414
|
-
try {
|
|
1415
|
-
// See if there's a cookie stored with data.
|
|
1416
|
-
extend = cookieStore.parse(name) || {};
|
|
1417
|
-
if (extend['distinct_id']) {
|
|
1418
|
-
cookieStore.set(name, { distinct_id: extend['distinct_id'] });
|
|
1419
|
-
}
|
|
1420
|
-
} catch (err) {}
|
|
1421
|
-
const value = _.extend(extend, JSON.parse(localStore.get(name) || '{}'));
|
|
1422
|
-
localStore.set(name, value);
|
|
1423
|
-
return value
|
|
1424
|
-
} catch (err) {
|
|
1425
|
-
// noop
|
|
1426
|
-
}
|
|
1427
|
-
return null
|
|
1428
|
-
},
|
|
1429
|
-
|
|
1430
|
-
set: function (name, value) {
|
|
1431
|
-
try {
|
|
1432
|
-
localStore.set(name, value);
|
|
1433
|
-
if (value.distinct_id) {
|
|
1434
|
-
cookieStore.set(name, { distinct_id: value.distinct_id });
|
|
1435
|
-
}
|
|
1436
|
-
} catch (err) {
|
|
1437
|
-
localStore.error(err);
|
|
1438
|
-
}
|
|
1439
|
-
},
|
|
1440
|
-
|
|
1441
|
-
remove: function (name) {
|
|
1442
|
-
try {
|
|
1443
|
-
window.localStorage.removeItem(name);
|
|
1444
|
-
cookieStore.remove(name);
|
|
1445
|
-
} catch (err) {
|
|
1446
|
-
localStore.error(err);
|
|
1447
|
-
}
|
|
1448
|
-
},
|
|
1449
|
-
};
|
|
1450
|
-
|
|
1451
|
-
const memoryStorage = {};
|
|
1452
|
-
|
|
1453
|
-
// Storage that only lasts the length of the pageview if we don't want to use cookies
|
|
1454
|
-
const memoryStore = {
|
|
1455
|
-
is_supported: function () {
|
|
1456
|
-
return true
|
|
1457
|
-
},
|
|
1458
|
-
|
|
1459
|
-
error: function (msg) {
|
|
1460
|
-
},
|
|
1461
|
-
|
|
1462
|
-
parse: function (name) {
|
|
1463
|
-
return memoryStorage[name] || null
|
|
1464
|
-
},
|
|
1465
|
-
|
|
1466
|
-
set: function (name, value) {
|
|
1467
|
-
memoryStorage[name] = value;
|
|
1468
|
-
},
|
|
1469
|
-
|
|
1470
|
-
remove: function (name) {
|
|
1471
|
-
delete memoryStorage[name];
|
|
1472
|
-
},
|
|
1473
|
-
};
|
|
1474
|
-
|
|
1475
|
-
// Storage that only lasts the length of a tab/window. Survives page refreshes
|
|
1476
|
-
const sessionStore = {
|
|
1477
|
-
sessionStorageSupported: null,
|
|
1478
|
-
is_supported: function () {
|
|
1479
|
-
if (sessionStore.sessionStorageSupported !== null) {
|
|
1480
|
-
return sessionStore.sessionStorageSupported
|
|
1481
|
-
}
|
|
1482
|
-
sessionStore.sessionStorageSupported = true;
|
|
1483
|
-
if (window) {
|
|
1484
|
-
try {
|
|
1485
|
-
let key = '__support__',
|
|
1486
|
-
val = 'xyz';
|
|
1487
|
-
sessionStore.set(key, val);
|
|
1488
|
-
if (sessionStore.get(key) !== '"xyz"') {
|
|
1489
|
-
sessionStore.sessionStorageSupported = false;
|
|
1490
|
-
}
|
|
1491
|
-
sessionStore.remove(key);
|
|
1492
|
-
} catch (err) {
|
|
1493
|
-
sessionStore.sessionStorageSupported = false;
|
|
1494
|
-
}
|
|
1495
|
-
} else {
|
|
1496
|
-
sessionStore.sessionStorageSupported = false;
|
|
1497
|
-
}
|
|
1498
|
-
return sessionStore.sessionStorageSupported
|
|
1499
|
-
},
|
|
1500
|
-
error: function (msg) {
|
|
1501
|
-
if (Config.DEBUG) ;
|
|
1502
|
-
},
|
|
1503
|
-
|
|
1504
|
-
get: function (name) {
|
|
1505
|
-
try {
|
|
1506
|
-
return window.sessionStorage.getItem(name)
|
|
1507
|
-
} catch (err) {
|
|
1508
|
-
sessionStore.error(err);
|
|
1509
|
-
}
|
|
1510
|
-
return null
|
|
1511
|
-
},
|
|
1512
|
-
|
|
1513
|
-
parse: function (name) {
|
|
1514
|
-
try {
|
|
1515
|
-
return JSON.parse(sessionStore.get(name)) || null
|
|
1516
|
-
} catch (err) {
|
|
1517
|
-
// noop
|
|
1518
|
-
}
|
|
1519
|
-
return null
|
|
1520
|
-
},
|
|
1521
|
-
|
|
1522
|
-
set: function (name, value) {
|
|
1523
|
-
try {
|
|
1524
|
-
window.sessionStorage.setItem(name, JSON.stringify(value));
|
|
1525
|
-
} catch (err) {
|
|
1526
|
-
sessionStore.error(err);
|
|
1527
|
-
}
|
|
1528
|
-
},
|
|
1529
|
-
|
|
1530
|
-
remove: function (name) {
|
|
1531
|
-
try {
|
|
1532
|
-
window.sessionStorage.removeItem(name);
|
|
1533
|
-
} catch (err) {
|
|
1534
|
-
sessionStore.error(err);
|
|
1535
|
-
}
|
|
1536
|
-
},
|
|
1537
|
-
};
|
|
1538
|
-
|
|
1539
|
-
/* eslint camelcase: "off" */
|
|
1540
|
-
|
|
1541
|
-
/*
|
|
1542
|
-
* Constants
|
|
1543
|
-
*/
|
|
1544
|
-
/** @const */ var SET_QUEUE_KEY = '__mps';
|
|
1545
|
-
/** @const */ var SET_ONCE_QUEUE_KEY = '__mpso';
|
|
1546
|
-
/** @const */ var UNSET_QUEUE_KEY = '__mpus';
|
|
1547
|
-
/** @const */ var ADD_QUEUE_KEY = '__mpa';
|
|
1548
|
-
/** @const */ var APPEND_QUEUE_KEY = '__mpap';
|
|
1549
|
-
/** @const */ var REMOVE_QUEUE_KEY = '__mpr';
|
|
1550
|
-
/** @const */ var UNION_QUEUE_KEY = '__mpu';
|
|
1551
|
-
/** @const */ var CAMPAIGN_IDS_KEY = '__cmpns';
|
|
1552
|
-
/** @const */ var EVENT_TIMERS_KEY = '__timers';
|
|
1553
|
-
/** @const */ var SESSION_RECORDING_ENABLED = '$session_recording_enabled';
|
|
1554
|
-
/** @const */ var SESSION_ID = '$sesid';
|
|
1555
|
-
/** @const */ var ENABLED_FEATURE_FLAGS = '$enabled_feature_flags';
|
|
1556
|
-
/** @const */ var RESERVED_PROPERTIES = [
|
|
1557
|
-
SET_QUEUE_KEY,
|
|
1558
|
-
SET_ONCE_QUEUE_KEY,
|
|
1559
|
-
UNSET_QUEUE_KEY,
|
|
1560
|
-
ADD_QUEUE_KEY,
|
|
1561
|
-
APPEND_QUEUE_KEY,
|
|
1562
|
-
REMOVE_QUEUE_KEY,
|
|
1563
|
-
UNION_QUEUE_KEY,
|
|
1564
|
-
CAMPAIGN_IDS_KEY,
|
|
1565
|
-
EVENT_TIMERS_KEY,
|
|
1566
|
-
SESSION_RECORDING_ENABLED,
|
|
1567
|
-
SESSION_ID,
|
|
1568
|
-
ENABLED_FEATURE_FLAGS,
|
|
1569
|
-
];
|
|
1570
|
-
|
|
1571
|
-
/**
|
|
1572
|
-
* UserMaven Persistence Object
|
|
1573
|
-
* @constructor
|
|
1574
|
-
*/
|
|
1575
|
-
var UserMavenPersistence = function (config) {
|
|
1576
|
-
// clean chars that aren't accepted by the http spec for cookie values
|
|
1577
|
-
// https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
|
|
1578
|
-
let token = '';
|
|
1579
|
-
|
|
1580
|
-
if (config['token']) {
|
|
1581
|
-
token = config['token'].replace(/\+/g, 'PL').replace(/\//g, 'SL').replace(/=/g, 'EQ');
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
this['props'] = {};
|
|
1585
|
-
this.campaign_params_saved = false;
|
|
1586
|
-
|
|
1587
|
-
if (config['persistence_name']) {
|
|
1588
|
-
this.name = 'um_' + config['persistence_name'];
|
|
1589
|
-
} else {
|
|
1590
|
-
this.name = 'um_' + token + '_usermaven';
|
|
1591
|
-
}
|
|
1592
|
-
|
|
1593
|
-
var storage_type = config['persistence'];
|
|
1594
|
-
if (storage_type !== 'cookie' && storage_type.indexOf('localStorage') === -1 && storage_type !== 'memory') {
|
|
1595
|
-
console$1.critical('Unknown persistence type ' + storage_type + '; falling back to cookie');
|
|
1596
|
-
storage_type = config['persistence'] = 'cookie';
|
|
1597
|
-
}
|
|
1598
|
-
if (storage_type === 'localStorage' && localStore.is_supported()) {
|
|
1599
|
-
this.storage = localStore;
|
|
1600
|
-
} else if (storage_type === 'localStorage+cookie' && localPlusCookieStore.is_supported()) {
|
|
1601
|
-
this.storage = localPlusCookieStore;
|
|
1602
|
-
} else if (storage_type === 'memory') {
|
|
1603
|
-
this.storage = memoryStore;
|
|
1604
|
-
} else {
|
|
1605
|
-
this.storage = cookieStore;
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
|
-
this.load();
|
|
1609
|
-
this.update_config(config);
|
|
1610
|
-
this.save();
|
|
1611
|
-
};
|
|
1612
|
-
|
|
1613
|
-
UserMavenPersistence.prototype.properties = function () {
|
|
1614
|
-
var p = {};
|
|
1615
|
-
// Filter out reserved properties
|
|
1616
|
-
_.each(this['props'], function (v, k) {
|
|
1617
|
-
if (k === ENABLED_FEATURE_FLAGS && typeof v === 'object') {
|
|
1618
|
-
var keys = Object.keys(v);
|
|
1619
|
-
for (var i = 0; i < keys.length; i++) {
|
|
1620
|
-
p[`$feature/${keys[i]}`] = v[keys[i]];
|
|
1621
|
-
}
|
|
1622
|
-
} else if (!_.include(RESERVED_PROPERTIES, k)) {
|
|
1623
|
-
p[k] = v;
|
|
1624
|
-
}
|
|
1625
|
-
});
|
|
1626
|
-
return p
|
|
1627
|
-
};
|
|
1628
|
-
|
|
1629
|
-
UserMavenPersistence.prototype.load = function () {
|
|
1630
|
-
if (this.disabled) {
|
|
1631
|
-
return
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
var entry = this.storage.parse(this.name);
|
|
1635
|
-
|
|
1636
|
-
if (entry) {
|
|
1637
|
-
this['props'] = _.extend({}, entry);
|
|
1638
|
-
}
|
|
1639
|
-
};
|
|
1640
|
-
|
|
1641
|
-
UserMavenPersistence.prototype.save = function () {
|
|
1642
|
-
if (this.disabled) {
|
|
1643
|
-
return
|
|
1644
|
-
}
|
|
1645
|
-
this.storage.set(this.name, this['props'], this.expire_days, this.cross_subdomain, this.secure);
|
|
1646
|
-
};
|
|
1647
|
-
|
|
1648
|
-
UserMavenPersistence.prototype.remove = function () {
|
|
1649
|
-
// remove both domain and subdomain cookies
|
|
1650
|
-
this.storage.remove(this.name, false);
|
|
1651
|
-
this.storage.remove(this.name, true);
|
|
1652
|
-
};
|
|
1653
|
-
|
|
1654
|
-
// removes the storage entry and deletes all loaded data
|
|
1655
|
-
// forced name for tests
|
|
1656
|
-
UserMavenPersistence.prototype.clear = function () {
|
|
1657
|
-
this.remove();
|
|
1658
|
-
this['props'] = {};
|
|
1659
|
-
};
|
|
1660
|
-
|
|
1661
|
-
/**
|
|
1662
|
-
* @param {Object} props
|
|
1663
|
-
* @param {*=} default_value
|
|
1664
|
-
* @param {number=} days
|
|
1665
|
-
*/
|
|
1666
|
-
UserMavenPersistence.prototype.register_once = function (props, default_value, days) {
|
|
1667
|
-
if (_.isObject(props)) {
|
|
1668
|
-
if (typeof default_value === 'undefined') {
|
|
1669
|
-
default_value = 'None';
|
|
1670
|
-
}
|
|
1671
|
-
this.expire_days = typeof days === 'undefined' ? this.default_expiry : days;
|
|
1672
|
-
|
|
1673
|
-
_.each(
|
|
1674
|
-
props,
|
|
1675
|
-
function (val, prop) {
|
|
1676
|
-
if (!this['props'].hasOwnProperty(prop) || this['props'][prop] === default_value) {
|
|
1677
|
-
this['props'][prop] = val;
|
|
1678
|
-
}
|
|
1679
|
-
},
|
|
1680
|
-
this
|
|
1681
|
-
);
|
|
1682
|
-
|
|
1683
|
-
this.save();
|
|
1684
|
-
|
|
1685
|
-
return true
|
|
1686
|
-
}
|
|
1687
|
-
return false
|
|
1688
|
-
};
|
|
1689
|
-
|
|
1690
|
-
/**
|
|
1691
|
-
* @param {Object} props
|
|
1692
|
-
* @param {number=} days
|
|
1693
|
-
*/
|
|
1694
|
-
UserMavenPersistence.prototype.register = function (props, days) {
|
|
1695
|
-
if (_.isObject(props)) {
|
|
1696
|
-
this.expire_days = typeof days === 'undefined' ? this.default_expiry : days;
|
|
1697
|
-
|
|
1698
|
-
_.extend(this['props'], props);
|
|
1699
|
-
|
|
1700
|
-
this.save();
|
|
1701
|
-
|
|
1702
|
-
return true
|
|
1703
|
-
}
|
|
1704
|
-
return false
|
|
1705
|
-
};
|
|
1706
|
-
|
|
1707
|
-
UserMavenPersistence.prototype.unregister = function (prop) {
|
|
1708
|
-
if (prop in this['props']) {
|
|
1709
|
-
delete this['props'][prop];
|
|
1710
|
-
this.save();
|
|
1711
|
-
}
|
|
1712
|
-
};
|
|
1713
|
-
|
|
1714
|
-
UserMavenPersistence.prototype.update_campaign_params = function () {
|
|
1715
|
-
if (!this.campaign_params_saved) {
|
|
1716
|
-
this.register(_.info.campaignParams());
|
|
1717
|
-
this.campaign_params_saved = true;
|
|
1718
|
-
}
|
|
1719
|
-
};
|
|
1720
|
-
|
|
1721
|
-
UserMavenPersistence.prototype.update_search_keyword = function (referrer) {
|
|
1722
|
-
this.register(_.info.searchInfo(referrer));
|
|
1723
|
-
};
|
|
1724
|
-
|
|
1725
|
-
// EXPORTED METHOD, we test this directly.
|
|
1726
|
-
UserMavenPersistence.prototype.update_referrer_info = function (referrer) {
|
|
1727
|
-
// If referrer doesn't exist, we want to note the fact that it was type-in traffic.
|
|
1728
|
-
// Register once, so first touch
|
|
1729
|
-
this.register_once(
|
|
1730
|
-
{
|
|
1731
|
-
$initial_referrer: referrer || '$direct',
|
|
1732
|
-
$initial_referring_domain: _.info.referringDomain(referrer) || '$direct',
|
|
1733
|
-
},
|
|
1734
|
-
''
|
|
1735
|
-
);
|
|
1736
|
-
// Register the current referrer but override if it's different, hence register
|
|
1737
|
-
this.register({
|
|
1738
|
-
$referrer: referrer || this['props']['$referrer'] || '$direct',
|
|
1739
|
-
$referring_domain: _.info.referringDomain(referrer) || this['props']['$referring_domain'] || '$direct',
|
|
1740
|
-
});
|
|
1741
|
-
};
|
|
1742
|
-
|
|
1743
|
-
UserMavenPersistence.prototype.get_referrer_info = function () {
|
|
1744
|
-
return _.strip_empty_properties({
|
|
1745
|
-
$initial_referrer: this['props']['$initial_referrer'],
|
|
1746
|
-
$initial_referring_domain: this['props']['$initial_referring_domain'],
|
|
1747
|
-
})
|
|
1748
|
-
};
|
|
1749
|
-
|
|
1750
|
-
// safely fills the passed in object with stored properties,
|
|
1751
|
-
// does not override any properties defined in both
|
|
1752
|
-
// returns the passed in object
|
|
1753
|
-
UserMavenPersistence.prototype.safe_merge = function (props) {
|
|
1754
|
-
_.each(this['props'], function (val, prop) {
|
|
1755
|
-
if (!(prop in props)) {
|
|
1756
|
-
props[prop] = val;
|
|
1757
|
-
}
|
|
1758
|
-
});
|
|
1759
|
-
|
|
1760
|
-
return props
|
|
1761
|
-
};
|
|
1762
|
-
|
|
1763
|
-
UserMavenPersistence.prototype.update_config = function (config) {
|
|
1764
|
-
this.default_expiry = this.expire_days = config['cookie_expiration'];
|
|
1765
|
-
this.set_disabled(config['disable_persistence']);
|
|
1766
|
-
this.set_cross_subdomain(config['cross_subdomain_cookie']);
|
|
1767
|
-
this.set_secure(config['secure_cookie']);
|
|
1768
|
-
};
|
|
1769
|
-
|
|
1770
|
-
UserMavenPersistence.prototype.set_disabled = function (disabled) {
|
|
1771
|
-
this.disabled = disabled;
|
|
1772
|
-
if (this.disabled) {
|
|
1773
|
-
this.remove();
|
|
1774
|
-
} else {
|
|
1775
|
-
this.save();
|
|
1776
|
-
}
|
|
1777
|
-
};
|
|
1778
|
-
|
|
1779
|
-
UserMavenPersistence.prototype.set_cross_subdomain = function (cross_subdomain) {
|
|
1780
|
-
if (cross_subdomain !== this.cross_subdomain) {
|
|
1781
|
-
this.cross_subdomain = cross_subdomain;
|
|
1782
|
-
this.remove();
|
|
1783
|
-
this.save();
|
|
1784
|
-
}
|
|
1785
|
-
};
|
|
1786
|
-
|
|
1787
|
-
UserMavenPersistence.prototype.get_cross_subdomain = function () {
|
|
1788
|
-
return this.cross_subdomain
|
|
1789
|
-
};
|
|
1790
|
-
|
|
1791
|
-
UserMavenPersistence.prototype.set_secure = function (secure) {
|
|
1792
|
-
if (secure !== this.secure) {
|
|
1793
|
-
this.secure = secure ? true : false;
|
|
1794
|
-
this.remove();
|
|
1795
|
-
this.save();
|
|
551
|
+
// let bomb = { toString : undefined, valueOf: function(o) { return "function BOMBA!"; }};
|
|
552
|
+
var _isFunction = function (f) {
|
|
553
|
+
try {
|
|
554
|
+
return /^\s*\bfunction\b/.test(f);
|
|
555
|
+
}
|
|
556
|
+
catch (x) {
|
|
557
|
+
return false;
|
|
1796
558
|
}
|
|
1797
559
|
};
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
var timers = this['props'][EVENT_TIMERS_KEY] || {};
|
|
1801
|
-
timers[event_name] = timestamp;
|
|
1802
|
-
this['props'][EVENT_TIMERS_KEY] = timers;
|
|
1803
|
-
this.save();
|
|
1804
|
-
};
|
|
1805
|
-
|
|
1806
|
-
UserMavenPersistence.prototype.remove_event_timer = function (event_name) {
|
|
1807
|
-
var timers = this['props'][EVENT_TIMERS_KEY] || {};
|
|
1808
|
-
var timestamp = timers[event_name];
|
|
1809
|
-
if (!_.isUndefined(timestamp)) {
|
|
1810
|
-
delete this['props'][EVENT_TIMERS_KEY][event_name];
|
|
1811
|
-
this.save();
|
|
1812
|
-
}
|
|
1813
|
-
return timestamp
|
|
560
|
+
var _isUndefined = function (obj) {
|
|
561
|
+
return obj === void 0;
|
|
1814
562
|
};
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
563
|
+
var _register_event = (function () {
|
|
564
|
+
// written by Dean Edwards, 2005
|
|
565
|
+
// with input from Tino Zijdel - crisp@xs4all.nl
|
|
566
|
+
// with input from Carl Sverre - mail@carlsverre.com
|
|
567
|
+
// with input from PostHog
|
|
568
|
+
// http://dean.edwards.name/weblog/2005/10/add-event/
|
|
569
|
+
// https://gist.github.com/1930440
|
|
570
|
+
/**
|
|
571
|
+
* @param {Object} element
|
|
572
|
+
* @param {string} type
|
|
573
|
+
* @param {function(...*)} handler
|
|
574
|
+
* @param {boolean=} oldSchool
|
|
575
|
+
* @param {boolean=} useCapture
|
|
576
|
+
*/
|
|
577
|
+
var register_event = function (element, type, handler, oldSchool, useCapture) {
|
|
578
|
+
if (!element) {
|
|
579
|
+
getLogger().error('No valid element provided to register_event');
|
|
580
|
+
return;
|
|
1827
581
|
}
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
582
|
+
if (element.addEventListener && !oldSchool) {
|
|
583
|
+
element.addEventListener(type, handler, !!useCapture);
|
|
584
|
+
}
|
|
585
|
+
else {
|
|
586
|
+
var ontype = 'on' + type;
|
|
587
|
+
var old_handler = element[ontype] // can be undefined
|
|
588
|
+
;
|
|
589
|
+
element[ontype] = makeHandler(element, handler, old_handler);
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
function makeHandler(element, new_handler, old_handlers) {
|
|
593
|
+
return function (event) {
|
|
594
|
+
event = event || fixEvent(window.event);
|
|
595
|
+
// this basically happens in firefox whenever another script
|
|
596
|
+
// overwrites the onload callback and doesn't pass the event
|
|
597
|
+
// object to previously defined callbacks. All the browsers
|
|
598
|
+
// that don't define window.event implement addEventListener
|
|
599
|
+
// so the dom_loaded handler will still be fired as usual.
|
|
600
|
+
if (!event) {
|
|
601
|
+
return undefined;
|
|
602
|
+
}
|
|
603
|
+
var ret = true;
|
|
604
|
+
var old_result;
|
|
605
|
+
if (_isFunction(old_handlers)) {
|
|
606
|
+
old_result = old_handlers(event);
|
|
1839
607
|
}
|
|
608
|
+
var new_result = new_handler.call(element, event);
|
|
609
|
+
if (false === old_result || false === new_result) {
|
|
610
|
+
ret = false;
|
|
611
|
+
}
|
|
612
|
+
return ret;
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
function fixEvent(event) {
|
|
616
|
+
if (event) {
|
|
617
|
+
event.preventDefault = fixEvent.preventDefault;
|
|
618
|
+
event.stopPropagation = fixEvent.stopPropagation;
|
|
1840
619
|
}
|
|
620
|
+
return event;
|
|
1841
621
|
}
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
622
|
+
fixEvent.preventDefault = function () {
|
|
623
|
+
this.returnValue = false;
|
|
624
|
+
};
|
|
625
|
+
fixEvent.stopPropagation = function () {
|
|
626
|
+
this.cancelBubble = true;
|
|
627
|
+
};
|
|
628
|
+
return register_event;
|
|
629
|
+
})();
|
|
630
|
+
var _safewrap = function (f) {
|
|
631
|
+
return function () {
|
|
632
|
+
var args = [];
|
|
633
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
634
|
+
args[_i] = arguments[_i];
|
|
1846
635
|
}
|
|
1847
|
-
|
|
1848
|
-
|
|
636
|
+
try {
|
|
637
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
638
|
+
// @ts-ignore
|
|
639
|
+
return f.apply(this, args);
|
|
1849
640
|
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
_setSessionId(sessionId, timestamp) {
|
|
1856
|
-
if (sessionId !== this.sessionId || timestamp !== this.timestamp) {
|
|
1857
|
-
this.timestamp = timestamp;
|
|
1858
|
-
this.sessionId = sessionId;
|
|
1859
|
-
this.persistence.register({ [SESSION_ID]: [timestamp, sessionId] });
|
|
641
|
+
catch (e) {
|
|
642
|
+
getLogger().error('Implementation error. Please turn on debug and contact support@usermaven.com.', e);
|
|
643
|
+
// if (Config.DEBUG) {
|
|
644
|
+
// getLogger.critical(e)
|
|
645
|
+
// }
|
|
1860
646
|
}
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
647
|
+
};
|
|
648
|
+
};
|
|
649
|
+
var _safewrap_instance_methods = function (obj) {
|
|
650
|
+
for (var func in obj) {
|
|
651
|
+
if (typeof obj[func] === 'function') {
|
|
652
|
+
obj[func] = _safewrap(obj[func]);
|
|
1866
653
|
}
|
|
1867
|
-
return this.persistence['props'][SESSION_ID] || [0, null]
|
|
1868
654
|
}
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
655
|
+
};
|
|
656
|
+
var COPY_IN_PROGRESS_ATTRIBUTE = typeof Symbol !== 'undefined' ? Symbol('__deepCircularCopyInProgress__') : '__deepCircularCopyInProgress__';
|
|
657
|
+
/**
|
|
658
|
+
* Deep copies an object.
|
|
659
|
+
* It handles cycles by replacing all references to them with `undefined`
|
|
660
|
+
* Also supports customizing native values
|
|
661
|
+
*
|
|
662
|
+
* @param value
|
|
663
|
+
* @param customizer
|
|
664
|
+
* @param [key] if provided this is the object key associated with the value to be copied. It allows the customizer function to have context when it runs
|
|
665
|
+
* @returns {{}|undefined|*}
|
|
666
|
+
*/
|
|
667
|
+
function deepCircularCopy(value, customizer, key) {
|
|
668
|
+
if (value !== Object(value))
|
|
669
|
+
return customizer ? customizer(value, key) : value; // primitive value
|
|
670
|
+
if (value[COPY_IN_PROGRESS_ATTRIBUTE])
|
|
671
|
+
return undefined;
|
|
672
|
+
value[COPY_IN_PROGRESS_ATTRIBUTE] = true;
|
|
673
|
+
var result;
|
|
674
|
+
if (_isArray(value)) {
|
|
675
|
+
result = [];
|
|
676
|
+
_eachArray(value, function (it) {
|
|
677
|
+
result.push(deepCircularCopy(it, customizer));
|
|
678
|
+
});
|
|
1874
679
|
}
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
timestamp = timestamp || new Date().getTime();
|
|
1892
|
-
|
|
1893
|
-
let [lastTimestamp, sessionId] = this._getSessionId();
|
|
1894
|
-
let windowId = this._getWindowId();
|
|
1895
|
-
|
|
1896
|
-
if (!sessionId || (Math.abs(timestamp - lastTimestamp) > this.session_change_threshold)) {
|
|
1897
|
-
sessionId = _.UUID();
|
|
1898
|
-
windowId = _.UUID();
|
|
1899
|
-
} else if (!windowId) {
|
|
1900
|
-
windowId = _.UUID();
|
|
680
|
+
else {
|
|
681
|
+
result = {};
|
|
682
|
+
_each(value, function (val, key) {
|
|
683
|
+
if (key !== COPY_IN_PROGRESS_ATTRIBUTE) {
|
|
684
|
+
result[key] = deepCircularCopy(val, customizer, key);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
delete value[COPY_IN_PROGRESS_ATTRIBUTE];
|
|
689
|
+
return result;
|
|
690
|
+
}
|
|
691
|
+
var LONG_STRINGS_ALLOW_LIST = ['$performance_raw'];
|
|
692
|
+
function _copyAndTruncateStrings(object, maxStringLength) {
|
|
693
|
+
return deepCircularCopy(object, function (value, key) {
|
|
694
|
+
if (key && LONG_STRINGS_ALLOW_LIST.indexOf(key) > -1) {
|
|
695
|
+
return value;
|
|
1901
696
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
this._setWindowId(windowId);
|
|
1906
|
-
this._setSessionId(sessionId, newTimestamp);
|
|
1907
|
-
return {
|
|
1908
|
-
session_id: sessionId,
|
|
1909
|
-
window_id: windowId,
|
|
697
|
+
if (typeof value === 'string' && maxStringLength !== null) {
|
|
698
|
+
return value.slice(0, maxStringLength);
|
|
1910
699
|
}
|
|
1911
|
-
|
|
700
|
+
return value;
|
|
701
|
+
});
|
|
1912
702
|
}
|
|
1913
703
|
|
|
1914
704
|
/*
|
|
@@ -1919,15 +709,15 @@ class SessionIdManager {
|
|
|
1919
709
|
function getClassName(el) {
|
|
1920
710
|
switch (typeof el.className) {
|
|
1921
711
|
case 'string':
|
|
1922
|
-
return el.className
|
|
712
|
+
return el.className;
|
|
713
|
+
// TODO: when is this ever used?
|
|
1923
714
|
case 'object': // handle cases where className might be SVGAnimatedString or some other type
|
|
1924
|
-
return el.className.baseVal || el.getAttribute('class') || ''
|
|
715
|
+
return ('baseVal' in el.className ? el.className.baseVal : null) || el.getAttribute('class') || '';
|
|
1925
716
|
default:
|
|
1926
717
|
// future proof
|
|
1927
|
-
return ''
|
|
718
|
+
return '';
|
|
1928
719
|
}
|
|
1929
720
|
}
|
|
1930
|
-
|
|
1931
721
|
/*
|
|
1932
722
|
* Get the direct text content of an element, protecting against sensitive data collection.
|
|
1933
723
|
* Concats textContent of each of the element's text node children; this avoids potential
|
|
@@ -1939,11 +729,10 @@ function getClassName(el) {
|
|
|
1939
729
|
*/
|
|
1940
730
|
function getSafeText(el) {
|
|
1941
731
|
var elText = '';
|
|
1942
|
-
|
|
1943
732
|
if (shouldCaptureElement(el) && !isSensitiveElement(el) && el.childNodes && el.childNodes.length) {
|
|
1944
|
-
|
|
733
|
+
_each(el.childNodes, function (child) {
|
|
1945
734
|
if (isTextNode(child) && child.textContent) {
|
|
1946
|
-
elText +=
|
|
735
|
+
elText += _trim(child.textContent)
|
|
1947
736
|
// scrub potentially sensitive values
|
|
1948
737
|
.split(/(\s+)/)
|
|
1949
738
|
.filter(shouldCaptureValue)
|
|
@@ -1956,19 +745,16 @@ function getSafeText(el) {
|
|
|
1956
745
|
}
|
|
1957
746
|
});
|
|
1958
747
|
}
|
|
1959
|
-
|
|
1960
|
-
return _.trim(elText)
|
|
748
|
+
return _trim(elText);
|
|
1961
749
|
}
|
|
1962
|
-
|
|
1963
750
|
/*
|
|
1964
751
|
* Check whether an element has nodeType Node.ELEMENT_NODE
|
|
1965
752
|
* @param {Element} el - element to check
|
|
1966
753
|
* @returns {boolean} whether el is of the correct nodeType
|
|
1967
754
|
*/
|
|
1968
755
|
function isElementNode(el) {
|
|
1969
|
-
return el && el.nodeType === 1 // Node.ELEMENT_NODE - use integer constant for browser portability
|
|
756
|
+
return !!el && el.nodeType === 1; // Node.ELEMENT_NODE - use integer constant for browser portability
|
|
1970
757
|
}
|
|
1971
|
-
|
|
1972
758
|
/*
|
|
1973
759
|
* Check whether an element is of a given tag type.
|
|
1974
760
|
* Due to potential reference discrepancies (such as the webcomponents.js polyfill),
|
|
@@ -1980,18 +766,24 @@ function isElementNode(el) {
|
|
|
1980
766
|
* @returns {boolean} whether el is of the given tag type
|
|
1981
767
|
*/
|
|
1982
768
|
function isTag(el, tag) {
|
|
1983
|
-
return el && el.tagName && el.tagName.toLowerCase() === tag.toLowerCase()
|
|
769
|
+
return !!el && !!el.tagName && el.tagName.toLowerCase() === tag.toLowerCase();
|
|
1984
770
|
}
|
|
1985
|
-
|
|
1986
771
|
/*
|
|
1987
772
|
* Check whether an element has nodeType Node.TEXT_NODE
|
|
1988
773
|
* @param {Element} el - element to check
|
|
1989
774
|
* @returns {boolean} whether el is of the correct nodeType
|
|
1990
775
|
*/
|
|
1991
776
|
function isTextNode(el) {
|
|
1992
|
-
return el && el.nodeType === 3 // Node.TEXT_NODE - use integer constant for browser portability
|
|
777
|
+
return !!el && el.nodeType === 3; // Node.TEXT_NODE - use integer constant for browser portability
|
|
778
|
+
}
|
|
779
|
+
/*
|
|
780
|
+
* Check whether an element has nodeType Node.DOCUMENT_FRAGMENT_NODE
|
|
781
|
+
* @param {Element} el - element to check
|
|
782
|
+
* @returns {boolean} whether el is of the correct nodeType
|
|
783
|
+
*/
|
|
784
|
+
function isDocumentFragment(el) {
|
|
785
|
+
return !!el && el.nodeType === 11; // Node.DOCUMENT_FRAGMENT_NODE - use integer constant for browser portability
|
|
1993
786
|
}
|
|
1994
|
-
|
|
1995
787
|
var usefulElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'label'];
|
|
1996
788
|
/*
|
|
1997
789
|
* Check whether a DOM event should be "captured" or if it may contain sentitive data
|
|
@@ -2002,60 +794,56 @@ var usefulElements = ['a', 'button', 'form', 'input', 'select', 'textarea', 'lab
|
|
|
2002
794
|
*/
|
|
2003
795
|
function shouldCaptureDomEvent(el, event) {
|
|
2004
796
|
if (!el || isTag(el, 'html') || !isElementNode(el)) {
|
|
2005
|
-
return false
|
|
797
|
+
return false;
|
|
2006
798
|
}
|
|
2007
|
-
|
|
2008
799
|
var parentIsUsefulElement = false;
|
|
2009
|
-
var targetElementList = [el];
|
|
800
|
+
var targetElementList = [el]; // TODO: remove this var, it's never queried
|
|
2010
801
|
var parentNode = true;
|
|
2011
802
|
var curEl = el;
|
|
2012
803
|
while (curEl.parentNode && !isTag(curEl, 'body')) {
|
|
2013
804
|
// If element is a shadow root, we skip it
|
|
2014
|
-
if (curEl.parentNode
|
|
805
|
+
if (isDocumentFragment(curEl.parentNode)) {
|
|
2015
806
|
targetElementList.push(curEl.parentNode.host);
|
|
2016
807
|
curEl = curEl.parentNode.host;
|
|
2017
|
-
continue
|
|
808
|
+
continue;
|
|
2018
809
|
}
|
|
2019
|
-
parentNode = curEl.parentNode;
|
|
2020
|
-
if (!parentNode)
|
|
810
|
+
parentNode = curEl.parentNode || false;
|
|
811
|
+
if (!parentNode)
|
|
812
|
+
break;
|
|
2021
813
|
if (usefulElements.indexOf(parentNode.tagName.toLowerCase()) > -1) {
|
|
2022
814
|
parentIsUsefulElement = true;
|
|
2023
|
-
}
|
|
2024
|
-
|
|
2025
|
-
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
var compStyles_1 = window.getComputedStyle(parentNode);
|
|
818
|
+
if (compStyles_1 && compStyles_1.getPropertyValue('cursor') === 'pointer') {
|
|
2026
819
|
parentIsUsefulElement = true;
|
|
2027
820
|
}
|
|
2028
821
|
}
|
|
2029
|
-
|
|
2030
822
|
targetElementList.push(parentNode);
|
|
2031
823
|
curEl = parentNode;
|
|
2032
824
|
}
|
|
2033
|
-
|
|
2034
|
-
let compStyles = window.getComputedStyle(el);
|
|
825
|
+
var compStyles = window.getComputedStyle(el);
|
|
2035
826
|
if (compStyles && compStyles.getPropertyValue('cursor') === 'pointer' && event.type === 'click') {
|
|
2036
|
-
return true
|
|
827
|
+
return true;
|
|
2037
828
|
}
|
|
2038
|
-
|
|
2039
829
|
var tag = el.tagName.toLowerCase();
|
|
2040
830
|
switch (tag) {
|
|
2041
831
|
case 'html':
|
|
2042
|
-
return false
|
|
832
|
+
return false;
|
|
2043
833
|
case 'form':
|
|
2044
|
-
return event.type === 'submit'
|
|
834
|
+
return event.type === 'submit';
|
|
2045
835
|
case 'input':
|
|
2046
|
-
return event.type === 'change' || event.type === 'click'
|
|
836
|
+
return event.type === 'change' || event.type === 'click';
|
|
2047
837
|
case 'select':
|
|
2048
838
|
case 'textarea':
|
|
2049
|
-
return event.type === 'change' || event.type === 'click'
|
|
839
|
+
return event.type === 'change' || event.type === 'click';
|
|
2050
840
|
default:
|
|
2051
|
-
if (parentIsUsefulElement)
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
(usefulElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true')
|
|
2055
|
-
)
|
|
841
|
+
if (parentIsUsefulElement)
|
|
842
|
+
return event.type === 'click';
|
|
843
|
+
return (event.type === 'click' &&
|
|
844
|
+
(usefulElements.indexOf(tag) > -1 || el.getAttribute('contenteditable') === 'true'));
|
|
2056
845
|
}
|
|
2057
846
|
}
|
|
2058
|
-
|
|
2059
847
|
/*
|
|
2060
848
|
* Check whether a DOM element should be "captured" or if it may contain sentitive data
|
|
2061
849
|
* using a variety of heuristics.
|
|
@@ -2065,40 +853,38 @@ function shouldCaptureDomEvent(el, event) {
|
|
|
2065
853
|
function shouldCaptureElement(el) {
|
|
2066
854
|
for (var curEl = el; curEl.parentNode && !isTag(curEl, 'body'); curEl = curEl.parentNode) {
|
|
2067
855
|
var classes = getClassName(curEl).split(' ');
|
|
2068
|
-
if (
|
|
2069
|
-
return false
|
|
856
|
+
if (_includes(classes, 'ph-sensitive') || _includes(classes, 'ph-no-capture')) {
|
|
857
|
+
return false;
|
|
2070
858
|
}
|
|
2071
859
|
}
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
return true
|
|
860
|
+
if (_includes(getClassName(el).split(' '), 'ph-include')) {
|
|
861
|
+
return true;
|
|
2075
862
|
}
|
|
2076
|
-
|
|
2077
863
|
// don't include hidden or password fields
|
|
2078
864
|
var type = el.type || '';
|
|
2079
865
|
if (typeof type === 'string') {
|
|
2080
866
|
// it's possible for el.type to be a DOM element if el is a form with a child input[name="type"]
|
|
2081
867
|
switch (type.toLowerCase()) {
|
|
2082
868
|
case 'hidden':
|
|
2083
|
-
return false
|
|
869
|
+
return false;
|
|
2084
870
|
case 'password':
|
|
2085
|
-
return false
|
|
871
|
+
return false;
|
|
2086
872
|
}
|
|
2087
873
|
}
|
|
2088
|
-
|
|
2089
874
|
// filter out data from fields that look like sensitive fields
|
|
2090
875
|
var name = el.name || el.id || '';
|
|
876
|
+
// See https://github.com/posthog/posthog-js/issues/165
|
|
877
|
+
// Under specific circumstances a bug caused .replace to be called on a DOM element
|
|
878
|
+
// instead of a string, removing the element from the page. Ensure this issue is mitigated.
|
|
2091
879
|
if (typeof name === 'string') {
|
|
2092
880
|
// it's possible for el.name or el.id to be a DOM element if el is a form with a child input[name="name"]
|
|
2093
881
|
var sensitiveNameRegex = /^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i;
|
|
2094
882
|
if (sensitiveNameRegex.test(name.replace(/[^a-zA-Z0-9]/g, ''))) {
|
|
2095
|
-
return false
|
|
883
|
+
return false;
|
|
2096
884
|
}
|
|
2097
885
|
}
|
|
2098
|
-
|
|
2099
|
-
return true
|
|
886
|
+
return true;
|
|
2100
887
|
}
|
|
2101
|
-
|
|
2102
888
|
/*
|
|
2103
889
|
* Check whether a DOM element is 'sensitive' and we should only capture limited data
|
|
2104
890
|
* @param {Element} el - element to check
|
|
@@ -2107,18 +893,15 @@ function shouldCaptureElement(el) {
|
|
|
2107
893
|
function isSensitiveElement(el) {
|
|
2108
894
|
// don't send data from inputs or similar elements since there will always be
|
|
2109
895
|
// a risk of clientside javascript placing sensitive data in attributes
|
|
2110
|
-
|
|
2111
|
-
if (
|
|
2112
|
-
(isTag(el, 'input') && !allowedInputTypes.includes(el.type)) ||
|
|
896
|
+
var allowedInputTypes = ['button', 'checkbox', 'submit', 'reset'];
|
|
897
|
+
if ((isTag(el, 'input') && !allowedInputTypes.includes(el.type)) ||
|
|
2113
898
|
isTag(el, 'select') ||
|
|
2114
899
|
isTag(el, 'textarea') ||
|
|
2115
|
-
el.getAttribute('contenteditable') === 'true'
|
|
2116
|
-
|
|
2117
|
-
return true
|
|
900
|
+
el.getAttribute('contenteditable') === 'true') {
|
|
901
|
+
return true;
|
|
2118
902
|
}
|
|
2119
|
-
return false
|
|
903
|
+
return false;
|
|
2120
904
|
}
|
|
2121
|
-
|
|
2122
905
|
/*
|
|
2123
906
|
* Check whether a string value should be "captured" or if it may contain sentitive data
|
|
2124
907
|
* using a variety of heuristics.
|
|
@@ -2126,30 +909,25 @@ function isSensitiveElement(el) {
|
|
|
2126
909
|
* @returns {boolean} whether the element should be captured
|
|
2127
910
|
*/
|
|
2128
911
|
function shouldCaptureValue(value) {
|
|
2129
|
-
if (value === null ||
|
|
2130
|
-
return false
|
|
912
|
+
if (value === null || _isUndefined(value)) {
|
|
913
|
+
return false;
|
|
2131
914
|
}
|
|
2132
|
-
|
|
2133
915
|
if (typeof value === 'string') {
|
|
2134
|
-
value =
|
|
2135
|
-
|
|
916
|
+
value = _trim(value);
|
|
2136
917
|
// check to see if input value looks like a credit card number
|
|
2137
918
|
// see: https://www.safaribooksonline.com/library/view/regular-expressions-cookbook/9781449327453/ch04s20.html
|
|
2138
919
|
var ccRegex = /^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/;
|
|
2139
920
|
if (ccRegex.test((value || '').replace(/[- ]/g, ''))) {
|
|
2140
|
-
return false
|
|
921
|
+
return false;
|
|
2141
922
|
}
|
|
2142
|
-
|
|
2143
923
|
// check to see if input value looks like a social security number
|
|
2144
924
|
var ssnRegex = /(^\d{3}-?\d{2}-?\d{4}$)/;
|
|
2145
925
|
if (ssnRegex.test(value)) {
|
|
2146
|
-
return false
|
|
926
|
+
return false;
|
|
2147
927
|
}
|
|
2148
928
|
}
|
|
2149
|
-
|
|
2150
|
-
return true
|
|
929
|
+
return true;
|
|
2151
930
|
}
|
|
2152
|
-
|
|
2153
931
|
/*
|
|
2154
932
|
* Check whether an attribute name is an Angular style attr (either _ngcontent or _nghost)
|
|
2155
933
|
* These update on each build and lead to noise in the element chain
|
|
@@ -2159,61 +937,58 @@ function shouldCaptureValue(value) {
|
|
|
2159
937
|
*/
|
|
2160
938
|
function isAngularStyleAttr(attributeName) {
|
|
2161
939
|
if (typeof attributeName === 'string') {
|
|
2162
|
-
return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost'
|
|
940
|
+
return attributeName.substring(0, 10) === '_ngcontent' || attributeName.substring(0, 7) === '_nghost';
|
|
2163
941
|
}
|
|
2164
|
-
return false
|
|
942
|
+
return false;
|
|
2165
943
|
}
|
|
2166
944
|
|
|
2167
945
|
// Naive rage click implementation: If mouse has not moved than RAGE_CLICK_THRESHOLD_PX
|
|
2168
946
|
// over RAGE_CLICK_CLICK_COUNT clicks with max RAGE_CLICK_TIMEOUT_MS between clicks, it's
|
|
2169
947
|
// counted as a rage click
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
948
|
+
var RAGE_CLICK_THRESHOLD_PX = 30;
|
|
949
|
+
var RAGE_CLICK_TIMEOUT_MS = 1000;
|
|
950
|
+
var RAGE_CLICK_CLICK_COUNT = 3;
|
|
951
|
+
var RageClick = /** @class */ (function () {
|
|
952
|
+
function RageClick(instance, enabled) {
|
|
953
|
+
if (enabled === void 0) { enabled = false; }
|
|
2176
954
|
this.clicks = [];
|
|
2177
955
|
this.instance = instance;
|
|
2178
956
|
this.enabled = enabled;
|
|
2179
957
|
}
|
|
2180
|
-
|
|
2181
|
-
click(x, y, timestamp) {
|
|
958
|
+
RageClick.prototype.click = function (x, y, timestamp) {
|
|
2182
959
|
if (!this.enabled) {
|
|
2183
|
-
return
|
|
960
|
+
return;
|
|
2184
961
|
}
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
if (
|
|
2188
|
-
lastClick &&
|
|
962
|
+
var lastClick = this.clicks[this.clicks.length - 1];
|
|
963
|
+
if (lastClick &&
|
|
2189
964
|
Math.abs(x - lastClick.x) + Math.abs(y - lastClick.y) < RAGE_CLICK_THRESHOLD_PX &&
|
|
2190
|
-
timestamp - lastClick.timestamp < RAGE_CLICK_TIMEOUT_MS
|
|
2191
|
-
|
|
2192
|
-
this.clicks.push({ x, y, timestamp });
|
|
2193
|
-
|
|
965
|
+
timestamp - lastClick.timestamp < RAGE_CLICK_TIMEOUT_MS) {
|
|
966
|
+
this.clicks.push({ x: x, y: y, timestamp: timestamp });
|
|
2194
967
|
if (this.clicks.length === RAGE_CLICK_CLICK_COUNT) {
|
|
2195
968
|
this.instance.capture('$rageclick');
|
|
2196
969
|
}
|
|
2197
|
-
} else {
|
|
2198
|
-
this.clicks = [{ x, y, timestamp }];
|
|
2199
970
|
}
|
|
2200
|
-
|
|
2201
|
-
}
|
|
971
|
+
else {
|
|
972
|
+
this.clicks = [{ x: x, y: y, timestamp: timestamp }];
|
|
973
|
+
}
|
|
974
|
+
};
|
|
975
|
+
return RageClick;
|
|
976
|
+
}());
|
|
2202
977
|
|
|
2203
978
|
var autocapture = {
|
|
2204
979
|
_initializedTokens: [],
|
|
2205
|
-
|
|
2206
980
|
_previousElementSibling: function (el) {
|
|
2207
981
|
if (el.previousElementSibling) {
|
|
2208
|
-
return el.previousElementSibling
|
|
2209
|
-
}
|
|
982
|
+
return el.previousElementSibling;
|
|
983
|
+
}
|
|
984
|
+
else {
|
|
985
|
+
var _el = el;
|
|
2210
986
|
do {
|
|
2211
|
-
|
|
2212
|
-
} while (
|
|
2213
|
-
return
|
|
987
|
+
_el = _el.previousSibling; // resolves to ChildNode->Node, which is Element's parent class
|
|
988
|
+
} while (_el && !isElementNode(_el));
|
|
989
|
+
return _el;
|
|
2214
990
|
}
|
|
2215
991
|
},
|
|
2216
|
-
|
|
2217
992
|
_getPropertiesFromElement: function (elem, maskInputs, maskText) {
|
|
2218
993
|
var tag_name = elem.tagName.toLowerCase();
|
|
2219
994
|
var props = {
|
|
@@ -2222,22 +997,19 @@ var autocapture = {
|
|
|
2222
997
|
if (usefulElements.indexOf(tag_name) > -1 && !maskText) {
|
|
2223
998
|
props['$el_text'] = getSafeText(elem);
|
|
2224
999
|
}
|
|
2225
|
-
|
|
2226
1000
|
var classes = getClassName(elem);
|
|
2227
1001
|
if (classes.length > 0)
|
|
2228
1002
|
props['classes'] = classes.split(' ').filter(function (c) {
|
|
2229
|
-
return c !== ''
|
|
1003
|
+
return c !== '';
|
|
2230
1004
|
});
|
|
2231
|
-
|
|
2232
|
-
_.each(elem.attributes, function (attr) {
|
|
1005
|
+
_each(elem.attributes, function (attr) {
|
|
2233
1006
|
// Only capture attributes we know are safe
|
|
2234
|
-
if (isSensitiveElement(elem) && ['name', 'id', 'class'].indexOf(attr.name) === -1)
|
|
2235
|
-
|
|
1007
|
+
if (isSensitiveElement(elem) && ['name', 'id', 'class'].indexOf(attr.name) === -1)
|
|
1008
|
+
return;
|
|
2236
1009
|
if (!maskInputs && shouldCaptureValue(attr.value) && !isAngularStyleAttr(attr.name)) {
|
|
2237
1010
|
props['attr__' + attr.name] = attr.value;
|
|
2238
1011
|
}
|
|
2239
1012
|
});
|
|
2240
|
-
|
|
2241
1013
|
var nthChild = 1;
|
|
2242
1014
|
var nthOfType = 1;
|
|
2243
1015
|
var currentElem = elem;
|
|
@@ -2250,219 +1022,178 @@ var autocapture = {
|
|
|
2250
1022
|
}
|
|
2251
1023
|
props['nth_child'] = nthChild;
|
|
2252
1024
|
props['nth_of_type'] = nthOfType;
|
|
2253
|
-
|
|
2254
|
-
return props
|
|
1025
|
+
return props;
|
|
2255
1026
|
},
|
|
2256
|
-
|
|
2257
1027
|
_getDefaultProperties: function (eventType) {
|
|
2258
1028
|
return {
|
|
2259
1029
|
$event_type: eventType,
|
|
2260
1030
|
$ce_version: 1,
|
|
2261
|
-
}
|
|
1031
|
+
};
|
|
2262
1032
|
},
|
|
2263
|
-
|
|
2264
1033
|
_extractCustomPropertyValue: function (customProperty) {
|
|
2265
1034
|
var propValues = [];
|
|
2266
|
-
|
|
1035
|
+
_each(document.querySelectorAll(customProperty['css_selector']), function (matchedElem) {
|
|
2267
1036
|
var value;
|
|
2268
|
-
|
|
2269
1037
|
if (['input', 'select'].indexOf(matchedElem.tagName.toLowerCase()) > -1) {
|
|
2270
1038
|
value = matchedElem['value'];
|
|
2271
|
-
}
|
|
1039
|
+
}
|
|
1040
|
+
else if (matchedElem['textContent']) {
|
|
2272
1041
|
value = matchedElem['textContent'];
|
|
2273
1042
|
}
|
|
2274
|
-
|
|
2275
1043
|
if (shouldCaptureValue(value)) {
|
|
2276
1044
|
propValues.push(value);
|
|
2277
1045
|
}
|
|
2278
1046
|
});
|
|
2279
|
-
return propValues.join(', ')
|
|
1047
|
+
return propValues.join(', ');
|
|
2280
1048
|
},
|
|
2281
|
-
|
|
1049
|
+
// TODO: delete custom_properties after changeless typescript refactor
|
|
2282
1050
|
_getCustomProperties: function (targetElementList) {
|
|
2283
|
-
var
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
function (
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
}
|
|
2297
|
-
},
|
|
2298
|
-
this
|
|
2299
|
-
);
|
|
2300
|
-
},
|
|
2301
|
-
this
|
|
2302
|
-
);
|
|
2303
|
-
},
|
|
2304
|
-
this
|
|
2305
|
-
);
|
|
2306
|
-
return props
|
|
1051
|
+
var _this = this;
|
|
1052
|
+
var props = {}; // will be deleted
|
|
1053
|
+
_each(this._customProperties, function (customProperty) {
|
|
1054
|
+
_each(customProperty['event_selectors'], function (eventSelector) {
|
|
1055
|
+
var eventElements = document.querySelectorAll(eventSelector);
|
|
1056
|
+
_each(eventElements, function (eventElement) {
|
|
1057
|
+
if (_includes(targetElementList, eventElement) && shouldCaptureElement(eventElement)) {
|
|
1058
|
+
props[customProperty['name']] = _this._extractCustomPropertyValue(customProperty);
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
});
|
|
1062
|
+
});
|
|
1063
|
+
return props;
|
|
2307
1064
|
},
|
|
2308
|
-
|
|
2309
1065
|
_getEventTarget: function (e) {
|
|
1066
|
+
var _a;
|
|
2310
1067
|
// https://developer.mozilla.org/en-US/docs/Web/API/Event/target#Compatibility_notes
|
|
2311
1068
|
if (typeof e.target === 'undefined') {
|
|
2312
|
-
return e.srcElement
|
|
2313
|
-
}
|
|
2314
|
-
|
|
2315
|
-
|
|
1069
|
+
return e.srcElement || null;
|
|
1070
|
+
}
|
|
1071
|
+
else {
|
|
1072
|
+
if ((_a = e.target) === null || _a === void 0 ? void 0 : _a.shadowRoot) {
|
|
1073
|
+
return e.composedPath()[0] || null;
|
|
2316
1074
|
}
|
|
2317
|
-
return e.target
|
|
1075
|
+
return e.target || null;
|
|
2318
1076
|
}
|
|
2319
1077
|
},
|
|
2320
|
-
|
|
2321
|
-
|
|
1078
|
+
_captureEvent: function (e, instance, opts) {
|
|
1079
|
+
var _this = this;
|
|
1080
|
+
var _a;
|
|
2322
1081
|
/*** Don't mess with this code without running IE8 tests on it ***/
|
|
2323
1082
|
var target = this._getEventTarget(e);
|
|
2324
1083
|
if (isTextNode(target)) {
|
|
2325
1084
|
// defeat Safari bug (see: http://www.quirksmode.org/js/events_properties.html)
|
|
2326
|
-
target = target.parentNode;
|
|
1085
|
+
target = (target.parentNode || null);
|
|
2327
1086
|
}
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
this.rageclicks.click(e.clientX, e.clientY, new Date().getTime());
|
|
1087
|
+
if (e.type === 'click' && e instanceof MouseEvent) {
|
|
1088
|
+
(_a = this.rageclicks) === null || _a === void 0 ? void 0 : _a.click(e.clientX, e.clientY, new Date().getTime());
|
|
2331
1089
|
}
|
|
2332
|
-
|
|
2333
|
-
if (shouldCaptureDomEvent(target, e)) {
|
|
1090
|
+
if (target && shouldCaptureDomEvent(target, e)) {
|
|
2334
1091
|
var targetElementList = [target];
|
|
2335
1092
|
var curEl = target;
|
|
2336
1093
|
while (curEl.parentNode && !isTag(curEl, 'body')) {
|
|
2337
|
-
if (curEl.parentNode
|
|
1094
|
+
if (isDocumentFragment(curEl.parentNode)) {
|
|
2338
1095
|
targetElementList.push(curEl.parentNode.host);
|
|
2339
1096
|
curEl = curEl.parentNode.host;
|
|
2340
|
-
continue
|
|
1097
|
+
continue;
|
|
2341
1098
|
}
|
|
2342
1099
|
targetElementList.push(curEl.parentNode);
|
|
2343
1100
|
curEl = curEl.parentNode;
|
|
2344
1101
|
}
|
|
2345
|
-
|
|
2346
|
-
var
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
explicitNoCapture = true;
|
|
2365
|
-
}
|
|
2366
|
-
|
|
2367
|
-
elementsJson.push(
|
|
2368
|
-
this._getPropertiesFromElement(
|
|
2369
|
-
el,
|
|
2370
|
-
instance.get_config('mask_all_element_attributes'),
|
|
2371
|
-
instance.get_config('mask_all_text')
|
|
2372
|
-
)
|
|
2373
|
-
);
|
|
2374
|
-
},
|
|
2375
|
-
this
|
|
2376
|
-
);
|
|
2377
|
-
|
|
2378
|
-
if (!instance.get_config('mask_all_text')) {
|
|
2379
|
-
elementsJson[0]['$el_text'] = getSafeText(target);
|
|
1102
|
+
var elementsJson_1 = [];
|
|
1103
|
+
var href_1, explicitNoCapture_1 = false;
|
|
1104
|
+
_each(targetElementList, function (el) {
|
|
1105
|
+
var shouldCaptureEl = shouldCaptureElement(el);
|
|
1106
|
+
// if the element or a parent element is an anchor tag
|
|
1107
|
+
// include the href as a property
|
|
1108
|
+
if (el.tagName.toLowerCase() === 'a') {
|
|
1109
|
+
href_1 = el.getAttribute('href');
|
|
1110
|
+
href_1 = shouldCaptureEl && shouldCaptureValue(href_1) && href_1;
|
|
1111
|
+
}
|
|
1112
|
+
// allow users to programmatically prevent capturing of elements by adding class 'ph-no-capture'
|
|
1113
|
+
var classes = getClassName(el).split(' ');
|
|
1114
|
+
if (_includes(classes, 'ph-no-capture')) {
|
|
1115
|
+
explicitNoCapture_1 = true;
|
|
1116
|
+
}
|
|
1117
|
+
elementsJson_1.push(_this._getPropertiesFromElement(el, opts === null || opts === void 0 ? void 0 : opts.mask_all_element_attributes, opts === null || opts === void 0 ? void 0 : opts.mask_all_text));
|
|
1118
|
+
});
|
|
1119
|
+
if (!(opts === null || opts === void 0 ? void 0 : opts.mask_all_text)) {
|
|
1120
|
+
elementsJson_1[0]['$el_text'] = getSafeText(target);
|
|
2380
1121
|
}
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
elementsJson[0]['attr__href'] = href;
|
|
1122
|
+
if (href_1) {
|
|
1123
|
+
elementsJson_1[0]['attr__href'] = href_1;
|
|
2384
1124
|
}
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
return false
|
|
1125
|
+
if (explicitNoCapture_1) {
|
|
1126
|
+
return false;
|
|
2388
1127
|
}
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
{
|
|
2393
|
-
$elements: elementsJson,
|
|
2394
|
-
},
|
|
2395
|
-
this._getCustomProperties(targetElementList)
|
|
2396
|
-
);
|
|
2397
|
-
|
|
1128
|
+
var props = _extend(this._getDefaultProperties(e.type), {
|
|
1129
|
+
$elements: elementsJson_1,
|
|
1130
|
+
}, this._getCustomProperties(targetElementList));
|
|
2398
1131
|
instance.capture('$autocapture', props);
|
|
2399
|
-
return true
|
|
1132
|
+
return true;
|
|
2400
1133
|
}
|
|
2401
1134
|
},
|
|
2402
|
-
|
|
2403
1135
|
// only reason is to stub for unit tests
|
|
2404
1136
|
// since you can't override window.location props
|
|
2405
1137
|
_navigate: function (href) {
|
|
2406
1138
|
window.location.href = href;
|
|
2407
1139
|
},
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
var handler =
|
|
1140
|
+
_addDomEventHandlers: function (instance, opts) {
|
|
1141
|
+
var _this = this;
|
|
1142
|
+
var handler = function (e) {
|
|
2411
1143
|
e = e || window.event;
|
|
2412
|
-
|
|
2413
|
-
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
1144
|
+
_this._captureEvent(e, instance, opts);
|
|
1145
|
+
};
|
|
1146
|
+
_register_event(document, 'submit', handler, false, true);
|
|
1147
|
+
_register_event(document, 'change', handler, false, true);
|
|
1148
|
+
_register_event(document, 'click', handler, false, true);
|
|
2417
1149
|
},
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
if (this._initializedTokens.indexOf(token) > -1) {
|
|
2424
|
-
console.log('autocapture already initialized for token "' + token + '"');
|
|
2425
|
-
return
|
|
2426
|
-
}
|
|
2427
|
-
|
|
2428
|
-
this._initializedTokens.push(token);
|
|
2429
|
-
|
|
2430
|
-
if (instance.get_config('autocapture')) {
|
|
2431
|
-
this._addDomEventHandlers(instance);
|
|
2432
|
-
} else {
|
|
2433
|
-
instance['__autocapture_enabled'] = false;
|
|
2434
|
-
}
|
|
2435
|
-
|
|
1150
|
+
_customProperties: [],
|
|
1151
|
+
rageclicks: null,
|
|
1152
|
+
opts: {},
|
|
1153
|
+
init: function (instance, opts) {
|
|
1154
|
+
var _this = this;
|
|
2436
1155
|
this.rageclicks = new RageClick(instance);
|
|
1156
|
+
this.opts = opts;
|
|
1157
|
+
if (!(document && document.body)) {
|
|
1158
|
+
console.log('document not ready yet, trying again in 500 milliseconds...');
|
|
1159
|
+
setTimeout(function () {
|
|
1160
|
+
_this.readyAutocapture(instance, opts);
|
|
1161
|
+
}, 500);
|
|
1162
|
+
return;
|
|
1163
|
+
}
|
|
1164
|
+
this.readyAutocapture(instance, opts);
|
|
1165
|
+
},
|
|
1166
|
+
readyAutocapture: function (instance, opts) {
|
|
1167
|
+
this._addDomEventHandlers(instance, opts);
|
|
2437
1168
|
},
|
|
2438
|
-
|
|
2439
1169
|
// this is a mechanism to ramp up CE with no server-side interaction.
|
|
2440
1170
|
// when CE is active, every page load results in a decide request. we
|
|
2441
1171
|
// need to gently ramp this up so we don't overload decide. this decides
|
|
2442
1172
|
// deterministically if CE is enabled for this project by modding the char
|
|
2443
1173
|
// value of the project token.
|
|
2444
1174
|
enabledForProject: function (token, numBuckets, numEnabledBuckets) {
|
|
2445
|
-
|
|
2446
|
-
|
|
1175
|
+
if (!token) {
|
|
1176
|
+
return true;
|
|
1177
|
+
}
|
|
1178
|
+
numBuckets = !_isUndefined(numBuckets) ? numBuckets : 10;
|
|
1179
|
+
numEnabledBuckets = !_isUndefined(numEnabledBuckets) ? numEnabledBuckets : 10;
|
|
2447
1180
|
var charCodeSum = 0;
|
|
2448
1181
|
for (var i = 0; i < token.length; i++) {
|
|
2449
1182
|
charCodeSum += token.charCodeAt(i);
|
|
2450
1183
|
}
|
|
2451
|
-
return charCodeSum % numBuckets < numEnabledBuckets
|
|
1184
|
+
return charCodeSum % numBuckets < numEnabledBuckets;
|
|
2452
1185
|
},
|
|
2453
|
-
|
|
2454
1186
|
isBrowserSupported: function () {
|
|
2455
|
-
return
|
|
1187
|
+
return _isFunction(document.querySelectorAll);
|
|
2456
1188
|
},
|
|
2457
1189
|
};
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
_.safewrap_instance_methods(autocapture);
|
|
1190
|
+
_bind_instance_methods(autocapture);
|
|
1191
|
+
_safewrap_instance_methods(autocapture);
|
|
2461
1192
|
|
|
2462
1193
|
var VERSION_INFO = {
|
|
2463
1194
|
env: 'production',
|
|
2464
|
-
date: '2022-
|
|
2465
|
-
version: '1.0
|
|
1195
|
+
date: '2022-09-03T13:48:55.501Z',
|
|
1196
|
+
version: '1.1.0'
|
|
2466
1197
|
};
|
|
2467
1198
|
var USERMAVEN_VERSION = "".concat(VERSION_INFO.version, "/").concat(VERSION_INFO.env, "@").concat(VERSION_INFO.date);
|
|
2468
1199
|
var MAX_AGE_TEN_YEARS = 31622400 * 10;
|
|
@@ -2837,6 +1568,14 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2837
1568
|
this.beaconApi = false;
|
|
2838
1569
|
this.transport = xmlHttpTransport;
|
|
2839
1570
|
this.customHeaders = function () { return ({}); };
|
|
1571
|
+
this.queue = new MemoryQueue();
|
|
1572
|
+
this.maxSendAttempts = 4;
|
|
1573
|
+
this.retryTimeout = [500, 1e12];
|
|
1574
|
+
this.flushing = false;
|
|
1575
|
+
this.attempt = 1;
|
|
1576
|
+
this.propertyBlacklist = [];
|
|
1577
|
+
// public persistence?: UserMavenPersistence;
|
|
1578
|
+
// public sessionManager?: SessionIdManager;
|
|
2840
1579
|
this.__autocapture_enabled = false;
|
|
2841
1580
|
}
|
|
2842
1581
|
// private anonymousId: string = '';
|
|
@@ -2891,6 +1630,24 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2891
1630
|
return this.sendJson(e);
|
|
2892
1631
|
};
|
|
2893
1632
|
UsermavenClientImpl.prototype.sendJson = function (json) {
|
|
1633
|
+
return __awaiter(this, void 0, Promise, function () {
|
|
1634
|
+
return __generator(this, function (_a) {
|
|
1635
|
+
switch (_a.label) {
|
|
1636
|
+
case 0:
|
|
1637
|
+
if (!(this.maxSendAttempts > 1)) return [3 /*break*/, 1];
|
|
1638
|
+
this.queue.push([json, 0]);
|
|
1639
|
+
this.scheduleFlush(0);
|
|
1640
|
+
return [3 /*break*/, 3];
|
|
1641
|
+
case 1: return [4 /*yield*/, this.doSendJson(json)];
|
|
1642
|
+
case 2:
|
|
1643
|
+
_a.sent();
|
|
1644
|
+
_a.label = 3;
|
|
1645
|
+
case 3: return [2 /*return*/];
|
|
1646
|
+
}
|
|
1647
|
+
});
|
|
1648
|
+
});
|
|
1649
|
+
};
|
|
1650
|
+
UsermavenClientImpl.prototype.doSendJson = function (json) {
|
|
2894
1651
|
var _this = this;
|
|
2895
1652
|
var cookiePolicy = this.cookiePolicy !== "keep" ? "&cookie_policy=".concat(this.cookiePolicy) : "";
|
|
2896
1653
|
var ipPolicy = this.ipPolicy !== "keep" ? "&ip_policy=".concat(this.ipPolicy) : "";
|
|
@@ -2905,6 +1662,68 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2905
1662
|
return _this.postHandle(code, body);
|
|
2906
1663
|
});
|
|
2907
1664
|
};
|
|
1665
|
+
UsermavenClientImpl.prototype.scheduleFlush = function (timeout) {
|
|
1666
|
+
var _this = this;
|
|
1667
|
+
if (this.flushing) {
|
|
1668
|
+
return;
|
|
1669
|
+
}
|
|
1670
|
+
this.flushing = true;
|
|
1671
|
+
if (typeof timeout === "undefined") {
|
|
1672
|
+
var random = Math.random() + 1;
|
|
1673
|
+
var factor = Math.pow(2, this.attempt++);
|
|
1674
|
+
timeout = Math.min(this.retryTimeout[0] * random * factor, this.retryTimeout[1]);
|
|
1675
|
+
}
|
|
1676
|
+
getLogger().debug("Scheduling event queue flush in ".concat(timeout, " ms."));
|
|
1677
|
+
setTimeout(function () { return _this.flush(); }, timeout);
|
|
1678
|
+
};
|
|
1679
|
+
UsermavenClientImpl.prototype.flush = function () {
|
|
1680
|
+
return __awaiter(this, void 0, Promise, function () {
|
|
1681
|
+
var queue;
|
|
1682
|
+
var _a;
|
|
1683
|
+
var _this = this;
|
|
1684
|
+
return __generator(this, function (_b) {
|
|
1685
|
+
switch (_b.label) {
|
|
1686
|
+
case 0:
|
|
1687
|
+
if (isWindowAvailable() && !window.navigator.onLine) {
|
|
1688
|
+
this.flushing = false;
|
|
1689
|
+
this.scheduleFlush();
|
|
1690
|
+
}
|
|
1691
|
+
queue = this.queue.flush();
|
|
1692
|
+
this.flushing = false;
|
|
1693
|
+
if (queue.length === 0) {
|
|
1694
|
+
return [2 /*return*/];
|
|
1695
|
+
}
|
|
1696
|
+
_b.label = 1;
|
|
1697
|
+
case 1:
|
|
1698
|
+
_b.trys.push([1, 3, , 4]);
|
|
1699
|
+
return [4 /*yield*/, this.doSendJson(queue.map(function (el) { return el[0]; }))];
|
|
1700
|
+
case 2:
|
|
1701
|
+
_b.sent();
|
|
1702
|
+
this.attempt = 1;
|
|
1703
|
+
getLogger().debug("Successfully flushed ".concat(queue.length, " events from queue"));
|
|
1704
|
+
return [3 /*break*/, 4];
|
|
1705
|
+
case 3:
|
|
1706
|
+
_b.sent();
|
|
1707
|
+
queue = queue.map(function (el) { return [el[0], el[1] + 1]; }).filter(function (el) {
|
|
1708
|
+
if (el[1] >= _this.maxSendAttempts) {
|
|
1709
|
+
getLogger().error("Dropping queued event after ".concat(el[1], " attempts since max send attempts ").concat(_this.maxSendAttempts, " reached. See logs for details"));
|
|
1710
|
+
return false;
|
|
1711
|
+
}
|
|
1712
|
+
return true;
|
|
1713
|
+
});
|
|
1714
|
+
if (queue.length > 0) {
|
|
1715
|
+
(_a = this.queue).push.apply(_a, queue);
|
|
1716
|
+
this.scheduleFlush();
|
|
1717
|
+
}
|
|
1718
|
+
else {
|
|
1719
|
+
this.attempt = 1;
|
|
1720
|
+
}
|
|
1721
|
+
return [3 /*break*/, 4];
|
|
1722
|
+
case 4: return [2 /*return*/];
|
|
1723
|
+
}
|
|
1724
|
+
});
|
|
1725
|
+
});
|
|
1726
|
+
};
|
|
2908
1727
|
UsermavenClientImpl.prototype.postHandle = function (status, response) {
|
|
2909
1728
|
if (this.cookiePolicy === "strict" || this.cookiePolicy === "comply") {
|
|
2910
1729
|
if (status === 200) {
|
|
@@ -2950,10 +1769,9 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2950
1769
|
UsermavenClientImpl.prototype.getCtx = function (env) {
|
|
2951
1770
|
var now = new Date();
|
|
2952
1771
|
var props = env.describeClient() || {};
|
|
2953
|
-
var _a = this.sessionManager.getSessionAndWindowId(), session_id = _a.session_id, window_id = _a.window_id;
|
|
2954
1772
|
var company = this.userProperties['company'] || {};
|
|
2955
1773
|
delete this.userProperties['company'];
|
|
2956
|
-
var payload = __assign(__assign({ event_id: "",
|
|
1774
|
+
var payload = __assign(__assign({ event_id: "", user: __assign({ anonymous_id: this.cookiePolicy !== "strict"
|
|
2957
1775
|
? env.getAnonymousId({
|
|
2958
1776
|
name: this.idCookieName,
|
|
2959
1777
|
domain: this.cookieDomain,
|
|
@@ -2987,7 +1805,7 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
2987
1805
|
};
|
|
2988
1806
|
UsermavenClientImpl.prototype.init = function (options) {
|
|
2989
1807
|
var _this = this;
|
|
2990
|
-
var _a, _b;
|
|
1808
|
+
var _a, _b, _c, _d;
|
|
2991
1809
|
if (isWindowAvailable() && !options.force_use_fetch) {
|
|
2992
1810
|
if (options.fetch) {
|
|
2993
1811
|
getLogger().warn("Custom fetch implementation is provided to Usermaven. However, it will be ignored since Usermaven runs in browser");
|
|
@@ -3074,21 +1892,17 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3074
1892
|
}
|
|
3075
1893
|
getLogger().debug("Restored persistent properties", this.permanentProperties);
|
|
3076
1894
|
}
|
|
3077
|
-
|
|
1895
|
+
this.propertyBlacklist = options.property_blacklist && options.property_blacklist.length > 0 ? options.property_blacklist : [];
|
|
1896
|
+
// // Added these configuration for session management + autocapture
|
|
3078
1897
|
var defaultConfig = {
|
|
3079
|
-
persistence: 'cookie',
|
|
3080
|
-
persistence_name: 'session',
|
|
3081
1898
|
autocapture: false,
|
|
3082
|
-
capture_pageview: true,
|
|
3083
|
-
store_google: false,
|
|
3084
|
-
save_referrer: false,
|
|
3085
1899
|
properties_string_max_length: null,
|
|
3086
1900
|
property_blacklist: [],
|
|
3087
1901
|
sanitize_properties: null
|
|
3088
1902
|
};
|
|
3089
|
-
this.config =
|
|
1903
|
+
this.config = _extend({}, defaultConfig, options || {}, this.config || {}, { token: this.apiKey });
|
|
3090
1904
|
getLogger().debug('Default Configuration', this.config);
|
|
3091
|
-
this.manageSession(this.config);
|
|
1905
|
+
// this.manageSession(this.config);
|
|
3092
1906
|
this.manageAutoCapture(this.config);
|
|
3093
1907
|
if (options.capture_3rd_party_cookies === false) {
|
|
3094
1908
|
this._3pCookies = {};
|
|
@@ -3108,9 +1922,21 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3108
1922
|
if (options.segment_hook) {
|
|
3109
1923
|
interceptSegmentCalls(this);
|
|
3110
1924
|
}
|
|
1925
|
+
if (isWindowAvailable()) {
|
|
1926
|
+
if (!options.disable_event_persistence) {
|
|
1927
|
+
this.queue = new LocalStorageQueue("jitsu-event-queue");
|
|
1928
|
+
this.scheduleFlush(0);
|
|
1929
|
+
}
|
|
1930
|
+
window.addEventListener("beforeunload", function () { return _this.flush(); });
|
|
1931
|
+
}
|
|
1932
|
+
this.retryTimeout = [
|
|
1933
|
+
(_c = options.min_send_timeout) !== null && _c !== void 0 ? _c : this.retryTimeout[0],
|
|
1934
|
+
(_d = options.max_send_timeout) !== null && _d !== void 0 ? _d : this.retryTimeout[1],
|
|
1935
|
+
];
|
|
1936
|
+
if (!!options.max_send_attempts) {
|
|
1937
|
+
this.maxSendAttempts = options.max_send_attempts;
|
|
1938
|
+
}
|
|
3111
1939
|
this.initialized = true;
|
|
3112
|
-
// Set up the window close event handler "unload"
|
|
3113
|
-
window.addEventListener && window.addEventListener('unload', this._handle_unload.bind(this));
|
|
3114
1940
|
};
|
|
3115
1941
|
UsermavenClientImpl.prototype.interceptAnalytics = function (analytics) {
|
|
3116
1942
|
var _this = this;
|
|
@@ -3190,30 +2016,6 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3190
2016
|
this.propsPersistance.save(this.permanentProperties);
|
|
3191
2017
|
}
|
|
3192
2018
|
};
|
|
3193
|
-
/**
|
|
3194
|
-
* Manage session capability
|
|
3195
|
-
* @param options
|
|
3196
|
-
*/
|
|
3197
|
-
UsermavenClientImpl.prototype.manageSession = function (options) {
|
|
3198
|
-
getLogger().debug('Options', options);
|
|
3199
|
-
options = options || {};
|
|
3200
|
-
getLogger().debug('Options', options);
|
|
3201
|
-
// cross_subdomain_cookie: whether to keep cookie across domains and subdomains
|
|
3202
|
-
var defaultConfig = {
|
|
3203
|
-
persistence: options.persistence || 'cookie',
|
|
3204
|
-
persistence_name: options.persistence_name || 'session',
|
|
3205
|
-
cross_subdomain_cookie: options.cross_subdomain_cookie || true
|
|
3206
|
-
};
|
|
3207
|
-
// TODO: Default session name would be session_
|
|
3208
|
-
this.config = _.extend(defaultConfig, this.config || {}, {
|
|
3209
|
-
token: this.apiKey,
|
|
3210
|
-
});
|
|
3211
|
-
getLogger().debug('Default Configuration', this.config);
|
|
3212
|
-
this.persistence = new UserMavenPersistence(this.config);
|
|
3213
|
-
getLogger().debug('Persistence Configuration', this.persistence);
|
|
3214
|
-
this.sessionManager = new SessionIdManager(this.config, this.persistence);
|
|
3215
|
-
getLogger().debug('Session Configuration', this.sessionManager);
|
|
3216
|
-
};
|
|
3217
2019
|
/**
|
|
3218
2020
|
* Manage auto-capturing
|
|
3219
2021
|
* @param options
|
|
@@ -3228,14 +2030,17 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3228
2030
|
var num_enabled_buckets = 100;
|
|
3229
2031
|
if (!autocapture.enabledForProject(this.apiKey, num_buckets, num_enabled_buckets)) {
|
|
3230
2032
|
this.config['autocapture'] = false;
|
|
2033
|
+
this.__autocapture_enabled = false;
|
|
3231
2034
|
console.log('Not in active bucket: disabling Automatic Event Collection.');
|
|
3232
2035
|
}
|
|
3233
2036
|
else if (!autocapture.isBrowserSupported()) {
|
|
3234
2037
|
this.config['autocapture'] = false;
|
|
2038
|
+
this.__autocapture_enabled = false;
|
|
3235
2039
|
console.log('Disabling Automatic Event Collection because this browser is not supported');
|
|
3236
2040
|
}
|
|
3237
2041
|
else {
|
|
3238
|
-
|
|
2042
|
+
console.log('Autocapture enabled...');
|
|
2043
|
+
autocapture.init(this, options);
|
|
3239
2044
|
}
|
|
3240
2045
|
};
|
|
3241
2046
|
/**
|
|
@@ -3243,12 +2048,7 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3243
2048
|
* frequently used usermaven function.
|
|
3244
2049
|
*
|
|
3245
2050
|
* ### Usage:
|
|
3246
|
-
*
|
|
3247
|
-
* // capture an event named 'Registered'
|
|
3248
|
-
* usermaven.capture('Registered', {'Gender': 'Male', 'Age': 21});
|
|
3249
|
-
*
|
|
3250
|
-
* // capture an event using navigator.sendBeacon
|
|
3251
|
-
* usermaven.capture('Left page', {'duration_seconds': 35}, {transport: 'sendBeacon'});
|
|
2051
|
+
* usermaven.capture('Registered', {'Gender': 'Male', 'Age': 21}, {});
|
|
3252
2052
|
*
|
|
3253
2053
|
* @param {String} event_name The name of the event. This can be anything the user does - 'Button Click', 'Sign Up', 'Item Purchased', etc.
|
|
3254
2054
|
* @param {Object} [properties] A set of properties to include with the event you're sending. These describe the user who did the event or details about the event itself.
|
|
@@ -3262,63 +2062,39 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3262
2062
|
console.error('Trying to capture event before initialization');
|
|
3263
2063
|
return;
|
|
3264
2064
|
}
|
|
3265
|
-
|
|
3266
|
-
|
|
2065
|
+
console.log(properties);
|
|
2066
|
+
if (_isUndefined(event_name) || typeof event_name !== 'string') {
|
|
2067
|
+
console.error('No event name provided to usermaven.capture');
|
|
3267
2068
|
return;
|
|
3268
2069
|
}
|
|
3269
|
-
if (_.isBlockedUA(userAgent)) {
|
|
3270
|
-
|
|
3271
|
-
}
|
|
3272
|
-
var start_timestamp = this['persistence'].remove_event_timer(event_name);
|
|
3273
|
-
// update persistence
|
|
3274
|
-
this['persistence'].update_search_keyword(document.referrer);
|
|
3275
|
-
if (this.get_config('store_google')) {
|
|
3276
|
-
this['persistence'].update_campaign_params();
|
|
3277
|
-
}
|
|
3278
|
-
if (this.get_config('save_referrer')) {
|
|
3279
|
-
this['persistence'].update_referrer_info(document.referrer);
|
|
3280
|
-
}
|
|
2070
|
+
// if (_.isBlockedUA(userAgent)) {
|
|
2071
|
+
// return
|
|
2072
|
+
// }
|
|
3281
2073
|
var data = {
|
|
3282
2074
|
event: event_name + (properties['$event_type'] ? '_' + properties['$event_type'] : ''),
|
|
3283
|
-
properties: this._calculate_event_properties(event_name, properties
|
|
2075
|
+
properties: this._calculate_event_properties(event_name, properties),
|
|
3284
2076
|
};
|
|
3285
|
-
data =
|
|
3286
|
-
// send
|
|
2077
|
+
data = _copyAndTruncateStrings(data, this.get_config('properties_string_max_length'));
|
|
2078
|
+
// send event if there is a tagname available
|
|
3287
2079
|
if ((_b = (_a = data.properties) === null || _a === void 0 ? void 0 : _a.autocapture_attributes) === null || _b === void 0 ? void 0 : _b.tag_name) {
|
|
3288
2080
|
this.track("$autocapture", data.properties);
|
|
3289
2081
|
// this.track(data.event, data.properties)
|
|
3290
2082
|
}
|
|
3291
2083
|
};
|
|
3292
|
-
UsermavenClientImpl.prototype._calculate_event_properties = function (event_name, event_properties
|
|
2084
|
+
UsermavenClientImpl.prototype._calculate_event_properties = function (event_name, event_properties) {
|
|
3293
2085
|
var _a, _b;
|
|
3294
2086
|
// set defaults
|
|
3295
2087
|
var properties = event_properties || {};
|
|
3296
2088
|
if (event_name === '$snapshot') {
|
|
3297
2089
|
return properties;
|
|
3298
2090
|
}
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
var duration_in_ms = new Date().getTime() - start_timestamp;
|
|
3302
|
-
properties['$duration'] = parseFloat((duration_in_ms / 1000).toFixed(3));
|
|
3303
|
-
}
|
|
3304
|
-
// note: extend writes to the first object, so lets make sure we
|
|
3305
|
-
// don't write to the persistence properties object and info
|
|
3306
|
-
// properties object by passing in a new object
|
|
3307
|
-
// update properties with pageview info and super-properties
|
|
3308
|
-
// exlude , _.info.properties()
|
|
3309
|
-
properties = _.extend({}, this['persistence'].properties(), properties);
|
|
3310
|
-
var property_blacklist = this.get_config('property_blacklist');
|
|
3311
|
-
if (_.isArray(property_blacklist)) {
|
|
3312
|
-
_.each(property_blacklist, function (blacklisted_prop) {
|
|
2091
|
+
if (_isArray(this.propertyBlacklist)) {
|
|
2092
|
+
_each(this.propertyBlacklist, function (blacklisted_prop) {
|
|
3313
2093
|
delete properties[blacklisted_prop];
|
|
3314
2094
|
});
|
|
3315
2095
|
}
|
|
3316
2096
|
else {
|
|
3317
|
-
console.error('Invalid value for property_blacklist config: ' +
|
|
3318
|
-
}
|
|
3319
|
-
var sanitize_properties = this.get_config('sanitize_properties');
|
|
3320
|
-
if (sanitize_properties) {
|
|
3321
|
-
properties = sanitize_properties(properties, event_name);
|
|
2097
|
+
console.error('Invalid value for property_blacklist config: ' + this.propertyBlacklist);
|
|
3322
2098
|
}
|
|
3323
2099
|
// assign first element from $elements only
|
|
3324
2100
|
var attributes = {};
|
|
@@ -3329,24 +2105,15 @@ var UsermavenClientImpl = /** @class */ (function () {
|
|
|
3329
2105
|
properties['autocapture_attributes'] = attributes;
|
|
3330
2106
|
properties['autocapture_attributes']["el_text"] = (_a = properties['autocapture_attributes']["$el_text"]) !== null && _a !== void 0 ? _a : "";
|
|
3331
2107
|
properties['autocapture_attributes']["event_type"] = (_b = properties["$event_type"]) !== null && _b !== void 0 ? _b : "";
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
delete properties['$initial_referring_domain'];
|
|
3336
|
-
delete properties['$referrer'];
|
|
3337
|
-
delete properties['$referring_domain'];
|
|
3338
|
-
delete properties['$elements'];
|
|
2108
|
+
['$ce_version', "$event_type", "$initial_referrer", "$initial_referring_domain", "$referrer", "$referring_domain", "$elements"].forEach(function (key) {
|
|
2109
|
+
delete properties[key];
|
|
2110
|
+
});
|
|
3339
2111
|
// TODO: later remove this from the autotrack code.
|
|
3340
2112
|
delete properties['autocapture_attributes']["$el_text"];
|
|
3341
2113
|
delete properties['autocapture_attributes']["nth_child"];
|
|
3342
2114
|
delete properties['autocapture_attributes']["nth_of_type"];
|
|
3343
2115
|
return properties;
|
|
3344
2116
|
};
|
|
3345
|
-
UsermavenClientImpl.prototype._handle_unload = function () {
|
|
3346
|
-
if (this.get_config('capture_pageview')) {
|
|
3347
|
-
this.capture('$pageleave');
|
|
3348
|
-
}
|
|
3349
|
-
};
|
|
3350
2117
|
return UsermavenClientImpl;
|
|
3351
2118
|
}());
|
|
3352
2119
|
function interceptSegmentCalls(t) {
|