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