jumpy-lion 0.0.41 → 0.0.42

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.
Files changed (119) hide show
  1. package/dist/browser-controller.d.ts.map +1 -1
  2. package/dist/browser-controller.js +102 -16
  3. package/dist/browser-controller.js.map +1 -1
  4. package/dist/browser-plugin.d.ts +20 -1
  5. package/dist/browser-plugin.d.ts.map +1 -1
  6. package/dist/browser-plugin.js +21 -1
  7. package/dist/browser-plugin.js.map +1 -1
  8. package/dist/browser-process/browser.d.ts +22 -1
  9. package/dist/browser-process/browser.d.ts.map +1 -1
  10. package/dist/browser-process/browser.js +77 -5
  11. package/dist/browser-process/browser.js.map +1 -1
  12. package/dist/browser-profiles/chrome/default.d.ts +116 -0
  13. package/dist/browser-profiles/chrome/default.d.ts.map +1 -1
  14. package/dist/browser-profiles/chrome/default.js +118 -1
  15. package/dist/browser-profiles/chrome/default.js.map +1 -1
  16. package/dist/browser-profiles/chrome/populate-profile.d.ts +76 -0
  17. package/dist/browser-profiles/chrome/populate-profile.d.ts.map +1 -0
  18. package/dist/browser-profiles/chrome/populate-profile.js +300 -0
  19. package/dist/browser-profiles/chrome/populate-profile.js.map +1 -0
  20. package/dist/browser-profiles/index.d.ts +1 -0
  21. package/dist/browser-profiles/index.d.ts.map +1 -1
  22. package/dist/browser-profiles/index.js +2 -0
  23. package/dist/browser-profiles/index.js.map +1 -1
  24. package/dist/crawler.d.ts +32 -1
  25. package/dist/crawler.d.ts.map +1 -1
  26. package/dist/crawler.js +7 -0
  27. package/dist/crawler.js.map +1 -1
  28. package/dist/fingerprinting/custom-fingerprint-injector.d.ts +87 -0
  29. package/dist/fingerprinting/custom-fingerprint-injector.d.ts.map +1 -0
  30. package/dist/fingerprinting/custom-fingerprint-injector.js +342 -0
  31. package/dist/fingerprinting/custom-fingerprint-injector.js.map +1 -0
  32. package/dist/fingerprinting/fingerprint-injector.d.ts +40 -2
  33. package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
  34. package/dist/fingerprinting/fingerprint-injector.js +449 -44
  35. package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
  36. package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts.map +1 -1
  37. package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js +11 -1
  38. package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js.map +1 -1
  39. package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts.map +1 -1
  40. package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js +11 -1
  41. package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js.map +1 -1
  42. package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts +14 -0
  43. package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts.map +1 -0
  44. package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js +497 -0
  45. package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js.map +1 -0
  46. package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts.map +1 -1
  47. package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js +11 -1
  48. package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js.map +1 -1
  49. package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts +14 -0
  50. package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts.map +1 -0
  51. package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js +536 -0
  52. package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js.map +1 -0
  53. package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts.map +1 -1
  54. package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js +11 -1
  55. package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js.map +1 -1
  56. package/dist/fingerprinting/fingerprint-overrides/index.d.ts +16 -1
  57. package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -1
  58. package/dist/fingerprinting/fingerprint-overrides/index.js +19 -1
  59. package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -1
  60. package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts +45 -0
  61. package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts.map +1 -0
  62. package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js +291 -0
  63. package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js.map +1 -0
  64. package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -1
  65. package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +54 -22
  66. package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -1
  67. package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts.map +1 -1
  68. package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js +4 -5
  69. package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js.map +1 -1
  70. package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts.map +1 -1
  71. package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js +11 -1
  72. package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js.map +1 -1
  73. package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts +13 -0
  74. package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -1
  75. package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +413 -70
  76. package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -1
  77. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +10 -3
  78. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -1
  79. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +132 -73
  80. package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -1
  81. package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts +55 -0
  82. package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts.map +1 -0
  83. package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js +380 -0
  84. package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js.map +1 -0
  85. package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts +8 -0
  86. package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -1
  87. package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +417 -71
  88. package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -1
  89. package/dist/fingerprinting/fingerprint-overrides/storage-consistency.d.ts +13 -0
  90. package/dist/fingerprinting/fingerprint-overrides/storage-consistency.d.ts.map +1 -0
  91. package/dist/fingerprinting/fingerprint-overrides/storage-consistency.js +368 -0
  92. package/dist/fingerprinting/fingerprint-overrides/storage-consistency.js.map +1 -0
  93. package/dist/fingerprinting/fingerprint-overrides/timing-consistency.d.ts +13 -0
  94. package/dist/fingerprinting/fingerprint-overrides/timing-consistency.d.ts.map +1 -0
  95. package/dist/fingerprinting/fingerprint-overrides/timing-consistency.js +438 -0
  96. package/dist/fingerprinting/fingerprint-overrides/timing-consistency.js.map +1 -0
  97. package/dist/fingerprinting/fingerprint-overrides/utils.d.ts +12 -0
  98. package/dist/fingerprinting/fingerprint-overrides/utils.d.ts.map +1 -0
  99. package/dist/fingerprinting/fingerprint-overrides/utils.js +315 -0
  100. package/dist/fingerprinting/fingerprint-overrides/utils.js.map +1 -0
  101. package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -1
  102. package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +13 -1
  103. package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -1
  104. package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts.map +1 -1
  105. package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js +11 -1
  106. package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js.map +1 -1
  107. package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts.map +1 -1
  108. package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +11 -1
  109. package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js.map +1 -1
  110. package/dist/page.d.ts +12 -0
  111. package/dist/page.d.ts.map +1 -1
  112. package/dist/page.js +35 -3
  113. package/dist/page.js.map +1 -1
  114. package/dist/tsconfig.build.tsbuildinfo +1 -1
  115. package/package.json +4 -4
  116. package/dist/fingerprinting/canvas-fingerprint.d.ts +0 -4
  117. package/dist/fingerprinting/canvas-fingerprint.d.ts.map +0 -1
  118. package/dist/fingerprinting/canvas-fingerprint.js +0 -60
  119. package/dist/fingerprinting/canvas-fingerprint.js.map +0 -1
