@jshookmcp/jshook 0.2.8 → 0.3.0

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 (162) hide show
  1. package/README.md +36 -5
  2. package/README.zh.md +36 -5
  3. package/dist/{AntiCheatDetector-S8VRj-dD.mjs → AntiCheatDetector-CqGDXmfc.mjs} +160 -54
  4. package/dist/{CodeInjector-4Z3ngPoX.mjs → CodeInjector-BdjRfNx7.mjs} +5 -5
  5. package/dist/ConsoleMonitor-DykL3IAw.mjs +2269 -0
  6. package/dist/{DarwinAPI-B8hg_yhz.mjs → DarwinAPI-ETyy0xyo.mjs} +1 -1
  7. package/dist/DetailedDataManager-HT49OrvF.mjs +217 -0
  8. package/dist/EventBus-DFKvADm3.mjs +141 -0
  9. package/dist/EvidenceGraphBridge-318Oi0Lf.mjs +153 -0
  10. package/dist/{ExtensionManager-D5-bO9D8.mjs → ExtensionManager-BDMsY2Dz.mjs} +27 -13
  11. package/dist/{FingerprintManager-BVxFJL2-.mjs → FingerprintManager-BN4UQWnX.mjs} +1 -1
  12. package/dist/{HardwareBreakpoint-DK1yjWkV.mjs → HardwareBreakpoint-Cc2AFq1Y.mjs} +3 -3
  13. package/dist/{HeapAnalyzer-CEbo10xU.mjs → HeapAnalyzer-DruMgsgj.mjs} +21 -21
  14. package/dist/HookGeneratorBuilders.core.generators.storage-CTbB4Lcx.mjs +566 -0
  15. package/dist/InstrumentationSession-DLH0vd-z.mjs +244 -0
  16. package/dist/{MemoryController-DdtnBdD4.mjs → MemoryController-CMtviNW_.mjs} +3 -3
  17. package/dist/{MemoryScanSession-RMixN3bX.mjs → MemoryScanSession-ITgb_NMi.mjs} +81 -78
  18. package/dist/{MemoryScanner-QjK4ld0B.mjs → MemoryScanner-CiL7Z3ey.mjs} +50 -21
  19. package/dist/{NativeMemoryManager.impl-CB6gJ0NM.mjs → NativeMemoryManager.impl-D9Lkovvn.mjs} +20 -56
  20. package/dist/{NativeMemoryManager.utils-BML4q1ry.mjs → NativeMemoryManager.utils-BBlAixF5.mjs} +1 -1
  21. package/dist/{PEAnalyzer-CK0xe0Fs.mjs → PEAnalyzer-DMQ44gen.mjs} +16 -16
  22. package/dist/PageController-BPJNqqBN.mjs +431 -0
  23. package/dist/{PointerChainEngine-Cd73qu5b.mjs → PointerChainEngine-K7wN8Z-w.mjs} +10 -7
  24. package/dist/PrerequisiteError-TuyZIs6n.mjs +20 -0
  25. package/dist/ProcessRegistry-zGg12QbE.mjs +74 -0
  26. package/dist/ResponseBuilder-CJXWmWNw.mjs +143 -0
  27. package/dist/ReverseEvidenceGraph-C02-gXOh.mjs +269 -0
  28. package/dist/ScriptManager-ZuWD-0Jg.mjs +3003 -0
  29. package/dist/{Speedhack-CeF0XmEz.mjs → Speedhack-D-z0umeT.mjs} +2 -2
  30. package/dist/{StructureAnalyzer-D4GkMduU.mjs → StructureAnalyzer-Cav5AVSL.mjs} +9 -6
  31. package/dist/ToolCatalog-5OJdMiF0.mjs +582 -0
  32. package/dist/ToolError-jh9whhMd.mjs +15 -0
  33. package/dist/ToolProbe-DbCFGyrg.mjs +45 -0
  34. package/dist/ToolRegistry-B9krbTtI.mjs +180 -0
  35. package/dist/ToolRouter.policy-BGDAGyeH.mjs +344 -0
  36. package/dist/TraceRecorder-B41Z5XBj.mjs +1286 -0
  37. package/dist/{Win32API-Bc0QnQsN.mjs → Win32API-C2kjj0ze.mjs} +19 -13
  38. package/dist/{Win32Debug-DUHt9XUn.mjs → Win32Debug-CKrGOTpo.mjs} +3 -3
  39. package/dist/WorkflowEngine-DJ6M4opp.mjs +569 -0
  40. package/dist/analysis-BHeJW2Nb.mjs +1234 -0
  41. package/dist/antidebug-BRKeyt27.mjs +1081 -0
  42. package/dist/artifactRetention-CPXkUJXp.mjs +598 -0
  43. package/dist/artifacts-DkfosXH3.mjs +59 -0
  44. package/dist/authorization-schema-DRqyJMSk.mjs +31 -0
  45. package/dist/betterSqlite3-DLSBZodi.mjs +74 -0
  46. package/dist/binary-instrument--V3MAhJ4.mjs +971 -0
  47. package/dist/bind-helpers-ClV34xdn.mjs +42 -0
  48. package/dist/boringssl-inspector-Bo_LOLaS.mjs +180 -0
  49. package/dist/browser-Dx3_S2cG.mjs +4369 -0
  50. package/dist/capabilities-CcHlvWgK.mjs +33 -0
  51. package/dist/concurrency-Drev_Vz9.mjs +41 -0
  52. package/dist/{constants-CCvsN80K.mjs → constants-CDZLOoVv.mjs} +105 -48
  53. package/dist/coordination-DgItD9DL.mjs +259 -0
  54. package/dist/debugger-RS3RSAqs.mjs +1288 -0
  55. package/dist/definitions-BEoYofW5.mjs +47 -0
  56. package/dist/definitions-BRaefg3u.mjs +365 -0
  57. package/dist/definitions-BbkvZkiv.mjs +96 -0
  58. package/dist/definitions-BtWSHJ3o.mjs +17 -0
  59. package/dist/definitions-C1gCHO0i.mjs +43 -0
  60. package/dist/definitions-CDOg_b-l.mjs +138 -0
  61. package/dist/definitions-CVPD9hzZ.mjs +54 -0
  62. package/dist/definitions-Cea8Lgl7.mjs +94 -0
  63. package/dist/definitions-DAgIyjxM.mjs +10 -0
  64. package/dist/definitions-DJA27nsL.mjs +66 -0
  65. package/dist/definitions-DKPFU3LW.mjs +25 -0
  66. package/dist/definitions-DPRpZQ96.mjs +47 -0
  67. package/dist/definitions-DUE5gmdn.mjs +18 -0
  68. package/dist/definitions-DYVjOtxa.mjs +26 -0
  69. package/dist/definitions-DcYLVLCo.mjs +37 -0
  70. package/dist/definitions-Pp5LI2H4.mjs +27 -0
  71. package/dist/definitions-j9KdHVNR.mjs +14 -0
  72. package/dist/definitions-uzkjBwa7.mjs +258 -0
  73. package/dist/definitions-va-AnLuQ.mjs +28 -0
  74. package/dist/encoding-DJeqHmpd.mjs +1079 -0
  75. package/dist/evidence-graph-bridge-DcYizFk2.mjs +136 -0
  76. package/dist/{factory-CibqTNC8.mjs → factory-C90tBff6.mjs} +41 -56
  77. package/dist/flat-target-session-Dgax2Cy3.mjs +29 -0
  78. package/dist/graphql-CoHrhweh.mjs +1197 -0
  79. package/dist/handlers-4jmR0nMs.mjs +898 -0
  80. package/dist/handlers-BAHPxcch.mjs +789 -0
  81. package/dist/handlers-BOs9b907.mjs +2600 -0
  82. package/dist/handlers-BWXEy6ef.mjs +917 -0
  83. package/dist/handlers-Bndn6QvE.mjs +111 -0
  84. package/dist/handlers-BqC4bD4s.mjs +681 -0
  85. package/dist/handlers-BtYq60bM2.mjs +276 -0
  86. package/dist/handlers-BzgcB4iv.mjs +799 -0
  87. package/dist/handlers-CRyRWj2b.mjs +859 -0
  88. package/dist/handlers-CVv2H1uq.mjs +592 -0
  89. package/dist/handlers-Dl5a7JS4.mjs +572 -0
  90. package/dist/handlers-Dx2d7jt7.mjs +2537 -0
  91. package/dist/handlers-Dz9PYsCa.mjs +2805 -0
  92. package/dist/handlers-HujRKC3b.mjs +661 -0
  93. package/dist/handlers.impl-XWXkQfyi.mjs +807 -0
  94. package/dist/hooks-B1B8NRHL.mjs +898 -0
  95. package/dist/index.mjs +491 -259
  96. package/dist/{logger-BmWzC2lM.mjs → logger-Dh_xb7_2.mjs} +14 -6
  97. package/dist/maintenance-PRMkLVRW.mjs +835 -0
  98. package/dist/manifest-67Bok-Si.mjs +58 -0
  99. package/dist/manifest-6lNTMZAB2.mjs +87 -0
  100. package/dist/manifest-B2duEHiH.mjs +90 -0
  101. package/dist/manifest-B6EY9Vm8.mjs +57 -0
  102. package/dist/manifest-B6nKSbyY.mjs +95 -0
  103. package/dist/manifest-BL8AQNPF.mjs +106 -0
  104. package/dist/manifest-BSZvJJmV.mjs +47 -0
  105. package/dist/manifest-BU7qzUyX.mjs +418 -0
  106. package/dist/manifest-Bl62e8WK.mjs +49 -0
  107. package/dist/manifest-Bo5cXjdt.mjs +82 -0
  108. package/dist/manifest-BpS4gtUK.mjs +1347 -0
  109. package/dist/manifest-Bv65_e2W.mjs +101 -0
  110. package/dist/manifest-BytNIF4Z.mjs +117 -0
  111. package/dist/manifest-C-xtsjS3.mjs +81 -0
  112. package/dist/manifest-CDYl7OhA.mjs +66 -0
  113. package/dist/manifest-CRZ3xmkD.mjs +61 -0
  114. package/dist/manifest-CoW6u4Tp.mjs +132 -0
  115. package/dist/manifest-Cq5zN_8A.mjs +50 -0
  116. package/dist/manifest-D7YZM_2e.mjs +194 -0
  117. package/dist/manifest-DE_VrAeQ.mjs +314 -0
  118. package/dist/manifest-DGsXSCpT.mjs +39 -0
  119. package/dist/manifest-DJ2vfEuW.mjs +156 -0
  120. package/dist/manifest-DPXDYhEu.mjs +80 -0
  121. package/dist/manifest-Dd4fQb0a.mjs +322 -0
  122. package/dist/manifest-Deq6opGg.mjs +223 -0
  123. package/dist/manifest-DfJTafJK.mjs +37 -0
  124. package/dist/manifest-DgOdgN_j.mjs +50 -0
  125. package/dist/manifest-DlbMW4v4.mjs +47 -0
  126. package/dist/manifest-DmVfbH0w.mjs +374 -0
  127. package/dist/manifest-Dog6Ddjr.mjs +109 -0
  128. package/dist/manifest-DvgU5FWb.mjs +58 -0
  129. package/dist/manifest-HsfDBs7j.mjs +50 -0
  130. package/dist/manifest-I8oQHvCG.mjs +186 -0
  131. package/dist/manifest-NvH_a-av.mjs +786 -0
  132. package/dist/manifest-cEJU1v0Z.mjs +129 -0
  133. package/dist/manifest-wOl5XLB12.mjs +112 -0
  134. package/dist/modules-tZozf0LQ.mjs +10635 -0
  135. package/dist/mojo-ipc-DXNEXEqb.mjs +640 -0
  136. package/dist/network-CPVvwvFg.mjs +3852 -0
  137. package/dist/{artifacts-BbdOMET5.mjs → outputPaths-um7lCRY3.mjs} +219 -216
  138. package/dist/parse-args-B4cY5Vx5.mjs +39 -0
  139. package/dist/platform-CYeFoTWp.mjs +2161 -0
  140. package/dist/process-BTbgcVc6.mjs +1306 -0
  141. package/dist/proxy-r8YN6nP1.mjs +192 -0
  142. package/dist/registry-Bl8ZQW61.mjs +34 -0
  143. package/dist/response-CWhh2aLo.mjs +34 -0
  144. package/dist/server/plugin-api.mjs +2 -2
  145. package/dist/shared-state-board-BoZnSoj-.mjs +586 -0
  146. package/dist/sourcemap-BIDHUVXy.mjs +934 -0
  147. package/dist/ssrf-policy-Dsqd-DTX.mjs +166 -0
  148. package/dist/streaming-Dal6utPp.mjs +725 -0
  149. package/dist/tool-builder-BHJp32mV.mjs +186 -0
  150. package/dist/transform-DRVgGG90.mjs +1011 -0
  151. package/dist/types-Bx92KJfT.mjs +4 -0
  152. package/dist/wasm-BYx5UOeG.mjs +1044 -0
  153. package/dist/webcrack-Be0_FccV.mjs +747 -0
  154. package/dist/workflow-BpuKEtvn.mjs +725 -0
  155. package/package.json +82 -49
  156. package/dist/ExtensionManager-CPTJhHFg.mjs +0 -2
  157. package/dist/ToolCatalog-Bq4V2sbJ.mjs +0 -67201
  158. package/dist/{CacheAdapters-CzFNpD9a.mjs → CacheAdapters-jJFy20G-.mjs} +0 -0
  159. package/dist/{StealthVerifier-BzBCFiwx.mjs → StealthVerifier-BWmPgQsv.mjs} +0 -0
  160. package/dist/{VersionDetector-CNXcvD46.mjs → VersionDetector-K3V4vGsw.mjs} +0 -0
  161. package/dist/{formatAddress-ChCSIRWT.mjs → formatAddress-nnMvEohD.mjs} +0 -0
  162. package/dist/{types-BBjOqye-.mjs → types-DDBWs9UP.mjs} +1 -1
