playwright-stealth-ultimate 5.0.0__py3-none-any.whl

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 (52) hide show
  1. playwright_stealth/__init__.py +46 -0
  2. playwright_stealth/config/capabilities/chromium/136.json +19 -0
  3. playwright_stealth/config/capabilities/chromium/137.json +20 -0
  4. playwright_stealth/config/capabilities/chromium/138.json +21 -0
  5. playwright_stealth/config/capabilities/chromium/139.json +22 -0
  6. playwright_stealth/config/policies/balanced.yaml +19 -0
  7. playwright_stealth/config/policies/performance.yaml +22 -0
  8. playwright_stealth/config/policies/strict.yaml +19 -0
  9. playwright_stealth/config/profiles/macos_ventura_chrome_139.yaml +38 -0
  10. playwright_stealth/config/profiles/windows_10_chrome_138.yaml +38 -0
  11. playwright_stealth/config/profiles/windows_11_chrome_139.yaml +38 -0
  12. playwright_stealth/js/audio.js +348 -0
  13. playwright_stealth/js/canvas.js +333 -0
  14. playwright_stealth/js/chrome.app.js +226 -0
  15. playwright_stealth/js/chrome.csi.js +194 -0
  16. playwright_stealth/js/chrome.hairline.js +138 -0
  17. playwright_stealth/js/chrome.load.times.js +330 -0
  18. playwright_stealth/js/chrome.runtime.js +698 -0
  19. playwright_stealth/js/concurrency.js +272 -0
  20. playwright_stealth/js/errors.js +321 -0
  21. playwright_stealth/js/evasions.proxies.js +278 -0
  22. playwright_stealth/js/fonts.js +497 -0
  23. playwright_stealth/js/generate.magic.arrays.js +317 -0
  24. playwright_stealth/js/iframe.contentWindow.js +318 -0
  25. playwright_stealth/js/intl.js +455 -0
  26. playwright_stealth/js/media.codecs.js +283 -0
  27. playwright_stealth/js/navigator.deviceMemory.js +290 -0
  28. playwright_stealth/js/navigator.hardware.js +362 -0
  29. playwright_stealth/js/navigator.hardwareConcurrency.js +133 -0
  30. playwright_stealth/js/navigator.languages.js +174 -0
  31. playwright_stealth/js/navigator.maxTouchPoints.js +387 -0
  32. playwright_stealth/js/navigator.permissions.js +240 -0
  33. playwright_stealth/js/navigator.platform.js +179 -0
  34. playwright_stealth/js/navigator.plugins.js +245 -0
  35. playwright_stealth/js/navigator.userAgent.js +218 -0
  36. playwright_stealth/js/navigator.vendor.js +158 -0
  37. playwright_stealth/js/navigator.webdriver.js +332 -0
  38. playwright_stealth/js/screen.js +386 -0
  39. playwright_stealth/js/utils.js +567 -0
  40. playwright_stealth/js/webgl.anisotropy.js +230 -0
  41. playwright_stealth/js/webgl.js +549 -0
  42. playwright_stealth/js/webgl.vendor.js +243 -0
  43. playwright_stealth/js/webrtc.js +514 -0
  44. playwright_stealth/js/window.outerdimensions.js +173 -0
  45. playwright_stealth/js/window.properties.js +242 -0
  46. playwright_stealth/version.py +16 -0
  47. playwright_stealth_ultimate-5.0.0.dist-info/METADATA +425 -0
  48. playwright_stealth_ultimate-5.0.0.dist-info/RECORD +52 -0
  49. playwright_stealth_ultimate-5.0.0.dist-info/WHEEL +5 -0
  50. playwright_stealth_ultimate-5.0.0.dist-info/entry_points.txt +2 -0
  51. playwright_stealth_ultimate-5.0.0.dist-info/licenses/LICENSE +21 -0
  52. playwright_stealth_ultimate-5.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,46 @@