@@ -0,0 +1,14 @@
1
+ /**
2
+ * DataDome-Specific Bypass Module
3
+ * Targeted countermeasures for DataDome bot detection 2024-2025
4
+ *
5
+ * Features:
6
+ * - JavaScript challenge response handling
7
+ * - Proof-of-work computation timing spoofing
8
+ * - eval() and Function() source hiding
9
+ * - DataDome cookie consistency
10
+ * - dd-* header handling
11
+ * - Device Check signal spoofing
12
+ */
13
+ export declare const createDataDomeBypassScript: () => string;
14
+ //# sourceMappingURL=datadome-bypass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datadome-bypass.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/datadome-bypass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,0BAA0B,QAAO,MA0gB7C,CAAC"}
@@ -0,0 +1,536 @@
1
+ /**
2
+ * DataDome-Specific Bypass Module
3
+ * Targeted countermeasures for DataDome bot detection 2024-2025
4
+ *
5
+ * Features:
6
+ * - JavaScript challenge response handling
7
+ * - Proof-of-work computation timing spoofing
8
+ * - eval() and Function() source hiding
9
+ * - DataDome cookie consistency
10
+ * - dd-* header handling
11
+ * - Device Check signal spoofing
12
+ */
13
+ export const createDataDomeBypassScript = () => {
14
+ return `
15
+ (() => {
16
+ 'use strict';
17
+
18
+ // DataDome-Specific Bypass for 2024-2025
19
+ const bypassDataDome = () => {
20
+ // Generate consistent session identifiers
21
+ const generateSessionId = () => {
22
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
23
+ let result = '';
24
+ for (let i = 0; i < 32; i++) {
25
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
26
+ }
27
+ return result;
28
+ };
29
+
30
+ const sessionId = generateSessionId();
31
+
32
+ // 1. Handle DataDome JavaScript challenges
33
+ const handleJSChallenges = () => {
34
+ // Track challenge timing to appear human-like
35
+ const challengeStartTimes = new Map();
36
+
37
+ // Override setTimeout to add realistic delays to challenges
38
+ const originalSetTimeout = window.setTimeout;
39
+ window.setTimeout = function(callback, delay, ...args) {
40
+ // DataDome often uses very short timeouts for detection
41
+ // Add slight variance to appear more human
42
+ const isDataDomeChallenge = callback &&
43
+ (callback.toString().includes('dd_') ||
44
+ callback.toString().includes('datadome'));
45
+
46
+ if (isDataDomeChallenge && delay < 100) {
47
+ delay = delay + Math.floor(Math.random() * 50);
48
+ }
49
+
50
+ return originalSetTimeout.call(this, callback, delay, ...args);
51
+ };
52
+
53
+ // Monitor for challenge scripts - but wait for DOM to be ready
54
+ const setupObserver = () => {
55
+ if (!document.documentElement) {
56
+ console.log('[CDP-FP-DEBUG] document.documentElement not ready, will retry');
57
+ return;
58
+ }
59
+
60
+ try {
61
+ const observer = new MutationObserver((mutations) => {
62
+ for (const mutation of mutations) {
63
+ for (const node of mutation.addedNodes) {
64
+ if (node.nodeName === 'SCRIPT') {
65
+ const script = node;
66
+ if (script.src && script.src.includes('datadome')) {
67
+ // Mark challenge start time
68
+ challengeStartTimes.set(script.src, performance.now());
69
+ }
70
+ }
71
+ }
72
+ }
73
+ });
74
+
75
+ // Double-check documentElement exists before observing
76
+ if (document.documentElement) {
77
+ observer.observe(document.documentElement, {
78
+ childList: true,
79
+ subtree: true
80
+ });
81
+ console.log('[CDP-FP-DEBUG] DataDome challenge observer set up');
82
+ }
83
+ } catch (e) {
84
+ console.log('[CDP-FP-DEBUG] Could not set up DataDome observer:', e.message);
85
+ }
86
+ };
87
+
88
+ // Try to set up observer, or wait for DOM
89
+ if (document.documentElement) {
90
+ setupObserver();
91
+ } else {
92
+ // Wait for DOM to be ready
93
+ if (document.readyState === 'loading') {
94
+ document.addEventListener('DOMContentLoaded', setupObserver);
95
+ } else {
96
+ // DOM is interactive or complete, set up immediately
97
+ setupObserver();
98
+ }
99
+ }
100
+ };
101
+
102
+ // 2. Spoof proof-of-work computation timing
103
+ const spoofPOWTiming = () => {
104
+ // DataDome may use proof-of-work challenges
105
+ // These should complete in human-like time (not instant)
106
+
107
+ const originalWorker = window.Worker;
108
+
109
+ if (originalWorker) {
110
+ window.Worker = function(scriptURL, options) {
111
+ const worker = new originalWorker(scriptURL, options);
112
+
113
+ // Intercept messages to/from worker
114
+ const originalPostMessage = worker.postMessage;
115
+ worker.postMessage = function(message, transfer) {
116
+ // Add delay before sending to worker
117
+ const delay = 10 + Math.random() * 20;
118
+
119
+ setTimeout(() => {
120
+ originalPostMessage.call(this, message, transfer);
121
+ }, delay);
122
+ };
123
+
124
+ // Add delay to worker responses
125
+ const originalOnMessage = Object.getOwnPropertyDescriptor(Worker.prototype, 'onmessage');
126
+ if (originalOnMessage) {
127
+ Object.defineProperty(worker, 'onmessage', {
128
+ get() {
129
+ return originalOnMessage.get.call(this);
130
+ },
131
+ set(handler) {
132
+ const wrappedHandler = function(event) {
133
+ // Add slight delay to appear like real computation
134
+ setTimeout(() => {
135
+ handler.call(this, event);
136
+ }, 5 + Math.random() * 15);
137
+ };
138
+ originalOnMessage.set.call(this, wrappedHandler);
139
+ }
140
+ });
141
+ }
142
+
143
+ return worker;
144
+ };
145
+
146
+ // Note: Don't assign to prototype - it may be frozen in modern Chrome
147
+ }
148
+ };
149
+
150
+ // 3. Protect eval() and Function() from source detection
151
+ const protectEvalSources = () => {
152
+ const originalEval = window.eval;
153
+ const OriginalFunction = window.Function;
154
+
155
+ // DataDome may check eval source strings
156
+ window.eval = function(code) {
157
+ // Clean DataDome detection patterns
158
+ if (typeof code === 'string') {
159
+ // Remove obvious eval markers
160
+ code = code.replace(/\\/\\/.*datadome.*$/gm, '');
161
+ code = code.replace(/\\/\\*.*datadome.*\\*\\//g, '');
162
+ }
163
+
164
+ return originalEval.call(this, code);
165
+ };
166
+
167
+ const FunctionProxy = new Proxy(OriginalFunction, {
168
+ construct(target, args) {
169
+ // Clean function body
170
+ if (args.length > 0 && typeof args[args.length - 1] === 'string') {
171
+ args[args.length - 1] = args[args.length - 1]
172
+ .replace(/\\/\\/.*datadome.*$/gm, '')
173
+ .replace(/\\/\\*.*datadome.*\\*\\//g, '');
174
+ }
175
+
176
+ return Reflect.construct(target, args);
177
+ },
178
+ apply(target, thisArg, args) {
179
+ // Clean function body for apply calls
180
+ if (args.length > 0 && typeof args[args.length - 1] === 'string') {
181
+ args[args.length - 1] = args[args.length - 1]
182
+ .replace(/\\/\\/.*datadome.*$/gm, '')
183
+ .replace(/\\/\\*.*datadome.*\\*\\//g, '');
184
+ }
185
+
186
+ return Reflect.apply(target, thisArg, args);
187
+ },
188
+ get(target, prop) {
189
+ // Return the original prototype when accessing .prototype
190
+ if (prop === 'prototype') {
191
+ return OriginalFunction.prototype;
192
+ }
193
+ return Reflect.get(target, prop);
194
+ }
195
+ });
196
+
197
+ // Use defineProperty to replace Function without modifying frozen prototype
198
+ try {
199
+ Object.defineProperty(window, 'Function', {
200
+ value: FunctionProxy,
201
+ writable: true,
202
+ enumerable: false,
203
+ configurable: true
204
+ });
205
+ } catch (e) {
206
+ // If we can't redefine, just assign
207
+ window.Function = FunctionProxy;
208
+ }
209
+ };
210
+
211
+ // 4. Handle DataDome cookies consistently
212
+ const handleDataDomeCookies = () => {
213
+ // Track datadome cookies
214
+ const datadomePattern = /^datadome/i;
215
+
216
+ // Override document.cookie getter/setter
217
+ const cookieDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie');
218
+
219
+ if (cookieDescriptor) {
220
+ Object.defineProperty(document, 'cookie', {
221
+ get() {
222
+ const cookies = cookieDescriptor.get.call(this);
223
+ // Return cookies normally, datadome expects them
224
+ return cookies;
225
+ },
226
+ set(value) {
227
+ // Allow datadome cookies to be set normally
228
+ return cookieDescriptor.set.call(this, value);
229
+ },
230
+ configurable: true
231
+ });
232
+ }
233
+ };
234
+
235
+ // 5. Spoof DataDome device signals
236
+ const spoofDeviceSignals = () => {
237
+ // DataDome Device Check looks for specific signals
238
+
239
+ // Helper to check if property can be redefined
240
+ const canRedefineProperty = (obj, prop) => {
241
+ try {
242
+ const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
243
+ return !descriptor || descriptor.configurable !== false;
244
+ } catch (e) {
245
+ return false;
246
+ }
247
+ };
248
+
249
+ // Ensure consistent hardware concurrency (only if not already defined as non-configurable)
250
+ if (canRedefineProperty(navigator, 'hardwareConcurrency')) {
251
+ const expectedConcurrency = navigator.hardwareConcurrency || 8;
252
+ try {
253
+ Object.defineProperty(navigator, 'hardwareConcurrency', {
254
+ get: () => expectedConcurrency,
255
+ configurable: true // Allow other scripts to modify
256
+ });
257
+ } catch (e) {
258
+ // Property already defined, skip
259
+ }
260
+ }
261
+
262
+ // Ensure deviceMemory is present and reasonable (only if not already defined as non-configurable)
263
+ if (canRedefineProperty(navigator, 'deviceMemory')) {
264
+ const expectedMemory = navigator.deviceMemory || 8;
265
+ try {
266
+ Object.defineProperty(navigator, 'deviceMemory', {
267
+ get: () => expectedMemory,
268
+ configurable: true // Allow other scripts to modify
269
+ });
270
+ } catch (e) {
271
+ // Property already defined, skip
272
+ }
273
+ }
274
+
275
+ // Ensure connection info looks real
276
+ if ('connection' in navigator) {
277
+ const conn = navigator.connection;
278
+ if (conn) {
279
+ try {
280
+ if (canRedefineProperty(conn, 'effectiveType')) {
281
+ Object.defineProperty(conn, 'effectiveType', {
282
+ get: () => '4g',
283
+ configurable: true
284
+ });
285
+ }
286
+ if (canRedefineProperty(conn, 'rtt')) {
287
+ Object.defineProperty(conn, 'rtt', {
288
+ get: () => 50 + Math.floor(Math.random() * 50),
289
+ configurable: true
290
+ });
291
+ }
292
+ if (canRedefineProperty(conn, 'downlink')) {
293
+ Object.defineProperty(conn, 'downlink', {
294
+ get: () => 10 + Math.random() * 40,
295
+ configurable: true
296
+ });
297
+ }
298
+ } catch (e) {}
299
+ }
300
+ }
301
+ };
302
+
303
+ // 6. Handle dd-* headers in fetch/XHR
304
+ const handleDataDomeHeaders = () => {
305
+ // Override fetch to ensure proper headers
306
+ const originalFetch = window.fetch;
307
+
308
+ window.fetch = function(input, init = {}) {
309
+ // Ensure proper headers are sent
310
+ if (!init.headers) {
311
+ init.headers = {};
312
+ }
313
+
314
+ // Clone headers if needed
315
+ if (init.headers instanceof Headers) {
316
+ const headersObj = {};
317
+ init.headers.forEach((value, key) => {
318
+ headersObj[key] = value;
319
+ });
320
+ init.headers = headersObj;
321
+ }
322
+
323
+ // Add realistic browser headers if missing
324
+ if (!init.headers['Accept-Language']) {
325
+ init.headers['Accept-Language'] = 'en-US,en;q=0.9';
326
+ }
327
+
328
+ return originalFetch.call(this, input, init);
329
+ };
330
+
331
+ // Override XMLHttpRequest
332
+ const originalOpen = XMLHttpRequest.prototype.open;
333
+ const originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
334
+ const headersMap = new WeakMap();
335
+
336
+ XMLHttpRequest.prototype.open = function(method, url, ...args) {
337
+ headersMap.set(this, {});
338
+ return originalOpen.call(this, method, url, ...args);
339
+ };
340
+
341
+ XMLHttpRequest.prototype.setRequestHeader = function(name, value) {
342
+ const headers = headersMap.get(this) || {};
343
+ headers[name.toLowerCase()] = value;
344
+ headersMap.set(this, headers);
345
+ return originalSetRequestHeader.call(this, name, value);
346
+ };
347
+ };
348
+
349
+ // 7. Protect canvas fingerprinting from DataDome
350
+ const protectCanvasForDataDome = () => {
351
+ // DataDome uses specific canvas tests
352
+ const originalToDataURL = HTMLCanvasElement.prototype.toDataURL;
353
+ const canvasCache = new WeakMap();
354
+
355
+ HTMLCanvasElement.prototype.toDataURL = function(...args) {
356
+ // Cache canvas results for consistency
357
+ const key = this.width + 'x' + this.height;
358
+
359
+ if (canvasCache.has(this)) {
360
+ const cached = canvasCache.get(this);
361
+ if (cached.key === key) {
362
+ return cached.result;
363
+ }
364
+ }
365
+
366
+ const result = originalToDataURL.apply(this, args);
367
+ canvasCache.set(this, { key, result });
368
+
369
+ return result;
370
+ };
371
+ };
372
+
373
+ // 8. Handle visibility/focus detection
374
+ const handleVisibilityDetection = () => {
375
+ // DataDome may check if page is visible/focused
376
+ Object.defineProperty(document, 'hidden', {
377
+ get: () => false,
378
+ configurable: true
379
+ });
380
+
381
+ Object.defineProperty(document, 'visibilityState', {
382
+ get: () => 'visible',
383
+ configurable: true
384
+ });
385
+
386
+ // Ensure hasFocus returns true
387
+ const originalHasFocus = document.hasFocus;
388
+ document.hasFocus = function() {
389
+ return true;
390
+ };
391
+ };
392
+
393
+ // 9. Spoof mouse/touch presence
394
+ const spoofInputPresence = () => {
395
+ // DataDome checks for input device presence
396
+
397
+ // Ensure pointer events are supported
398
+ Object.defineProperty(navigator, 'maxTouchPoints', {
399
+ get: () => 0, // Desktop has 0 touch points
400
+ configurable: true
401
+ });
402
+
403
+ // Ensure we have a mouse (matchMedia for hover)
404
+ const originalMatchMedia = window.matchMedia;
405
+ window.matchMedia = function(query) {
406
+ const result = originalMatchMedia.call(this, query);
407
+
408
+ // Ensure hover is supported (we have a mouse)
409
+ if (query === '(hover: hover)') {
410
+ return Object.assign({}, result, { matches: true });
411
+ }
412
+
413
+ // Ensure pointer is fine (mouse, not touch)
414
+ if (query === '(pointer: fine)') {
415
+ return Object.assign({}, result, { matches: true });
416
+ }
417
+
418
+ return result;
419
+ };
420
+ };
421
+
422
+ // 10. Handle DataDome's timing checks
423
+ const handleTimingChecks = () => {
424
+ // DataDome measures various timing signals
425
+
426
+ // Ensure navigation timing looks normal
427
+ if (performance.timing) {
428
+ const timing = performance.timing;
429
+
430
+ // These should look like a real page load
431
+ const loadTime = timing.loadEventEnd - timing.navigationStart;
432
+
433
+ // If load time is suspiciously fast, we need to appear slower
434
+ if (loadTime > 0 && loadTime < 500) {
435
+ // Page loaded too fast, might be detected
436
+ // The timing is already set, but we can affect new measurements
437
+ }
438
+ }
439
+
440
+ // Add realistic performance entries
441
+ if (performance.mark && performance.measure) {
442
+ try {
443
+ performance.mark('dd_page_start');
444
+ setTimeout(() => {
445
+ performance.mark('dd_page_ready');
446
+ performance.measure('dd_load_time', 'dd_page_start', 'dd_page_ready');
447
+ }, 100 + Math.random() * 200);
448
+ } catch (e) {}
449
+ }
450
+ };
451
+
452
+ // 11. Ensure WebGL looks consistent
453
+ const ensureWebGLConsistency = () => {
454
+ // DataDome checks WebGL renderer consistency
455
+ const originalGetParameter = WebGLRenderingContext.prototype.getParameter;
456
+ let cachedRenderer = null;
457
+ let cachedVendor = null;
458
+
459
+ WebGLRenderingContext.prototype.getParameter = function(param) {
460
+ // Cache WebGL values for consistency across calls
461
+ if (param === 0x9245) { // UNMASKED_VENDOR_WEBGL
462
+ if (!cachedVendor) {
463
+ cachedVendor = originalGetParameter.call(this, param);
464
+ }
465
+ return cachedVendor;
466
+ }
467
+
468
+ if (param === 0x9246) { // UNMASKED_RENDERER_WEBGL
469
+ if (!cachedRenderer) {
470
+ cachedRenderer = originalGetParameter.call(this, param);
471
+ }
472
+ return cachedRenderer;
473
+ }
474
+
475
+ return originalGetParameter.call(this, param);
476
+ };
477
+
478
+ if (typeof WebGL2RenderingContext !== 'undefined') {
479
+ WebGL2RenderingContext.prototype.getParameter = WebGLRenderingContext.prototype.getParameter;
480
+ }
481
+ };
482
+
483
+ // 12. Handle iframe detection
484
+ const handleIframeDetection = () => {
485
+ // DataDome may check if running in iframe
486
+ // Helper to safely define
487
+ const safeDefine = (obj, prop, getter) => {
488
+ try {
489
+ const desc = Object.getOwnPropertyDescriptor(obj, prop);
490
+ if (desc && desc.configurable === false) return;
491
+ Object.defineProperty(obj, prop, {
492
+ get: getter,
493
+ configurable: true
494
+ });
495
+ } catch (e) {}
496
+ };
497
+
498
+ safeDefine(window, 'self', () => window);
499
+ safeDefine(window, 'top', () => window);
500
+ safeDefine(window, 'parent', () => window);
501
+ };
502
+
503
+ // Initialize all DataDome bypasses
504
+ try {
505
+ handleJSChallenges();
506
+ spoofPOWTiming();
507
+ protectEvalSources();
508
+ handleDataDomeCookies();
509
+ spoofDeviceSignals();
510
+ handleDataDomeHeaders();
511
+ protectCanvasForDataDome();
512
+ handleVisibilityDetection();
513
+ spoofInputPresence();
514
+ handleTimingChecks();
515
+ ensureWebGLConsistency();
516
+ handleIframeDetection();
517
+ } catch (e) {
518
+ console.error('[DATADOME-BYPASS] Failed to apply DataDome bypass:', e);
519
+ throw e; // Rethrow to make errors visible
520
+ }
521
+ };
522
+
523
+ const DEBUG_PREFIX = '[CDP-FP-DEBUG]';
524
+ const ERROR_PREFIX = '[CDP-FP-ERROR]';
525
+
526
+ try {
527
+ console.log(DEBUG_PREFIX, 'Starting DataDome bypass...');
528
+ bypassDataDome();
529
+ console.log(DEBUG_PREFIX, '✓ DataDome bypass applied');
530
+ } catch (e) {
531
+ console.error(ERROR_PREFIX, '✗ Failed to apply DataDome bypass:', e);
532
+ throw e;
533
+ }
534
+ })();`;
535
+ };
536
+ //# sourceMappingURL=datadome-bypass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"datadome-bypass.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/datadome-bypass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAW,EAAE;IACnD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAwgBL,CAAC;AACP,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"font-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/font-spoofing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,wBAAwB,QAAO,MAoN3C,CAAC"}
1
+ {"version":3,"file":"font-spoofing.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/font-spoofing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,wBAAwB,QAAO,MA8N3C,CAAC"}
@@ -212,7 +212,17 @@ export const createFontSpoofingScript = () => {
212
212
  };
