Update portal JS
This commit is contained in:
parent
750eaafe65
commit
1c17c6b077
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Fingerprintjs2 2.0.5 - Modern & flexible browser fingerprint library v2
|
* Fingerprintjs2 2.1.0 - Modern & flexible browser fingerprint library v2
|
||||||
* https://github.com/Valve/fingerprintjs2
|
* https://github.com/Valve/fingerprintjs2
|
||||||
* Copyright (c) 2015 Valentin Vasilyev (valentin.vasilyev@outlook.com)
|
* Copyright (c) 2015 Valentin Vasilyev (valentin.vasilyev@outlook.com)
|
||||||
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
|
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
|
||||||
|
@ -22,12 +22,12 @@
|
||||||
})('Fingerprint2', this, function () {
|
})('Fingerprint2', this, function () {
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
/// MurmurHash3 related functions
|
/// MurmurHash3 related functions
|
||||||
|
|
||||||
//
|
//
|
||||||
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
||||||
// added together as a 64bit int (as an array of two 32bit ints).
|
// added together as a 64bit int (as an array of two 32bit ints).
|
||||||
//
|
//
|
||||||
var x64Add = function (m, n) {
|
var x64Add = function (m, n) {
|
||||||
m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]
|
m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]
|
||||||
n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]
|
n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]
|
||||||
|
@ -46,10 +46,10 @@
|
||||||
return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]
|
return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
||||||
// multiplied together as a 64bit int (as an array of two 32bit ints).
|
// multiplied together as a 64bit int (as an array of two 32bit ints).
|
||||||
//
|
//
|
||||||
var x64Multiply = function (m, n) {
|
var x64Multiply = function (m, n) {
|
||||||
m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]
|
m = [m[0] >>> 16, m[0] & 0xffff, m[1] >>> 16, m[1] & 0xffff]
|
||||||
n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]
|
n = [n[0] >>> 16, n[0] & 0xffff, n[1] >>> 16, n[1] & 0xffff]
|
||||||
|
@ -76,11 +76,11 @@
|
||||||
o[0] &= 0xffff
|
o[0] &= 0xffff
|
||||||
return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]
|
return [(o[0] << 16) | o[1], (o[2] << 16) | o[3]]
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Given a 64bit int (as an array of two 32bit ints) and an int
|
// Given a 64bit int (as an array of two 32bit ints) and an int
|
||||||
// representing a number of bit positions, returns the 64bit int (as an
|
// representing a number of bit positions, returns the 64bit int (as an
|
||||||
// array of two 32bit ints) rotated left by that number of positions.
|
// array of two 32bit ints) rotated left by that number of positions.
|
||||||
//
|
//
|
||||||
var x64Rotl = function (m, n) {
|
var x64Rotl = function (m, n) {
|
||||||
n %= 64
|
n %= 64
|
||||||
if (n === 32) {
|
if (n === 32) {
|
||||||
|
@ -92,11 +92,11 @@
|
||||||
return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))]
|
return [(m[1] << n) | (m[0] >>> (32 - n)), (m[0] << n) | (m[1] >>> (32 - n))]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Given a 64bit int (as an array of two 32bit ints) and an int
|
// Given a 64bit int (as an array of two 32bit ints) and an int
|
||||||
// representing a number of bit positions, returns the 64bit int (as an
|
// representing a number of bit positions, returns the 64bit int (as an
|
||||||
// array of two 32bit ints) shifted left by that number of positions.
|
// array of two 32bit ints) shifted left by that number of positions.
|
||||||
//
|
//
|
||||||
var x64LeftShift = function (m, n) {
|
var x64LeftShift = function (m, n) {
|
||||||
n %= 64
|
n %= 64
|
||||||
if (n === 0) {
|
if (n === 0) {
|
||||||
|
@ -107,18 +107,18 @@
|
||||||
return [m[1] << (n - 32), 0]
|
return [m[1] << (n - 32), 0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
// Given two 64bit ints (as an array of two 32bit ints) returns the two
|
||||||
// xored together as a 64bit int (as an array of two 32bit ints).
|
// xored together as a 64bit int (as an array of two 32bit ints).
|
||||||
//
|
//
|
||||||
var x64Xor = function (m, n) {
|
var x64Xor = function (m, n) {
|
||||||
return [m[0] ^ n[0], m[1] ^ n[1]]
|
return [m[0] ^ n[0], m[1] ^ n[1]]
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Given a block, returns murmurHash3's final x64 mix of that block.
|
// Given a block, returns murmurHash3's final x64 mix of that block.
|
||||||
// (`[0, h[0] >>> 1]` is a 33 bit unsigned right shift. This is the
|
// (`[0, h[0] >>> 1]` is a 33 bit unsigned right shift. This is the
|
||||||
// only place where we need to right shift 64bit ints.)
|
// only place where we need to right shift 64bit ints.)
|
||||||
//
|
//
|
||||||
var x64Fmix = function (h) {
|
var x64Fmix = function (h) {
|
||||||
h = x64Xor(h, [0, h[0] >>> 1])
|
h = x64Xor(h, [0, h[0] >>> 1])
|
||||||
h = x64Multiply(h, [0xff51afd7, 0xed558ccd])
|
h = x64Multiply(h, [0xff51afd7, 0xed558ccd])
|
||||||
|
@ -128,10 +128,10 @@
|
||||||
return h
|
return h
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Given a string and an optional seed as an int, returns a 128 bit
|
// Given a string and an optional seed as an int, returns a 128 bit
|
||||||
// hash using the x64 flavor of MurmurHash3, as an unsigned hex.
|
// hash using the x64 flavor of MurmurHash3, as an unsigned hex.
|
||||||
//
|
//
|
||||||
var x64hash128 = function (key, seed) {
|
var x64hash128 = function (key, seed) {
|
||||||
key = key || ''
|
key = key || ''
|
||||||
seed = seed || 0
|
seed = seed || 0
|
||||||
|
@ -233,9 +233,9 @@
|
||||||
preprocessor: null,
|
preprocessor: null,
|
||||||
audio: {
|
audio: {
|
||||||
timeout: 1000,
|
timeout: 1000,
|
||||||
// On iOS 11, audio context can only be used in response to user interaction.
|
// On iOS 11, audio context can only be used in response to user interaction.
|
||||||
// We require users to explicitly enable audio fingerprinting on iOS 11.
|
// We require users to explicitly enable audio fingerprinting on iOS 11.
|
||||||
// See https://stackoverflow.com/questions/46363048/onaudioprocess-not-called-on-ios11#46534088
|
// See https://stackoverflow.com/questions/46363048/onaudioprocess-not-called-on-ios11#46534088
|
||||||
excludeIOS11: true
|
excludeIOS11: true
|
||||||
},
|
},
|
||||||
fonts: {
|
fonts: {
|
||||||
|
@ -245,7 +245,7 @@
|
||||||
extendedJsFonts: false
|
extendedJsFonts: false
|
||||||
},
|
},
|
||||||
screen: {
|
screen: {
|
||||||
// To ensure consistent fingerprints when users rotate their mobile devices
|
// To ensure consistent fingerprints when users rotate their mobile devices
|
||||||
detectScreenOrientation: true
|
detectScreenOrientation: true
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
|
@ -311,7 +311,7 @@
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices
|
// https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices
|
||||||
var enumerateDevicesKey = function (done, options) {
|
var enumerateDevicesKey = function (done, options) {
|
||||||
if (!isEnumerateDevicesSupported()) {
|
if (!isEnumerateDevicesSupported()) {
|
||||||
return done(options.NOT_AVAILABLE)
|
return done(options.NOT_AVAILABLE)
|
||||||
|
@ -329,11 +329,11 @@
|
||||||
var isEnumerateDevicesSupported = function () {
|
var isEnumerateDevicesSupported = function () {
|
||||||
return (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices)
|
return (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices)
|
||||||
}
|
}
|
||||||
// Inspired by and based on https://github.com/cozylife/audio-fingerprint
|
// Inspired by and based on https://github.com/cozylife/audio-fingerprint
|
||||||
var audioKey = function (done, options) {
|
var audioKey = function (done, options) {
|
||||||
var audioOptions = options.audio
|
var audioOptions = options.audio
|
||||||
if (audioOptions.excludeIOS11 && navigator.userAgent.match(/OS 11.+Version\/11.+Safari/)) {
|
if (audioOptions.excludeIOS11 && navigator.userAgent.match(/OS 11.+Version\/11.+Safari/)) {
|
||||||
// See comment for excludeUserAgent and https://stackoverflow.com/questions/46363048/onaudioprocess-not-called-on-ios11#46534088
|
// See comment for excludeUserAgent and https://stackoverflow.com/questions/46363048/onaudioprocess-not-called-on-ios11#46534088
|
||||||
return done(options.EXCLUDED)
|
return done(options.EXCLUDED)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,12 +351,12 @@
|
||||||
|
|
||||||
var compressor = context.createDynamicsCompressor()
|
var compressor = context.createDynamicsCompressor()
|
||||||
each([
|
each([
|
||||||
['threshold', -50],
|
['threshold', -50],
|
||||||
['knee', 40],
|
['knee', 40],
|
||||||
['ratio', 12],
|
['ratio', 12],
|
||||||
['reduction', -20],
|
['reduction', -20],
|
||||||
['attack', 0],
|
['attack', 0],
|
||||||
['release', 0.25]
|
['release', 0.25]
|
||||||
], function (item) {
|
], function (item) {
|
||||||
if (compressor[item[0]] !== undefined && typeof compressor[item[0]].setValueAtTime === 'function') {
|
if (compressor[item[0]] !== undefined && typeof compressor[item[0]].setValueAtTime === 'function') {
|
||||||
compressor[item[0]].setValueAtTime(item[1], context.currentTime)
|
compressor[item[0]].setValueAtTime(item[1], context.currentTime)
|
||||||
|
@ -370,7 +370,7 @@
|
||||||
|
|
||||||
var audioTimeoutId = setTimeout(function () {
|
var audioTimeoutId = setTimeout(function () {
|
||||||
console.warn('Audio fingerprint timed out. Please report bug at https://github.com/Valve/fingerprintjs2 with your user agent: "' + navigator.userAgent + '".')
|
console.warn('Audio fingerprint timed out. Please report bug at https://github.com/Valve/fingerprintjs2 with your user agent: "' + navigator.userAgent + '".')
|
||||||
context.oncomplete = function () {}
|
context.oncomplete = function () { }
|
||||||
context = null
|
context = null
|
||||||
return done('audioTimeout')
|
return done('audioTimeout')
|
||||||
}, audioOptions.timeout)
|
}, audioOptions.timeout)
|
||||||
|
@ -380,9 +380,9 @@
|
||||||
try {
|
try {
|
||||||
clearTimeout(audioTimeoutId)
|
clearTimeout(audioTimeoutId)
|
||||||
fingerprint = event.renderedBuffer.getChannelData(0)
|
fingerprint = event.renderedBuffer.getChannelData(0)
|
||||||
.slice(4500, 5000)
|
.slice(4500, 5000)
|
||||||
.reduce(function (acc, val) { return acc + Math.abs(val) }, 0)
|
.reduce(function (acc, val) { return acc + Math.abs(val) }, 0)
|
||||||
.toString()
|
.toString()
|
||||||
oscillator.disconnect()
|
oscillator.disconnect()
|
||||||
compressor.disconnect()
|
compressor.disconnect()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -395,6 +395,9 @@
|
||||||
var UserAgent = function (done) {
|
var UserAgent = function (done) {
|
||||||
done(navigator.userAgent)
|
done(navigator.userAgent)
|
||||||
}
|
}
|
||||||
|
var webdriver = function (done, options) {
|
||||||
|
done(navigator.webdriver == null ? options.NOT_AVAILABLE : navigator.webdriver)
|
||||||
|
}
|
||||||
var languageKey = function (done, options) {
|
var languageKey = function (done, options) {
|
||||||
done(navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage || options.NOT_AVAILABLE)
|
done(navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage || options.NOT_AVAILABLE)
|
||||||
}
|
}
|
||||||
|
@ -451,7 +454,7 @@
|
||||||
done(hasIndexedDB(options))
|
done(hasIndexedDB(options))
|
||||||
}
|
}
|
||||||
var addBehaviorKey = function (done) {
|
var addBehaviorKey = function (done) {
|
||||||
// body might not be defined at this point or removed programmatically
|
// body might not be defined at this point or removed programmatically
|
||||||
done(!!(document.body && document.body.addBehavior))
|
done(!!(document.body && document.body.addBehavior))
|
||||||
}
|
}
|
||||||
var openDatabaseKey = function (done) {
|
var openDatabaseKey = function (done) {
|
||||||
|
@ -502,7 +505,7 @@
|
||||||
var hasLiedBrowserKey = function (done) {
|
var hasLiedBrowserKey = function (done) {
|
||||||
done(getHasLiedBrowser())
|
done(getHasLiedBrowser())
|
||||||
}
|
}
|
||||||
// flash fonts (will increase fingerprinting time 20X to ~ 130-150ms)
|
// flash fonts (will increase fingerprinting time 20X to ~ 130-150ms)
|
||||||
var flashFontsKey = function (done, options) {
|
var flashFontsKey = function (done, options) {
|
||||||
// we do flash if swfobject is loaded
|
// we do flash if swfobject is loaded
|
||||||
if (!hasSwfObjectLoaded()) {
|
if (!hasSwfObjectLoaded()) {
|
||||||
|
@ -518,10 +521,10 @@
|
||||||
done(fonts)
|
done(fonts)
|
||||||
}, options)
|
}, options)
|
||||||
}
|
}
|
||||||
// kudos to http://www.lalit.org/lab/javascript-css-font-detect/
|
// kudos to http://www.lalit.org/lab/javascript-css-font-detect/
|
||||||
var jsFontsKey = function (done, options) {
|
var jsFontsKey = function (done, options) {
|
||||||
// a font will be compared against all the three default fonts.
|
// a font will be compared against all the three default fonts.
|
||||||
// and if it doesn't match all 3 then that font is not available.
|
// and if it doesn't match all 3 then that font is not available.
|
||||||
var baseFonts = ['monospace', 'sans-serif', 'serif']
|
var baseFonts = ['monospace', 'sans-serif', 'serif']
|
||||||
|
|
||||||
var fontList = [
|
var fontList = [
|
||||||
|
@ -577,42 +580,42 @@
|
||||||
|
|
||||||
fontList = fontList.concat(options.fonts.userDefinedFonts)
|
fontList = fontList.concat(options.fonts.userDefinedFonts)
|
||||||
|
|
||||||
// remove duplicate fonts
|
// remove duplicate fonts
|
||||||
fontList = fontList.filter(function (font, position) {
|
fontList = fontList.filter(function (font, position) {
|
||||||
return fontList.indexOf(font) === position
|
return fontList.indexOf(font) === position
|
||||||
})
|
})
|
||||||
|
|
||||||
// we use m or w because these two characters take up the maximum width.
|
// we use m or w because these two characters take up the maximum width.
|
||||||
// And we use a LLi so that the same matching fonts can get separated
|
// And we use a LLi so that the same matching fonts can get separated
|
||||||
var testString = 'mmmmmmmmmmlli'
|
var testString = 'mmmmmmmmmmlli'
|
||||||
|
|
||||||
// we test using 72px font size, we may use any size. I guess larger the better.
|
// we test using 72px font size, we may use any size. I guess larger the better.
|
||||||
var testSize = '72px'
|
var testSize = '72px'
|
||||||
|
|
||||||
var h = document.getElementsByTagName('body')[0]
|
var h = document.getElementsByTagName('body')[0]
|
||||||
|
|
||||||
// div to load spans for the base fonts
|
// div to load spans for the base fonts
|
||||||
var baseFontsDiv = document.createElement('div')
|
var baseFontsDiv = document.createElement('div')
|
||||||
|
|
||||||
// div to load spans for the fonts to detect
|
// div to load spans for the fonts to detect
|
||||||
var fontsDiv = document.createElement('div')
|
var fontsDiv = document.createElement('div')
|
||||||
|
|
||||||
var defaultWidth = {}
|
var defaultWidth = {}
|
||||||
var defaultHeight = {}
|
var defaultHeight = {}
|
||||||
|
|
||||||
// creates a span where the fonts will be loaded
|
// creates a span where the fonts will be loaded
|
||||||
var createSpan = function () {
|
var createSpan = function () {
|
||||||
var s = document.createElement('span')
|
var s = document.createElement('span')
|
||||||
/*
|
/*
|
||||||
* We need this css as in some weird browser this
|
* We need this css as in some weird browser this
|
||||||
* span elements shows up for a microSec which creates a
|
* span elements shows up for a microSec which creates a
|
||||||
* bad user experience
|
* bad user experience
|
||||||
*/
|
*/
|
||||||
s.style.position = 'absolute'
|
s.style.position = 'absolute'
|
||||||
s.style.left = '-9999px'
|
s.style.left = '-9999px'
|
||||||
s.style.fontSize = testSize
|
s.style.fontSize = testSize
|
||||||
|
|
||||||
// css font reset to reset external styles
|
// css font reset to reset external styles
|
||||||
s.style.fontStyle = 'normal'
|
s.style.fontStyle = 'normal'
|
||||||
s.style.fontWeight = 'normal'
|
s.style.fontWeight = 'normal'
|
||||||
s.style.letterSpacing = 'normal'
|
s.style.letterSpacing = 'normal'
|
||||||
|
@ -630,14 +633,14 @@
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates a span and load the font to detect and a base font for fallback
|
// creates a span and load the font to detect and a base font for fallback
|
||||||
var createSpanWithFonts = function (fontToDetect, baseFont) {
|
var createSpanWithFonts = function (fontToDetect, baseFont) {
|
||||||
var s = createSpan()
|
var s = createSpan()
|
||||||
s.style.fontFamily = "'" + fontToDetect + "'," + baseFont
|
s.style.fontFamily = "'" + fontToDetect + "'," + baseFont
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates spans for the base fonts and adds them to baseFontsDiv
|
// creates spans for the base fonts and adds them to baseFontsDiv
|
||||||
var initializeBaseFontsSpans = function () {
|
var initializeBaseFontsSpans = function () {
|
||||||
var spans = []
|
var spans = []
|
||||||
for (var index = 0, length = baseFonts.length; index < length; index++) {
|
for (var index = 0, length = baseFonts.length; index < length; index++) {
|
||||||
|
@ -649,7 +652,7 @@
|
||||||
return spans
|
return spans
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates spans for the fonts to detect and adds them to fontsDiv
|
// creates spans for the fonts to detect and adds them to fontsDiv
|
||||||
var initializeFontsSpans = function () {
|
var initializeFontsSpans = function () {
|
||||||
var spans = {}
|
var spans = {}
|
||||||
for (var i = 0, l = fontList.length; i < l; i++) {
|
for (var i = 0, l = fontList.length; i < l; i++) {
|
||||||
|
@ -664,7 +667,7 @@
|
||||||
return spans
|
return spans
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if a font is available
|
// checks if a font is available
|
||||||
var isFontAvailable = function (fontSpans) {
|
var isFontAvailable = function (fontSpans) {
|
||||||
var detected = false
|
var detected = false
|
||||||
for (var i = 0; i < baseFonts.length; i++) {
|
for (var i = 0; i < baseFonts.length; i++) {
|
||||||
|
@ -676,25 +679,25 @@
|
||||||
return detected
|
return detected
|
||||||
}
|
}
|
||||||
|
|
||||||
// create spans for base fonts
|
// create spans for base fonts
|
||||||
var baseFontsSpans = initializeBaseFontsSpans()
|
var baseFontsSpans = initializeBaseFontsSpans()
|
||||||
|
|
||||||
// add the spans to the DOM
|
// add the spans to the DOM
|
||||||
h.appendChild(baseFontsDiv)
|
h.appendChild(baseFontsDiv)
|
||||||
|
|
||||||
// get the default width for the three base fonts
|
// get the default width for the three base fonts
|
||||||
for (var index = 0, length = baseFonts.length; index < length; index++) {
|
for (var index = 0, length = baseFonts.length; index < length; index++) {
|
||||||
defaultWidth[baseFonts[index]] = baseFontsSpans[index].offsetWidth // width for the default font
|
defaultWidth[baseFonts[index]] = baseFontsSpans[index].offsetWidth // width for the default font
|
||||||
defaultHeight[baseFonts[index]] = baseFontsSpans[index].offsetHeight // height for the default font
|
defaultHeight[baseFonts[index]] = baseFontsSpans[index].offsetHeight // height for the default font
|
||||||
}
|
}
|
||||||
|
|
||||||
// create spans for fonts to detect
|
// create spans for fonts to detect
|
||||||
var fontsSpans = initializeFontsSpans()
|
var fontsSpans = initializeFontsSpans()
|
||||||
|
|
||||||
// add all the spans to the DOM
|
// add all the spans to the DOM
|
||||||
h.appendChild(fontsDiv)
|
h.appendChild(fontsDiv)
|
||||||
|
|
||||||
// check available fonts
|
// check available fonts
|
||||||
var available = []
|
var available = []
|
||||||
for (var i = 0, l = fontList.length; i < l; i++) {
|
for (var i = 0, l = fontList.length; i < l; i++) {
|
||||||
if (isFontAvailable(fontsSpans[fontList[i]])) {
|
if (isFontAvailable(fontsSpans[fontList[i]])) {
|
||||||
|
@ -702,7 +705,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove spans from DOM
|
// remove spans from DOM
|
||||||
h.removeChild(fontsDiv)
|
h.removeChild(fontsDiv)
|
||||||
h.removeChild(baseFontsDiv)
|
h.removeChild(baseFontsDiv)
|
||||||
done(available)
|
done(available)
|
||||||
|
@ -724,13 +727,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var plugins = []
|
var plugins = []
|
||||||
// plugins isn't defined in Node envs.
|
// plugins isn't defined in Node envs.
|
||||||
for (var i = 0, l = navigator.plugins.length; i < l; i++) {
|
for (var i = 0, l = navigator.plugins.length; i < l; i++) {
|
||||||
if (navigator.plugins[i]) { plugins.push(navigator.plugins[i]) }
|
if (navigator.plugins[i]) { plugins.push(navigator.plugins[i]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// sorting plugins only for those user agents, that we know randomize the plugins
|
// sorting plugins only for those user agents, that we know randomize the plugins
|
||||||
// every time we try to enumerate them
|
// every time we try to enumerate them
|
||||||
if (pluginsShouldBeSorted(options)) {
|
if (pluginsShouldBeSorted(options)) {
|
||||||
plugins = plugins.sort(function (a, b) {
|
plugins = plugins.sort(function (a, b) {
|
||||||
if (a.name > b.name) { return 1 }
|
if (a.name > b.name) { return 1 }
|
||||||
|
@ -772,10 +775,10 @@
|
||||||
'rmocx.RealPlayer G2 Control',
|
'rmocx.RealPlayer G2 Control',
|
||||||
'rmocx.RealPlayer G2 Control.1'
|
'rmocx.RealPlayer G2 Control.1'
|
||||||
]
|
]
|
||||||
// starting to detect plugins in IE
|
// starting to detect plugins in IE
|
||||||
result = map(names, function (name) {
|
result = map(names, function (name) {
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-new
|
// eslint-disable-next-line no-new
|
||||||
new window.ActiveXObject(name)
|
new window.ActiveXObject(name)
|
||||||
return name
|
return name
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -815,7 +818,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=781447
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=781447
|
||||||
var hasLocalStorage = function (options) {
|
var hasLocalStorage = function (options) {
|
||||||
try {
|
try {
|
||||||
return !!window.localStorage
|
return !!window.localStorage
|
||||||
|
@ -857,14 +860,14 @@
|
||||||
return options.NOT_AVAILABLE
|
return options.NOT_AVAILABLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// This is a crude and primitive touch screen detection.
|
// This is a crude and primitive touch screen detection.
|
||||||
// It's not possible to currently reliably detect the availability of a touch screen
|
// It's not possible to currently reliably detect the availability of a touch screen
|
||||||
// with a JS, without actually subscribing to a touch event.
|
// with a JS, without actually subscribing to a touch event.
|
||||||
// http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
|
// http://www.stucox.com/blog/you-cant-detect-a-touchscreen/
|
||||||
// https://github.com/Modernizr/Modernizr/issues/548
|
// https://github.com/Modernizr/Modernizr/issues/548
|
||||||
// method returns an array of 3 values:
|
// method returns an array of 3 values:
|
||||||
// maxTouchPoints, the success or failure of creating a TouchEvent,
|
// maxTouchPoints, the success or failure of creating a TouchEvent,
|
||||||
// and the availability of the 'ontouchstart' property
|
// and the availability of the 'ontouchstart' property
|
||||||
|
|
||||||
var getTouchSupport = function () {
|
var getTouchSupport = function () {
|
||||||
var maxTouchPoints = 0
|
var maxTouchPoints = 0
|
||||||
|
@ -883,19 +886,19 @@
|
||||||
var touchStart = 'ontouchstart' in window
|
var touchStart = 'ontouchstart' in window
|
||||||
return [maxTouchPoints, touchEvent, touchStart]
|
return [maxTouchPoints, touchEvent, touchStart]
|
||||||
}
|
}
|
||||||
// https://www.browserleaks.com/canvas#how-does-it-work
|
// https://www.browserleaks.com/canvas#how-does-it-work
|
||||||
|
|
||||||
var getCanvasFp = function (options) {
|
var getCanvasFp = function (options) {
|
||||||
var result = []
|
var result = []
|
||||||
// Very simple now, need to make it more complex (geo shapes etc)
|
// Very simple now, need to make it more complex (geo shapes etc)
|
||||||
var canvas = document.createElement('canvas')
|
var canvas = document.createElement('canvas')
|
||||||
canvas.width = 2000
|
canvas.width = 2000
|
||||||
canvas.height = 200
|
canvas.height = 200
|
||||||
canvas.style.display = 'inline'
|
canvas.style.display = 'inline'
|
||||||
var ctx = canvas.getContext('2d')
|
var ctx = canvas.getContext('2d')
|
||||||
// detect browser support of canvas winding
|
// detect browser support of canvas winding
|
||||||
// http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/
|
// http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/
|
||||||
// https://github.com/Modernizr/Modernizr/blob/master/feature-detects/canvas/winding.js
|
// https://github.com/Modernizr/Modernizr/blob/master/feature-detects/canvas/winding.js
|
||||||
ctx.rect(0, 0, 10, 10)
|
ctx.rect(0, 0, 10, 10)
|
||||||
ctx.rect(2, 2, 6, 6)
|
ctx.rect(2, 2, 6, 6)
|
||||||
result.push('canvas winding:' + ((ctx.isPointInPath(5, 5, 'evenodd') === false) ? 'yes' : 'no'))
|
result.push('canvas winding:' + ((ctx.isPointInPath(5, 5, 'evenodd') === false) ? 'yes' : 'no'))
|
||||||
|
@ -904,7 +907,7 @@
|
||||||
ctx.fillStyle = '#f60'
|
ctx.fillStyle = '#f60'
|
||||||
ctx.fillRect(125, 1, 62, 20)
|
ctx.fillRect(125, 1, 62, 20)
|
||||||
ctx.fillStyle = '#069'
|
ctx.fillStyle = '#069'
|
||||||
// https://github.com/Valve/fingerprintjs2/issues/66
|
// https://github.com/Valve/fingerprintjs2/issues/66
|
||||||
if (options.dontUseFakeFontInCanvas) {
|
if (options.dontUseFakeFontInCanvas) {
|
||||||
ctx.font = '11pt Arial'
|
ctx.font = '11pt Arial'
|
||||||
} else {
|
} else {
|
||||||
|
@ -915,9 +918,9 @@
|
||||||
ctx.font = '18pt Arial'
|
ctx.font = '18pt Arial'
|
||||||
ctx.fillText('Cwm fjordbank glyphs vext quiz, \ud83d\ude03', 4, 45)
|
ctx.fillText('Cwm fjordbank glyphs vext quiz, \ud83d\ude03', 4, 45)
|
||||||
|
|
||||||
// canvas blending
|
// canvas blending
|
||||||
// http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
|
// http://blogs.adobe.com/webplatform/2013/01/28/blending-features-in-canvas/
|
||||||
// http://jsfiddle.net/NDYV8/16/
|
// http://jsfiddle.net/NDYV8/16/
|
||||||
ctx.globalCompositeOperation = 'multiply'
|
ctx.globalCompositeOperation = 'multiply'
|
||||||
ctx.fillStyle = 'rgb(255,0,255)'
|
ctx.fillStyle = 'rgb(255,0,255)'
|
||||||
ctx.beginPath()
|
ctx.beginPath()
|
||||||
|
@ -935,9 +938,9 @@
|
||||||
ctx.closePath()
|
ctx.closePath()
|
||||||
ctx.fill()
|
ctx.fill()
|
||||||
ctx.fillStyle = 'rgb(255,0,255)'
|
ctx.fillStyle = 'rgb(255,0,255)'
|
||||||
// canvas winding
|
// canvas winding
|
||||||
// http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/
|
// http://blogs.adobe.com/webplatform/2013/01/30/winding-rules-in-canvas/
|
||||||
// http://jsfiddle.net/NDYV8/19/
|
// http://jsfiddle.net/NDYV8/19/
|
||||||
ctx.arc(75, 75, 75, 0, Math.PI * 2, true)
|
ctx.arc(75, 75, 75, 0, Math.PI * 2, true)
|
||||||
ctx.arc(75, 75, 25, 0, Math.PI * 2, true)
|
ctx.arc(75, 75, 25, 0, Math.PI * 2, true)
|
||||||
ctx.fill('evenodd')
|
ctx.fill('evenodd')
|
||||||
|
@ -969,10 +972,10 @@
|
||||||
|
|
||||||
gl = getWebglCanvas()
|
gl = getWebglCanvas()
|
||||||
if (!gl) { return null }
|
if (!gl) { return null }
|
||||||
// WebGL fingerprinting is a combination of techniques, found in MaxMind antifraud script & Augur fingerprinting.
|
// WebGL fingerprinting is a combination of techniques, found in MaxMind antifraud script & Augur fingerprinting.
|
||||||
// First it draws a gradient object with shaders and convers the image to the Base64 string.
|
// First it draws a gradient object with shaders and convers the image to the Base64 string.
|
||||||
// Then it enumerates all WebGL extensions & capabilities and appends them to the Base64 string, resulting in a huge WebGL string, potentially very unique on each device
|
// Then it enumerates all WebGL extensions & capabilities and appends them to the Base64 string, resulting in a huge WebGL string, potentially very unique on each device
|
||||||
// Since iOS supports webgl starting from version 8.1 and 8.1 runs on several graphics chips, the results may be different across ios devices, but we need to verify it.
|
// Since iOS supports webgl starting from version 8.1 and 8.1 runs on several graphics chips, the results may be different across ios devices, but we need to verify it.
|
||||||
var result = []
|
var result = []
|
||||||
var vShaderTemplate = 'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}'
|
var vShaderTemplate = 'attribute vec2 attrVertex;varying vec2 varyinTexCoordinate;uniform vec2 uniformOffset;void main(){varyinTexCoordinate=attrVertex+uniformOffset;gl_Position=vec4(attrVertex,0,1);}'
|
||||||
var fShaderTemplate = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}'
|
var fShaderTemplate = 'precision mediump float;varying vec2 varyinTexCoordinate;void main() {gl_FragColor=vec4(varyinTexCoordinate,0,1);}'
|
||||||
|
@ -1002,7 +1005,7 @@
|
||||||
try {
|
try {
|
||||||
result.push(gl.canvas.toDataURL())
|
result.push(gl.canvas.toDataURL())
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
/* .toDataURL may be absent or broken (blocked by extension) */
|
/* .toDataURL may be absent or broken (blocked by extension) */
|
||||||
}
|
}
|
||||||
result.push('extensions:' + (gl.getSupportedExtensions() || []).join(';'))
|
result.push('extensions:' + (gl.getSupportedExtensions() || []).join(';'))
|
||||||
result.push('webgl aliased line width range:' + fa2s(gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE)))
|
result.push('webgl aliased line width range:' + fa2s(gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE)))
|
||||||
|
@ -1032,7 +1035,7 @@
|
||||||
result.push('webgl version:' + gl.getParameter(gl.VERSION))
|
result.push('webgl version:' + gl.getParameter(gl.VERSION))
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Add the unmasked vendor and unmasked renderer if the debug_renderer_info extension is available
|
// Add the unmasked vendor and unmasked renderer if the debug_renderer_info extension is available
|
||||||
var extensionDebugRendererInfo = gl.getExtension('WEBGL_debug_renderer_info')
|
var extensionDebugRendererInfo = gl.getExtension('WEBGL_debug_renderer_info')
|
||||||
if (extensionDebugRendererInfo) {
|
if (extensionDebugRendererInfo) {
|
||||||
result.push('webgl unmasked vendor:' + gl.getParameter(extensionDebugRendererInfo.UNMASKED_VENDOR_WEBGL))
|
result.push('webgl unmasked vendor:' + gl.getParameter(extensionDebugRendererInfo.UNMASKED_VENDOR_WEBGL))
|
||||||
|
@ -1061,7 +1064,7 @@
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
var getWebglVendorAndRenderer = function () {
|
var getWebglVendorAndRenderer = function () {
|
||||||
/* This a subset of the WebGL fingerprint with a lot of entropy, while being reasonably browser-independent */
|
/* This a subset of the WebGL fingerprint with a lot of entropy, while being reasonably browser-independent */
|
||||||
try {
|
try {
|
||||||
var glContext = getWebglCanvas()
|
var glContext = getWebglCanvas()
|
||||||
var extensionDebugRendererInfo = glContext.getExtension('WEBGL_debug_renderer_info')
|
var extensionDebugRendererInfo = glContext.getExtension('WEBGL_debug_renderer_info')
|
||||||
|
@ -1076,7 +1079,7 @@
|
||||||
ads.className = 'adsbox'
|
ads.className = 'adsbox'
|
||||||
var result = false
|
var result = false
|
||||||
try {
|
try {
|
||||||
// body may not exist, that's why we need try/catch
|
// body may not exist, that's why we need try/catch
|
||||||
document.body.appendChild(ads)
|
document.body.appendChild(ads)
|
||||||
result = document.getElementsByClassName('adsbox')[0].offsetHeight === 0
|
result = document.getElementsByClassName('adsbox')[0].offsetHeight === 0
|
||||||
document.body.removeChild(ads)
|
document.body.removeChild(ads)
|
||||||
|
@ -1086,7 +1089,8 @@
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
var getHasLiedLanguages = function () {
|
var getHasLiedLanguages = function () {
|
||||||
// We check if navigator.language is equal to the first language of navigator.languages
|
// We check if navigator.language is equal to the first language of navigator.languages
|
||||||
|
// navigator.languages is undefined on IE11 (and potentially older IEs)
|
||||||
if (typeof navigator.languages !== 'undefined') {
|
if (typeof navigator.languages !== 'undefined') {
|
||||||
try {
|
try {
|
||||||
var firstLanguages = navigator.languages[0].substr(0, 2)
|
var firstLanguages = navigator.languages[0].substr(0, 2)
|
||||||
|
@ -1107,14 +1111,14 @@
|
||||||
var oscpu = navigator.oscpu
|
var oscpu = navigator.oscpu
|
||||||
var platform = navigator.platform.toLowerCase()
|
var platform = navigator.platform.toLowerCase()
|
||||||
var os
|
var os
|
||||||
// We extract the OS from the user agent (respect the order of the if else if statement)
|
// We extract the OS from the user agent (respect the order of the if else if statement)
|
||||||
if (userAgent.indexOf('windows phone') >= 0) {
|
if (userAgent.indexOf('windows phone') >= 0) {
|
||||||
os = 'Windows Phone'
|
os = 'Windows Phone'
|
||||||
} else if (userAgent.indexOf('win') >= 0) {
|
} else if (userAgent.indexOf('win') >= 0) {
|
||||||
os = 'Windows'
|
os = 'Windows'
|
||||||
} else if (userAgent.indexOf('android') >= 0) {
|
} else if (userAgent.indexOf('android') >= 0) {
|
||||||
os = 'Android'
|
os = 'Android'
|
||||||
} else if (userAgent.indexOf('linux') >= 0) {
|
} else if (userAgent.indexOf('linux') >= 0 || userAgent.indexOf('cros') >= 0) {
|
||||||
os = 'Linux'
|
os = 'Linux'
|
||||||
} else if (userAgent.indexOf('iphone') >= 0 || userAgent.indexOf('ipad') >= 0) {
|
} else if (userAgent.indexOf('iphone') >= 0 || userAgent.indexOf('ipad') >= 0) {
|
||||||
os = 'iOS'
|
os = 'iOS'
|
||||||
|
@ -1123,16 +1127,16 @@
|
||||||
} else {
|
} else {
|
||||||
os = 'Other'
|
os = 'Other'
|
||||||
}
|
}
|
||||||
// We detect if the person uses a mobile device
|
// We detect if the person uses a mobile device
|
||||||
var mobileDevice = (('ontouchstart' in window) ||
|
var mobileDevice = (('ontouchstart' in window) ||
|
||||||
(navigator.maxTouchPoints > 0) ||
|
(navigator.maxTouchPoints > 0) ||
|
||||||
(navigator.msMaxTouchPoints > 0))
|
(navigator.msMaxTouchPoints > 0))
|
||||||
|
|
||||||
if (mobileDevice && os !== 'Windows Phone' && os !== 'Android' && os !== 'iOS' && os !== 'Other') {
|
if (mobileDevice && os !== 'Windows Phone' && os !== 'Android' && os !== 'iOS' && os !== 'Other') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// We compare oscpu with the OS extracted from the UA
|
// We compare oscpu with the OS extracted from the UA
|
||||||
if (typeof oscpu !== 'undefined') {
|
if (typeof oscpu !== 'undefined') {
|
||||||
oscpu = oscpu.toLowerCase()
|
oscpu = oscpu.toLowerCase()
|
||||||
if (oscpu.indexOf('win') >= 0 && os !== 'Windows' && os !== 'Windows Phone') {
|
if (oscpu.indexOf('win') >= 0 && os !== 'Windows' && os !== 'Windows Phone') {
|
||||||
|
@ -1146,15 +1150,22 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We compare platform with the OS extracted from the UA
|
// We compare platform with the OS extracted from the UA
|
||||||
if (platform.indexOf('win') >= 0 && os !== 'Windows' && os !== 'Windows Phone') {
|
if (platform.indexOf('win') >= 0 && os !== 'Windows' && os !== 'Windows Phone') {
|
||||||
return true
|
return true
|
||||||
} else if ((platform.indexOf('linux') >= 0 || platform.indexOf('android') >= 0 || platform.indexOf('pike') >= 0) && os !== 'Linux' && os !== 'Android') {
|
} else if ((platform.indexOf('linux') >= 0 || platform.indexOf('android') >= 0 || platform.indexOf('pike') >= 0) && os !== 'Linux' && os !== 'Android') {
|
||||||
return true
|
return true
|
||||||
} else if ((platform.indexOf('mac') >= 0 || platform.indexOf('ipad') >= 0 || platform.indexOf('ipod') >= 0 || platform.indexOf('iphone') >= 0) && os !== 'Mac' && os !== 'iOS') {
|
} else if ((platform.indexOf('mac') >= 0 || platform.indexOf('ipad') >= 0 || platform.indexOf('ipod') >= 0 || platform.indexOf('iphone') >= 0) && os !== 'Mac' && os !== 'iOS') {
|
||||||
return true
|
return true
|
||||||
} else if ((platform.indexOf('win') === -1 && platform.indexOf('linux') === -1 && platform.indexOf('mac') === -1) !== (os === 'Other')) {
|
} else {
|
||||||
return true
|
var platformIsOther = platform.indexOf('win') < 0 &&
|
||||||
|
platform.indexOf('linux') < 0 &&
|
||||||
|
platform.indexOf('mac') < 0 &&
|
||||||
|
platform.indexOf('iphone') < 0 &&
|
||||||
|
platform.indexOf('ipad') < 0
|
||||||
|
if (platformIsOther !== (os === 'Other')) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return typeof navigator.plugins === 'undefined' && os !== 'Windows' && os !== 'Windows Phone'
|
return typeof navigator.plugins === 'undefined' && os !== 'Windows' && os !== 'Windows Phone'
|
||||||
|
@ -1163,7 +1174,7 @@
|
||||||
var userAgent = navigator.userAgent.toLowerCase()
|
var userAgent = navigator.userAgent.toLowerCase()
|
||||||
var productSub = navigator.productSub
|
var productSub = navigator.productSub
|
||||||
|
|
||||||
// we extract the browser from the user agent (respect the order of the tests)
|
// we extract the browser from the user agent (respect the order of the tests)
|
||||||
var browser
|
var browser
|
||||||
if (userAgent.indexOf('firefox') >= 0) {
|
if (userAgent.indexOf('firefox') >= 0) {
|
||||||
browser = 'Firefox'
|
browser = 'Firefox'
|
||||||
|
@ -1183,7 +1194,7 @@
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-eval
|
// eslint-disable-next-line no-eval
|
||||||
var tempRes = eval.toString().length
|
var tempRes = eval.toString().length
|
||||||
if (tempRes === 37 && browser !== 'Safari' && browser !== 'Firefox' && browser !== 'Other') {
|
if (tempRes === 37 && browser !== 'Safari' && browser !== 'Firefox' && browser !== 'Other') {
|
||||||
return true
|
return true
|
||||||
|
@ -1193,10 +1204,10 @@
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// We create an error to see how it is handled
|
// We create an error to see how it is handled
|
||||||
var errFirefox
|
var errFirefox
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-throw-literal
|
// eslint-disable-next-line no-throw-literal
|
||||||
throw 'a'
|
throw 'a'
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
try {
|
try {
|
||||||
|
@ -1213,7 +1224,7 @@
|
||||||
return !!(elem.getContext && elem.getContext('2d'))
|
return !!(elem.getContext && elem.getContext('2d'))
|
||||||
}
|
}
|
||||||
var isWebGlSupported = function () {
|
var isWebGlSupported = function () {
|
||||||
// code taken from Modernizr
|
// code taken from Modernizr
|
||||||
if (!isCanvasSupported()) {
|
if (!isCanvasSupported()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -1262,38 +1273,39 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var components = [
|
var components = [
|
||||||
{key: 'userAgent', getData: UserAgent},
|
{ key: 'userAgent', getData: UserAgent },
|
||||||
{key: 'language', getData: languageKey},
|
{ key: 'webdriver', getData: webdriver },
|
||||||
{key: 'colorDepth', getData: colorDepthKey},
|
{ key: 'language', getData: languageKey },
|
||||||
{key: 'deviceMemory', getData: deviceMemoryKey},
|
{ key: 'colorDepth', getData: colorDepthKey },
|
||||||
{key: 'pixelRatio', getData: pixelRatioKey},
|
{ key: 'deviceMemory', getData: deviceMemoryKey },
|
||||||
{key: 'hardwareConcurrency', getData: hardwareConcurrencyKey},
|
{ key: 'pixelRatio', getData: pixelRatioKey },
|
||||||
{key: 'screenResolution', getData: screenResolutionKey},
|
{ key: 'hardwareConcurrency', getData: hardwareConcurrencyKey },
|
||||||
{key: 'availableScreenResolution', getData: availableScreenResolutionKey},
|
{ key: 'screenResolution', getData: screenResolutionKey },
|
||||||
{key: 'timezoneOffset', getData: timezoneOffset},
|
{ key: 'availableScreenResolution', getData: availableScreenResolutionKey },
|
||||||
{key: 'timezone', getData: timezone},
|
{ key: 'timezoneOffset', getData: timezoneOffset },
|
||||||
{key: 'sessionStorage', getData: sessionStorageKey},
|
{ key: 'timezone', getData: timezone },
|
||||||
{key: 'localStorage', getData: localStorageKey},
|
{ key: 'sessionStorage', getData: sessionStorageKey },
|
||||||
{key: 'indexedDb', getData: indexedDbKey},
|
{ key: 'localStorage', getData: localStorageKey },
|
||||||
{key: 'addBehavior', getData: addBehaviorKey},
|
{ key: 'indexedDb', getData: indexedDbKey },
|
||||||
{key: 'openDatabase', getData: openDatabaseKey},
|
{ key: 'addBehavior', getData: addBehaviorKey },
|
||||||
{key: 'cpuClass', getData: cpuClassKey},
|
{ key: 'openDatabase', getData: openDatabaseKey },
|
||||||
{key: 'platform', getData: platformKey},
|
{ key: 'cpuClass', getData: cpuClassKey },
|
||||||
{key: 'doNotTrack', getData: doNotTrackKey},
|
{ key: 'platform', getData: platformKey },
|
||||||
{key: 'plugins', getData: pluginsComponent},
|
{ key: 'doNotTrack', getData: doNotTrackKey },
|
||||||
{key: 'canvas', getData: canvasKey},
|
{ key: 'plugins', getData: pluginsComponent },
|
||||||
{key: 'webgl', getData: webglKey},
|
{ key: 'canvas', getData: canvasKey },
|
||||||
{key: 'webglVendorAndRenderer', getData: webglVendorAndRendererKey},
|
{ key: 'webgl', getData: webglKey },
|
||||||
{key: 'adBlock', getData: adBlockKey},
|
{ key: 'webglVendorAndRenderer', getData: webglVendorAndRendererKey },
|
||||||
{key: 'hasLiedLanguages', getData: hasLiedLanguagesKey},
|
{ key: 'adBlock', getData: adBlockKey },
|
||||||
{key: 'hasLiedResolution', getData: hasLiedResolutionKey},
|
{ key: 'hasLiedLanguages', getData: hasLiedLanguagesKey },
|
||||||
{key: 'hasLiedOs', getData: hasLiedOsKey},
|
{ key: 'hasLiedResolution', getData: hasLiedResolutionKey },
|
||||||
{key: 'hasLiedBrowser', getData: hasLiedBrowserKey},
|
{ key: 'hasLiedOs', getData: hasLiedOsKey },
|
||||||
{key: 'touchSupport', getData: touchSupportKey},
|
{ key: 'hasLiedBrowser', getData: hasLiedBrowserKey },
|
||||||
{key: 'fonts', getData: jsFontsKey, pauseBefore: true},
|
{ key: 'touchSupport', getData: touchSupportKey },
|
||||||
{key: 'fontsFlash', getData: flashFontsKey, pauseBefore: true},
|
{ key: 'fonts', getData: jsFontsKey, pauseBefore: true },
|
||||||
{key: 'audio', getData: audioKey},
|
{ key: 'fontsFlash', getData: flashFontsKey, pauseBefore: true },
|
||||||
{key: 'enumerateDevices', getData: enumerateDevicesKey}
|
{ key: 'audio', getData: audioKey },
|
||||||
|
{ key: 'enumerateDevices', getData: enumerateDevicesKey }
|
||||||
]
|
]
|
||||||
|
|
||||||
var Fingerprint2 = function (options) {
|
var Fingerprint2 = function (options) {
|
||||||
|
@ -1316,7 +1328,7 @@
|
||||||
if (typeof options.preprocessor === 'function') {
|
if (typeof options.preprocessor === 'function') {
|
||||||
value = options.preprocessor(key, value)
|
value = options.preprocessor(key, value)
|
||||||
}
|
}
|
||||||
keys.data.push({key: key, value: value})
|
keys.data.push({ key: key, value: value })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1373,30 +1385,32 @@
|
||||||
for (var i = 0; i < components.length; i++) {
|
for (var i = 0; i < components.length; i++) {
|
||||||
var component = components[i]
|
var component = components[i]
|
||||||
if (component.value === (options.NOT_AVAILABLE || 'not available')) {
|
if (component.value === (options.NOT_AVAILABLE || 'not available')) {
|
||||||
newComponents.push({key: component.key, value: 'unknown'})
|
newComponents.push({ key: component.key, value: 'unknown' })
|
||||||
} else if (component.key === 'plugins') {
|
} else if (component.key === 'plugins') {
|
||||||
newComponents.push({key: 'plugins',
|
newComponents.push({
|
||||||
|
key: 'plugins',
|
||||||
value: map(component.value, function (p) {
|
value: map(component.value, function (p) {
|
||||||
var mimeTypes = map(p[2], function (mt) {
|
var mimeTypes = map(p[2], function (mt) {
|
||||||
if (mt.join) { return mt.join('~') }
|
if (mt.join) { return mt.join('~') }
|
||||||
return mt
|
return mt
|
||||||
}).join(',')
|
}).join(',')
|
||||||
return [p[0], p[1], mimeTypes].join('::')
|
return [p[0], p[1], mimeTypes].join('::')
|
||||||
})})
|
})
|
||||||
|
})
|
||||||
} else if (['canvas', 'webgl'].indexOf(component.key) !== -1) {
|
} else if (['canvas', 'webgl'].indexOf(component.key) !== -1) {
|
||||||
newComponents.push({key: component.key, value: component.value.join('~')})
|
newComponents.push({ key: component.key, value: component.value.join('~') })
|
||||||
} else if (['sessionStorage', 'localStorage', 'indexedDb', 'addBehavior', 'openDatabase'].indexOf(component.key) !== -1) {
|
} else if (['sessionStorage', 'localStorage', 'indexedDb', 'addBehavior', 'openDatabase'].indexOf(component.key) !== -1) {
|
||||||
if (component.value) {
|
if (component.value) {
|
||||||
newComponents.push({key: component.key, value: 1})
|
newComponents.push({ key: component.key, value: 1 })
|
||||||
} else {
|
} else {
|
||||||
// skip
|
// skip
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (component.value) {
|
if (component.value) {
|
||||||
newComponents.push(component.value.join ? {key: component.key, value: component.value.join(';')} : component)
|
newComponents.push(component.value.join ? { key: component.key, value: component.value.join(';') } : component)
|
||||||
} else {
|
} else {
|
||||||
newComponents.push({key: component.key, value: component.value})
|
newComponents.push({ key: component.key, value: component.value })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1406,6 +1420,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Fingerprint2.x64hash128 = x64hash128
|
Fingerprint2.x64hash128 = x64hash128
|
||||||
Fingerprint2.VERSION = '2.0.0'
|
Fingerprint2.VERSION = '2.1.0'
|
||||||
return Fingerprint2
|
return Fingerprint2
|
||||||
})
|
})
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
/*!
|
/*!
|
||||||
* jQuery JavaScript Library v3.4.0
|
* jQuery JavaScript Library v3.4.1
|
||||||
* https://jquery.com/
|
* https://jquery.com/
|
||||||
*
|
*
|
||||||
* Includes Sizzle.js
|
* Includes Sizzle.js
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
* Released under the MIT license
|
* Released under the MIT license
|
||||||
* https://jquery.org/license
|
* https://jquery.org/license
|
||||||
*
|
*
|
||||||
* Date: 2019-04-10T19:48Z
|
* Date: 2019-05-01T21:04Z
|
||||||
*/
|
*/
|
||||||
( function( global, factory ) {
|
( function( global, factory ) {
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ function toType( obj ) {
|
||||||
|
|
||||||
|
|
||||||
var
|
var
|
||||||
version = "3.4.0",
|
version = "3.4.1",
|
||||||
|
|
||||||
// Define a local copy of jQuery
|
// Define a local copy of jQuery
|
||||||
jQuery = function( selector, context ) {
|
jQuery = function( selector, context ) {
|
||||||
|
@ -4498,8 +4498,12 @@ var documentElement = document.documentElement;
|
||||||
},
|
},
|
||||||
composed = { composed: true };
|
composed = { composed: true };
|
||||||
|
|
||||||
|
// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
|
||||||
// Check attachment across shadow DOM boundaries when possible (gh-3504)
|
// Check attachment across shadow DOM boundaries when possible (gh-3504)
|
||||||
if ( documentElement.attachShadow ) {
|
// Support: iOS 10.0-10.2 only
|
||||||
|
// Early iOS 10 versions support `attachShadow` but not `getRootNode`,
|
||||||
|
// leading to errors. We need to check for `getRootNode`.
|
||||||
|
if ( documentElement.getRootNode ) {
|
||||||
isAttached = function( elem ) {
|
isAttached = function( elem ) {
|
||||||
return jQuery.contains( elem.ownerDocument, elem ) ||
|
return jQuery.contains( elem.ownerDocument, elem ) ||
|
||||||
elem.getRootNode( composed ) === elem.ownerDocument;
|
elem.getRootNode( composed ) === elem.ownerDocument;
|
||||||
|
@ -5359,8 +5363,7 @@ jQuery.event = {
|
||||||
|
|
||||||
// Claim the first handler
|
// Claim the first handler
|
||||||
if ( rcheckableType.test( el.type ) &&
|
if ( rcheckableType.test( el.type ) &&
|
||||||
el.click && nodeName( el, "input" ) &&
|
el.click && nodeName( el, "input" ) ) {
|
||||||
dataPriv.get( el, "click" ) === undefined ) {
|
|
||||||
|
|
||||||
// dataPriv.set( el, "click", ... )
|
// dataPriv.set( el, "click", ... )
|
||||||
leverageNative( el, "click", returnTrue );
|
leverageNative( el, "click", returnTrue );
|
||||||
|
@ -5377,8 +5380,7 @@ jQuery.event = {
|
||||||
|
|
||||||
// Force setup before triggering a click
|
// Force setup before triggering a click
|
||||||
if ( rcheckableType.test( el.type ) &&
|
if ( rcheckableType.test( el.type ) &&
|
||||||
el.click && nodeName( el, "input" ) &&
|
el.click && nodeName( el, "input" ) ) {
|
||||||
dataPriv.get( el, "click" ) === undefined ) {
|
|
||||||
|
|
||||||
leverageNative( el, "click" );
|
leverageNative( el, "click" );
|
||||||
}
|
}
|
||||||
|
@ -5419,7 +5421,9 @@ function leverageNative( el, type, expectSync ) {
|
||||||
|
|
||||||
// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
|
// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
|
||||||
if ( !expectSync ) {
|
if ( !expectSync ) {
|
||||||
jQuery.event.add( el, type, returnTrue );
|
if ( dataPriv.get( el, type ) === undefined ) {
|
||||||
|
jQuery.event.add( el, type, returnTrue );
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5434,9 +5438,13 @@ function leverageNative( el, type, expectSync ) {
|
||||||
if ( ( event.isTrigger & 1 ) && this[ type ] ) {
|
if ( ( event.isTrigger & 1 ) && this[ type ] ) {
|
||||||
|
|
||||||
// Interrupt processing of the outer synthetic .trigger()ed event
|
// Interrupt processing of the outer synthetic .trigger()ed event
|
||||||
if ( !saved ) {
|
// Saved data should be false in such cases, but might be a leftover capture object
|
||||||
|
// from an async native handler (gh-4350)
|
||||||
|
if ( !saved.length ) {
|
||||||
|
|
||||||
// Store arguments for use when handling the inner native event
|
// Store arguments for use when handling the inner native event
|
||||||
|
// There will always be at least one argument (an event object), so this array
|
||||||
|
// will not be confused with a leftover capture object.
|
||||||
saved = slice.call( arguments );
|
saved = slice.call( arguments );
|
||||||
dataPriv.set( this, type, saved );
|
dataPriv.set( this, type, saved );
|
||||||
|
|
||||||
|
@ -5449,14 +5457,14 @@ function leverageNative( el, type, expectSync ) {
|
||||||
if ( saved !== result || notAsync ) {
|
if ( saved !== result || notAsync ) {
|
||||||
dataPriv.set( this, type, false );
|
dataPriv.set( this, type, false );
|
||||||
} else {
|
} else {
|
||||||
result = undefined;
|
result = {};
|
||||||
}
|
}
|
||||||
if ( saved !== result ) {
|
if ( saved !== result ) {
|
||||||
|
|
||||||
// Cancel the outer synthetic event
|
// Cancel the outer synthetic event
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
return result;
|
return result.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is an inner synthetic event for an event with a bubbling surrogate
|
// If this is an inner synthetic event for an event with a bubbling surrogate
|
||||||
|
@ -5471,17 +5479,19 @@ function leverageNative( el, type, expectSync ) {
|
||||||
|
|
||||||
// If this is a native event triggered above, everything is now in order
|
// If this is a native event triggered above, everything is now in order
|
||||||
// Fire an inner synthetic event with the original arguments
|
// Fire an inner synthetic event with the original arguments
|
||||||
} else if ( saved ) {
|
} else if ( saved.length ) {
|
||||||
|
|
||||||
// ...and capture the result
|
// ...and capture the result
|
||||||
dataPriv.set( this, type, jQuery.event.trigger(
|
dataPriv.set( this, type, {
|
||||||
|
value: jQuery.event.trigger(
|
||||||
|
|
||||||
// Support: IE <=9 - 11+
|
// Support: IE <=9 - 11+
|
||||||
// Extend with the prototype to reset the above stopImmediatePropagation()
|
// Extend with the prototype to reset the above stopImmediatePropagation()
|
||||||
jQuery.extend( saved.shift(), jQuery.Event.prototype ),
|
jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
|
||||||
saved,
|
saved.slice( 1 ),
|
||||||
this
|
this
|
||||||
) );
|
)
|
||||||
|
} );
|
||||||
|
|
||||||
// Abort handling of the native event
|
// Abort handling of the native event
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user