@@ -1,49 +1,10 @@
1
- import { t as logger } from "./logger-BmWzC2lM.mjs";
2
- import { a as MemoryProtection, t as createPlatformProvider } from "./factory-CibqTNC8.mjs";
3
- import { v as isKoffiAvailable, y as isWindows } from "./Win32API-Bc0QnQsN.mjs";
4
- import { i as parsePattern, t as findPatternInBuffer } from "./NativeMemoryManager.utils-BML4q1ry.mjs";
1
+ import { t as logger } from "./logger-Dh_xb7_2.mjs";
2
+ import { v as isKoffiAvailable, y as isWindows } from "./Win32API-C2kjj0ze.mjs";
3
+ import { n as cpuLimit } from "./concurrency-Drev_Vz9.mjs";
4
+ import { t as createPlatformProvider } from "./factory-C90tBff6.mjs";
5
+ import { i as parsePattern, t as findPatternInBuffer } from "./NativeMemoryManager.utils-BBlAixF5.mjs";
5
6
  import { exec } from "node:child_process";
6
7
  import { promisify } from "node:util";
7
- //#region src/utils/concurrency.ts
8
- function pLimit(concurrency) {
9
- if (concurrency < 1) throw new RangeError("concurrency must be >= 1");
10
- let activeCount = 0;
11
- const queue = [];
12
- function next() {
13
- if (queue.length > 0 && activeCount < concurrency) {
14
- activeCount++;
15
- queue.shift()();
16
- }
17
- }
18
- function run(fn) {
19
- return new Promise((resolve, reject) => {
20
- const execute = async () => {
21
- try {
22
- resolve(await fn());
23
- } catch (err) {
24
- reject(err);
25
- } finally {
26
- activeCount--;
27
- next();
28
- }
29
- };
30
- if (activeCount < concurrency) {
31
- activeCount++;
32
- execute();
33
- } else queue.push(() => {
34
- execute();
35
- });
36
- });
37
- }
38
- return run;
39
- }
40
- /** External CLI calls, HAR export, large file I/O */
41
- const ioLimit = pLimit(parseInt(process.env.jshook_IO_CONCURRENCY || "4", 10));
42
- /** CPU-heavy: AST parsing, deobfuscation, binary decoding */
43
- const cpuLimit = pLimit(parseInt(process.env.jshook_CPU_CONCURRENCY || "2", 10));
44
- /** CDP-heavy: heap snapshots, traces, profiling */
45
- const cdpLimit = pLimit(parseInt(process.env.jshook_CDP_CONCURRENCY || "2", 10));
46
- //#endregion
47
8
  //#region src/native/NativeMemoryManager.availability.ts