213
213
  };
214
214
 
215
- spoofFonts();
215
+ const DEBUG_PREFIX = '[CDP-FP-DEBUG]';
216
+ const ERROR_PREFIX = '[CDP-FP-ERROR]';
217
+
218
+ try {
219
+ console.log(DEBUG_PREFIX, 'Starting font spoofing...');
220
+ spoofFonts();
221
+ console.log(DEBUG_PREFIX, '✓ Font spoofing applied');
222
+ } catch (e) {
223
+ console.error(ERROR_PREFIX, '✗ Failed to apply font spoofing:', e);
224
+ throw e;
225
+ }
216
226
  })();
217
227
  `;
218
228
  };
@@ -1 +1 @@
1
- {"version":3,"file":"font-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/font-spoofing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAW,EAAE;IACjD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkNV,CAAC;AACF,CAAC,CAAC"}
1
+ {"version":3,"file":"font-spoofing.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/font-spoofing.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,GAAW,EAAE;IACjD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4NV,CAAC;AACF,CAAC,CAAC"}
@@ -1,6 +1,14 @@
1
1
  /**
2
2
  * Fingerprint Overrides Index
3
3
  * Exports all individual fingerprint override modules
4
+ *
5
+ * 2024-2025 Additions:
6
+ * - CDP Detection Bypass
7
+ * - Storage Consistency
8
+ * - Timing Consistency
9
+ * - Keyboard Humanization
10
+ * - Scroll Humanization
11
+ * - DataDome Bypass
4
12
  */
5
13
  export { createStealthScript } from './stealth-script.js';
6
14
  export { createWebGLSpoofingScript, type WebGLConfig } from './webgl-spoofing.js';
@@ -11,9 +19,16 @@ export { createWebRTCSpoofingScript } from './webrtc-spoofing.js';
11
19
  export { createWebGPUSpoofingScript } from './webgpu-spoofing.js';
12
20
  export { createPlatformConsistencyScript, type PlatformConfig } from './platform-consistency.js';
13
21
  export { setupMouseMovementHumanization } from './mouse-humanization.js';
14
- export { setupRuntimeEnableBypass } from './runtime-enable-bypass.js';
22
+ export { createRuntimeEnableBypassScript } from './runtime-enable-bypass.js';
15
23
  export { createFontSpoofingScript } from './font-spoofing.js';
16
24
  export { createPerformanceSpoofingScript } from './performance-spoofing.js';
17
25
  export { createLocaleSpoofingScript } from './locale-spoofing.js';
18
26
  export { createUAClientHintsSpoofingScript } from './ua-ch.js';
27
+ export { createStealthUtilsScript } from './utils.js';
28
+ export { createCDPDetectionBypassScript } from './cdp-detection-bypass.js';
29
+ export { createStorageConsistencyScript } from './storage-consistency.js';
30
+ export { createTimingConsistencyScript } from './timing-consistency.js';
31
+ export { createKeyboardHumanizationScript, setupKeyboardHumanization, generateTypingDelays, createHumanTypingFunction } from './keyboard-humanization.js';
32
+ export { createScrollHumanizationScript, setupScrollHumanization, humanScroll, humanScrollToElement, generateScrollPath } from './scroll-humanization.js';
33
+ export { createDataDomeBypassScript } from './datadome-bypass.js';
19
34
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,oCAAoC,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,oCAAoC,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC;AAG/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAGtD,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EACH,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACH,8BAA8B,EAC9B,uBAAuB,EACvB,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC"}
@@ -1,7 +1,16 @@
1
1
  /**
2
2
  * Fingerprint Overrides Index
3
3
  * Exports all individual fingerprint override modules
4
+ *
5
+ * 2024-2025 Additions:
6
+ * - CDP Detection Bypass
7
+ * - Storage Consistency
8
+ * - Timing Consistency
9
+ * - Keyboard Humanization
10
+ * - Scroll Humanization
11
+ * - DataDome Bypass
4
12
  */
13
+ // Base stealth and protection scripts
5
14
  export { createStealthScript } from './stealth-script.js';
6
15
  export { createWebGLSpoofingScript } from './webgl-spoofing.js';
7
16
  export { createAudioFingerprintSpoofingScript } from './audio-spoofing.js';
@@ -11,9 +20,18 @@ export { createWebRTCSpoofingScript } from './webrtc-spoofing.js';
11
20
  export { createWebGPUSpoofingScript } from './webgpu-spoofing.js';
12
21
  export { createPlatformConsistencyScript } from './platform-consistency.js';
13
22
  export { setupMouseMovementHumanization } from './mouse-humanization.js';
14
- export { setupRuntimeEnableBypass } from './runtime-enable-bypass.js';
23
+ export { createRuntimeEnableBypassScript } from './runtime-enable-bypass.js';
15
24
  export { createFontSpoofingScript } from './font-spoofing.js';
16
25
  export { createPerformanceSpoofingScript } from './performance-spoofing.js';
17
26
  export { createLocaleSpoofingScript } from './locale-spoofing.js';
18
27
  export { createUAClientHintsSpoofingScript } from './ua-ch.js';
28
+ // Stealth utilities (must be injected first)
29
+ export { createStealthUtilsScript } from './utils.js';
30
+ // 2024-2025 New modules
31
+ export { createCDPDetectionBypassScript } from './cdp-detection-bypass.js';
32
+ export { createStorageConsistencyScript } from './storage-consistency.js';
33
+ export { createTimingConsistencyScript } from './timing-consistency.js';
34
+ export { createKeyboardHumanizationScript, setupKeyboardHumanization, generateTypingDelays, createHumanTypingFunction } from './keyboard-humanization.js';
35
+ export { createScrollHumanizationScript, setupScrollHumanization, humanScroll, humanScrollToElement, generateScrollPath } from './scroll-humanization.js';
36
+ export { createDataDomeBypassScript } from './datadome-bypass.js';
19
37
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAoB,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,oCAAoC,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAuB,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/fingerprinting/fingerprint-overrides/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,sCAAsC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,yBAAyB,EAAoB,MAAM,qBAAqB,CAAC;AAClF,OAAO,EAAE,oCAAoC,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,oCAAoC,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,+BAA+B,EAAuB,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,8BAA8B,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC;AAE/D,6CAA6C;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAwB;AACxB,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EACH,gCAAgC,EAChC,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACH,8BAA8B,EAC9B,uBAAuB,EACvB,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EACrB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC"}