@axeptio/behavior-detection 1.0.2 → 1.1.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 (59) hide show
  1. package/README.md +126 -12
  2. package/dist/behavior-detection.esm.min.js +1 -1
  3. package/dist/behavior-detection.esm.min.js.map +4 -4
  4. package/dist/behavior-detection.min.js +1 -1
  5. package/dist/behavior-detection.min.js.map +3 -3
  6. package/dist/cjs/index.cjs +2320 -0
  7. package/dist/esm/browser.js +0 -2
  8. package/dist/esm/index.d.ts +1 -1
  9. package/dist/esm/index.js +1 -1
  10. package/dist/esm/strategies/click.d.ts +8 -0
  11. package/dist/esm/strategies/click.js +108 -9
  12. package/dist/esm/strategies/environment.d.ts +39 -0
  13. package/dist/esm/strategies/environment.js +188 -7
  14. package/dist/esm/strategies/index.d.ts +4 -0
  15. package/dist/esm/strategies/index.js +4 -0
  16. package/dist/esm/strategies/mouse.d.ts +53 -1
  17. package/dist/esm/strategies/mouse.js +198 -2
  18. package/dist/esm/strategies/timing.d.ts +64 -0
  19. package/dist/esm/strategies/timing.js +308 -0
  20. package/dist/esm/strategies/visibility.d.ts +64 -0
  21. package/dist/esm/strategies/visibility.js +295 -0
  22. package/dist/index.d.ts +1 -1
  23. package/dist/strategies/click.d.ts +8 -0
  24. package/dist/strategies/environment.d.ts +39 -0
  25. package/dist/strategies/index.d.ts +4 -0
  26. package/dist/strategies/mouse.d.ts +53 -1
  27. package/dist/strategies/timing.d.ts +64 -0
  28. package/dist/strategies/visibility.d.ts +64 -0
  29. package/package.json +16 -15
  30. package/dist/cjs/behavior-detector.d.ts +0 -102
  31. package/dist/cjs/behavior-detector.js +0 -315
  32. package/dist/cjs/browser.d.ts +0 -33
  33. package/dist/cjs/browser.js +0 -226
  34. package/dist/cjs/index.d.ts +0 -38
  35. package/dist/cjs/index.js +0 -55
  36. package/dist/cjs/math-utils.d.ts +0 -84
  37. package/dist/cjs/math-utils.js +0 -141
  38. package/dist/cjs/strategies/click.d.ts +0 -39
  39. package/dist/cjs/strategies/click.js +0 -173
  40. package/dist/cjs/strategies/environment.d.ts +0 -52
  41. package/dist/cjs/strategies/environment.js +0 -148
  42. package/dist/cjs/strategies/index.d.ts +0 -18
  43. package/dist/cjs/strategies/index.js +0 -36
  44. package/dist/cjs/strategies/keyboard.d.ts +0 -43
  45. package/dist/cjs/strategies/keyboard.js +0 -233
  46. package/dist/cjs/strategies/mouse.d.ts +0 -39
  47. package/dist/cjs/strategies/mouse.js +0 -159
  48. package/dist/cjs/strategies/resize.d.ts +0 -21
  49. package/dist/cjs/strategies/resize.js +0 -97
  50. package/dist/cjs/strategies/scroll.d.ts +0 -37
  51. package/dist/cjs/strategies/scroll.js +0 -149
  52. package/dist/cjs/strategies/tap.d.ts +0 -38
  53. package/dist/cjs/strategies/tap.js +0 -214
  54. package/dist/cjs/strategy.d.ts +0 -107
  55. package/dist/cjs/strategy.js +0 -33
  56. package/dist/cjs/types.d.ts +0 -168
  57. package/dist/cjs/types.js +0 -26
  58. package/dist/esm/browser-iife.d.ts +0 -5
  59. package/dist/esm/browser-iife.js +0 -157
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["esm/behavior-detector.js", "esm/strategy.js", "esm/math-utils.js", "esm/strategies/mouse.js", "esm/strategies/scroll.js", "esm/strategies/click.js", "esm/strategies/tap.js", "esm/strategies/keyboard.js", "esm/strategies/environment.js", "esm/strategies/resize.js", "esm/browser.js"],
4
- "sourcesContent": ["/**\n * Main class for behavior detection\n * Uses modular strategy pattern for tree-shakeable, autonomous detection modules\n */\nexport class BehaviorDetector {\n constructor(tickOptions) {\n // Strategy mode\n this.strategies = new Map();\n this.isTracking = false;\n this.isPausedByVisibility = false;\n this.tickInterval = null;\n this.tickIntervalMs = 1000; // Default: 1 second\n this.pauseOnHidden = true;\n this.visibilityChangeHandler = null;\n // Confidence tracking\n this.confidenceScore = 0;\n this.CONFIDENCE_TARGET = 1.0; // Target confidence for reliable classification\n this.CONFIDENCE_DECAY = 0.95; // Per event decay to prevent infinite growth\n if (tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.interval) {\n this.tickIntervalMs = tickOptions.interval;\n }\n if ((tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.pauseOnHidden) !== undefined) {\n this.pauseOnHidden = tickOptions.pauseOnHidden;\n }\n }\n /**\n * Add a detection strategy\n */\n addStrategy(strategy, weight) {\n const config = {\n strategy,\n weight: weight !== null && weight !== void 0 ? weight : strategy.defaultWeight,\n enabled: true,\n };\n this.strategies.set(strategy.name, config);\n // Set up event callback for confidence tracking\n if (strategy.setEventCallback) {\n strategy.setEventCallback((event) => {\n this.onStrategyEvent(event, config.weight);\n });\n }\n // If already tracking, start this strategy immediately\n if (this.isTracking) {\n strategy.start();\n }\n return this;\n }\n /**\n * Handle event from strategy - update confidence\n */\n onStrategyEvent(event, strategyWeight) {\n // Apply decay to existing confidence to prevent infinite growth\n this.confidenceScore *= this.CONFIDENCE_DECAY;\n // Add weighted contribution from this event\n // eventWeight (0-1) * strategyWeight (e.g. 0.3 for mouse) = contribution\n const contribution = event.weight * strategyWeight;\n this.confidenceScore = Math.min(this.CONFIDENCE_TARGET, this.confidenceScore + contribution);\n }\n /**\n * Remove a detection strategy\n */\n removeStrategy(name) {\n const config = this.strategies.get(name);\n if (config) {\n if (this.isTracking) {\n config.strategy.stop();\n }\n this.strategies.delete(name);\n }\n return this;\n }\n /**\n * Enable/disable a strategy\n */\n setStrategyEnabled(name, enabled) {\n const config = this.strategies.get(name);\n if (config) {\n config.enabled = enabled;\n // If tracking and being disabled, stop it\n if (!enabled && this.isTracking) {\n config.strategy.stop();\n }\n // If tracking and being enabled, start it\n if (enabled && this.isTracking) {\n config.strategy.start();\n }\n }\n return this;\n }\n /**\n * Get all registered strategies\n */\n getStrategies() {\n return this.strategies;\n }\n /**\n * Start tracking\n */\n start() {\n if (this.isTracking)\n return;\n this.isTracking = true;\n // Set up visibility change listener\n if (this.pauseOnHidden && typeof document !== 'undefined') {\n this.visibilityChangeHandler = this.handleVisibilityChange.bind(this);\n document.addEventListener('visibilitychange', this.visibilityChangeHandler);\n // Check initial visibility state\n if (document.hidden) {\n this.isPausedByVisibility = true;\n return; // Don't start strategies if already hidden\n }\n }\n // Start all enabled strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.start();\n }\n }\n // Start tick mechanism\n this.startTick();\n }\n /**\n * Stop tracking\n */\n stop() {\n if (!this.isTracking)\n return;\n this.isTracking = false;\n this.isPausedByVisibility = false;\n // Remove visibility change listener\n if (this.visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n // Stop all strategies\n for (const [_, config] of this.strategies) {\n config.strategy.stop();\n }\n // Stop tick\n this.stopTick();\n }\n /**\n * Reset all data\n */\n reset() {\n this.confidenceScore = 0;\n for (const [_, config] of this.strategies) {\n config.strategy.reset();\n }\n }\n /**\n * Calculate human likelihood score\n */\n async score(options = {}) {\n const breakdown = this.calculateStrategyScore();\n const result = {\n score: breakdown.overall,\n };\n if (options.breakdown) {\n result.breakdown = breakdown;\n }\n // Note: auditTrail not available in strategy mode\n // Each strategy manages its own data independently\n return result;\n }\n /**\n * Check if currently tracking\n */\n isActive() {\n return this.isTracking;\n }\n /**\n * Check if currently paused due to tab visibility\n */\n isPaused() {\n return this.isPausedByVisibility;\n }\n /**\n * Get event count from all strategies\n */\n getEventCount() {\n var _a, _b;\n const counts = {};\n for (const [name, config] of this.strategies) {\n const debug = (_b = (_a = config.strategy).getDebugInfo) === null || _b === void 0 ? void 0 : _b.call(_a);\n if ((debug === null || debug === void 0 ? void 0 : debug.eventCount) !== undefined) {\n counts[name] = debug.eventCount;\n }\n }\n return counts;\n }\n /**\n * Get debug info from all strategies\n */\n getStrategyDebugInfo() {\n const debug = {};\n for (const [name, config] of this.strategies) {\n if (config.strategy.getDebugInfo) {\n debug[name] = config.strategy.getDebugInfo();\n }\n }\n return debug;\n }\n /**\n * Get current confidence score (0-1)\n * Represents how much interaction data we've collected\n * Higher confidence = more reliable classification\n */\n getConfidence() {\n return Math.min(1, this.confidenceScore);\n }\n /**\n * Check if confidence is above threshold for reliable classification\n * @param threshold - Minimum confidence (0-1), default 0.3\n */\n hasConfidentData(threshold = 0.3) {\n return this.getConfidence() >= threshold;\n }\n /**\n * Cleanup resources\n */\n destroy() {\n this.stop();\n this.strategies.clear();\n }\n /**\n * Handle visibility change events\n */\n handleVisibilityChange() {\n if (!this.isTracking)\n return;\n if (document.hidden) {\n // Tab became hidden - pause detection\n if (!this.isPausedByVisibility) {\n this.isPausedByVisibility = true;\n // Stop all strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.stop();\n }\n }\n // Stop tick\n this.stopTick();\n }\n }\n else {\n // Tab became visible - resume detection\n if (this.isPausedByVisibility) {\n this.isPausedByVisibility = false;\n // Restart all enabled strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.start();\n }\n }\n // Restart tick\n this.startTick();\n }\n }\n }\n /**\n * Start tick mechanism for strategies\n */\n startTick() {\n if (this.tickInterval !== null)\n return;\n this.tickInterval = window.setInterval(() => {\n const now = Date.now();\n for (const [_, config] of this.strategies) {\n if (config.enabled && config.strategy.onTick) {\n config.strategy.onTick(now);\n }\n }\n }, this.tickIntervalMs);\n }\n /**\n * Stop tick mechanism\n */\n stopTick() {\n if (this.tickInterval !== null) {\n clearInterval(this.tickInterval);\n this.tickInterval = null;\n }\n }\n /**\n * Calculate score using strategies\n */\n calculateStrategyScore() {\n const factors = {};\n const weights = {};\n let totalWeight = 0;\n let weightedSum = 0;\n for (const [name, config] of this.strategies) {\n if (!config.enabled)\n continue;\n const score = config.strategy.score();\n factors[name] = score;\n weights[name] = config.weight;\n if (score !== undefined && score !== null) {\n totalWeight += config.weight;\n weightedSum += score * config.weight;\n }\n }\n const overall = totalWeight > 0 ? weightedSum / totalWeight : 0.5;\n return {\n overall: Math.max(0, Math.min(1, overall)),\n factors,\n weights,\n };\n }\n}\n", "/**\n * Detection Strategy Interface\n * Each strategy is a fully autonomous module responsible for:\n * - Registering its own event listeners\n * - Managing its own state and events\n * - Responding to lifecycle events (start/stop)\n * - Optionally receiving tick updates for polling-based detection\n */\n/**\n * Base class for detection strategies\n * Handles event callback pattern to avoid repetition\n */\nexport class BaseStrategy {\n constructor() {\n this.eventCallback = null;\n }\n setEventCallback(callback) {\n this.eventCallback = callback;\n }\n notifyEvent(weight) {\n if (this.eventCallback) {\n this.eventCallback({\n strategy: this.name,\n weight,\n timestamp: Date.now()\n });\n }\n }\n}\n", "/**\n * Mathematical utility functions for continuous scoring\n * Replaces magic number if-else chains with smooth mathematical functions\n */\n/**\n * Sigmoid function - Maps any value to [0, 1] with smooth S-curve\n * @param x - Input value\n * @param midpoint - Value that maps to 0.5\n * @param steepness - How steep the curve is (higher = steeper)\n */\nexport function sigmoid(x, midpoint = 0, steepness = 1) {\n return 1 / (1 + Math.exp(-steepness * (x - midpoint)));\n}\n/**\n * Inverse sigmoid - High values map to low scores\n */\nexport function inverseSigmoid(x, midpoint = 0, steepness = 1) {\n return 1 - sigmoid(x, midpoint, steepness);\n}\n/**\n * Gaussian (bell curve) - Peak at ideal value, falls off on both sides\n * @param x - Input value\n * @param ideal - Optimal value (peak of curve)\n * @param width - How wide the acceptable range is\n */\nexport function gaussian(x, ideal = 0, width = 1) {\n const exponent = -Math.pow(x - ideal, 2) / (2 * width * width);\n return Math.exp(exponent);\n}\n/**\n * Exponential decay - High values get penalized exponentially\n */\nexport function exponentialDecay(x, decayRate = 0.1) {\n return Math.exp(-decayRate * x);\n}\n/**\n * Normalize value to [0, 1] range\n */\nexport function normalize(value, min = 0, max = 1) {\n if (max === min)\n return 0.5;\n return Math.max(0, Math.min(1, (value - min) / (max - min)));\n}\n/**\n * Clamp value to [0, 1]\n */\nexport function clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n/**\n * Calculate statistical metrics for an array of numbers\n * @param values - Array of numerical values\n * @returns Statistical metrics (mean, variance, stdDev, cv)\n */\nexport function calculateStatistics(values) {\n if (values.length === 0) {\n return { mean: 0, variance: 0, stdDev: 0, cv: 0 };\n }\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / values.length;\n const stdDev = Math.sqrt(variance);\n const cv = mean > 0 ? stdDev / mean : 0;\n return { mean, variance, stdDev, cv };\n}\n/**\n * Analyze timing intervals for bot-like patterns\n * Returns raw analysis data without scoring - caller decides heuristics\n *\n * @param intervals - Array of time intervals (ms)\n * @returns Analysis of interval patterns including stats and uniqueness\n */\nexport function analyzeIntervals(intervals) {\n if (intervals.length < 2)\n return undefined;\n // Check for identical intervals (round to 10ms to account for floating point)\n const uniqueCount = new Set(intervals.map(i => Math.round(i / 10))).size;\n const allIdentical = uniqueCount === 1;\n // Calculate statistics\n const statistics = calculateStatistics(intervals);\n return {\n statistics,\n uniqueCount,\n allIdentical,\n };\n}\n/**\n * Score coefficient of variation\n * Maps CV to human-likeness score using Gaussian\n * Ideal CV is around 0.4-0.5 (moderate variation)\n */\nexport function scoreCoefficientOfVariation(cv) {\n // Too low (<0.1) = bot-like (too consistent)\n // Too high (>1.5) = random noise\n // Ideal = 0.4-0.6 (natural human variation)\n if (cv < 0.05)\n return 0.1; // Almost zero variation - definitely bot\n if (cv > 2.0)\n return 0.3; // Too random\n // Gaussian centered at 0.45 with width of 0.35\n return gaussian(cv, 0.45, 0.35);\n}\n/**\n * Score entropy - Higher is better (more random = more human)\n * Uses sigmoid to smoothly map entropy to score\n */\nexport function scoreEntropy(normalizedEntropy) {\n // Entropy of 0.7+ is very human\n // Entropy < 0.3 is very bot-like\n return sigmoid(normalizedEntropy, 0.5, 8); // Steep curve at midpoint 0.5\n}\n/**\n * Score autocorrelation - Lower is better (less periodic = more human)\n */\nexport function scoreAutocorrelation(autocorr) {\n // Low autocorrelation (<0.2) is natural\n // High autocorrelation (>0.6) is periodic/bot-like\n return inverseSigmoid(autocorr, 0.4, 10);\n}\n/**\n * Score jerk - Lower is better (smoother = more human)\n */\nexport function scoreJerk(avgJerk) {\n // Human jerk typically < 0.01\n // Bot jerk often > 0.1\n // Use inverse sigmoid\n return inverseSigmoid(avgJerk, 0.05, 50);\n}\n", "/**\n * Mouse Movement Detection Strategy\n * Autonomous module that manages its own mouse event listeners and state\n * Tracks distance and angle to detect unnatural jumps and sharp turns\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { calculateStatistics, gaussian } from '../math-utils.js';\nexport class MouseStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'mouse';\n this.defaultWeight = 0.30;\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n this.rollingWindowMs = 5000;\n this.listener = null;\n this.leaveListener = null;\n this.isActive = false;\n this.screenDiagonal = 1;\n if ((options === null || options === void 0 ? void 0 : options.rollingWindow) !== undefined)\n this.rollingWindowMs = options.rollingWindow;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Calculate screen diagonal for normalization (distance relative to screen size)\n const width = window.innerWidth;\n const height = window.innerHeight;\n this.screenDiagonal = Math.sqrt(width * width + height * height);\n this.listener = (e) => {\n const mouseEvent = e;\n const now = Date.now();\n const currentPos = { x: mouseEvent.clientX, y: mouseEvent.clientY };\n // Calculate distance and angle from previous position\n if (this.lastPosition) {\n const dx = currentPos.x - this.lastPosition.x;\n const dy = currentPos.y - this.lastPosition.y;\n const pixelDistance = Math.sqrt(dx * dx + dy * dy);\n // Normalize distance to screen diagonal (0-1 range)\n // A full diagonal movement = 1.0, a 10px movement on 2000px screen = 0.005\n const normalizedDistance = pixelDistance / this.screenDiagonal;\n // Only record if movement is meaningful (> 0.001 = ~2px on 2000px screen)\n if (normalizedDistance > 0.001) {\n const rawAngle = Math.atan2(dy, dx); // -PI to PI\n // Unwrap angle to avoid discontinuities (e.g., circles)\n let angleDiff = rawAngle - this.lastAngle;\n // Normalize difference to -PI to PI\n while (angleDiff > Math.PI)\n angleDiff -= 2 * Math.PI;\n while (angleDiff < -Math.PI)\n angleDiff += 2 * Math.PI;\n this.cumulativeAngle += angleDiff;\n this.lastAngle = rawAngle;\n // Store normalized distance (not raw pixels)\n this.distanceSeries.push({ value: normalizedDistance, timestamp: now });\n this.angleSeries.push({ value: this.cumulativeAngle, timestamp: now });\n // Notify detector for confidence tracking\n this.notifyEvent(Math.min(1, normalizedDistance * 100));\n }\n // Apply rolling window efficiently: remove old events from start\n // Since events are chronological, we only check from the beginning\n const cutoff = now - this.rollingWindowMs;\n while (this.distanceSeries.length > 0 && this.distanceSeries[0].timestamp < cutoff) {\n this.distanceSeries.shift();\n this.angleSeries.shift(); // Keep both arrays in sync\n }\n }\n this.lastPosition = currentPos;\n };\n document.addEventListener('mousemove', this.listener, { passive: true });\n // Clear data when mouse leaves the window (discontinuous tracking)\n this.leaveListener = () => {\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n };\n document.addEventListener('mouseleave', this.leaveListener, { passive: true });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n document.removeEventListener('mousemove', this.listener);\n this.listener = null;\n }\n if (this.leaveListener) {\n document.removeEventListener('mouseleave', this.leaveListener);\n this.leaveListener = null;\n }\n }\n reset() {\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n }\n score() {\n if (this.distanceSeries.length < 10)\n return undefined;\n // Mouse-specific pattern detection (optimized for normalized continuous data)\n // Generic smoothness detector is calibrated for discrete events, not continuous movement\n return this.detectMousePatterns();\n }\n /**\n * Mouse-specific pattern detection\n * Detects bot-like patterns: constant velocity, linear paths\n */\n detectMousePatterns() {\n if (this.distanceSeries.length < 10)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. VELOCITY CONSISTENCY - Bots often move at constant speed\n const distances = this.distanceSeries.map(p => p.value);\n if (distances.length >= 3) {\n const stats = calculateStatistics(distances);\n // Real human movement has high variation (CV ~0.8-1.2)\n // page.mouse.move() with steps has lower CV (~0.4-0.6)\n // Narrower gaussian to be strict\n score += gaussian(stats.cv, 0.9, 0.35);\n factors++;\n }\n // 2. DIRECTION CHANGES - Bots often have too few or too many sharp turns\n const angles = this.angleSeries.map(p => p.value);\n if (angles.length >= 3) {\n const angleChanges = [];\n for (let i = 1; i < angles.length; i++) {\n angleChanges.push(Math.abs(angles[i] - angles[i - 1]));\n }\n const avgChange = angleChanges.reduce((a, b) => a + b, 0) / angleChanges.length;\n // Real humans have moderate but varied direction changes\n // page.mouse.move() linear interpolation has very small, consistent changes\n score += gaussian(avgChange, 0.15, 0.12);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.distanceSeries.length,\n rollingWindow: this.rollingWindowMs,\n isActive: this.isActive,\n distanceSeries: this.distanceSeries,\n angleSeries: this.angleSeries,\n };\n }\n}\n", "/**\n * Scroll Behavior Detection Strategy\n * Autonomous module managing scroll event listeners\n * Tracks normalized scroll distance and velocity patterns\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { calculateStatistics, gaussian, inverseSigmoid } from '../math-utils.js';\nexport class ScrollStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'scroll';\n this.defaultWeight = 0.15;\n this.distanceSeries = [];\n this.velocitySeries = [];\n this.lastScrollY = null;\n this.lastTimestamp = 0;\n this.rollingWindowMs = 5000;\n this.documentHeight = 1;\n this.listener = null;\n this.isActive = false;\n if ((options === null || options === void 0 ? void 0 : options.rollingWindow) !== undefined)\n this.rollingWindowMs = options.rollingWindow;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Calculate document height for normalization\n this.documentHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, 1);\n this.listener = (_e) => {\n const scrollY = window.scrollY;\n const now = Date.now();\n // Always update last position on first event\n if (this.lastScrollY === null) {\n this.lastScrollY = scrollY;\n this.lastTimestamp = now;\n return;\n }\n const pixelDelta = scrollY - this.lastScrollY;\n const deltaTime = now - this.lastTimestamp;\n // Skip if no actual scroll happened\n if (pixelDelta === 0) {\n return;\n }\n // Normalize scroll distance to document height (0-1 range)\n const normalizedDistance = Math.abs(pixelDelta) / this.documentHeight;\n // Record all scroll movements (no threshold - let pattern detection decide)\n if (deltaTime > 0) {\n const velocity = normalizedDistance / deltaTime; // normalized units per ms\n // Store as time series\n this.distanceSeries.push({ value: normalizedDistance, timestamp: now });\n this.velocitySeries.push({ value: velocity, timestamp: now });\n // Notify detector for confidence tracking\n this.notifyEvent(Math.min(1, normalizedDistance * 10));\n // Apply rolling window efficiently\n const cutoff = now - this.rollingWindowMs;\n while (this.distanceSeries.length > 0 && this.distanceSeries[0].timestamp < cutoff) {\n this.distanceSeries.shift();\n this.velocitySeries.shift();\n }\n }\n this.lastScrollY = scrollY;\n this.lastTimestamp = now;\n };\n // Listen on window for scroll events (document scrolling)\n window.addEventListener('scroll', this.listener, { passive: true });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n window.removeEventListener('scroll', this.listener);\n this.listener = null;\n }\n }\n reset() {\n this.distanceSeries = [];\n this.velocitySeries = [];\n this.lastScrollY = null;\n this.lastTimestamp = 0;\n }\n score() {\n if (this.distanceSeries.length < 2)\n return undefined;\n // Scroll-specific pattern detection\n return this.detectScrollPatterns();\n }\n /**\n * Scroll-specific pattern detection\n * Detects bot-like patterns: constant deltas, instant jumps, too smooth\n */\n detectScrollPatterns() {\n if (this.distanceSeries.length < 2)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. IDENTICAL DELTAS - Smoking gun for bots\n const distances = this.distanceSeries.map(p => p.value);\n if (distances.length >= 2) {\n // Check if all distances are identical (tolerance for floating point)\n const uniqueDistances = new Set(distances.map(d => Math.round(d * 1000))).size;\n if (uniqueDistances === 1) {\n // All scroll amounts identical = definite bot\n return 0.05;\n }\n }\n // 2. DISTANCE CONSISTENCY - Bots often scroll same amount repeatedly\n if (distances.length >= 2) {\n const stats = calculateStatistics(distances);\n // Real humans have high CV (>0.8) due to natural scroll acceleration/deceleration\n // Simple automation has lower CV even with varied amounts\n // Gaussian centered high with narrow width - be strict\n score += gaussian(stats.cv, 1.0, 0.4);\n factors++;\n }\n // 3. VELOCITY VARIATION - Humans have highly variable scroll speeds\n const velocities = this.velocitySeries.map(p => p.value);\n if (velocities.length >= 2) {\n const stats = calculateStatistics(velocities);\n // Human velocity is very chaotic (acceleration/deceleration)\n // Automation has more consistent velocity even with delays\n score += gaussian(stats.cv, 1.2, 0.5);\n factors++;\n }\n // 4. INSTANT JUMPS - Detect programmatic scrollTo\n const instantJumps = distances.filter(d => d > 0.1).length; // >10% of document in one event\n if (distances.length > 0) {\n const jumpRatio = instantJumps / distances.length;\n // Penalize high jump ratio (programmatic scrollTo)\n score += inverseSigmoid(jumpRatio, 0.3, 15);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.distanceSeries.length,\n rollingWindow: this.rollingWindowMs,\n isActive: this.isActive,\n distanceSeries: this.distanceSeries,\n velocitySeries: this.velocitySeries,\n };\n }\n}\n", "/**\n * Click Behavior Detection Strategy\n * Monitors specific elements for click positioning patterns\n */\nimport { BaseStrategy } from '../strategy.js';\nexport class ClickStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'click';\n this.defaultWeight = 0.30;\n this.events = [];\n this.targetSelectors = ['button', 'a', 'input[type=\"submit\"]', '[role=\"button\"]'];\n this.lastMousePosition = null;\n this.mouseListener = null;\n this.clickListeners = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Track mouse position globally\n this.mouseListener = (e) => {\n const mouseEvent = e;\n this.lastMousePosition = {\n x: mouseEvent.clientX,\n y: mouseEvent.clientY,\n };\n };\n document.addEventListener('mousemove', this.mouseListener, { passive: true });\n // Find all matching elements and attach listeners\n this.attachClickListeners();\n }\n /**\n * Add a new target selector at runtime\n */\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n // Attach listeners if already active\n if (this.isActive) {\n this.attachClickListenersForSelector(selector);\n }\n }\n }\n attachClickListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachClickListenersForSelector(selector);\n });\n }\n attachClickListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.clickListeners.has(element))\n return; // Already attached\n const listener = (e) => {\n var _a, _b;\n const clickEvent = e;\n const rect = element.getBoundingClientRect();\n // Check if element is in viewport\n const inViewport = (rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth);\n // Analyze click position\n let position;\n if (!this.lastMousePosition) {\n position = 'no-mouse-data'; // Bot - no mouse movement\n }\n else {\n const mx = this.lastMousePosition.x;\n const my = this.lastMousePosition.y;\n // Check if mouse was over element\n const overElement = (mx >= rect.left &&\n mx <= rect.right &&\n my >= rect.top &&\n my <= rect.bottom);\n if (!overElement) {\n position = 'outside'; // Bot - mouse not over target\n }\n else {\n // Check if dead center (suspicious)\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const distanceFromCenter = Math.sqrt((mx - centerX) ** 2 + (my - centerY) ** 2);\n // Dead center = within 2px of center\n if (distanceFromCenter < 2) {\n position = 'dead-center'; // Suspicious - too perfect\n }\n else {\n position = 'over-element'; // Human - somewhere on the button\n }\n }\n }\n this.events.push({\n clickX: clickEvent.clientX,\n clickY: clickEvent.clientY,\n mouseX: (_a = this.lastMousePosition) === null || _a === void 0 ? void 0 : _a.x,\n mouseY: (_b = this.lastMousePosition) === null || _b === void 0 ? void 0 : _b.y,\n rect,\n inViewport,\n position,\n timestamp: Date.now(),\n });\n // Notify detector - clicks are high-value events\n this.notifyEvent(1.0);\n };\n element.addEventListener('click', listener);\n this.clickListeners.set(element, listener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n // Remove mouse listener\n if (this.mouseListener) {\n document.removeEventListener('mousemove', this.mouseListener);\n this.mouseListener = null;\n }\n // Remove all click listeners\n this.clickListeners.forEach((listener, element) => {\n element.removeEventListener('click', listener);\n });\n this.clickListeners.clear();\n }\n reset() {\n this.events = [];\n this.lastMousePosition = null;\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let totalScore = 0;\n for (const click of this.events) {\n switch (click.position) {\n case 'no-mouse-data':\n totalScore += 0.0; // Bot - no mouse movement\n break;\n case 'outside':\n totalScore += 0.0; // Bot - mouse not over target\n break;\n case 'dead-center':\n totalScore += 0.5; // Suspicious - too perfect\n break;\n case 'over-element':\n totalScore += 1.0; // Human - natural click\n break;\n }\n }\n return totalScore / this.events.length;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n positions: {\n noMouseData: this.events.filter(e => e.position === 'no-mouse-data').length,\n outside: this.events.filter(e => e.position === 'outside').length,\n deadCenter: this.events.filter(e => e.position === 'dead-center').length,\n overElement: this.events.filter(e => e.position === 'over-element').length,\n },\n inViewport: this.events.filter(e => e.inViewport).length,\n trackedElements: this.clickListeners.size,\n };\n }\n}\n", "/**\n * Tap Behavior Detection Strategy (Mobile)\n * Monitors touch interactions on specific elements\n * Analyzes tap duration, precision, movement, and timing patterns\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { analyzeIntervals, scoreCoefficientOfVariation, gaussian } from '../math-utils.js';\nexport class TapStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'tap';\n this.defaultWeight = 0.35;\n this.events = [];\n this.targetSelectors = ['button', 'a', 'input[type=\"submit\"]', '[role=\"button\"]'];\n this.touchStartListeners = new Map();\n this.touchEndListeners = new Map();\n this.activeTouches = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n this.attachTouchListeners();\n }\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n if (this.isActive) {\n this.attachTouchListenersForSelector(selector);\n }\n }\n }\n attachTouchListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachTouchListenersForSelector(selector);\n });\n }\n attachTouchListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.touchStartListeners.has(element))\n return;\n const startListener = (e) => {\n const touchEvent = e;\n // Only track first touch (ignore multi-touch)\n if (touchEvent.touches.length !== 1)\n return;\n const touch = touchEvent.touches[0];\n this.activeTouches.set(touch.identifier, {\n x: touch.clientX,\n y: touch.clientY,\n timestamp: Date.now(),\n element,\n });\n };\n const endListener = (e) => {\n const touchEvent = e;\n if (touchEvent.changedTouches.length !== 1)\n return;\n const touch = touchEvent.changedTouches[0];\n const startData = this.activeTouches.get(touch.identifier);\n if (!startData || startData.element !== element)\n return;\n const now = Date.now();\n const duration = now - startData.timestamp;\n const dx = touch.clientX - startData.x;\n const dy = touch.clientY - startData.y;\n const movement = Math.sqrt(dx * dx + dy * dy);\n const rect = element.getBoundingClientRect();\n const inViewport = (rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth);\n // Analyze tap position\n const tx = touch.clientX;\n const ty = touch.clientY;\n const overElement = (tx >= rect.left &&\n tx <= rect.right &&\n ty >= rect.top &&\n ty <= rect.bottom);\n let position;\n if (!overElement) {\n position = 'outside';\n }\n else {\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const distanceFromCenter = Math.sqrt((tx - centerX) ** 2 + (ty - centerY) ** 2);\n // Dead center = within 2px\n position = distanceFromCenter < 2 ? 'dead-center' : 'over-element';\n }\n this.events.push({\n x: tx,\n y: ty,\n rect,\n inViewport,\n position,\n duration,\n movement,\n timestamp: now,\n });\n // Notify detector - taps are high-value events\n this.notifyEvent(1.0);\n this.activeTouches.delete(touch.identifier);\n };\n element.addEventListener('touchstart', startListener, { passive: true });\n element.addEventListener('touchend', endListener, { passive: true });\n this.touchStartListeners.set(element, startListener);\n this.touchEndListeners.set(element, endListener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n this.touchStartListeners.forEach((listener, element) => {\n element.removeEventListener('touchstart', listener);\n });\n this.touchStartListeners.clear();\n this.touchEndListeners.forEach((listener, element) => {\n element.removeEventListener('touchend', listener);\n });\n this.touchEndListeners.clear();\n this.activeTouches.clear();\n }\n reset() {\n this.events = [];\n this.activeTouches.clear();\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. Position accuracy\n let positionScore = 0;\n for (const tap of this.events) {\n switch (tap.position) {\n case 'outside':\n positionScore += 0.0; // Bot\n break;\n case 'dead-center':\n positionScore += 0.5; // Suspicious\n break;\n case 'over-element':\n positionScore += 1.0; // Human\n break;\n }\n }\n score += positionScore / this.events.length;\n factors++;\n // 2. Tap duration variation - Humans have natural variation (50-150ms typical)\n const durations = this.events.map(e => e.duration);\n if (durations.length >= 2) {\n const durationAnalysis = analyzeIntervals(durations);\n if (durationAnalysis) {\n const { statistics, allIdentical } = durationAnalysis;\n // All identical = bot\n if (allIdentical) {\n return 0.05;\n }\n // Human tap durations have moderate CV (~0.3-0.5)\n score += scoreCoefficientOfVariation(statistics.cv);\n factors++;\n // Ideal duration: 70-120ms\n score += gaussian(statistics.mean, 95, 40);\n factors++;\n }\n }\n // 3. Tap movement - Real fingers move slightly (1-5px), bots are often 0px\n const movements = this.events.map(e => e.movement);\n if (movements.length > 0) {\n const avgMovement = movements.reduce((a, b) => a + b, 0) / movements.length;\n // Some movement is natural (1-5px), too much is a swipe, zero is suspicious\n score += gaussian(avgMovement, 2, 3);\n factors++;\n }\n // 4. Tap interval timing - Time between taps should vary naturally\n if (this.events.length >= 3) {\n const intervals = [];\n for (let i = 1; i < this.events.length; i++) {\n intervals.push(this.events[i].timestamp - this.events[i - 1].timestamp);\n }\n const intervalAnalysis = analyzeIntervals(intervals);\n if (intervalAnalysis && !intervalAnalysis.allIdentical) {\n score += scoreCoefficientOfVariation(intervalAnalysis.statistics.cv);\n factors++;\n }\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n positions: {\n outside: this.events.filter(e => e.position === 'outside').length,\n deadCenter: this.events.filter(e => e.position === 'dead-center').length,\n overElement: this.events.filter(e => e.position === 'over-element').length,\n },\n durations: this.events.map(e => e.duration),\n movements: this.events.map(e => e.movement),\n inViewport: this.events.filter(e => e.inViewport).length,\n trackedElements: this.touchStartListeners.size,\n };\n }\n}\n", "/**\n * Keyboard Timing Detection Strategy\n * Monitors typing in specific input fields\n * Analyzes keydown/keyup timing and micro-variations\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { analyzeIntervals, scoreCoefficientOfVariation } from '../math-utils.js';\nexport class KeyboardStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'keyboard';\n this.defaultWeight = 0.10;\n this.events = [];\n this.targetSelectors = ['input[type=\"text\"]', 'input[type=\"email\"]', 'textarea'];\n this.focusedElement = null;\n this.focusedElementSelector = '';\n this.lastEventTimestamp = 0;\n this.sessionPauseThreshold = 1000;\n this.downListener = null;\n this.upListener = null;\n this.focusListeners = new Map();\n this.blurListeners = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Attach focus/blur listeners to all matching elements\n this.attachFocusListeners();\n // Key event listeners (only track when an input is focused)\n this.downListener = (e) => {\n if (!this.focusedElement)\n return; // No input focused\n const now = Date.now();\n const keyEvent = e;\n // Clear events if pause > 1s (new typing session)\n if (this.lastEventTimestamp > 0 && now - this.lastEventTimestamp > this.sessionPauseThreshold) {\n this.events = [];\n }\n this.events.push({\n key: keyEvent.key,\n type: 'down',\n timestamp: now,\n targetElement: this.focusedElementSelector,\n });\n // Notify detector - keystrokes are valuable events\n this.notifyEvent(0.8);\n this.lastEventTimestamp = now;\n };\n this.upListener = (e) => {\n if (!this.focusedElement)\n return; // No input focused\n const now = Date.now();\n const keyEvent = e;\n // Clear events if pause > 1s (new typing session)\n if (this.lastEventTimestamp > 0 && now - this.lastEventTimestamp > this.sessionPauseThreshold) {\n this.events = [];\n }\n this.events.push({\n key: keyEvent.key,\n type: 'up',\n timestamp: now,\n targetElement: this.focusedElementSelector,\n });\n this.lastEventTimestamp = now;\n };\n document.addEventListener('keydown', this.downListener);\n document.addEventListener('keyup', this.upListener);\n }\n /**\n * Add a new target selector at runtime\n */\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n if (this.isActive) {\n this.attachFocusListenersForSelector(selector);\n }\n }\n }\n attachFocusListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachFocusListenersForSelector(selector);\n });\n }\n attachFocusListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.focusListeners.has(element))\n return; // Already attached\n const focusListener = () => {\n this.focusedElement = element;\n this.focusedElementSelector = selector;\n };\n const blurListener = () => {\n this.focusedElement = null;\n this.focusedElementSelector = '';\n };\n element.addEventListener('focus', focusListener);\n element.addEventListener('blur', blurListener);\n this.focusListeners.set(element, focusListener);\n this.blurListeners.set(element, blurListener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.downListener) {\n document.removeEventListener('keydown', this.downListener);\n this.downListener = null;\n }\n if (this.upListener) {\n document.removeEventListener('keyup', this.upListener);\n this.upListener = null;\n }\n // Remove focus/blur listeners\n this.focusListeners.forEach((listener, element) => {\n element.removeEventListener('focus', listener);\n });\n this.focusListeners.clear();\n this.blurListeners.forEach((listener, element) => {\n element.removeEventListener('blur', listener);\n });\n this.blurListeners.clear();\n this.focusedElement = null;\n }\n reset() {\n this.events = [];\n this.focusedElement = null;\n this.focusedElementSelector = '';\n this.lastEventTimestamp = 0;\n }\n score() {\n if (this.events.length < 6)\n return undefined; // Need at least 3 key pairs\n const downEvents = this.events.filter(e => e.type === 'down');\n if (downEvents.length < 3)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. Analyze keystroke intervals (time between keydown events)\n const keystrokeIntervals = [];\n for (let i = 1; i < downEvents.length; i++) {\n keystrokeIntervals.push(downEvents[i].timestamp - downEvents[i - 1].timestamp);\n }\n const keystrokeAnalysis = analyzeIntervals(keystrokeIntervals);\n if (keystrokeAnalysis) {\n const { statistics, allIdentical } = keystrokeAnalysis;\n // Keyboard-specific heuristics for keystroke timing\n if (allIdentical) {\n return 0.1; // All identical - bot!\n }\n const keystrokeScore = scoreCoefficientOfVariation(statistics.cv);\n score += keystrokeScore;\n factors++;\n // Early return if bot detected\n if (keystrokeScore <= 0.1)\n return keystrokeScore;\n }\n // 2. Analyze press durations (keydown-to-keyup duration)\n const pressDurations = [];\n for (let i = 0; i < this.events.length - 1; i++) {\n if (this.events[i].type === 'down' && this.events[i + 1].type === 'up' &&\n this.events[i].key === this.events[i + 1].key) {\n pressDurations.push(this.events[i + 1].timestamp - this.events[i].timestamp);\n }\n }\n const pressDurationAnalysis = analyzeIntervals(pressDurations);\n if (pressDurationAnalysis) {\n const { statistics, allIdentical } = pressDurationAnalysis;\n // Keyboard-specific heuristics for press duration\n if (allIdentical) {\n return 0.1; // All identical - bot!\n }\n // Check for suspiciously fast key releases (bots often have <5ms press duration)\n if (statistics.mean < 5) {\n score += 0.1; // Too fast = bot (instant release)\n factors++;\n }\n else {\n const pressDurationScore = scoreCoefficientOfVariation(statistics.cv);\n score += pressDurationScore;\n factors++;\n // Early return if bot detected\n if (pressDurationScore <= 0.1)\n return pressDurationScore;\n }\n }\n // 3. Bonus for backspace usage (human error correction)\n const backspaceCount = this.events.filter(e => e.key === 'Backspace').length;\n if (backspaceCount > 0) {\n // Natural human behavior - making corrections\n const backspaceRatio = backspaceCount / downEvents.length;\n if (backspaceRatio > 0.05 && backspaceRatio < 0.3) {\n score += 1.0; // Reasonable error correction\n factors++;\n }\n else if (backspaceRatio > 0) {\n score += 0.8; // Some backspaces\n factors++;\n }\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n // Calculate press durations for visualization\n const pressDurations = [];\n for (let i = 0; i < this.events.length - 1; i++) {\n if (this.events[i].type === 'down' && this.events[i + 1].type === 'up' &&\n this.events[i].key === this.events[i + 1].key) {\n pressDurations.push(this.events[i + 1].timestamp - this.events[i].timestamp);\n }\n }\n return {\n eventCount: this.events.length,\n downEvents: this.events.filter(e => e.type === 'down').length,\n upEvents: this.events.filter(e => e.type === 'up').length,\n backspaceCount: this.events.filter(e => e.key === 'Backspace').length,\n pressDurations, // For graphing\n focusedElement: this.focusedElementSelector,\n trackedElements: this.focusListeners.size,\n };\n }\n}\n", "/**\n * Environment Fingerprinting Strategy\n * Captures browser environment on initialization and tick updates\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { inverseSigmoid, gaussian } from '../math-utils.js';\nexport class EnvironmentStrategy extends BaseStrategy {\n constructor() {\n super(...arguments);\n this.name = 'environment';\n this.defaultWeight = 0.08;\n this.data = null;\n }\n start() {\n this.captureEnvironment();\n }\n stop() {\n // Environment data persists\n }\n reset() {\n this.data = null;\n }\n onTick(_timestamp) {\n // Re-capture environment periodically to detect changes\n this.captureEnvironment();\n }\n score() {\n if (!this.data)\n return undefined;\n const env = this.data;\n let score = 0;\n let factors = 0;\n // Suspicious indicators\n score += env.suspiciousDimensions ? 0.1 : 1.0;\n score += env.suspiciousRatio ? 0.2 : 1.0;\n score += env.featureInconsistency ? 0.3 : 1.0;\n factors += 3;\n // Browser features\n const featureCount = [\n env.hasWebGL,\n env.hasLocalStorage,\n env.hasSessionStorage,\n env.hasIndexedDB,\n ].filter(Boolean).length;\n score += featureCount / 4;\n factors++;\n // Plugins\n score += inverseSigmoid(env.plugins, -2, -0.5);\n score += (env.plugins > 0 ? 1.0 : 0.1);\n factors += 2;\n // Device\n score += gaussian(env.devicePixelRatio, 2, 1.5);\n score += (env.colorDepth === 24 || env.colorDepth === 32) ? 1.0 : 0.4;\n factors += 2;\n return factors > 0 ? score / factors : undefined;\n }\n isMobileDevice() {\n // Multiple checks for mobile detection\n const hasTouchScreen = navigator.maxTouchPoints > 0 || 'ontouchstart' in window;\n const mobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n const smallScreen = window.innerWidth < 768 && window.innerHeight < 1024;\n return (hasTouchScreen && smallScreen) || mobileUA;\n }\n captureEnvironment() {\n try {\n // WebGL detection\n let hasWebGL = false;\n try {\n const canvas = document.createElement('canvas');\n hasWebGL = !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));\n }\n catch (e) {\n hasWebGL = false;\n }\n // WebRTC detection\n const hasWebRTC = !!(window.RTCPeerConnection ||\n window.mozRTCPeerConnection ||\n window.webkitRTCPeerConnection);\n // Mobile detection\n const isMobile = this.isMobileDevice();\n const windowWidth = window.innerWidth;\n const windowHeight = window.innerHeight;\n const screenWidth = window.screen.width;\n const screenHeight = window.screen.height;\n // Suspicious dimensions\n const suspiciousDimensions = (windowWidth === 800 && windowHeight === 600) ||\n (windowWidth === 1024 && windowHeight === 768) ||\n (windowWidth === 1280 && windowHeight === 720) ||\n (screenWidth === 800 && screenHeight === 600);\n // Suspicious ratio\n const windowScreenRatio = (windowWidth * windowHeight) / (screenWidth * screenHeight);\n const suspiciousRatio = windowScreenRatio === 1.0 ||\n windowScreenRatio < 0.1 ||\n windowScreenRatio > 1.0;\n // Feature inconsistency\n const hasStorage = typeof localStorage !== 'undefined' && typeof sessionStorage !== 'undefined';\n const featureInconsistency = (navigator.plugins.length === 0 && navigator.mimeTypes.length === 0) ||\n !hasWebGL ||\n !hasStorage;\n this.data = {\n screenWidth,\n screenHeight,\n windowWidth,\n windowHeight,\n devicePixelRatio: window.devicePixelRatio,\n colorDepth: window.screen.colorDepth,\n userAgent: navigator.userAgent,\n platform: navigator.platform,\n language: navigator.language,\n languages: navigator.languages ? Array.from(navigator.languages) : [navigator.language],\n hardwareConcurrency: navigator.hardwareConcurrency,\n maxTouchPoints: navigator.maxTouchPoints || 0,\n vendor: navigator.vendor,\n hasWebGL,\n hasWebRTC,\n hasLocalStorage: typeof localStorage !== 'undefined',\n hasSessionStorage: typeof sessionStorage !== 'undefined',\n hasIndexedDB: 'indexedDB' in window,\n plugins: navigator.plugins.length,\n mimeTypes: navigator.mimeTypes.length,\n suspiciousRatio,\n suspiciousDimensions,\n featureInconsistency,\n isMobile,\n timestamp: Date.now(),\n };\n }\n catch (error) {\n console.warn('Failed to capture environment:', error);\n }\n }\n getDebugInfo() {\n return this.data;\n }\n /**\n * Check if current device is mobile\n * Returns true if mobile, false otherwise\n * Returns null if environment hasn't been captured yet\n */\n isMobile() {\n var _a, _b;\n return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.isMobile) !== null && _b !== void 0 ? _b : null;\n }\n}\n", "/**\n * Resize Behavior Detection Strategy\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { inverseSigmoid, sigmoid } from '../math-utils.js';\nexport class ResizeStrategy extends BaseStrategy {\n constructor() {\n super(...arguments);\n this.name = 'resize';\n this.defaultWeight = 0.02;\n this.events = [];\n this.listener = null;\n this.isActive = false;\n this.lastMousePosition = null;\n this.mouseListener = null;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Track mouse for resize detection\n this.mouseListener = (e) => {\n const mouseEvent = e;\n this.lastMousePosition = {\n x: mouseEvent.clientX,\n y: mouseEvent.clientY,\n };\n };\n document.addEventListener('mousemove', this.mouseListener, { passive: true });\n // Track resizes\n this.listener = () => {\n var _a, _b;\n const mouseX = (_a = this.lastMousePosition) === null || _a === void 0 ? void 0 : _a.x;\n const mouseY = (_b = this.lastMousePosition) === null || _b === void 0 ? void 0 : _b.y;\n let mouseNearEdge = false;\n if (mouseX !== undefined && mouseY !== undefined) {\n const edgeThreshold = 50;\n mouseNearEdge = (mouseX < edgeThreshold ||\n mouseX > window.innerWidth - edgeThreshold ||\n mouseY < edgeThreshold ||\n mouseY > window.innerHeight - edgeThreshold);\n }\n this.events.push({\n width: window.innerWidth,\n height: window.innerHeight,\n mouseX,\n mouseY,\n mouseNearEdge,\n timestamp: Date.now(),\n });\n };\n window.addEventListener('resize', this.listener);\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n window.removeEventListener('resize', this.listener);\n this.listener = null;\n }\n if (this.mouseListener) {\n document.removeEventListener('mousemove', this.mouseListener);\n this.mouseListener = null;\n }\n }\n reset() {\n this.events = [];\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let score = 0;\n let factors = 0;\n // Frequency\n score += inverseSigmoid(this.events.length, 5, 0.5);\n factors++;\n // Mouse near edge\n const withMouse = this.events.filter(e => e.mouseX !== undefined);\n if (withMouse.length > 0) {\n const nearEdge = withMouse.filter(e => e.mouseNearEdge).length;\n score += sigmoid(nearEdge / withMouse.length, 0.5, 8);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n withMouseData: this.events.filter(e => e.mouseX !== undefined).length,\n };\n }\n}\n", "/**\n * Browser Build - Auto-initializing standalone bundle for CDN usage\n *\n * Usage:\n * <script src=\"https://cdn.../behavior-detector.js\"></script>\n * <script>\n * window.bdSettings = {\n * strategies: {\n * mouse: { weight: 0.3 },\n * scroll: { weight: 0.15 },\n * click: { weight: 0.3 },\n * keyboard: { weight: 0.1 },\n * environment: { weight: 0.08 },\n * resize: { weight: 0.02 }\n * },\n * autoStart: true,\n * checkMs: 2000,\n * pauseOnHidden: true, // Auto-pause when tab hidden (default: true)\n * onScore: (result) => {\n * console.log('Human likelihood:', result.score);\n * if (result.score < 0.3) {\n * // Likely bot\n * }\n * },\n * ifBot: (result) => {\n * // Called when score < threshold\n * console.warn('Bot detected:', result);\n * },\n * botThreshold: 0.3\n * }\n * </script>\n */\nimport { BehaviorDetector } from './behavior-detector.js';\nimport { MouseStrategy, ScrollStrategy, ClickStrategy, TapStrategy, KeyboardStrategy, EnvironmentStrategy, ResizeStrategy, } from './strategies/index.js';\n/**\n * Detect if the current device is mobile\n */\nfunction isMobileDevice() {\n const hasTouchScreen = navigator.maxTouchPoints > 0 || 'ontouchstart' in window;\n const mobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n const smallScreen = window.innerWidth < 768 && window.innerHeight < 1024;\n return (hasTouchScreen && smallScreen) || mobileUA;\n}\nclass BehaviorDetectionAPI {\n constructor() {\n this.detector = null;\n this.checkInterval = null;\n this.settings = null;\n }\n /**\n * Initialize the detector with settings\n */\n init(settings) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;\n if (this.detector) {\n this.stop();\n }\n this.settings = settings;\n this.detector = new BehaviorDetector({\n pauseOnHidden: settings.pauseOnHidden !== undefined ? settings.pauseOnHidden : true\n });\n // Detect if mobile to adjust strategy selection and weights\n const isMobile = isMobileDevice();\n const strategies = settings.strategies || {};\n // Mobile-adjusted default weights\n const defaultWeights = isMobile ? {\n mouse: 0, // Disabled on mobile\n scroll: 0.35, // Increased (more reliable on mobile)\n click: 0, // Disabled on mobile (use tap instead)\n tap: 0.35, // Mobile tap detection\n keyboard: 0.15,\n environment: 0.10,\n resize: 0.05, // Orientation changes\n } : {\n mouse: 0.30,\n scroll: 0.15,\n click: 0.30,\n tap: 0, // Disabled on desktop\n keyboard: 0.10,\n environment: 0.08,\n resize: 0.02,\n };\n // Mouse - Desktop only\n if (!isMobile && ((_a = strategies.mouse) === null || _a === void 0 ? void 0 : _a.enabled) !== false) {\n const strategy = new MouseStrategy();\n const weight = (_c = (_b = strategies.mouse) === null || _b === void 0 ? void 0 : _b.weight) !== null && _c !== void 0 ? _c : defaultWeights.mouse;\n this.detector.addStrategy(strategy, weight);\n }\n // Scroll - Universal\n if (((_d = strategies.scroll) === null || _d === void 0 ? void 0 : _d.enabled) !== false) {\n const strategy = new ScrollStrategy();\n const weight = (_f = (_e = strategies.scroll) === null || _e === void 0 ? void 0 : _e.weight) !== null && _f !== void 0 ? _f : defaultWeights.scroll;\n this.detector.addStrategy(strategy, weight);\n }\n // Click - Desktop only\n if (!isMobile && ((_g = strategies.click) === null || _g === void 0 ? void 0 : _g.enabled) !== false) {\n const strategy = new ClickStrategy();\n const weight = (_j = (_h = strategies.click) === null || _h === void 0 ? void 0 : _h.weight) !== null && _j !== void 0 ? _j : defaultWeights.click;\n this.detector.addStrategy(strategy, weight);\n }\n // Tap - Mobile only\n if (isMobile && ((_k = strategies.tap) === null || _k === void 0 ? void 0 : _k.enabled) !== false) {\n const strategy = new TapStrategy();\n const weight = (_m = (_l = strategies.tap) === null || _l === void 0 ? void 0 : _l.weight) !== null && _m !== void 0 ? _m : defaultWeights.tap;\n this.detector.addStrategy(strategy, weight);\n }\n // Keyboard - Universal\n if (((_o = strategies.keyboard) === null || _o === void 0 ? void 0 : _o.enabled) !== false) {\n const strategy = new KeyboardStrategy();\n const weight = (_q = (_p = strategies.keyboard) === null || _p === void 0 ? void 0 : _p.weight) !== null && _q !== void 0 ? _q : defaultWeights.keyboard;\n this.detector.addStrategy(strategy, weight);\n }\n // Environment - Universal\n if (((_r = strategies.environment) === null || _r === void 0 ? void 0 : _r.enabled) !== false) {\n const strategy = new EnvironmentStrategy();\n const weight = (_t = (_s = strategies.environment) === null || _s === void 0 ? void 0 : _s.weight) !== null && _t !== void 0 ? _t : defaultWeights.environment;\n this.detector.addStrategy(strategy, weight);\n }\n // Resize - Universal\n if (((_u = strategies.resize) === null || _u === void 0 ? void 0 : _u.enabled) !== false) {\n const strategy = new ResizeStrategy();\n const weight = (_w = (_v = strategies.resize) === null || _v === void 0 ? void 0 : _v.weight) !== null && _w !== void 0 ? _w : defaultWeights.resize;\n this.detector.addStrategy(strategy, weight);\n }\n // Start if autoStart is enabled\n if (settings.autoStart !== false) {\n this.start();\n }\n // Set up periodic checking if checkMs is specified\n if (settings.checkMs && settings.checkMs > 0) {\n this.startPeriodicCheck(settings.checkMs);\n }\n // Call onReady callback\n if (settings.onReady) {\n settings.onReady(this);\n }\n }\n /**\n * Start detection\n */\n start() {\n if (!this.detector) {\n console.warn('BehaviorDetector: Call init() before start()');\n return;\n }\n this.detector.start();\n }\n /**\n * Stop detection\n */\n stop() {\n if (this.detector) {\n this.detector.stop();\n }\n if (this.checkInterval !== null) {\n clearInterval(this.checkInterval);\n this.checkInterval = null;\n }\n }\n /**\n * Get current score\n */\n async score() {\n if (!this.detector) {\n console.warn('BehaviorDetector: Call init() before score()');\n return null;\n }\n return this.detector.score({ breakdown: true });\n }\n /**\n * Start periodic checking\n */\n startPeriodicCheck(intervalMs) {\n if (this.checkInterval !== null) {\n clearInterval(this.checkInterval);\n }\n this.checkInterval = window.setInterval(async () => {\n var _a, _b;\n const result = await this.score();\n if (!result || !this.settings)\n return;\n // Call onScore callback\n if (this.settings.onScore) {\n this.settings.onScore(result);\n }\n // Check thresholds\n const botThreshold = (_a = this.settings.botThreshold) !== null && _a !== void 0 ? _a : 0.3;\n const humanThreshold = (_b = this.settings.humanThreshold) !== null && _b !== void 0 ? _b : 0.7;\n if (result.score < botThreshold && this.settings.ifBot) {\n this.settings.ifBot(result);\n }\n else if (result.score >= humanThreshold && this.settings.ifHuman) {\n this.settings.ifHuman(result);\n }\n }, intervalMs);\n }\n /**\n * Get the underlying detector instance for advanced usage\n */\n getDetector() {\n return this.detector;\n }\n}\n// Create global API instance\nconst api = new BehaviorDetectionAPI();\n// Auto-initialize if settings are already present\nif (typeof window !== 'undefined') {\n // Expose API globally\n window.BehaviorDetector = api;\n // Check for settings on load\n const checkAndInit = () => {\n const settings = window.bdSettings;\n if (settings) {\n api.init(settings);\n }\n };\n // Try immediate init\n checkAndInit();\n // Also try after DOM ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', checkAndInit);\n }\n}\n// No exports needed for browser IIFE build - window.BehaviorDetector is sufficient\n"],
5
- "mappings": "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",
6
- "names": ["BehaviorDetector", "tickOptions", "strategy", "weight", "config", "event", "strategyWeight", "contribution", "name", "enabled", "_", "options", "breakdown", "result", "_a", "_b", "counts", "debug", "threshold", "now", "factors", "weights", "totalWeight", "weightedSum", "score", "overall", "BaseStrategy", "callback", "weight", "sigmoid", "x", "midpoint", "steepness", "inverseSigmoid", "gaussian", "ideal", "width", "exponent", "calculateStatistics", "values", "mean", "a", "b", "variance", "sum", "v", "stdDev", "cv", "analyzeIntervals", "intervals", "uniqueCount", "i", "allIdentical", "scoreCoefficientOfVariation", "gaussian", "MouseStrategy", "BaseStrategy", "options", "width", "height", "e", "mouseEvent", "now", "currentPos", "dx", "dy", "normalizedDistance", "rawAngle", "angleDiff", "cutoff", "score", "factors", "distances", "p", "stats", "calculateStatistics", "gaussian", "angles", "angleChanges", "i", "avgChange", "b", "ScrollStrategy", "BaseStrategy", "options", "_e", "scrollY", "now", "pixelDelta", "deltaTime", "normalizedDistance", "velocity", "cutoff", "score", "factors", "distances", "p", "d", "stats", "calculateStatistics", "gaussian", "velocities", "instantJumps", "jumpRatio", "inverseSigmoid", "ClickStrategy", "BaseStrategy", "options", "e", "mouseEvent", "selector", "element", "listener", "_a", "_b", "clickEvent", "rect", "inViewport", "position", "mx", "my", "centerX", "centerY", "totalScore", "click", "TapStrategy", "BaseStrategy", "options", "selector", "element", "startListener", "e", "touchEvent", "touch", "endListener", "startData", "now", "duration", "dx", "dy", "movement", "rect", "inViewport", "tx", "ty", "overElement", "position", "centerX", "centerY", "listener", "score", "factors", "positionScore", "tap", "durations", "durationAnalysis", "analyzeIntervals", "statistics", "allIdentical", "scoreCoefficientOfVariation", "gaussian", "movements", "avgMovement", "b", "intervals", "i", "intervalAnalysis", "KeyboardStrategy", "BaseStrategy", "options", "e", "now", "keyEvent", "selector", "element", "focusListener", "blurListener", "listener", "downEvents", "score", "factors", "keystrokeIntervals", "i", "keystrokeAnalysis", "analyzeIntervals", "statistics", "allIdentical", "keystrokeScore", "scoreCoefficientOfVariation", "pressDurations", "pressDurationAnalysis", "pressDurationScore", "backspaceCount", "backspaceRatio", "EnvironmentStrategy", "BaseStrategy", "_timestamp", "env", "score", "factors", "featureCount", "inverseSigmoid", "gaussian", "hasTouchScreen", "mobileUA", "smallScreen", "hasWebGL", "canvas", "e", "hasWebRTC", "isMobile", "windowWidth", "windowHeight", "screenWidth", "screenHeight", "suspiciousDimensions", "windowScreenRatio", "suspiciousRatio", "hasStorage", "featureInconsistency", "error", "_a", "_b", "ResizeStrategy", "BaseStrategy", "e", "mouseEvent", "_a", "_b", "mouseX", "mouseY", "mouseNearEdge", "score", "factors", "inverseSigmoid", "withMouse", "nearEdge", "sigmoid", "isMobileDevice", "hasTouchScreen", "mobileUA", "smallScreen", "BehaviorDetectionAPI", "settings", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_j", "_k", "_l", "_m", "_o", "_p", "_q", "_r", "_s", "_t", "_u", "_v", "_w", "BehaviorDetector", "isMobile", "strategies", "defaultWeights", "strategy", "MouseStrategy", "weight", "ScrollStrategy", "ClickStrategy", "TapStrategy", "KeyboardStrategy", "EnvironmentStrategy", "ResizeStrategy", "intervalMs", "result", "botThreshold", "humanThreshold", "api", "checkAndInit"]
4
+ "sourcesContent": ["/**\n * Main class for behavior detection\n * Uses modular strategy pattern for tree-shakeable, autonomous detection modules\n */\nexport class BehaviorDetector {\n constructor(tickOptions) {\n // Strategy mode\n this.strategies = new Map();\n this.isTracking = false;\n this.isPausedByVisibility = false;\n this.tickInterval = null;\n this.tickIntervalMs = 1000; // Default: 1 second\n this.pauseOnHidden = true;\n this.visibilityChangeHandler = null;\n // Confidence tracking\n this.confidenceScore = 0;\n this.CONFIDENCE_TARGET = 1.0; // Target confidence for reliable classification\n this.CONFIDENCE_DECAY = 0.95; // Per event decay to prevent infinite growth\n if (tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.interval) {\n this.tickIntervalMs = tickOptions.interval;\n }\n if ((tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.pauseOnHidden) !== undefined) {\n this.pauseOnHidden = tickOptions.pauseOnHidden;\n }\n }\n /**\n * Add a detection strategy\n */\n addStrategy(strategy, weight) {\n const config = {\n strategy,\n weight: weight !== null && weight !== void 0 ? weight : strategy.defaultWeight,\n enabled: true,\n };\n this.strategies.set(strategy.name, config);\n // Set up event callback for confidence tracking\n if (strategy.setEventCallback) {\n strategy.setEventCallback((event) => {\n this.onStrategyEvent(event, config.weight);\n });\n }\n // If already tracking, start this strategy immediately\n if (this.isTracking) {\n strategy.start();\n }\n return this;\n }\n /**\n * Handle event from strategy - update confidence\n */\n onStrategyEvent(event, strategyWeight) {\n // Apply decay to existing confidence to prevent infinite growth\n this.confidenceScore *= this.CONFIDENCE_DECAY;\n // Add weighted contribution from this event\n // eventWeight (0-1) * strategyWeight (e.g. 0.3 for mouse) = contribution\n const contribution = event.weight * strategyWeight;\n this.confidenceScore = Math.min(this.CONFIDENCE_TARGET, this.confidenceScore + contribution);\n }\n /**\n * Remove a detection strategy\n */\n removeStrategy(name) {\n const config = this.strategies.get(name);\n if (config) {\n if (this.isTracking) {\n config.strategy.stop();\n }\n this.strategies.delete(name);\n }\n return this;\n }\n /**\n * Enable/disable a strategy\n */\n setStrategyEnabled(name, enabled) {\n const config = this.strategies.get(name);\n if (config) {\n config.enabled = enabled;\n // If tracking and being disabled, stop it\n if (!enabled && this.isTracking) {\n config.strategy.stop();\n }\n // If tracking and being enabled, start it\n if (enabled && this.isTracking) {\n config.strategy.start();\n }\n }\n return this;\n }\n /**\n * Get all registered strategies\n */\n getStrategies() {\n return this.strategies;\n }\n /**\n * Start tracking\n */\n start() {\n if (this.isTracking)\n return;\n this.isTracking = true;\n // Set up visibility change listener\n if (this.pauseOnHidden && typeof document !== 'undefined') {\n this.visibilityChangeHandler = this.handleVisibilityChange.bind(this);\n document.addEventListener('visibilitychange', this.visibilityChangeHandler);\n // Check initial visibility state\n if (document.hidden) {\n this.isPausedByVisibility = true;\n return; // Don't start strategies if already hidden\n }\n }\n // Start all enabled strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.start();\n }\n }\n // Start tick mechanism\n this.startTick();\n }\n /**\n * Stop tracking\n */\n stop() {\n if (!this.isTracking)\n return;\n this.isTracking = false;\n this.isPausedByVisibility = false;\n // Remove visibility change listener\n if (this.visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n // Stop all strategies\n for (const [_, config] of this.strategies) {\n config.strategy.stop();\n }\n // Stop tick\n this.stopTick();\n }\n /**\n * Reset all data\n */\n reset() {\n this.confidenceScore = 0;\n for (const [_, config] of this.strategies) {\n config.strategy.reset();\n }\n }\n /**\n * Calculate human likelihood score\n */\n async score(options = {}) {\n const breakdown = this.calculateStrategyScore();\n const result = {\n score: breakdown.overall,\n };\n if (options.breakdown) {\n result.breakdown = breakdown;\n }\n // Note: auditTrail not available in strategy mode\n // Each strategy manages its own data independently\n return result;\n }\n /**\n * Check if currently tracking\n */\n isActive() {\n return this.isTracking;\n }\n /**\n * Check if currently paused due to tab visibility\n */\n isPaused() {\n return this.isPausedByVisibility;\n }\n /**\n * Get event count from all strategies\n */\n getEventCount() {\n var _a, _b;\n const counts = {};\n for (const [name, config] of this.strategies) {\n const debug = (_b = (_a = config.strategy).getDebugInfo) === null || _b === void 0 ? void 0 : _b.call(_a);\n if ((debug === null || debug === void 0 ? void 0 : debug.eventCount) !== undefined) {\n counts[name] = debug.eventCount;\n }\n }\n return counts;\n }\n /**\n * Get debug info from all strategies\n */\n getStrategyDebugInfo() {\n const debug = {};\n for (const [name, config] of this.strategies) {\n if (config.strategy.getDebugInfo) {\n debug[name] = config.strategy.getDebugInfo();\n }\n }\n return debug;\n }\n /**\n * Get current confidence score (0-1)\n * Represents how much interaction data we've collected\n * Higher confidence = more reliable classification\n */\n getConfidence() {\n return Math.min(1, this.confidenceScore);\n }\n /**\n * Check if confidence is above threshold for reliable classification\n * @param threshold - Minimum confidence (0-1), default 0.3\n */\n hasConfidentData(threshold = 0.3) {\n return this.getConfidence() >= threshold;\n }\n /**\n * Cleanup resources\n */\n destroy() {\n this.stop();\n this.strategies.clear();\n }\n /**\n * Handle visibility change events\n */\n handleVisibilityChange() {\n if (!this.isTracking)\n return;\n if (document.hidden) {\n // Tab became hidden - pause detection\n if (!this.isPausedByVisibility) {\n this.isPausedByVisibility = true;\n // Stop all strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.stop();\n }\n }\n // Stop tick\n this.stopTick();\n }\n }\n else {\n // Tab became visible - resume detection\n if (this.isPausedByVisibility) {\n this.isPausedByVisibility = false;\n // Restart all enabled strategies\n for (const [_, config] of this.strategies) {\n if (config.enabled) {\n config.strategy.start();\n }\n }\n // Restart tick\n this.startTick();\n }\n }\n }\n /**\n * Start tick mechanism for strategies\n */\n startTick() {\n if (this.tickInterval !== null)\n return;\n this.tickInterval = window.setInterval(() => {\n const now = Date.now();\n for (const [_, config] of this.strategies) {\n if (config.enabled && config.strategy.onTick) {\n config.strategy.onTick(now);\n }\n }\n }, this.tickIntervalMs);\n }\n /**\n * Stop tick mechanism\n */\n stopTick() {\n if (this.tickInterval !== null) {\n clearInterval(this.tickInterval);\n this.tickInterval = null;\n }\n }\n /**\n * Calculate score using strategies\n */\n calculateStrategyScore() {\n const factors = {};\n const weights = {};\n let totalWeight = 0;\n let weightedSum = 0;\n for (const [name, config] of this.strategies) {\n if (!config.enabled)\n continue;\n const score = config.strategy.score();\n factors[name] = score;\n weights[name] = config.weight;\n if (score !== undefined && score !== null) {\n totalWeight += config.weight;\n weightedSum += score * config.weight;\n }\n }\n const overall = totalWeight > 0 ? weightedSum / totalWeight : 0.5;\n return {\n overall: Math.max(0, Math.min(1, overall)),\n factors,\n weights,\n };\n }\n}\n", "/**\n * Detection Strategy Interface\n * Each strategy is a fully autonomous module responsible for:\n * - Registering its own event listeners\n * - Managing its own state and events\n * - Responding to lifecycle events (start/stop)\n * - Optionally receiving tick updates for polling-based detection\n */\n/**\n * Base class for detection strategies\n * Handles event callback pattern to avoid repetition\n */\nexport class BaseStrategy {\n constructor() {\n this.eventCallback = null;\n }\n setEventCallback(callback) {\n this.eventCallback = callback;\n }\n notifyEvent(weight) {\n if (this.eventCallback) {\n this.eventCallback({\n strategy: this.name,\n weight,\n timestamp: Date.now()\n });\n }\n }\n}\n", "/**\n * Mathematical utility functions for continuous scoring\n * Replaces magic number if-else chains with smooth mathematical functions\n */\n/**\n * Sigmoid function - Maps any value to [0, 1] with smooth S-curve\n * @param x - Input value\n * @param midpoint - Value that maps to 0.5\n * @param steepness - How steep the curve is (higher = steeper)\n */\nexport function sigmoid(x, midpoint = 0, steepness = 1) {\n return 1 / (1 + Math.exp(-steepness * (x - midpoint)));\n}\n/**\n * Inverse sigmoid - High values map to low scores\n */\nexport function inverseSigmoid(x, midpoint = 0, steepness = 1) {\n return 1 - sigmoid(x, midpoint, steepness);\n}\n/**\n * Gaussian (bell curve) - Peak at ideal value, falls off on both sides\n * @param x - Input value\n * @param ideal - Optimal value (peak of curve)\n * @param width - How wide the acceptable range is\n */\nexport function gaussian(x, ideal = 0, width = 1) {\n const exponent = -Math.pow(x - ideal, 2) / (2 * width * width);\n return Math.exp(exponent);\n}\n/**\n * Exponential decay - High values get penalized exponentially\n */\nexport function exponentialDecay(x, decayRate = 0.1) {\n return Math.exp(-decayRate * x);\n}\n/**\n * Normalize value to [0, 1] range\n */\nexport function normalize(value, min = 0, max = 1) {\n if (max === min)\n return 0.5;\n return Math.max(0, Math.min(1, (value - min) / (max - min)));\n}\n/**\n * Clamp value to [0, 1]\n */\nexport function clamp01(value) {\n return Math.max(0, Math.min(1, value));\n}\n/**\n * Calculate statistical metrics for an array of numbers\n * @param values - Array of numerical values\n * @returns Statistical metrics (mean, variance, stdDev, cv)\n */\nexport function calculateStatistics(values) {\n if (values.length === 0) {\n return { mean: 0, variance: 0, stdDev: 0, cv: 0 };\n }\n const mean = values.reduce((a, b) => a + b, 0) / values.length;\n const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / values.length;\n const stdDev = Math.sqrt(variance);\n const cv = mean > 0 ? stdDev / mean : 0;\n return { mean, variance, stdDev, cv };\n}\n/**\n * Analyze timing intervals for bot-like patterns\n * Returns raw analysis data without scoring - caller decides heuristics\n *\n * @param intervals - Array of time intervals (ms)\n * @returns Analysis of interval patterns including stats and uniqueness\n */\nexport function analyzeIntervals(intervals) {\n if (intervals.length < 2)\n return undefined;\n // Check for identical intervals (round to 10ms to account for floating point)\n const uniqueCount = new Set(intervals.map(i => Math.round(i / 10))).size;\n const allIdentical = uniqueCount === 1;\n // Calculate statistics\n const statistics = calculateStatistics(intervals);\n return {\n statistics,\n uniqueCount,\n allIdentical,\n };\n}\n/**\n * Score coefficient of variation\n * Maps CV to human-likeness score using Gaussian\n * Ideal CV is around 0.4-0.5 (moderate variation)\n */\nexport function scoreCoefficientOfVariation(cv) {\n // Too low (<0.1) = bot-like (too consistent)\n // Too high (>1.5) = random noise\n // Ideal = 0.4-0.6 (natural human variation)\n if (cv < 0.05)\n return 0.1; // Almost zero variation - definitely bot\n if (cv > 2.0)\n return 0.3; // Too random\n // Gaussian centered at 0.45 with width of 0.35\n return gaussian(cv, 0.45, 0.35);\n}\n/**\n * Score entropy - Higher is better (more random = more human)\n * Uses sigmoid to smoothly map entropy to score\n */\nexport function scoreEntropy(normalizedEntropy) {\n // Entropy of 0.7+ is very human\n // Entropy < 0.3 is very bot-like\n return sigmoid(normalizedEntropy, 0.5, 8); // Steep curve at midpoint 0.5\n}\n/**\n * Score autocorrelation - Lower is better (less periodic = more human)\n */\nexport function scoreAutocorrelation(autocorr) {\n // Low autocorrelation (<0.2) is natural\n // High autocorrelation (>0.6) is periodic/bot-like\n return inverseSigmoid(autocorr, 0.4, 10);\n}\n/**\n * Score jerk - Lower is better (smoother = more human)\n */\nexport function scoreJerk(avgJerk) {\n // Human jerk typically < 0.01\n // Bot jerk often > 0.1\n // Use inverse sigmoid\n return inverseSigmoid(avgJerk, 0.05, 50);\n}\n", "/**\n * Mouse Movement Detection Strategy\n * Autonomous module that manages its own mouse event listeners and state\n * Tracks distance and angle to detect unnatural jumps and sharp turns\n *\n * Enhanced detection:\n * - Pre-click stillness (micro-movements before clicks)\n * - Entry point analysis (where mouse enters viewport)\n * - Velocity consistency\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { calculateStatistics, gaussian } from '../math-utils.js';\nexport class MouseStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'mouse';\n this.defaultWeight = 0.30;\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n this.rollingWindowMs = 5000;\n this.listener = null;\n this.leaveListener = null;\n this.enterListener = null;\n this.isActive = false;\n this.screenDiagonal = 1;\n /** Entry points tracking */\n this.entryPoints = [];\n /** Micro-movements in last 500ms (for stillness detection) */\n this.microMovements = [];\n /** Stillness window in ms */\n this.STILLNESS_WINDOW = 500;\n if ((options === null || options === void 0 ? void 0 : options.rollingWindow) !== undefined)\n this.rollingWindowMs = options.rollingWindow;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Calculate screen diagonal for normalization (distance relative to screen size)\n const width = window.innerWidth;\n const height = window.innerHeight;\n this.screenDiagonal = Math.sqrt(width * width + height * height);\n this.listener = (e) => {\n const mouseEvent = e;\n const now = Date.now();\n const currentPos = { x: mouseEvent.clientX, y: mouseEvent.clientY, timestamp: now };\n // Calculate distance and angle from previous position\n if (this.lastPosition) {\n const dx = currentPos.x - this.lastPosition.x;\n const dy = currentPos.y - this.lastPosition.y;\n const pixelDistance = Math.sqrt(dx * dx + dy * dy);\n // Track micro-movements (1-5px) for stillness detection\n if (pixelDistance >= 1 && pixelDistance <= 5) {\n this.microMovements.push({ dx, dy, timestamp: now });\n // Clean up old micro-movements (shift from front, more efficient than filter)\n const cutoffMicro = now - this.STILLNESS_WINDOW;\n while (this.microMovements.length > 0 && this.microMovements[0].timestamp < cutoffMicro) {\n this.microMovements.shift();\n }\n }\n // Normalize distance to screen diagonal (0-1 range)\n // A full diagonal movement = 1.0, a 10px movement on 2000px screen = 0.005\n const normalizedDistance = pixelDistance / this.screenDiagonal;\n // Only record if movement is meaningful (> 0.001 = ~2px on 2000px screen)\n if (normalizedDistance > 0.001) {\n const rawAngle = Math.atan2(dy, dx); // -PI to PI\n // Unwrap angle to avoid discontinuities (e.g., circles)\n let angleDiff = rawAngle - this.lastAngle;\n // Normalize difference to -PI to PI\n while (angleDiff > Math.PI)\n angleDiff -= 2 * Math.PI;\n while (angleDiff < -Math.PI)\n angleDiff += 2 * Math.PI;\n this.cumulativeAngle += angleDiff;\n this.lastAngle = rawAngle;\n // Store normalized distance (not raw pixels)\n this.distanceSeries.push({ value: normalizedDistance, timestamp: now });\n this.angleSeries.push({ value: this.cumulativeAngle, timestamp: now });\n // Notify detector for confidence tracking\n this.notifyEvent(Math.min(1, normalizedDistance * 100));\n }\n // Apply rolling window efficiently: remove old events from start\n // Since events are chronological, we only check from the beginning\n const cutoff = now - this.rollingWindowMs;\n while (this.distanceSeries.length > 0 && this.distanceSeries[0].timestamp < cutoff) {\n this.distanceSeries.shift();\n this.angleSeries.shift(); // Keep both arrays in sync\n }\n }\n this.lastPosition = currentPos;\n };\n document.addEventListener('mousemove', this.listener, { passive: true });\n // Track mouse entry points into viewport\n this.enterListener = (e) => {\n const mouseEvent = e;\n const now = Date.now();\n const x = mouseEvent.clientX;\n const y = mouseEvent.clientY;\n const width = window.innerWidth;\n const height = window.innerHeight;\n // Calculate edge distances\n const distTop = y;\n const distBottom = height - y;\n const distLeft = x;\n const distRight = width - x;\n const minEdgeDist = Math.min(distTop, distBottom, distLeft, distRight);\n // Determine entry edge\n let entryEdge;\n const edgeThreshold = 50; // pixels from edge to count as edge entry\n if (minEdgeDist < edgeThreshold) {\n if (distTop <= minEdgeDist)\n entryEdge = 'top';\n else if (distBottom <= minEdgeDist)\n entryEdge = 'bottom';\n else if (distLeft <= minEdgeDist)\n entryEdge = 'left';\n else\n entryEdge = 'right';\n }\n else if (x > width * 0.35 && x < width * 0.65 &&\n y > height * 0.35 && y < height * 0.65) {\n entryEdge = 'center'; // Suspicious - bots often start at center\n }\n else if ((distTop < edgeThreshold * 2 && distLeft < edgeThreshold * 2) ||\n (distTop < edgeThreshold * 2 && distRight < edgeThreshold * 2) ||\n (distBottom < edgeThreshold * 2 && distLeft < edgeThreshold * 2) ||\n (distBottom < edgeThreshold * 2 && distRight < edgeThreshold * 2)) {\n entryEdge = 'corner';\n }\n else {\n // Entry from middle of an edge, normal\n if (distTop < distBottom && distTop < distLeft && distTop < distRight)\n entryEdge = 'top';\n else if (distBottom < distLeft && distBottom < distRight)\n entryEdge = 'bottom';\n else if (distLeft < distRight)\n entryEdge = 'left';\n else\n entryEdge = 'right';\n }\n this.entryPoints.push({\n x,\n y,\n timestamp: now,\n edgeDistance: minEdgeDist,\n entryEdge,\n });\n // Keep only last 20 entry points (shift is more memory efficient than slice)\n if (this.entryPoints.length > 20) {\n this.entryPoints.shift();\n }\n };\n document.addEventListener('mouseenter', this.enterListener, { passive: true });\n // Clear data when mouse leaves the window (discontinuous tracking)\n this.leaveListener = () => {\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n this.microMovements = [];\n };\n document.addEventListener('mouseleave', this.leaveListener, { passive: true });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n document.removeEventListener('mousemove', this.listener);\n this.listener = null;\n }\n if (this.leaveListener) {\n document.removeEventListener('mouseleave', this.leaveListener);\n this.leaveListener = null;\n }\n if (this.enterListener) {\n document.removeEventListener('mouseenter', this.enterListener);\n this.enterListener = null;\n }\n }\n reset() {\n this.distanceSeries = [];\n this.angleSeries = [];\n this.lastPosition = null;\n this.lastAngle = 0;\n this.cumulativeAngle = 0;\n this.entryPoints = [];\n this.microMovements = [];\n }\n score() {\n if (this.distanceSeries.length < 10)\n return undefined;\n // Mouse-specific pattern detection (optimized for normalized continuous data)\n // Generic smoothness detector is calibrated for discrete events, not continuous movement\n return this.detectMousePatterns();\n }\n /**\n * Mouse-specific pattern detection\n * Detects bot-like patterns: constant velocity, linear paths, suspicious entry points\n */\n detectMousePatterns() {\n if (this.distanceSeries.length < 10)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. VELOCITY CONSISTENCY - Bots often move at constant speed\n const distances = this.distanceSeries.map(p => p.value);\n if (distances.length >= 3) {\n const stats = calculateStatistics(distances);\n // Real human movement has high variation (CV ~0.8-1.2)\n // page.mouse.move() with steps has lower CV (~0.4-0.6)\n // Narrower gaussian to be strict\n score += gaussian(stats.cv, 0.9, 0.35);\n factors++;\n }\n // 2. DIRECTION CHANGES - Bots often have too few or too many sharp turns\n const angles = this.angleSeries.map(p => p.value);\n if (angles.length >= 3) {\n const angleChanges = [];\n for (let i = 1; i < angles.length; i++) {\n angleChanges.push(Math.abs(angles[i] - angles[i - 1]));\n }\n const avgChange = angleChanges.reduce((a, b) => a + b, 0) / angleChanges.length;\n // Real humans have moderate but varied direction changes\n // page.mouse.move() linear interpolation has very small, consistent changes\n score += gaussian(avgChange, 0.15, 0.12);\n factors++;\n }\n // 3. ENTRY POINT ANALYSIS - Where does mouse enter the viewport?\n const entryScore = this.scoreEntryPoints();\n if (entryScore !== undefined) {\n score += entryScore;\n factors++;\n }\n // 4. MICRO-MOVEMENT PRESENCE - Humans have tremors, bots don't\n const microScore = this.scoreMicroMovements();\n if (microScore !== undefined) {\n score += microScore;\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n /**\n * Score based on viewport entry points\n * Humans enter from edges with momentum; bots often start at (0,0) or center\n */\n scoreEntryPoints() {\n if (this.entryPoints.length < 2)\n return undefined;\n let suspiciousCount = 0;\n let centerCount = 0;\n let cornerCount = 0;\n let originCount = 0;\n for (const entry of this.entryPoints) {\n // Check for (0,0) or near-origin entries (very suspicious)\n if (entry.x < 5 && entry.y < 5) {\n originCount++;\n suspiciousCount++;\n }\n else if (entry.entryEdge === 'center') {\n centerCount++;\n suspiciousCount++;\n }\n else if (entry.entryEdge === 'corner') {\n cornerCount++;\n // Corners are slightly suspicious but not as bad as center\n if (entry.edgeDistance < 10)\n suspiciousCount++;\n }\n }\n const total = this.entryPoints.length;\n const suspiciousRatio = suspiciousCount / total;\n // High ratio of origin entries = definitely bot\n if (originCount >= 2 || originCount / total >= 0.5)\n return 0.1;\n // High ratio of center entries = likely bot\n if (centerCount / total >= 0.5)\n return 0.2;\n // Mix of suspicious entries\n if (suspiciousRatio >= 0.7)\n return 0.3;\n if (suspiciousRatio >= 0.5)\n return 0.5;\n if (suspiciousRatio >= 0.3)\n return 0.7;\n // Mostly edge entries = human\n return 1.0;\n }\n /**\n * Score based on micro-movements (tremor detection)\n * Humans have natural hand tremor causing 1-5px jitter\n * Bots have perfect stillness or no micro-movements\n */\n scoreMicroMovements() {\n // Need some movement data first\n if (this.distanceSeries.length < 20)\n return undefined;\n const microCount = this.microMovements.length;\n // Calculate expected micro-movements based on tracking duration\n // Humans should have ~5-20 micro-movements per second when cursor is active\n const oldestEvent = this.distanceSeries[0];\n const newestEvent = this.distanceSeries[this.distanceSeries.length - 1];\n const durationMs = newestEvent.timestamp - oldestEvent.timestamp;\n if (durationMs < 1000)\n return undefined; // Need at least 1 second of data\n // Micro-movements per second\n const microPerSecond = (microCount / durationMs) * 1000;\n // No micro-movements at all = very suspicious\n if (microCount === 0)\n return 0.3;\n // Very few micro-movements = somewhat suspicious\n if (microPerSecond < 1)\n return 0.5;\n // Some micro-movements = more human-like\n if (microPerSecond < 5)\n return 0.7;\n // Good amount of micro-movements = human\n if (microPerSecond >= 5 && microPerSecond <= 30)\n return 1.0;\n // Excessive micro-movements (> 30/sec) might be artificial noise\n return 0.8;\n }\n /**\n * Get micro-movement count for external use (e.g., by ClickStrategy)\n */\n getMicroMovementCount() {\n return this.microMovements.length;\n }\n /**\n * Get last position for external use\n */\n getLastPosition() {\n return this.lastPosition ? { x: this.lastPosition.x, y: this.lastPosition.y } : null;\n }\n getDebugInfo() {\n return {\n eventCount: this.distanceSeries.length,\n rollingWindow: this.rollingWindowMs,\n isActive: this.isActive,\n distanceSeries: this.distanceSeries,\n angleSeries: this.angleSeries,\n entryPoints: this.entryPoints,\n microMovementCount: this.microMovements.length,\n lastPosition: this.lastPosition,\n };\n }\n}\n", "/**\n * Scroll Behavior Detection Strategy\n * Autonomous module managing scroll event listeners\n * Tracks normalized scroll distance and velocity patterns\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { calculateStatistics, gaussian, inverseSigmoid } from '../math-utils.js';\nexport class ScrollStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'scroll';\n this.defaultWeight = 0.15;\n this.distanceSeries = [];\n this.velocitySeries = [];\n this.lastScrollY = null;\n this.lastTimestamp = 0;\n this.rollingWindowMs = 5000;\n this.documentHeight = 1;\n this.listener = null;\n this.isActive = false;\n if ((options === null || options === void 0 ? void 0 : options.rollingWindow) !== undefined)\n this.rollingWindowMs = options.rollingWindow;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Calculate document height for normalization\n this.documentHeight = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, 1);\n this.listener = (_e) => {\n const scrollY = window.scrollY;\n const now = Date.now();\n // Always update last position on first event\n if (this.lastScrollY === null) {\n this.lastScrollY = scrollY;\n this.lastTimestamp = now;\n return;\n }\n const pixelDelta = scrollY - this.lastScrollY;\n const deltaTime = now - this.lastTimestamp;\n // Skip if no actual scroll happened\n if (pixelDelta === 0) {\n return;\n }\n // Normalize scroll distance to document height (0-1 range)\n const normalizedDistance = Math.abs(pixelDelta) / this.documentHeight;\n // Record all scroll movements (no threshold - let pattern detection decide)\n if (deltaTime > 0) {\n const velocity = normalizedDistance / deltaTime; // normalized units per ms\n // Store as time series\n this.distanceSeries.push({ value: normalizedDistance, timestamp: now });\n this.velocitySeries.push({ value: velocity, timestamp: now });\n // Notify detector for confidence tracking\n this.notifyEvent(Math.min(1, normalizedDistance * 10));\n // Apply rolling window efficiently\n const cutoff = now - this.rollingWindowMs;\n while (this.distanceSeries.length > 0 && this.distanceSeries[0].timestamp < cutoff) {\n this.distanceSeries.shift();\n this.velocitySeries.shift();\n }\n }\n this.lastScrollY = scrollY;\n this.lastTimestamp = now;\n };\n // Listen on window for scroll events (document scrolling)\n window.addEventListener('scroll', this.listener, { passive: true });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n window.removeEventListener('scroll', this.listener);\n this.listener = null;\n }\n }\n reset() {\n this.distanceSeries = [];\n this.velocitySeries = [];\n this.lastScrollY = null;\n this.lastTimestamp = 0;\n }\n score() {\n if (this.distanceSeries.length < 2)\n return undefined;\n // Scroll-specific pattern detection\n return this.detectScrollPatterns();\n }\n /**\n * Scroll-specific pattern detection\n * Detects bot-like patterns: constant deltas, instant jumps, too smooth\n */\n detectScrollPatterns() {\n if (this.distanceSeries.length < 2)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. IDENTICAL DELTAS - Smoking gun for bots\n const distances = this.distanceSeries.map(p => p.value);\n if (distances.length >= 2) {\n // Check if all distances are identical (tolerance for floating point)\n const uniqueDistances = new Set(distances.map(d => Math.round(d * 1000))).size;\n if (uniqueDistances === 1) {\n // All scroll amounts identical = definite bot\n return 0.05;\n }\n }\n // 2. DISTANCE CONSISTENCY - Bots often scroll same amount repeatedly\n if (distances.length >= 2) {\n const stats = calculateStatistics(distances);\n // Real humans have high CV (>0.8) due to natural scroll acceleration/deceleration\n // Simple automation has lower CV even with varied amounts\n // Gaussian centered high with narrow width - be strict\n score += gaussian(stats.cv, 1.0, 0.4);\n factors++;\n }\n // 3. VELOCITY VARIATION - Humans have highly variable scroll speeds\n const velocities = this.velocitySeries.map(p => p.value);\n if (velocities.length >= 2) {\n const stats = calculateStatistics(velocities);\n // Human velocity is very chaotic (acceleration/deceleration)\n // Automation has more consistent velocity even with delays\n score += gaussian(stats.cv, 1.2, 0.5);\n factors++;\n }\n // 4. INSTANT JUMPS - Detect programmatic scrollTo\n const instantJumps = distances.filter(d => d > 0.1).length; // >10% of document in one event\n if (distances.length > 0) {\n const jumpRatio = instantJumps / distances.length;\n // Penalize high jump ratio (programmatic scrollTo)\n score += inverseSigmoid(jumpRatio, 0.3, 15);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.distanceSeries.length,\n rollingWindow: this.rollingWindowMs,\n isActive: this.isActive,\n distanceSeries: this.distanceSeries,\n velocitySeries: this.velocitySeries,\n };\n }\n}\n", "/**\n * Click Behavior Detection Strategy\n * Monitors specific elements for click positioning patterns\n *\n * Enhanced detection:\n * - Click-mouse position delta (bots using .click() have mismatched positions)\n * - Pre-click mouse trajectory analysis\n * - Time between last mousemove and click\n */\nimport { BaseStrategy } from '../strategy.js';\nexport class ClickStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'click';\n this.defaultWeight = 0.30;\n this.events = [];\n this.targetSelectors = ['button', 'a', 'input[type=\"submit\"]', '[role=\"button\"]'];\n this.lastMousePosition = null;\n this.mouseListener = null;\n this.clickListeners = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Track mouse position globally with timestamp\n this.mouseListener = (e) => {\n const mouseEvent = e;\n this.lastMousePosition = {\n x: mouseEvent.clientX,\n y: mouseEvent.clientY,\n timestamp: Date.now(),\n };\n };\n document.addEventListener('mousemove', this.mouseListener, { passive: true });\n // Find all matching elements and attach listeners\n this.attachClickListeners();\n }\n /**\n * Add a new target selector at runtime\n */\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n // Attach listeners if already active\n if (this.isActive) {\n this.attachClickListenersForSelector(selector);\n }\n }\n }\n attachClickListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachClickListenersForSelector(selector);\n });\n }\n attachClickListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.clickListeners.has(element))\n return; // Already attached\n const listener = (e) => {\n var _a, _b;\n const clickEvent = e;\n const now = Date.now();\n const rect = element.getBoundingClientRect();\n // Check if element is in viewport\n const inViewport = (rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth);\n // Calculate mouse-click position delta\n // Bots using element.click() have click event coordinates different from mouse position\n let mouseClickDelta = 0;\n let timeSinceMouseMove = -1;\n if (this.lastMousePosition) {\n const dx = clickEvent.clientX - this.lastMousePosition.x;\n const dy = clickEvent.clientY - this.lastMousePosition.y;\n mouseClickDelta = Math.sqrt(dx * dx + dy * dy);\n timeSinceMouseMove = now - this.lastMousePosition.timestamp;\n }\n // Analyze click position\n let position;\n if (!this.lastMousePosition) {\n position = 'no-mouse-data'; // Bot - no mouse movement\n }\n else {\n const mx = this.lastMousePosition.x;\n const my = this.lastMousePosition.y;\n // Check if mouse was over element\n const overElement = (mx >= rect.left &&\n mx <= rect.right &&\n my >= rect.top &&\n my <= rect.bottom);\n if (!overElement) {\n position = 'outside'; // Bot - mouse not over target\n }\n else {\n // Check if dead center (suspicious)\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const distanceFromCenter = Math.sqrt((mx - centerX) ** 2 + (my - centerY) ** 2);\n // Dead center = within 2px of center\n if (distanceFromCenter < 2) {\n position = 'dead-center'; // Suspicious - too perfect\n }\n else {\n position = 'over-element'; // Human - somewhere on the button\n }\n }\n }\n this.events.push({\n clickX: clickEvent.clientX,\n clickY: clickEvent.clientY,\n mouseX: (_a = this.lastMousePosition) === null || _a === void 0 ? void 0 : _a.x,\n mouseY: (_b = this.lastMousePosition) === null || _b === void 0 ? void 0 : _b.y,\n rect,\n inViewport,\n position,\n timestamp: now,\n mouseClickDelta,\n timeSinceMouseMove,\n isTrusted: clickEvent.isTrusted,\n });\n // Notify detector - clicks are high-value events\n this.notifyEvent(1.0);\n };\n element.addEventListener('click', listener);\n this.clickListeners.set(element, listener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n // Remove mouse listener\n if (this.mouseListener) {\n document.removeEventListener('mousemove', this.mouseListener);\n this.mouseListener = null;\n }\n // Remove all click listeners\n this.clickListeners.forEach((listener, element) => {\n element.removeEventListener('click', listener);\n });\n this.clickListeners.clear();\n }\n reset() {\n this.events = [];\n this.lastMousePosition = null;\n }\n score() {\n const eventCount = this.events.length;\n if (eventCount === 0)\n return undefined;\n // Pre-compute counts in a single pass\n let positionScore = 0;\n let clicksWithDelta = 0;\n let mismatchCount = 0;\n let clicksWithTiming = 0;\n let suspiciousTimingCount = 0;\n let untrustedCount = 0;\n for (const click of this.events) {\n // Position scoring\n switch (click.position) {\n case 'no-mouse-data':\n positionScore += 0.0;\n break;\n case 'outside':\n positionScore += 0.0;\n break;\n case 'dead-center':\n positionScore += 0.5;\n break;\n case 'over-element':\n positionScore += 1.0;\n break;\n }\n // Delta scoring\n if (click.mouseClickDelta >= 0) {\n clicksWithDelta++;\n if (click.mouseClickDelta > 5)\n mismatchCount++;\n }\n // Timing scoring\n if (click.timeSinceMouseMove >= 0) {\n clicksWithTiming++;\n if (click.timeSinceMouseMove < 10 || click.timeSinceMouseMove > 2000) {\n suspiciousTimingCount++;\n }\n }\n // Trusted scoring\n if (!click.isTrusted)\n untrustedCount++;\n }\n let score = 0;\n let factors = 0;\n // 1. Position-based scoring\n score += positionScore / eventCount;\n factors++;\n // 2. Mouse-click delta scoring\n if (clicksWithDelta >= 2) {\n const mismatchRatio = mismatchCount / clicksWithDelta;\n let deltaScore;\n if (mismatchRatio >= 0.8)\n deltaScore = 0.1;\n else if (mismatchRatio >= 0.5)\n deltaScore = 0.3;\n else if (mismatchRatio >= 0.3)\n deltaScore = 0.5;\n else if (mismatchRatio > 0)\n deltaScore = 0.7;\n else\n deltaScore = 1.0;\n score += deltaScore;\n factors++;\n }\n // 3. Mouse-to-click timing\n if (clicksWithTiming >= 2) {\n const suspiciousRatio = suspiciousTimingCount / clicksWithTiming;\n let timingScore;\n if (suspiciousRatio >= 0.8)\n timingScore = 0.2;\n else if (suspiciousRatio >= 0.5)\n timingScore = 0.4;\n else if (suspiciousRatio >= 0.3)\n timingScore = 0.6;\n else if (suspiciousRatio > 0)\n timingScore = 0.8;\n else\n timingScore = 1.0;\n score += timingScore;\n factors++;\n }\n // 4. Trusted event scoring\n if (eventCount >= 2) {\n const untrustedRatio = untrustedCount / eventCount;\n let trustedScore;\n if (untrustedRatio >= 0.5)\n trustedScore = 0.1;\n else if (untrustedRatio > 0)\n trustedScore = 0.3;\n else\n trustedScore = 1.0;\n score += trustedScore;\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n positions: {\n noMouseData: this.events.filter(e => e.position === 'no-mouse-data').length,\n outside: this.events.filter(e => e.position === 'outside').length,\n deadCenter: this.events.filter(e => e.position === 'dead-center').length,\n overElement: this.events.filter(e => e.position === 'over-element').length,\n },\n inViewport: this.events.filter(e => e.inViewport).length,\n trackedElements: this.clickListeners.size,\n mouseClickDeltas: this.events.map(e => e.mouseClickDelta),\n timeSinceMouseMoves: this.events.map(e => e.timeSinceMouseMove),\n untrustedClicks: this.events.filter(e => !e.isTrusted).length,\n };\n }\n}\n", "/**\n * Tap Behavior Detection Strategy (Mobile)\n * Monitors touch interactions on specific elements\n * Analyzes tap duration, precision, movement, and timing patterns\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { analyzeIntervals, scoreCoefficientOfVariation, gaussian } from '../math-utils.js';\nexport class TapStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'tap';\n this.defaultWeight = 0.35;\n this.events = [];\n this.targetSelectors = ['button', 'a', 'input[type=\"submit\"]', '[role=\"button\"]'];\n this.touchStartListeners = new Map();\n this.touchEndListeners = new Map();\n this.activeTouches = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n this.attachTouchListeners();\n }\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n if (this.isActive) {\n this.attachTouchListenersForSelector(selector);\n }\n }\n }\n attachTouchListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachTouchListenersForSelector(selector);\n });\n }\n attachTouchListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.touchStartListeners.has(element))\n return;\n const startListener = (e) => {\n const touchEvent = e;\n // Only track first touch (ignore multi-touch)\n if (touchEvent.touches.length !== 1)\n return;\n const touch = touchEvent.touches[0];\n this.activeTouches.set(touch.identifier, {\n x: touch.clientX,\n y: touch.clientY,\n timestamp: Date.now(),\n element,\n });\n };\n const endListener = (e) => {\n const touchEvent = e;\n if (touchEvent.changedTouches.length !== 1)\n return;\n const touch = touchEvent.changedTouches[0];\n const startData = this.activeTouches.get(touch.identifier);\n if (!startData || startData.element !== element)\n return;\n const now = Date.now();\n const duration = now - startData.timestamp;\n const dx = touch.clientX - startData.x;\n const dy = touch.clientY - startData.y;\n const movement = Math.sqrt(dx * dx + dy * dy);\n const rect = element.getBoundingClientRect();\n const inViewport = (rect.top >= 0 &&\n rect.left >= 0 &&\n rect.bottom <= window.innerHeight &&\n rect.right <= window.innerWidth);\n // Analyze tap position\n const tx = touch.clientX;\n const ty = touch.clientY;\n const overElement = (tx >= rect.left &&\n tx <= rect.right &&\n ty >= rect.top &&\n ty <= rect.bottom);\n let position;\n if (!overElement) {\n position = 'outside';\n }\n else {\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n const distanceFromCenter = Math.sqrt((tx - centerX) ** 2 + (ty - centerY) ** 2);\n // Dead center = within 2px\n position = distanceFromCenter < 2 ? 'dead-center' : 'over-element';\n }\n this.events.push({\n x: tx,\n y: ty,\n rect,\n inViewport,\n position,\n duration,\n movement,\n timestamp: now,\n });\n // Notify detector - taps are high-value events\n this.notifyEvent(1.0);\n this.activeTouches.delete(touch.identifier);\n };\n element.addEventListener('touchstart', startListener, { passive: true });\n element.addEventListener('touchend', endListener, { passive: true });\n this.touchStartListeners.set(element, startListener);\n this.touchEndListeners.set(element, endListener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n this.touchStartListeners.forEach((listener, element) => {\n element.removeEventListener('touchstart', listener);\n });\n this.touchStartListeners.clear();\n this.touchEndListeners.forEach((listener, element) => {\n element.removeEventListener('touchend', listener);\n });\n this.touchEndListeners.clear();\n this.activeTouches.clear();\n }\n reset() {\n this.events = [];\n this.activeTouches.clear();\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. Position accuracy\n let positionScore = 0;\n for (const tap of this.events) {\n switch (tap.position) {\n case 'outside':\n positionScore += 0.0; // Bot\n break;\n case 'dead-center':\n positionScore += 0.5; // Suspicious\n break;\n case 'over-element':\n positionScore += 1.0; // Human\n break;\n }\n }\n score += positionScore / this.events.length;\n factors++;\n // 2. Tap duration variation - Humans have natural variation (50-150ms typical)\n const durations = this.events.map(e => e.duration);\n if (durations.length >= 2) {\n const durationAnalysis = analyzeIntervals(durations);\n if (durationAnalysis) {\n const { statistics, allIdentical } = durationAnalysis;\n // All identical = bot\n if (allIdentical) {\n return 0.05;\n }\n // Human tap durations have moderate CV (~0.3-0.5)\n score += scoreCoefficientOfVariation(statistics.cv);\n factors++;\n // Ideal duration: 70-120ms\n score += gaussian(statistics.mean, 95, 40);\n factors++;\n }\n }\n // 3. Tap movement - Real fingers move slightly (1-5px), bots are often 0px\n const movements = this.events.map(e => e.movement);\n if (movements.length > 0) {\n const avgMovement = movements.reduce((a, b) => a + b, 0) / movements.length;\n // Some movement is natural (1-5px), too much is a swipe, zero is suspicious\n score += gaussian(avgMovement, 2, 3);\n factors++;\n }\n // 4. Tap interval timing - Time between taps should vary naturally\n if (this.events.length >= 3) {\n const intervals = [];\n for (let i = 1; i < this.events.length; i++) {\n intervals.push(this.events[i].timestamp - this.events[i - 1].timestamp);\n }\n const intervalAnalysis = analyzeIntervals(intervals);\n if (intervalAnalysis && !intervalAnalysis.allIdentical) {\n score += scoreCoefficientOfVariation(intervalAnalysis.statistics.cv);\n factors++;\n }\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n positions: {\n outside: this.events.filter(e => e.position === 'outside').length,\n deadCenter: this.events.filter(e => e.position === 'dead-center').length,\n overElement: this.events.filter(e => e.position === 'over-element').length,\n },\n durations: this.events.map(e => e.duration),\n movements: this.events.map(e => e.movement),\n inViewport: this.events.filter(e => e.inViewport).length,\n trackedElements: this.touchStartListeners.size,\n };\n }\n}\n", "/**\n * Keyboard Timing Detection Strategy\n * Monitors typing in specific input fields\n * Analyzes keydown/keyup timing and micro-variations\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { analyzeIntervals, scoreCoefficientOfVariation } from '../math-utils.js';\nexport class KeyboardStrategy extends BaseStrategy {\n constructor(options) {\n super();\n this.name = 'keyboard';\n this.defaultWeight = 0.10;\n this.events = [];\n this.targetSelectors = ['input[type=\"text\"]', 'input[type=\"email\"]', 'textarea'];\n this.focusedElement = null;\n this.focusedElementSelector = '';\n this.lastEventTimestamp = 0;\n this.sessionPauseThreshold = 1000;\n this.downListener = null;\n this.upListener = null;\n this.focusListeners = new Map();\n this.blurListeners = new Map();\n this.isActive = false;\n if (options === null || options === void 0 ? void 0 : options.targetSelectors) {\n this.targetSelectors = options.targetSelectors;\n }\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Attach focus/blur listeners to all matching elements\n this.attachFocusListeners();\n // Key event listeners (only track when an input is focused)\n this.downListener = (e) => {\n if (!this.focusedElement)\n return; // No input focused\n const now = Date.now();\n const keyEvent = e;\n // Clear events if pause > 1s (new typing session)\n if (this.lastEventTimestamp > 0 && now - this.lastEventTimestamp > this.sessionPauseThreshold) {\n this.events = [];\n }\n this.events.push({\n key: keyEvent.key,\n type: 'down',\n timestamp: now,\n targetElement: this.focusedElementSelector,\n });\n // Notify detector - keystrokes are valuable events\n this.notifyEvent(0.8);\n this.lastEventTimestamp = now;\n };\n this.upListener = (e) => {\n if (!this.focusedElement)\n return; // No input focused\n const now = Date.now();\n const keyEvent = e;\n // Clear events if pause > 1s (new typing session)\n if (this.lastEventTimestamp > 0 && now - this.lastEventTimestamp > this.sessionPauseThreshold) {\n this.events = [];\n }\n this.events.push({\n key: keyEvent.key,\n type: 'up',\n timestamp: now,\n targetElement: this.focusedElementSelector,\n });\n this.lastEventTimestamp = now;\n };\n document.addEventListener('keydown', this.downListener);\n document.addEventListener('keyup', this.upListener);\n }\n /**\n * Add a new target selector at runtime\n */\n addTarget(selector) {\n if (!this.targetSelectors.includes(selector)) {\n this.targetSelectors.push(selector);\n if (this.isActive) {\n this.attachFocusListenersForSelector(selector);\n }\n }\n }\n attachFocusListeners() {\n this.targetSelectors.forEach(selector => {\n this.attachFocusListenersForSelector(selector);\n });\n }\n attachFocusListenersForSelector(selector) {\n const elements = document.querySelectorAll(selector);\n elements.forEach(element => {\n if (this.focusListeners.has(element))\n return; // Already attached\n const focusListener = () => {\n this.focusedElement = element;\n this.focusedElementSelector = selector;\n };\n const blurListener = () => {\n this.focusedElement = null;\n this.focusedElementSelector = '';\n };\n element.addEventListener('focus', focusListener);\n element.addEventListener('blur', blurListener);\n this.focusListeners.set(element, focusListener);\n this.blurListeners.set(element, blurListener);\n });\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.downListener) {\n document.removeEventListener('keydown', this.downListener);\n this.downListener = null;\n }\n if (this.upListener) {\n document.removeEventListener('keyup', this.upListener);\n this.upListener = null;\n }\n // Remove focus/blur listeners\n this.focusListeners.forEach((listener, element) => {\n element.removeEventListener('focus', listener);\n });\n this.focusListeners.clear();\n this.blurListeners.forEach((listener, element) => {\n element.removeEventListener('blur', listener);\n });\n this.blurListeners.clear();\n this.focusedElement = null;\n }\n reset() {\n this.events = [];\n this.focusedElement = null;\n this.focusedElementSelector = '';\n this.lastEventTimestamp = 0;\n }\n score() {\n if (this.events.length < 6)\n return undefined; // Need at least 3 key pairs\n const downEvents = this.events.filter(e => e.type === 'down');\n if (downEvents.length < 3)\n return undefined;\n let score = 0;\n let factors = 0;\n // 1. Analyze keystroke intervals (time between keydown events)\n const keystrokeIntervals = [];\n for (let i = 1; i < downEvents.length; i++) {\n keystrokeIntervals.push(downEvents[i].timestamp - downEvents[i - 1].timestamp);\n }\n const keystrokeAnalysis = analyzeIntervals(keystrokeIntervals);\n if (keystrokeAnalysis) {\n const { statistics, allIdentical } = keystrokeAnalysis;\n // Keyboard-specific heuristics for keystroke timing\n if (allIdentical) {\n return 0.1; // All identical - bot!\n }\n const keystrokeScore = scoreCoefficientOfVariation(statistics.cv);\n score += keystrokeScore;\n factors++;\n // Early return if bot detected\n if (keystrokeScore <= 0.1)\n return keystrokeScore;\n }\n // 2. Analyze press durations (keydown-to-keyup duration)\n const pressDurations = [];\n for (let i = 0; i < this.events.length - 1; i++) {\n if (this.events[i].type === 'down' && this.events[i + 1].type === 'up' &&\n this.events[i].key === this.events[i + 1].key) {\n pressDurations.push(this.events[i + 1].timestamp - this.events[i].timestamp);\n }\n }\n const pressDurationAnalysis = analyzeIntervals(pressDurations);\n if (pressDurationAnalysis) {\n const { statistics, allIdentical } = pressDurationAnalysis;\n // Keyboard-specific heuristics for press duration\n if (allIdentical) {\n return 0.1; // All identical - bot!\n }\n // Check for suspiciously fast key releases (bots often have <5ms press duration)\n if (statistics.mean < 5) {\n score += 0.1; // Too fast = bot (instant release)\n factors++;\n }\n else {\n const pressDurationScore = scoreCoefficientOfVariation(statistics.cv);\n score += pressDurationScore;\n factors++;\n // Early return if bot detected\n if (pressDurationScore <= 0.1)\n return pressDurationScore;\n }\n }\n // 3. Bonus for backspace usage (human error correction)\n const backspaceCount = this.events.filter(e => e.key === 'Backspace').length;\n if (backspaceCount > 0) {\n // Natural human behavior - making corrections\n const backspaceRatio = backspaceCount / downEvents.length;\n if (backspaceRatio > 0.05 && backspaceRatio < 0.3) {\n score += 1.0; // Reasonable error correction\n factors++;\n }\n else if (backspaceRatio > 0) {\n score += 0.8; // Some backspaces\n factors++;\n }\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n // Calculate press durations for visualization\n const pressDurations = [];\n for (let i = 0; i < this.events.length - 1; i++) {\n if (this.events[i].type === 'down' && this.events[i + 1].type === 'up' &&\n this.events[i].key === this.events[i + 1].key) {\n pressDurations.push(this.events[i + 1].timestamp - this.events[i].timestamp);\n }\n }\n return {\n eventCount: this.events.length,\n downEvents: this.events.filter(e => e.type === 'down').length,\n upEvents: this.events.filter(e => e.type === 'up').length,\n backspaceCount: this.events.filter(e => e.key === 'Backspace').length,\n pressDurations, // For graphing\n focusedElement: this.focusedElementSelector,\n trackedElements: this.focusListeners.size,\n };\n }\n}\n", "/**\n * Environment Fingerprinting Strategy\n * Captures browser environment on initialization and tick updates\n * Includes critical automation/bot detection signals\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { inverseSigmoid, gaussian } from '../math-utils.js';\n/**\n * Automation framework globals that indicate bot activity\n * These are injected by various testing/automation frameworks\n */\nconst AUTOMATION_GLOBALS = [\n '__nightmare',\n '_phantom',\n 'callPhantom',\n '__selenium_evaluate',\n '__webdriver_evaluate',\n '__driver_evaluate',\n '__webdriver_script_function',\n '__lastWatirAlert',\n '__lastWatirConfirm',\n '__lastWatirPrompt',\n '_Selenium_IDE_Recorder',\n 'domAutomation',\n 'domAutomationController',\n 'webdriver',\n '_webdriver_script_fn',\n '__webdriver_script_func',\n '__fxdriver_evaluate',\n '__fxdriver_unwrapped',\n '__selenium_unwrapped',\n];\nexport class EnvironmentStrategy extends BaseStrategy {\n constructor() {\n super(...arguments);\n this.name = 'environment';\n this.defaultWeight = 0.08;\n this.data = null;\n }\n start() {\n this.captureEnvironment();\n }\n stop() {\n // Environment data persists\n }\n reset() {\n this.data = null;\n }\n onTick(_timestamp) {\n // Re-capture environment periodically to detect changes\n this.captureEnvironment();\n }\n score() {\n if (!this.data)\n return undefined;\n const env = this.data;\n const auto = env.automation;\n // ============================================\n // IMMEDIATE DISQUALIFICATION - HIGH CONFIDENCE BOT SIGNALS\n // ============================================\n // P0: navigator.webdriver === true (HIGHEST PRIORITY)\n // This is the most reliable automation indicator\n if (auto.isWebdriver) {\n return 0.05;\n }\n // P0: Automation framework globals detected\n if (auto.hasAutomationGlobals) {\n return 0.1;\n }\n // P0: CDP injection detected (Chrome DevTools Protocol)\n if (auto.hasCDPInjection) {\n return 0.1;\n }\n // P2: Headless browser detection\n // Multiple headless indicators = very likely bot\n const headlessIndicatorCount = [\n auto.hasHeadlessUA,\n auto.hasChromelessRuntime,\n auto.hasSoftwareRenderer,\n ].filter(Boolean).length;\n if (headlessIndicatorCount >= 2) {\n return 0.15;\n }\n // Single strong headless indicator\n if (auto.hasHeadlessUA) {\n return 0.2;\n }\n // ============================================\n // WEIGHTED SCORING FOR OTHER SIGNALS\n // ============================================\n let score = 0;\n let factors = 0;\n // Suspicious indicators\n score += env.suspiciousDimensions ? 0.1 : 1.0;\n score += env.suspiciousRatio ? 0.2 : 1.0;\n score += env.featureInconsistency ? 0.3 : 1.0;\n factors += 3;\n // Browser features\n const featureCount = [\n env.hasWebGL,\n env.hasLocalStorage,\n env.hasSessionStorage,\n env.hasIndexedDB,\n ].filter(Boolean).length;\n score += featureCount / 4;\n factors++;\n // Plugins (only suspicious on desktop)\n if (!env.isMobile) {\n score += inverseSigmoid(env.plugins, -2, -0.5);\n score += (env.plugins > 0 ? 1.0 : 0.1);\n factors += 2;\n // No plugins on desktop Chrome = suspicious (but not conclusive)\n if (auto.hasNoPlugins && env.vendor.includes('Google')) {\n score += 0.3;\n factors++;\n }\n }\n // Chromeless runtime (window.chrome but no chrome.runtime)\n if (auto.hasChromelessRuntime) {\n score += 0.3;\n factors++;\n }\n // Software renderer (SwiftShader)\n if (auto.hasSoftwareRenderer) {\n score += 0.4;\n factors++;\n }\n // Device\n score += gaussian(env.devicePixelRatio, 2, 1.5);\n score += (env.colorDepth === 24 || env.colorDepth === 32) ? 1.0 : 0.4;\n factors += 2;\n return factors > 0 ? score / factors : undefined;\n }\n isMobileDevice() {\n // Multiple checks for mobile detection\n const hasTouchScreen = navigator.maxTouchPoints > 0 || 'ontouchstart' in window;\n const mobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n const smallScreen = window.innerWidth < 768 && window.innerHeight < 1024;\n return (hasTouchScreen && smallScreen) || mobileUA;\n }\n /**\n * Detect automation indicators\n */\n detectAutomation() {\n const isMobile = this.isMobileDevice();\n // 1. navigator.webdriver - HIGHEST PRIORITY\n const isWebdriver = navigator.webdriver === true;\n // 2. Headless UA detection\n const ua = navigator.userAgent;\n const hasHeadlessUA = /HeadlessChrome|Headless/i.test(ua);\n // 3. Chrome without runtime (headless Chrome indicator)\n const win = window;\n const hasChromelessRuntime = !!(win.chrome &&\n typeof win.chrome === 'object' &&\n !win.chrome.runtime);\n // 4. Automation framework globals\n const detectedGlobals = [];\n for (const global of AUTOMATION_GLOBALS) {\n if (global in win) {\n detectedGlobals.push(global);\n }\n }\n const hasAutomationGlobals = detectedGlobals.length > 0;\n // 5. CDP (Chrome DevTools Protocol) injection detection\n // CDP injects properties matching pattern: cdc_ or __cdc_\n const detectedCDPKeys = [];\n try {\n for (const key of Object.keys(win)) {\n if (/^cdc_|^__cdc_/.test(key)) {\n detectedCDPKeys.push(key);\n }\n }\n }\n catch (_a) {\n // Some environments throw on Object.keys(window)\n }\n const hasCDPInjection = detectedCDPKeys.length > 0;\n // 6. No plugins on desktop (suspicious)\n const hasNoPlugins = !isMobile && navigator.plugins.length === 0;\n // 7. Software renderer detection (SwiftShader, ANGLE without GPU)\n let hasSoftwareRenderer = false;\n try {\n const canvas = document.createElement('canvas');\n const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n if (gl) {\n const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n if (debugInfo) {\n const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);\n // SwiftShader = headless Chrome software renderer\n // ANGLE without real GPU = suspicious\n hasSoftwareRenderer = /SwiftShader|Software|LLVMpipe/i.test(renderer);\n // Store for debugging\n this._webglRenderer = renderer;\n }\n }\n }\n catch (_b) {\n // WebGL not available\n }\n return {\n isWebdriver,\n hasHeadlessUA,\n hasChromelessRuntime,\n hasSoftwareRenderer,\n hasNoPlugins,\n hasAutomationGlobals,\n detectedGlobals,\n hasCDPInjection,\n detectedCDPKeys,\n };\n }\n captureEnvironment() {\n try {\n // WebGL detection\n let hasWebGL = false;\n let webglRenderer;\n try {\n const canvas = document.createElement('canvas');\n const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');\n hasWebGL = !!gl;\n if (gl) {\n const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');\n if (debugInfo) {\n webglRenderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);\n }\n }\n }\n catch (e) {\n hasWebGL = false;\n }\n // WebRTC detection\n const hasWebRTC = !!(window.RTCPeerConnection ||\n window.mozRTCPeerConnection ||\n window.webkitRTCPeerConnection);\n // Mobile detection\n const isMobile = this.isMobileDevice();\n const windowWidth = window.innerWidth;\n const windowHeight = window.innerHeight;\n const screenWidth = window.screen.width;\n const screenHeight = window.screen.height;\n // Suspicious dimensions\n const suspiciousDimensions = (windowWidth === 800 && windowHeight === 600) ||\n (windowWidth === 1024 && windowHeight === 768) ||\n (windowWidth === 1280 && windowHeight === 720) ||\n (screenWidth === 800 && screenHeight === 600);\n // Suspicious ratio\n const windowScreenRatio = (windowWidth * windowHeight) / (screenWidth * screenHeight);\n const suspiciousRatio = windowScreenRatio === 1.0 ||\n windowScreenRatio < 0.1 ||\n windowScreenRatio > 1.0;\n // Feature inconsistency\n const hasStorage = typeof localStorage !== 'undefined' && typeof sessionStorage !== 'undefined';\n const featureInconsistency = (navigator.plugins.length === 0 && navigator.mimeTypes.length === 0) ||\n !hasWebGL ||\n !hasStorage;\n // Detect automation indicators\n const automation = this.detectAutomation();\n this.data = {\n screenWidth,\n screenHeight,\n windowWidth,\n windowHeight,\n devicePixelRatio: window.devicePixelRatio,\n colorDepth: window.screen.colorDepth,\n userAgent: navigator.userAgent,\n platform: navigator.platform,\n language: navigator.language,\n languages: navigator.languages ? Array.from(navigator.languages) : [navigator.language],\n hardwareConcurrency: navigator.hardwareConcurrency,\n maxTouchPoints: navigator.maxTouchPoints || 0,\n vendor: navigator.vendor,\n hasWebGL,\n hasWebRTC,\n hasLocalStorage: typeof localStorage !== 'undefined',\n hasSessionStorage: typeof sessionStorage !== 'undefined',\n hasIndexedDB: 'indexedDB' in window,\n plugins: navigator.plugins.length,\n mimeTypes: navigator.mimeTypes.length,\n suspiciousRatio,\n suspiciousDimensions,\n featureInconsistency,\n isMobile,\n timestamp: Date.now(),\n automation,\n webglRenderer,\n };\n }\n catch (_a) {\n // Silent fail - environment capture is best effort\n }\n }\n getDebugInfo() {\n return this.data;\n }\n /**\n * Check if current device is mobile\n * Returns true if mobile, false otherwise\n * Returns null if environment hasn't been captured yet\n */\n isMobile() {\n var _a, _b;\n return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.isMobile) !== null && _b !== void 0 ? _b : null;\n }\n /**\n * Get automation detection results\n * Returns null if environment hasn't been captured yet\n */\n getAutomationIndicators() {\n var _a, _b;\n return (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.automation) !== null && _b !== void 0 ? _b : null;\n }\n /**\n * Quick check if any strong automation indicator is present\n * Returns true if likely a bot, false if likely human, null if not checked yet\n */\n isLikelyBot() {\n if (!this.data)\n return null;\n const auto = this.data.automation;\n return (auto.isWebdriver ||\n auto.hasAutomationGlobals ||\n auto.hasCDPInjection ||\n auto.hasHeadlessUA);\n }\n}\n", "/**\n * Resize Behavior Detection Strategy\n */\nimport { BaseStrategy } from '../strategy.js';\nimport { inverseSigmoid, sigmoid } from '../math-utils.js';\nexport class ResizeStrategy extends BaseStrategy {\n constructor() {\n super(...arguments);\n this.name = 'resize';\n this.defaultWeight = 0.02;\n this.events = [];\n this.listener = null;\n this.isActive = false;\n this.lastMousePosition = null;\n this.mouseListener = null;\n }\n start() {\n if (this.isActive)\n return;\n this.isActive = true;\n // Track mouse for resize detection\n this.mouseListener = (e) => {\n const mouseEvent = e;\n this.lastMousePosition = {\n x: mouseEvent.clientX,\n y: mouseEvent.clientY,\n };\n };\n document.addEventListener('mousemove', this.mouseListener, { passive: true });\n // Track resizes\n this.listener = () => {\n var _a, _b;\n const mouseX = (_a = this.lastMousePosition) === null || _a === void 0 ? void 0 : _a.x;\n const mouseY = (_b = this.lastMousePosition) === null || _b === void 0 ? void 0 : _b.y;\n let mouseNearEdge = false;\n if (mouseX !== undefined && mouseY !== undefined) {\n const edgeThreshold = 50;\n mouseNearEdge = (mouseX < edgeThreshold ||\n mouseX > window.innerWidth - edgeThreshold ||\n mouseY < edgeThreshold ||\n mouseY > window.innerHeight - edgeThreshold);\n }\n this.events.push({\n width: window.innerWidth,\n height: window.innerHeight,\n mouseX,\n mouseY,\n mouseNearEdge,\n timestamp: Date.now(),\n });\n };\n window.addEventListener('resize', this.listener);\n }\n stop() {\n if (!this.isActive)\n return;\n this.isActive = false;\n if (this.listener) {\n window.removeEventListener('resize', this.listener);\n this.listener = null;\n }\n if (this.mouseListener) {\n document.removeEventListener('mousemove', this.mouseListener);\n this.mouseListener = null;\n }\n }\n reset() {\n this.events = [];\n }\n score() {\n if (this.events.length === 0)\n return undefined;\n let score = 0;\n let factors = 0;\n // Frequency\n score += inverseSigmoid(this.events.length, 5, 0.5);\n factors++;\n // Mouse near edge\n const withMouse = this.events.filter(e => e.mouseX !== undefined);\n if (withMouse.length > 0) {\n const nearEdge = withMouse.filter(e => e.mouseNearEdge).length;\n score += sigmoid(nearEdge / withMouse.length, 0.5, 8);\n factors++;\n }\n return factors > 0 ? score / factors : undefined;\n }\n getDebugInfo() {\n return {\n eventCount: this.events.length,\n withMouseData: this.events.filter(e => e.mouseX !== undefined).length,\n };\n }\n}\n", "/**\n * Browser Build - Auto-initializing standalone bundle for CDN usage\n *\n * Usage:\n * <script src=\"https://cdn.../behavior-detector.js\"></script>\n * <script>\n * window.bdSettings = {\n * strategies: {\n * mouse: { weight: 0.3 },\n * scroll: { weight: 0.15 },\n * click: { weight: 0.3 },\n * keyboard: { weight: 0.1 },\n * environment: { weight: 0.08 },\n * resize: { weight: 0.02 }\n * },\n * autoStart: true,\n * checkMs: 2000,\n * pauseOnHidden: true, // Auto-pause when tab hidden (default: true)\n * onScore: (result) => {\n * console.log('Human likelihood:', result.score);\n * if (result.score < 0.3) {\n * // Likely bot\n * }\n * },\n * ifBot: (result) => {\n * // Called when score < threshold\n * console.warn('Bot detected:', result);\n * },\n * botThreshold: 0.3\n * }\n * </script>\n */\nimport { BehaviorDetector } from './behavior-detector.js';\nimport { MouseStrategy, ScrollStrategy, ClickStrategy, TapStrategy, KeyboardStrategy, EnvironmentStrategy, ResizeStrategy, } from './strategies/index.js';\n/**\n * Detect if the current device is mobile\n */\nfunction isMobileDevice() {\n const hasTouchScreen = navigator.maxTouchPoints > 0 || 'ontouchstart' in window;\n const mobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\n const smallScreen = window.innerWidth < 768 && window.innerHeight < 1024;\n return (hasTouchScreen && smallScreen) || mobileUA;\n}\nclass BehaviorDetectionAPI {\n constructor() {\n this.detector = null;\n this.checkInterval = null;\n this.settings = null;\n }\n /**\n * Initialize the detector with settings\n */\n init(settings) {\n var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;\n if (this.detector) {\n this.stop();\n }\n this.settings = settings;\n this.detector = new BehaviorDetector({\n pauseOnHidden: settings.pauseOnHidden !== undefined ? settings.pauseOnHidden : true\n });\n // Detect if mobile to adjust strategy selection and weights\n const isMobile = isMobileDevice();\n const strategies = settings.strategies || {};\n // Mobile-adjusted default weights\n const defaultWeights = isMobile ? {\n mouse: 0, // Disabled on mobile\n scroll: 0.35, // Increased (more reliable on mobile)\n click: 0, // Disabled on mobile (use tap instead)\n tap: 0.35, // Mobile tap detection\n keyboard: 0.15,\n environment: 0.10,\n resize: 0.05, // Orientation changes\n } : {\n mouse: 0.30,\n scroll: 0.15,\n click: 0.30,\n tap: 0, // Disabled on desktop\n keyboard: 0.10,\n environment: 0.08,\n resize: 0.02,\n };\n // Mouse - Desktop only\n if (!isMobile && ((_a = strategies.mouse) === null || _a === void 0 ? void 0 : _a.enabled) !== false) {\n const strategy = new MouseStrategy();\n const weight = (_c = (_b = strategies.mouse) === null || _b === void 0 ? void 0 : _b.weight) !== null && _c !== void 0 ? _c : defaultWeights.mouse;\n this.detector.addStrategy(strategy, weight);\n }\n // Scroll - Universal\n if (((_d = strategies.scroll) === null || _d === void 0 ? void 0 : _d.enabled) !== false) {\n const strategy = new ScrollStrategy();\n const weight = (_f = (_e = strategies.scroll) === null || _e === void 0 ? void 0 : _e.weight) !== null && _f !== void 0 ? _f : defaultWeights.scroll;\n this.detector.addStrategy(strategy, weight);\n }\n // Click - Desktop only\n if (!isMobile && ((_g = strategies.click) === null || _g === void 0 ? void 0 : _g.enabled) !== false) {\n const strategy = new ClickStrategy();\n const weight = (_j = (_h = strategies.click) === null || _h === void 0 ? void 0 : _h.weight) !== null && _j !== void 0 ? _j : defaultWeights.click;\n this.detector.addStrategy(strategy, weight);\n }\n // Tap - Mobile only\n if (isMobile && ((_k = strategies.tap) === null || _k === void 0 ? void 0 : _k.enabled) !== false) {\n const strategy = new TapStrategy();\n const weight = (_m = (_l = strategies.tap) === null || _l === void 0 ? void 0 : _l.weight) !== null && _m !== void 0 ? _m : defaultWeights.tap;\n this.detector.addStrategy(strategy, weight);\n }\n // Keyboard - Universal\n if (((_o = strategies.keyboard) === null || _o === void 0 ? void 0 : _o.enabled) !== false) {\n const strategy = new KeyboardStrategy();\n const weight = (_q = (_p = strategies.keyboard) === null || _p === void 0 ? void 0 : _p.weight) !== null && _q !== void 0 ? _q : defaultWeights.keyboard;\n this.detector.addStrategy(strategy, weight);\n }\n // Environment - Universal\n if (((_r = strategies.environment) === null || _r === void 0 ? void 0 : _r.enabled) !== false) {\n const strategy = new EnvironmentStrategy();\n const weight = (_t = (_s = strategies.environment) === null || _s === void 0 ? void 0 : _s.weight) !== null && _t !== void 0 ? _t : defaultWeights.environment;\n this.detector.addStrategy(strategy, weight);\n }\n // Resize - Universal\n if (((_u = strategies.resize) === null || _u === void 0 ? void 0 : _u.enabled) !== false) {\n const strategy = new ResizeStrategy();\n const weight = (_w = (_v = strategies.resize) === null || _v === void 0 ? void 0 : _v.weight) !== null && _w !== void 0 ? _w : defaultWeights.resize;\n this.detector.addStrategy(strategy, weight);\n }\n // Start if autoStart is enabled\n if (settings.autoStart !== false) {\n this.start();\n }\n // Set up periodic checking if checkMs is specified\n if (settings.checkMs && settings.checkMs > 0) {\n this.startPeriodicCheck(settings.checkMs);\n }\n // Call onReady callback\n if (settings.onReady) {\n settings.onReady(this);\n }\n }\n /**\n * Start detection\n */\n start() {\n if (!this.detector) {\n return;\n }\n this.detector.start();\n }\n /**\n * Stop detection\n */\n stop() {\n if (this.detector) {\n this.detector.stop();\n }\n if (this.checkInterval !== null) {\n clearInterval(this.checkInterval);\n this.checkInterval = null;\n }\n }\n /**\n * Get current score\n */\n async score() {\n if (!this.detector) {\n return null;\n }\n return this.detector.score({ breakdown: true });\n }\n /**\n * Start periodic checking\n */\n startPeriodicCheck(intervalMs) {\n if (this.checkInterval !== null) {\n clearInterval(this.checkInterval);\n }\n this.checkInterval = window.setInterval(async () => {\n var _a, _b;\n const result = await this.score();\n if (!result || !this.settings)\n return;\n // Call onScore callback\n if (this.settings.onScore) {\n this.settings.onScore(result);\n }\n // Check thresholds\n const botThreshold = (_a = this.settings.botThreshold) !== null && _a !== void 0 ? _a : 0.3;\n const humanThreshold = (_b = this.settings.humanThreshold) !== null && _b !== void 0 ? _b : 0.7;\n if (result.score < botThreshold && this.settings.ifBot) {\n this.settings.ifBot(result);\n }\n else if (result.score >= humanThreshold && this.settings.ifHuman) {\n this.settings.ifHuman(result);\n }\n }, intervalMs);\n }\n /**\n * Get the underlying detector instance for advanced usage\n */\n getDetector() {\n return this.detector;\n }\n}\n// Create global API instance\nconst api = new BehaviorDetectionAPI();\n// Auto-initialize if settings are already present\nif (typeof window !== 'undefined') {\n // Expose API globally\n window.BehaviorDetector = api;\n // Check for settings on load\n const checkAndInit = () => {\n const settings = window.bdSettings;\n if (settings) {\n api.init(settings);\n }\n };\n // Try immediate init\n checkAndInit();\n // Also try after DOM ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', checkAndInit);\n }\n}\n// No exports needed for browser IIFE build - window.BehaviorDetector is sufficient\n"],
5
+ "mappings": "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",
6
+ "names": ["BehaviorDetector", "tickOptions", "strategy", "weight", "config", "event", "strategyWeight", "contribution", "name", "enabled", "_", "options", "breakdown", "result", "_a", "_b", "counts", "debug", "threshold", "now", "factors", "weights", "totalWeight", "weightedSum", "score", "overall", "BaseStrategy", "callback", "weight", "sigmoid", "x", "midpoint", "steepness", "inverseSigmoid", "gaussian", "ideal", "width", "exponent", "calculateStatistics", "values", "mean", "a", "b", "variance", "sum", "v", "stdDev", "cv", "analyzeIntervals", "intervals", "uniqueCount", "i", "allIdentical", "scoreCoefficientOfVariation", "gaussian", "MouseStrategy", "BaseStrategy", "options", "width", "height", "e", "mouseEvent", "now", "currentPos", "dx", "dy", "pixelDistance", "cutoffMicro", "normalizedDistance", "rawAngle", "angleDiff", "cutoff", "x", "y", "distTop", "distBottom", "distLeft", "distRight", "minEdgeDist", "entryEdge", "edgeThreshold", "score", "factors", "distances", "p", "stats", "calculateStatistics", "gaussian", "angles", "angleChanges", "i", "avgChange", "b", "entryScore", "microScore", "suspiciousCount", "centerCount", "cornerCount", "originCount", "entry", "total", "suspiciousRatio", "microCount", "oldestEvent", "durationMs", "microPerSecond", "ScrollStrategy", "BaseStrategy", "options", "_e", "scrollY", "now", "pixelDelta", "deltaTime", "normalizedDistance", "velocity", "cutoff", "score", "factors", "distances", "p", "d", "stats", "calculateStatistics", "gaussian", "velocities", "instantJumps", "jumpRatio", "inverseSigmoid", "ClickStrategy", "BaseStrategy", "options", "e", "mouseEvent", "selector", "element", "listener", "_a", "_b", "clickEvent", "now", "rect", "inViewport", "mouseClickDelta", "timeSinceMouseMove", "dx", "dy", "position", "mx", "my", "centerX", "centerY", "eventCount", "positionScore", "clicksWithDelta", "mismatchCount", "clicksWithTiming", "suspiciousTimingCount", "untrustedCount", "click", "score", "factors", "mismatchRatio", "deltaScore", "suspiciousRatio", "timingScore", "untrustedRatio", "trustedScore", "TapStrategy", "BaseStrategy", "options", "selector", "element", "startListener", "e", "touchEvent", "touch", "endListener", "startData", "now", "duration", "dx", "dy", "movement", "rect", "inViewport", "tx", "ty", "overElement", "position", "centerX", "centerY", "listener", "score", "factors", "positionScore", "tap", "durations", "durationAnalysis", "analyzeIntervals", "statistics", "allIdentical", "scoreCoefficientOfVariation", "gaussian", "movements", "avgMovement", "a", "b", "intervals", "i", "intervalAnalysis", "KeyboardStrategy", "BaseStrategy", "options", "e", "now", "keyEvent", "selector", "element", "focusListener", "blurListener", "listener", "downEvents", "score", "factors", "keystrokeIntervals", "i", "keystrokeAnalysis", "analyzeIntervals", "statistics", "allIdentical", "keystrokeScore", "scoreCoefficientOfVariation", "pressDurations", "pressDurationAnalysis", "pressDurationScore", "backspaceCount", "backspaceRatio", "AUTOMATION_GLOBALS", "EnvironmentStrategy", "BaseStrategy", "_timestamp", "env", "auto", "score", "factors", "featureCount", "inverseSigmoid", "gaussian", "hasTouchScreen", "mobileUA", "smallScreen", "isMobile", "isWebdriver", "ua", "hasHeadlessUA", "win", "hasChromelessRuntime", "detectedGlobals", "global", "hasAutomationGlobals", "detectedCDPKeys", "key", "_a", "hasCDPInjection", "hasNoPlugins", "hasSoftwareRenderer", "canvas", "gl", "debugInfo", "renderer", "_b", "hasWebGL", "webglRenderer", "e", "hasWebRTC", "windowWidth", "windowHeight", "screenWidth", "screenHeight", "suspiciousDimensions", "windowScreenRatio", "suspiciousRatio", "hasStorage", "featureInconsistency", "automation", "ResizeStrategy", "BaseStrategy", "e", "mouseEvent", "_a", "_b", "mouseX", "mouseY", "mouseNearEdge", "score", "factors", "inverseSigmoid", "withMouse", "nearEdge", "sigmoid", "isMobileDevice", "hasTouchScreen", "mobileUA", "smallScreen", "BehaviorDetectionAPI", "settings", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_j", "_k", "_l", "_m", "_o", "_p", "_q", "_r", "_s", "_t", "_u", "_v", "_w", "BehaviorDetector", "isMobile", "strategies", "defaultWeights", "strategy", "MouseStrategy", "weight", "ScrollStrategy", "ClickStrategy", "TapStrategy", "KeyboardStrategy", "EnvironmentStrategy", "ResizeStrategy", "intervalMs", "result", "botThreshold", "humanThreshold", "api", "checkAndInit"]
7
7
  }