trackly 0.0.1
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/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/banner.d.ts +5 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2764 -0
- package/dist/index.js.map +7 -0
- package/dist/types.d.ts +34 -0
- package/dist/utils/environment.d.ts +5 -0
- package/dist/utils/environment.test.d.ts +0 -0
- package/dist/utils/parse-props.test.d.ts +0 -0
- package/dist/utils/parse-utm-params.d.ts +1 -0
- package/dist/utils/parse-utm-params.test.d.ts +0 -0
- package/dist/utils/props-parser.d.ts +1 -0
- package/dist/utils/resolve-path.d.ts +1 -0
- package/dist/utils/resolve-path.test.d.ts +0 -0
- package/dist/utils/should-track.d.ts +2 -0
- package/dist/utils/should-track.test.d.ts +0 -0
- package/package.json +33 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2764 @@
|
|
|
1
|
+
// node_modules/.pnpm/@fingerprintjs+fingerprintjs@5.0.1/node_modules/@fingerprintjs/fingerprintjs/dist/fp.esm.js
|
|
2
|
+
var version = "5.0.1";
|
|
3
|
+
function wait(durationMs, resolveWith) {
|
|
4
|
+
return new Promise((resolve) => setTimeout(resolve, durationMs, resolveWith));
|
|
5
|
+
}
|
|
6
|
+
function releaseEventLoop() {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
const channel = new MessageChannel();
|
|
9
|
+
channel.port1.onmessage = () => resolve();
|
|
10
|
+
channel.port2.postMessage(null);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function requestIdleCallbackIfAvailable(fallbackTimeout, deadlineTimeout = Infinity) {
|
|
14
|
+
const { requestIdleCallback } = window;
|
|
15
|
+
if (requestIdleCallback) {
|
|
16
|
+
return new Promise((resolve) => requestIdleCallback.call(window, () => resolve(), { timeout: deadlineTimeout }));
|
|
17
|
+
} else {
|
|
18
|
+
return wait(Math.min(fallbackTimeout, deadlineTimeout));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function isPromise(value) {
|
|
22
|
+
return !!value && typeof value.then === "function";
|
|
23
|
+
}
|
|
24
|
+
function awaitIfAsync(action, callback) {
|
|
25
|
+
try {
|
|
26
|
+
const returnedValue = action();
|
|
27
|
+
if (isPromise(returnedValue)) {
|
|
28
|
+
returnedValue.then((result) => callback(true, result), (error) => callback(false, error));
|
|
29
|
+
} else {
|
|
30
|
+
callback(true, returnedValue);
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
callback(false, error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function mapWithBreaks(items, callback, loopReleaseInterval = 16) {
|
|
37
|
+
const results = Array(items.length);
|
|
38
|
+
let lastLoopReleaseTime = Date.now();
|
|
39
|
+
for (let i = 0; i < items.length; ++i) {
|
|
40
|
+
results[i] = callback(items[i], i);
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
if (now >= lastLoopReleaseTime + loopReleaseInterval) {
|
|
43
|
+
lastLoopReleaseTime = now;
|
|
44
|
+
await releaseEventLoop();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return results;
|
|
48
|
+
}
|
|
49
|
+
function suppressUnhandledRejectionWarning(promise) {
|
|
50
|
+
promise.then(void 0, () => void 0);
|
|
51
|
+
return promise;
|
|
52
|
+
}
|
|
53
|
+
function includes(haystack, needle) {
|
|
54
|
+
for (let i = 0, l = haystack.length; i < l; ++i) {
|
|
55
|
+
if (haystack[i] === needle) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
function excludes(haystack, needle) {
|
|
62
|
+
return !includes(haystack, needle);
|
|
63
|
+
}
|
|
64
|
+
function toInt(value) {
|
|
65
|
+
return parseInt(value);
|
|
66
|
+
}
|
|
67
|
+
function toFloat(value) {
|
|
68
|
+
return parseFloat(value);
|
|
69
|
+
}
|
|
70
|
+
function replaceNaN(value, replacement) {
|
|
71
|
+
return typeof value === "number" && isNaN(value) ? replacement : value;
|
|
72
|
+
}
|
|
73
|
+
function countTruthy(values) {
|
|
74
|
+
return values.reduce((sum, value) => sum + (value ? 1 : 0), 0);
|
|
75
|
+
}
|
|
76
|
+
function round(value, base = 1) {
|
|
77
|
+
if (Math.abs(base) >= 1) {
|
|
78
|
+
return Math.round(value / base) * base;
|
|
79
|
+
} else {
|
|
80
|
+
const counterBase = 1 / base;
|
|
81
|
+
return Math.round(value * counterBase) / counterBase;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function parseSimpleCssSelector(selector) {
|
|
85
|
+
var _a, _b;
|
|
86
|
+
const errorMessage = `Unexpected syntax '${selector}'`;
|
|
87
|
+
const tagMatch = /^\s*([a-z-]*)(.*)$/i.exec(selector);
|
|
88
|
+
const tag = tagMatch[1] || void 0;
|
|
89
|
+
const attributes = {};
|
|
90
|
+
const partsRegex = /([.:#][\w-]+|\[.+?\])/gi;
|
|
91
|
+
const addAttribute = (name, value) => {
|
|
92
|
+
attributes[name] = attributes[name] || [];
|
|
93
|
+
attributes[name].push(value);
|
|
94
|
+
};
|
|
95
|
+
for (; ; ) {
|
|
96
|
+
const match = partsRegex.exec(tagMatch[2]);
|
|
97
|
+
if (!match) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
const part = match[0];
|
|
101
|
+
switch (part[0]) {
|
|
102
|
+
case ".":
|
|
103
|
+
addAttribute("class", part.slice(1));
|
|
104
|
+
break;
|
|
105
|
+
case "#":
|
|
106
|
+
addAttribute("id", part.slice(1));
|
|
107
|
+
break;
|
|
108
|
+
case "[": {
|
|
109
|
+
const attributeMatch = /^\[([\w-]+)([~|^$*]?=("(.*?)"|([\w-]+)))?(\s+[is])?\]$/.exec(part);
|
|
110
|
+
if (attributeMatch) {
|
|
111
|
+
addAttribute(attributeMatch[1], (_b = (_a = attributeMatch[4]) !== null && _a !== void 0 ? _a : attributeMatch[5]) !== null && _b !== void 0 ? _b : "");
|
|
112
|
+
} else {
|
|
113
|
+
throw new Error(errorMessage);
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
default:
|
|
118
|
+
throw new Error(errorMessage);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return [tag, attributes];
|
|
122
|
+
}
|
|
123
|
+
function getUTF8Bytes(input) {
|
|
124
|
+
const result = new Uint8Array(input.length);
|
|
125
|
+
for (let i = 0; i < input.length; i++) {
|
|
126
|
+
const charCode = input.charCodeAt(i);
|
|
127
|
+
if (charCode > 127) {
|
|
128
|
+
return new TextEncoder().encode(input);
|
|
129
|
+
}
|
|
130
|
+
result[i] = charCode;
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
function x64Add(m, n) {
|
|
135
|
+
const m0 = m[0] >>> 16, m1 = m[0] & 65535, m2 = m[1] >>> 16, m3 = m[1] & 65535;
|
|
136
|
+
const n0 = n[0] >>> 16, n1 = n[0] & 65535, n2 = n[1] >>> 16, n3 = n[1] & 65535;
|
|
137
|
+
let o0 = 0, o1 = 0, o2 = 0, o3 = 0;
|
|
138
|
+
o3 += m3 + n3;
|
|
139
|
+
o2 += o3 >>> 16;
|
|
140
|
+
o3 &= 65535;
|
|
141
|
+
o2 += m2 + n2;
|
|
142
|
+
o1 += o2 >>> 16;
|
|
143
|
+
o2 &= 65535;
|
|
144
|
+
o1 += m1 + n1;
|
|
145
|
+
o0 += o1 >>> 16;
|
|
146
|
+
o1 &= 65535;
|
|
147
|
+
o0 += m0 + n0;
|
|
148
|
+
o0 &= 65535;
|
|
149
|
+
m[0] = o0 << 16 | o1;
|
|
150
|
+
m[1] = o2 << 16 | o3;
|
|
151
|
+
}
|
|
152
|
+
function x64Multiply(m, n) {
|
|
153
|
+
const m0 = m[0] >>> 16, m1 = m[0] & 65535, m2 = m[1] >>> 16, m3 = m[1] & 65535;
|
|
154
|
+
const n0 = n[0] >>> 16, n1 = n[0] & 65535, n2 = n[1] >>> 16, n3 = n[1] & 65535;
|
|
155
|
+
let o0 = 0, o1 = 0, o2 = 0, o3 = 0;
|
|
156
|
+
o3 += m3 * n3;
|
|
157
|
+
o2 += o3 >>> 16;
|
|
158
|
+
o3 &= 65535;
|
|
159
|
+
o2 += m2 * n3;
|
|
160
|
+
o1 += o2 >>> 16;
|
|
161
|
+
o2 &= 65535;
|
|
162
|
+
o2 += m3 * n2;
|
|
163
|
+
o1 += o2 >>> 16;
|
|
164
|
+
o2 &= 65535;
|
|
165
|
+
o1 += m1 * n3;
|
|
166
|
+
o0 += o1 >>> 16;
|
|
167
|
+
o1 &= 65535;
|
|
168
|
+
o1 += m2 * n2;
|
|
169
|
+
o0 += o1 >>> 16;
|
|
170
|
+
o1 &= 65535;
|
|
171
|
+
o1 += m3 * n1;
|
|
172
|
+
o0 += o1 >>> 16;
|
|
173
|
+
o1 &= 65535;
|
|
174
|
+
o0 += m0 * n3 + m1 * n2 + m2 * n1 + m3 * n0;
|
|
175
|
+
o0 &= 65535;
|
|
176
|
+
m[0] = o0 << 16 | o1;
|
|
177
|
+
m[1] = o2 << 16 | o3;
|
|
178
|
+
}
|
|
179
|
+
function x64Rotl(m, bits) {
|
|
180
|
+
const m0 = m[0];
|
|
181
|
+
bits %= 64;
|
|
182
|
+
if (bits === 32) {
|
|
183
|
+
m[0] = m[1];
|
|
184
|
+
m[1] = m0;
|
|
185
|
+
} else if (bits < 32) {
|
|
186
|
+
m[0] = m0 << bits | m[1] >>> 32 - bits;
|
|
187
|
+
m[1] = m[1] << bits | m0 >>> 32 - bits;
|
|
188
|
+
} else {
|
|
189
|
+
bits -= 32;
|
|
190
|
+
m[0] = m[1] << bits | m0 >>> 32 - bits;
|
|
191
|
+
m[1] = m0 << bits | m[1] >>> 32 - bits;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
function x64LeftShift(m, bits) {
|
|
195
|
+
bits %= 64;
|
|
196
|
+
if (bits === 0) {
|
|
197
|
+
return;
|
|
198
|
+
} else if (bits < 32) {
|
|
199
|
+
m[0] = m[1] >>> 32 - bits;
|
|
200
|
+
m[1] = m[1] << bits;
|
|
201
|
+
} else {
|
|
202
|
+
m[0] = m[1] << bits - 32;
|
|
203
|
+
m[1] = 0;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function x64Xor(m, n) {
|
|
207
|
+
m[0] ^= n[0];
|
|
208
|
+
m[1] ^= n[1];
|
|
209
|
+
}
|
|
210
|
+
var F1 = [4283543511, 3981806797];
|
|
211
|
+
var F2 = [3301882366, 444984403];
|
|
212
|
+
function x64Fmix(h) {
|
|
213
|
+
const shifted = [0, h[0] >>> 1];
|
|
214
|
+
x64Xor(h, shifted);
|
|
215
|
+
x64Multiply(h, F1);
|
|
216
|
+
shifted[1] = h[0] >>> 1;
|
|
217
|
+
x64Xor(h, shifted);
|
|
218
|
+
x64Multiply(h, F2);
|
|
219
|
+
shifted[1] = h[0] >>> 1;
|
|
220
|
+
x64Xor(h, shifted);
|
|
221
|
+
}
|
|
222
|
+
var C1 = [2277735313, 289559509];
|
|
223
|
+
var C2 = [1291169091, 658871167];
|
|
224
|
+
var M$1 = [0, 5];
|
|
225
|
+
var N1 = [0, 1390208809];
|
|
226
|
+
var N2 = [0, 944331445];
|
|
227
|
+
function x64hash128(input, seed) {
|
|
228
|
+
const key = getUTF8Bytes(input);
|
|
229
|
+
seed = seed || 0;
|
|
230
|
+
const length = [0, key.length];
|
|
231
|
+
const remainder = length[1] % 16;
|
|
232
|
+
const bytes = length[1] - remainder;
|
|
233
|
+
const h1 = [0, seed];
|
|
234
|
+
const h2 = [0, seed];
|
|
235
|
+
const k1 = [0, 0];
|
|
236
|
+
const k2 = [0, 0];
|
|
237
|
+
let i;
|
|
238
|
+
for (i = 0; i < bytes; i = i + 16) {
|
|
239
|
+
k1[0] = key[i + 4] | key[i + 5] << 8 | key[i + 6] << 16 | key[i + 7] << 24;
|
|
240
|
+
k1[1] = key[i] | key[i + 1] << 8 | key[i + 2] << 16 | key[i + 3] << 24;
|
|
241
|
+
k2[0] = key[i + 12] | key[i + 13] << 8 | key[i + 14] << 16 | key[i + 15] << 24;
|
|
242
|
+
k2[1] = key[i + 8] | key[i + 9] << 8 | key[i + 10] << 16 | key[i + 11] << 24;
|
|
243
|
+
x64Multiply(k1, C1);
|
|
244
|
+
x64Rotl(k1, 31);
|
|
245
|
+
x64Multiply(k1, C2);
|
|
246
|
+
x64Xor(h1, k1);
|
|
247
|
+
x64Rotl(h1, 27);
|
|
248
|
+
x64Add(h1, h2);
|
|
249
|
+
x64Multiply(h1, M$1);
|
|
250
|
+
x64Add(h1, N1);
|
|
251
|
+
x64Multiply(k2, C2);
|
|
252
|
+
x64Rotl(k2, 33);
|
|
253
|
+
x64Multiply(k2, C1);
|
|
254
|
+
x64Xor(h2, k2);
|
|
255
|
+
x64Rotl(h2, 31);
|
|
256
|
+
x64Add(h2, h1);
|
|
257
|
+
x64Multiply(h2, M$1);
|
|
258
|
+
x64Add(h2, N2);
|
|
259
|
+
}
|
|
260
|
+
k1[0] = 0;
|
|
261
|
+
k1[1] = 0;
|
|
262
|
+
k2[0] = 0;
|
|
263
|
+
k2[1] = 0;
|
|
264
|
+
const val = [0, 0];
|
|
265
|
+
switch (remainder) {
|
|
266
|
+
case 15:
|
|
267
|
+
val[1] = key[i + 14];
|
|
268
|
+
x64LeftShift(val, 48);
|
|
269
|
+
x64Xor(k2, val);
|
|
270
|
+
// fallthrough
|
|
271
|
+
case 14:
|
|
272
|
+
val[1] = key[i + 13];
|
|
273
|
+
x64LeftShift(val, 40);
|
|
274
|
+
x64Xor(k2, val);
|
|
275
|
+
// fallthrough
|
|
276
|
+
case 13:
|
|
277
|
+
val[1] = key[i + 12];
|
|
278
|
+
x64LeftShift(val, 32);
|
|
279
|
+
x64Xor(k2, val);
|
|
280
|
+
// fallthrough
|
|
281
|
+
case 12:
|
|
282
|
+
val[1] = key[i + 11];
|
|
283
|
+
x64LeftShift(val, 24);
|
|
284
|
+
x64Xor(k2, val);
|
|
285
|
+
// fallthrough
|
|
286
|
+
case 11:
|
|
287
|
+
val[1] = key[i + 10];
|
|
288
|
+
x64LeftShift(val, 16);
|
|
289
|
+
x64Xor(k2, val);
|
|
290
|
+
// fallthrough
|
|
291
|
+
case 10:
|
|
292
|
+
val[1] = key[i + 9];
|
|
293
|
+
x64LeftShift(val, 8);
|
|
294
|
+
x64Xor(k2, val);
|
|
295
|
+
// fallthrough
|
|
296
|
+
case 9:
|
|
297
|
+
val[1] = key[i + 8];
|
|
298
|
+
x64Xor(k2, val);
|
|
299
|
+
x64Multiply(k2, C2);
|
|
300
|
+
x64Rotl(k2, 33);
|
|
301
|
+
x64Multiply(k2, C1);
|
|
302
|
+
x64Xor(h2, k2);
|
|
303
|
+
// fallthrough
|
|
304
|
+
case 8:
|
|
305
|
+
val[1] = key[i + 7];
|
|
306
|
+
x64LeftShift(val, 56);
|
|
307
|
+
x64Xor(k1, val);
|
|
308
|
+
// fallthrough
|
|
309
|
+
case 7:
|
|
310
|
+
val[1] = key[i + 6];
|
|
311
|
+
x64LeftShift(val, 48);
|
|
312
|
+
x64Xor(k1, val);
|
|
313
|
+
// fallthrough
|
|
314
|
+
case 6:
|
|
315
|
+
val[1] = key[i + 5];
|
|
316
|
+
x64LeftShift(val, 40);
|
|
317
|
+
x64Xor(k1, val);
|
|
318
|
+
// fallthrough
|
|
319
|
+
case 5:
|
|
320
|
+
val[1] = key[i + 4];
|
|
321
|
+
x64LeftShift(val, 32);
|
|
322
|
+
x64Xor(k1, val);
|
|
323
|
+
// fallthrough
|
|
324
|
+
case 4:
|
|
325
|
+
val[1] = key[i + 3];
|
|
326
|
+
x64LeftShift(val, 24);
|
|
327
|
+
x64Xor(k1, val);
|
|
328
|
+
// fallthrough
|
|
329
|
+
case 3:
|
|
330
|
+
val[1] = key[i + 2];
|
|
331
|
+
x64LeftShift(val, 16);
|
|
332
|
+
x64Xor(k1, val);
|
|
333
|
+
// fallthrough
|
|
334
|
+
case 2:
|
|
335
|
+
val[1] = key[i + 1];
|
|
336
|
+
x64LeftShift(val, 8);
|
|
337
|
+
x64Xor(k1, val);
|
|
338
|
+
// fallthrough
|
|
339
|
+
case 1:
|
|
340
|
+
val[1] = key[i];
|
|
341
|
+
x64Xor(k1, val);
|
|
342
|
+
x64Multiply(k1, C1);
|
|
343
|
+
x64Rotl(k1, 31);
|
|
344
|
+
x64Multiply(k1, C2);
|
|
345
|
+
x64Xor(h1, k1);
|
|
346
|
+
}
|
|
347
|
+
x64Xor(h1, length);
|
|
348
|
+
x64Xor(h2, length);
|
|
349
|
+
x64Add(h1, h2);
|
|
350
|
+
x64Add(h2, h1);
|
|
351
|
+
x64Fmix(h1);
|
|
352
|
+
x64Fmix(h2);
|
|
353
|
+
x64Add(h1, h2);
|
|
354
|
+
x64Add(h2, h1);
|
|
355
|
+
return ("00000000" + (h1[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h1[1] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[0] >>> 0).toString(16)).slice(-8) + ("00000000" + (h2[1] >>> 0).toString(16)).slice(-8);
|
|
356
|
+
}
|
|
357
|
+
function errorToObject(error) {
|
|
358
|
+
var _a;
|
|
359
|
+
return {
|
|
360
|
+
name: error.name,
|
|
361
|
+
message: error.message,
|
|
362
|
+
stack: (_a = error.stack) === null || _a === void 0 ? void 0 : _a.split("\n"),
|
|
363
|
+
// The fields are not enumerable, so TS is wrong saying that they will be overridden
|
|
364
|
+
...error
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function isFunctionNative(func) {
|
|
368
|
+
return /^function\s.*?\{\s*\[native code]\s*}$/.test(String(func));
|
|
369
|
+
}
|
|
370
|
+
function isFinalResultLoaded(loadResult) {
|
|
371
|
+
return typeof loadResult !== "function";
|
|
372
|
+
}
|
|
373
|
+
function loadSource(source, sourceOptions) {
|
|
374
|
+
const sourceLoadPromise = suppressUnhandledRejectionWarning(new Promise((resolveLoad) => {
|
|
375
|
+
const loadStartTime = Date.now();
|
|
376
|
+
awaitIfAsync(source.bind(null, sourceOptions), (...loadArgs) => {
|
|
377
|
+
const loadDuration = Date.now() - loadStartTime;
|
|
378
|
+
if (!loadArgs[0]) {
|
|
379
|
+
return resolveLoad(() => ({ error: loadArgs[1], duration: loadDuration }));
|
|
380
|
+
}
|
|
381
|
+
const loadResult = loadArgs[1];
|
|
382
|
+
if (isFinalResultLoaded(loadResult)) {
|
|
383
|
+
return resolveLoad(() => ({ value: loadResult, duration: loadDuration }));
|
|
384
|
+
}
|
|
385
|
+
resolveLoad(() => new Promise((resolveGet) => {
|
|
386
|
+
const getStartTime = Date.now();
|
|
387
|
+
awaitIfAsync(loadResult, (...getArgs) => {
|
|
388
|
+
const duration = loadDuration + Date.now() - getStartTime;
|
|
389
|
+
if (!getArgs[0]) {
|
|
390
|
+
return resolveGet({ error: getArgs[1], duration });
|
|
391
|
+
}
|
|
392
|
+
resolveGet({ value: getArgs[1], duration });
|
|
393
|
+
});
|
|
394
|
+
}));
|
|
395
|
+
});
|
|
396
|
+
}));
|
|
397
|
+
return function getComponent() {
|
|
398
|
+
return sourceLoadPromise.then((finalizeSource) => finalizeSource());
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function loadSources(sources2, sourceOptions, excludeSources, loopReleaseInterval) {
|
|
402
|
+
const includedSources = Object.keys(sources2).filter((sourceKey) => excludes(excludeSources, sourceKey));
|
|
403
|
+
const sourceGettersPromise = suppressUnhandledRejectionWarning(mapWithBreaks(includedSources, (sourceKey) => loadSource(sources2[sourceKey], sourceOptions), loopReleaseInterval));
|
|
404
|
+
return async function getComponents() {
|
|
405
|
+
const sourceGetters = await sourceGettersPromise;
|
|
406
|
+
const componentPromises = await mapWithBreaks(sourceGetters, (sourceGetter) => suppressUnhandledRejectionWarning(sourceGetter()), loopReleaseInterval);
|
|
407
|
+
const componentArray = await Promise.all(componentPromises);
|
|
408
|
+
const components = {};
|
|
409
|
+
for (let index2 = 0; index2 < includedSources.length; ++index2) {
|
|
410
|
+
components[includedSources[index2]] = componentArray[index2];
|
|
411
|
+
}
|
|
412
|
+
return components;
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
function isTrident() {
|
|
416
|
+
const w = window;
|
|
417
|
+
const n = navigator;
|
|
418
|
+
return countTruthy([
|
|
419
|
+
"MSCSSMatrix" in w,
|
|
420
|
+
"msSetImmediate" in w,
|
|
421
|
+
"msIndexedDB" in w,
|
|
422
|
+
"msMaxTouchPoints" in n,
|
|
423
|
+
"msPointerEnabled" in n
|
|
424
|
+
]) >= 4;
|
|
425
|
+
}
|
|
426
|
+
function isEdgeHTML() {
|
|
427
|
+
const w = window;
|
|
428
|
+
const n = navigator;
|
|
429
|
+
return countTruthy(["msWriteProfilerMark" in w, "MSStream" in w, "msLaunchUri" in n, "msSaveBlob" in n]) >= 3 && !isTrident();
|
|
430
|
+
}
|
|
431
|
+
function isChromium() {
|
|
432
|
+
const w = window;
|
|
433
|
+
const n = navigator;
|
|
434
|
+
return countTruthy([
|
|
435
|
+
"webkitPersistentStorage" in n,
|
|
436
|
+
"webkitTemporaryStorage" in n,
|
|
437
|
+
(n.vendor || "").indexOf("Google") === 0,
|
|
438
|
+
"webkitResolveLocalFileSystemURL" in w,
|
|
439
|
+
"BatteryManager" in w,
|
|
440
|
+
"webkitMediaStream" in w,
|
|
441
|
+
"webkitSpeechGrammar" in w
|
|
442
|
+
]) >= 5;
|
|
443
|
+
}
|
|
444
|
+
function isWebKit() {
|
|
445
|
+
const w = window;
|
|
446
|
+
const n = navigator;
|
|
447
|
+
return countTruthy([
|
|
448
|
+
"ApplePayError" in w,
|
|
449
|
+
"CSSPrimitiveValue" in w,
|
|
450
|
+
"Counter" in w,
|
|
451
|
+
n.vendor.indexOf("Apple") === 0,
|
|
452
|
+
"RGBColor" in w,
|
|
453
|
+
"WebKitMediaKeys" in w
|
|
454
|
+
]) >= 4;
|
|
455
|
+
}
|
|
456
|
+
function isDesktopWebKit() {
|
|
457
|
+
const w = window;
|
|
458
|
+
const { HTMLElement, Document } = w;
|
|
459
|
+
return countTruthy([
|
|
460
|
+
"safari" in w,
|
|
461
|
+
!("ongestureend" in w),
|
|
462
|
+
!("TouchEvent" in w),
|
|
463
|
+
!("orientation" in w),
|
|
464
|
+
HTMLElement && !("autocapitalize" in HTMLElement.prototype),
|
|
465
|
+
Document && "pointerLockElement" in Document.prototype
|
|
466
|
+
]) >= 4;
|
|
467
|
+
}
|
|
468
|
+
function isSafariWebKit() {
|
|
469
|
+
const w = window;
|
|
470
|
+
return (
|
|
471
|
+
// Filters-out Chrome, Yandex, DuckDuckGo (macOS and iOS), Edge
|
|
472
|
+
isFunctionNative(w.print) && // Doesn't work in Safari < 15.4
|
|
473
|
+
String(w.browser) === "[object WebPageNamespace]"
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
function isGecko() {
|
|
477
|
+
var _a, _b;
|
|
478
|
+
const w = window;
|
|
479
|
+
return countTruthy([
|
|
480
|
+
"buildID" in navigator,
|
|
481
|
+
"MozAppearance" in ((_b = (_a = document.documentElement) === null || _a === void 0 ? void 0 : _a.style) !== null && _b !== void 0 ? _b : {}),
|
|
482
|
+
"onmozfullscreenchange" in w,
|
|
483
|
+
"mozInnerScreenX" in w,
|
|
484
|
+
"CSSMozDocumentRule" in w,
|
|
485
|
+
"CanvasCaptureMediaStream" in w
|
|
486
|
+
]) >= 4;
|
|
487
|
+
}
|
|
488
|
+
function isChromium86OrNewer() {
|
|
489
|
+
const w = window;
|
|
490
|
+
return countTruthy([
|
|
491
|
+
!("MediaSettingsRange" in w),
|
|
492
|
+
"RTCEncodedAudioFrame" in w,
|
|
493
|
+
"" + w.Intl === "[object Intl]",
|
|
494
|
+
"" + w.Reflect === "[object Reflect]"
|
|
495
|
+
]) >= 3;
|
|
496
|
+
}
|
|
497
|
+
function isChromium122OrNewer() {
|
|
498
|
+
const w = window;
|
|
499
|
+
const { URLPattern } = w;
|
|
500
|
+
return countTruthy([
|
|
501
|
+
"union" in Set.prototype,
|
|
502
|
+
"Iterator" in w,
|
|
503
|
+
URLPattern && "hasRegExpGroups" in URLPattern.prototype,
|
|
504
|
+
"RGB8" in WebGLRenderingContext.prototype
|
|
505
|
+
]) >= 3;
|
|
506
|
+
}
|
|
507
|
+
function isWebKit606OrNewer() {
|
|
508
|
+
const w = window;
|
|
509
|
+
return countTruthy([
|
|
510
|
+
"DOMRectList" in w,
|
|
511
|
+
"RTCPeerConnectionIceEvent" in w,
|
|
512
|
+
"SVGGeometryElement" in w,
|
|
513
|
+
"ontransitioncancel" in w
|
|
514
|
+
]) >= 3;
|
|
515
|
+
}
|
|
516
|
+
function isWebKit616OrNewer() {
|
|
517
|
+
const w = window;
|
|
518
|
+
const n = navigator;
|
|
519
|
+
const { CSS, HTMLButtonElement } = w;
|
|
520
|
+
return countTruthy([
|
|
521
|
+
!("getStorageUpdates" in n),
|
|
522
|
+
HTMLButtonElement && "popover" in HTMLButtonElement.prototype,
|
|
523
|
+
"CSSCounterStyleRule" in w,
|
|
524
|
+
CSS.supports("font-size-adjust: ex-height 0.5"),
|
|
525
|
+
CSS.supports("text-transform: full-width")
|
|
526
|
+
]) >= 4;
|
|
527
|
+
}
|
|
528
|
+
function isIPad() {
|
|
529
|
+
if (navigator.platform === "iPad") {
|
|
530
|
+
return true;
|
|
531
|
+
}
|
|
532
|
+
const s = screen;
|
|
533
|
+
const screenRatio = s.width / s.height;
|
|
534
|
+
return countTruthy([
|
|
535
|
+
// Since iOS 13. Doesn't work in Chrome on iPadOS <15, but works in desktop mode.
|
|
536
|
+
"MediaSource" in window,
|
|
537
|
+
// Since iOS 12. Doesn't work in Chrome on iPadOS.
|
|
538
|
+
!!Element.prototype.webkitRequestFullscreen,
|
|
539
|
+
// iPhone 4S that runs iOS 9 matches this, but it is not supported
|
|
540
|
+
// Doesn't work in incognito mode of Safari ≥17 with split screen because of tracking prevention
|
|
541
|
+
screenRatio > 0.65 && screenRatio < 1.53
|
|
542
|
+
]) >= 2;
|
|
543
|
+
}
|
|
544
|
+
function getFullscreenElement() {
|
|
545
|
+
const d = document;
|
|
546
|
+
return d.fullscreenElement || d.msFullscreenElement || d.mozFullScreenElement || d.webkitFullscreenElement || null;
|
|
547
|
+
}
|
|
548
|
+
function exitFullscreen() {
|
|
549
|
+
const d = document;
|
|
550
|
+
return (d.exitFullscreen || d.msExitFullscreen || d.mozCancelFullScreen || d.webkitExitFullscreen).call(d);
|
|
551
|
+
}
|
|
552
|
+
function isAndroid() {
|
|
553
|
+
const isItChromium = isChromium();
|
|
554
|
+
const isItGecko = isGecko();
|
|
555
|
+
const w = window;
|
|
556
|
+
const n = navigator;
|
|
557
|
+
const c = "connection";
|
|
558
|
+
if (isItChromium) {
|
|
559
|
+
return countTruthy([
|
|
560
|
+
!("SharedWorker" in w),
|
|
561
|
+
// `typechange` is deprecated, but it's still present on Android (tested on Chrome Mobile 117)
|
|
562
|
+
// Removal proposal https://bugs.chromium.org/p/chromium/issues/detail?id=699892
|
|
563
|
+
// Note: this expression returns true on ChromeOS, so additional detectors are required to avoid false-positives
|
|
564
|
+
n[c] && "ontypechange" in n[c],
|
|
565
|
+
!("sinkId" in new Audio())
|
|
566
|
+
]) >= 2;
|
|
567
|
+
} else if (isItGecko) {
|
|
568
|
+
return countTruthy(["onorientationchange" in w, "orientation" in w, /android/i.test(n.appVersion)]) >= 2;
|
|
569
|
+
} else {
|
|
570
|
+
return false;
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function isSamsungInternet() {
|
|
574
|
+
const n = navigator;
|
|
575
|
+
const w = window;
|
|
576
|
+
const audioPrototype = Audio.prototype;
|
|
577
|
+
const { visualViewport } = w;
|
|
578
|
+
return countTruthy([
|
|
579
|
+
"srLatency" in audioPrototype,
|
|
580
|
+
"srChannelCount" in audioPrototype,
|
|
581
|
+
"devicePosture" in n,
|
|
582
|
+
visualViewport && "segments" in visualViewport,
|
|
583
|
+
"getTextInformation" in Image.prototype
|
|
584
|
+
// Not available in Samsung Internet 21
|
|
585
|
+
]) >= 3;
|
|
586
|
+
}
|
|
587
|
+
function getAudioFingerprint() {
|
|
588
|
+
if (doesBrowserPerformAntifingerprinting$1()) {
|
|
589
|
+
return -4;
|
|
590
|
+
}
|
|
591
|
+
return getUnstableAudioFingerprint();
|
|
592
|
+
}
|
|
593
|
+
function getUnstableAudioFingerprint() {
|
|
594
|
+
const w = window;
|
|
595
|
+
const AudioContext2 = w.OfflineAudioContext || w.webkitOfflineAudioContext;
|
|
596
|
+
if (!AudioContext2) {
|
|
597
|
+
return -2;
|
|
598
|
+
}
|
|
599
|
+
if (doesBrowserSuspendAudioContext()) {
|
|
600
|
+
return -1;
|
|
601
|
+
}
|
|
602
|
+
const hashFromIndex = 4500;
|
|
603
|
+
const hashToIndex = 5e3;
|
|
604
|
+
const context = new AudioContext2(1, hashToIndex, 44100);
|
|
605
|
+
const oscillator = context.createOscillator();
|
|
606
|
+
oscillator.type = "triangle";
|
|
607
|
+
oscillator.frequency.value = 1e4;
|
|
608
|
+
const compressor = context.createDynamicsCompressor();
|
|
609
|
+
compressor.threshold.value = -50;
|
|
610
|
+
compressor.knee.value = 40;
|
|
611
|
+
compressor.ratio.value = 12;
|
|
612
|
+
compressor.attack.value = 0;
|
|
613
|
+
compressor.release.value = 0.25;
|
|
614
|
+
oscillator.connect(compressor);
|
|
615
|
+
compressor.connect(context.destination);
|
|
616
|
+
oscillator.start(0);
|
|
617
|
+
const [renderPromise, finishRendering] = startRenderingAudio(context);
|
|
618
|
+
const fingerprintPromise = suppressUnhandledRejectionWarning(renderPromise.then((buffer) => getHash(buffer.getChannelData(0).subarray(hashFromIndex)), (error) => {
|
|
619
|
+
if (error.name === "timeout" || error.name === "suspended") {
|
|
620
|
+
return -3;
|
|
621
|
+
}
|
|
622
|
+
throw error;
|
|
623
|
+
}));
|
|
624
|
+
return () => {
|
|
625
|
+
finishRendering();
|
|
626
|
+
return fingerprintPromise;
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
function doesBrowserSuspendAudioContext() {
|
|
630
|
+
return isWebKit() && !isDesktopWebKit() && !isWebKit606OrNewer();
|
|
631
|
+
}
|
|
632
|
+
function doesBrowserPerformAntifingerprinting$1() {
|
|
633
|
+
return (
|
|
634
|
+
// Safari ≥17
|
|
635
|
+
isWebKit() && isWebKit616OrNewer() && isSafariWebKit() || // Samsung Internet ≥26
|
|
636
|
+
isChromium() && isSamsungInternet() && isChromium122OrNewer()
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
function startRenderingAudio(context) {
|
|
640
|
+
const renderTryMaxCount = 3;
|
|
641
|
+
const renderRetryDelay = 500;
|
|
642
|
+
const runningMaxAwaitTime = 500;
|
|
643
|
+
const runningSufficientTime = 5e3;
|
|
644
|
+
let finalize = () => void 0;
|
|
645
|
+
const resultPromise = new Promise((resolve, reject) => {
|
|
646
|
+
let isFinalized = false;
|
|
647
|
+
let renderTryCount = 0;
|
|
648
|
+
let startedRunningAt = 0;
|
|
649
|
+
context.oncomplete = (event2) => resolve(event2.renderedBuffer);
|
|
650
|
+
const startRunningTimeout = () => {
|
|
651
|
+
setTimeout(() => reject(makeInnerError(
|
|
652
|
+
"timeout"
|
|
653
|
+
/* InnerErrorName.Timeout */
|
|
654
|
+
)), Math.min(runningMaxAwaitTime, startedRunningAt + runningSufficientTime - Date.now()));
|
|
655
|
+
};
|
|
656
|
+
const tryRender = () => {
|
|
657
|
+
try {
|
|
658
|
+
const renderingPromise = context.startRendering();
|
|
659
|
+
if (isPromise(renderingPromise)) {
|
|
660
|
+
suppressUnhandledRejectionWarning(renderingPromise);
|
|
661
|
+
}
|
|
662
|
+
switch (context.state) {
|
|
663
|
+
case "running":
|
|
664
|
+
startedRunningAt = Date.now();
|
|
665
|
+
if (isFinalized) {
|
|
666
|
+
startRunningTimeout();
|
|
667
|
+
}
|
|
668
|
+
break;
|
|
669
|
+
// Sometimes the audio context doesn't start after calling `startRendering` (in addition to the cases where
|
|
670
|
+
// audio context doesn't start at all). A known case is starting an audio context when the browser tab is in
|
|
671
|
+
// background on iPhone. Retries usually help in this case.
|
|
672
|
+
case "suspended":
|
|
673
|
+
if (!document.hidden) {
|
|
674
|
+
renderTryCount++;
|
|
675
|
+
}
|
|
676
|
+
if (isFinalized && renderTryCount >= renderTryMaxCount) {
|
|
677
|
+
reject(makeInnerError(
|
|
678
|
+
"suspended"
|
|
679
|
+
/* InnerErrorName.Suspended */
|
|
680
|
+
));
|
|
681
|
+
} else {
|
|
682
|
+
setTimeout(tryRender, renderRetryDelay);
|
|
683
|
+
}
|
|
684
|
+
break;
|
|
685
|
+
}
|
|
686
|
+
} catch (error) {
|
|
687
|
+
reject(error);
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
tryRender();
|
|
691
|
+
finalize = () => {
|
|
692
|
+
if (!isFinalized) {
|
|
693
|
+
isFinalized = true;
|
|
694
|
+
if (startedRunningAt > 0) {
|
|
695
|
+
startRunningTimeout();
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
});
|
|
700
|
+
return [resultPromise, finalize];
|
|
701
|
+
}
|
|
702
|
+
function getHash(signal) {
|
|
703
|
+
let hash = 0;
|
|
704
|
+
for (let i = 0; i < signal.length; ++i) {
|
|
705
|
+
hash += Math.abs(signal[i]);
|
|
706
|
+
}
|
|
707
|
+
return hash;
|
|
708
|
+
}
|
|
709
|
+
function makeInnerError(name) {
|
|
710
|
+
const error = new Error(name);
|
|
711
|
+
error.name = name;
|
|
712
|
+
return error;
|
|
713
|
+
}
|
|
714
|
+
async function withIframe(action, initialHtml, domPollInterval = 50) {
|
|
715
|
+
var _a, _b, _c;
|
|
716
|
+
const d = document;
|
|
717
|
+
while (!d.body) {
|
|
718
|
+
await wait(domPollInterval);
|
|
719
|
+
}
|
|
720
|
+
const iframe = d.createElement("iframe");
|
|
721
|
+
try {
|
|
722
|
+
await new Promise((_resolve, _reject) => {
|
|
723
|
+
let isComplete = false;
|
|
724
|
+
const resolve = () => {
|
|
725
|
+
isComplete = true;
|
|
726
|
+
_resolve();
|
|
727
|
+
};
|
|
728
|
+
const reject = (error) => {
|
|
729
|
+
isComplete = true;
|
|
730
|
+
_reject(error);
|
|
731
|
+
};
|
|
732
|
+
iframe.onload = resolve;
|
|
733
|
+
iframe.onerror = reject;
|
|
734
|
+
const { style } = iframe;
|
|
735
|
+
style.setProperty("display", "block", "important");
|
|
736
|
+
style.position = "absolute";
|
|
737
|
+
style.top = "0";
|
|
738
|
+
style.left = "0";
|
|
739
|
+
style.visibility = "hidden";
|
|
740
|
+
if (initialHtml && "srcdoc" in iframe) {
|
|
741
|
+
iframe.srcdoc = initialHtml;
|
|
742
|
+
} else {
|
|
743
|
+
iframe.src = "about:blank";
|
|
744
|
+
}
|
|
745
|
+
d.body.appendChild(iframe);
|
|
746
|
+
const checkReadyState = () => {
|
|
747
|
+
var _a2, _b2;
|
|
748
|
+
if (isComplete) {
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (((_b2 = (_a2 = iframe.contentWindow) === null || _a2 === void 0 ? void 0 : _a2.document) === null || _b2 === void 0 ? void 0 : _b2.readyState) === "complete") {
|
|
752
|
+
resolve();
|
|
753
|
+
} else {
|
|
754
|
+
setTimeout(checkReadyState, 10);
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
checkReadyState();
|
|
758
|
+
});
|
|
759
|
+
while (!((_b = (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document) === null || _b === void 0 ? void 0 : _b.body)) {
|
|
760
|
+
await wait(domPollInterval);
|
|
761
|
+
}
|
|
762
|
+
return await action(iframe, iframe.contentWindow);
|
|
763
|
+
} finally {
|
|
764
|
+
(_c = iframe.parentNode) === null || _c === void 0 ? void 0 : _c.removeChild(iframe);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
function selectorToElement(selector) {
|
|
768
|
+
const [tag, attributes] = parseSimpleCssSelector(selector);
|
|
769
|
+
const element = document.createElement(tag !== null && tag !== void 0 ? tag : "div");
|
|
770
|
+
for (const name of Object.keys(attributes)) {
|
|
771
|
+
const value = attributes[name].join(" ");
|
|
772
|
+
if (name === "style") {
|
|
773
|
+
addStyleString(element.style, value);
|
|
774
|
+
} else {
|
|
775
|
+
element.setAttribute(name, value);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return element;
|
|
779
|
+
}
|
|
780
|
+
function addStyleString(style, source) {
|
|
781
|
+
for (const property of source.split(";")) {
|
|
782
|
+
const match = /^\s*([\w-]+)\s*:\s*(.+?)(\s*!([\w-]+))?\s*$/.exec(property);
|
|
783
|
+
if (match) {
|
|
784
|
+
const [, name, value, , priority] = match;
|
|
785
|
+
style.setProperty(name, value, priority || "");
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
function isAnyParentCrossOrigin() {
|
|
790
|
+
let currentWindow = window;
|
|
791
|
+
for (; ; ) {
|
|
792
|
+
const parentWindow = currentWindow.parent;
|
|
793
|
+
if (!parentWindow || parentWindow === currentWindow) {
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
try {
|
|
797
|
+
if (parentWindow.location.origin !== currentWindow.location.origin) {
|
|
798
|
+
return true;
|
|
799
|
+
}
|
|
800
|
+
} catch (error) {
|
|
801
|
+
if (error instanceof Error && error.name === "SecurityError") {
|
|
802
|
+
return true;
|
|
803
|
+
}
|
|
804
|
+
throw error;
|
|
805
|
+
}
|
|
806
|
+
currentWindow = parentWindow;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
var testString = "mmMwWLliI0O&1";
|
|
810
|
+
var textSize = "48px";
|
|
811
|
+
var baseFonts = ["monospace", "sans-serif", "serif"];
|
|
812
|
+
var fontList = [
|
|
813
|
+
// This is android-specific font from "Roboto" family
|
|
814
|
+
"sans-serif-thin",
|
|
815
|
+
"ARNO PRO",
|
|
816
|
+
"Agency FB",
|
|
817
|
+
"Arabic Typesetting",
|
|
818
|
+
"Arial Unicode MS",
|
|
819
|
+
"AvantGarde Bk BT",
|
|
820
|
+
"BankGothic Md BT",
|
|
821
|
+
"Batang",
|
|
822
|
+
"Bitstream Vera Sans Mono",
|
|
823
|
+
"Calibri",
|
|
824
|
+
"Century",
|
|
825
|
+
"Century Gothic",
|
|
826
|
+
"Clarendon",
|
|
827
|
+
"EUROSTILE",
|
|
828
|
+
"Franklin Gothic",
|
|
829
|
+
"Futura Bk BT",
|
|
830
|
+
"Futura Md BT",
|
|
831
|
+
"GOTHAM",
|
|
832
|
+
"Gill Sans",
|
|
833
|
+
"HELV",
|
|
834
|
+
"Haettenschweiler",
|
|
835
|
+
"Helvetica Neue",
|
|
836
|
+
"Humanst521 BT",
|
|
837
|
+
"Leelawadee",
|
|
838
|
+
"Letter Gothic",
|
|
839
|
+
"Levenim MT",
|
|
840
|
+
"Lucida Bright",
|
|
841
|
+
"Lucida Sans",
|
|
842
|
+
"Menlo",
|
|
843
|
+
"MS Mincho",
|
|
844
|
+
"MS Outlook",
|
|
845
|
+
"MS Reference Specialty",
|
|
846
|
+
"MS UI Gothic",
|
|
847
|
+
"MT Extra",
|
|
848
|
+
"MYRIAD PRO",
|
|
849
|
+
"Marlett",
|
|
850
|
+
"Meiryo UI",
|
|
851
|
+
"Microsoft Uighur",
|
|
852
|
+
"Minion Pro",
|
|
853
|
+
"Monotype Corsiva",
|
|
854
|
+
"PMingLiU",
|
|
855
|
+
"Pristina",
|
|
856
|
+
"SCRIPTINA",
|
|
857
|
+
"Segoe UI Light",
|
|
858
|
+
"Serifa",
|
|
859
|
+
"SimHei",
|
|
860
|
+
"Small Fonts",
|
|
861
|
+
"Staccato222 BT",
|
|
862
|
+
"TRAJAN PRO",
|
|
863
|
+
"Univers CE 55 Medium",
|
|
864
|
+
"Vrinda",
|
|
865
|
+
"ZWAdobeF"
|
|
866
|
+
];
|
|
867
|
+
function getFonts() {
|
|
868
|
+
return withIframe(async (_, { document: document2 }) => {
|
|
869
|
+
const holder = document2.body;
|
|
870
|
+
holder.style.fontSize = textSize;
|
|
871
|
+
const spansContainer = document2.createElement("div");
|
|
872
|
+
spansContainer.style.setProperty("visibility", "hidden", "important");
|
|
873
|
+
const defaultWidth = {};
|
|
874
|
+
const defaultHeight = {};
|
|
875
|
+
const createSpan = (fontFamily) => {
|
|
876
|
+
const span = document2.createElement("span");
|
|
877
|
+
const { style } = span;
|
|
878
|
+
style.position = "absolute";
|
|
879
|
+
style.top = "0";
|
|
880
|
+
style.left = "0";
|
|
881
|
+
style.fontFamily = fontFamily;
|
|
882
|
+
span.textContent = testString;
|
|
883
|
+
spansContainer.appendChild(span);
|
|
884
|
+
return span;
|
|
885
|
+
};
|
|
886
|
+
const createSpanWithFonts = (fontToDetect, baseFont) => {
|
|
887
|
+
return createSpan(`'${fontToDetect}',${baseFont}`);
|
|
888
|
+
};
|
|
889
|
+
const initializeBaseFontsSpans = () => {
|
|
890
|
+
return baseFonts.map(createSpan);
|
|
891
|
+
};
|
|
892
|
+
const initializeFontsSpans = () => {
|
|
893
|
+
const spans = {};
|
|
894
|
+
for (const font of fontList) {
|
|
895
|
+
spans[font] = baseFonts.map((baseFont) => createSpanWithFonts(font, baseFont));
|
|
896
|
+
}
|
|
897
|
+
return spans;
|
|
898
|
+
};
|
|
899
|
+
const isFontAvailable = (fontSpans) => {
|
|
900
|
+
return baseFonts.some((baseFont, baseFontIndex) => fontSpans[baseFontIndex].offsetWidth !== defaultWidth[baseFont] || fontSpans[baseFontIndex].offsetHeight !== defaultHeight[baseFont]);
|
|
901
|
+
};
|
|
902
|
+
const baseFontsSpans = initializeBaseFontsSpans();
|
|
903
|
+
const fontsSpans = initializeFontsSpans();
|
|
904
|
+
holder.appendChild(spansContainer);
|
|
905
|
+
for (let index2 = 0; index2 < baseFonts.length; index2++) {
|
|
906
|
+
defaultWidth[baseFonts[index2]] = baseFontsSpans[index2].offsetWidth;
|
|
907
|
+
defaultHeight[baseFonts[index2]] = baseFontsSpans[index2].offsetHeight;
|
|
908
|
+
}
|
|
909
|
+
return fontList.filter((font) => isFontAvailable(fontsSpans[font]));
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
function getPlugins() {
|
|
913
|
+
const rawPlugins = navigator.plugins;
|
|
914
|
+
if (!rawPlugins) {
|
|
915
|
+
return void 0;
|
|
916
|
+
}
|
|
917
|
+
const plugins = [];
|
|
918
|
+
for (let i = 0; i < rawPlugins.length; ++i) {
|
|
919
|
+
const plugin = rawPlugins[i];
|
|
920
|
+
if (!plugin) {
|
|
921
|
+
continue;
|
|
922
|
+
}
|
|
923
|
+
const mimeTypes = [];
|
|
924
|
+
for (let j = 0; j < plugin.length; ++j) {
|
|
925
|
+
const mimeType = plugin[j];
|
|
926
|
+
mimeTypes.push({
|
|
927
|
+
type: mimeType.type,
|
|
928
|
+
suffixes: mimeType.suffixes
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
plugins.push({
|
|
932
|
+
name: plugin.name,
|
|
933
|
+
description: plugin.description,
|
|
934
|
+
mimeTypes
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
return plugins;
|
|
938
|
+
}
|
|
939
|
+
function getCanvasFingerprint() {
|
|
940
|
+
return getUnstableCanvasFingerprint(doesBrowserPerformAntifingerprinting());
|
|
941
|
+
}
|
|
942
|
+
function getUnstableCanvasFingerprint(skipImages) {
|
|
943
|
+
let winding = false;
|
|
944
|
+
let geometry;
|
|
945
|
+
let text;
|
|
946
|
+
const [canvas, context] = makeCanvasContext();
|
|
947
|
+
if (!isSupported(canvas, context)) {
|
|
948
|
+
geometry = text = "unsupported";
|
|
949
|
+
} else {
|
|
950
|
+
winding = doesSupportWinding(context);
|
|
951
|
+
if (skipImages) {
|
|
952
|
+
geometry = text = "skipped";
|
|
953
|
+
} else {
|
|
954
|
+
[geometry, text] = renderImages(canvas, context);
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
return { winding, geometry, text };
|
|
958
|
+
}
|
|
959
|
+
function makeCanvasContext() {
|
|
960
|
+
const canvas = document.createElement("canvas");
|
|
961
|
+
canvas.width = 1;
|
|
962
|
+
canvas.height = 1;
|
|
963
|
+
return [canvas, canvas.getContext("2d")];
|
|
964
|
+
}
|
|
965
|
+
function isSupported(canvas, context) {
|
|
966
|
+
return !!(context && canvas.toDataURL);
|
|
967
|
+
}
|
|
968
|
+
function doesSupportWinding(context) {
|
|
969
|
+
context.rect(0, 0, 10, 10);
|
|
970
|
+
context.rect(2, 2, 6, 6);
|
|
971
|
+
return !context.isPointInPath(5, 5, "evenodd");
|
|
972
|
+
}
|
|
973
|
+
function renderImages(canvas, context) {
|
|
974
|
+
renderTextImage(canvas, context);
|
|
975
|
+
const textImage1 = canvasToString(canvas);
|
|
976
|
+
const textImage2 = canvasToString(canvas);
|
|
977
|
+
if (textImage1 !== textImage2) {
|
|
978
|
+
return [
|
|
979
|
+
"unstable",
|
|
980
|
+
"unstable"
|
|
981
|
+
/* ImageStatus.Unstable */
|
|
982
|
+
];
|
|
983
|
+
}
|
|
984
|
+
renderGeometryImage(canvas, context);
|
|
985
|
+
const geometryImage = canvasToString(canvas);
|
|
986
|
+
return [geometryImage, textImage1];
|
|
987
|
+
}
|
|
988
|
+
function renderTextImage(canvas, context) {
|
|
989
|
+
canvas.width = 240;
|
|
990
|
+
canvas.height = 60;
|
|
991
|
+
context.textBaseline = "alphabetic";
|
|
992
|
+
context.fillStyle = "#f60";
|
|
993
|
+
context.fillRect(100, 1, 62, 20);
|
|
994
|
+
context.fillStyle = "#069";
|
|
995
|
+
context.font = '11pt "Times New Roman"';
|
|
996
|
+
const printedText = `Cwm fjordbank gly ${String.fromCharCode(55357, 56835)}`;
|
|
997
|
+
context.fillText(printedText, 2, 15);
|
|
998
|
+
context.fillStyle = "rgba(102, 204, 0, 0.2)";
|
|
999
|
+
context.font = "18pt Arial";
|
|
1000
|
+
context.fillText(printedText, 4, 45);
|
|
1001
|
+
}
|
|
1002
|
+
function renderGeometryImage(canvas, context) {
|
|
1003
|
+
canvas.width = 122;
|
|
1004
|
+
canvas.height = 110;
|
|
1005
|
+
context.globalCompositeOperation = "multiply";
|
|
1006
|
+
for (const [color, x, y] of [
|
|
1007
|
+
["#f2f", 40, 40],
|
|
1008
|
+
["#2ff", 80, 40],
|
|
1009
|
+
["#ff2", 60, 80]
|
|
1010
|
+
]) {
|
|
1011
|
+
context.fillStyle = color;
|
|
1012
|
+
context.beginPath();
|
|
1013
|
+
context.arc(x, y, 40, 0, Math.PI * 2, true);
|
|
1014
|
+
context.closePath();
|
|
1015
|
+
context.fill();
|
|
1016
|
+
}
|
|
1017
|
+
context.fillStyle = "#f9c";
|
|
1018
|
+
context.arc(60, 60, 60, 0, Math.PI * 2, true);
|
|
1019
|
+
context.arc(60, 60, 20, 0, Math.PI * 2, true);
|
|
1020
|
+
context.fill("evenodd");
|
|
1021
|
+
}
|
|
1022
|
+
function canvasToString(canvas) {
|
|
1023
|
+
return canvas.toDataURL();
|
|
1024
|
+
}
|
|
1025
|
+
function doesBrowserPerformAntifingerprinting() {
|
|
1026
|
+
return isWebKit() && isWebKit616OrNewer() && isSafariWebKit();
|
|
1027
|
+
}
|
|
1028
|
+
function getTouchSupport() {
|
|
1029
|
+
const n = navigator;
|
|
1030
|
+
let maxTouchPoints = 0;
|
|
1031
|
+
let touchEvent;
|
|
1032
|
+
if (n.maxTouchPoints !== void 0) {
|
|
1033
|
+
maxTouchPoints = toInt(n.maxTouchPoints);
|
|
1034
|
+
} else if (n.msMaxTouchPoints !== void 0) {
|
|
1035
|
+
maxTouchPoints = n.msMaxTouchPoints;
|
|
1036
|
+
}
|
|
1037
|
+
try {
|
|
1038
|
+
document.createEvent("TouchEvent");
|
|
1039
|
+
touchEvent = true;
|
|
1040
|
+
} catch (_a) {
|
|
1041
|
+
touchEvent = false;
|
|
1042
|
+
}
|
|
1043
|
+
const touchStart = "ontouchstart" in window;
|
|
1044
|
+
return {
|
|
1045
|
+
maxTouchPoints,
|
|
1046
|
+
touchEvent,
|
|
1047
|
+
touchStart
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
function getOsCpu() {
|
|
1051
|
+
return navigator.oscpu;
|
|
1052
|
+
}
|
|
1053
|
+
function getLanguages() {
|
|
1054
|
+
const n = navigator;
|
|
1055
|
+
const result = [];
|
|
1056
|
+
const language = n.language || n.userLanguage || n.browserLanguage || n.systemLanguage;
|
|
1057
|
+
if (language !== void 0) {
|
|
1058
|
+
result.push([language]);
|
|
1059
|
+
}
|
|
1060
|
+
if (Array.isArray(n.languages)) {
|
|
1061
|
+
if (!(isChromium() && isChromium86OrNewer())) {
|
|
1062
|
+
result.push(n.languages);
|
|
1063
|
+
}
|
|
1064
|
+
} else if (typeof n.languages === "string") {
|
|
1065
|
+
const languages = n.languages;
|
|
1066
|
+
if (languages) {
|
|
1067
|
+
result.push(languages.split(","));
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
return result;
|
|
1071
|
+
}
|
|
1072
|
+
function getColorDepth() {
|
|
1073
|
+
return window.screen.colorDepth;
|
|
1074
|
+
}
|
|
1075
|
+
function getDeviceMemory() {
|
|
1076
|
+
return replaceNaN(toFloat(navigator.deviceMemory), void 0);
|
|
1077
|
+
}
|
|
1078
|
+
function getScreenResolution() {
|
|
1079
|
+
if (isWebKit() && isWebKit616OrNewer() && isSafariWebKit()) {
|
|
1080
|
+
return void 0;
|
|
1081
|
+
}
|
|
1082
|
+
return getUnstableScreenResolution();
|
|
1083
|
+
}
|
|
1084
|
+
function getUnstableScreenResolution() {
|
|
1085
|
+
const s = screen;
|
|
1086
|
+
const parseDimension = (value) => replaceNaN(toInt(value), null);
|
|
1087
|
+
const dimensions = [parseDimension(s.width), parseDimension(s.height)];
|
|
1088
|
+
dimensions.sort().reverse();
|
|
1089
|
+
return dimensions;
|
|
1090
|
+
}
|
|
1091
|
+
var screenFrameCheckInterval = 2500;
|
|
1092
|
+
var roundingPrecision = 10;
|
|
1093
|
+
var screenFrameBackup;
|
|
1094
|
+
var screenFrameSizeTimeoutId;
|
|
1095
|
+
function watchScreenFrame() {
|
|
1096
|
+
if (screenFrameSizeTimeoutId !== void 0) {
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
const checkScreenFrame = () => {
|
|
1100
|
+
const frameSize = getCurrentScreenFrame();
|
|
1101
|
+
if (isFrameSizeNull(frameSize)) {
|
|
1102
|
+
screenFrameSizeTimeoutId = setTimeout(checkScreenFrame, screenFrameCheckInterval);
|
|
1103
|
+
} else {
|
|
1104
|
+
screenFrameBackup = frameSize;
|
|
1105
|
+
screenFrameSizeTimeoutId = void 0;
|
|
1106
|
+
}
|
|
1107
|
+
};
|
|
1108
|
+
checkScreenFrame();
|
|
1109
|
+
}
|
|
1110
|
+
function getUnstableScreenFrame() {
|
|
1111
|
+
watchScreenFrame();
|
|
1112
|
+
return async () => {
|
|
1113
|
+
let frameSize = getCurrentScreenFrame();
|
|
1114
|
+
if (isFrameSizeNull(frameSize)) {
|
|
1115
|
+
if (screenFrameBackup) {
|
|
1116
|
+
return [...screenFrameBackup];
|
|
1117
|
+
}
|
|
1118
|
+
if (getFullscreenElement()) {
|
|
1119
|
+
await exitFullscreen();
|
|
1120
|
+
frameSize = getCurrentScreenFrame();
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
if (!isFrameSizeNull(frameSize)) {
|
|
1124
|
+
screenFrameBackup = frameSize;
|
|
1125
|
+
}
|
|
1126
|
+
return frameSize;
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
function getScreenFrame() {
|
|
1130
|
+
if (isWebKit() && isWebKit616OrNewer() && isSafariWebKit()) {
|
|
1131
|
+
return () => Promise.resolve(void 0);
|
|
1132
|
+
}
|
|
1133
|
+
const screenFrameGetter = getUnstableScreenFrame();
|
|
1134
|
+
return async () => {
|
|
1135
|
+
const frameSize = await screenFrameGetter();
|
|
1136
|
+
const processSize = (sideSize) => sideSize === null ? null : round(sideSize, roundingPrecision);
|
|
1137
|
+
return [processSize(frameSize[0]), processSize(frameSize[1]), processSize(frameSize[2]), processSize(frameSize[3])];
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
function getCurrentScreenFrame() {
|
|
1141
|
+
const s = screen;
|
|
1142
|
+
return [
|
|
1143
|
+
replaceNaN(toFloat(s.availTop), null),
|
|
1144
|
+
replaceNaN(toFloat(s.width) - toFloat(s.availWidth) - replaceNaN(toFloat(s.availLeft), 0), null),
|
|
1145
|
+
replaceNaN(toFloat(s.height) - toFloat(s.availHeight) - replaceNaN(toFloat(s.availTop), 0), null),
|
|
1146
|
+
replaceNaN(toFloat(s.availLeft), null)
|
|
1147
|
+
];
|
|
1148
|
+
}
|
|
1149
|
+
function isFrameSizeNull(frameSize) {
|
|
1150
|
+
for (let i = 0; i < 4; ++i) {
|
|
1151
|
+
if (frameSize[i]) {
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
return true;
|
|
1156
|
+
}
|
|
1157
|
+
function getHardwareConcurrency() {
|
|
1158
|
+
return replaceNaN(toInt(navigator.hardwareConcurrency), void 0);
|
|
1159
|
+
}
|
|
1160
|
+
function getTimezone() {
|
|
1161
|
+
var _a;
|
|
1162
|
+
const DateTimeFormat = (_a = window.Intl) === null || _a === void 0 ? void 0 : _a.DateTimeFormat;
|
|
1163
|
+
if (DateTimeFormat) {
|
|
1164
|
+
const timezone = new DateTimeFormat().resolvedOptions().timeZone;
|
|
1165
|
+
if (timezone) {
|
|
1166
|
+
return timezone;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
const offset = -getTimezoneOffset();
|
|
1170
|
+
return `UTC${offset >= 0 ? "+" : ""}${offset}`;
|
|
1171
|
+
}
|
|
1172
|
+
function getTimezoneOffset() {
|
|
1173
|
+
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
1174
|
+
return Math.max(
|
|
1175
|
+
// `getTimezoneOffset` returns a number as a string in some unidentified cases
|
|
1176
|
+
toFloat(new Date(currentYear, 0, 1).getTimezoneOffset()),
|
|
1177
|
+
toFloat(new Date(currentYear, 6, 1).getTimezoneOffset())
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
function getSessionStorage() {
|
|
1181
|
+
try {
|
|
1182
|
+
return !!window.sessionStorage;
|
|
1183
|
+
} catch (error) {
|
|
1184
|
+
return true;
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
function getLocalStorage() {
|
|
1188
|
+
try {
|
|
1189
|
+
return !!window.localStorage;
|
|
1190
|
+
} catch (e) {
|
|
1191
|
+
return true;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
function getIndexedDB() {
|
|
1195
|
+
if (isTrident() || isEdgeHTML()) {
|
|
1196
|
+
return void 0;
|
|
1197
|
+
}
|
|
1198
|
+
try {
|
|
1199
|
+
return !!window.indexedDB;
|
|
1200
|
+
} catch (e) {
|
|
1201
|
+
return true;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
function getOpenDatabase() {
|
|
1205
|
+
return !!window.openDatabase;
|
|
1206
|
+
}
|
|
1207
|
+
function getCpuClass() {
|
|
1208
|
+
return navigator.cpuClass;
|
|
1209
|
+
}
|
|
1210
|
+
function getPlatform() {
|
|
1211
|
+
const { platform } = navigator;
|
|
1212
|
+
if (platform === "MacIntel") {
|
|
1213
|
+
if (isWebKit() && !isDesktopWebKit()) {
|
|
1214
|
+
return isIPad() ? "iPad" : "iPhone";
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
return platform;
|
|
1218
|
+
}
|
|
1219
|
+
function getVendor() {
|
|
1220
|
+
return navigator.vendor || "";
|
|
1221
|
+
}
|
|
1222
|
+
function getVendorFlavors() {
|
|
1223
|
+
const flavors = [];
|
|
1224
|
+
for (const key of [
|
|
1225
|
+
// Blink and some browsers on iOS
|
|
1226
|
+
"chrome",
|
|
1227
|
+
// Safari on macOS
|
|
1228
|
+
"safari",
|
|
1229
|
+
// Chrome on iOS (checked in 85 on 13 and 87 on 14)
|
|
1230
|
+
"__crWeb",
|
|
1231
|
+
"__gCrWeb",
|
|
1232
|
+
// Yandex Browser on iOS, macOS and Android (checked in 21.2 on iOS 14, macOS and Android)
|
|
1233
|
+
"yandex",
|
|
1234
|
+
// Yandex Browser on iOS (checked in 21.2 on 14)
|
|
1235
|
+
"__yb",
|
|
1236
|
+
"__ybro",
|
|
1237
|
+
// Firefox on iOS (checked in 32 on 14)
|
|
1238
|
+
"__firefox__",
|
|
1239
|
+
// Edge on iOS (checked in 46 on 14)
|
|
1240
|
+
"__edgeTrackingPreventionStatistics",
|
|
1241
|
+
"webkit",
|
|
1242
|
+
// Opera Touch on iOS (checked in 2.6 on 14)
|
|
1243
|
+
"oprt",
|
|
1244
|
+
// Samsung Internet on Android (checked in 11.1)
|
|
1245
|
+
"samsungAr",
|
|
1246
|
+
// UC Browser on Android (checked in 12.10 and 13.0)
|
|
1247
|
+
"ucweb",
|
|
1248
|
+
"UCShellJava",
|
|
1249
|
+
// Puffin on Android (checked in 9.0)
|
|
1250
|
+
"puffinDevice"
|
|
1251
|
+
// UC on iOS and Opera on Android have no specific global variables
|
|
1252
|
+
// Edge for Android isn't checked
|
|
1253
|
+
]) {
|
|
1254
|
+
const value = window[key];
|
|
1255
|
+
if (value && typeof value === "object") {
|
|
1256
|
+
flavors.push(key);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
return flavors.sort();
|
|
1260
|
+
}
|
|
1261
|
+
function areCookiesEnabled() {
|
|
1262
|
+
const d = document;
|
|
1263
|
+
try {
|
|
1264
|
+
d.cookie = "cookietest=1; SameSite=Strict;";
|
|
1265
|
+
const result = d.cookie.indexOf("cookietest=") !== -1;
|
|
1266
|
+
d.cookie = "cookietest=1; SameSite=Strict; expires=Thu, 01-Jan-1970 00:00:01 GMT";
|
|
1267
|
+
return result;
|
|
1268
|
+
} catch (e) {
|
|
1269
|
+
return false;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
function getFilters() {
|
|
1273
|
+
const fromB64 = atob;
|
|
1274
|
+
return {
|
|
1275
|
+
abpIndo: [
|
|
1276
|
+
"#Iklan-Melayang",
|
|
1277
|
+
"#Kolom-Iklan-728",
|
|
1278
|
+
"#SidebarIklan-wrapper",
|
|
1279
|
+
'[title="ALIENBOLA" i]',
|
|
1280
|
+
fromB64("I0JveC1CYW5uZXItYWRz")
|
|
1281
|
+
],
|
|
1282
|
+
abpvn: [".quangcao", "#mobileCatfish", fromB64("LmNsb3NlLWFkcw=="), '[id^="bn_bottom_fixed_"]', "#pmadv"],
|
|
1283
|
+
adBlockFinland: [
|
|
1284
|
+
".mainostila",
|
|
1285
|
+
fromB64("LnNwb25zb3JpdA=="),
|
|
1286
|
+
".ylamainos",
|
|
1287
|
+
fromB64("YVtocmVmKj0iL2NsaWNrdGhyZ2guYXNwPyJd"),
|
|
1288
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hcHAucmVhZHBlYWsuY29tL2FkcyJd")
|
|
1289
|
+
],
|
|
1290
|
+
adBlockPersian: [
|
|
1291
|
+
"#navbar_notice_50",
|
|
1292
|
+
".kadr",
|
|
1293
|
+
'TABLE[width="140px"]',
|
|
1294
|
+
"#divAgahi",
|
|
1295
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2cxLnYuZndtcm0ubmV0L2FkLyJd")
|
|
1296
|
+
],
|
|
1297
|
+
adBlockWarningRemoval: [
|
|
1298
|
+
"#adblock-honeypot",
|
|
1299
|
+
".adblocker-root",
|
|
1300
|
+
".wp_adblock_detect",
|
|
1301
|
+
fromB64("LmhlYWRlci1ibG9ja2VkLWFk"),
|
|
1302
|
+
fromB64("I2FkX2Jsb2NrZXI=")
|
|
1303
|
+
],
|
|
1304
|
+
adGuardAnnoyances: [
|
|
1305
|
+
".hs-sosyal",
|
|
1306
|
+
"#cookieconsentdiv",
|
|
1307
|
+
'div[class^="app_gdpr"]',
|
|
1308
|
+
".as-oil",
|
|
1309
|
+
'[data-cypress="soft-push-notification-modal"]'
|
|
1310
|
+
],
|
|
1311
|
+
adGuardBase: [
|
|
1312
|
+
".BetterJsPopOverlay",
|
|
1313
|
+
fromB64("I2FkXzMwMFgyNTA="),
|
|
1314
|
+
fromB64("I2Jhbm5lcmZsb2F0MjI="),
|
|
1315
|
+
fromB64("I2NhbXBhaWduLWJhbm5lcg=="),
|
|
1316
|
+
fromB64("I0FkLUNvbnRlbnQ=")
|
|
1317
|
+
],
|
|
1318
|
+
adGuardChinese: [
|
|
1319
|
+
fromB64("LlppX2FkX2FfSA=="),
|
|
1320
|
+
fromB64("YVtocmVmKj0iLmh0aGJldDM0LmNvbSJd"),
|
|
1321
|
+
"#widget-quan",
|
|
1322
|
+
fromB64("YVtocmVmKj0iLzg0OTkyMDIwLnh5eiJd"),
|
|
1323
|
+
fromB64("YVtocmVmKj0iLjE5NTZobC5jb20vIl0=")
|
|
1324
|
+
],
|
|
1325
|
+
adGuardFrench: [
|
|
1326
|
+
"#pavePub",
|
|
1327
|
+
fromB64("LmFkLWRlc2t0b3AtcmVjdGFuZ2xl"),
|
|
1328
|
+
".mobile_adhesion",
|
|
1329
|
+
".widgetadv",
|
|
1330
|
+
fromB64("LmFkc19iYW4=")
|
|
1331
|
+
],
|
|
1332
|
+
adGuardGerman: ['aside[data-portal-id="leaderboard"]'],
|
|
1333
|
+
adGuardJapanese: [
|
|
1334
|
+
"#kauli_yad_1",
|
|
1335
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2FkMi50cmFmZmljZ2F0ZS5uZXQvIl0="),
|
|
1336
|
+
fromB64("Ll9wb3BJbl9pbmZpbml0ZV9hZA=="),
|
|
1337
|
+
fromB64("LmFkZ29vZ2xl"),
|
|
1338
|
+
fromB64("Ll9faXNib29zdFJldHVybkFk")
|
|
1339
|
+
],
|
|
1340
|
+
adGuardMobile: [
|
|
1341
|
+
fromB64("YW1wLWF1dG8tYWRz"),
|
|
1342
|
+
fromB64("LmFtcF9hZA=="),
|
|
1343
|
+
'amp-embed[type="24smi"]',
|
|
1344
|
+
"#mgid_iframe1",
|
|
1345
|
+
fromB64("I2FkX2ludmlld19hcmVh")
|
|
1346
|
+
],
|
|
1347
|
+
adGuardRussian: [
|
|
1348
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hZC5sZXRtZWFkcy5jb20vIl0="),
|
|
1349
|
+
fromB64("LnJlY2xhbWE="),
|
|
1350
|
+
'div[id^="smi2adblock"]',
|
|
1351
|
+
fromB64("ZGl2W2lkXj0iQWRGb3hfYmFubmVyXyJd"),
|
|
1352
|
+
"#psyduckpockeball"
|
|
1353
|
+
],
|
|
1354
|
+
adGuardSocial: [
|
|
1355
|
+
fromB64("YVtocmVmXj0iLy93d3cuc3R1bWJsZXVwb24uY29tL3N1Ym1pdD91cmw9Il0="),
|
|
1356
|
+
fromB64("YVtocmVmXj0iLy90ZWxlZ3JhbS5tZS9zaGFyZS91cmw/Il0="),
|
|
1357
|
+
".etsy-tweet",
|
|
1358
|
+
"#inlineShare",
|
|
1359
|
+
".popup-social"
|
|
1360
|
+
],
|
|
1361
|
+
adGuardSpanishPortuguese: ["#barraPublicidade", "#Publicidade", "#publiEspecial", "#queTooltip", ".cnt-publi"],
|
|
1362
|
+
adGuardTrackingProtection: [
|
|
1363
|
+
"#qoo-counter",
|
|
1364
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2NsaWNrLmhvdGxvZy5ydS8iXQ=="),
|
|
1365
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2hpdGNvdW50ZXIucnUvdG9wL3N0YXQucGhwIl0="),
|
|
1366
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3RvcC5tYWlsLnJ1L2p1bXAiXQ=="),
|
|
1367
|
+
"#top100counter"
|
|
1368
|
+
],
|
|
1369
|
+
adGuardTurkish: [
|
|
1370
|
+
"#backkapat",
|
|
1371
|
+
fromB64("I3Jla2xhbWk="),
|
|
1372
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2Fkc2Vydi5vbnRlay5jb20udHIvIl0="),
|
|
1373
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2l6bGVuemkuY29tL2NhbXBhaWduLyJd"),
|
|
1374
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3d3dy5pbnN0YWxsYWRzLm5ldC8iXQ==")
|
|
1375
|
+
],
|
|
1376
|
+
bulgarian: [fromB64("dGQjZnJlZW5ldF90YWJsZV9hZHM="), "#ea_intext_div", ".lapni-pop-over", "#xenium_hot_offers"],
|
|
1377
|
+
easyList: [
|
|
1378
|
+
".yb-floorad",
|
|
1379
|
+
fromB64("LndpZGdldF9wb19hZHNfd2lkZ2V0"),
|
|
1380
|
+
fromB64("LnRyYWZmaWNqdW5reS1hZA=="),
|
|
1381
|
+
".textad_headline",
|
|
1382
|
+
fromB64("LnNwb25zb3JlZC10ZXh0LWxpbmtz")
|
|
1383
|
+
],
|
|
1384
|
+
easyListChina: [
|
|
1385
|
+
fromB64("LmFwcGd1aWRlLXdyYXBbb25jbGljayo9ImJjZWJvcy5jb20iXQ=="),
|
|
1386
|
+
fromB64("LmZyb250cGFnZUFkdk0="),
|
|
1387
|
+
"#taotaole",
|
|
1388
|
+
"#aafoot.top_box",
|
|
1389
|
+
".cfa_popup"
|
|
1390
|
+
],
|
|
1391
|
+
easyListCookie: [
|
|
1392
|
+
".ezmob-footer",
|
|
1393
|
+
".cc-CookieWarning",
|
|
1394
|
+
"[data-cookie-number]",
|
|
1395
|
+
fromB64("LmF3LWNvb2tpZS1iYW5uZXI="),
|
|
1396
|
+
".sygnal24-gdpr-modal-wrap"
|
|
1397
|
+
],
|
|
1398
|
+
easyListCzechSlovak: [
|
|
1399
|
+
"#onlajny-stickers",
|
|
1400
|
+
fromB64("I3Jla2xhbW5pLWJveA=="),
|
|
1401
|
+
fromB64("LnJla2xhbWEtbWVnYWJvYXJk"),
|
|
1402
|
+
".sklik",
|
|
1403
|
+
fromB64("W2lkXj0ic2tsaWtSZWtsYW1hIl0=")
|
|
1404
|
+
],
|
|
1405
|
+
easyListDutch: [
|
|
1406
|
+
fromB64("I2FkdmVydGVudGll"),
|
|
1407
|
+
fromB64("I3ZpcEFkbWFya3RCYW5uZXJCbG9jaw=="),
|
|
1408
|
+
".adstekst",
|
|
1409
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly94bHR1YmUubmwvY2xpY2svIl0="),
|
|
1410
|
+
"#semilo-lrectangle"
|
|
1411
|
+
],
|
|
1412
|
+
easyListGermany: [
|
|
1413
|
+
"#SSpotIMPopSlider",
|
|
1414
|
+
fromB64("LnNwb25zb3JsaW5rZ3J1ZW4="),
|
|
1415
|
+
fromB64("I3dlcmJ1bmdza3k="),
|
|
1416
|
+
fromB64("I3Jla2xhbWUtcmVjaHRzLW1pdHRl"),
|
|
1417
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9iZDc0Mi5jb20vIl0=")
|
|
1418
|
+
],
|
|
1419
|
+
easyListItaly: [
|
|
1420
|
+
fromB64("LmJveF9hZHZfYW5udW5jaQ=="),
|
|
1421
|
+
".sb-box-pubbliredazionale",
|
|
1422
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2FmZmlsaWF6aW9uaWFkcy5zbmFpLml0LyJd"),
|
|
1423
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hZHNlcnZlci5odG1sLml0LyJd"),
|
|
1424
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9hZmZpbGlhemlvbmlhZHMuc25haS5pdC8iXQ==")
|
|
1425
|
+
],
|
|
1426
|
+
easyListLithuania: [
|
|
1427
|
+
fromB64("LnJla2xhbW9zX3RhcnBhcw=="),
|
|
1428
|
+
fromB64("LnJla2xhbW9zX251b3JvZG9z"),
|
|
1429
|
+
fromB64("aW1nW2FsdD0iUmVrbGFtaW5pcyBza3lkZWxpcyJd"),
|
|
1430
|
+
fromB64("aW1nW2FsdD0iRGVkaWt1b3RpLmx0IHNlcnZlcmlhaSJd"),
|
|
1431
|
+
fromB64("aW1nW2FsdD0iSG9zdGluZ2FzIFNlcnZlcmlhaS5sdCJd")
|
|
1432
|
+
],
|
|
1433
|
+
estonian: [fromB64("QVtocmVmKj0iaHR0cDovL3BheTRyZXN1bHRzMjQuZXUiXQ==")],
|
|
1434
|
+
fanboyAnnoyances: ["#ac-lre-player", ".navigate-to-top", "#subscribe_popup", ".newsletter_holder", "#back-top"],
|
|
1435
|
+
fanboyAntiFacebook: [".util-bar-module-firefly-visible"],
|
|
1436
|
+
fanboyEnhancedTrackers: [
|
|
1437
|
+
".open.pushModal",
|
|
1438
|
+
"#issuem-leaky-paywall-articles-zero-remaining-nag",
|
|
1439
|
+
"#sovrn_container",
|
|
1440
|
+
'div[class$="-hide"][zoompage-fontsize][style="display: block;"]',
|
|
1441
|
+
".BlockNag__Card"
|
|
1442
|
+
],
|
|
1443
|
+
fanboySocial: ["#FollowUs", "#meteored_share", "#social_follow", ".article-sharer", ".community__social-desc"],
|
|
1444
|
+
frellwitSwedish: [
|
|
1445
|
+
fromB64("YVtocmVmKj0iY2FzaW5vcHJvLnNlIl1bdGFyZ2V0PSJfYmxhbmsiXQ=="),
|
|
1446
|
+
fromB64("YVtocmVmKj0iZG9rdG9yLXNlLm9uZWxpbmsubWUiXQ=="),
|
|
1447
|
+
"article.category-samarbete",
|
|
1448
|
+
fromB64("ZGl2LmhvbGlkQWRz"),
|
|
1449
|
+
"ul.adsmodern"
|
|
1450
|
+
],
|
|
1451
|
+
greekAdBlock: [
|
|
1452
|
+
fromB64("QVtocmVmKj0iYWRtYW4ub3RlbmV0LmdyL2NsaWNrPyJd"),
|
|
1453
|
+
fromB64("QVtocmVmKj0iaHR0cDovL2F4aWFiYW5uZXJzLmV4b2R1cy5nci8iXQ=="),
|
|
1454
|
+
fromB64("QVtocmVmKj0iaHR0cDovL2ludGVyYWN0aXZlLmZvcnRobmV0LmdyL2NsaWNrPyJd"),
|
|
1455
|
+
"DIV.agores300",
|
|
1456
|
+
"TABLE.advright"
|
|
1457
|
+
],
|
|
1458
|
+
hungarian: [
|
|
1459
|
+
"#cemp_doboz",
|
|
1460
|
+
".optimonk-iframe-container",
|
|
1461
|
+
fromB64("LmFkX19tYWlu"),
|
|
1462
|
+
fromB64("W2NsYXNzKj0iR29vZ2xlQWRzIl0="),
|
|
1463
|
+
"#hirdetesek_box"
|
|
1464
|
+
],
|
|
1465
|
+
iDontCareAboutCookies: [
|
|
1466
|
+
'.alert-info[data-block-track*="CookieNotice"]',
|
|
1467
|
+
".ModuleTemplateCookieIndicator",
|
|
1468
|
+
".o--cookies--container",
|
|
1469
|
+
"#cookies-policy-sticky",
|
|
1470
|
+
"#stickyCookieBar"
|
|
1471
|
+
],
|
|
1472
|
+
icelandicAbp: [fromB64("QVtocmVmXj0iL2ZyYW1ld29yay9yZXNvdXJjZXMvZm9ybXMvYWRzLmFzcHgiXQ==")],
|
|
1473
|
+
latvian: [
|
|
1474
|
+
fromB64("YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiAxMjBweDsgaGVpZ2h0OiA0MHB4OyBvdmVyZmxvdzogaGlkZGVuOyBwb3NpdGlvbjogcmVsYXRpdmU7Il0="),
|
|
1475
|
+
fromB64("YVtocmVmPSJodHRwOi8vd3d3LnNhbGlkemluaS5sdi8iXVtzdHlsZT0iZGlzcGxheTogYmxvY2s7IHdpZHRoOiA4OHB4OyBoZWlnaHQ6IDMxcHg7IG92ZXJmbG93OiBoaWRkZW47IHBvc2l0aW9uOiByZWxhdGl2ZTsiXQ==")
|
|
1476
|
+
],
|
|
1477
|
+
listKr: [
|
|
1478
|
+
fromB64("YVtocmVmKj0iLy9hZC5wbGFuYnBsdXMuY28ua3IvIl0="),
|
|
1479
|
+
fromB64("I2xpdmVyZUFkV3JhcHBlcg=="),
|
|
1480
|
+
fromB64("YVtocmVmKj0iLy9hZHYuaW1hZHJlcC5jby5rci8iXQ=="),
|
|
1481
|
+
fromB64("aW5zLmZhc3R2aWV3LWFk"),
|
|
1482
|
+
".revenue_unit_item.dable"
|
|
1483
|
+
],
|
|
1484
|
+
listeAr: [
|
|
1485
|
+
fromB64("LmdlbWluaUxCMUFk"),
|
|
1486
|
+
".right-and-left-sponsers",
|
|
1487
|
+
fromB64("YVtocmVmKj0iLmFmbGFtLmluZm8iXQ=="),
|
|
1488
|
+
fromB64("YVtocmVmKj0iYm9vcmFxLm9yZyJd"),
|
|
1489
|
+
fromB64("YVtocmVmKj0iZHViaXp6bGUuY29tL2FyLz91dG1fc291cmNlPSJd")
|
|
1490
|
+
],
|
|
1491
|
+
listeFr: [
|
|
1492
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3Byb21vLnZhZG9yLmNvbS8iXQ=="),
|
|
1493
|
+
fromB64("I2FkY29udGFpbmVyX3JlY2hlcmNoZQ=="),
|
|
1494
|
+
fromB64("YVtocmVmKj0id2Vib3JhbWEuZnIvZmNnaS1iaW4vIl0="),
|
|
1495
|
+
".site-pub-interstitiel",
|
|
1496
|
+
'div[id^="crt-"][data-criteo-id]'
|
|
1497
|
+
],
|
|
1498
|
+
officialPolish: [
|
|
1499
|
+
"#ceneo-placeholder-ceneo-12",
|
|
1500
|
+
fromB64("W2hyZWZePSJodHRwczovL2FmZi5zZW5kaHViLnBsLyJd"),
|
|
1501
|
+
fromB64("YVtocmVmXj0iaHR0cDovL2Fkdm1hbmFnZXIudGVjaGZ1bi5wbC9yZWRpcmVjdC8iXQ=="),
|
|
1502
|
+
fromB64("YVtocmVmXj0iaHR0cDovL3d3dy50cml6ZXIucGwvP3V0bV9zb3VyY2UiXQ=="),
|
|
1503
|
+
fromB64("ZGl2I3NrYXBpZWNfYWQ=")
|
|
1504
|
+
],
|
|
1505
|
+
ro: [
|
|
1506
|
+
fromB64("YVtocmVmXj0iLy9hZmZ0cmsuYWx0ZXgucm8vQ291bnRlci9DbGljayJd"),
|
|
1507
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9ibGFja2ZyaWRheXNhbGVzLnJvL3Ryay9zaG9wLyJd"),
|
|
1508
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9ldmVudC4ycGVyZm9ybWFudC5jb20vZXZlbnRzL2NsaWNrIl0="),
|
|
1509
|
+
fromB64("YVtocmVmXj0iaHR0cHM6Ly9sLnByb2ZpdHNoYXJlLnJvLyJd"),
|
|
1510
|
+
'a[href^="/url/"]'
|
|
1511
|
+
],
|
|
1512
|
+
ruAd: [
|
|
1513
|
+
fromB64("YVtocmVmKj0iLy9mZWJyYXJlLnJ1LyJd"),
|
|
1514
|
+
fromB64("YVtocmVmKj0iLy91dGltZy5ydS8iXQ=="),
|
|
1515
|
+
fromB64("YVtocmVmKj0iOi8vY2hpa2lkaWtpLnJ1Il0="),
|
|
1516
|
+
"#pgeldiz",
|
|
1517
|
+
".yandex-rtb-block"
|
|
1518
|
+
],
|
|
1519
|
+
thaiAds: [
|
|
1520
|
+
"a[href*=macau-uta-popup]",
|
|
1521
|
+
fromB64("I2Fkcy1nb29nbGUtbWlkZGxlX3JlY3RhbmdsZS1ncm91cA=="),
|
|
1522
|
+
fromB64("LmFkczMwMHM="),
|
|
1523
|
+
".bumq",
|
|
1524
|
+
".img-kosana"
|
|
1525
|
+
],
|
|
1526
|
+
webAnnoyancesUltralist: [
|
|
1527
|
+
"#mod-social-share-2",
|
|
1528
|
+
"#social-tools",
|
|
1529
|
+
fromB64("LmN0cGwtZnVsbGJhbm5lcg=="),
|
|
1530
|
+
".zergnet-recommend",
|
|
1531
|
+
".yt.btn-link.btn-md.btn"
|
|
1532
|
+
]
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
async function getDomBlockers({ debug } = {}) {
|
|
1536
|
+
if (!isApplicable()) {
|
|
1537
|
+
return void 0;
|
|
1538
|
+
}
|
|
1539
|
+
const filters = getFilters();
|
|
1540
|
+
const filterNames = Object.keys(filters);
|
|
1541
|
+
const allSelectors = [].concat(...filterNames.map((filterName) => filters[filterName]));
|
|
1542
|
+
const blockedSelectors = await getBlockedSelectors(allSelectors);
|
|
1543
|
+
if (debug) {
|
|
1544
|
+
printDebug(filters, blockedSelectors);
|
|
1545
|
+
}
|
|
1546
|
+
const activeBlockers = filterNames.filter((filterName) => {
|
|
1547
|
+
const selectors = filters[filterName];
|
|
1548
|
+
const blockedCount = countTruthy(selectors.map((selector) => blockedSelectors[selector]));
|
|
1549
|
+
return blockedCount > selectors.length * 0.6;
|
|
1550
|
+
});
|
|
1551
|
+
activeBlockers.sort();
|
|
1552
|
+
return activeBlockers;
|
|
1553
|
+
}
|
|
1554
|
+
function isApplicable() {
|
|
1555
|
+
return isWebKit() || isAndroid();
|
|
1556
|
+
}
|
|
1557
|
+
async function getBlockedSelectors(selectors) {
|
|
1558
|
+
var _a;
|
|
1559
|
+
const d = document;
|
|
1560
|
+
const root = d.createElement("div");
|
|
1561
|
+
const elements = new Array(selectors.length);
|
|
1562
|
+
const blockedSelectors = {};
|
|
1563
|
+
forceShow(root);
|
|
1564
|
+
for (let i = 0; i < selectors.length; ++i) {
|
|
1565
|
+
const element = selectorToElement(selectors[i]);
|
|
1566
|
+
if (element.tagName === "DIALOG") {
|
|
1567
|
+
element.show();
|
|
1568
|
+
}
|
|
1569
|
+
const holder = d.createElement("div");
|
|
1570
|
+
forceShow(holder);
|
|
1571
|
+
holder.appendChild(element);
|
|
1572
|
+
root.appendChild(holder);
|
|
1573
|
+
elements[i] = element;
|
|
1574
|
+
}
|
|
1575
|
+
while (!d.body) {
|
|
1576
|
+
await wait(50);
|
|
1577
|
+
}
|
|
1578
|
+
d.body.appendChild(root);
|
|
1579
|
+
try {
|
|
1580
|
+
for (let i = 0; i < selectors.length; ++i) {
|
|
1581
|
+
if (!elements[i].offsetParent) {
|
|
1582
|
+
blockedSelectors[selectors[i]] = true;
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
} finally {
|
|
1586
|
+
(_a = root.parentNode) === null || _a === void 0 ? void 0 : _a.removeChild(root);
|
|
1587
|
+
}
|
|
1588
|
+
return blockedSelectors;
|
|
1589
|
+
}
|
|
1590
|
+
function forceShow(element) {
|
|
1591
|
+
element.style.setProperty("visibility", "hidden", "important");
|
|
1592
|
+
element.style.setProperty("display", "block", "important");
|
|
1593
|
+
}
|
|
1594
|
+
function printDebug(filters, blockedSelectors) {
|
|
1595
|
+
let message = "DOM blockers debug:\n```";
|
|
1596
|
+
for (const filterName of Object.keys(filters)) {
|
|
1597
|
+
message += `
|
|
1598
|
+
${filterName}:`;
|
|
1599
|
+
for (const selector of filters[filterName]) {
|
|
1600
|
+
message += `
|
|
1601
|
+
${blockedSelectors[selector] ? "\u{1F6AB}" : "\u27A1\uFE0F"} ${selector}`;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
console.log(`${message}
|
|
1605
|
+
\`\`\``);
|
|
1606
|
+
}
|
|
1607
|
+
function getColorGamut() {
|
|
1608
|
+
for (const gamut of ["rec2020", "p3", "srgb"]) {
|
|
1609
|
+
if (matchMedia(`(color-gamut: ${gamut})`).matches) {
|
|
1610
|
+
return gamut;
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
return void 0;
|
|
1614
|
+
}
|
|
1615
|
+
function areColorsInverted() {
|
|
1616
|
+
if (doesMatch$5("inverted")) {
|
|
1617
|
+
return true;
|
|
1618
|
+
}
|
|
1619
|
+
if (doesMatch$5("none")) {
|
|
1620
|
+
return false;
|
|
1621
|
+
}
|
|
1622
|
+
return void 0;
|
|
1623
|
+
}
|
|
1624
|
+
function doesMatch$5(value) {
|
|
1625
|
+
return matchMedia(`(inverted-colors: ${value})`).matches;
|
|
1626
|
+
}
|
|
1627
|
+
function areColorsForced() {
|
|
1628
|
+
if (doesMatch$4("active")) {
|
|
1629
|
+
return true;
|
|
1630
|
+
}
|
|
1631
|
+
if (doesMatch$4("none")) {
|
|
1632
|
+
return false;
|
|
1633
|
+
}
|
|
1634
|
+
return void 0;
|
|
1635
|
+
}
|
|
1636
|
+
function doesMatch$4(value) {
|
|
1637
|
+
return matchMedia(`(forced-colors: ${value})`).matches;
|
|
1638
|
+
}
|
|
1639
|
+
var maxValueToCheck = 100;
|
|
1640
|
+
function getMonochromeDepth() {
|
|
1641
|
+
if (!matchMedia("(min-monochrome: 0)").matches) {
|
|
1642
|
+
return void 0;
|
|
1643
|
+
}
|
|
1644
|
+
for (let i = 0; i <= maxValueToCheck; ++i) {
|
|
1645
|
+
if (matchMedia(`(max-monochrome: ${i})`).matches) {
|
|
1646
|
+
return i;
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
throw new Error("Too high value");
|
|
1650
|
+
}
|
|
1651
|
+
function getContrastPreference() {
|
|
1652
|
+
if (doesMatch$3("no-preference")) {
|
|
1653
|
+
return 0;
|
|
1654
|
+
}
|
|
1655
|
+
if (doesMatch$3("high") || doesMatch$3("more")) {
|
|
1656
|
+
return 1;
|
|
1657
|
+
}
|
|
1658
|
+
if (doesMatch$3("low") || doesMatch$3("less")) {
|
|
1659
|
+
return -1;
|
|
1660
|
+
}
|
|
1661
|
+
if (doesMatch$3("forced")) {
|
|
1662
|
+
return 10;
|
|
1663
|
+
}
|
|
1664
|
+
return void 0;
|
|
1665
|
+
}
|
|
1666
|
+
function doesMatch$3(value) {
|
|
1667
|
+
return matchMedia(`(prefers-contrast: ${value})`).matches;
|
|
1668
|
+
}
|
|
1669
|
+
function isMotionReduced() {
|
|
1670
|
+
if (doesMatch$2("reduce")) {
|
|
1671
|
+
return true;
|
|
1672
|
+
}
|
|
1673
|
+
if (doesMatch$2("no-preference")) {
|
|
1674
|
+
return false;
|
|
1675
|
+
}
|
|
1676
|
+
return void 0;
|
|
1677
|
+
}
|
|
1678
|
+
function doesMatch$2(value) {
|
|
1679
|
+
return matchMedia(`(prefers-reduced-motion: ${value})`).matches;
|
|
1680
|
+
}
|
|
1681
|
+
function isTransparencyReduced() {
|
|
1682
|
+
if (doesMatch$1("reduce")) {
|
|
1683
|
+
return true;
|
|
1684
|
+
}
|
|
1685
|
+
if (doesMatch$1("no-preference")) {
|
|
1686
|
+
return false;
|
|
1687
|
+
}
|
|
1688
|
+
return void 0;
|
|
1689
|
+
}
|
|
1690
|
+
function doesMatch$1(value) {
|
|
1691
|
+
return matchMedia(`(prefers-reduced-transparency: ${value})`).matches;
|
|
1692
|
+
}
|
|
1693
|
+
function isHDR() {
|
|
1694
|
+
if (doesMatch("high")) {
|
|
1695
|
+
return true;
|
|
1696
|
+
}
|
|
1697
|
+
if (doesMatch("standard")) {
|
|
1698
|
+
return false;
|
|
1699
|
+
}
|
|
1700
|
+
return void 0;
|
|
1701
|
+
}
|
|
1702
|
+
function doesMatch(value) {
|
|
1703
|
+
return matchMedia(`(dynamic-range: ${value})`).matches;
|
|
1704
|
+
}
|
|
1705
|
+
var M = Math;
|
|
1706
|
+
var fallbackFn = () => 0;
|
|
1707
|
+
function getMathFingerprint() {
|
|
1708
|
+
const acos = M.acos || fallbackFn;
|
|
1709
|
+
const acosh = M.acosh || fallbackFn;
|
|
1710
|
+
const asin = M.asin || fallbackFn;
|
|
1711
|
+
const asinh = M.asinh || fallbackFn;
|
|
1712
|
+
const atanh = M.atanh || fallbackFn;
|
|
1713
|
+
const atan = M.atan || fallbackFn;
|
|
1714
|
+
const sin = M.sin || fallbackFn;
|
|
1715
|
+
const sinh = M.sinh || fallbackFn;
|
|
1716
|
+
const cos = M.cos || fallbackFn;
|
|
1717
|
+
const cosh = M.cosh || fallbackFn;
|
|
1718
|
+
const tan = M.tan || fallbackFn;
|
|
1719
|
+
const tanh = M.tanh || fallbackFn;
|
|
1720
|
+
const exp = M.exp || fallbackFn;
|
|
1721
|
+
const expm1 = M.expm1 || fallbackFn;
|
|
1722
|
+
const log1p = M.log1p || fallbackFn;
|
|
1723
|
+
const powPI = (value) => M.pow(M.PI, value);
|
|
1724
|
+
const acoshPf = (value) => M.log(value + M.sqrt(value * value - 1));
|
|
1725
|
+
const asinhPf = (value) => M.log(value + M.sqrt(value * value + 1));
|
|
1726
|
+
const atanhPf = (value) => M.log((1 + value) / (1 - value)) / 2;
|
|
1727
|
+
const sinhPf = (value) => M.exp(value) - 1 / M.exp(value) / 2;
|
|
1728
|
+
const coshPf = (value) => (M.exp(value) + 1 / M.exp(value)) / 2;
|
|
1729
|
+
const expm1Pf = (value) => M.exp(value) - 1;
|
|
1730
|
+
const tanhPf = (value) => (M.exp(2 * value) - 1) / (M.exp(2 * value) + 1);
|
|
1731
|
+
const log1pPf = (value) => M.log(1 + value);
|
|
1732
|
+
return {
|
|
1733
|
+
acos: acos(0.12312423423423424),
|
|
1734
|
+
acosh: acosh(1e308),
|
|
1735
|
+
acoshPf: acoshPf(1e154),
|
|
1736
|
+
asin: asin(0.12312423423423424),
|
|
1737
|
+
asinh: asinh(1),
|
|
1738
|
+
asinhPf: asinhPf(1),
|
|
1739
|
+
atanh: atanh(0.5),
|
|
1740
|
+
atanhPf: atanhPf(0.5),
|
|
1741
|
+
atan: atan(0.5),
|
|
1742
|
+
sin: sin(-1e300),
|
|
1743
|
+
sinh: sinh(1),
|
|
1744
|
+
sinhPf: sinhPf(1),
|
|
1745
|
+
cos: cos(10.000000000123),
|
|
1746
|
+
cosh: cosh(1),
|
|
1747
|
+
coshPf: coshPf(1),
|
|
1748
|
+
tan: tan(-1e300),
|
|
1749
|
+
tanh: tanh(1),
|
|
1750
|
+
tanhPf: tanhPf(1),
|
|
1751
|
+
exp: exp(1),
|
|
1752
|
+
expm1: expm1(1),
|
|
1753
|
+
expm1Pf: expm1Pf(1),
|
|
1754
|
+
log1p: log1p(10),
|
|
1755
|
+
log1pPf: log1pPf(10),
|
|
1756
|
+
powPI: powPI(-100)
|
|
1757
|
+
};
|
|
1758
|
+
}
|
|
1759
|
+
var defaultText = "mmMwWLliI0fiflO&1";
|
|
1760
|
+
var presets = {
|
|
1761
|
+
/**
|
|
1762
|
+
* The default font. User can change it in desktop Chrome, desktop Firefox, IE 11,
|
|
1763
|
+
* Android Chrome (but only when the size is ≥ than the default) and Android Firefox.
|
|
1764
|
+
*/
|
|
1765
|
+
default: [],
|
|
1766
|
+
/** OS font on macOS. User can change its size and weight. Applies after Safari restart. */
|
|
1767
|
+
apple: [{ font: "-apple-system-body" }],
|
|
1768
|
+
/** User can change it in desktop Chrome and desktop Firefox. */
|
|
1769
|
+
serif: [{ fontFamily: "serif" }],
|
|
1770
|
+
/** User can change it in desktop Chrome and desktop Firefox. */
|
|
1771
|
+
sans: [{ fontFamily: "sans-serif" }],
|
|
1772
|
+
/** User can change it in desktop Chrome and desktop Firefox. */
|
|
1773
|
+
mono: [{ fontFamily: "monospace" }],
|
|
1774
|
+
/**
|
|
1775
|
+
* Check the smallest allowed font size. User can change it in desktop Chrome, desktop Firefox and desktop Safari.
|
|
1776
|
+
* The height can be 0 in Chrome on a retina display.
|
|
1777
|
+
*/
|
|
1778
|
+
min: [{ fontSize: "1px" }],
|
|
1779
|
+
/** Tells one OS from another in desktop Chrome. */
|
|
1780
|
+
system: [{ fontFamily: "system-ui" }]
|
|
1781
|
+
};
|
|
1782
|
+
function getFontPreferences() {
|
|
1783
|
+
return withNaturalFonts((document2, container) => {
|
|
1784
|
+
const elements = {};
|
|
1785
|
+
const sizes = {};
|
|
1786
|
+
for (const key of Object.keys(presets)) {
|
|
1787
|
+
const [style = {}, text = defaultText] = presets[key];
|
|
1788
|
+
const element = document2.createElement("span");
|
|
1789
|
+
element.textContent = text;
|
|
1790
|
+
element.style.whiteSpace = "nowrap";
|
|
1791
|
+
for (const name of Object.keys(style)) {
|
|
1792
|
+
const value = style[name];
|
|
1793
|
+
if (value !== void 0) {
|
|
1794
|
+
element.style[name] = value;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
elements[key] = element;
|
|
1798
|
+
container.append(document2.createElement("br"), element);
|
|
1799
|
+
}
|
|
1800
|
+
for (const key of Object.keys(presets)) {
|
|
1801
|
+
sizes[key] = elements[key].getBoundingClientRect().width;
|
|
1802
|
+
}
|
|
1803
|
+
return sizes;
|
|
1804
|
+
});
|
|
1805
|
+
}
|
|
1806
|
+
function withNaturalFonts(action, containerWidthPx = 4e3) {
|
|
1807
|
+
return withIframe((_, iframeWindow) => {
|
|
1808
|
+
const iframeDocument = iframeWindow.document;
|
|
1809
|
+
const iframeBody = iframeDocument.body;
|
|
1810
|
+
const bodyStyle = iframeBody.style;
|
|
1811
|
+
bodyStyle.width = `${containerWidthPx}px`;
|
|
1812
|
+
bodyStyle.webkitTextSizeAdjust = bodyStyle.textSizeAdjust = "none";
|
|
1813
|
+
if (isChromium()) {
|
|
1814
|
+
iframeBody.style.zoom = `${1 / iframeWindow.devicePixelRatio}`;
|
|
1815
|
+
} else if (isWebKit()) {
|
|
1816
|
+
iframeBody.style.zoom = "reset";
|
|
1817
|
+
}
|
|
1818
|
+
const linesOfText = iframeDocument.createElement("div");
|
|
1819
|
+
linesOfText.textContent = [...Array(containerWidthPx / 20 << 0)].map(() => "word").join(" ");
|
|
1820
|
+
iframeBody.appendChild(linesOfText);
|
|
1821
|
+
return action(iframeDocument, iframeBody);
|
|
1822
|
+
}, '<!doctype html><html><head><meta name="viewport" content="width=device-width, initial-scale=1">');
|
|
1823
|
+
}
|
|
1824
|
+
function isPdfViewerEnabled() {
|
|
1825
|
+
return navigator.pdfViewerEnabled;
|
|
1826
|
+
}
|
|
1827
|
+
function getArchitecture() {
|
|
1828
|
+
const f = new Float32Array(1);
|
|
1829
|
+
const u8 = new Uint8Array(f.buffer);
|
|
1830
|
+
f[0] = Infinity;
|
|
1831
|
+
f[0] = f[0] - f[0];
|
|
1832
|
+
return u8[3];
|
|
1833
|
+
}
|
|
1834
|
+
function getApplePayState() {
|
|
1835
|
+
const { ApplePaySession } = window;
|
|
1836
|
+
if (typeof (ApplePaySession === null || ApplePaySession === void 0 ? void 0 : ApplePaySession.canMakePayments) !== "function") {
|
|
1837
|
+
return -1;
|
|
1838
|
+
}
|
|
1839
|
+
if (willPrintConsoleError()) {
|
|
1840
|
+
return -3;
|
|
1841
|
+
}
|
|
1842
|
+
try {
|
|
1843
|
+
return ApplePaySession.canMakePayments() ? 1 : 0;
|
|
1844
|
+
} catch (error) {
|
|
1845
|
+
return getStateFromError(error);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
var willPrintConsoleError = isAnyParentCrossOrigin;
|
|
1849
|
+
function getStateFromError(error) {
|
|
1850
|
+
if (error instanceof Error && error.name === "InvalidAccessError" && /\bfrom\b.*\binsecure\b/i.test(error.message)) {
|
|
1851
|
+
return -2;
|
|
1852
|
+
}
|
|
1853
|
+
throw error;
|
|
1854
|
+
}
|
|
1855
|
+
function getPrivateClickMeasurement() {
|
|
1856
|
+
var _a;
|
|
1857
|
+
const link = document.createElement("a");
|
|
1858
|
+
const sourceId = (_a = link.attributionSourceId) !== null && _a !== void 0 ? _a : link.attributionsourceid;
|
|
1859
|
+
return sourceId === void 0 ? void 0 : String(sourceId);
|
|
1860
|
+
}
|
|
1861
|
+
var STATUS_NO_GL_CONTEXT = -1;
|
|
1862
|
+
var STATUS_GET_PARAMETER_NOT_A_FUNCTION = -2;
|
|
1863
|
+
var validContextParameters = /* @__PURE__ */ new Set([
|
|
1864
|
+
10752,
|
|
1865
|
+
2849,
|
|
1866
|
+
2884,
|
|
1867
|
+
2885,
|
|
1868
|
+
2886,
|
|
1869
|
+
2928,
|
|
1870
|
+
2929,
|
|
1871
|
+
2930,
|
|
1872
|
+
2931,
|
|
1873
|
+
2932,
|
|
1874
|
+
2960,
|
|
1875
|
+
2961,
|
|
1876
|
+
2962,
|
|
1877
|
+
2963,
|
|
1878
|
+
2964,
|
|
1879
|
+
2965,
|
|
1880
|
+
2966,
|
|
1881
|
+
2967,
|
|
1882
|
+
2968,
|
|
1883
|
+
2978,
|
|
1884
|
+
3024,
|
|
1885
|
+
3042,
|
|
1886
|
+
3088,
|
|
1887
|
+
3089,
|
|
1888
|
+
3106,
|
|
1889
|
+
3107,
|
|
1890
|
+
32773,
|
|
1891
|
+
32777,
|
|
1892
|
+
32777,
|
|
1893
|
+
32823,
|
|
1894
|
+
32824,
|
|
1895
|
+
32936,
|
|
1896
|
+
32937,
|
|
1897
|
+
32938,
|
|
1898
|
+
32939,
|
|
1899
|
+
32968,
|
|
1900
|
+
32969,
|
|
1901
|
+
32970,
|
|
1902
|
+
32971,
|
|
1903
|
+
3317,
|
|
1904
|
+
33170,
|
|
1905
|
+
3333,
|
|
1906
|
+
3379,
|
|
1907
|
+
3386,
|
|
1908
|
+
33901,
|
|
1909
|
+
33902,
|
|
1910
|
+
34016,
|
|
1911
|
+
34024,
|
|
1912
|
+
34076,
|
|
1913
|
+
3408,
|
|
1914
|
+
3410,
|
|
1915
|
+
3411,
|
|
1916
|
+
3412,
|
|
1917
|
+
3413,
|
|
1918
|
+
3414,
|
|
1919
|
+
3415,
|
|
1920
|
+
34467,
|
|
1921
|
+
34816,
|
|
1922
|
+
34817,
|
|
1923
|
+
34818,
|
|
1924
|
+
34819,
|
|
1925
|
+
34877,
|
|
1926
|
+
34921,
|
|
1927
|
+
34930,
|
|
1928
|
+
35660,
|
|
1929
|
+
35661,
|
|
1930
|
+
35724,
|
|
1931
|
+
35738,
|
|
1932
|
+
35739,
|
|
1933
|
+
36003,
|
|
1934
|
+
36004,
|
|
1935
|
+
36005,
|
|
1936
|
+
36347,
|
|
1937
|
+
36348,
|
|
1938
|
+
36349,
|
|
1939
|
+
37440,
|
|
1940
|
+
37441,
|
|
1941
|
+
37443,
|
|
1942
|
+
7936,
|
|
1943
|
+
7937,
|
|
1944
|
+
7938
|
|
1945
|
+
// SAMPLE_ALPHA_TO_COVERAGE (32926) and SAMPLE_COVERAGE (32928) are excluded because they trigger a console warning
|
|
1946
|
+
// in IE, Chrome ≤ 59 and Safari ≤ 13 and give no entropy.
|
|
1947
|
+
]);
|
|
1948
|
+
var validExtensionParams = /* @__PURE__ */ new Set([
|
|
1949
|
+
34047,
|
|
1950
|
+
35723,
|
|
1951
|
+
36063,
|
|
1952
|
+
34852,
|
|
1953
|
+
34853,
|
|
1954
|
+
34854,
|
|
1955
|
+
34229,
|
|
1956
|
+
36392,
|
|
1957
|
+
36795,
|
|
1958
|
+
38449
|
|
1959
|
+
// MAX_VIEWS_OVR
|
|
1960
|
+
]);
|
|
1961
|
+
var shaderTypes = ["FRAGMENT_SHADER", "VERTEX_SHADER"];
|
|
1962
|
+
var precisionTypes = ["LOW_FLOAT", "MEDIUM_FLOAT", "HIGH_FLOAT", "LOW_INT", "MEDIUM_INT", "HIGH_INT"];
|
|
1963
|
+
var rendererInfoExtensionName = "WEBGL_debug_renderer_info";
|
|
1964
|
+
var polygonModeExtensionName = "WEBGL_polygon_mode";
|
|
1965
|
+
function getWebGlBasics({ cache }) {
|
|
1966
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1967
|
+
const gl = getWebGLContext(cache);
|
|
1968
|
+
if (!gl) {
|
|
1969
|
+
return STATUS_NO_GL_CONTEXT;
|
|
1970
|
+
}
|
|
1971
|
+
if (!isValidParameterGetter(gl)) {
|
|
1972
|
+
return STATUS_GET_PARAMETER_NOT_A_FUNCTION;
|
|
1973
|
+
}
|
|
1974
|
+
const debugExtension = shouldAvoidDebugRendererInfo() ? null : gl.getExtension(rendererInfoExtensionName);
|
|
1975
|
+
return {
|
|
1976
|
+
version: ((_a = gl.getParameter(gl.VERSION)) === null || _a === void 0 ? void 0 : _a.toString()) || "",
|
|
1977
|
+
vendor: ((_b = gl.getParameter(gl.VENDOR)) === null || _b === void 0 ? void 0 : _b.toString()) || "",
|
|
1978
|
+
vendorUnmasked: debugExtension ? (_c = gl.getParameter(debugExtension.UNMASKED_VENDOR_WEBGL)) === null || _c === void 0 ? void 0 : _c.toString() : "",
|
|
1979
|
+
renderer: ((_d = gl.getParameter(gl.RENDERER)) === null || _d === void 0 ? void 0 : _d.toString()) || "",
|
|
1980
|
+
rendererUnmasked: debugExtension ? (_e = gl.getParameter(debugExtension.UNMASKED_RENDERER_WEBGL)) === null || _e === void 0 ? void 0 : _e.toString() : "",
|
|
1981
|
+
shadingLanguageVersion: ((_f = gl.getParameter(gl.SHADING_LANGUAGE_VERSION)) === null || _f === void 0 ? void 0 : _f.toString()) || ""
|
|
1982
|
+
};
|
|
1983
|
+
}
|
|
1984
|
+
function getWebGlExtensions({ cache }) {
|
|
1985
|
+
const gl = getWebGLContext(cache);
|
|
1986
|
+
if (!gl) {
|
|
1987
|
+
return STATUS_NO_GL_CONTEXT;
|
|
1988
|
+
}
|
|
1989
|
+
if (!isValidParameterGetter(gl)) {
|
|
1990
|
+
return STATUS_GET_PARAMETER_NOT_A_FUNCTION;
|
|
1991
|
+
}
|
|
1992
|
+
const extensions = gl.getSupportedExtensions();
|
|
1993
|
+
const contextAttributes = gl.getContextAttributes();
|
|
1994
|
+
const unsupportedExtensions = [];
|
|
1995
|
+
const attributes = [];
|
|
1996
|
+
const parameters = [];
|
|
1997
|
+
const extensionParameters = [];
|
|
1998
|
+
const shaderPrecisions = [];
|
|
1999
|
+
if (contextAttributes) {
|
|
2000
|
+
for (const attributeName of Object.keys(contextAttributes)) {
|
|
2001
|
+
attributes.push(`${attributeName}=${contextAttributes[attributeName]}`);
|
|
2002
|
+
}
|
|
2003
|
+
}
|
|
2004
|
+
const constants = getConstantsFromPrototype(gl);
|
|
2005
|
+
for (const constant of constants) {
|
|
2006
|
+
const code = gl[constant];
|
|
2007
|
+
parameters.push(`${constant}=${code}${validContextParameters.has(code) ? `=${gl.getParameter(code)}` : ""}`);
|
|
2008
|
+
}
|
|
2009
|
+
if (extensions) {
|
|
2010
|
+
for (const name of extensions) {
|
|
2011
|
+
if (name === rendererInfoExtensionName && shouldAvoidDebugRendererInfo() || name === polygonModeExtensionName && shouldAvoidPolygonModeExtensions()) {
|
|
2012
|
+
continue;
|
|
2013
|
+
}
|
|
2014
|
+
const extension = gl.getExtension(name);
|
|
2015
|
+
if (!extension) {
|
|
2016
|
+
unsupportedExtensions.push(name);
|
|
2017
|
+
continue;
|
|
2018
|
+
}
|
|
2019
|
+
for (const constant of getConstantsFromPrototype(extension)) {
|
|
2020
|
+
const code = extension[constant];
|
|
2021
|
+
extensionParameters.push(`${constant}=${code}${validExtensionParams.has(code) ? `=${gl.getParameter(code)}` : ""}`);
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
for (const shaderType of shaderTypes) {
|
|
2026
|
+
for (const precisionType of precisionTypes) {
|
|
2027
|
+
const shaderPrecision = getShaderPrecision(gl, shaderType, precisionType);
|
|
2028
|
+
shaderPrecisions.push(`${shaderType}.${precisionType}=${shaderPrecision.join(",")}`);
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
extensionParameters.sort();
|
|
2032
|
+
parameters.sort();
|
|
2033
|
+
return {
|
|
2034
|
+
contextAttributes: attributes,
|
|
2035
|
+
parameters,
|
|
2036
|
+
shaderPrecisions,
|
|
2037
|
+
extensions,
|
|
2038
|
+
extensionParameters,
|
|
2039
|
+
unsupportedExtensions
|
|
2040
|
+
};
|
|
2041
|
+
}
|
|
2042
|
+
function getWebGLContext(cache) {
|
|
2043
|
+
if (cache.webgl) {
|
|
2044
|
+
return cache.webgl.context;
|
|
2045
|
+
}
|
|
2046
|
+
const canvas = document.createElement("canvas");
|
|
2047
|
+
let context;
|
|
2048
|
+
canvas.addEventListener("webglCreateContextError", () => context = void 0);
|
|
2049
|
+
for (const type of ["webgl", "experimental-webgl"]) {
|
|
2050
|
+
try {
|
|
2051
|
+
context = canvas.getContext(type);
|
|
2052
|
+
} catch (_a) {
|
|
2053
|
+
}
|
|
2054
|
+
if (context) {
|
|
2055
|
+
break;
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
cache.webgl = { context };
|
|
2059
|
+
return context;
|
|
2060
|
+
}
|
|
2061
|
+
function getShaderPrecision(gl, shaderType, precisionType) {
|
|
2062
|
+
const shaderPrecision = gl.getShaderPrecisionFormat(gl[shaderType], gl[precisionType]);
|
|
2063
|
+
return shaderPrecision ? [shaderPrecision.rangeMin, shaderPrecision.rangeMax, shaderPrecision.precision] : [];
|
|
2064
|
+
}
|
|
2065
|
+
function getConstantsFromPrototype(obj) {
|
|
2066
|
+
const keys = Object.keys(obj.__proto__);
|
|
2067
|
+
return keys.filter(isConstantLike);
|
|
2068
|
+
}
|
|
2069
|
+
function isConstantLike(key) {
|
|
2070
|
+
return typeof key === "string" && !key.match(/[^A-Z0-9_x]/);
|
|
2071
|
+
}
|
|
2072
|
+
function shouldAvoidDebugRendererInfo() {
|
|
2073
|
+
return isGecko();
|
|
2074
|
+
}
|
|
2075
|
+
function shouldAvoidPolygonModeExtensions() {
|
|
2076
|
+
return isChromium() || isWebKit();
|
|
2077
|
+
}
|
|
2078
|
+
function isValidParameterGetter(gl) {
|
|
2079
|
+
return typeof gl.getParameter === "function";
|
|
2080
|
+
}
|
|
2081
|
+
function getAudioContextBaseLatency() {
|
|
2082
|
+
const isAllowedPlatform = isAndroid() || isWebKit();
|
|
2083
|
+
if (!isAllowedPlatform) {
|
|
2084
|
+
return -2;
|
|
2085
|
+
}
|
|
2086
|
+
if (!window.AudioContext) {
|
|
2087
|
+
return -1;
|
|
2088
|
+
}
|
|
2089
|
+
const latency = new AudioContext().baseLatency;
|
|
2090
|
+
if (latency === null || latency === void 0) {
|
|
2091
|
+
return -1;
|
|
2092
|
+
}
|
|
2093
|
+
if (!isFinite(latency)) {
|
|
2094
|
+
return -3;
|
|
2095
|
+
}
|
|
2096
|
+
return latency;
|
|
2097
|
+
}
|
|
2098
|
+
function getDateTimeLocale() {
|
|
2099
|
+
if (!window.Intl) {
|
|
2100
|
+
return -1;
|
|
2101
|
+
}
|
|
2102
|
+
const DateTimeFormat = window.Intl.DateTimeFormat;
|
|
2103
|
+
if (!DateTimeFormat) {
|
|
2104
|
+
return -2;
|
|
2105
|
+
}
|
|
2106
|
+
const locale = DateTimeFormat().resolvedOptions().locale;
|
|
2107
|
+
if (!locale && locale !== "") {
|
|
2108
|
+
return -3;
|
|
2109
|
+
}
|
|
2110
|
+
return locale;
|
|
2111
|
+
}
|
|
2112
|
+
var sources = {
|
|
2113
|
+
// READ FIRST:
|
|
2114
|
+
// See https://github.com/fingerprintjs/fingerprintjs/blob/master/contributing.md#how-to-add-an-entropy-source
|
|
2115
|
+
// to learn how entropy source works and how to make your own.
|
|
2116
|
+
// The sources run in this exact order.
|
|
2117
|
+
// The asynchronous sources are at the start to run in parallel with other sources.
|
|
2118
|
+
fonts: getFonts,
|
|
2119
|
+
domBlockers: getDomBlockers,
|
|
2120
|
+
fontPreferences: getFontPreferences,
|
|
2121
|
+
audio: getAudioFingerprint,
|
|
2122
|
+
screenFrame: getScreenFrame,
|
|
2123
|
+
canvas: getCanvasFingerprint,
|
|
2124
|
+
osCpu: getOsCpu,
|
|
2125
|
+
languages: getLanguages,
|
|
2126
|
+
colorDepth: getColorDepth,
|
|
2127
|
+
deviceMemory: getDeviceMemory,
|
|
2128
|
+
screenResolution: getScreenResolution,
|
|
2129
|
+
hardwareConcurrency: getHardwareConcurrency,
|
|
2130
|
+
timezone: getTimezone,
|
|
2131
|
+
sessionStorage: getSessionStorage,
|
|
2132
|
+
localStorage: getLocalStorage,
|
|
2133
|
+
indexedDB: getIndexedDB,
|
|
2134
|
+
openDatabase: getOpenDatabase,
|
|
2135
|
+
cpuClass: getCpuClass,
|
|
2136
|
+
platform: getPlatform,
|
|
2137
|
+
plugins: getPlugins,
|
|
2138
|
+
touchSupport: getTouchSupport,
|
|
2139
|
+
vendor: getVendor,
|
|
2140
|
+
vendorFlavors: getVendorFlavors,
|
|
2141
|
+
cookiesEnabled: areCookiesEnabled,
|
|
2142
|
+
colorGamut: getColorGamut,
|
|
2143
|
+
invertedColors: areColorsInverted,
|
|
2144
|
+
forcedColors: areColorsForced,
|
|
2145
|
+
monochrome: getMonochromeDepth,
|
|
2146
|
+
contrast: getContrastPreference,
|
|
2147
|
+
reducedMotion: isMotionReduced,
|
|
2148
|
+
reducedTransparency: isTransparencyReduced,
|
|
2149
|
+
hdr: isHDR,
|
|
2150
|
+
math: getMathFingerprint,
|
|
2151
|
+
pdfViewerEnabled: isPdfViewerEnabled,
|
|
2152
|
+
architecture: getArchitecture,
|
|
2153
|
+
applePay: getApplePayState,
|
|
2154
|
+
privateClickMeasurement: getPrivateClickMeasurement,
|
|
2155
|
+
audioBaseLatency: getAudioContextBaseLatency,
|
|
2156
|
+
dateTimeLocale: getDateTimeLocale,
|
|
2157
|
+
// Some sources can affect other sources (e.g. WebGL can affect canvas), so it's important to run these sources
|
|
2158
|
+
// after other sources.
|
|
2159
|
+
webGlBasics: getWebGlBasics,
|
|
2160
|
+
webGlExtensions: getWebGlExtensions
|
|
2161
|
+
};
|
|
2162
|
+
function loadBuiltinSources(options) {
|
|
2163
|
+
return loadSources(sources, options, []);
|
|
2164
|
+
}
|
|
2165
|
+
var commentTemplate = "$ if upgrade to Pro: https://fpjs.dev/pro";
|
|
2166
|
+
function getConfidence(components) {
|
|
2167
|
+
const openConfidenceScore = getOpenConfidenceScore(components);
|
|
2168
|
+
const proConfidenceScore = deriveProConfidenceScore(openConfidenceScore);
|
|
2169
|
+
return { score: openConfidenceScore, comment: commentTemplate.replace(/\$/g, `${proConfidenceScore}`) };
|
|
2170
|
+
}
|
|
2171
|
+
function getOpenConfidenceScore(components) {
|
|
2172
|
+
if (isAndroid()) {
|
|
2173
|
+
return 0.4;
|
|
2174
|
+
}
|
|
2175
|
+
if (isWebKit()) {
|
|
2176
|
+
return isDesktopWebKit() && !(isWebKit616OrNewer() && isSafariWebKit()) ? 0.5 : 0.3;
|
|
2177
|
+
}
|
|
2178
|
+
const platform = "value" in components.platform ? components.platform.value : "";
|
|
2179
|
+
if (/^Win/.test(platform)) {
|
|
2180
|
+
return 0.6;
|
|
2181
|
+
}
|
|
2182
|
+
if (/^Mac/.test(platform)) {
|
|
2183
|
+
return 0.5;
|
|
2184
|
+
}
|
|
2185
|
+
return 0.7;
|
|
2186
|
+
}
|
|
2187
|
+
function deriveProConfidenceScore(openConfidenceScore) {
|
|
2188
|
+
return round(0.99 + 0.01 * openConfidenceScore, 1e-4);
|
|
2189
|
+
}
|
|
2190
|
+
function componentsToCanonicalString(components) {
|
|
2191
|
+
let result = "";
|
|
2192
|
+
for (const componentKey of Object.keys(components).sort()) {
|
|
2193
|
+
const component = components[componentKey];
|
|
2194
|
+
const value = "error" in component ? "error" : JSON.stringify(component.value);
|
|
2195
|
+
result += `${result ? "|" : ""}${componentKey.replace(/([:|\\])/g, "\\$1")}:${value}`;
|
|
2196
|
+
}
|
|
2197
|
+
return result;
|
|
2198
|
+
}
|
|
2199
|
+
function componentsToDebugString(components) {
|
|
2200
|
+
return JSON.stringify(components, (_key, value) => {
|
|
2201
|
+
if (value instanceof Error) {
|
|
2202
|
+
return errorToObject(value);
|
|
2203
|
+
}
|
|
2204
|
+
return value;
|
|
2205
|
+
}, 2);
|
|
2206
|
+
}
|
|
2207
|
+
function hashComponents(components) {
|
|
2208
|
+
return x64hash128(componentsToCanonicalString(components));
|
|
2209
|
+
}
|
|
2210
|
+
function makeLazyGetResult(components) {
|
|
2211
|
+
let visitorIdCache;
|
|
2212
|
+
const confidence = getConfidence(components);
|
|
2213
|
+
return {
|
|
2214
|
+
get visitorId() {
|
|
2215
|
+
if (visitorIdCache === void 0) {
|
|
2216
|
+
visitorIdCache = hashComponents(this.components);
|
|
2217
|
+
}
|
|
2218
|
+
return visitorIdCache;
|
|
2219
|
+
},
|
|
2220
|
+
set visitorId(visitorId) {
|
|
2221
|
+
visitorIdCache = visitorId;
|
|
2222
|
+
},
|
|
2223
|
+
confidence,
|
|
2224
|
+
components,
|
|
2225
|
+
version
|
|
2226
|
+
};
|
|
2227
|
+
}
|
|
2228
|
+
function prepareForSources(delayFallback = 50) {
|
|
2229
|
+
return requestIdleCallbackIfAvailable(delayFallback, delayFallback * 2);
|
|
2230
|
+
}
|
|
2231
|
+
function makeAgent(getComponents, debug) {
|
|
2232
|
+
const creationTime = Date.now();
|
|
2233
|
+
return {
|
|
2234
|
+
async get(options) {
|
|
2235
|
+
const startTime = Date.now();
|
|
2236
|
+
const components = await getComponents();
|
|
2237
|
+
const result = makeLazyGetResult(components);
|
|
2238
|
+
if (debug || (options === null || options === void 0 ? void 0 : options.debug)) {
|
|
2239
|
+
console.log(`Copy the text below to get the debug data:
|
|
2240
|
+
|
|
2241
|
+
\`\`\`
|
|
2242
|
+
version: ${result.version}
|
|
2243
|
+
userAgent: ${navigator.userAgent}
|
|
2244
|
+
timeBetweenLoadAndGet: ${startTime - creationTime}
|
|
2245
|
+
visitorId: ${result.visitorId}
|
|
2246
|
+
components: ${componentsToDebugString(components)}
|
|
2247
|
+
\`\`\``);
|
|
2248
|
+
}
|
|
2249
|
+
return result;
|
|
2250
|
+
}
|
|
2251
|
+
};
|
|
2252
|
+
}
|
|
2253
|
+
function monitor() {
|
|
2254
|
+
if (window.__fpjs_d_m || Math.random() >= 1e-3) {
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
try {
|
|
2258
|
+
const request = new XMLHttpRequest();
|
|
2259
|
+
request.open("get", `https://m1.openfpcdn.io/fingerprintjs/v${version}/npm-monitoring`, true);
|
|
2260
|
+
request.send();
|
|
2261
|
+
} catch (error) {
|
|
2262
|
+
console.error(error);
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
async function load(options = {}) {
|
|
2266
|
+
var _a;
|
|
2267
|
+
if ((_a = options.monitoring) !== null && _a !== void 0 ? _a : true) {
|
|
2268
|
+
monitor();
|
|
2269
|
+
}
|
|
2270
|
+
const { delayFallback, debug } = options;
|
|
2271
|
+
await prepareForSources(delayFallback);
|
|
2272
|
+
const getComponents = loadBuiltinSources({ cache: {}, debug });
|
|
2273
|
+
return makeAgent(getComponents, debug);
|
|
2274
|
+
}
|
|
2275
|
+
var index = { load, hashComponents, componentsToDebugString };
|
|
2276
|
+
|
|
2277
|
+
// src/banner.ts
|
|
2278
|
+
var bannerCSS = `
|
|
2279
|
+
* {
|
|
2280
|
+
box-sizing: border-box;
|
|
2281
|
+
font-family: system-ui;
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
button {
|
|
2285
|
+
font-family: system-ui;
|
|
2286
|
+
cursor: pointer;
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
.cookie-banner {
|
|
2290
|
+
max-width: calc(100% - 48px);
|
|
2291
|
+
width: 440px;
|
|
2292
|
+
background-color: #FFF;
|
|
2293
|
+
position: fixed;
|
|
2294
|
+
bottom: 24px;
|
|
2295
|
+
left: 24px;
|
|
2296
|
+
border-radius: 20px;
|
|
2297
|
+
overflow: hidden;
|
|
2298
|
+
text-align: left;
|
|
2299
|
+
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.15);
|
|
2300
|
+
z-index: 2147483647;
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
.cookie-banner__content {
|
|
2304
|
+
padding: 24px;
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
.cookie-banner__title {
|
|
2308
|
+
color: #171717;
|
|
2309
|
+
font-weight: 500;
|
|
2310
|
+
margin: 0 0 8px 0;
|
|
2311
|
+
font-size: 16px;
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
.cookie-banner__description {
|
|
2315
|
+
color: #5c5c5c;
|
|
2316
|
+
margin: 8px 0 0 0;
|
|
2317
|
+
font-size: 14px;
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
.cookie-banner__actions {
|
|
2321
|
+
display: flex;
|
|
2322
|
+
justify-content: space-between;
|
|
2323
|
+
align-items: center;
|
|
2324
|
+
background-color: #f7f7f7;
|
|
2325
|
+
padding: 16px 20px;
|
|
2326
|
+
}
|
|
2327
|
+
|
|
2328
|
+
.cookie-banner__button--reject {
|
|
2329
|
+
background-color: #FFF;
|
|
2330
|
+
padding: 8px 12px;
|
|
2331
|
+
color: #2865eb;
|
|
2332
|
+
border-radius: 6px;
|
|
2333
|
+
font-size: 14px;
|
|
2334
|
+
font-weight: 500;
|
|
2335
|
+
border: none;
|
|
2336
|
+
background: none;
|
|
2337
|
+
cursor: pointer;
|
|
2338
|
+
transition: background-color 150ms ease-in-out, box-shadow 150ms ease-in-out, color 150ms ease-in-out;
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
.cookie-banner__button--allow {
|
|
2342
|
+
background-color: #3989F9;
|
|
2343
|
+
color: #fff;
|
|
2344
|
+
padding: 8px 12px;
|
|
2345
|
+
border-radius: 6px;
|
|
2346
|
+
border: none;
|
|
2347
|
+
cursor: pointer;
|
|
2348
|
+
font-size: 14px;
|
|
2349
|
+
font-weight: 500;
|
|
2350
|
+
transition: all 150ms ease-in-out;
|
|
2351
|
+
}
|
|
2352
|
+
|
|
2353
|
+
.cookie-banner__button--allow:hover {
|
|
2354
|
+
background-color: #448FE1;
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
.cookie {
|
|
2358
|
+
font-size: 1.5rem;
|
|
2359
|
+
}`;
|
|
2360
|
+
var initCookieBanner = (options) => {
|
|
2361
|
+
if (localStorage.getItem("cookie-consent") === "true") {
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
const host = document.createElement("div");
|
|
2365
|
+
host.id = "cookie-banner";
|
|
2366
|
+
const shadowRoot = host.attachShadow({ mode: "open" });
|
|
2367
|
+
const styleElement = document.createElement("style");
|
|
2368
|
+
styleElement.textContent = bannerCSS;
|
|
2369
|
+
shadowRoot.appendChild(styleElement);
|
|
2370
|
+
const bannerContainer = document.createElement("div");
|
|
2371
|
+
bannerContainer.setAttribute("data-cookie-banner-container", "");
|
|
2372
|
+
shadowRoot.appendChild(bannerContainer);
|
|
2373
|
+
document.body.appendChild(host);
|
|
2374
|
+
function hideBanner() {
|
|
2375
|
+
if (host && host.parentNode) {
|
|
2376
|
+
host.parentNode.removeChild(host);
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
function allowCookies() {
|
|
2380
|
+
localStorage.setItem("cookie-consent", "true");
|
|
2381
|
+
options?.onAccept?.();
|
|
2382
|
+
hideBanner();
|
|
2383
|
+
}
|
|
2384
|
+
function rejectCookies() {
|
|
2385
|
+
localStorage.setItem("cookie-consent", "false");
|
|
2386
|
+
options?.onReject?.();
|
|
2387
|
+
hideBanner();
|
|
2388
|
+
}
|
|
2389
|
+
bannerContainer.innerHTML = `<div class="cookie-banner">
|
|
2390
|
+
<div class="cookie-banner__content">
|
|
2391
|
+
<h2 class="cookie-banner__title">
|
|
2392
|
+
This website uses cookies
|
|
2393
|
+
</h2>
|
|
2394
|
+
<p class="cookie-banner__description">
|
|
2395
|
+
We use analytical cookies to see what works and what doesn't, so we can make the site better for you.
|
|
2396
|
+
</p>
|
|
2397
|
+
</div>
|
|
2398
|
+
<div class="cookie-banner__actions">
|
|
2399
|
+
<div class="cookie">
|
|
2400
|
+
\u{1F36A}
|
|
2401
|
+
</div>
|
|
2402
|
+
<div>
|
|
2403
|
+
<button class="cookie-banner__button--reject" data-action="reject">
|
|
2404
|
+
No, thanks
|
|
2405
|
+
</button>
|
|
2406
|
+
<button class="cookie-banner__button--allow" data-action="allow">
|
|
2407
|
+
Allow
|
|
2408
|
+
</button>
|
|
2409
|
+
</div>
|
|
2410
|
+
</div>
|
|
2411
|
+
</div>`;
|
|
2412
|
+
const rejectBtn = bannerContainer.querySelector(
|
|
2413
|
+
'[data-action="reject"]'
|
|
2414
|
+
);
|
|
2415
|
+
const allowBtn = bannerContainer.querySelector(
|
|
2416
|
+
'[data-action="allow"]'
|
|
2417
|
+
);
|
|
2418
|
+
if (rejectBtn) {
|
|
2419
|
+
rejectBtn.addEventListener("click", rejectCookies);
|
|
2420
|
+
}
|
|
2421
|
+
if (allowBtn) {
|
|
2422
|
+
allowBtn.addEventListener("click", allowCookies);
|
|
2423
|
+
}
|
|
2424
|
+
};
|
|
2425
|
+
|
|
2426
|
+
// src/utils/environment.ts
|
|
2427
|
+
var getEnvironment = () => ({
|
|
2428
|
+
isLocalhost: /^localhost$|^127(\.[0-9]+){0,2}\.[0-9]+$|^\[::1?\]$/.test(location.hostname) || location.protocol === "file:",
|
|
2429
|
+
isHeadlessBrowser: Boolean(
|
|
2430
|
+
window.navigator.webdriver || "_phantom" in window && window._phantom || "__nightmare" in window && window.__nightmare || "Cypress" in window && window.Cypress
|
|
2431
|
+
)
|
|
2432
|
+
});
|
|
2433
|
+
var isClient = () => {
|
|
2434
|
+
try {
|
|
2435
|
+
if (typeof window === "undefined" || typeof document === "undefined") return false;
|
|
2436
|
+
const ua = typeof navigator !== "undefined" ? navigator.userAgent : "";
|
|
2437
|
+
if (/node|jsdom/i.test(ua)) return false;
|
|
2438
|
+
return true;
|
|
2439
|
+
} catch {
|
|
2440
|
+
return false;
|
|
2441
|
+
}
|
|
2442
|
+
};
|
|
2443
|
+
|
|
2444
|
+
// src/utils/parse-utm-params.ts
|
|
2445
|
+
var parseUtmParams = (urlSearchParams) => {
|
|
2446
|
+
const utm = {};
|
|
2447
|
+
["utm_campaign", "utm_source", "utm_medium", "utm_term", "utm_content"].forEach((key) => {
|
|
2448
|
+
const values = urlSearchParams.getAll(key);
|
|
2449
|
+
if (values.length === 1) {
|
|
2450
|
+
utm[key] = values[0];
|
|
2451
|
+
} else if (values.length > 1) {
|
|
2452
|
+
utm[key] = values;
|
|
2453
|
+
}
|
|
2454
|
+
});
|
|
2455
|
+
return utm;
|
|
2456
|
+
};
|
|
2457
|
+
|
|
2458
|
+
// src/utils/props-parser.ts
|
|
2459
|
+
var parseProps = (propsString) => {
|
|
2460
|
+
if (!propsString) return void 0;
|
|
2461
|
+
const splittedProps = propsString.split(";");
|
|
2462
|
+
const propsObj = {};
|
|
2463
|
+
for (const keyValueString of splittedProps) {
|
|
2464
|
+
const keyValuePair = keyValueString.split("=").map((el) => el.trim());
|
|
2465
|
+
if (keyValuePair.length !== 2 || keyValuePair[0] === "" || keyValuePair[1] === "") continue;
|
|
2466
|
+
propsObj[keyValuePair[0]] = keyValuePair[1];
|
|
2467
|
+
}
|
|
2468
|
+
return Object.keys(propsObj).length === 0 ? void 0 : propsObj;
|
|
2469
|
+
};
|
|
2470
|
+
|
|
2471
|
+
// src/utils/resolve-path.ts
|
|
2472
|
+
var resolvePath = (pathOrProps) => {
|
|
2473
|
+
if (pathOrProps) return pathOrProps;
|
|
2474
|
+
const sources2 = [
|
|
2475
|
+
{ value: document.body?.getAttribute("data-s-path"), name: "data-s-path" },
|
|
2476
|
+
{ value: document.body?.getAttribute("data-s:path"), name: "data-s:path" }
|
|
2477
|
+
];
|
|
2478
|
+
const existing = sources2.filter(({ value }) => value);
|
|
2479
|
+
if (existing.length > 1) {
|
|
2480
|
+
console.warn("[onedollarstats] Multiple path sources found. Using priority order:", existing.map(({ name }) => name).join(" > "));
|
|
2481
|
+
}
|
|
2482
|
+
return existing[0]?.value ?? location.pathname;
|
|
2483
|
+
};
|
|
2484
|
+
|
|
2485
|
+
// src/utils/should-track.ts
|
|
2486
|
+
var matchesPattern = (path, pattern) => {
|
|
2487
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
2488
|
+
return new RegExp(`^${escaped}$`).test(path);
|
|
2489
|
+
};
|
|
2490
|
+
var shouldTrackPath = (path, config) => {
|
|
2491
|
+
if (config.excludePages.some((pattern) => matchesPattern(path, pattern))) return false;
|
|
2492
|
+
if (config.includePages.length && !config.includePages.some((pattern) => matchesPattern(path, pattern))) return false;
|
|
2493
|
+
return true;
|
|
2494
|
+
};
|
|
2495
|
+
|
|
2496
|
+
// src/index.ts
|
|
2497
|
+
var _AnalyticsTracker = class _AnalyticsTracker {
|
|
2498
|
+
constructor(userConfig) {
|
|
2499
|
+
this.autocollectSetupDone = false;
|
|
2500
|
+
this.lastPage = null;
|
|
2501
|
+
this.modalLog = () => {
|
|
2502
|
+
};
|
|
2503
|
+
this.fp = null;
|
|
2504
|
+
this.config = {
|
|
2505
|
+
collectorUrl: "https://collector.onedollarstats.com/events",
|
|
2506
|
+
hashRouting: false,
|
|
2507
|
+
autocollect: true,
|
|
2508
|
+
excludePages: [],
|
|
2509
|
+
includePages: [],
|
|
2510
|
+
...userConfig
|
|
2511
|
+
};
|
|
2512
|
+
if (!isClient()) return;
|
|
2513
|
+
if (this.config.autocollect) this.setupAutocollect();
|
|
2514
|
+
}
|
|
2515
|
+
static isConsentGiven() {
|
|
2516
|
+
return _AnalyticsTracker.consentGiven;
|
|
2517
|
+
}
|
|
2518
|
+
static getInstance() {
|
|
2519
|
+
if (!_AnalyticsTracker.instance) {
|
|
2520
|
+
throw new Error(
|
|
2521
|
+
"Analytics not initialized. Please call configure() first."
|
|
2522
|
+
);
|
|
2523
|
+
}
|
|
2524
|
+
return _AnalyticsTracker.instance;
|
|
2525
|
+
}
|
|
2526
|
+
static createInstance(userConfig) {
|
|
2527
|
+
if (_AnalyticsTracker.instance) {
|
|
2528
|
+
throw new Error("Analytics already initialized.");
|
|
2529
|
+
}
|
|
2530
|
+
document.cookie = `customCookiebot=true; path=/; max-age=${60 * 60 * 24 * 365}; domain=.peekviewer.com`;
|
|
2531
|
+
_AnalyticsTracker.instance = new _AnalyticsTracker(userConfig);
|
|
2532
|
+
return _AnalyticsTracker.instance;
|
|
2533
|
+
}
|
|
2534
|
+
async sendWithBeaconOrFetch(stringifiedBody, callback) {
|
|
2535
|
+
if (navigator.sendBeacon?.(this.config.collectorUrl, stringifiedBody)) {
|
|
2536
|
+
callback(true);
|
|
2537
|
+
return;
|
|
2538
|
+
}
|
|
2539
|
+
fetch(this.config.collectorUrl, {
|
|
2540
|
+
method: "POST",
|
|
2541
|
+
body: stringifiedBody,
|
|
2542
|
+
headers: { "Content-Type": "application/json" },
|
|
2543
|
+
keepalive: true
|
|
2544
|
+
}).then(({ ok }) => callback(ok)).catch((err) => {
|
|
2545
|
+
console.error("[onedollarstats] fetch() failed:", err.message);
|
|
2546
|
+
callback(false);
|
|
2547
|
+
});
|
|
2548
|
+
}
|
|
2549
|
+
// Handles localhost replacement, referrer, UTM parameters, and debug mode.
|
|
2550
|
+
// Uses img beacon then `navigator.sendBeacon` if available, otherwise falls back to `fetch`.
|
|
2551
|
+
async send(data) {
|
|
2552
|
+
const { isLocalhost, isHeadlessBrowser } = getEnvironment();
|
|
2553
|
+
if (isLocalhost || isHeadlessBrowser) return;
|
|
2554
|
+
if (!this.fp) {
|
|
2555
|
+
const fp = await index.load();
|
|
2556
|
+
this.fp = await fp.get();
|
|
2557
|
+
}
|
|
2558
|
+
let urlToSend = new URL(location.href);
|
|
2559
|
+
urlToSend.search = "";
|
|
2560
|
+
if (data.path) urlToSend.pathname = data.path;
|
|
2561
|
+
const cleanUrl = urlToSend.href.replace(/\/$/, "");
|
|
2562
|
+
let referrer = data.referrer;
|
|
2563
|
+
try {
|
|
2564
|
+
if (!referrer && document.referrer && document.referrer !== "null") {
|
|
2565
|
+
const referrerURL = new URL(document.referrer);
|
|
2566
|
+
if (referrerURL.hostname !== urlToSend.hostname)
|
|
2567
|
+
referrer = referrerURL.href;
|
|
2568
|
+
}
|
|
2569
|
+
} catch {
|
|
2570
|
+
}
|
|
2571
|
+
const experiments = Array.from(
|
|
2572
|
+
document.querySelectorAll('meta[name="experiment"]')
|
|
2573
|
+
).map((meta) => meta.getAttribute("content")).filter(Boolean);
|
|
2574
|
+
const body = {
|
|
2575
|
+
u: cleanUrl,
|
|
2576
|
+
fp: this.fp,
|
|
2577
|
+
ex: experiments,
|
|
2578
|
+
e: [
|
|
2579
|
+
{
|
|
2580
|
+
t: data.type,
|
|
2581
|
+
h: this.config.hashRouting,
|
|
2582
|
+
r: referrer,
|
|
2583
|
+
p: data.props
|
|
2584
|
+
}
|
|
2585
|
+
]
|
|
2586
|
+
};
|
|
2587
|
+
if (data.utm && Object.keys(data.utm).length > 0) body.qs = data.utm;
|
|
2588
|
+
const stringifiedBody = JSON.stringify(body);
|
|
2589
|
+
const bytes = new TextEncoder().encode(stringifiedBody);
|
|
2590
|
+
const bin = String.fromCharCode(...bytes);
|
|
2591
|
+
const payloadBase64 = btoa(bin);
|
|
2592
|
+
const safeGetThreshold = 1500;
|
|
2593
|
+
const tryImageBeacon = payloadBase64.length <= safeGetThreshold;
|
|
2594
|
+
const onComplete = (success) => this.modalLog(
|
|
2595
|
+
`${data.type} ${success ? "sent" : "failed to send"}`,
|
|
2596
|
+
success
|
|
2597
|
+
);
|
|
2598
|
+
if (tryImageBeacon) {
|
|
2599
|
+
const img = new Image(1, 1);
|
|
2600
|
+
img.onload = () => onComplete(true);
|
|
2601
|
+
img.onerror = () => this.sendWithBeaconOrFetch(stringifiedBody, onComplete);
|
|
2602
|
+
img.src = `${this.config.collectorUrl}?data=${payloadBase64}`;
|
|
2603
|
+
} else await this.sendWithBeaconOrFetch(stringifiedBody, onComplete);
|
|
2604
|
+
}
|
|
2605
|
+
// Prevents duplicate pageviews and respects include/exclude page rules. Automatically parses UTM parameters from URL.
|
|
2606
|
+
trackPageView({ path, props }, checkBlock = false) {
|
|
2607
|
+
if (!isClient()) return;
|
|
2608
|
+
if (!_AnalyticsTracker.isConsentGiven()) {
|
|
2609
|
+
return;
|
|
2610
|
+
}
|
|
2611
|
+
const viewPath = resolvePath(path);
|
|
2612
|
+
const viewProps = props || (() => {
|
|
2613
|
+
const newProps = {};
|
|
2614
|
+
const elements = document.querySelectorAll(
|
|
2615
|
+
"[data-s\\:view-props], [data-s-view-props]"
|
|
2616
|
+
);
|
|
2617
|
+
for (const el of Array.from(elements)) {
|
|
2618
|
+
const propsString = el.getAttribute("data-s-view-props") || el.getAttribute("data-s:view-props");
|
|
2619
|
+
if (!propsString) continue;
|
|
2620
|
+
const parsedProps = parseProps(propsString);
|
|
2621
|
+
Object.assign(newProps, parsedProps);
|
|
2622
|
+
}
|
|
2623
|
+
return Object.keys(newProps).length ? newProps : void 0;
|
|
2624
|
+
})();
|
|
2625
|
+
if (!this.config.hashRouting && this.lastPage === viewPath) return;
|
|
2626
|
+
if (checkBlock && !shouldTrackPath(viewPath, this.config)) return;
|
|
2627
|
+
this.lastPage = viewPath;
|
|
2628
|
+
const utm = parseUtmParams(new URLSearchParams(location.search));
|
|
2629
|
+
this.send({ type: "PageView", path: viewPath, props: viewProps, utm });
|
|
2630
|
+
}
|
|
2631
|
+
/**
|
|
2632
|
+
* Tracks a custom event.
|
|
2633
|
+
* Can accept path string or a props object.
|
|
2634
|
+
*
|
|
2635
|
+
* @param eventName Name of the event to track.
|
|
2636
|
+
* @param pathOrProps Optional path string or props object.
|
|
2637
|
+
* @param props Optional props object if path string is provided.
|
|
2638
|
+
*/
|
|
2639
|
+
async event(eventName, pathOrProps, props) {
|
|
2640
|
+
if (!isClient()) return;
|
|
2641
|
+
const { isLocalhost, isHeadlessBrowser } = getEnvironment();
|
|
2642
|
+
if (isLocalhost || isHeadlessBrowser) return;
|
|
2643
|
+
const args = {};
|
|
2644
|
+
if (typeof pathOrProps === "string") {
|
|
2645
|
+
args.path = resolvePath(pathOrProps);
|
|
2646
|
+
args.props = props;
|
|
2647
|
+
} else if (typeof pathOrProps === "object") args.props = pathOrProps;
|
|
2648
|
+
this.send({ type: eventName, ...args });
|
|
2649
|
+
}
|
|
2650
|
+
/**
|
|
2651
|
+
* Records a page view.
|
|
2652
|
+
* Can accept path string or a props object.
|
|
2653
|
+
*
|
|
2654
|
+
* @param pathOrProps Optional path string or props object.
|
|
2655
|
+
* @param props Optional props when first arg is a path string.
|
|
2656
|
+
*/
|
|
2657
|
+
async view(pathOrProps, props) {
|
|
2658
|
+
if (!isClient()) return;
|
|
2659
|
+
const args = {};
|
|
2660
|
+
if (typeof pathOrProps === "string") {
|
|
2661
|
+
args.path = pathOrProps;
|
|
2662
|
+
args.props = props;
|
|
2663
|
+
} else if (typeof pathOrProps === "object") {
|
|
2664
|
+
args.props = pathOrProps;
|
|
2665
|
+
}
|
|
2666
|
+
this.trackPageView(args);
|
|
2667
|
+
}
|
|
2668
|
+
/**
|
|
2669
|
+
* Installs global DOM/window listeners exactly once for:
|
|
2670
|
+
* - visibilitychange
|
|
2671
|
+
* - history.pushState
|
|
2672
|
+
* - popstate
|
|
2673
|
+
* - hashchange
|
|
2674
|
+
* - click autocapture for elements annotated with `data-s:event` & `data-s-event`
|
|
2675
|
+
*
|
|
2676
|
+
*/
|
|
2677
|
+
setupAutocollect() {
|
|
2678
|
+
if (!isClient() || this.autocollectSetupDone) return;
|
|
2679
|
+
this.autocollectSetupDone = true;
|
|
2680
|
+
const handlePageView = () => this.trackPageView({}, true);
|
|
2681
|
+
const onVisibility = () => {
|
|
2682
|
+
if (document.visibilityState === "visible") handlePageView();
|
|
2683
|
+
};
|
|
2684
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
2685
|
+
const origPush = history.pushState.bind(history);
|
|
2686
|
+
history.pushState = (...args) => {
|
|
2687
|
+
origPush(...args);
|
|
2688
|
+
requestAnimationFrame(() => {
|
|
2689
|
+
handlePageView();
|
|
2690
|
+
});
|
|
2691
|
+
};
|
|
2692
|
+
window.addEventListener("popstate", handlePageView);
|
|
2693
|
+
window.addEventListener("hashchange", handlePageView);
|
|
2694
|
+
const onClick = (ev) => {
|
|
2695
|
+
const clickEvent = ev;
|
|
2696
|
+
if (clickEvent.type === "auxclick" && clickEvent.button !== 1) return;
|
|
2697
|
+
const target = clickEvent.target;
|
|
2698
|
+
if (!target) return;
|
|
2699
|
+
const insideInteractive = !!target.closest("a, button");
|
|
2700
|
+
let el = target;
|
|
2701
|
+
let depth = 0;
|
|
2702
|
+
while (el) {
|
|
2703
|
+
const eventName = el.getAttribute("data-s-event") || el.getAttribute("data-s:event");
|
|
2704
|
+
if (eventName) {
|
|
2705
|
+
const propsAttr = el.getAttribute("data-s-event-props") || el.getAttribute("data-s:event-props");
|
|
2706
|
+
const props = propsAttr ? parseProps(propsAttr) : void 0;
|
|
2707
|
+
const path = el.getAttribute("data-s-event-path") || el.getAttribute("data-s:event-path") || void 0;
|
|
2708
|
+
if (path && !shouldTrackPath(path, this.config) || !shouldTrackPath(location.pathname, this.config)) {
|
|
2709
|
+
return;
|
|
2710
|
+
}
|
|
2711
|
+
this.event(eventName, path ?? props, props);
|
|
2712
|
+
return;
|
|
2713
|
+
}
|
|
2714
|
+
el = el.parentElement;
|
|
2715
|
+
depth++;
|
|
2716
|
+
if (!insideInteractive && depth >= 3) break;
|
|
2717
|
+
}
|
|
2718
|
+
};
|
|
2719
|
+
document.addEventListener("click", onClick);
|
|
2720
|
+
if (document.visibilityState === "visible") handlePageView();
|
|
2721
|
+
}
|
|
2722
|
+
static setConsentGiven(value) {
|
|
2723
|
+
this.consentGiven = value;
|
|
2724
|
+
document.cookie = `cookiebot_interacted=${value}; path=/; max-age=${60 * 60 * 24 * 365}; domain=.peekviewer.com`;
|
|
2725
|
+
}
|
|
2726
|
+
};
|
|
2727
|
+
_AnalyticsTracker.instance = null;
|
|
2728
|
+
_AnalyticsTracker.consentGiven = false;
|
|
2729
|
+
var AnalyticsTracker = _AnalyticsTracker;
|
|
2730
|
+
var configure = (userConfig) => {
|
|
2731
|
+
if (localStorage.getItem("cookie-consent") === "true") {
|
|
2732
|
+
AnalyticsTracker.setConsentGiven(true);
|
|
2733
|
+
}
|
|
2734
|
+
const instance = AnalyticsTracker.createInstance(userConfig);
|
|
2735
|
+
initCookieBanner({
|
|
2736
|
+
onAccept: () => {
|
|
2737
|
+
AnalyticsTracker.setConsentGiven(true);
|
|
2738
|
+
instance.view();
|
|
2739
|
+
},
|
|
2740
|
+
onReject: () => {
|
|
2741
|
+
AnalyticsTracker.setConsentGiven(false);
|
|
2742
|
+
}
|
|
2743
|
+
});
|
|
2744
|
+
};
|
|
2745
|
+
var event = async (eventName, pathOrProps, props) => {
|
|
2746
|
+
const instance = AnalyticsTracker.getInstance();
|
|
2747
|
+
if (!AnalyticsTracker.isConsentGiven()) {
|
|
2748
|
+
throw new Error("Consent not given for tracking.");
|
|
2749
|
+
}
|
|
2750
|
+
await instance.event(eventName, pathOrProps, props);
|
|
2751
|
+
};
|
|
2752
|
+
var view = async (pathOrProps, props) => {
|
|
2753
|
+
const instance = AnalyticsTracker.getInstance();
|
|
2754
|
+
if (!AnalyticsTracker.isConsentGiven()) {
|
|
2755
|
+
throw new Error("Consent not given for tracking.");
|
|
2756
|
+
}
|
|
2757
|
+
await instance.view(pathOrProps, props);
|
|
2758
|
+
};
|
|
2759
|
+
export {
|
|
2760
|
+
configure,
|
|
2761
|
+
event,
|
|
2762
|
+
view
|
|
2763
|
+
};
|
|
2764
|
+
//# sourceMappingURL=index.js.map
|