@niksbanna/bot-detector 1.0.4 → 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.
package/README.md CHANGED
@@ -266,7 +266,11 @@ npm run dev
266
266
 
267
267
  ## Changelog
268
268
 
269
- ### v1.0.4
269
+ ### v1.1.0
270
+ - **TypeScript support:** Added first-party TypeScript declarations (`dist/types.d.ts`). All public classes, interfaces, and functions are now fully typed — `DetectionResult`, `SignalResult`, `DetectorOptions`, `DetectOptions`, and every built-in signal class.
271
+ - **Fix — `WebDriverSignal` false positive:** The previous check flagged any own property descriptor that had a getter, regardless of what value it returned. This caused false positives in environments where a native or third-party getter returns `false`. The signal now invokes the getter and only triggers when it returns `true`; it still catches stealth-plugin overrides (non-native getters that hide the flag).
272
+
273
+ ### v1.0.5
270
274
  - **Optimization:** Drastically reduced npm package "unpacked size" (from ~1MB down to ~300KB) by disabling source map generation and excluding the raw `src/` directory from the published NPM tarball.
271
275
 
272
276
  ### v1.0.3
@@ -640,15 +640,22 @@ var WebDriverSignal = class extends Signal {
640
640
  }
641
641
  const descriptor = Object.getOwnPropertyDescriptor(navigator, "webdriver");