1
+ # playwright_stealth/__init__.py
2
+ """Playwright Stealth — Advanced Anti-Bot Evasion Suite."""
3
+
4
+ from .version import __version__, __version_info__, get_version, get_version_info
5
+
6
+ from .core import (
7
+ HardwareTier,
8
+ OSType,
9
+ BrowserVendor,
10
+ HardwareProfile,
11
+ BrowserProfile,
12
+ FingerprintProfile,
13
+ )
14
+
15
+ from .models import (
16
+ InjectionPlan,
17
+ SnapshotNode,
18
+ )
19
+
20
+ from .js import ScriptLoader, get_loader
21
+
22
+ from .adapters.playwright import (
23
+ stealth_sync,
24
+ stealth_async,
25
+ dump_configuration,
26
+ )
27
+
28
+ __all__ = [
29
+ "__version__",
30
+ "__version_info__",
31
+ "get_version",
32
+ "get_version_info",
33
+ "HardwareTier",
34
+ "OSType",
35
+ "BrowserVendor",
36
+ "HardwareProfile",
37
+ "BrowserProfile",
38
+ "FingerprintProfile",
39
+ "InjectionPlan",
40
+ "SnapshotNode",
41
+ "ScriptLoader",
42
+ "get_loader",
43
+ "stealth_sync",
44
+ "stealth_async",
45
+ "dump_configuration",
46
+ ]
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": "136.0.0.0",
3
+ "features": {
4
+ "webgpu": {"supported": false},
5
+ "fedcm": {"supported": false},
6
+ "storage_buckets": {"supported": false},
7
+ "private_network_access": {"supported": true},
8
+ "navigator_uadata": {"supported": true},
9
+ "pdf_viewer": {"supported": true},
10
+ "webgl2": {"supported": true},
11
+ "webgl_extensions": {"supported": true}
12
+ },
13
+ "apis": {
14
+ "storage": {"status": "stable"},
15
+ "permissions": {"status": "stable"}
16
+ },
17
+ "deprecations": [],
18
+ "experimental": []
19
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "version": "137.0.0.0",
3
+ "features": {
4
+ "webgpu": false,
5
+ "fedcm": false,
6
+ "storage_buckets": true,
7
+ "private_network_access": true,
8
+ "navigator_uadata": true,
9
+ "pdf_viewer": true,
10
+ "webgl2": true,
11
+ "webgl_extensions": true
12
+ },
13
+ "apis": {
14
+ "storage": "stable",
15
+ "permissions": "stable",
16
+ "storage_buckets": "experimental"
17
+ },
18
+ "deprecations": [],
19
+ "experimental": ["storage_buckets"]
20
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": "138.0.0.0",
3
+ "features": {
4
+ "webgpu": false,
5
+ "fedcm": true,
6
+ "storage_buckets": true,
7
+ "private_network_access": true,
8
+ "navigator_uadata": true,
9
+ "pdf_viewer": true,
10
+ "webgl2": true,
11
+ "webgl_extensions": true
12
+ },
13
+ "apis": {
14
+ "storage": "stable",
15
+ "permissions": "stable",
16
+ "fedcm": "experimental",
17
+ "storage_buckets": "experimental"
18
+ },
19
+ "deprecations": [],
20
+ "experimental": ["fedcm", "storage_buckets"]
21
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "version": "139.0.0.0",
3
+ "features": {
4
+ "webgpu": {"supported": true, "experimental": true},
5
+ "fedcm": {"supported": true, "experimental": true},
6
+ "storage_buckets": {"supported": true, "experimental": true},
7
+ "private_network_access": {"supported": true},
8
+ "navigator_uadata": {"supported": true},
9
+ "pdf_viewer": {"supported": true},
10
+ "webgl2": {"supported": true},
11
+ "webgl_extensions": {"supported": true}
12
+ },
13
+ "apis": {
14
+ "storage": {"status": "stable"},
15
+ "permissions": {"status": "stable"},
16
+ "webgpu": {"status": "experimental"},
17
+ "fedcm": {"status": "experimental"},
18
+ "storage_buckets": {"status": "experimental"}
19
+ },
20
+ "deprecations": [],
21
+ "experimental": ["webgpu", "fedcm", "storage_buckets"]
22
+ }
@@ -0,0 +1,19 @@
1
+ # config/policies/balanced.yaml
2
+ consistency: balanced
3
+ performance: balanced
4
+ fallback: auto
5
+ retry:
6
+ max: 3
7
+ delay: 1.0
8
+ validation:
9
+ hardware: true
10
+ browser: true
11
+ locale: true
12
+ network: false
13
+ display: false
14
+ modules:
15
+ require_all: false
16
+ allow_fallback: true
17
+ injection:
18
+ verify_checksum: true
19
+ optimize: true
@@ -0,0 +1,22 @@
1
+ # config/policies/performance.yaml
2
+ consistency: relaxed
3
+ performance: high
4
+ fallback: auto
5
+ retry:
6
+ max: 2
7
+ delay: 0.5
8
+ validation:
9
+ hardware: false
10
+ browser: false
11
+ locale: false
12
+ network: false
13
+ display: false
14
+ modules:
15
+ require_all: false
16
+ allow_fallback: true
17
+ injection:
18
+ verify_checksum: false
19
+ optimize: true
20
+ cache:
21
+ enabled: true
22
+ ttl: 3600
@@ -0,0 +1,19 @@
1
+ # config/policies/strict.yaml
2
+ consistency: strict
3
+ performance: balanced
4
+ fallback: none
5
+ retry:
6
+ max: 1
7
+ delay: 0.5
8
+ validation:
9
+ hardware: true
10
+ browser: true
11
+ locale: true
12
+ network: true
13
+ display: true
14
+ modules:
15
+ require_all: true
16
+ allow_fallback: false
17
+ injection:
18
+ verify_checksum: true
19
+ optimize: true
@@ -0,0 +1,38 @@
1
+ # config/profiles/macos_ventura_chrome_139.yaml
2
+ id: macos_ventura_chrome_139
3
+ hardware:
4
+ tier: high
5
+ cpu: Apple M2
6
+ cpu_cores: 8
7
+ ram: 16
8
+ gpu: Apple M2 GPU
9
+ gpu_vendor: Apple Inc.
10
+ gpu_renderer: ANGLE (Apple, Apple M2 GPU OpenGL)
11
+ screen: [2560, 1600]
12
+ dpi: 2.0
13
+ browser:
14
+ os: macos
15
+ version: 139.0.0.0
16
+ chrome_version: 139.0.0.0
17
+ platform: MacIntel
18
+ platform_version: 10.15.7
19
+ locale: en-US
20
+ languages: [en-US, en, fr-FR, fr]
21
+ timezone: America/Los_Angeles
22
+ user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
23
+ accept_language: en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7
24
+ fonts: [Helvetica, Arial, Times New Roman, Courier New, Verdana, Georgia]
25
+ modules:
26
+ enabled:
27
+ - webdriver
28
+ - chrome_runtime
29
+ - canvas
30
+ - audio
31
+ - intl
32
+ - webgl
33
+ - permissions
34
+ - user_agent_data
35
+ - pdf_viewer
36
+ policies:
37
+ consistency: strict
38
+ performance: balanced
@@ -0,0 +1,38 @@
1
+ # config/profiles/windows_10_chrome_138.yaml
2
+ id: windows_10_chrome_138
3
+ hardware:
4
+ tier: medium
5
+ cpu: Intel Core i5-1135G7
6
+ cpu_cores: 4
7
+ ram: 8
8
+ gpu: Intel Iris Xe Graphics
9
+ gpu_vendor: Intel Inc.
10
+ gpu_renderer: ANGLE (Intel, Intel Iris Xe Graphics Direct3D11)
11
+ screen: [1920, 1080]
12
+ dpi: 1.0
13
+ browser:
14
+ os: windows
15
+ version: 138.0.0.0
16
+ chrome_version: 138.0.0.0
17
+ platform: Win32
18
+ platform_version: 10.0.0
19
+ locale: en-US
20
+ languages: [en-US, en, fr-FR, fr]
21
+ timezone: America/New_York
22
+ user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36
23
+ accept_language: en-US,en;q=0.9,fr-FR;q=0.8,fr;q=0.7
24
+ fonts: [Arial, Helvetica, Times New Roman, Courier New, Verdana, Georgia]
25
+ modules:
26
+ enabled:
27
+ - webdriver
28
+ - chrome_runtime
29
+ - canvas
30
+ - audio
31
+ - intl
32
+ - webgl
33
+ - permissions
34
+ - user_agent_data
35
+ - pdf_viewer
36
+ policies:
37
+ consistency: strict
38
+ performance: balanced
@@ -0,0 +1,38 @@
1
+ # config/profiles/windows_11_chrome_139.yaml
2
+ id: windows_11_chrome_139
3
+ hardware:
4
+ tier: high
5
+ cpu: Intel Core i7-12700H
6
+ cpu_cores: 8
7
+ ram: 16
8
+ gpu: NVIDIA GeForce RTX 3060
9
+ gpu_vendor: NVIDIA Corporation
10
+ gpu_renderer: ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11)
11
+ screen: [2560, 1440]
12
+ dpi: 1.25
13
+ browser:
14
+ os: windows
15
+ version: 139.0.0.0
16
+ chrome_version: 139.0.0.0
17
+ platform: Win32
18
+ platform_version: 10.0.0
19
+ locale: fr-FR
20
+ languages: [fr-FR, fr, en-US, en]
21
+ timezone: Europe/Paris
22
+ user_agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36
23
+ accept_language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
24
+ fonts: [Arial, Helvetica, Times New Roman, Courier New, Verdana, Georgia, Tahoma]
25
+ modules:
26
+ enabled:
27
+ - webdriver
28
+ - chrome_runtime
29
+ - canvas
30
+ - audio
31
+ - intl
32
+ - webgl
33
+ - permissions
34
+ - user_agent_data
35
+ - pdf_viewer
36
+ policies:
37
+ consistency: strict
38
+ performance: balanced
@@ -0,0 +1,348 @@
1
+ /**
2
+ * audio.js
3
+ * Évasion pour l'API AudioContext / fingerprinting audio
4
+ *
5
+ * Ajoute un bruit déterministe aux signaux audio pour masquer
6
+ * les caractéristiques du système et éviter le fingerprinting.
7
+ *
8
+ * Problème ciblé: Les scripts de détection utilisent l'API AudioContext
9
+ * pour générer une empreinte unique du système audio.
10
+ *
11
+ * Compatibilité: Chrome 80+
12
+ *
13
+ * Référence: https://developer.mozilla.org/en-US/docs/Web/API/AudioContext
14
+ */
15
+
16
+ (function() {
17
+ 'use strict';
18
+
19
+ // =========================================================================
20
+ // 1. VÉRIFICATION DES DÉPENDANCES
21
+ // =========================================================================
22
+
23
+ // Vérifier que opts existe
24
+ var opts = window.__STEALTH_OPTS__ || {};
25
+
26
+ // Vérifier que AudioContext existe
27
+ if (typeof AudioContext === 'undefined' && typeof OfflineAudioContext === 'undefined') {
28
+ if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
29
+ console.warn('[stealth] AudioContext not available, skipping audio.js');
30
+ }
31
+ return;
32
+ }
33
+
34
+ // =========================================================================
35
+ // 2. FONCTION DE BRUIT DÉTERMINISTE
36
+ // =========================================================================
37
+
38
+ /**
39
+ * Génère une valeur de bruit déterministe basée sur une graine
40
+ * @param {number} seed - Graine pour le générateur
41
+ * @param {number} index - Index pour variation
42
+ * @returns {number} Valeur de bruit entre -1 et 1
43
+ */
44
+ function deterministicNoise(seed, index) {
45
+ // Combiner la graine et l'index
46
+ var value = seed + index * 0.01;
47
+ // Utiliser une fonction sinusoïdale pour générer un bruit pseudo-aléatoire
48
+ var noise = Math.sin(value * 10000) * Math.cos(value * 7777);
49
+ // Normaliser entre -1 et 1
50
+ return Math.max(-1, Math.min(1, noise));
51
+ }
52
+
53
+ /**
54
+ * Obtient la graine pour le bruit audio
55
+ * @returns {number} Graine de bruit
56
+ */
57
+ function getAudioSeed() {
58
+ // Utiliser la seed du profil si disponible
59
+ if (typeof opts.seed !== 'undefined') {
60
+ return opts.seed;
61
+ }
62
+ // Utiliser une valeur basée sur le profil matériel
63
+ if (opts.hardware_profile) {
64
+ var profileHash = 0;
65
+ for (var i = 0; i < opts.hardware_profile.length; i++) {
66
+ profileHash = ((profileHash << 5) - profileHash) + opts.hardware_profile.charCodeAt(i);
67
+ profileHash = profileHash & profileHash;
68
+ }
69
+ return Math.abs(profileHash);
70
+ }
71
+ // Valeur par défaut
72
+ return 42;
73
+ }
74
+
75
+ // =========================================================================
76
+ // 3. PATCH DE AudioBuffer.prototype.getChannelData
77
+ // =========================================================================
78
+
79
+ /**
80
+ * Patch getChannelData pour ajouter du bruit déterministe
81
+ */
82
+ function patchGetChannelData() {
83
+ try {
84
+ if (typeof AudioBuffer === 'undefined' || !AudioBuffer.prototype) {
85
+ return;
86
+ }
87
+
88
+ var seed = getAudioSeed();
89
+ var originalGetChannelData = AudioBuffer.prototype.getChannelData;
90
+
91
+ AudioBuffer.prototype.getChannelData = function(channel) {
92
+ // Appeler la méthode originale
93
+ var result = originalGetChannelData.call(this, channel);
94
+
95
+ // Ajouter du bruit déterministe
96
+ var noiseAmount = 0.0001 + (seed % 100) / 1000000;
97
+ var step = Math.max(1, Math.floor(result.length / 100));
98
+
99
+ for (var i = 0; i < result.length; i += step) {
100
+ var noise = deterministicNoise(seed, i) * noiseAmount;
101
+ result[i] = Math.max(-1, Math.min(1, result[i] + noise));
102
+ }
103
+
104
+ return result;
105
+ };
106
+
107
+ if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
108
+ console.log('[stealth] AudioBuffer.prototype.getChannelData patched');
109
+ }
110
+
111
+ } catch (e) {
112
+ console.warn('[stealth] patchGetChannelData error:', e);
113
+ }
114
+ }
115
+
116
+ // =========================================================================
117
+ // 4. PATCH DE AnalyserNode
118
+ // =========================================================================
119
+
120
+ /**
121
+ * Patch AnalyserNode pour masquer les caractéristiques audio
122
+ */
123
+ function patchAnalyserNode() {
124
+ try {
125
+ if (typeof AnalyserNode === 'undefined' || !AnalyserNode.prototype) {
126
+ return;
127
+ }
128
+
129
+ var seed = getAudioSeed();
130
+
131
+ // Patch getByteFrequencyData
132
+ var originalGetByteFrequencyData = AnalyserNode.prototype.getByteFrequencyData;
133
+ AnalyserNode.prototype.getByteFrequencyData = function(array) {
134
+ originalGetByteFrequencyData.call(this, array);
135
+ // Ajouter du bruit déterministe
136
+ var noiseAmount = 0.5 + (seed % 50) / 100;
137
+ for (var i = 0; i < array.length; i++) {
138
+ var noise = deterministicNoise(seed + i, i) * noiseAmount;
139
+ array[i] = Math.max(0, Math.min(255, array[i] + noise));
140
+ }
141
+ return array;
142
+ };
143
+
144
+ // Patch getByteTimeDomainData
145
+ var originalGetByteTimeDomainData = AnalyserNode.prototype.getByteTimeDomainData;
146
+ AnalyserNode.prototype.getByteTimeDomainData = function(array) {
147
+ originalGetByteTimeDomainData.call(this, array);
148
+ var noiseAmount = 0.5 + (seed % 50) / 100;
149
+ for (var i = 0; i < array.length; i++) {
150
+ var noise = deterministicNoise(seed + i * 2, i) * noiseAmount;
151
+ array[i] = Math.max(0, Math.min(255, array[i] + noise));
152
+ }
153
+ return array;
154
+ };
155
+
156
+ // Patch getFloatFrequencyData
157
+ if (typeof AnalyserNode.prototype.getFloatFrequencyData === 'function') {
158
+ var originalGetFloatFrequencyData = AnalyserNode.prototype.getFloatFrequencyData;
159
+ AnalyserNode.prototype.getFloatFrequencyData = function(array) {
160
+ originalGetFloatFrequencyData.call(this, array);
161
+ var noiseAmount = 0.5 + (seed % 50) / 100;
162
+ for (var i = 0; i < array.length; i++) {
163
+ var noise = deterministicNoise(seed + i * 3, i) * noiseAmount;
164
+ array[i] = Math.max(-200, Math.min(200, array[i] + noise));
165
+ }
166
+ return array;
167
+ };
168
+ }
169
+
170
+ if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
171
+ console.log('[stealth] AnalyserNode patched');
172
+ }
173
+
174
+ } catch (e) {
175
+ console.warn('[stealth] patchAnalyserNode error:', e);
176
+ }
177
+ }
178
+
179
+ // =========================================================================
180
+ // 5. PATCH DE OscillatorNode
181
+ // =========================================================================
182
+
183
+ /**
184
+ * Patch OscillatorNode pour masquer les caractéristiques audio
185
+ */
186
+ function patchOscillatorNode() {
187
+ try {
188
+ if (typeof OscillatorNode === 'undefined' || !OscillatorNode.prototype) {
189
+ return;
190
+ }
191
+
192
+ var seed = getAudioSeed();
193
+
194
+ // Patch start pour ajouter un décalage temporel
195
+ var originalStart = OscillatorNode.prototype.start;
196
+ OscillatorNode.prototype.start = function(when) {
197
+ // Ajouter un micro-décalage déterministe
198
+ var offset = (seed % 100) / 1000000;
199
+ var newWhen = (when || 0) + offset;
200
+ return originalStart.call(this, newWhen);
201
+ };
202
+
203
+ // Patch stop pour ajouter un décalage temporel
204
+ var originalStop = OscillatorNode.prototype.stop;
205
+ OscillatorNode.prototype.stop = function(when) {
206
+ var offset = (seed % 100) / 1000000;
207
+ var newWhen = (when || 0) + offset;
208
+ return originalStop.call(this, newWhen);
209
+ };
210
+
211
+ if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
212
+ console.log('[stealth] OscillatorNode patched');
213
+ }
214
+
215
+ } catch (e) {
216
+ console.warn('[stealth] patchOscillatorNode error:', e);
217
+ }
218
+ }
219
+
220
+ // =========================================================================
221
+ // 6. PATCH DE AudioContext
222
+ // =========================================================================
223
+
224
+ /**
225
+ * Patch AudioContext pour masquer les caractéristiques audio
226
+ */
227
+ function patchAudioContext() {
228
+ try {
229
+ if (typeof AudioContext === 'undefined') {
230
+ return;
231
+ }
232
+
233
+ var seed = getAudioSeed();
234
+
235
+ // Patch createAnalyser pour ajouter du bruit
236
+ var originalCreateAnalyser = AudioContext.prototype.createAnalyser;
237
+ AudioContext.prototype.createAnalyser = function() {
238
+ var analyser = originalCreateAnalyser.call(this);
239
+ // Ajouter une propriété cachée pour identifier le patch
240
+ analyser.__stealth_patched = true;
241
+ return analyser;
242
+ };
243
+
244
+ // Patch createOscillator pour ajouter du bruit
245
+ var originalCreateOscillator = AudioContext.prototype.createOscillator;
246
+ AudioContext.prototype.createOscillator = function() {
247
+ var oscillator = originalCreateOscillator.call(this);
248
+ oscillator.__stealth_patched = true;
249
+ return oscillator;
250
+ };
251
+
252
+ // Patch createBuffer pour ajouter du bruit
253
+ var originalCreateBuffer = AudioContext.prototype.createBuffer;
254
+ AudioContext.prototype.createBuffer = function(numChannels, length, sampleRate) {
255
+ var buffer = originalCreateBuffer.call(this, numChannels, length, sampleRate);
256
+ // Ajouter du bruit déterministe au buffer
257
+ for (var channel = 0; channel < numChannels; channel++) {
258
+ var data = buffer.getChannelData(channel);
259
+ var noiseAmount = 0.0001 + (seed % 100) / 1000000;
260
+ for (var i = 0; i < data.length; i += 10) {
261
+ var noise = deterministicNoise(seed + channel * 1000 + i, i) * noiseAmount;
262
+ data[i] = Math.max(-1, Math.min(1, data[i] + noise));
263
+ }
264
+ }
265
+ return buffer;
266
+ };
267
+
268
+ if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
269
+ console.log('[stealth] AudioContext patched');
270
+ }
271
+
272
+ } catch (e) {
273
+ console.warn('[stealth] patchAudioContext error:', e);
274
+ }
275
+ }
276
+
277
+ // =========================================================================
278
+ // 7. PATCH DE OfflineAudioContext
279
+ // =========================================================================
280
+
281
+ /**
282
+ * Patch OfflineAudioContext pour masquer les caractéristiques audio
283
+ */
284
+ function patchOfflineAudioContext() {
285
+ try {
286
+ if (typeof OfflineAudioContext === 'undefined') {
287
+ return;
288
+ }
289
+
290
+ var seed = getAudioSeed();
291
+
292
+ // Patch startRendering pour ajouter du bruit
293
+ var originalStartRendering = OfflineAudioContext.prototype.startRendering;
294
+ OfflineAudioContext.prototype.startRendering = function() {
295
+ var result = originalStartRendering.call(this);
296
+ // Ajouter du bruit déterministe au résultat
297
+ if (result && typeof result.then === 'function') {
298
+ return result.then(function(audioBuffer) {
299
+ if (audioBuffer && audioBuffer.getChannelData) {
300
+ var noiseAmount = 0.0001 + (seed % 100) / 1000000;
301
+ for (var channel = 0; channel < audioBuffer.numberOfChannels; channel++) {
302
+ var data = audioBuffer.getChannelData(channel);
303
+ for (var i = 0; i < data.length; i += 10) {
304
+ var noise = deterministicNoise(seed + channel * 1000 + i, i) * noiseAmount;
305
+ data[i] = Math.max(-1, Math.min(1, data[i] + noise));
306
+ }
307
+ }
308
+ }
309
+ return audioBuffer;
310
+ });
311
+ }
312
+ return result;
313
+ };
314
+
315
+ if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
316
+ console.log('[stealth] OfflineAudioContext patched');
317
+ }
318
+
319
+ } catch (e) {
320
+ console.warn('[stealth] patchOfflineAudioContext error:', e);
321
+ }
322
+ }
323
+
324
+ // =========================================================================
325
+ // 8. APPLICATION DES PATCHS
326
+ // =========================================================================
327
+
328
+ // Appliquer tous les patches
329
+ patchGetChannelData();
330
+ patchAnalyserNode();
331
+ patchOscillatorNode();
332
+ patchAudioContext();
333
+ patchOfflineAudioContext();
334
+
335
+ // =========================================================================
336
+ // 9. LOG DE DÉBOGAGE
337
+ // =========================================================================
338
+
339
+ if (typeof window.__STEALTH_DEBUG__ !== 'undefined' && window.__STEALTH_DEBUG__) {
340
+ console.log('[stealth] audio.js loaded successfully');
341
+ console.log('[stealth] AudioContext patched:',
342
+ typeof AudioContext !== 'undefined');
343
+ console.log('[stealth] OfflineAudioContext patched:',
344
+ typeof OfflineAudioContext !== 'undefined');
345
+ console.log('[stealth] Audio seed:', getAudioSeed());
346
+ }
347
+
348
+ })();