48
9
  async function checkNativeMemoryAvailability(execAsync) {
49
10
  if (process.platform === "darwin") return checkDarwinAvailability(execAsync);
@@ -135,11 +96,14 @@ function scanRegionInChunks(region, patternBytes, mask, readChunk, chunkSize = S
135
96
  * Win32-only methods (injection, debug) are guarded by platform checks.
136
97
  */
137
98
  var NativeMemoryManager = class {
138
- _provider = null;
99
+ providerCache = null;
139
100
  /** Lazily create the platform memory provider */
140
101
  get provider() {
141
- if (!this._provider) this._provider = createPlatformProvider();
142
- return this._provider;
102
+ if (!this.providerCache) this.providerCache = createPlatformProvider();
103
+ return this.providerCache;
104
+ }
105
+ set provider(value) {
106
+ this.providerCache = value;
143
107
  }
144
108
  async checkAvailability() {
145
109
  return checkNativeMemoryAvailability(execAsync);
@@ -363,7 +327,7 @@ var NativeMemoryManager = class {
363
327
  error: "DLL injection is only supported on Windows"
364
328
  };
365
329
  try {
366
- const { openProcessForMemory, CloseHandle, WriteProcessMemory, VirtualAllocEx, CreateRemoteThread, GetModuleHandle, GetProcAddress, PAGE, MEM } = await import("./Win32API-Bc0QnQsN.mjs").then((n) => n.g);
330
+ const { openProcessForMemory, CloseHandle, WriteProcessMemory, VirtualAllocEx, CreateRemoteThread, GetModuleHandle, GetProcAddress, PAGE, MEM } = await import("./Win32API-C2kjj0ze.mjs").then((n) => n.g);
367
331
  const handle = openProcessForMemory(pid, true);
368
332
  try {
369
333
  const loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
@@ -413,7 +377,7 @@ var NativeMemoryManager = class {
413
377
  let buffer;
414
378
  if (encoding === "base64") buffer = Buffer.from(shellcode, "base64");
415
379
  else buffer = Buffer.from(shellcode.replace(/\s/g, ""), "hex");
416
- const { openProcessForMemory, CloseHandle, WriteProcessMemory, VirtualAllocEx, VirtualProtectEx, CreateRemoteThread, PAGE, MEM } = await import("./Win32API-Bc0QnQsN.mjs").then((n) => n.g);
380
+ const { openProcessForMemory, CloseHandle, WriteProcessMemory, VirtualAllocEx, VirtualProtectEx, CreateRemoteThread, PAGE, MEM } = await import("./Win32API-C2kjj0ze.mjs").then((n) => n.g);
417
381
  const handle = openProcessForMemory(pid, true);
418
382
  try {
419
383
  const remoteMem = VirtualAllocEx(handle, 0n, buffer.length, MEM.COMMIT | MEM.RESERVE, PAGE.READWRITE);
@@ -460,7 +424,7 @@ var NativeMemoryManager = class {
460
424
  error: "Debug port check is only supported on Windows"
461
425
  };
462
426
  try {
463
- const { openProcessForMemory, CloseHandle, NtQueryInformationProcess } = await import("./Win32API-Bc0QnQsN.mjs").then((n) => n.g);
427
+ const { openProcessForMemory, CloseHandle, NtQueryInformationProcess } = await import("./Win32API-C2kjj0ze.mjs").then((n) => n.g);
464
428
  const handle = openProcessForMemory(pid, false);
465
429
  try {
466
430
  const { status, debugPort } = NtQueryInformationProcess(handle, 7);
@@ -502,12 +466,12 @@ function regionInfoToMemoryRegion(info) {
502
466
  }
503
467
  /** Convert MemoryProtection flags to human-readable string */
504
468
  function protectionToString(prot) {
505
- if (prot === MemoryProtection.NoAccess) return "NOACCESS";
469
+ if (prot === 0) return "NOACCESS";
506
470
  const parts = [];
507
- const hasRead = (prot & MemoryProtection.Read) !== 0;
508
- const hasWrite = (prot & MemoryProtection.Write) !== 0;
509
- const hasExec = (prot & MemoryProtection.Execute) !== 0;
510
- const hasGuard = (prot & MemoryProtection.Guard) !== 0;
471
+ const hasRead = (prot & 1) !== 0;
472
+ const hasWrite = (prot & 2) !== 0;
473
+ const hasExec = (prot & 4) !== 0;
474
+ const hasGuard = (prot & 8) !== 0;
511
475
  if (hasRead && hasWrite && hasExec) parts.push("RWX");
512
476
  else if (hasRead && hasExec) parts.push("RX");
513
477
  else if (hasRead && hasWrite) parts.push("RW");
@@ -518,4 +482,4 @@ function protectionToString(prot) {
518
482
  }
519
483
  const nativeMemoryManager = new NativeMemoryManager();
520
484
  //#endregion
521
- export { ioLimit as i, cdpLimit as n, cpuLimit as r, nativeMemoryManager as t };
485
+ export { nativeMemoryManager as t };
@@ -1,4 +1,4 @@
1
- import { u as PAGE, v as isKoffiAvailable$1 } from "./Win32API-Bc0QnQsN.mjs";
1
+ import { u as PAGE, v as isKoffiAvailable$1 } from "./Win32API-C2kjj0ze.mjs";
2
2
  //#region src/native/NativeMemoryManager.utils.ts
3
3
  function isKoffiAvailable() {
4
4
  return isKoffiAvailable$1();
@@ -1,5 +1,5 @@
1
- import { t as logger } from "./logger-BmWzC2lM.mjs";
2
- import { a as GetModuleFileNameEx, b as openProcessForMemory, d as ReadProcessMemory, i as GetModuleBaseName, n as EnumProcessModules, s as GetModuleInformation, t as CloseHandle } from "./Win32API-Bc0QnQsN.mjs";
1
+ import { t as logger } from "./logger-Dh_xb7_2.mjs";
2
+ import { a as GetModuleFileNameEx, b as openProcessForMemory, d as ReadProcessMemory, i as GetModuleBaseName, n as EnumProcessModules, s as GetModuleInformation, t as CloseHandle } from "./Win32API-C2kjj0ze.mjs";
3
3
  import { promises } from "node:fs";
4
4
  //#region src/native/PEAnalyzer.types.ts
5
5
  /** PE section characteristic flags */
@@ -104,7 +104,7 @@ var PEAnalyzer = class {
104
104
  const base = BigInt(moduleBase);
105
105
  const hProcess = openProcessForMemory(pid);
106
106
  try {
107
- const headers = await this._readCoreHeaders(hProcess, base);
107
+ const headers = await this.readCoreHeaders(hProcess, base);
108
108
  const sections = [];
109
109
  for (let i = 0; i < headers.numSections; i++) {
110
110
  const off = headers.firstSectionOffset + i * SECTION_HEADER_SIZE;
@@ -138,7 +138,7 @@ var PEAnalyzer = class {
138
138
  const base = BigInt(moduleBase);
139
139
  const hProcess = openProcessForMemory(pid);
140
140
  try {
141
- const headers = await this._readCoreHeaders(hProcess, base);
141
+ const headers = await this.readCoreHeaders(hProcess, base);
142
142
  const importRva = headers.dataDirectories[IMAGE_DIRECTORY_ENTRY.IMPORT];
143
143
  if (!importRva || importRva.rva === 0) return [];
144
144
  const imports = [];
@@ -151,7 +151,7 @@ var PEAnalyzer = class {
151
151
  const nullIdx = nameData.indexOf(0);
152
152
  const dllName = nameData.subarray(0, nullIdx > 0 ? nullIdx : 256).toString("ascii");
153
153
  const originalFirstThunkRva = desc.readUInt32LE(0) || desc.readUInt32LE(16);
154
- const functions = this._readThunkArray(hProcess, base, originalFirstThunkRva, headers.isPE32Plus);
154
+ const functions = this.readThunkArray(hProcess, base, originalFirstThunkRva, headers.isPE32Plus);
155
155
  imports.push({
156
156
  dllName,
157
157
  functions
@@ -170,7 +170,7 @@ var PEAnalyzer = class {
170
170
  const base = BigInt(moduleBase);
171
171
  const hProcess = openProcessForMemory(pid);
172
172
  try {
173
- const exportDir = (await this._readCoreHeaders(hProcess, base)).dataDirectories[IMAGE_DIRECTORY_ENTRY.EXPORT];
173
+ const exportDir = (await this.readCoreHeaders(hProcess, base)).dataDirectories[IMAGE_DIRECTORY_ENTRY.EXPORT];
174
174
  if (!exportDir || exportDir.rva === 0) return [];
175
175
  const expData = ReadProcessMemory(hProcess, base + BigInt(exportDir.rva), 40);
176
176
  const numberOfNames = expData.readUInt32LE(24);
@@ -213,7 +213,7 @@ var PEAnalyzer = class {
213
213
  const hProcess = openProcessForMemory(pid);
214
214
  const detections = [];
215
215
  try {
216
- const modules = this._enumerateModulesInternal(hProcess);
216
+ const modules = this.enumerateModulesInternal(hProcess);
217
217
  const targets = moduleName ? modules.filter((m) => m.name.toLowerCase().includes(moduleName.toLowerCase())) : modules;
218
218
  for (const mod of targets) try {
219
219
  const diskData = await promises.readFile(mod.path);
@@ -222,12 +222,12 @@ var PEAnalyzer = class {
222
222
  const funcRva = parseInt(exp.rva, 16);
223
223
  if (funcRva === 0 || exp.forwardedTo) continue;
224
224
  const memBytes = ReadProcessMemory(hProcess, BigInt(mod.base) + BigInt(funcRva), COMPARE_BYTES);
225
- const diskOffset = this._rvaToFileOffset(diskData, funcRva);
225
+ const diskOffset = this.rvaToFileOffset(diskData, funcRva);
226
226
  if (diskOffset < 0 || diskOffset + COMPARE_BYTES > diskData.length) continue;
227
227
  const diskBytes = diskData.subarray(diskOffset, diskOffset + COMPARE_BYTES);
228
228
  if (!memBytes.equals(diskBytes)) {
229
- const hookType = this._classifyHook(memBytes);
230
- const jumpTarget = this._decodeJumpTarget(memBytes, BigInt(mod.base) + BigInt(funcRva));
229
+ const hookType = this.classifyHook(memBytes);
230
+ const jumpTarget = this.decodeJumpTarget(memBytes, BigInt(mod.base) + BigInt(funcRva));
231
231
  detections.push({
232
232
  address: `0x${(BigInt(mod.base) + BigInt(funcRva)).toString(16)}`,
233
233
  moduleName: mod.name,
@@ -273,7 +273,7 @@ var PEAnalyzer = class {
273
273
  });
274
274
  return anomalies;
275
275
  }
276
- async _readCoreHeaders(hProcess, base) {
276
+ async readCoreHeaders(hProcess, base) {
277
277
  const e_lfanew = ReadProcessMemory(hProcess, base, 64).readUInt32LE(60);
278
278
  const ntData = ReadProcessMemory(hProcess, base + BigInt(e_lfanew), 264);
279
279
  const numSections = ntData.readUInt16LE(6);
@@ -296,7 +296,7 @@ var PEAnalyzer = class {
296
296
  dataDirectories
297
297
  };
298
298
  }
299
- _readThunkArray(hProcess, base, thunkRva, isPE32Plus) {
299
+ readThunkArray(hProcess, base, thunkRva, isPE32Plus) {
300
300
  const thunkSize = isPE32Plus ? 8 : 4;
301
301
  const functions = [];
302
302
  const IMAGE_ORDINAL_FLAG = isPE32Plus ? 9223372036854775808n : 2147483648n;
@@ -326,7 +326,7 @@ var PEAnalyzer = class {
326
326
  }
327
327
  return functions;
328
328
  }
329
- _enumerateModulesInternal(hProcess) {
329
+ enumerateModulesInternal(hProcess) {
330
330
  const modules = [];
331
331
  try {
332
332
  const { modules: modHandles, count } = EnumProcessModules(hProcess);
@@ -347,7 +347,7 @@ var PEAnalyzer = class {
347
347
  }
348
348
  return modules;
349
349
  }
350
- _rvaToFileOffset(peData, rva) {
350
+ rvaToFileOffset(peData, rva) {
351
351
  const e_lfanew = peData.readUInt32LE(60);
352
352
  const numSections = peData.readUInt16LE(e_lfanew + 6);
353
353
  const sizeOfOptionalHeader = peData.readUInt16LE(e_lfanew + 20);
@@ -362,13 +362,13 @@ var PEAnalyzer = class {
362
362
  }
363
363
  return -1;
364
364
  }
365
- _classifyHook(memBytes) {
365
+ classifyHook(memBytes) {
366
366
  if (memBytes[0] === 233) return "jmp_rel32";
367
367
  if (memBytes[0] === 255 && memBytes[1] === 37) return "jmp_abs64";
368
368
  if (memBytes[0] === 104 && memBytes[5] === 195) return "push_ret";
369
369
  return "unknown";
370
370
  }
371
- _decodeJumpTarget(memBytes, funcAddr) {
371
+ decodeJumpTarget(memBytes, funcAddr) {
372
372
  if (memBytes[0] === 233) {
373
373
  const rel32 = memBytes.readInt32LE(1);
374
374
  return `0x${(funcAddr + 5n + BigInt(rel32)).toString(16)}`;
@@ -0,0 +1,431 @@
1
+ import { t as logger } from "./logger-Dh_xb7_2.mjs";
2
+ import { Jt as PAGE_NETWORK_IDLE_TIMEOUT_MS, qt as PAGE_FRAME_SELECTOR_TIMEOUT_MS } from "./constants-CDZLOoVv.mjs";
3
+ import { setTimeout as setTimeout$1 } from "node:timers/promises";
4
+ //#region src/modules/collector/PageController.ts
5
+ var PageController = class {
6
+ constructor(collector) {
7
+ this.collector = collector;
8
+ }
9
+ async getBrowser() {
10
+ return this.collector.getBrowser();
11
+ }
12
+ hasAttachedTargetSession() {
13
+ return this.collector.getAttachedTargetSession() !== null;
14
+ }
15
+ getAttachedTargetInfo() {
16
+ return this.collector.getAttachedTargetInfo();
17
+ }
18
+ async evaluateAttachedTarget(code, options) {
19
+ return await this.collector.getBrowserTargetSessionManager().evaluate(code, options);
20
+ }
21
+ async addScriptToAttachedTarget(source) {
22
+ return await this.collector.getBrowserTargetSessionManager().addScriptToEvaluateOnNewDocument(source);
23
+ }
24
+ async navigate(url, options) {
25
+ const page = await this.collector.getActivePage();
26
+ const startTime = Date.now();
27
+ await page.goto(url, {
28
+ waitUntil: options?.waitUntil || "networkidle2",
29
+ timeout: options?.timeout || 3e4
30
+ });
31
+ const loadTime = Date.now() - startTime;
32
+ const title = await page.title();
33
+ const currentUrl = page.url();
34
+ logger.info(`Navigated to: ${url}`);
35
+ return {
36
+ url: currentUrl,
37
+ title,
38
+ loadTime
39
+ };
40
+ }
41
+ async reload(options) {
42
+ await (await this.collector.getActivePage()).reload({
43
+ waitUntil: options?.waitUntil || "networkidle2",
44
+ timeout: options?.timeout || 3e4
45
+ });
46
+ logger.info("Page reloaded");
47
+ }
48
+ async goBack(timeout = 1e4) {
49
+ await (await this.collector.getActivePage()).goBack({
50
+ waitUntil: "domcontentloaded",
51
+ timeout
52
+ });
53
+ logger.info("Navigated back");
54
+ }
55
+ async goForward(timeout = 1e4) {
56
+ await (await this.collector.getActivePage()).goForward({
57
+ waitUntil: "domcontentloaded",
58
+ timeout
59
+ });
60
+ logger.info("Navigated forward");
61
+ }
62
+ async click(selector, options, frameOptions) {
63
+ const page = await this.collector.getActivePage();
64
+ const context = await this.resolveFrame(page, frameOptions);
65
+ const timeout = options?.timeout;
66
+ const clickOptions = {
67
+ button: options?.button || "left",
68
+ clickCount: options?.clickCount || 1,
69
+ delay: options?.delay
70
+ };
71
+ if (options?.offset) clickOptions.offset = options.offset;
72
+ if (typeof timeout === "number" && Number.isFinite(timeout) && timeout > 0) {
73
+ page.setDefaultTimeout(timeout);
74
+ try {
75
+ await context.click(selector, clickOptions);
76
+ } finally {
77
+ page.setDefaultTimeout(this.collector["config"]?.timeout ?? 3e4);
78
+ }
79
+ } else await context.click(selector, clickOptions);
80
+ logger.info(`Clicked: ${selector}${frameOptions?.frameUrl || frameOptions?.frameSelector ? " (in frame)" : ""}`);
81
+ }
82
+ async type(selector, text, options, frameOptions) {
83
+ const page = await this.collector.getActivePage();
84
+ await (await this.resolveFrame(page, frameOptions)).type(selector, text, { delay: options?.delay });
85
+ logger.info(`Typed into ${selector}: ${text.substring(0, 20)}...`);
86
+ }
87
+ async select(selector, values, frameOptions) {
88
+ const page = await this.collector.getActivePage();
89
+ await (await this.resolveFrame(page, frameOptions)).select(selector, ...values);
90
+ logger.info(`Selected in ${selector}: ${values.join(", ")}`);
91
+ }
92
+ async hover(selector, frameOptions) {
93
+ const page = await this.collector.getActivePage();
94
+ await (await this.resolveFrame(page, frameOptions)).hover(selector);
95
+ logger.info(`Hovered: ${selector}`);
96
+ }
97
+ async scroll(options) {
98
+ await (await this.collector.getActivePage()).evaluate((opts) => {
99
+ window.scrollTo(opts.x || 0, opts.y || 0);
100
+ }, options);
101
+ logger.info(`Scrolled to: x=${options.x || 0}, y=${options.y || 0}`);
102
+ }
103
+ async waitForSelector(selector, timeout) {
104
+ try {
105
+ const page = await this.collector.getActivePage();
106
+ await page.waitForSelector(selector, { timeout: timeout || 3e4 });
107
+ const element = await page.evaluate((sel) => {
108
+ const el = document.querySelector(sel);
109
+ if (!el) return null;
110
+ return {
111
+ tagName: el.tagName.toLowerCase(),
112
+ id: el.id || void 0,
113
+ className: el.className || void 0,
114
+ textContent: el.textContent?.trim().substring(0, 100) || void 0,
115
+ attributes: Array.from(el.attributes).reduce((acc, attr) => {
116
+ acc[attr.name] = attr.value;
117
+ return acc;
118
+ }, {})
119
+ };
120
+ }, selector);
121
+ logger.info(`Selector appeared: ${selector}`);
122
+ return {
123
+ success: true,
124
+ element,
125
+ message: `Selector appeared: ${selector}`
126
+ };
127
+ } catch (error) {
128
+ logger.error(`waitForSelector timeout for ${selector}:`, error);
129
+ return {
130
+ success: false,
131
+ message: `Timeout waiting for selector: ${selector}`
132
+ };
133
+ }
134
+ }
135
+ async waitForNavigation(timeout) {
136
+ await (await this.collector.getActivePage()).waitForNavigation({
137
+ waitUntil: "networkidle2",
138
+ timeout: timeout || 3e4
139
+ });
140
+ logger.info("Navigation completed");
141
+ }
142
+ async evaluate(code, frameOptions) {
143
+ const page = await this.collector.getActivePage();
144
+ if (frameOptions?.frameUrl || frameOptions?.frameSelector) {
145
+ const result = await evaluateOnContextWithTimeout(page, await this.resolveFrame(page, frameOptions), code);
146
+ logger.info("JavaScript executed (in frame)");
147
+ return result;
148
+ }
149
+ const result = await evaluateWithTimeout(page, code);
150
+ logger.info("JavaScript executed");
151
+ return result;
152
+ }
153
+ /**
154
+ * Resolve a child frame from the active page.
155
+ * When no options are provided (or both fields are undefined), returns page.mainFrame().
156
+ */
157
+ async resolveFrame(page, options) {
158
+ if (!options) return page.mainFrame();
159
+ if (options.frameUrl) {
160
+ const frames = page.frames();
161
+ const frame = frames.find((f) => f.url().includes(options.frameUrl));
162
+ if (!frame) {
163
+ const available = frames.map((f) => f.url()).filter((u) => u && u !== "about:blank");
164
+ throw new Error(`No frame matching URL substring "${options.frameUrl}". Available frames: ${available.join(", ") || "(none)"}`);
165
+ }
166
+ return frame;
167
+ }
168
+ if (options.frameSelector) {
169
+ await page.waitForSelector(options.frameSelector, { timeout: PAGE_FRAME_SELECTOR_TIMEOUT_MS }).catch(() => null);
170
+ const handle = await page.$(options.frameSelector);
171
+ if (!handle) throw new Error(`No element found for iframe selector: ${options.frameSelector}`);
172
+ const frame = await handle.contentFrame();
173
+ if (!frame) throw new Error(`Element "${options.frameSelector}" exists but has no content frame (not an iframe or not yet loaded).`);
174
+ return frame;
175
+ }
176
+ return page.mainFrame();
177
+ }
178
+ /** List all frames in the active page with URL and name info. */
179
+ async listFrames() {
180
+ const page = await this.collector.getActivePage();
181
+ const mainFrame = page.mainFrame();
182
+ return page.frames().map((frame) => ({
183
+ url: frame.url(),
184
+ name: frame.name() || "",
185
+ id: frame["_id"] || "",
186
+ isMainFrame: frame === mainFrame
187
+ }));
188
+ }
189
+ async getURL() {
190
+ return (await this.collector.getActivePage()).url();
191
+ }
192
+ async getTitle() {
193
+ return await (await this.collector.getActivePage()).title();
194
+ }
195
+ async getContent() {
196
+ return await (await this.collector.getActivePage()).content();
197
+ }
198
+ async screenshot(options) {
199
+ const page = await this.collector.getActivePage();
200
+ const screenshotOpts = {
201
+ path: options?.path,
202
+ type: options?.type || "png",
203
+ quality: options?.quality,
204
+ fullPage: options?.fullPage || false
205
+ };
206
+ if (options?.clip) {
207
+ screenshotOpts.clip = options.clip;
208
+ screenshotOpts.fullPage = false;
209
+ }
210
+ const buffer = await page.screenshot(screenshotOpts);
211
+ logger.info(`Screenshot taken${options?.path ? `: ${options.path}` : ""}`);
212
+ return buffer;
213
+ }
214
+ async getPerformanceMetrics() {
215
+ const metrics = await evaluateWithTimeout(await this.collector.getActivePage(), () => {
216
+ const perf = performance.getEntriesByType("navigation")[0];
217
+ return {
218
+ domContentLoaded: perf.domContentLoadedEventEnd - perf.domContentLoadedEventStart,
219
+ loadComplete: perf.loadEventEnd - perf.loadEventStart,
220
+ dns: perf.domainLookupEnd - perf.domainLookupStart,
221
+ tcp: perf.connectEnd - perf.connectStart,
222
+ request: perf.responseStart - perf.requestStart,
223
+ response: perf.responseEnd - perf.responseStart,
224
+ total: perf.loadEventEnd - perf.fetchStart,
225
+ resources: performance.getEntriesByType("resource").length
226
+ };
227
+ });
228
+ logger.info("Performance metrics retrieved");
229
+ return metrics;
230
+ }
231
+ async injectScript(scriptContent) {
232
+ await evaluateWithTimeout(await this.collector.getActivePage(), (script) => {
233
+ const scriptElement = document.createElement("script");
234
+ scriptElement.textContent = script;
235
+ document.head.appendChild(scriptElement);
236
+ }, scriptContent);
237
+ logger.info("Script injected into page");
238
+ }
239
+ async setCookies(cookies) {
240
+ await (await this.collector.getActivePage()).setCookie(...cookies);
241
+ logger.info(`Set ${cookies.length} cookies`);
242
+ }
243
+ async getCookies() {
244
+ const cookies = await (await this.collector.getActivePage()).cookies();
245
+ logger.info(`Retrieved ${cookies.length} cookies`);
246
+ return cookies;
247
+ }
248
+ async clearCookies() {
249
+ const page = await this.collector.getActivePage();
250
+ const cookies = await page.cookies();
251
+ await page.deleteCookie(...cookies);
252
+ logger.info("All cookies cleared");
253
+ }
254
+ async setViewport(width, height) {
255
+ await (await this.collector.getActivePage()).setViewport({
256
+ width,
257
+ height
258
+ });
259
+ logger.info(`Viewport set to ${width}x${height}`);
260
+ }
261
+ async emulateDevice(deviceName) {
262
+ const page = await this.collector.getActivePage();
263
+ const devices = {
264
+ iPhone: {
265
+ viewport: {
266
+ width: 375,
267
+ height: 812,
268
+ isMobile: true
269
+ },
270
+ userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15"
271
+ },
272
+ iPad: {
273
+ viewport: {
274
+ width: 768,
275
+ height: 1024,
276
+ isMobile: true
277
+ },
278
+ userAgent: "Mozilla/5.0 (iPad; CPU OS 14_0 like Mac OS X) AppleWebKit/605.1.15"
279
+ },
280
+ Android: {
281
+ viewport: {
282
+ width: 360,
283
+ height: 640,
284
+ isMobile: true
285
+ },
286
+ userAgent: "Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 Chrome/91.0.4472.120"
287
+ }
288
+ };
289
+ const normalized = String(deviceName || "").trim().toLowerCase();
290
+ let resolvedDevice = null;
291
+ if (normalized.includes("iphone")) resolvedDevice = "iPhone";
292
+ else if (normalized.includes("ipad")) resolvedDevice = "iPad";
293
+ else if (normalized.includes("android") || normalized.includes("pixel")) resolvedDevice = "Android";
294
+ if (!resolvedDevice) throw new Error(`Unsupported device "${deviceName}". Supported values include: iPhone, iPad, Android (aliases like "iPhone 13" are accepted).`);
295
+ const device = devices[resolvedDevice];
296
+ await page.setViewport(device.viewport);
297
+ await page.setUserAgent(device.userAgent);
298
+ logger.info(`Emulating ${resolvedDevice} (input: ${deviceName})`);
299
+ return resolvedDevice;
300
+ }
301
+ async waitForNetworkIdle(timeout = PAGE_NETWORK_IDLE_TIMEOUT_MS) {
302
+ await (await this.collector.getActivePage()).waitForNetworkIdle({ timeout });
303
+ logger.info("Network is idle");
304
+ }
305
+ async getLocalStorage() {
306
+ const storage = await (await this.collector.getActivePage()).evaluate(() => {
307
+ const items = {};
308
+ for (let i = 0; i < localStorage.length; i++) {
309
+ const key = localStorage.key(i);
310
+ if (key) items[key] = localStorage.getItem(key) || "";
311
+ }
312
+ return items;
313
+ });
314
+ logger.info(`Retrieved ${Object.keys(storage).length} localStorage items`);
315
+ return storage;
316
+ }
317
+ async setLocalStorage(key, value) {
318
+ await (await this.collector.getActivePage()).evaluate((k, v) => {
319
+ localStorage.setItem(k, v);
320
+ }, key, value);
321
+ logger.info(`Set localStorage: ${key}`);
322
+ }
323
+ async clearLocalStorage() {
324
+ await (await this.collector.getActivePage()).evaluate(() => {
325
+ localStorage.clear();
326
+ });
327
+ logger.info("LocalStorage cleared");
328
+ }
329
+ async pressKey(key) {
330
+ await (await this.collector.getActivePage()).keyboard.press(key);
331
+ logger.info(`Pressed key: ${key}`);
332
+ }
333
+ async uploadFile(selector, filePath) {
334
+ const input = await (await this.collector.getActivePage()).$(selector);
335
+ if (!input) throw new Error(`File input not found: ${selector}`);
336
+ await input.uploadFile(filePath);
337
+ logger.info(`File uploaded: ${filePath}`);
338
+ }
339
+ async getAllLinks() {
340
+ const links = await (await this.collector.getActivePage()).evaluate(() => {
341
+ const anchors = document.querySelectorAll("a[href]");
342
+ const result = [];
343
+ for (let i = 0; i < anchors.length; i++) {
344
+ const anchor = anchors[i];
345
+ result.push({
346
+ text: anchor.textContent?.trim() || "",
347
+ href: anchor.href
348
+ });
349
+ }
350
+ return result;
351
+ });
352
+ logger.info(`Found ${links.length} links`);
353
+ return links;
354
+ }
355
+ async getPage() {
356
+ return await this.collector.getActivePage();
357
+ }
358
+ };
359
+ /**
360
+ * Pre-flight CDP health check: verify the page CDP target is responsive.
361
+ * After debugger enable + pause/resume, the Playwright CDP session can enter
362
+ * a zombie state where Runtime.evaluate hangs indefinitely without firing
363
+ * 'disconnected'. Without this check, page.evaluate() blocks for the full 30 s
364
+ * timeout — with this check we fail fast (~3 s) with a clear message.
365
+ */
366
+ async function checkPageCDPHealth(page, timeoutMs = 500) {
367
+ const ac = new AbortController();
368
+ const timer = setTimeout$1(timeoutMs, void 0, { signal: ac.signal }).then(() => {
369
+ throw new Error("cdp_unreachable");
370
+ });
371
+ try {
372
+ const cdp = await Promise.race([page.createCDPSession(), timer]);
373
+ await Promise.race([cdp.send("Runtime.evaluate", {
374
+ expression: "1",
375
+ returnByValue: true
376
+ }), timer]);
377
+ } catch (err) {
378
+ if ((err instanceof Error ? err.message : String(err)) === "cdp_unreachable") throw new Error("CDP session unresponsive — the debugger may be blocking page evaluation. Call debugger_lifecycle({ action: 'disable' })() before this tool, or run it before debugger_lifecycle({ action: 'enable' })().", { cause: err });
379
+ throw err;
380
+ } finally {
381
+ ac.abort();
382
+ }
383
+ }
384
+ async function evaluateOnContextWithTimeout(page, context, pageFunction, ...args) {
385
+ const timeoutMs = 3e4;
386
+ await checkPageCDPHealth(page);
387
+ return Promise.race([context.evaluate(pageFunction, ...[...args]), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`page.evaluate timed out after ${timeoutMs}ms`)), timeoutMs))]);
388
+ }
389
+ async function evaluateWithTimeout(page, pageFunction, ...args) {
390
+ return evaluateOnContextWithTimeout(page, page, pageFunction, ...args);
391
+ }
392
+ /**
393
+ * Wrap a page.evaluateOnNewDocument() call with:
394
+ * 1. A CDP pre-flight health check
395
+ * 2. A hard timeout (30 s) as a backstop
396
+ */
397
+ async function evaluateOnNewDocumentWithTimeout(page, pageFunction, ...args) {
398
+ const timeoutMs = 3e4;
399
+ await checkPageCDPHealth(page);
400
+ return Promise.race([page.evaluateOnNewDocument(pageFunction, ...[...args]), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`page.evaluateOnNewDocument timed out after ${timeoutMs}ms`)), timeoutMs))]);
401
+ }
402
+ /**
403
+ * Wrap page.coverage.startJSCoverage() with a timeout.
404
+ */
405
+ async function coverageStartJSWithTimeout(page, options) {
406
+ const timeoutMs = 3e4;
407
+ return Promise.race([page.coverage.startJSCoverage(options), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`coverage.startJSCoverage timed out after ${timeoutMs}ms`)), timeoutMs))]);
408
+ }
409
+ /**
410
+ * Wrap page.coverage.startCSSCoverage() with a timeout.
411
+ */
412
+ async function coverageStartCSSWithTimeout(page, options) {
413
+ const timeoutMs = 3e4;
414
+ return Promise.race([page.coverage.startCSSCoverage(options), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`coverage.startCSSCoverage timed out after ${timeoutMs}ms`)), timeoutMs))]);
415
+ }
416
+ /**
417
+ * Wrap page.coverage.stopJSCoverage() with a timeout.
418
+ */
419
+ async function coverageStopJSWithTimeout(page) {
420
+ const timeoutMs = 3e4;
421
+ return Promise.race([page.coverage.stopJSCoverage(), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`coverage.stopJSCoverage timed out after ${timeoutMs}ms`)), timeoutMs))]);
422
+ }
423
+ /**
424
+ * Wrap page.coverage.stopCSSCoverage() with a timeout.
425
+ */
426
+ async function coverageStopCSSWithTimeout(page) {
427
+ const timeoutMs = 3e4;
428
+ return Promise.race([page.coverage.stopCSSCoverage(), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`coverage.stopCSSCoverage timed out after ${timeoutMs}ms`)), timeoutMs))]);
429
+ }
430
+ //#endregion
431
+ export { coverageStopJSWithTimeout as a, coverageStopCSSWithTimeout as i, coverageStartCSSWithTimeout as n, evaluateOnNewDocumentWithTimeout as o, coverageStartJSWithTimeout as r, evaluateWithTimeout as s, PageController as t };