642
642
  if (descriptor) {
643
- if (descriptor.get || !descriptor.configurable) {
644
- return this.createResult(true, {
645
- webdriver: "modified",
646
- descriptor: {
647
- configurable: descriptor.configurable,
648
- enumerable: descriptor.enumerable,
649
- hasGetter: !!descriptor.get
643
+ if (descriptor.get) {
644
+ try {
645
+ const val = descriptor.get.call(navigator);
646
+ if (val === true) {
647
+ return this.createResult(true, { webdriver: true, source: "own-getter" }, 1);
648
+ }
649
+ if (!descriptor.get.toString().includes("[native code]")) {
650
+ return this.createResult(true, {
651
+ webdriver: "hidden",
652
+ descriptor: { configurable: descriptor.configurable }
653
+ }, 0.8);
650
654
  }
651
- }, 0.8);
655
+ } catch (e) {
656
+ }
657
+ } else if (descriptor.value === true) {
658
+ return this.createResult(true, { webdriver: true, source: "own-property" }, 1);
652
659
  }
653
660
  }
654
661
  try {
@@ -586,15 +586,22 @@ var WebDriverSignal = class extends Signal {
586
586
  }
587
587
  const descriptor = Object.getOwnPropertyDescriptor(navigator, "webdriver");
588
588
  if (descriptor) {
589
- if (descriptor.get || !descriptor.configurable) {
590
- return this.createResult(true, {
591
- webdriver: "modified",
592
- descriptor: {
593
- configurable: descriptor.configurable,
594
- enumerable: descriptor.enumerable,
595
- hasGetter: !!descriptor.get
589
+ if (descriptor.get) {
590
+ try {
591
+ const val = descriptor.get.call(navigator);
592
+ if (val === true) {
593
+ return this.createResult(true, { webdriver: true, source: "own-getter" }, 1);
594
+ }
595
+ if (!descriptor.get.toString().includes("[native code]")) {
596
+ return this.createResult(true, {
597
+ webdriver: "hidden",
598
+ descriptor: { configurable: descriptor.configurable }
599
+ }, 0.8);
596
600
  }
597
- }, 0.8);
601
+ } catch (e) {
602
+ }
603
+ } else if (descriptor.value === true) {
604
+ return this.createResult(true, { webdriver: true, source: "own-property" }, 1);
598
605
  }
599
606
  }
600
607
  try {
@@ -640,15 +640,22 @@ var BotDetectorLib = (() => {
640
640
  }
641
641
  const descriptor = Object.getOwnPropertyDescriptor(navigator, "webdriver");
642
642
  if (descriptor) {
643
- if (descriptor.get || !descriptor.configurable) {
644
- return this.createResult(true, {
645
- webdriver: "modified",
646
- descriptor: {
647
- configurable: descriptor.configurable,
648
- enumerable: descriptor.enumerable,
649
- hasGetter: !!descriptor.get
643
+ if (descriptor.get) {
644
+ try {
645
+ const val = descriptor.get.call(navigator);
646
+ if (val === true) {
647
+ return this.createResult(true, { webdriver: true, source: "own-getter" }, 1);
648
+ }
649
+ if (!descriptor.get.toString().includes("[native code]")) {
650
+ return this.createResult(true, {
651
+ webdriver: "hidden",
652
+ descriptor: { configurable: descriptor.configurable }
653
+ }, 0.8);
650
654
  }
651
- }, 0.8);
655
+ } catch (e) {
656
+ }
657
+ } else if (descriptor.value === true) {
658
+ return this.createResult(true, { webdriver: true, source: "own-property" }, 1);
652
659
  }
653
660
  }
654
661
  try {
@@ -1,3 +1,3 @@
1
- var BotDetectorLib=(()=>{var G=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var at=(f,e,t)=>e in f?G(f,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):f[e]=t;var rt=(f,e)=>{for(var t in e)G(f,t,{get:e[t],enumerable:!0})},ct=(f,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of st(e))!ot.call(f,n)&&n!==t&&G(f,n,{get:()=>e[n],enumerable:!(i=it(e,n))||i.enumerable});return f};var ht=f=>ct(G({},"__esModule",{value:!0}),f);var o=(f,e,t)=>at(f,typeof e!="symbol"?e+"":e,t);var dt={};rt(dt,{AudioContextSignal:()=>P,BotDetector:()=>$,CanvasSignal:()=>L,DOMContentTimingSignal:()=>A,HeadlessSignal:()=>M,InteractionTimingSignal:()=>C,KeyboardPatternSignal:()=>E,MouseMovementSignal:()=>k,NavigatorAnomalySignal:()=>b,PageLoadSignal:()=>H,PermissionsSignal:()=>T,PhantomJSSignal:()=>K,PlaywrightSignal:()=>B,PluginsSignal:()=>R,PuppeteerSignal:()=>O,ScoringEngine:()=>N,ScreenSignal:()=>I,ScrollBehaviorSignal:()=>D,SeleniumSignal:()=>V,Signal:()=>m,Signals:()=>Z,Verdict:()=>U,VerdictEngine:()=>F,WebDriverSignal:()=>v,WebGLSignal:()=>S,createDetector:()=>X,default:()=>ut,defaultInstantSignals:()=>J,defaultInteractionSignals:()=>tt,defaultSignals:()=>lt,detect:()=>Q,detectInstant:()=>et});var m=class{constructor(e={}){this.options=e,this._lastResult=null}get id(){return this.constructor.id}get category(){return this.constructor.category}get weight(){var e;return(e=this.options.weight)!=null?e:this.constructor.weight}get description(){return this.constructor.description}get requiresInteraction(){return this.constructor.requiresInteraction}get lastResult(){return this._lastResult}async detect(){throw new Error(`Signal.detect() must be implemented by ${this.constructor.name}`)}async run(){try{return this._lastResult=await this.detect(),this._lastResult}catch(e){return this._lastResult={triggered:!1,value:null,confidence:0,error:e.message},this._lastResult}}reset(){this._lastResult=null}createResult(e,t=null,i=1){return{triggered:!!e,value:t,confidence:Math.max(0,Math.min(1,i))}}};o(m,"id","base-signal"),o(m,"category","uncategorized"),o(m,"weight",.5),o(m,"description","Base signal class"),o(m,"requiresInteraction",!1);var N=class{constructor(e={}){this.weightOverrides=e.weightOverrides||{},this.maxScore=e.maxScore||100,this._results=new Map}getWeight(e,t){var i;return(i=this.weightOverrides[e])!=null?i:t}addResult(e,t,i){let n=this.getWeight(e,i);this._results.set(e,{...t,weight:n,contribution:t.triggered?n*t.confidence:0})}calculate(){if(this._results.size===0)return 0;let e=0,t=0;for(let[,n]of this._results)e+=n.weight,t+=n.contribution;if(e===0)return 0;let i=t/e*this.maxScore;return Math.round(i*100)/100}getBreakdown(){let e=[],t=this.calculate();for(let[i,n]of this._results)e.push({signalId:i,triggered:n.triggered,confidence:n.confidence,weight:n.weight,contribution:n.contribution,percentOfScore:t>0?(n.contribution/t*100).toFixed(1):"0.0"});return e.sort((i,n)=>n.contribution-i.contribution)}getTriggeredSignals(){let e=[];for(let[t,i]of this._results)i.triggered&&e.push(t);return e}getTriggeredCount(){let e=0;for(let[,t]of this._results)t.triggered&&e++;return e}reset(){this._results.clear()}};var U={HUMAN:"human",SUSPICIOUS:"suspicious",BOT:"bot"},Y=class Y{constructor(e={}){var t,i;this.humanThreshold=(t=e.humanThreshold)!=null?t:Y.DEFAULT_THRESHOLDS.human,this.suspiciousThreshold=(i=e.suspiciousThreshold)!=null?i:Y.DEFAULT_THRESHOLDS.suspicious,this.instantBotSignals=new Set(e.instantBotSignals||[])}getVerdict(e,t=[]){for(let r of t)if(this.instantBotSignals.has(r))return{verdict:U.BOT,score:e,confidence:"high",reason:`Instant bot signal triggered: ${r}`,triggeredCount:t.length};let i,n,s;return e<this.humanThreshold?(i=U.HUMAN,n=e<10?"high":"medium",s="Low bot score"):e<this.suspiciousThreshold?(i=U.SUSPICIOUS,n="medium",s="Moderate bot indicators detected"):(i=U.BOT,n=e>=75?"high":"medium",s="High accumulation of bot indicators"),{verdict:i,score:e,confidence:n,reason:s,triggeredCount:t.length}}isInstantBotSignal(e){return this.instantBotSignals.has(e)}addInstantBotSignal(e){this.instantBotSignals.add(e)}setThresholds(e){e.human!==void 0&&(this.humanThreshold=e.human),e.suspicious!==void 0&&(this.suspiciousThreshold=e.suspicious)}};o(Y,"DEFAULT_THRESHOLDS",{human:20,suspicious:50});var F=Y;var $=class{constructor(e={}){if(this.options=e,this._signals=new Map,this._scoringEngine=new N({weightOverrides:e.weightOverrides}),this._verdictEngine=new F({humanThreshold:e.humanThreshold,suspiciousThreshold:e.suspiciousThreshold,instantBotSignals:e.instantBotSignals}),this._lastDetection=null,this._detectionTimeout=e.detectionTimeout||5e3,this._isRunning=!1,e.signals)for(let t of e.signals)this.registerSignal(t)}registerSignal(e){if(!(e instanceof m))throw new Error("Signal must be an instance of Signal class");let t=e.id;if(this._signals.has(t))throw new Error(`Signal with ID "${t}" is already registered`);return this._signals.set(t,e),this}registerSignals(e){for(let t of e)this.registerSignal(t);return this}unregisterSignal(e){return this._signals.delete(e)}getSignal(e){return this._signals.get(e)}getSignals(){return Array.from(this._signals.values())}getSignalsByCategory(e){return this.getSignals().filter(t=>t.category===e)}async detect(e={}){if(this._isRunning)throw new Error("Detection is already running");this._isRunning=!0,this._scoringEngine.reset();let t=performance.now(),i=new Map;try{let n=this.getSignals().filter(u=>!(e.skipInteractionSignals&&u.requiresInteraction)),s=n.map(async u=>{let l,h=new Promise(w=>{l=setTimeout(()=>w({triggered:!1,value:null,confidence:0,error:"timeout"}),this._detectionTimeout)}),g=await Promise.race([u.run(),h]);return clearTimeout(l),{signal:u,result:g}}),r=await Promise.all(s);for(let{signal:u,result:l}of r)i.set(u.id,{...l,category:u.category,weight:u.weight,description:u.description}),this._scoringEngine.addResult(u.id,l,u.weight);let c=this._scoringEngine.calculate(),a=this._scoringEngine.getTriggeredSignals(),p=this._verdictEngine.getVerdict(c,a),d=performance.now()-t;return this._lastDetection={...p,signals:Object.fromEntries(i),breakdown:this._scoringEngine.getBreakdown(),timestamp:Date.now(),detectionTimeMs:Math.round(d),totalSignals:n.length,triggeredSignals:a},this._lastDetection}finally{this._isRunning=!1}}getLastDetection(){return this._lastDetection}getScore(){var e,t;return(t=(e=this._lastDetection)==null?void 0:e.score)!=null?t:0}getTriggeredSignals(){var e,t;return(t=(e=this._lastDetection)==null?void 0:e.triggeredSignals)!=null?t:[]}isRunning(){return this._isRunning}reset(){this._scoringEngine.reset(),this._lastDetection=null;for(let e of this._signals.values())e.reset()}configure(e){(e.humanThreshold!==void 0||e.suspiciousThreshold!==void 0)&&this._verdictEngine.setThresholds({human:e.humanThreshold,suspicious:e.suspiciousThreshold}),e.detectionTimeout!==void 0&&(this._detectionTimeout=e.detectionTimeout)}static withDefaults(){throw new Error(`BotDetector.withDefaults() is not supported. Use createDetector() from '@niksbanna/bot-detector' instead:
1
+ var BotDetectorLib=(()=>{var G=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var st=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var rt=(f,e,t)=>e in f?G(f,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):f[e]=t;var at=(f,e)=>{for(var t in e)G(f,t,{get:e[t],enumerable:!0})},ct=(f,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of st(e))!ot.call(f,n)&&n!==t&&G(f,n,{get:()=>e[n],enumerable:!(i=it(e,n))||i.enumerable});return f};var ht=f=>ct(G({},"__esModule",{value:!0}),f);var o=(f,e,t)=>rt(f,typeof e!="symbol"?e+"":e,t);var dt={};at(dt,{AudioContextSignal:()=>P,BotDetector:()=>$,CanvasSignal:()=>L,DOMContentTimingSignal:()=>A,HeadlessSignal:()=>M,InteractionTimingSignal:()=>C,KeyboardPatternSignal:()=>E,MouseMovementSignal:()=>k,NavigatorAnomalySignal:()=>b,PageLoadSignal:()=>H,PermissionsSignal:()=>T,PhantomJSSignal:()=>K,PlaywrightSignal:()=>B,PluginsSignal:()=>D,PuppeteerSignal:()=>O,ScoringEngine:()=>N,ScreenSignal:()=>I,ScrollBehaviorSignal:()=>R,SeleniumSignal:()=>V,Signal:()=>m,Signals:()=>Z,Verdict:()=>U,VerdictEngine:()=>F,WebDriverSignal:()=>y,WebGLSignal:()=>S,createDetector:()=>X,default:()=>ut,defaultInstantSignals:()=>J,defaultInteractionSignals:()=>tt,defaultSignals:()=>lt,detect:()=>Q,detectInstant:()=>et});var m=class{constructor(e={}){this.options=e,this._lastResult=null}get id(){return this.constructor.id}get category(){return this.constructor.category}get weight(){var e;return(e=this.options.weight)!=null?e:this.constructor.weight}get description(){return this.constructor.description}get requiresInteraction(){return this.constructor.requiresInteraction}get lastResult(){return this._lastResult}async detect(){throw new Error(`Signal.detect() must be implemented by ${this.constructor.name}`)}async run(){try{return this._lastResult=await this.detect(),this._lastResult}catch(e){return this._lastResult={triggered:!1,value:null,confidence:0,error:e.message},this._lastResult}}reset(){this._lastResult=null}createResult(e,t=null,i=1){return{triggered:!!e,value:t,confidence:Math.max(0,Math.min(1,i))}}};o(m,"id","base-signal"),o(m,"category","uncategorized"),o(m,"weight",.5),o(m,"description","Base signal class"),o(m,"requiresInteraction",!1);var N=class{constructor(e={}){this.weightOverrides=e.weightOverrides||{},this.maxScore=e.maxScore||100,this._results=new Map}getWeight(e,t){var i;return(i=this.weightOverrides[e])!=null?i:t}addResult(e,t,i){let n=this.getWeight(e,i);this._results.set(e,{...t,weight:n,contribution:t.triggered?n*t.confidence:0})}calculate(){if(this._results.size===0)return 0;let e=0,t=0;for(let[,n]of this._results)e+=n.weight,t+=n.contribution;if(e===0)return 0;let i=t/e*this.maxScore;return Math.round(i*100)/100}getBreakdown(){let e=[],t=this.calculate();for(let[i,n]of this._results)e.push({signalId:i,triggered:n.triggered,confidence:n.confidence,weight:n.weight,contribution:n.contribution,percentOfScore:t>0?(n.contribution/t*100).toFixed(1):"0.0"});return e.sort((i,n)=>n.contribution-i.contribution)}getTriggeredSignals(){let e=[];for(let[t,i]of this._results)i.triggered&&e.push(t);return e}getTriggeredCount(){let e=0;for(let[,t]of this._results)t.triggered&&e++;return e}reset(){this._results.clear()}};var U={HUMAN:"human",SUSPICIOUS:"suspicious",BOT:"bot"},Y=class Y{constructor(e={}){var t,i;this.humanThreshold=(t=e.humanThreshold)!=null?t:Y.DEFAULT_THRESHOLDS.human,this.suspiciousThreshold=(i=e.suspiciousThreshold)!=null?i:Y.DEFAULT_THRESHOLDS.suspicious,this.instantBotSignals=new Set(e.instantBotSignals||[])}getVerdict(e,t=[]){for(let a of t)if(this.instantBotSignals.has(a))return{verdict:U.BOT,score:e,confidence:"high",reason:`Instant bot signal triggered: ${a}`,triggeredCount:t.length};let i,n,s;return e<this.humanThreshold?(i=U.HUMAN,n=e<10?"high":"medium",s="Low bot score"):e<this.suspiciousThreshold?(i=U.SUSPICIOUS,n="medium",s="Moderate bot indicators detected"):(i=U.BOT,n=e>=75?"high":"medium",s="High accumulation of bot indicators"),{verdict:i,score:e,confidence:n,reason:s,triggeredCount:t.length}}isInstantBotSignal(e){return this.instantBotSignals.has(e)}addInstantBotSignal(e){this.instantBotSignals.add(e)}setThresholds(e){e.human!==void 0&&(this.humanThreshold=e.human),e.suspicious!==void 0&&(this.suspiciousThreshold=e.suspicious)}};o(Y,"DEFAULT_THRESHOLDS",{human:20,suspicious:50});var F=Y;var $=class{constructor(e={}){if(this.options=e,this._signals=new Map,this._scoringEngine=new N({weightOverrides:e.weightOverrides}),this._verdictEngine=new F({humanThreshold:e.humanThreshold,suspiciousThreshold:e.suspiciousThreshold,instantBotSignals:e.instantBotSignals}),this._lastDetection=null,this._detectionTimeout=e.detectionTimeout||5e3,this._isRunning=!1,e.signals)for(let t of e.signals)this.registerSignal(t)}registerSignal(e){if(!(e instanceof m))throw new Error("Signal must be an instance of Signal class");let t=e.id;if(this._signals.has(t))throw new Error(`Signal with ID "${t}" is already registered`);return this._signals.set(t,e),this}registerSignals(e){for(let t of e)this.registerSignal(t);return this}unregisterSignal(e){return this._signals.delete(e)}getSignal(e){return this._signals.get(e)}getSignals(){return Array.from(this._signals.values())}getSignalsByCategory(e){return this.getSignals().filter(t=>t.category===e)}async detect(e={}){if(this._isRunning)throw new Error("Detection is already running");this._isRunning=!0,this._scoringEngine.reset();let t=performance.now(),i=new Map;try{let n=this.getSignals().filter(u=>!(e.skipInteractionSignals&&u.requiresInteraction)),s=n.map(async u=>{let l,h=new Promise(w=>{l=setTimeout(()=>w({triggered:!1,value:null,confidence:0,error:"timeout"}),this._detectionTimeout)}),g=await Promise.race([u.run(),h]);return clearTimeout(l),{signal:u,result:g}}),a=await Promise.all(s);for(let{signal:u,result:l}of a)i.set(u.id,{...l,category:u.category,weight:u.weight,description:u.description}),this._scoringEngine.addResult(u.id,l,u.weight);let c=this._scoringEngine.calculate(),r=this._scoringEngine.getTriggeredSignals(),p=this._verdictEngine.getVerdict(c,r),d=performance.now()-t;return this._lastDetection={...p,signals:Object.fromEntries(i),breakdown:this._scoringEngine.getBreakdown(),timestamp:Date.now(),detectionTimeMs:Math.round(d),totalSignals:n.length,triggeredSignals:r},this._lastDetection}finally{this._isRunning=!1}}getLastDetection(){return this._lastDetection}getScore(){var e,t;return(t=(e=this._lastDetection)==null?void 0:e.score)!=null?t:0}getTriggeredSignals(){var e,t;return(t=(e=this._lastDetection)==null?void 0:e.triggeredSignals)!=null?t:[]}isRunning(){return this._isRunning}reset(){this._scoringEngine.reset(),this._lastDetection=null;for(let e of this._signals.values())e.reset()}configure(e){(e.humanThreshold!==void 0||e.suspiciousThreshold!==void 0)&&this._verdictEngine.setThresholds({human:e.humanThreshold,suspicious:e.suspiciousThreshold}),e.detectionTimeout!==void 0&&(this._detectionTimeout=e.detectionTimeout)}static withDefaults(){throw new Error(`BotDetector.withDefaults() is not supported. Use createDetector() from '@niksbanna/bot-detector' instead:
2
2
  import { createDetector } from '@niksbanna/bot-detector';
3
- const detector = createDetector();`)}};var v=class extends m{async detect(){if(navigator.webdriver===!0)return this.createResult(!0,{webdriver:!0},1);let e=Object.getOwnPropertyDescriptor(navigator,"webdriver");if(e&&(e.get||!e.configurable))return this.createResult(!0,{webdriver:"modified",descriptor:{configurable:e.configurable,enumerable:e.enumerable,hasGetter:!!e.get}},.8);try{let t=Object.getPrototypeOf(navigator),i=Object.getOwnPropertyDescriptor(t,"webdriver");if(i&&i.get&&i.get.call(navigator)===!0)return this.createResult(!0,{webdriver:!0,source:"prototype"},1)}catch{}return this.createResult(!1)}};o(v,"id","webdriver"),o(v,"category","environment"),o(v,"weight",1),o(v,"description","Detects navigator.webdriver automation flag");var M=class extends m{async detect(){let e=[],t=0,i=navigator.userAgent||"";i.includes("HeadlessChrome")&&(e.push("headless-ua"),t=Math.max(t,1)),i.includes("Chrome")&&!i.includes("Chromium")&&typeof window.chrome>"u"&&(e.push("missing-chrome-object"),t=Math.max(t,.6)),navigator.plugins&&navigator.plugins.length===0&&(e.push("no-plugins"),t=Math.max(t,.5)),(!navigator.languages||navigator.languages.length===0)&&(e.push("no-languages"),t=Math.max(t,.6)),window.outerWidth===0&&window.outerHeight===0&&(e.push("zero-outer-dimensions"),t=Math.max(t,.7)),typeof navigator.connection>"u"&&i.includes("Chrome")&&(e.push("missing-connection-api"),t=Math.max(t,.3));try{typeof Notification<"u"&&Notification.permission==="denied"&&window.outerWidth===0&&(e.push("notification-headless-pattern"),t=Math.max(t,.5))}catch{}(window.callPhantom||window._phantom)&&(e.push("phantomjs"),t=Math.max(t,1)),window.__nightmare&&(e.push("nightmare"),t=Math.max(t,1));let n=e.length>0;return e.length>=3&&(t=Math.min(1,t+.2)),this.createResult(n,{indicators:e},t)}};o(M,"id","headless"),o(M,"category","environment"),o(M,"weight",.8),o(M,"description","Detects headless browser indicators");var b=class extends m{async detect(){let e=[],t=0,i=0,n=navigator.userAgent||"",s=navigator.platform||"";i++,s.includes("Win")&&!n.includes("Windows")?(e.push("platform-ua-mismatch-windows"),t+=1):s.includes("Mac")&&!n.includes("Mac")?(e.push("platform-ua-mismatch-mac"),t+=1):s.includes("Linux")&&!n.includes("Linux")&&!n.includes("Android")&&(e.push("platform-ua-mismatch-linux"),t+=1),i++,!(n.includes("Chrome")&&!n.includes("Chromium"))&&(!s||s===""||s==="undefined")&&(e.push("empty-platform"),t+=1),i++,navigator.language&&navigator.languages&&(navigator.languages.includes(navigator.language)||(e.push("language-mismatch"),t+=.5)),i++,n.includes("Chrome")&&navigator.vendor!=="Google Inc."?(e.push("vendor-mismatch-chrome"),t+=.5):n.includes("Firefox")&&navigator.vendor!==""?(e.push("vendor-mismatch-firefox"),t+=.5):n.includes("Safari")&&!n.includes("Chrome")&&navigator.vendor!=="Apple Computer, Inc."&&(e.push("vendor-mismatch-safari"),t+=.5),i++,typeof navigator.hardwareConcurrency<"u"&&(navigator.hardwareConcurrency===0||navigator.hardwareConcurrency>128)&&(e.push("suspicious-hardware-concurrency"),t+=.5),i++,typeof navigator.deviceMemory<"u"&&(navigator.deviceMemory===0||navigator.deviceMemory>512)&&(e.push("suspicious-device-memory"),t+=.5),i++;let c=/Android|iPhone|iPad|iPod|Mobile/i.test(n),a=navigator.maxTouchPoints>0;!c&&navigator.maxTouchPoints>5&&(e.push("desktop-high-touch-points"),t+=.3),i++;try{let u=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");u&&u.get&&u.get.toString().includes("native code")===!1&&(e.push("spoofed-user-agent"),t+=1)}catch{}let p=e.length>0,d=Math.min(1,t/Math.max(1,i));return this.createResult(p,{anomalies:e},d)}};o(b,"id","navigator-anomaly"),o(b,"category","environment"),o(b,"weight",.7),o(b,"description","Detects navigator property inconsistencies");var T=class extends m{async detect(){let e=[];if(!navigator.permissions)return this.createResult(!1,{supported:!1},0);try{let n=await navigator.permissions.query({name:"notifications"});if(typeof Notification<"u"){let s=Notification.permission;(s==="granted"&&n.state!=="granted"||s==="denied"&&n.state!=="denied"||s==="default"&&n.state!=="prompt")&&e.push("notification-permission-mismatch")}try{(await navigator.permissions.query({name:"geolocation"})).state==="denied"&&window.outerWidth===0&&e.push("geo-denied-headless")}catch{}try{await navigator.permissions.query({name:"camera"})}catch(s){s.name==="TypeError"&&e.push("camera-permission-error")}}catch(n){n.name!=="TypeError"&&e.push("permissions-query-error")}let t=e.length>0,i=Math.min(1,e.length*.4);return this.createResult(t,{anomalies:e},i)}};o(T,"id","permissions"),o(T,"category","environment"),o(T,"weight",.5),o(T,"description","Detects Permissions API anomalies");var k=class extends m{constructor(e={}){super(e),this._movements=[],this._isTracking=!1,this._trackingDuration=Math.min(e.trackingDuration||2500,2500),this._minMovements=e.minMovements||5,this._boundHandler=null}startTracking(){this._isTracking||(this._movements=[],this._isTracking=!0,this._boundHandler=e=>{this._movements.push({x:e.clientX,y:e.clientY,t:performance.now()})},document.addEventListener("mousemove",this._boundHandler,{passive:!0}))}stopTracking(){this._isTracking&&(this._isTracking=!1,this._boundHandler&&(document.removeEventListener("mousemove",this._boundHandler),this._boundHandler=null))}async detect(){let e=[],t=0;this._movements.length===0&&(this.startTracking(),await new Promise(r=>setTimeout(r,this._trackingDuration)),this.stopTracking());let i=this._movements;if(i.length<this._minMovements)return e.push("no-mouse-movement"),t=Math.max(t,.6),this.createResult(!0,{anomalies:e,movements:i.length},t);let n=this._analyzeMovements(i);n.teleportCount>0&&(e.push("mouse-teleportation"),t=Math.max(t,.7)),n.linearPathRatio>.9&&(e.push("linear-path"),t=Math.max(t,.8)),n.velocityVariance<.01&&i.length>10&&(e.push("constant-velocity"),t=Math.max(t,.7)),n.accelerationChanges===0&&i.length>10&&(e.push("no-acceleration-variance"),t=Math.max(t,.6)),n.timingVariance<1&&i.length>10&&(e.push("robotic-timing"),t=Math.max(t,.8));let s=e.length>0;return this.createResult(s,{anomalies:e,movementCount:i.length,analysis:n},t)}_analyzeMovements(e){if(e.length<3)return{teleportCount:0,linearPathRatio:0,velocityVariance:0,accelerationChanges:0,timingVariance:0};let t=0,i=[],n=[],s=[];for(let l=1;l<e.length;l++){let h=e[l-1],g=e[l],w=g.x-h.x,x=g.y-h.y,_=g.t-h.t;if(_===0)continue;let q=Math.sqrt(w*w+x*x),y=q/_;i.push(y),n.push(Math.atan2(x,w)),s.push(_),q>300&&_<10&&t++}let r=i.reduce((l,h)=>l+h,0)/i.length,c=i.reduce((l,h)=>l+Math.pow(h-r,2),0)/i.length,a=0;if(n.length>1){let l=0;for(let h=1;h<n.length;h++)Math.abs(n[h]-n[h-1])<.1&&l++;a=l/(n.length-1)}let p=s.reduce((l,h)=>l+h,0)/s.length,d=s.reduce((l,h)=>l+Math.pow(h-p,2),0)/s.length,u=0;for(let l=1;l<i.length;l++)(i[l]-i[l-1])*(i[l-1]-(i[l-2]||0))<0&&u++;return{teleportCount:t,linearPathRatio:a,velocityVariance:c,accelerationChanges:u,timingVariance:d}}reset(){super.reset(),this.stopTracking(),this._movements=[]}};o(k,"id","mouse-movement"),o(k,"category","behavior"),o(k,"weight",.9),o(k,"description","Detects non-human mouse movement patterns"),o(k,"requiresInteraction",!0);var E=class extends m{constructor(e={}){super(e),this._keystrokes=[],this._isTracking=!1,this._trackingDuration=Math.min(e.trackingDuration||2500,2500),this._minKeystrokes=e.minKeystrokes||10,this._boundKeydownHandler=null,this._boundKeyupHandler=null}startTracking(){this._isTracking||(this._keystrokes=[],this._isTracking=!0,this._boundKeydownHandler=e=>{this._keystrokes.push({type:"down",key:e.key,code:e.code,t:performance.now()})},this._boundKeyupHandler=e=>{this._keystrokes.push({type:"up",key:e.key,code:e.code,t:performance.now()})},document.addEventListener("keydown",this._boundKeydownHandler,{passive:!0}),document.addEventListener("keyup",this._boundKeyupHandler,{passive:!0}))}stopTracking(){this._isTracking&&(this._isTracking=!1,this._boundKeydownHandler&&(document.removeEventListener("keydown",this._boundKeydownHandler),this._boundKeydownHandler=null),this._boundKeyupHandler&&(document.removeEventListener("keyup",this._boundKeyupHandler),this._boundKeyupHandler=null))}async detect(){let e=[],t=0;this._keystrokes.length===0&&(this.startTracking(),await new Promise(c=>setTimeout(c,this._trackingDuration)),this.stopTracking());let i=this._keystrokes,n=i.filter(c=>c.type==="down");if(n.length<this._minKeystrokes)return this.createResult(!1,{reason:"insufficient-data",keystrokes:n.length},0);let s=this._analyzeKeystrokes(i);s.avgInterKeystrokeTime<50&&n.length>20&&(e.push("inhuman-speed"),t=Math.max(t,.9)),s.timingVariance<5&&n.length>15&&(e.push("robotic-timing"),t=Math.max(t,.8)),s.missingKeyups>n.length*.5&&(e.push("missing-keyups"),t=Math.max(t,.7)),s.holdTimeVariance<2&&s.holdTimes.length>10&&(e.push("constant-hold-time"),t=Math.max(t,.6)),s.sequentialKeys>n.length*.8&&n.length>10&&(e.push("sequential-input"),t=Math.max(t,.5)),s.rhythmScore<.1&&n.length>20&&(e.push("no-rhythm-variation"),t=Math.max(t,.6));let r=e.length>0;return this.createResult(r,{anomalies:e,keystrokeCount:n.length,analysis:s},t)}_analyzeKeystrokes(e){let t=e.filter(h=>h.type==="down"),i=e.filter(h=>h.type==="up");if(t.length<2)return{avgInterKeystrokeTime:1/0,timingVariance:1/0,missingKeyups:0,holdTimeVariance:1/0,holdTimes:[],sequentialKeys:0,rhythmScore:1};let n=[];for(let h=1;h<t.length;h++)n.push(t[h].t-t[h-1].t);let s=n.reduce((h,g)=>h+g,0)/n.length,r=n.reduce((h,g)=>h+Math.pow(g-s,2),0)/n.length,c=[];for(let h of t){let g=i.find(w=>w.key===h.key&&w.t>h.t);g&&c.push(g.t-h.t)}let a=c.length>0?c.reduce((h,g)=>h+g,0)/c.length:0,p=c.length>0?c.reduce((h,g)=>h+Math.pow(g-a,2),0)/c.length:1/0,d=t.length-c.length,u=0;for(let h=1;h<t.length;h++){let g=t[h-1].key.charCodeAt(0),w=t[h].key.charCodeAt(0);Math.abs(w-g)===1&&u++}let l=0;if(n.length>5){let h=[...n].sort((x,_)=>x-_),g=h[Math.floor(h.length/2)];l=n.filter(x=>Math.abs(x-g)>g*.3).length/n.length}return{avgInterKeystrokeTime:s,timingVariance:r,missingKeyups:d,holdTimeVariance:p,holdTimes:c,sequentialKeys:u,rhythmScore:l}}reset(){super.reset(),this.stopTracking(),this._keystrokes=[]}};o(E,"id","keyboard-pattern"),o(E,"category","behavior"),o(E,"weight",.8),o(E,"description","Detects non-human keystroke patterns"),o(E,"requiresInteraction",!0);var C=class extends m{constructor(e={}){super(e),this._pageLoadTime=performance.now(),this._firstInteractionTime=null,this._interactions=[],this._isTracking=!1,this._trackingDuration=e.trackingDuration||5e3,this._boundHandler=null}startTracking(){if(this._isTracking)return;this._interactions=[],this._isTracking=!0;let e=["click","mousedown","touchstart","keydown","scroll"];this._boundHandler=t=>{let i=performance.now();this._firstInteractionTime===null&&(this._firstInteractionTime=i),this._interactions.push({type:t.type,t:i,timeSinceLoad:i-this._pageLoadTime})};for(let t of e)document.addEventListener(t,this._boundHandler,{passive:!0,capture:!0})}stopTracking(){if(!this._isTracking)return;this._isTracking=!1;let e=["click","mousedown","touchstart","keydown","scroll"];if(this._boundHandler){for(let t of e)document.removeEventListener(t,this._boundHandler,{capture:!0});this._boundHandler=null}}async detect(){let e=[],t=0;!this._isTracking&&this._interactions.length===0&&(this.startTracking(),await new Promise(c=>setTimeout(c,this._trackingDuration)),this.stopTracking());let i=this._interactions;if(i.length===0)return this.createResult(!1,{reason:"no-interactions"},0);let n=i[0];if(n.timeSinceLoad<100?(e.push("instant-interaction"),t=Math.max(t,.9)):n.timeSinceLoad<300&&(e.push("very-fast-interaction"),t=Math.max(t,.6)),i.length>3){let c=[];for(let l=1;l<i.length;l++)c.push(i[l].t-i[l-1].t);let a=c.reduce((l,h)=>l+h,0)/c.length;c.reduce((l,h)=>l+Math.pow(h-a,2),0)/c.length<10&&i.length>5&&(e.push("robotic-intervals"),t=Math.max(t,.8));let d=50,u=0;for(let l of c)l<d&&u++;u>c.length*.7&&(e.push("burst-interactions"),t=Math.max(t,.7))}let s=i.map(c=>c.type).join(",");if(i.length>=6){let c=Math.floor(i.length/2),a=i.slice(0,c).map(d=>d.type).join(","),p=i.slice(c,c*2).map(d=>d.type).join(",");a===p&&a.length>0&&(e.push("repeated-sequence"),t=Math.max(t,.6))}let r=e.length>0;return this.createResult(r,{anomalies:e,interactionCount:i.length,timeToFirstInteraction:n.timeSinceLoad,firstInteractionType:n.type},t)}reset(){super.reset(),this.stopTracking(),this._pageLoadTime=performance.now(),this._firstInteractionTime=null,this._interactions=[]}};o(C,"id","interaction-timing"),o(C,"category","behavior"),o(C,"weight",.6),o(C,"description","Detects suspicious interaction timing"),o(C,"requiresInteraction",!0);var D=class extends m{constructor(e={}){super(e),this._scrollEvents=[],this._isTracking=!1,this._trackingDuration=Math.min(e.trackingDuration||2500,2500),this._boundHandler=null}startTracking(){this._isTracking||(this._scrollEvents=[],this._isTracking=!0,this._boundHandler=()=>{this._scrollEvents.push({scrollY:window.scrollY,scrollX:window.scrollX,t:performance.now()})},window.addEventListener("scroll",this._boundHandler,{passive:!0}))}stopTracking(){this._isTracking&&(this._isTracking=!1,this._boundHandler&&(window.removeEventListener("scroll",this._boundHandler),this._boundHandler=null))}async detect(){let e=[],t=0;this._scrollEvents.length===0&&(this.startTracking(),await new Promise(r=>setTimeout(r,this._trackingDuration)),this.stopTracking());let i=this._scrollEvents;if(i.length<3)return this.createResult(!1,{reason:"insufficient-scroll-data",scrollEvents:i.length},0);let n=this._analyzeScrollPatterns(i);n.instantJumps>0&&(e.push("instant-scroll-jumps"),t=Math.max(t,.7)),n.velocityVariance<.1&&i.length>10&&(e.push("constant-scroll-velocity"),t=Math.max(t,.6)),n.momentumEvents===0&&i.length>5&&(e.push("no-scroll-momentum"),t=Math.max(t,.5)),n.intervalVariance<5&&i.length>10&&(e.push("robotic-scroll-timing"),t=Math.max(t,.7)),n.scrollDirections===1&&Math.abs(n.totalScrollY)>1e3&&n.velocityVariance<1&&(e.push("one-dimensional-scroll"),t=Math.max(t,.4)),n.exactPositionScrolls>2&&(e.push("exact-position-scrolls"),t=Math.max(t,.6));let s=e.length>0;return this.createResult(s,{anomalies:e,scrollEventCount:i.length,analysis:n},t)}_analyzeScrollPatterns(e){if(e.length<2)return{instantJumps:0,velocityVariance:0,momentumEvents:0,intervalVariance:0,scrollDirections:0,totalScrollY:0,exactPositionScrolls:0};let t=0,i=0,n=[],s=[],r=!1,c=!1,a=0,p=[0,100,200,300,400,500,600,800,1e3];for(let x=1;x<e.length;x++){let _=e[x-1],q=e[x],y=q.scrollY-_.scrollY,W=q.scrollX-_.scrollX,z=q.t-_.t;if(s.push(z),Math.abs(y)>0&&(r=!0),Math.abs(W)>0&&(c=!0),z===0)continue;let j=Math.sqrt(y*y+W*W)/z;if(n.push(j),Math.abs(y)+Math.abs(W)>200&&z<20&&t++,x>1&&n.length>1){let nt=n[n.length-2];j<nt*.9&&j>0&&i++}p.includes(Math.round(q.scrollY))&&a++}let d=n.length>0?n.reduce((x,_)=>x+_,0)/n.length:0,u=n.length>0?n.reduce((x,_)=>x+Math.pow(_-d,2),0)/n.length:0,l=s.reduce((x,_)=>x+_,0)/s.length,h=s.reduce((x,_)=>x+Math.pow(_-l,2),0)/s.length,g=0;r&&g++,c&&g++;let w=e[e.length-1].scrollY-e[0].scrollY;return{instantJumps:t,velocityVariance:u,momentumEvents:i,intervalVariance:h,scrollDirections:g,totalScrollY:w,exactPositionScrolls:a}}reset(){super.reset(),this.stopTracking(),this._scrollEvents=[]}};o(D,"id","scroll-behavior"),o(D,"category","behavior"),o(D,"weight",.5),o(D,"description","Detects programmatic scroll patterns"),o(D,"requiresInteraction",!0);var R=class extends m{async detect(){let e=[],t=0,i=navigator.plugins,n=navigator.mimeTypes;if(!i)return e.push("no-plugins-object"),t=Math.max(t,.6),this.createResult(!0,{anomalies:e},t);i.length===0&&(e.push("empty-plugins"),t=Math.max(t,.5));let s=navigator.userAgent||"";if(s.includes("Chrome")&&!s.includes("Chromium")&&!Array.from(i).some(p=>p.name.includes("PDF")||p.name.includes("Chromium PDF"))&&i.length===0&&(e.push("chrome-missing-pdf-plugin"),t=Math.max(t,.4)),i.length>0&&n){let a=0;for(let p=0;p<i.length;p++)a+=i[p].length||0;n.length===0&&a>0&&(e.push("mimetypes-mismatch"),t=Math.max(t,.5))}if(i.length>1){let a=Array.from(i).map(d=>d.name);new Set(a).size<a.length&&(e.push("duplicate-plugins"),t=Math.max(t,.6))}try{let a=Object.getOwnPropertyDescriptor(Navigator.prototype,"plugins");a&&a.get&&(a.get.toString().includes("[native code]")||(e.push("plugins-getter-overridden"),t=Math.max(t,.7)))}catch{}!/Android|iPhone|iPad|iPod|Mobile/i.test(s)&&i.length===1&&(e.push("minimal-plugins"),t=Math.max(t,.3));let c=e.length>0;return this.createResult(c,{anomalies:e,pluginCount:i.length,mimeTypeCount:(n==null?void 0:n.length)||0},t)}};o(R,"id","plugins"),o(R,"category","fingerprint"),o(R,"weight",.6),o(R,"description","Detects browser plugin anomalies");var S=class extends m{async detect(){let e=[],t=0,i=document.createElement("canvas"),n=null;try{n=i.getContext("webgl")||i.getContext("experimental-webgl")}catch{e.push("webgl-error"),t=Math.max(t,.5)}if(!n)return e.push("webgl-unavailable"),t=Math.max(t,.4),this.createResult(!0,{anomalies:e},t);let s=n.getExtension("WEBGL_debug_renderer_info"),r="",c="";s&&(r=n.getParameter(s.UNMASKED_VENDOR_WEBGL)||"",c=n.getParameter(s.UNMASKED_RENDERER_WEBGL)||""),!r&&!c&&(e.push("no-webgl-renderer-info"),t=Math.max(t,.6));let a=["swiftshader","llvmpipe","software","mesa","google swiftshader","vmware","virtualbox"],p=c.toLowerCase();for(let w of a)if(p.includes(w)){e.push(`suspicious-renderer-${w.replace(/\s+/g,"-")}`),t=Math.max(t,.7);break}r&&c&&(p.includes("nvidia")&&!r.toLowerCase().includes("nvidia")&&(e.push("vendor-renderer-mismatch"),t=Math.max(t,.6)),(p.includes("amd")||p.includes("radeon"))&&!r.toLowerCase().includes("amd")&&!r.toLowerCase().includes("ati")&&(e.push("vendor-renderer-mismatch"),t=Math.max(t,.6)));let d=n.getSupportedExtensions()||[];d.length<5&&(e.push("few-webgl-extensions"),t=Math.max(t,.4));let u=n.getParameter(n.MAX_TEXTURE_SIZE),l=n.getParameter(n.MAX_VIEWPORT_DIMS);(u<1024||u>65536)&&(e.push("unrealistic-max-texture"),t=Math.max(t,.5));try{n.clearColor(0,0,0,1),n.clear(n.COLOR_BUFFER_BIT);let w=new Uint8Array(4);n.readPixels(0,0,1,1,n.RGBA,n.UNSIGNED_BYTE,w),w[3]!==255&&(e.push("webgl-render-failure"),t=Math.max(t,.6))}catch{e.push("webgl-render-error"),t=Math.max(t,.5)}let h=n.getExtension("WEBGL_lose_context");h&&h.loseContext();let g=e.length>0;return this.createResult(g,{anomalies:e,vendor:r,renderer:c,extensionCount:d.length,maxTextureSize:u},t)}};o(S,"id","webgl"),o(S,"category","fingerprint"),o(S,"weight",.7),o(S,"description","Detects WebGL rendering anomalies");var L=class extends m{async detect(){let e=[],t=0;try{let n=document.createElement("canvas");n.width=200,n.height=50;let s=n.getContext("2d");if(!s)return e.push("canvas-context-unavailable"),t=Math.max(t,.5),this.createResult(!0,{anomalies:e},t);s.textBaseline="alphabetic",s.font="14px Arial",s.fillStyle="#f60",s.fillRect(0,0,200,50),s.fillStyle="#069",s.fillText("Bot Detection Test \u{1F916}",2,15),s.fillStyle="rgba(102, 204, 0, 0.7)",s.fillText("Canvas Fingerprint",4,30),s.beginPath(),s.arc(100,25,10,0,Math.PI*2,!0),s.closePath(),s.fill();let r=n.toDataURL();s.clearRect(0,0,200,50),s.fillStyle="#f60",s.fillRect(0,0,200,50),s.fillStyle="#069",s.fillText("Bot Detection Test \u{1F916}",2,15),s.fillStyle="rgba(102, 204, 0, 0.7)",s.fillText("Canvas Fingerprint",4,30),s.beginPath(),s.arc(100,25,10,0,Math.PI*2,!0),s.closePath(),s.fill();let c=n.toDataURL();r!==c&&(e.push("canvas-randomized"),t=Math.max(t,.6)),r.length<1e3&&(e.push("canvas-possibly-blank"),t=Math.max(t,.4));let a=document.createElement("canvas");a.width=200,a.height=50;let p=a.toDataURL();r===p&&(e.push("canvas-rendering-blocked"),t=Math.max(t,.7));try{n.toDataURL.toString().includes("[native code]")||(e.push("toDataURL-overridden"),t=Math.max(t,.8))}catch{}let u=s.getImageData(0,0,200,50).data,l=!0,h=[u[0],u[1],u[2],u[3]];for(let g=4;g<u.length;g+=4)if(u[g]!==h[0]||u[g+1]!==h[1]||u[g+2]!==h[2]){l=!1;break}l&&(e.push("uniform-pixel-data"),t=Math.max(t,.6))}catch{e.push("canvas-error"),t=Math.max(t,.4)}let i=e.length>0;return this.createResult(i,{anomalies:e},t)}};o(L,"id","canvas"),o(L,"category","fingerprint"),o(L,"weight",.5),o(L,"description","Detects canvas fingerprint anomalies");var P=class extends m{async detect(){let e=[],t=0,i=window.AudioContext||window.webkitAudioContext;if(!i)return e.push("audio-context-unavailable"),t=Math.max(t,.4),this.createResult(!0,{anomalies:e},t);let n=null,s=null,r=null;try{n=new i;let a=n.sampleRate;if(a!==44100&&a!==48e3&&a!==96e3&&(e.push("unusual-sample-rate"),t=Math.max(t,.3)),s=n.createOscillator(),r=n.createAnalyser(),!s||!r)e.push("audio-nodes-unavailable"),t=Math.max(t,.5);else{let d=r.fftSize,u=n.destination;(!u||u.maxChannelCount===0)&&(e.push("no-audio-destination"),t=Math.max(t,.6)),u&&u.maxChannelCount<2&&(e.push("mono-audio-only"),t=Math.max(t,.3))}try{i.toString().includes("[native code]")||(e.push("audio-context-overridden"),t=Math.max(t,.7))}catch{}try{if(n.state==="suspended"&&await n.resume().catch(()=>{}),n.state==="running"){let d=n.createOscillator(),u=n.createGain(),l=n.createScriptProcessor?n.createScriptProcessor(4096,1,1):null;l&&(d.type="triangle",d.frequency.value=1e4,u.gain.value=0,d.connect(u),u.connect(l),l.connect(n.destination),d.start(0),await new Promise(h=>setTimeout(h,50)),d.stop(),d.disconnect(),u.disconnect(),l.disconnect())}}catch{e.push("audio-fingerprint-blocked"),t=Math.max(t,.4)}window.OfflineAudioContext||window.webkitOfflineAudioContext||(e.push("offline-audio-context-unavailable"),t=Math.max(t,.3))}catch{e.push("audio-context-error"),t=Math.max(t,.4)}finally{if(s)try{s.disconnect()}catch{}if(r)try{r.disconnect()}catch{}if(n)try{n.close()}catch{}}let c=e.length>0;return this.createResult(c,{anomalies:e},t)}};o(P,"id","audio-context"),o(P,"category","fingerprint"),o(P,"weight",.5),o(P,"description","Detects AudioContext anomalies");var I=class extends m{async detect(){let e=[],t=0,i=window.screen;if(!i)return e.push("no-screen-object"),t=Math.max(t,.6),this.createResult(!0,{anomalies:e},t);let n=i.width,s=i.height,r=i.availWidth,c=i.availHeight,a=i.colorDepth,p=i.pixelDepth,d=window.outerWidth,u=window.outerHeight,l=window.innerWidth,h=window.innerHeight;(d===0||u===0)&&(e.push("zero-outer-dimensions"),t=Math.max(t,.8)),(l===0||h===0)&&(e.push("zero-inner-dimensions"),t=Math.max(t,.7));let g=navigator.userAgent||"";!/Android|iPhone|iPad|iPod|Mobile/i.test(g)&&(n<640||s<480)&&(e.push("very-small-screen"),t=Math.max(t,.5)),(n>7680||s>4320)&&(e.push("unrealistic-screen-size"),t=Math.max(t,.4));let x=[{w:800,h:600},{w:1024,h:768},{w:1920,h:1080}];for(let y of x)if(n===y.w&&s===y.h&&d===y.w&&u===y.h){e.push("headless-default-dimensions"),t=Math.max(t,.5);break}(r>n||c>s)&&(e.push("available-exceeds-total"),t=Math.max(t,.7)),(d>n||u>s)&&(e.push("window-exceeds-screen"),t=Math.max(t,.6)),a!==24&&a!==32&&a!==30&&a!==48&&(e.push("unusual-color-depth"),t=Math.max(t,.3)),a!==p&&(e.push("depth-mismatch"),t=Math.max(t,.3));let _=window.devicePixelRatio;if(_===0||_===void 0?(e.push("missing-device-pixel-ratio"),t=Math.max(t,.5)):(_<.5||_>5)&&(e.push("unusual-device-pixel-ratio"),t=Math.max(t,.4)),i.orientation){let y=i.orientation.type,W=i.orientation.angle;y.includes("landscape")&&n<s&&(e.push("orientation-dimension-mismatch"),t=Math.max(t,.4)),y.includes("portrait")&&n>s&&(e.push("orientation-dimension-mismatch"),t=Math.max(t,.4))}l===d&&h===u&&d>0&&u>0&&(e.push("no-browser-chrome"),t=Math.max(t,.5));let q=e.length>0;return this.createResult(q,{anomalies:e,dimensions:{screen:{width:n,height:s},available:{width:r,height:c},window:{outer:{width:d,height:u},inner:{width:l,height:h}},colorDepth:a,devicePixelRatio:_}},t)}};o(I,"id","screen"),o(I,"category","fingerprint"),o(I,"weight",.4),o(I,"description","Detects unusual screen dimensions");var H=class extends m{async detect(){let e=[],t=0;if(!window.performance||!performance.timing){if(performance.getEntriesByType){let z=performance.getEntriesByType("navigation");if(z.length>0)return this._analyzeNavigationTiming(z[0])}return e.push("no-performance-api"),t=Math.max(t,.3),this.createResult(!0,{anomalies:e},t)}let i=performance.timing,n=i.navigationStart,s=(z,j)=>z===0||j===0?null:z-j,r=s(i.domContentLoadedEventEnd,n),c=s(i.domComplete,n),a=s(i.loadEventEnd,n),p=s(i.domainLookupEnd,i.domainLookupStart),d=s(i.connectEnd,i.connectStart),u=s(i.responseEnd,i.requestStart),l=s(i.domComplete,i.domLoading);r!==null&&r>0&&r<10&&(e.push("instant-dom-content-loaded"),t=Math.max(t,.7)),p===0&&d===0&&u!==null&&u<5&&(e.push("zero-network-timing"),t=Math.max(t,.4)),(r!==null&&r<0||c!==null&&c<0||a!==null&&a<0)&&(e.push("negative-timing"),t=Math.max(t,.8)),i.domContentLoadedEventEnd>0&&i.loadEventEnd>0&&i.domContentLoadedEventEnd>i.loadEventEnd&&(e.push("timing-order-violation"),t=Math.max(t,.7)),l!==null&&l>3e4&&(e.push("excessive-dom-processing"),t=Math.max(t,.3));let h=i.domContentLoadedEventStart-i.responseEnd;i.responseEnd>0&&i.domContentLoadedEventStart>0&&h>0&&h<5&&(e.push("instant-script-execution"),t=Math.max(t,.4));let g=performance.now(),w=g+2;for(;performance.now()<w;);performance.now()===g&&(e.push("frozen-performance-now"),t=Math.max(t,.6));let _=Date.now(),q=performance.now(),y=Date.now();Math.abs(y-_-(performance.now()-q))>100&&(e.push("timing-inconsistency"),t=Math.max(t,.5));let W=e.length>0;return this.createResult(W,{anomalies:e,timings:{domContentLoaded:r,domComplete:c,loadComplete:a,dnsLookup:p,tcpConnection:d,serverResponse:u,domProcessing:l}},t)}_analyzeNavigationTiming(e){let t=[],i=0,n=e.domContentLoadedEventEnd,s=e.loadEventEnd,r=e.domainLookupEnd-e.domainLookupStart,c=e.responseEnd-e.requestStart;n>0&&n<10&&(t.push("instant-dom-content-loaded"),i=Math.max(i,.7)),r===0&&c===0&&(t.push("zero-network-timing"),i=Math.max(i,.4));let a=t.length>0;return this.createResult(a,{anomalies:t,timings:{domContentLoaded:n,loadComplete:s,dnsLookup:r,serverResponse:c}},i)}};o(H,"id","page-load"),o(H,"category","timing"),o(H,"weight",.5),o(H,"description","Detects suspicious page load timing");var A=class extends m{constructor(e={}){super(e),this._domContentLoadedTime=null,this._documentReadyState=document.readyState,this._captureTime=performance.now(),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",()=>{this._domContentLoadedTime=performance.now()})}async detect(){let e=[],t=0,i=performance.now(),n=document.readyState,s=0,r=0,c=0;if(performance.getEntriesByType){let p=performance.getEntriesByType("resource");s=p.length;for(let d of p)r+=d.duration,d.initiatorType==="script"&&d.name.startsWith("http")&&c++}s===0&&n==="complete"&&(e.push("no-resources-loaded"),t=Math.max(t,.4)),this._domContentLoadedTime&&this._domContentLoadedTime<50&&s===0&&(e.push("instant-ready-no-resources"),t=Math.max(t,.6)),document.hidden&&this._documentReadyState==="loading"&&(e.push("hidden-at-load"),t=Math.max(t,.3)),typeof document.visibilityState>"u"&&(e.push("no-visibility-api"),t=Math.max(t,.4));try{let p=`__bdt_${Math.random().toString(36).slice(2)}`,d=performance.now(),u=document.createElement("div");u.id=p,document.body.appendChild(u);let l=performance.now();document.body.removeChild(u);let h=performance.now(),g=l-d,w=h-l;g===0&&w===0&&(e.push("instant-dom-operations"),t=Math.max(t,.5))}catch{document.body||(e.push("no-document-body"),t=Math.max(t,.4))}if(typeof MutationObserver>"u"&&(e.push("no-mutation-observer"),t=Math.max(t,.5)),typeof requestAnimationFrame>"u"&&(e.push("no-request-animation-frame"),t=Math.max(t,.5)),performance.getEntriesByType){let p=performance.getEntriesByType("paint");!p.find(l=>l.name==="first-paint")&&n==="complete"&&i>1e3&&(e.push("no-first-paint"),t=Math.max(t,.4)),!p.find(l=>l.name==="first-contentful-paint")&&n==="complete"&&i>1e3&&(e.push("no-first-contentful-paint"),t=Math.max(t,.4))}typeof IntersectionObserver>"u"&&(e.push("no-intersection-observer"),t=Math.max(t,.4));let a=e.length>0;return this.createResult(a,{anomalies:e,metrics:{readyState:n,resourceCount:s,externalScriptCount:c,domContentLoadedTime:this._domContentLoadedTime,documentHidden:document.hidden}},t)}};o(A,"id","dom-content-timing"),o(A,"category","timing"),o(A,"weight",.4),o(A,"description","Analyzes DOM content loaded timing patterns");var O=class extends m{async detect(){let e=[],t=0;window.__puppeteer_evaluation_script__&&(e.push("puppeteer-evaluation-script"),t=Math.max(t,1));let i=["__puppeteer_evaluation_script__","__puppeteer","puppeteer"];for(let a of i)a in window&&(e.push(`global-${a}`),t=Math.max(t,1));(navigator.userAgent||"").includes("HeadlessChrome")&&(e.push("headless-chrome-ua"),t=Math.max(t,.9)),(window.cdc_adoQpoasnfa76pfcZLmcfl_Array||window.cdc_adoQpoasnfa76pfcZLmcfl_Promise||window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol)&&(e.push("cdp-artifacts"),t=Math.max(t,1));try{window.eval.toString().includes("puppeteer")&&(e.push("eval-puppeteer"),t=Math.max(t,.9))}catch{}try{throw new Error("stack trace test")}catch(a){let p=a.stack||"";(p.includes("puppeteer")||p.includes("pptr"))&&(e.push("stack-trace-puppeteer"),t=Math.max(t,.8))}window.innerWidth===800&&window.innerHeight===600&&(e.push("default-viewport"),t=Math.max(t,.3));let s=["__zone_symbol__","__next","__webpack","__react","__REACT","__vite","__nuxt"];Object.keys(window).filter(a=>!a.startsWith("__")||typeof window[a]!="function"?!1:!s.some(p=>a.startsWith(p))).length>10&&(e.push("suspicious-bindings"),t=Math.max(t,.5));let c=e.length>0;return this.createResult(c,{indicators:e},t)}};o(O,"id","puppeteer"),o(O,"category","automation"),o(O,"weight",1),o(O,"description","Detects Puppeteer automation artifacts");var B=class extends m{async detect(){let e=[],t=0;window.__playwright&&(e.push("playwright-namespace"),t=Math.max(t,1));let i=["__playwright","__pw_manual","__pwInitScripts","playwright"];for(let r of i)r in window&&(e.push(`global-${r}`),t=Math.max(t,1));window.__playwright__binding__&&(e.push("playwright-binding"),t=Math.max(t,1));let n=navigator.userAgent||"";(n.includes("Playwright")||n.includes("HeadlessChrome"))&&(e.push("playwright-ua-marker"),t=Math.max(t,n.includes("Playwright")?1:.7));try{Object.keys(window).filter(a=>a.startsWith("__pw")).length>0&&(e.push("pw-bindings"),t=Math.max(t,1))}catch{}typeof window.__pw_date_intercepted<"u"&&(e.push("date-interception"),t=Math.max(t,.9)),window.__pw_geolocation__&&(e.push("geolocation-mock"),t=Math.max(t,.9)),window.__pw_permissions__&&(e.push("permissions-override"),t=Math.max(t,.9)),window.__cdpSession__&&(e.push("cdp-session"),t=Math.max(t,.8));try{throw new Error("stack trace test")}catch(r){let c=r.stack||"";(c.includes("playwright")||c.includes("__pw"))&&(e.push("stack-trace-playwright"),t=Math.max(t,.8))}try{let c=new Date().toLocaleString();window.__pwTimezone__&&(e.push("timezone-mock"),t=Math.max(t,.8))}catch{}let s=e.length>0;return this.createResult(s,{indicators:e},t)}};o(B,"id","playwright"),o(B,"category","automation"),o(B,"weight",1),o(B,"description","Detects Playwright automation artifacts");var V=class extends m{async detect(){let e=[],t=0,i=["_selenium","callSelenium","_Selenium_IDE_Recorder","__selenium_evaluate","__selenium_unwrap","__webdriver_evaluate","__webdriver_unwrap","__webdriver_script_function","__webdriver_script_func","__fxdriver_evaluate","__fxdriver_unwrap","webdriver"];for(let a of i)a in window&&(e.push(`global-${a}`),t=Math.max(t,1));let n=["__webdriver_script_fn","__driver_evaluate","__webdriver_evaluate","__selenium_evaluate","__fxdriver_evaluate","__driver_unwrap","__webdriver_unwrap","__selenium_unwrap","__fxdriver_unwrap"];for(let a of n)a in document&&(e.push(`document-${a}`),t=Math.max(t,1));Object.keys(window).filter(a=>a.startsWith("$cdc_")||a.startsWith("$wdc_")||a.startsWith("$chrome_asyncScriptInfo")).length>0&&(e.push("chromedriver-variables"),t=Math.max(t,1)),(window.webdriverCallback||document.documentElement.getAttribute("webdriver"))&&(e.push("geckodriver-artifacts"),t=Math.max(t,1));try{let a=document.documentElement;(a.hasAttribute("webdriver")||a.getAttribute("selenium")||a.getAttribute("driver"))&&(e.push("document-webdriver-attr"),t=Math.max(t,1))}catch{}(window.selenium||window.sideex)&&(e.push("selenium-ide"),t=Math.max(t,1));try{let a=Object.getOwnPropertyDescriptor(Navigator.prototype,"webdriver");a&&a.get&&(a.get.toString().includes("[native code]")||(e.push("webdriver-getter-modified"),t=Math.max(t,.7)))}catch{}(window.domAutomation||window.domAutomationController)&&(e.push("dom-automation"),t=Math.max(t,1)),window.awesomium&&(e.push("awesomium"),t=Math.max(t,.9)),window.external&&window.external.toString().includes("Selenium")&&(e.push("external-selenium"),t=Math.max(t,1));let c=e.length>0;return this.createResult(c,{indicators:e},t)}};o(V,"id","selenium"),o(V,"category","automation"),o(V,"weight",1),o(V,"description","Detects Selenium WebDriver artifacts");var K=class extends m{async detect(){let e=[],t=0;window.callPhantom&&(e.push("callPhantom"),t=Math.max(t,1)),window._phantom&&(e.push("_phantom"),t=Math.max(t,1)),window.phantom&&(e.push("phantom"),t=Math.max(t,1));let i=navigator.userAgent||"";i.includes("PhantomJS")&&(e.push("phantomjs-ua"),t=Math.max(t,1)),window.__phantomas&&(e.push("phantomas"),t=Math.max(t,1)),window.__casper&&(e.push("casperjs"),t=Math.max(t,1)),window.casper&&(e.push("casper-global"),t=Math.max(t,1)),window.slimer&&(e.push("slimerjs"),t=Math.max(t,1)),window.__nightmare&&(e.push("nightmare"),t=Math.max(t,1)),window.nightmare&&(e.push("nightmare-global"),t=Math.max(t,1));try{let r=Function.prototype.toString.call(Function);(r.includes("phantom")||r.includes("Phantom"))&&(e.push("function-prototype-phantom"),t=Math.max(t,.8))}catch{}try{throw new Error("test")}catch(r){(r.stack||"").includes("phantom")&&(e.push("stack-trace-phantom"),t=Math.max(t,.9))}navigator.plugins&&navigator.plugins.length===0&&e.length>0&&(e.push("no-plugins-phantom"),t=Math.max(t,.5));let n=["__PHANTOM__","PHANTOM"];for(let r of n)r in window&&(e.push(`phantom-prop-${r.toLowerCase()}`),t=Math.max(t,.9));i.includes("QtWebKit")&&(e.push("qtwebkit"),t=Math.max(t,.7));let s=e.length>0;return this.createResult(s,{indicators:e},t)}};o(K,"id","phantomjs"),o(K,"category","automation"),o(K,"weight",1),o(K,"description","Detects PhantomJS automation artifacts");var Z={WebDriverSignal:v,HeadlessSignal:M,NavigatorAnomalySignal:b,PermissionsSignal:T,MouseMovementSignal:k,KeyboardPatternSignal:E,InteractionTimingSignal:C,ScrollBehaviorSignal:D,PluginsSignal:R,WebGLSignal:S,CanvasSignal:L,AudioContextSignal:P,ScreenSignal:I,PageLoadSignal:H,DOMContentTimingSignal:A,PuppeteerSignal:O,PlaywrightSignal:B,SeleniumSignal:V,PhantomJSSignal:K},J=[new v,new M,new b,new T,new R,new S,new L,new P,new I,new H,new A,new O,new B,new V,new K],tt=[new k,new E,new C,new D],lt=[...J,...tt];function X(f={}){let{includeInteractionSignals:e=!0,instantBotSignals:t=["webdriver","puppeteer","playwright","selenium","phantomjs"],...i}=f,s=(e?[v,M,b,T,R,S,L,P,I,H,A,O,B,V,K,k,E,C,D]:[v,M,b,T,R,S,L,P,I,H,A,O,B,V,K]).map(r=>new r);return new $({signals:s,instantBotSignals:t,...i})}async function Q(f={}){return X({includeInteractionSignals:!f.skipInteractionSignals}).detect(f)}async function et(){return Q({skipInteractionSignals:!0})}var ut={BotDetector:$,createDetector:X,detect:Q,detectInstant:et,Signal:m,Signals:Z,Verdict:U};return ht(dt);})();
3
+ const detector = createDetector();`)}};var y=class extends m{async detect(){if(navigator.webdriver===!0)return this.createResult(!0,{webdriver:!0},1);let e=Object.getOwnPropertyDescriptor(navigator,"webdriver");if(e){if(e.get)try{if(e.get.call(navigator)===!0)return this.createResult(!0,{webdriver:!0,source:"own-getter"},1);if(!e.get.toString().includes("[native code]"))return this.createResult(!0,{webdriver:"hidden",descriptor:{configurable:e.configurable}},.8)}catch{}else if(e.value===!0)return this.createResult(!0,{webdriver:!0,source:"own-property"},1)}try{let t=Object.getPrototypeOf(navigator),i=Object.getOwnPropertyDescriptor(t,"webdriver");if(i&&i.get&&i.get.call(navigator)===!0)return this.createResult(!0,{webdriver:!0,source:"prototype"},1)}catch{}return this.createResult(!1)}};o(y,"id","webdriver"),o(y,"category","environment"),o(y,"weight",1),o(y,"description","Detects navigator.webdriver automation flag");var M=class extends m{async detect(){let e=[],t=0,i=navigator.userAgent||"";i.includes("HeadlessChrome")&&(e.push("headless-ua"),t=Math.max(t,1)),i.includes("Chrome")&&!i.includes("Chromium")&&typeof window.chrome>"u"&&(e.push("missing-chrome-object"),t=Math.max(t,.6)),navigator.plugins&&navigator.plugins.length===0&&(e.push("no-plugins"),t=Math.max(t,.5)),(!navigator.languages||navigator.languages.length===0)&&(e.push("no-languages"),t=Math.max(t,.6)),window.outerWidth===0&&window.outerHeight===0&&(e.push("zero-outer-dimensions"),t=Math.max(t,.7)),typeof navigator.connection>"u"&&i.includes("Chrome")&&(e.push("missing-connection-api"),t=Math.max(t,.3));try{typeof Notification<"u"&&Notification.permission==="denied"&&window.outerWidth===0&&(e.push("notification-headless-pattern"),t=Math.max(t,.5))}catch{}(window.callPhantom||window._phantom)&&(e.push("phantomjs"),t=Math.max(t,1)),window.__nightmare&&(e.push("nightmare"),t=Math.max(t,1));let n=e.length>0;return e.length>=3&&(t=Math.min(1,t+.2)),this.createResult(n,{indicators:e},t)}};o(M,"id","headless"),o(M,"category","environment"),o(M,"weight",.8),o(M,"description","Detects headless browser indicators");var b=class extends m{async detect(){let e=[],t=0,i=0,n=navigator.userAgent||"",s=navigator.platform||"";i++,s.includes("Win")&&!n.includes("Windows")?(e.push("platform-ua-mismatch-windows"),t+=1):s.includes("Mac")&&!n.includes("Mac")?(e.push("platform-ua-mismatch-mac"),t+=1):s.includes("Linux")&&!n.includes("Linux")&&!n.includes("Android")&&(e.push("platform-ua-mismatch-linux"),t+=1),i++,!(n.includes("Chrome")&&!n.includes("Chromium"))&&(!s||s===""||s==="undefined")&&(e.push("empty-platform"),t+=1),i++,navigator.language&&navigator.languages&&(navigator.languages.includes(navigator.language)||(e.push("language-mismatch"),t+=.5)),i++,n.includes("Chrome")&&navigator.vendor!=="Google Inc."?(e.push("vendor-mismatch-chrome"),t+=.5):n.includes("Firefox")&&navigator.vendor!==""?(e.push("vendor-mismatch-firefox"),t+=.5):n.includes("Safari")&&!n.includes("Chrome")&&navigator.vendor!=="Apple Computer, Inc."&&(e.push("vendor-mismatch-safari"),t+=.5),i++,typeof navigator.hardwareConcurrency<"u"&&(navigator.hardwareConcurrency===0||navigator.hardwareConcurrency>128)&&(e.push("suspicious-hardware-concurrency"),t+=.5),i++,typeof navigator.deviceMemory<"u"&&(navigator.deviceMemory===0||navigator.deviceMemory>512)&&(e.push("suspicious-device-memory"),t+=.5),i++;let c=/Android|iPhone|iPad|iPod|Mobile/i.test(n),r=navigator.maxTouchPoints>0;!c&&navigator.maxTouchPoints>5&&(e.push("desktop-high-touch-points"),t+=.3),i++;try{let u=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");u&&u.get&&u.get.toString().includes("native code")===!1&&(e.push("spoofed-user-agent"),t+=1)}catch{}let p=e.length>0,d=Math.min(1,t/Math.max(1,i));return this.createResult(p,{anomalies:e},d)}};o(b,"id","navigator-anomaly"),o(b,"category","environment"),o(b,"weight",.7),o(b,"description","Detects navigator property inconsistencies");var T=class extends m{async detect(){let e=[];if(!navigator.permissions)return this.createResult(!1,{supported:!1},0);try{let n=await navigator.permissions.query({name:"notifications"});if(typeof Notification<"u"){let s=Notification.permission;(s==="granted"&&n.state!=="granted"||s==="denied"&&n.state!=="denied"||s==="default"&&n.state!=="prompt")&&e.push("notification-permission-mismatch")}try{(await navigator.permissions.query({name:"geolocation"})).state==="denied"&&window.outerWidth===0&&e.push("geo-denied-headless")}catch{}try{await navigator.permissions.query({name:"camera"})}catch(s){s.name==="TypeError"&&e.push("camera-permission-error")}}catch(n){n.name!=="TypeError"&&e.push("permissions-query-error")}let t=e.length>0,i=Math.min(1,e.length*.4);return this.createResult(t,{anomalies:e},i)}};o(T,"id","permissions"),o(T,"category","environment"),o(T,"weight",.5),o(T,"description","Detects Permissions API anomalies");var k=class extends m{constructor(e={}){super(e),this._movements=[],this._isTracking=!1,this._trackingDuration=Math.min(e.trackingDuration||2500,2500),this._minMovements=e.minMovements||5,this._boundHandler=null}startTracking(){this._isTracking||(this._movements=[],this._isTracking=!0,this._boundHandler=e=>{this._movements.push({x:e.clientX,y:e.clientY,t:performance.now()})},document.addEventListener("mousemove",this._boundHandler,{passive:!0}))}stopTracking(){this._isTracking&&(this._isTracking=!1,this._boundHandler&&(document.removeEventListener("mousemove",this._boundHandler),this._boundHandler=null))}async detect(){let e=[],t=0;this._movements.length===0&&(this.startTracking(),await new Promise(a=>setTimeout(a,this._trackingDuration)),this.stopTracking());let i=this._movements;if(i.length<this._minMovements)return e.push("no-mouse-movement"),t=Math.max(t,.6),this.createResult(!0,{anomalies:e,movements:i.length},t);let n=this._analyzeMovements(i);n.teleportCount>0&&(e.push("mouse-teleportation"),t=Math.max(t,.7)),n.linearPathRatio>.9&&(e.push("linear-path"),t=Math.max(t,.8)),n.velocityVariance<.01&&i.length>10&&(e.push("constant-velocity"),t=Math.max(t,.7)),n.accelerationChanges===0&&i.length>10&&(e.push("no-acceleration-variance"),t=Math.max(t,.6)),n.timingVariance<1&&i.length>10&&(e.push("robotic-timing"),t=Math.max(t,.8));let s=e.length>0;return this.createResult(s,{anomalies:e,movementCount:i.length,analysis:n},t)}_analyzeMovements(e){if(e.length<3)return{teleportCount:0,linearPathRatio:0,velocityVariance:0,accelerationChanges:0,timingVariance:0};let t=0,i=[],n=[],s=[];for(let l=1;l<e.length;l++){let h=e[l-1],g=e[l],w=g.x-h.x,x=g.y-h.y,_=g.t-h.t;if(_===0)continue;let q=Math.sqrt(w*w+x*x),v=q/_;i.push(v),n.push(Math.atan2(x,w)),s.push(_),q>300&&_<10&&t++}let a=i.reduce((l,h)=>l+h,0)/i.length,c=i.reduce((l,h)=>l+Math.pow(h-a,2),0)/i.length,r=0;if(n.length>1){let l=0;for(let h=1;h<n.length;h++)Math.abs(n[h]-n[h-1])<.1&&l++;r=l/(n.length-1)}let p=s.reduce((l,h)=>l+h,0)/s.length,d=s.reduce((l,h)=>l+Math.pow(h-p,2),0)/s.length,u=0;for(let l=1;l<i.length;l++)(i[l]-i[l-1])*(i[l-1]-(i[l-2]||0))<0&&u++;return{teleportCount:t,linearPathRatio:r,velocityVariance:c,accelerationChanges:u,timingVariance:d}}reset(){super.reset(),this.stopTracking(),this._movements=[]}};o(k,"id","mouse-movement"),o(k,"category","behavior"),o(k,"weight",.9),o(k,"description","Detects non-human mouse movement patterns"),o(k,"requiresInteraction",!0);var E=class extends m{constructor(e={}){super(e),this._keystrokes=[],this._isTracking=!1,this._trackingDuration=Math.min(e.trackingDuration||2500,2500),this._minKeystrokes=e.minKeystrokes||10,this._boundKeydownHandler=null,this._boundKeyupHandler=null}startTracking(){this._isTracking||(this._keystrokes=[],this._isTracking=!0,this._boundKeydownHandler=e=>{this._keystrokes.push({type:"down",key:e.key,code:e.code,t:performance.now()})},this._boundKeyupHandler=e=>{this._keystrokes.push({type:"up",key:e.key,code:e.code,t:performance.now()})},document.addEventListener("keydown",this._boundKeydownHandler,{passive:!0}),document.addEventListener("keyup",this._boundKeyupHandler,{passive:!0}))}stopTracking(){this._isTracking&&(this._isTracking=!1,this._boundKeydownHandler&&(document.removeEventListener("keydown",this._boundKeydownHandler),this._boundKeydownHandler=null),this._boundKeyupHandler&&(document.removeEventListener("keyup",this._boundKeyupHandler),this._boundKeyupHandler=null))}async detect(){let e=[],t=0;this._keystrokes.length===0&&(this.startTracking(),await new Promise(c=>setTimeout(c,this._trackingDuration)),this.stopTracking());let i=this._keystrokes,n=i.filter(c=>c.type==="down");if(n.length<this._minKeystrokes)return this.createResult(!1,{reason:"insufficient-data",keystrokes:n.length},0);let s=this._analyzeKeystrokes(i);s.avgInterKeystrokeTime<50&&n.length>20&&(e.push("inhuman-speed"),t=Math.max(t,.9)),s.timingVariance<5&&n.length>15&&(e.push("robotic-timing"),t=Math.max(t,.8)),s.missingKeyups>n.length*.5&&(e.push("missing-keyups"),t=Math.max(t,.7)),s.holdTimeVariance<2&&s.holdTimes.length>10&&(e.push("constant-hold-time"),t=Math.max(t,.6)),s.sequentialKeys>n.length*.8&&n.length>10&&(e.push("sequential-input"),t=Math.max(t,.5)),s.rhythmScore<.1&&n.length>20&&(e.push("no-rhythm-variation"),t=Math.max(t,.6));let a=e.length>0;return this.createResult(a,{anomalies:e,keystrokeCount:n.length,analysis:s},t)}_analyzeKeystrokes(e){let t=e.filter(h=>h.type==="down"),i=e.filter(h=>h.type==="up");if(t.length<2)return{avgInterKeystrokeTime:1/0,timingVariance:1/0,missingKeyups:0,holdTimeVariance:1/0,holdTimes:[],sequentialKeys:0,rhythmScore:1};let n=[];for(let h=1;h<t.length;h++)n.push(t[h].t-t[h-1].t);let s=n.reduce((h,g)=>h+g,0)/n.length,a=n.reduce((h,g)=>h+Math.pow(g-s,2),0)/n.length,c=[];for(let h of t){let g=i.find(w=>w.key===h.key&&w.t>h.t);g&&c.push(g.t-h.t)}let r=c.length>0?c.reduce((h,g)=>h+g,0)/c.length:0,p=c.length>0?c.reduce((h,g)=>h+Math.pow(g-r,2),0)/c.length:1/0,d=t.length-c.length,u=0;for(let h=1;h<t.length;h++){let g=t[h-1].key.charCodeAt(0),w=t[h].key.charCodeAt(0);Math.abs(w-g)===1&&u++}let l=0;if(n.length>5){let h=[...n].sort((x,_)=>x-_),g=h[Math.floor(h.length/2)];l=n.filter(x=>Math.abs(x-g)>g*.3).length/n.length}return{avgInterKeystrokeTime:s,timingVariance:a,missingKeyups:d,holdTimeVariance:p,holdTimes:c,sequentialKeys:u,rhythmScore:l}}reset(){super.reset(),this.stopTracking(),this._keystrokes=[]}};o(E,"id","keyboard-pattern"),o(E,"category","behavior"),o(E,"weight",.8),o(E,"description","Detects non-human keystroke patterns"),o(E,"requiresInteraction",!0);var C=class extends m{constructor(e={}){super(e),this._pageLoadTime=performance.now(),this._firstInteractionTime=null,this._interactions=[],this._isTracking=!1,this._trackingDuration=e.trackingDuration||5e3,this._boundHandler=null}startTracking(){if(this._isTracking)return;this._interactions=[],this._isTracking=!0;let e=["click","mousedown","touchstart","keydown","scroll"];this._boundHandler=t=>{let i=performance.now();this._firstInteractionTime===null&&(this._firstInteractionTime=i),this._interactions.push({type:t.type,t:i,timeSinceLoad:i-this._pageLoadTime})};for(let t of e)document.addEventListener(t,this._boundHandler,{passive:!0,capture:!0})}stopTracking(){if(!this._isTracking)return;this._isTracking=!1;let e=["click","mousedown","touchstart","keydown","scroll"];if(this._boundHandler){for(let t of e)document.removeEventListener(t,this._boundHandler,{capture:!0});this._boundHandler=null}}async detect(){let e=[],t=0;!this._isTracking&&this._interactions.length===0&&(this.startTracking(),await new Promise(c=>setTimeout(c,this._trackingDuration)),this.stopTracking());let i=this._interactions;if(i.length===0)return this.createResult(!1,{reason:"no-interactions"},0);let n=i[0];if(n.timeSinceLoad<100?(e.push("instant-interaction"),t=Math.max(t,.9)):n.timeSinceLoad<300&&(e.push("very-fast-interaction"),t=Math.max(t,.6)),i.length>3){let c=[];for(let l=1;l<i.length;l++)c.push(i[l].t-i[l-1].t);let r=c.reduce((l,h)=>l+h,0)/c.length;c.reduce((l,h)=>l+Math.pow(h-r,2),0)/c.length<10&&i.length>5&&(e.push("robotic-intervals"),t=Math.max(t,.8));let d=50,u=0;for(let l of c)l<d&&u++;u>c.length*.7&&(e.push("burst-interactions"),t=Math.max(t,.7))}let s=i.map(c=>c.type).join(",");if(i.length>=6){let c=Math.floor(i.length/2),r=i.slice(0,c).map(d=>d.type).join(","),p=i.slice(c,c*2).map(d=>d.type).join(",");r===p&&r.length>0&&(e.push("repeated-sequence"),t=Math.max(t,.6))}let a=e.length>0;return this.createResult(a,{anomalies:e,interactionCount:i.length,timeToFirstInteraction:n.timeSinceLoad,firstInteractionType:n.type},t)}reset(){super.reset(),this.stopTracking(),this._pageLoadTime=performance.now(),this._firstInteractionTime=null,this._interactions=[]}};o(C,"id","interaction-timing"),o(C,"category","behavior"),o(C,"weight",.6),o(C,"description","Detects suspicious interaction timing"),o(C,"requiresInteraction",!0);var R=class extends m{constructor(e={}){super(e),this._scrollEvents=[],this._isTracking=!1,this._trackingDuration=Math.min(e.trackingDuration||2500,2500),this._boundHandler=null}startTracking(){this._isTracking||(this._scrollEvents=[],this._isTracking=!0,this._boundHandler=()=>{this._scrollEvents.push({scrollY:window.scrollY,scrollX:window.scrollX,t:performance.now()})},window.addEventListener("scroll",this._boundHandler,{passive:!0}))}stopTracking(){this._isTracking&&(this._isTracking=!1,this._boundHandler&&(window.removeEventListener("scroll",this._boundHandler),this._boundHandler=null))}async detect(){let e=[],t=0;this._scrollEvents.length===0&&(this.startTracking(),await new Promise(a=>setTimeout(a,this._trackingDuration)),this.stopTracking());let i=this._scrollEvents;if(i.length<3)return this.createResult(!1,{reason:"insufficient-scroll-data",scrollEvents:i.length},0);let n=this._analyzeScrollPatterns(i);n.instantJumps>0&&(e.push("instant-scroll-jumps"),t=Math.max(t,.7)),n.velocityVariance<.1&&i.length>10&&(e.push("constant-scroll-velocity"),t=Math.max(t,.6)),n.momentumEvents===0&&i.length>5&&(e.push("no-scroll-momentum"),t=Math.max(t,.5)),n.intervalVariance<5&&i.length>10&&(e.push("robotic-scroll-timing"),t=Math.max(t,.7)),n.scrollDirections===1&&Math.abs(n.totalScrollY)>1e3&&n.velocityVariance<1&&(e.push("one-dimensional-scroll"),t=Math.max(t,.4)),n.exactPositionScrolls>2&&(e.push("exact-position-scrolls"),t=Math.max(t,.6));let s=e.length>0;return this.createResult(s,{anomalies:e,scrollEventCount:i.length,analysis:n},t)}_analyzeScrollPatterns(e){if(e.length<2)return{instantJumps:0,velocityVariance:0,momentumEvents:0,intervalVariance:0,scrollDirections:0,totalScrollY:0,exactPositionScrolls:0};let t=0,i=0,n=[],s=[],a=!1,c=!1,r=0,p=[0,100,200,300,400,500,600,800,1e3];for(let x=1;x<e.length;x++){let _=e[x-1],q=e[x],v=q.scrollY-_.scrollY,W=q.scrollX-_.scrollX,z=q.t-_.t;if(s.push(z),Math.abs(v)>0&&(a=!0),Math.abs(W)>0&&(c=!0),z===0)continue;let j=Math.sqrt(v*v+W*W)/z;if(n.push(j),Math.abs(v)+Math.abs(W)>200&&z<20&&t++,x>1&&n.length>1){let nt=n[n.length-2];j<nt*.9&&j>0&&i++}p.includes(Math.round(q.scrollY))&&r++}let d=n.length>0?n.reduce((x,_)=>x+_,0)/n.length:0,u=n.length>0?n.reduce((x,_)=>x+Math.pow(_-d,2),0)/n.length:0,l=s.reduce((x,_)=>x+_,0)/s.length,h=s.reduce((x,_)=>x+Math.pow(_-l,2),0)/s.length,g=0;a&&g++,c&&g++;let w=e[e.length-1].scrollY-e[0].scrollY;return{instantJumps:t,velocityVariance:u,momentumEvents:i,intervalVariance:h,scrollDirections:g,totalScrollY:w,exactPositionScrolls:r}}reset(){super.reset(),this.stopTracking(),this._scrollEvents=[]}};o(R,"id","scroll-behavior"),o(R,"category","behavior"),o(R,"weight",.5),o(R,"description","Detects programmatic scroll patterns"),o(R,"requiresInteraction",!0);var D=class extends m{async detect(){let e=[],t=0,i=navigator.plugins,n=navigator.mimeTypes;if(!i)return e.push("no-plugins-object"),t=Math.max(t,.6),this.createResult(!0,{anomalies:e},t);i.length===0&&(e.push("empty-plugins"),t=Math.max(t,.5));let s=navigator.userAgent||"";if(s.includes("Chrome")&&!s.includes("Chromium")&&!Array.from(i).some(p=>p.name.includes("PDF")||p.name.includes("Chromium PDF"))&&i.length===0&&(e.push("chrome-missing-pdf-plugin"),t=Math.max(t,.4)),i.length>0&&n){let r=0;for(let p=0;p<i.length;p++)r+=i[p].length||0;n.length===0&&r>0&&(e.push("mimetypes-mismatch"),t=Math.max(t,.5))}if(i.length>1){let r=Array.from(i).map(d=>d.name);new Set(r).size<r.length&&(e.push("duplicate-plugins"),t=Math.max(t,.6))}try{let r=Object.getOwnPropertyDescriptor(Navigator.prototype,"plugins");r&&r.get&&(r.get.toString().includes("[native code]")||(e.push("plugins-getter-overridden"),t=Math.max(t,.7)))}catch{}!/Android|iPhone|iPad|iPod|Mobile/i.test(s)&&i.length===1&&(e.push("minimal-plugins"),t=Math.max(t,.3));let c=e.length>0;return this.createResult(c,{anomalies:e,pluginCount:i.length,mimeTypeCount:(n==null?void 0:n.length)||0},t)}};o(D,"id","plugins"),o(D,"category","fingerprint"),o(D,"weight",.6),o(D,"description","Detects browser plugin anomalies");var S=class extends m{async detect(){let e=[],t=0,i=document.createElement("canvas"),n=null;try{n=i.getContext("webgl")||i.getContext("experimental-webgl")}catch{e.push("webgl-error"),t=Math.max(t,.5)}if(!n)return e.push("webgl-unavailable"),t=Math.max(t,.4),this.createResult(!0,{anomalies:e},t);let s=n.getExtension("WEBGL_debug_renderer_info"),a="",c="";s&&(a=n.getParameter(s.UNMASKED_VENDOR_WEBGL)||"",c=n.getParameter(s.UNMASKED_RENDERER_WEBGL)||""),!a&&!c&&(e.push("no-webgl-renderer-info"),t=Math.max(t,.6));let r=["swiftshader","llvmpipe","software","mesa","google swiftshader","vmware","virtualbox"],p=c.toLowerCase();for(let w of r)if(p.includes(w)){e.push(`suspicious-renderer-${w.replace(/\s+/g,"-")}`),t=Math.max(t,.7);break}a&&c&&(p.includes("nvidia")&&!a.toLowerCase().includes("nvidia")&&(e.push("vendor-renderer-mismatch"),t=Math.max(t,.6)),(p.includes("amd")||p.includes("radeon"))&&!a.toLowerCase().includes("amd")&&!a.toLowerCase().includes("ati")&&(e.push("vendor-renderer-mismatch"),t=Math.max(t,.6)));let d=n.getSupportedExtensions()||[];d.length<5&&(e.push("few-webgl-extensions"),t=Math.max(t,.4));let u=n.getParameter(n.MAX_TEXTURE_SIZE),l=n.getParameter(n.MAX_VIEWPORT_DIMS);(u<1024||u>65536)&&(e.push("unrealistic-max-texture"),t=Math.max(t,.5));try{n.clearColor(0,0,0,1),n.clear(n.COLOR_BUFFER_BIT);let w=new Uint8Array(4);n.readPixels(0,0,1,1,n.RGBA,n.UNSIGNED_BYTE,w),w[3]!==255&&(e.push("webgl-render-failure"),t=Math.max(t,.6))}catch{e.push("webgl-render-error"),t=Math.max(t,.5)}let h=n.getExtension("WEBGL_lose_context");h&&h.loseContext();let g=e.length>0;return this.createResult(g,{anomalies:e,vendor:a,renderer:c,extensionCount:d.length,maxTextureSize:u},t)}};o(S,"id","webgl"),o(S,"category","fingerprint"),o(S,"weight",.7),o(S,"description","Detects WebGL rendering anomalies");var L=class extends m{async detect(){let e=[],t=0;try{let n=document.createElement("canvas");n.width=200,n.height=50;let s=n.getContext("2d");if(!s)return e.push("canvas-context-unavailable"),t=Math.max(t,.5),this.createResult(!0,{anomalies:e},t);s.textBaseline="alphabetic",s.font="14px Arial",s.fillStyle="#f60",s.fillRect(0,0,200,50),s.fillStyle="#069",s.fillText("Bot Detection Test \u{1F916}",2,15),s.fillStyle="rgba(102, 204, 0, 0.7)",s.fillText("Canvas Fingerprint",4,30),s.beginPath(),s.arc(100,25,10,0,Math.PI*2,!0),s.closePath(),s.fill();let a=n.toDataURL();s.clearRect(0,0,200,50),s.fillStyle="#f60",s.fillRect(0,0,200,50),s.fillStyle="#069",s.fillText("Bot Detection Test \u{1F916}",2,15),s.fillStyle="rgba(102, 204, 0, 0.7)",s.fillText("Canvas Fingerprint",4,30),s.beginPath(),s.arc(100,25,10,0,Math.PI*2,!0),s.closePath(),s.fill();let c=n.toDataURL();a!==c&&(e.push("canvas-randomized"),t=Math.max(t,.6)),a.length<1e3&&(e.push("canvas-possibly-blank"),t=Math.max(t,.4));let r=document.createElement("canvas");r.width=200,r.height=50;let p=r.toDataURL();a===p&&(e.push("canvas-rendering-blocked"),t=Math.max(t,.7));try{n.toDataURL.toString().includes("[native code]")||(e.push("toDataURL-overridden"),t=Math.max(t,.8))}catch{}let u=s.getImageData(0,0,200,50).data,l=!0,h=[u[0],u[1],u[2],u[3]];for(let g=4;g<u.length;g+=4)if(u[g]!==h[0]||u[g+1]!==h[1]||u[g+2]!==h[2]){l=!1;break}l&&(e.push("uniform-pixel-data"),t=Math.max(t,.6))}catch{e.push("canvas-error"),t=Math.max(t,.4)}let i=e.length>0;return this.createResult(i,{anomalies:e},t)}};o(L,"id","canvas"),o(L,"category","fingerprint"),o(L,"weight",.5),o(L,"description","Detects canvas fingerprint anomalies");var P=class extends m{async detect(){let e=[],t=0,i=window.AudioContext||window.webkitAudioContext;if(!i)return e.push("audio-context-unavailable"),t=Math.max(t,.4),this.createResult(!0,{anomalies:e},t);let n=null,s=null,a=null;try{n=new i;let r=n.sampleRate;if(r!==44100&&r!==48e3&&r!==96e3&&(e.push("unusual-sample-rate"),t=Math.max(t,.3)),s=n.createOscillator(),a=n.createAnalyser(),!s||!a)e.push("audio-nodes-unavailable"),t=Math.max(t,.5);else{let d=a.fftSize,u=n.destination;(!u||u.maxChannelCount===0)&&(e.push("no-audio-destination"),t=Math.max(t,.6)),u&&u.maxChannelCount<2&&(e.push("mono-audio-only"),t=Math.max(t,.3))}try{i.toString().includes("[native code]")||(e.push("audio-context-overridden"),t=Math.max(t,.7))}catch{}try{if(n.state==="suspended"&&await n.resume().catch(()=>{}),n.state==="running"){let d=n.createOscillator(),u=n.createGain(),l=n.createScriptProcessor?n.createScriptProcessor(4096,1,1):null;l&&(d.type="triangle",d.frequency.value=1e4,u.gain.value=0,d.connect(u),u.connect(l),l.connect(n.destination),d.start(0),await new Promise(h=>setTimeout(h,50)),d.stop(),d.disconnect(),u.disconnect(),l.disconnect())}}catch{e.push("audio-fingerprint-blocked"),t=Math.max(t,.4)}window.OfflineAudioContext||window.webkitOfflineAudioContext||(e.push("offline-audio-context-unavailable"),t=Math.max(t,.3))}catch{e.push("audio-context-error"),t=Math.max(t,.4)}finally{if(s)try{s.disconnect()}catch{}if(a)try{a.disconnect()}catch{}if(n)try{n.close()}catch{}}let c=e.length>0;return this.createResult(c,{anomalies:e},t)}};o(P,"id","audio-context"),o(P,"category","fingerprint"),o(P,"weight",.5),o(P,"description","Detects AudioContext anomalies");var I=class extends m{async detect(){let e=[],t=0,i=window.screen;if(!i)return e.push("no-screen-object"),t=Math.max(t,.6),this.createResult(!0,{anomalies:e},t);let n=i.width,s=i.height,a=i.availWidth,c=i.availHeight,r=i.colorDepth,p=i.pixelDepth,d=window.outerWidth,u=window.outerHeight,l=window.innerWidth,h=window.innerHeight;(d===0||u===0)&&(e.push("zero-outer-dimensions"),t=Math.max(t,.8)),(l===0||h===0)&&(e.push("zero-inner-dimensions"),t=Math.max(t,.7));let g=navigator.userAgent||"";!/Android|iPhone|iPad|iPod|Mobile/i.test(g)&&(n<640||s<480)&&(e.push("very-small-screen"),t=Math.max(t,.5)),(n>7680||s>4320)&&(e.push("unrealistic-screen-size"),t=Math.max(t,.4));let x=[{w:800,h:600},{w:1024,h:768},{w:1920,h:1080}];for(let v of x)if(n===v.w&&s===v.h&&d===v.w&&u===v.h){e.push("headless-default-dimensions"),t=Math.max(t,.5);break}(a>n||c>s)&&(e.push("available-exceeds-total"),t=Math.max(t,.7)),(d>n||u>s)&&(e.push("window-exceeds-screen"),t=Math.max(t,.6)),r!==24&&r!==32&&r!==30&&r!==48&&(e.push("unusual-color-depth"),t=Math.max(t,.3)),r!==p&&(e.push("depth-mismatch"),t=Math.max(t,.3));let _=window.devicePixelRatio;if(_===0||_===void 0?(e.push("missing-device-pixel-ratio"),t=Math.max(t,.5)):(_<.5||_>5)&&(e.push("unusual-device-pixel-ratio"),t=Math.max(t,.4)),i.orientation){let v=i.orientation.type,W=i.orientation.angle;v.includes("landscape")&&n<s&&(e.push("orientation-dimension-mismatch"),t=Math.max(t,.4)),v.includes("portrait")&&n>s&&(e.push("orientation-dimension-mismatch"),t=Math.max(t,.4))}l===d&&h===u&&d>0&&u>0&&(e.push("no-browser-chrome"),t=Math.max(t,.5));let q=e.length>0;return this.createResult(q,{anomalies:e,dimensions:{screen:{width:n,height:s},available:{width:a,height:c},window:{outer:{width:d,height:u},inner:{width:l,height:h}},colorDepth:r,devicePixelRatio:_}},t)}};o(I,"id","screen"),o(I,"category","fingerprint"),o(I,"weight",.4),o(I,"description","Detects unusual screen dimensions");var H=class extends m{async detect(){let e=[],t=0;if(!window.performance||!performance.timing){if(performance.getEntriesByType){let z=performance.getEntriesByType("navigation");if(z.length>0)return this._analyzeNavigationTiming(z[0])}return e.push("no-performance-api"),t=Math.max(t,.3),this.createResult(!0,{anomalies:e},t)}let i=performance.timing,n=i.navigationStart,s=(z,j)=>z===0||j===0?null:z-j,a=s(i.domContentLoadedEventEnd,n),c=s(i.domComplete,n),r=s(i.loadEventEnd,n),p=s(i.domainLookupEnd,i.domainLookupStart),d=s(i.connectEnd,i.connectStart),u=s(i.responseEnd,i.requestStart),l=s(i.domComplete,i.domLoading);a!==null&&a>0&&a<10&&(e.push("instant-dom-content-loaded"),t=Math.max(t,.7)),p===0&&d===0&&u!==null&&u<5&&(e.push("zero-network-timing"),t=Math.max(t,.4)),(a!==null&&a<0||c!==null&&c<0||r!==null&&r<0)&&(e.push("negative-timing"),t=Math.max(t,.8)),i.domContentLoadedEventEnd>0&&i.loadEventEnd>0&&i.domContentLoadedEventEnd>i.loadEventEnd&&(e.push("timing-order-violation"),t=Math.max(t,.7)),l!==null&&l>3e4&&(e.push("excessive-dom-processing"),t=Math.max(t,.3));let h=i.domContentLoadedEventStart-i.responseEnd;i.responseEnd>0&&i.domContentLoadedEventStart>0&&h>0&&h<5&&(e.push("instant-script-execution"),t=Math.max(t,.4));let g=performance.now(),w=g+2;for(;performance.now()<w;);performance.now()===g&&(e.push("frozen-performance-now"),t=Math.max(t,.6));let _=Date.now(),q=performance.now(),v=Date.now();Math.abs(v-_-(performance.now()-q))>100&&(e.push("timing-inconsistency"),t=Math.max(t,.5));let W=e.length>0;return this.createResult(W,{anomalies:e,timings:{domContentLoaded:a,domComplete:c,loadComplete:r,dnsLookup:p,tcpConnection:d,serverResponse:u,domProcessing:l}},t)}_analyzeNavigationTiming(e){let t=[],i=0,n=e.domContentLoadedEventEnd,s=e.loadEventEnd,a=e.domainLookupEnd-e.domainLookupStart,c=e.responseEnd-e.requestStart;n>0&&n<10&&(t.push("instant-dom-content-loaded"),i=Math.max(i,.7)),a===0&&c===0&&(t.push("zero-network-timing"),i=Math.max(i,.4));let r=t.length>0;return this.createResult(r,{anomalies:t,timings:{domContentLoaded:n,loadComplete:s,dnsLookup:a,serverResponse:c}},i)}};o(H,"id","page-load"),o(H,"category","timing"),o(H,"weight",.5),o(H,"description","Detects suspicious page load timing");var A=class extends m{constructor(e={}){super(e),this._domContentLoadedTime=null,this._documentReadyState=document.readyState,this._captureTime=performance.now(),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",()=>{this._domContentLoadedTime=performance.now()})}async detect(){let e=[],t=0,i=performance.now(),n=document.readyState,s=0,a=0,c=0;if(performance.getEntriesByType){let p=performance.getEntriesByType("resource");s=p.length;for(let d of p)a+=d.duration,d.initiatorType==="script"&&d.name.startsWith("http")&&c++}s===0&&n==="complete"&&(e.push("no-resources-loaded"),t=Math.max(t,.4)),this._domContentLoadedTime&&this._domContentLoadedTime<50&&s===0&&(e.push("instant-ready-no-resources"),t=Math.max(t,.6)),document.hidden&&this._documentReadyState==="loading"&&(e.push("hidden-at-load"),t=Math.max(t,.3)),typeof document.visibilityState>"u"&&(e.push("no-visibility-api"),t=Math.max(t,.4));try{let p=`__bdt_${Math.random().toString(36).slice(2)}`,d=performance.now(),u=document.createElement("div");u.id=p,document.body.appendChild(u);let l=performance.now();document.body.removeChild(u);let h=performance.now(),g=l-d,w=h-l;g===0&&w===0&&(e.push("instant-dom-operations"),t=Math.max(t,.5))}catch{document.body||(e.push("no-document-body"),t=Math.max(t,.4))}if(typeof MutationObserver>"u"&&(e.push("no-mutation-observer"),t=Math.max(t,.5)),typeof requestAnimationFrame>"u"&&(e.push("no-request-animation-frame"),t=Math.max(t,.5)),performance.getEntriesByType){let p=performance.getEntriesByType("paint");!p.find(l=>l.name==="first-paint")&&n==="complete"&&i>1e3&&(e.push("no-first-paint"),t=Math.max(t,.4)),!p.find(l=>l.name==="first-contentful-paint")&&n==="complete"&&i>1e3&&(e.push("no-first-contentful-paint"),t=Math.max(t,.4))}typeof IntersectionObserver>"u"&&(e.push("no-intersection-observer"),t=Math.max(t,.4));let r=e.length>0;return this.createResult(r,{anomalies:e,metrics:{readyState:n,resourceCount:s,externalScriptCount:c,domContentLoadedTime:this._domContentLoadedTime,documentHidden:document.hidden}},t)}};o(A,"id","dom-content-timing"),o(A,"category","timing"),o(A,"weight",.4),o(A,"description","Analyzes DOM content loaded timing patterns");var O=class extends m{async detect(){let e=[],t=0;window.__puppeteer_evaluation_script__&&(e.push("puppeteer-evaluation-script"),t=Math.max(t,1));let i=["__puppeteer_evaluation_script__","__puppeteer","puppeteer"];for(let r of i)r in window&&(e.push(`global-${r}`),t=Math.max(t,1));(navigator.userAgent||"").includes("HeadlessChrome")&&(e.push("headless-chrome-ua"),t=Math.max(t,.9)),(window.cdc_adoQpoasnfa76pfcZLmcfl_Array||window.cdc_adoQpoasnfa76pfcZLmcfl_Promise||window.cdc_adoQpoasnfa76pfcZLmcfl_Symbol)&&(e.push("cdp-artifacts"),t=Math.max(t,1));try{window.eval.toString().includes("puppeteer")&&(e.push("eval-puppeteer"),t=Math.max(t,.9))}catch{}try{throw new Error("stack trace test")}catch(r){let p=r.stack||"";(p.includes("puppeteer")||p.includes("pptr"))&&(e.push("stack-trace-puppeteer"),t=Math.max(t,.8))}window.innerWidth===800&&window.innerHeight===600&&(e.push("default-viewport"),t=Math.max(t,.3));let s=["__zone_symbol__","__next","__webpack","__react","__REACT","__vite","__nuxt"];Object.keys(window).filter(r=>!r.startsWith("__")||typeof window[r]!="function"?!1:!s.some(p=>r.startsWith(p))).length>10&&(e.push("suspicious-bindings"),t=Math.max(t,.5));let c=e.length>0;return this.createResult(c,{indicators:e},t)}};o(O,"id","puppeteer"),o(O,"category","automation"),o(O,"weight",1),o(O,"description","Detects Puppeteer automation artifacts");var B=class extends m{async detect(){let e=[],t=0;window.__playwright&&(e.push("playwright-namespace"),t=Math.max(t,1));let i=["__playwright","__pw_manual","__pwInitScripts","playwright"];for(let a of i)a in window&&(e.push(`global-${a}`),t=Math.max(t,1));window.__playwright__binding__&&(e.push("playwright-binding"),t=Math.max(t,1));let n=navigator.userAgent||"";(n.includes("Playwright")||n.includes("HeadlessChrome"))&&(e.push("playwright-ua-marker"),t=Math.max(t,n.includes("Playwright")?1:.7));try{Object.keys(window).filter(r=>r.startsWith("__pw")).length>0&&(e.push("pw-bindings"),t=Math.max(t,1))}catch{}typeof window.__pw_date_intercepted<"u"&&(e.push("date-interception"),t=Math.max(t,.9)),window.__pw_geolocation__&&(e.push("geolocation-mock"),t=Math.max(t,.9)),window.__pw_permissions__&&(e.push("permissions-override"),t=Math.max(t,.9)),window.__cdpSession__&&(e.push("cdp-session"),t=Math.max(t,.8));try{throw new Error("stack trace test")}catch(a){let c=a.stack||"";(c.includes("playwright")||c.includes("__pw"))&&(e.push("stack-trace-playwright"),t=Math.max(t,.8))}try{let c=new Date().toLocaleString();window.__pwTimezone__&&(e.push("timezone-mock"),t=Math.max(t,.8))}catch{}let s=e.length>0;return this.createResult(s,{indicators:e},t)}};o(B,"id","playwright"),o(B,"category","automation"),o(B,"weight",1),o(B,"description","Detects Playwright automation artifacts");var V=class extends m{async detect(){let e=[],t=0,i=["_selenium","callSelenium","_Selenium_IDE_Recorder","__selenium_evaluate","__selenium_unwrap","__webdriver_evaluate","__webdriver_unwrap","__webdriver_script_function","__webdriver_script_func","__fxdriver_evaluate","__fxdriver_unwrap","webdriver"];for(let r of i)r in window&&(e.push(`global-${r}`),t=Math.max(t,1));let n=["__webdriver_script_fn","__driver_evaluate","__webdriver_evaluate","__selenium_evaluate","__fxdriver_evaluate","__driver_unwrap","__webdriver_unwrap","__selenium_unwrap","__fxdriver_unwrap"];for(let r of n)r in document&&(e.push(`document-${r}`),t=Math.max(t,1));Object.keys(window).filter(r=>r.startsWith("$cdc_")||r.startsWith("$wdc_")||r.startsWith("$chrome_asyncScriptInfo")).length>0&&(e.push("chromedriver-variables"),t=Math.max(t,1)),(window.webdriverCallback||document.documentElement.getAttribute("webdriver"))&&(e.push("geckodriver-artifacts"),t=Math.max(t,1));try{let r=document.documentElement;(r.hasAttribute("webdriver")||r.getAttribute("selenium")||r.getAttribute("driver"))&&(e.push("document-webdriver-attr"),t=Math.max(t,1))}catch{}(window.selenium||window.sideex)&&(e.push("selenium-ide"),t=Math.max(t,1));try{let r=Object.getOwnPropertyDescriptor(Navigator.prototype,"webdriver");r&&r.get&&(r.get.toString().includes("[native code]")||(e.push("webdriver-getter-modified"),t=Math.max(t,.7)))}catch{}(window.domAutomation||window.domAutomationController)&&(e.push("dom-automation"),t=Math.max(t,1)),window.awesomium&&(e.push("awesomium"),t=Math.max(t,.9)),window.external&&window.external.toString().includes("Selenium")&&(e.push("external-selenium"),t=Math.max(t,1));let c=e.length>0;return this.createResult(c,{indicators:e},t)}};o(V,"id","selenium"),o(V,"category","automation"),o(V,"weight",1),o(V,"description","Detects Selenium WebDriver artifacts");var K=class extends m{async detect(){let e=[],t=0;window.callPhantom&&(e.push("callPhantom"),t=Math.max(t,1)),window._phantom&&(e.push("_phantom"),t=Math.max(t,1)),window.phantom&&(e.push("phantom"),t=Math.max(t,1));let i=navigator.userAgent||"";i.includes("PhantomJS")&&(e.push("phantomjs-ua"),t=Math.max(t,1)),window.__phantomas&&(e.push("phantomas"),t=Math.max(t,1)),window.__casper&&(e.push("casperjs"),t=Math.max(t,1)),window.casper&&(e.push("casper-global"),t=Math.max(t,1)),window.slimer&&(e.push("slimerjs"),t=Math.max(t,1)),window.__nightmare&&(e.push("nightmare"),t=Math.max(t,1)),window.nightmare&&(e.push("nightmare-global"),t=Math.max(t,1));try{let a=Function.prototype.toString.call(Function);(a.includes("phantom")||a.includes("Phantom"))&&(e.push("function-prototype-phantom"),t=Math.max(t,.8))}catch{}try{throw new Error("test")}catch(a){(a.stack||"").includes("phantom")&&(e.push("stack-trace-phantom"),t=Math.max(t,.9))}navigator.plugins&&navigator.plugins.length===0&&e.length>0&&(e.push("no-plugins-phantom"),t=Math.max(t,.5));let n=["__PHANTOM__","PHANTOM"];for(let a of n)a in window&&(e.push(`phantom-prop-${a.toLowerCase()}`),t=Math.max(t,.9));i.includes("QtWebKit")&&(e.push("qtwebkit"),t=Math.max(t,.7));let s=e.length>0;return this.createResult(s,{indicators:e},t)}};o(K,"id","phantomjs"),o(K,"category","automation"),o(K,"weight",1),o(K,"description","Detects PhantomJS automation artifacts");var Z={WebDriverSignal:y,HeadlessSignal:M,NavigatorAnomalySignal:b,PermissionsSignal:T,MouseMovementSignal:k,KeyboardPatternSignal:E,InteractionTimingSignal:C,ScrollBehaviorSignal:R,PluginsSignal:D,WebGLSignal:S,CanvasSignal:L,AudioContextSignal:P,ScreenSignal:I,PageLoadSignal:H,DOMContentTimingSignal:A,PuppeteerSignal:O,PlaywrightSignal:B,SeleniumSignal:V,PhantomJSSignal:K},J=[new y,new M,new b,new T,new D,new S,new L,new P,new I,new H,new A,new O,new B,new V,new K],tt=[new k,new E,new C,new R],lt=[...J,...tt];function X(f={}){let{includeInteractionSignals:e=!0,instantBotSignals:t=["webdriver","puppeteer","playwright","selenium","phantomjs"],...i}=f,s=(e?[y,M,b,T,D,S,L,P,I,H,A,O,B,V,K,k,E,C,R]:[y,M,b,T,D,S,L,P,I,H,A,O,B,V,K]).map(a=>new a);return new $({signals:s,instantBotSignals:t,...i})}async function Q(f={}){return X({includeInteractionSignals:!f.skipInteractionSignals}).detect(f)}async function et(){return Q({skipInteractionSignals:!0})}var ut={BotDetector:$,createDetector:X,detect:Q,detectInstant:et,Signal:m,Signals:Z,Verdict:U};return ht(dt);})();