jumpy-lion 0.0.32 → 0.0.34
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/dist/browser-controller.d.ts +2 -2
- package/dist/browser-controller.d.ts.map +1 -1
- package/dist/browser-controller.js +59 -21
- package/dist/browser-controller.js.map +1 -1
- package/dist/browser-plugin.d.ts +22 -0
- package/dist/browser-plugin.d.ts.map +1 -1
- package/dist/browser-plugin.js +118 -27
- package/dist/browser-plugin.js.map +1 -1
- package/dist/browser-process/browser.d.ts +15 -0
- package/dist/browser-process/browser.d.ts.map +1 -1
- package/dist/browser-process/browser.js +38 -3
- package/dist/browser-process/browser.js.map +1 -1
- package/dist/browser-process/process.d.ts +9 -0
- package/dist/browser-process/process.d.ts.map +1 -1
- package/dist/browser-process/process.js +99 -5
- package/dist/browser-process/process.js.map +1 -1
- package/dist/crawler.d.ts +18 -2
- package/dist/crawler.d.ts.map +1 -1
- package/dist/crawler.js +4 -5
- package/dist/crawler.js.map +1 -1
- package/dist/fingerprinting/anti-webgpu/background.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/background.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/background.js +6 -0
- package/dist/fingerprinting/anti-webgpu/background.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.js +50 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/inject.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.js +179 -0
- package/dist/fingerprinting/anti-webgpu/data/content_script/page_context/inject.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.js +95 -0
- package/dist/fingerprinting/anti-webgpu/data/popup/popup.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.js +255 -0
- package/dist/fingerprinting/anti-webgpu/lib/chrome.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.js +87 -0
- package/dist/fingerprinting/anti-webgpu/lib/common.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.js +13 -0
- package/dist/fingerprinting/anti-webgpu/lib/config.js.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.d.ts +2 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.d.ts.map +1 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.js +109 -0
- package/dist/fingerprinting/anti-webgpu/lib/runtime.js.map +1 -0
- package/dist/fingerprinting/fingerprint-injector.d.ts +85 -1
- package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +188 -90
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js +87 -0
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js +95 -0
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js +96 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts +7 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js +219 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +19 -0
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/index.js +19 -0
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +262 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts +7 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js +103 -0
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js +228 -0
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts +20 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +227 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +84 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +440 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +95 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts +12 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +167 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js +205 -0
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts +6 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +96 -0
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/page.d.ts +1 -0
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +42 -1
- package/dist/page.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locale Spoofing
|
|
3
|
+
* Ensures consistent Windows-style locale formatting for dates, numbers, and currencies
|
|
4
|
+
*/
|
|
5
|
+
export const createLocaleSpoofingScript = () => {
|
|
6
|
+
return `
|
|
7
|
+
(() => {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// Locale Spoofing for 2025 - Windows-consistent formatting
|
|
11
|
+
const spoofLocale = () => {
|
|
12
|
+
// Platform-specific locale configurations
|
|
13
|
+
const platform = navigator.platform || 'Win32';
|
|
14
|
+
|
|
15
|
+
// Windows-specific locale settings
|
|
16
|
+
const windowsLocaleConfig = {
|
|
17
|
+
dateFormat: {
|
|
18
|
+
weekday: 'long',
|
|
19
|
+
year: 'numeric',
|
|
20
|
+
month: 'long',
|
|
21
|
+
day: 'numeric'
|
|
22
|
+
},
|
|
23
|
+
timeFormat: {
|
|
24
|
+
hour: '2-digit',
|
|
25
|
+
minute: '2-digit',
|
|
26
|
+
second: '2-digit',
|
|
27
|
+
hour12: true
|
|
28
|
+
},
|
|
29
|
+
numberFormat: {
|
|
30
|
+
minimumFractionDigits: 0,
|
|
31
|
+
maximumFractionDigits: 3,
|
|
32
|
+
useGrouping: true
|
|
33
|
+
},
|
|
34
|
+
currencyFormat: {
|
|
35
|
+
style: 'currency',
|
|
36
|
+
currency: 'USD',
|
|
37
|
+
currencyDisplay: 'symbol'
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Override Intl.DateTimeFormat to use Windows-consistent formatting
|
|
42
|
+
const OriginalDateTimeFormat = Intl.DateTimeFormat;
|
|
43
|
+
Intl.DateTimeFormat = function(locales, options) {
|
|
44
|
+
// Ensure Windows-like date formatting regardless of actual locale
|
|
45
|
+
const windowsOptions = Object.assign({}, windowsLocaleConfig.dateFormat, options);
|
|
46
|
+
|
|
47
|
+
// Force specific Windows locale patterns
|
|
48
|
+
if (platform === 'Win32' || !platform.includes('Linux')) {
|
|
49
|
+
if (!options || !options.timeZone) {
|
|
50
|
+
// Use common Windows timezone handling
|
|
51
|
+
windowsOptions.timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const formatter = new OriginalDateTimeFormat(locales, windowsOptions);
|
|
56
|
+
|
|
57
|
+
// Override format method to ensure Windows-style output
|
|
58
|
+
const originalFormat = formatter.format;
|
|
59
|
+
formatter.format = function(date) {
|
|
60
|
+
let result = originalFormat.call(this, date);
|
|
61
|
+
|
|
62
|
+
// Apply Windows-specific formatting adjustments
|
|
63
|
+
if (platform === 'Win32') {
|
|
64
|
+
// Windows often uses specific date separators and formats
|
|
65
|
+
result = result.replace(/\\b(\\d{1,2})\\/(\\d{1,2})\\/(\\d{4})\\b/, '$1/$2/$3');
|
|
66
|
+
result = result.replace(/\\b(\\d{4})-(\\d{2})-(\\d{2})\\b/, '$2/$3/$1');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return result;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
return formatter;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Override Intl.NumberFormat for Windows-consistent number formatting
|
|
76
|
+
const OriginalNumberFormat = Intl.NumberFormat;
|
|
77
|
+
Intl.NumberFormat = function(locales, options) {
|
|
78
|
+
const windowsOptions = Object.assign({}, windowsLocaleConfig.numberFormat, options);
|
|
79
|
+
|
|
80
|
+
// Windows-specific number formatting
|
|
81
|
+
if (platform === 'Win32') {
|
|
82
|
+
windowsOptions.useGrouping = true;
|
|
83
|
+
if (options && options.style === 'currency') {
|
|
84
|
+
Object.assign(windowsOptions, windowsLocaleConfig.currencyFormat, options);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const formatter = new OriginalNumberFormat(locales, windowsOptions);
|
|
89
|
+
|
|
90
|
+
// Override format method for Windows-style numbers
|
|
91
|
+
const originalFormat = formatter.format;
|
|
92
|
+
formatter.format = function(number) {
|
|
93
|
+
let result = originalFormat.call(this, number);
|
|
94
|
+
|
|
95
|
+
// Windows-specific formatting adjustments
|
|
96
|
+
if (platform === 'Win32') {
|
|
97
|
+
// Ensure Windows-style thousand separators and decimal points
|
|
98
|
+
if (typeof number === 'number' && Math.abs(number) >= 1000) {
|
|
99
|
+
result = result.replace(/\\s/g, ','); // Replace spaces with commas for thousands
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return result;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
return formatter;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// Override Date.prototype methods for consistent formatting
|
|
110
|
+
const originalToLocaleString = Date.prototype.toLocaleString;
|
|
111
|
+
const originalToLocaleDateString = Date.prototype.toLocaleDateString;
|
|
112
|
+
const originalToLocaleTimeString = Date.prototype.toLocaleTimeString;
|
|
113
|
+
|
|
114
|
+
Date.prototype.toLocaleString = function(locales, options) {
|
|
115
|
+
const windowsOptions = Object.assign({}, windowsLocaleConfig.dateFormat, windowsLocaleConfig.timeFormat, options);
|
|
116
|
+
return originalToLocaleString.call(this, locales || 'en-US', windowsOptions);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
Date.prototype.toLocaleDateString = function(locales, options) {
|
|
120
|
+
const windowsOptions = Object.assign({}, windowsLocaleConfig.dateFormat, options);
|
|
121
|
+
return originalToLocaleDateString.call(this, locales || 'en-US', windowsOptions);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
Date.prototype.toLocaleTimeString = function(locales, options) {
|
|
125
|
+
const windowsOptions = Object.assign({}, windowsLocaleConfig.timeFormat, options);
|
|
126
|
+
return originalToLocaleTimeString.call(this, locales || 'en-US', windowsOptions);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// Override Number.prototype methods for consistent formatting
|
|
130
|
+
const originalToLocaleString = Number.prototype.toLocaleString;
|
|
131
|
+
Number.prototype.toLocaleString = function(locales, options) {
|
|
132
|
+
let windowsOptions = Object.assign({}, windowsLocaleConfig.numberFormat, options);
|
|
133
|
+
|
|
134
|
+
if (options && options.style === 'currency') {
|
|
135
|
+
windowsOptions = Object.assign({}, windowsLocaleConfig.currencyFormat, options);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return originalToLocaleString.call(this, locales || 'en-US', windowsOptions);
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
// Spoof timezone-related methods for consistency
|
|
142
|
+
const originalGetTimezoneOffset = Date.prototype.getTimezoneOffset;
|
|
143
|
+
Date.prototype.getTimezoneOffset = function() {
|
|
144
|
+
const offset = originalGetTimezoneOffset.call(this);
|
|
145
|
+
|
|
146
|
+
// Ensure timezone offset is reported consistently
|
|
147
|
+
// Windows tends to handle DST slightly differently
|
|
148
|
+
if (platform === 'Win32') {
|
|
149
|
+
const now = new Date();
|
|
150
|
+
const winterOffset = new Date(now.getFullYear(), 0, 1).getTimezoneOffset();
|
|
151
|
+
const summerOffset = new Date(now.getFullYear(), 6, 1).getTimezoneOffset();
|
|
152
|
+
|
|
153
|
+
// Apply Windows-style DST calculation if needed
|
|
154
|
+
if (winterOffset !== summerOffset) {
|
|
155
|
+
const isDST = offset === Math.min(winterOffset, summerOffset);
|
|
156
|
+
return isDST ? summerOffset : winterOffset;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return offset;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Override Intl.Collator for Windows-consistent string comparison
|
|
164
|
+
if (typeof Intl.Collator !== 'undefined') {
|
|
165
|
+
const OriginalCollator = Intl.Collator;
|
|
166
|
+
Intl.Collator = function(locales, options) {
|
|
167
|
+
const windowsOptions = Object.assign({
|
|
168
|
+
sensitivity: 'base',
|
|
169
|
+
usage: 'sort',
|
|
170
|
+
caseFirst: 'upper' // Windows typically sorts uppercase first
|
|
171
|
+
}, options);
|
|
172
|
+
|
|
173
|
+
return new OriginalCollator(locales, windowsOptions);
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Override Intl.PluralRules for consistency
|
|
178
|
+
if (typeof Intl.PluralRules !== 'undefined') {
|
|
179
|
+
const OriginalPluralRules = Intl.PluralRules;
|
|
180
|
+
Intl.PluralRules = function(locales, options) {
|
|
181
|
+
return new OriginalPluralRules(locales || 'en-US', options);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Override Intl.RelativeTimeFormat if available
|
|
186
|
+
if (typeof Intl.RelativeTimeFormat !== 'undefined') {
|
|
187
|
+
const OriginalRelativeTimeFormat = Intl.RelativeTimeFormat;
|
|
188
|
+
Intl.RelativeTimeFormat = function(locales, options) {
|
|
189
|
+
const windowsOptions = Object.assign({
|
|
190
|
+
style: 'long',
|
|
191
|
+
numeric: 'auto'
|
|
192
|
+
}, options);
|
|
193
|
+
|
|
194
|
+
return new OriginalRelativeTimeFormat(locales || 'en-US', windowsOptions);
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Spoof locale-specific string methods
|
|
199
|
+
const originalLocaleCompare = String.prototype.localeCompare;
|
|
200
|
+
String.prototype.localeCompare = function(compareString, locales, options) {
|
|
201
|
+
const windowsOptions = Object.assign({
|
|
202
|
+
sensitivity: 'base',
|
|
203
|
+
caseFirst: 'upper'
|
|
204
|
+
}, options);
|
|
205
|
+
|
|
206
|
+
return originalLocaleCompare.call(this, compareString, locales || 'en-US', windowsOptions);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Override console time formatting to be Windows-consistent
|
|
210
|
+
const originalConsoleTime = console.time;
|
|
211
|
+
const originalConsoleTimeEnd = console.timeEnd;
|
|
212
|
+
const originalConsoleTimeLog = console.timeLog;
|
|
213
|
+
|
|
214
|
+
if (originalConsoleTime) {
|
|
215
|
+
console.time = function(label) {
|
|
216
|
+
// Windows console tends to use specific time formatting
|
|
217
|
+
return originalConsoleTime.call(this, label);
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (originalConsoleTimeEnd) {
|
|
222
|
+
console.timeEnd = function(label) {
|
|
223
|
+
return originalConsoleTimeEnd.call(this, label);
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (originalConsoleTimeLog) {
|
|
228
|
+
console.timeLog = function(label, ...data) {
|
|
229
|
+
return originalConsoleTimeLog.call(this, label, ...data);
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Ensure consistent navigator.language reporting
|
|
234
|
+
if (navigator.language) {
|
|
235
|
+
Object.defineProperty(navigator, 'language', {
|
|
236
|
+
get: function() {
|
|
237
|
+
// Return Windows-common locale
|
|
238
|
+
return platform === 'Win32' ? 'en-US' : navigator.language;
|
|
239
|
+
},
|
|
240
|
+
configurable: false
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (navigator.languages) {
|
|
245
|
+
Object.defineProperty(navigator, 'languages', {
|
|
246
|
+
get: function() {
|
|
247
|
+
// Return Windows-typical language array
|
|
248
|
+
if (platform === 'Win32') {
|
|
249
|
+
return ['en-US', 'en'];
|
|
250
|
+
}
|
|
251
|
+
return navigator.languages;
|
|
252
|
+
},
|
|
253
|
+
configurable: false
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
spoofLocale();
|
|
259
|
+
})();
|
|
260
|
+
`;
|
|
261
|
+
};
|
|
262
|
+
//# sourceMappingURL=locale-spoofing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/locale-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAW,EAAE;IACnD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8PV,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mouse Movement Humanization
|
|
3
|
+
* Generates bezier curve movements instead of straight lines
|
|
4
|
+
* Includes automatic human-like interactions after page load
|
|
5
|
+
*/
|
|
6
|
+
export declare const setupMouseMovementHumanization: (client: any) => Promise<void>;
|
|
7
|
+
//# sourceMappingURL=mouse-humanization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mouse-humanization.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/mouse-humanization.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,8BAA8B,WAAkB,GAAG,KAAG,OAAO,CAAC,IAAI,CAgG9E,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mouse Movement Humanization
|
|
3
|
+
* Generates bezier curve movements instead of straight lines
|
|
4
|
+
* Includes automatic human-like interactions after page load
|
|
5
|
+
*/
|
|
6
|
+
export const setupMouseMovementHumanization = async (client) => {
|
|
7
|
+
// Override CDP Input domain to add human-like variations
|
|
8
|
+
await client.send('Runtime.evaluate', {
|
|
9
|
+
expression: `
|
|
10
|
+
(() => {
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
// Store original mouse position
|
|
14
|
+
let lastX = 0;
|
|
15
|
+
let lastY = 0;
|
|
16
|
+
|
|
17
|
+
// Add bezier curve movement simulation
|
|
18
|
+
window.__humanizeMouseMovement = (fromX, fromY, toX, toY) => {
|
|
19
|
+
const steps = 20 + Math.floor(Math.random() * 10);
|
|
20
|
+
const points = [];
|
|
21
|
+
|
|
22
|
+
// Generate control points for bezier curve
|
|
23
|
+
const cp1x = fromX + (toX - fromX) * 0.25 + (Math.random() - 0.5) * 50;
|
|
24
|
+
const cp1y = fromY + (toY - fromY) * 0.25 + (Math.random() - 0.5) * 50;
|
|
25
|
+
const cp2x = fromX + (toX - fromX) * 0.75 + (Math.random() - 0.5) * 50;
|
|
26
|
+
const cp2y = fromY + (toY - fromY) * 0.75 + (Math.random() - 0.5) * 50;
|
|
27
|
+
|
|
28
|
+
// Calculate bezier curve points
|
|
29
|
+
for (let i = 0; i <= steps; i++) {
|
|
30
|
+
const t = i / steps;
|
|
31
|
+
const t2 = t * t;
|
|
32
|
+
const t3 = t2 * t;
|
|
33
|
+
const mt = 1 - t;
|
|
34
|
+
const mt2 = mt * mt;
|
|
35
|
+
const mt3 = mt2 * mt;
|
|
36
|
+
|
|
37
|
+
const x = mt3 * fromX + 3 * mt2 * t * cp1x + 3 * mt * t2 * cp2x + t3 * toX;
|
|
38
|
+
const y = mt3 * fromY + 3 * mt2 * t * cp1y + 3 * mt * t2 * cp2y + t3 * toY;
|
|
39
|
+
|
|
40
|
+
points.push({ x: Math.round(x), y: Math.round(y) });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return points;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// Add automatic human-like behavior after page load
|
|
47
|
+
const simulateHumanBehavior = () => {
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
// Random mouse movement
|
|
50
|
+
const startX = 100 + Math.random() * 200;
|
|
51
|
+
const startY = 100 + Math.random() * 200;
|
|
52
|
+
const endX = 300 + Math.random() * 400;
|
|
53
|
+
const endY = 200 + Math.random() * 300;
|
|
54
|
+
|
|
55
|
+
// Simulate mouse movement event
|
|
56
|
+
const moveEvent = new MouseEvent('mousemove', {
|
|
57
|
+
clientX: startX,
|
|
58
|
+
clientY: startY,
|
|
59
|
+
bubbles: true,
|
|
60
|
+
cancelable: true
|
|
61
|
+
});
|
|
62
|
+
document.dispatchEvent(moveEvent);
|
|
63
|
+
|
|
64
|
+
// Small scroll to simulate user reading
|
|
65
|
+
setTimeout(() => {
|
|
66
|
+
const scrollAmount = 100 + Math.random() * 200;
|
|
67
|
+
window.scrollBy(0, scrollAmount);
|
|
68
|
+
|
|
69
|
+
// Set storage continuity marker
|
|
70
|
+
try {
|
|
71
|
+
const visitHash = btoa(window.location.hostname + Date.now()).substring(0, 16);
|
|
72
|
+
localStorage.setItem('g2_visit', visitHash);
|
|
73
|
+
sessionStorage.setItem('cdp_human_interaction', Date.now().toString());
|
|
74
|
+
} catch (e) {
|
|
75
|
+
// Storage might be disabled
|
|
76
|
+
}
|
|
77
|
+
}, 500 + Math.random() * 1000);
|
|
78
|
+
|
|
79
|
+
}, 1000 + Math.random() * 2000); // 1-3 seconds after load
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// Trigger human behavior on DOMContentLoaded
|
|
83
|
+
if (document.readyState === 'loading') {
|
|
84
|
+
document.addEventListener('DOMContentLoaded', simulateHumanBehavior);
|
|
85
|
+
} else {
|
|
86
|
+
simulateHumanBehavior();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Also add storage continuity for returning visitors
|
|
90
|
+
window.addEventListener('beforeunload', () => {
|
|
91
|
+
try {
|
|
92
|
+
const currentVisit = localStorage.getItem('g2_visit');
|
|
93
|
+
if (currentVisit) {
|
|
94
|
+
localStorage.setItem('g2_last_visit', currentVisit);
|
|
95
|
+
}
|
|
96
|
+
} catch (e) {
|
|
97
|
+
// Storage might be disabled
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
})();`,
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=mouse-humanization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mouse-humanization.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/mouse-humanization.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,8BAA8B,GAAG,KAAK,EAAE,MAAW,EAAiB,EAAE;IAC/E,yDAAyD;IACzD,MAAM,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE;QAClC,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA2Fd;KACD,CAAC,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/performance-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,+BAA+B,QAAO,MA8NlD,CAAC"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Spoofing
|
|
3
|
+
* Adjusts timing and memory characteristics to match Windows systems
|
|
4
|
+
*/
|
|
5
|
+
export const createPerformanceSpoofingScript = () => {
|
|
6
|
+
return `
|
|
7
|
+
(() => {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
// Performance Spoofing for 2025 - Windows-like characteristics
|
|
11
|
+
const spoofPerformance = () => {
|
|
12
|
+
// Store original methods
|
|
13
|
+
const originalNow = performance.now;
|
|
14
|
+
const originalGetEntries = performance.getEntries;
|
|
15
|
+
const originalGetEntriesByType = performance.getEntriesByType;
|
|
16
|
+
const originalGetEntriesByName = performance.getEntriesByName;
|
|
17
|
+
|
|
18
|
+
// Platform-specific timing characteristics
|
|
19
|
+
const platform = navigator.platform || 'Win32';
|
|
20
|
+
let timingOffset = 0;
|
|
21
|
+
let baseTime = originalNow.call(performance);
|
|
22
|
+
|
|
23
|
+
// Windows tends to have slightly different timing precision
|
|
24
|
+
const timingConfig = {
|
|
25
|
+
'Win32': {
|
|
26
|
+
precision: 0.1, // Windows has 0.1ms precision in many cases
|
|
27
|
+
jitter: 0.05, // Small random variation
|
|
28
|
+
baseOffset: 0 // No offset needed
|
|
29
|
+
},
|
|
30
|
+
'MacIntel': {
|
|
31
|
+
precision: 0.1,
|
|
32
|
+
jitter: 0.03,
|
|
33
|
+
baseOffset: 1.2
|
|
34
|
+
},
|
|
35
|
+
'Linux x86_64': {
|
|
36
|
+
precision: 0.001,
|
|
37
|
+
jitter: 0.02,
|
|
38
|
+
baseOffset: 0.8
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const config = timingConfig[platform] || timingConfig['Win32'];
|
|
43
|
+
|
|
44
|
+
// Spoof performance.now() with Windows-like characteristics
|
|
45
|
+
performance.now = function() {
|
|
46
|
+
const realTime = originalNow.call(performance) - baseTime;
|
|
47
|
+
const adjustedTime = realTime * (1 + config.baseOffset / 100);
|
|
48
|
+
|
|
49
|
+
// Add Windows-like timing jitter and precision
|
|
50
|
+
const jitter = (Math.random() - 0.5) * config.jitter;
|
|
51
|
+
const timeWithJitter = adjustedTime + jitter;
|
|
52
|
+
|
|
53
|
+
// Round to Windows-like precision
|
|
54
|
+
const rounded = Math.round(timeWithJitter / config.precision) * config.precision;
|
|
55
|
+
|
|
56
|
+
return baseTime + rounded;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Spoof memory information to look like Windows
|
|
60
|
+
if (performance.memory) {
|
|
61
|
+
// Windows Chrome typically reports different memory values
|
|
62
|
+
const memoryConfig = {
|
|
63
|
+
'Win32': {
|
|
64
|
+
usedJSHeapSize: { min: 25000000, variance: 15000000 },
|
|
65
|
+
totalJSHeapSize: { min: 45000000, variance: 25000000 },
|
|
66
|
+
jsHeapSizeLimit: 2172649472 // Typical Windows limit
|
|
67
|
+
},
|
|
68
|
+
'MacIntel': {
|
|
69
|
+
usedJSHeapSize: { min: 20000000, variance: 12000000 },
|
|
70
|
+
totalJSHeapSize: { min: 40000000, variance: 20000000 },
|
|
71
|
+
jsHeapSizeLimit: 4294705152 // Mac typically has higher limits
|
|
72
|
+
},
|
|
73
|
+
'Linux x86_64': {
|
|
74
|
+
usedJSHeapSize: { min: 18000000, variance: 10000000 },
|
|
75
|
+
totalJSHeapSize: { min: 35000000, variance: 18000000 },
|
|
76
|
+
jsHeapSizeLimit: 2147483648 // Linux varies more
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const memConfig = memoryConfig[platform] || memoryConfig['Win32'];
|
|
81
|
+
|
|
82
|
+
// Generate consistent but realistic memory values
|
|
83
|
+
const seed = navigator.userAgent.length + (navigator.platform || '').length;
|
|
84
|
+
const pseudoRandom = (seed * 9301 + 49297) % 233280 / 233280;
|
|
85
|
+
|
|
86
|
+
const fakeMemory = {
|
|
87
|
+
usedJSHeapSize: Math.floor(memConfig.usedJSHeapSize.min +
|
|
88
|
+
pseudoRandom * memConfig.usedJSHeapSize.variance),
|
|
89
|
+
totalJSHeapSize: Math.floor(memConfig.totalJSHeapSize.min +
|
|
90
|
+
pseudoRandom * memConfig.totalJSHeapSize.variance),
|
|
91
|
+
jsHeapSizeLimit: memConfig.jsHeapSizeLimit
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Ensure logical consistency
|
|
95
|
+
if (fakeMemory.usedJSHeapSize > fakeMemory.totalJSHeapSize) {
|
|
96
|
+
fakeMemory.totalJSHeapSize = fakeMemory.usedJSHeapSize + 5000000;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Object.defineProperty(performance, 'memory', {
|
|
100
|
+
value: fakeMemory,
|
|
101
|
+
writable: false,
|
|
102
|
+
configurable: true
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Spoof navigation timing to appear more like Windows
|
|
107
|
+
if (performance.navigation) {
|
|
108
|
+
Object.defineProperty(performance.navigation, 'type', {
|
|
109
|
+
value: 0, // TYPE_NAVIGATE - most common on Windows
|
|
110
|
+
writable: false
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
Object.defineProperty(performance.navigation, 'redirectCount', {
|
|
114
|
+
value: 0,
|
|
115
|
+
writable: false
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Spoof timing entries to have Windows-like characteristics
|
|
120
|
+
performance.getEntries = function() {
|
|
121
|
+
const entries = originalGetEntries.call(this);
|
|
122
|
+
return entries.map(entry => spoofTimingEntry(entry));
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
performance.getEntriesByType = function(type) {
|
|
126
|
+
const entries = originalGetEntriesByType.call(this, type);
|
|
127
|
+
return entries.map(entry => spoofTimingEntry(entry));
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
performance.getEntriesByName = function(name, type) {
|
|
131
|
+
const entries = originalGetEntriesByName.call(this, name, type);
|
|
132
|
+
return entries.map(entry => spoofTimingEntry(entry));
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
function spoofTimingEntry(entry) {
|
|
136
|
+
if (!entry) return entry;
|
|
137
|
+
|
|
138
|
+
// Create a copy of the entry with adjusted timings
|
|
139
|
+
const spoofedEntry = Object.assign({}, entry);
|
|
140
|
+
|
|
141
|
+
// Adjust timing values to be more Windows-like
|
|
142
|
+
const timingProps = [
|
|
143
|
+
'startTime', 'duration', 'fetchStart', 'domainLookupStart',
|
|
144
|
+
'domainLookupEnd', 'connectStart', 'connectEnd', 'requestStart',
|
|
145
|
+
'responseStart', 'responseEnd', 'domLoading', 'domInteractive',
|
|
146
|
+
'domContentLoadedEventStart', 'domContentLoadedEventEnd',
|
|
147
|
+
'domComplete', 'loadEventStart', 'loadEventEnd'
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
timingProps.forEach(prop => {
|
|
151
|
+
if (typeof spoofedEntry[prop] === 'number' && spoofedEntry[prop] > 0) {
|
|
152
|
+
// Apply Windows-like timing adjustments
|
|
153
|
+
const adjustment = 1 + (config.baseOffset / 100) +
|
|
154
|
+
(Math.random() - 0.5) * config.jitter / 10;
|
|
155
|
+
spoofedEntry[prop] = Math.round(spoofedEntry[prop] * adjustment / config.precision) * config.precision;
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return spoofedEntry;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Spoof requestIdleCallback timing (if available)
|
|
163
|
+
if ('requestIdleCallback' in window) {
|
|
164
|
+
const originalRequestIdleCallback = window.requestIdleCallback;
|
|
165
|
+
window.requestIdleCallback = function(callback, options) {
|
|
166
|
+
// Windows systems typically have different idle characteristics
|
|
167
|
+
const windowsOptions = Object.assign({}, options, {
|
|
168
|
+
timeout: options?.timeout ? Math.min(options.timeout, 5000) : 5000
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return originalRequestIdleCallback.call(this, function(deadline) {
|
|
172
|
+
// Modify deadline to appear more Windows-like
|
|
173
|
+
const modifiedDeadline = {
|
|
174
|
+
didTimeout: deadline.didTimeout,
|
|
175
|
+
timeRemaining: function() {
|
|
176
|
+
const remaining = deadline.timeRemaining();
|
|
177
|
+
// Windows tends to report slightly less remaining time
|
|
178
|
+
return Math.max(0, remaining * 0.95 - Math.random() * 2);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
return callback.call(this, modifiedDeadline);
|
|
183
|
+
}, windowsOptions);
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Spoof scheduler API (if available)
|
|
188
|
+
if ('scheduler' in window && window.scheduler) {
|
|
189
|
+
const originalPostTask = window.scheduler.postTask;
|
|
190
|
+
if (originalPostTask) {
|
|
191
|
+
window.scheduler.postTask = function(callback, options) {
|
|
192
|
+
// Windows scheduling tends to be slightly different
|
|
193
|
+
const windowsOptions = Object.assign({}, options);
|
|
194
|
+
if (windowsOptions.delay) {
|
|
195
|
+
windowsOptions.delay = Math.max(0, windowsOptions.delay - Math.random() * 2);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return originalPostTask.call(this, callback, windowsOptions);
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Spoof performance observer timing
|
|
204
|
+
if ('PerformanceObserver' in window) {
|
|
205
|
+
const OriginalPerformanceObserver = PerformanceObserver;
|
|
206
|
+
window.PerformanceObserver = class extends OriginalPerformanceObserver {
|
|
207
|
+
constructor(callback) {
|
|
208
|
+
super(function(list, observer) {
|
|
209
|
+
const entries = list.getEntries().map(entry => spoofTimingEntry(entry));
|
|
210
|
+
const modifiedList = {
|
|
211
|
+
getEntries: () => entries,
|
|
212
|
+
getEntriesByType: (type) => entries.filter(e => e.entryType === type),
|
|
213
|
+
getEntriesByName: (name, type) => entries.filter(e =>
|
|
214
|
+
e.name === name && (!type || e.entryType === type)
|
|
215
|
+
)
|
|
216
|
+
};
|
|
217
|
+
return callback.call(this, modifiedList, observer);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
spoofPerformance();
|
|
225
|
+
})();
|
|
226
|
+
`;
|
|
227
|
+
};
|
|
228
|
+
//# sourceMappingURL=performance-spoofing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/performance-spoofing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,+BAA+B,GAAG,GAAW,EAAE;IACxD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4NV,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform Consistency Script
|
|
3
|
+
* Ensures all browser properties match the specified platform (1:1 fingerprinting)
|
|
4
|
+
*/
|
|
5
|
+
export interface PlatformConfig {
|
|
6
|
+
platform?: string;
|
|
7
|
+
devicePixelRatio?: number;
|
|
8
|
+
screenDepth?: number;
|
|
9
|
+
colorDepth?: number;
|
|
10
|
+
hardwareConcurrency?: number;
|
|
11
|
+
maxTouchPoints?: number;
|
|
12
|
+
vendor?: string;
|
|
13
|
+
vendorSub?: string;
|
|
14
|
+
productSub?: string;
|
|
15
|
+
language?: string;
|
|
16
|
+
languages?: string[];
|
|
17
|
+
oscpu?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare const createPlatformConsistencyScript: (platform: string, fingerprintData?: PlatformConfig) => string;
|
|
20
|
+
//# sourceMappingURL=platform-consistency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-consistency.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/platform-consistency.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,+BAA+B,aAAc,MAAM,oBAAoB,cAAc,KAAG,MAgOpG,CAAC"}
|