1(()=>{var q=Object.defineProperty;var V=(i,e,t)=>e in i?q(i,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[e]=t;var s=(i,e,t)=>V(i,typeof e!="symbol"?e+"":e,t);var m=(i,e,t)=>new Promise((n,r)=>{var a=o=>{try{c(t.next(o))}catch(d){r(d)}},u=o=>{try{c(t.throw(o))}catch(d){r(d)}},c=o=>o.done?n(o.value):Promise.resolve(o.value).then(a,u);c((t=t.apply(i,e)).next())});var p=class{detect(){return navigator.webdriver===!0}};var v=class{detect(){try{if(Object.keys(window).filter(t=>t.startsWith("cdc_")).length>0)return"chromedriver"}catch(e){}return window._selenium||window.callSelenium||window.calledSelenium||window.__webdriver_evaluate||window.__webdriver_unwrapped||window.__webdriver_script_fn||window.__webdriver_script_function||window.__webdriver_script_func||window.__driver_evaluate||window.__driver_unwrapped||window.__fxdriver_evaluate||window.__fxdriver_unwrapped||window._Selenium_IDE_Recorder||window.$chrome_asyncScriptInfo||document.$cdc_asdjflasutopfhvcZLmcfl_||document.$chrome_asyncScriptInfo?"selenium":window.__playwright||window.__playwright_pages||window.__pw_manual?"playwright":window.__puppeteer_evaluation_script__?"puppeteer":window._phantom||window.callPhantom||window.__phantomas?"phantom":window.__nightmare?"nightmare":window.Cypress?"cypress":null}};var S=class S{detect(){let e=navigator.userAgent;return S.HEADLESS_PATTERNS.some(t=>t.test(e))}};s(S,"HEADLESS_PATTERNS",[/HeadlessChrome/i,/PhantomJS/i,/\bHeadless\b/i,/SlimerJS/i,/headless/i,/selenium/i,/webdriver/i,/puppeteer/i,/playwright/i,/cypress/i,/nodriver/i,/undetected/i,/bot/i,/crawl/i,/spider/i]);var b=S;var y=class{detectNoPlugins(){return navigator.plugins?navigator.plugins.length===0:!0}detectNoLanguages(){return navigator.languages?navigator.languages.length===0:!0}detectChromeRuntimeMissing(){let e=navigator.userAgent||"";if(!(/Chrome/.test(e)&&!/Chromium|Edg/.test(e)))return!1;if(!window.chrome)return!0;let n=typeof window.chrome.loadTimes=="function",r=typeof window.chrome.csi=="function";return!n&&!r}detectSuspiciousScreen(){try{let e=screen.colorDepth,t=screen.pixelDepth;return e===0||e<8||t===0||t<8||window.devicePixelRatio===0}catch(e){return!1}}detectNoBatteryAPI(){return typeof navigator.getBattery!="function"}detectNoConnectionAPI(){return!navigator.connection}};var w=class w{detect(){let e=this.getVendor(),t=this.getRenderer();if(!e||!t)return!1;let n=t.toLowerCase();return w.SUSPICIOUS_RENDERERS.some(r=>n.includes(r))}performRenderingTest(){let e=null;try{let t=document.createElement("canvas");if(t.width=150,t.height=150,e=t.getContext("webgl")||t.getContext("experimental-webgl"),!e)return{webgl_rendering_hash:null,webgl_rendering_noise:null,webgl_rendering_suspicious:!1};let n=this.getRenderer()||"",r=new Float32Array([-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1,-1]),a=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,a),e.bufferData(e.ARRAY_BUFFER,r,e.STATIC_DRAW);let u=e.createShader(e.VERTEX_SHADER);e.shaderSource(u,` 2 attribute vec3 position; 3 void main() { 4 gl_Position = vec4(position * 0.5, 1.0); 5 } 6 `),e.compileShader(u);let c=e.createShader(e.FRAGMENT_SHADER);e.shaderSource(c,` 7 precision mediump float; 8 void main() { 9 gl_FragColor = vec4(0.2, 0.5, 0.8, 1.0); 10 } 11 `),e.compileShader(c);let o=e.createProgram();e.attachShader(o,u),e.attachShader(o,c),e.linkProgram(o),e.useProgram(o);let d=e.getAttribLocation(o,"position");e.enableVertexAttribArray(d),e.vertexAttribPointer(d,3,e.FLOAT,!1,0,0),e.clearColor(0,0,0,1),e.clear(e.COLOR_BUFFER_BIT),e.drawArrays(e.TRIANGLES,0,6);let _=new Uint8Array(e.drawingBufferWidth*e.drawingBufferHeight*4);e.readPixels(0,0,e.drawingBufferWidth,e.drawingBufferHeight,e.RGBA,e.UNSIGNED_BYTE,_);let f=this._hashPixels(_.slice(0,1e3)),F=this._calculateNoiseRatio(_),M=w.HIGH_END_GPU_PATTERN.test(n),W=F>w.NOISE_THRESHOLD,G=M&&W;return e.deleteBuffer(a),e.deleteShader(u),e.deleteShader(c),e.deleteProgram(o),{webgl_rendering_hash:f,webgl_rendering_noise:parseFloat(F.toFixed(4)),webgl_rendering_suspicious:G}}catch(t){return{webgl_rendering_hash:null,webgl_rendering_noise:null,webgl_rendering_suspicious:!1}}finally{this._loseContext(e)}}_calculateNoiseRatio(e){let t=0;for(let n=0;n<e.length-4;n+=4)Math.abs(e[n]-e[n+4])>5&&t++;return t/(e.length/4)}_hashPixels(e){let t=0;for(let n=0;n<e.length;n++)t=(t<<5)-t+e[n],t=t|0;return t.toString(36)}_loseContext(e){if(e){try{let t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}catch(t){}try{e.canvas&&(e.canvas.width=0,e.canvas.height=0)}catch(t){}}}getVendor(){let e=null;try{let t=document.createElement("canvas");if(e=t.getContext("webgl")||t.getContext("experimental-webgl"),!e)return null;let n=e.getExtension("WEBGL_debug_renderer_info");return n?e.getParameter(n.UNMASKED_VENDOR_WEBGL):"unknown"}catch(t){return null}finally{this._loseContext(e)}}getRenderer(){let e=null;try{let t=document.createElement("canvas");if(e=t.getContext("webgl")||t.getContext("experimental-webgl"),!e)return null;let n=e.getExtension("WEBGL_debug_renderer_info");return n?e.getParameter(n.UNMASKED_RENDERER_WEBGL):"unknown"}catch(t){return null}finally{this._loseContext(e)}}};s(w,"SUSPICIOUS_RENDERERS",["swiftshader","llvmpipe","softpipe","mesa","software rasterizer","virtualbox","vmware"]),s(w,"HIGH_END_GPU_PATTERN",/nvi
11dia|geforce|rtx|gtx|radeon|rx\s/i),s(w,"NOISE_THRESHOLD",.1);var E=w;var R=class{detect(){return m(this,null,function*(){if(!navigator.permissions)return!1;try{let e=yield navigator.permissions.query({name:"notifications"});return!["granted","denied","prompt"].includes(e.state)}catch(e){return!0}})}};var A=class{detect(){return{cdp_stack_trace_leak:this.detectStackTraceLeak(),cdp_console_debug_leak:this.detectConsoleDebugLeak()}}detectStackTraceLeak(){try{let e=!1,t=new Error;return Object.defineProperty(t,"stack",{configurable:!1,enumerable:!1,get(){return e=!0,""}}),console.debug(t),e}catch(e){return!1}}detectConsoleDebugLeak(){try{let e=0,t={};return Object.defineProperty(t,"id",{get(){return e++,"test"}}),console.debug(t),e>1}catch(e){return!1}}};var k=class{detect(){return{no_outer_dimensions:this.detectNoOuterDimensions(),inner_equals_outer:this.detectInnerEqualsOuter()}}detectNoOuterDimensions(){try{let e=window.outerWidth,t=window.outerHeight;return typeof e!="number"||typeof t!="number"?!1:e===0||t===0}catch(e){return!1}}detectInnerEqualsOuter(){try{let e=window.outerWidth,t=window.outerHeight,n=window.innerWidth,r=window.innerHeight;return typeof e!="number"||typeof t!="number"||typeof n!="number"||typeof r!="number"||e===0||t===0?!1:n===e&&r===t}catch(e){return!1}}};var T=class{detect(){try{return!navigator.userAgentData||!navigator.userAgentData.brands?!1:navigator.userAgentData.brands.some(t=>!t||!t.brand?!1:t.brand.toLowerCase().includes("headless"))}catch(e){return!1}}};var x=class x{detect(){try{let e=document.createElement("canvas");e.width=200,e.height=50;let t=e.getContext("2d");if(!t)return{canvas_hash:null,canvas_suspicious:!0};t.textBaseline="top",t.font="14px Arial",t.fillStyle="#f60",t.fillRect(125,1,62,20),t.fillStyle="#069",t.fillText("HeadlessTest",2,15),t.fillStyle="rgba(102, 204, 0, 0.7)",t.fillText("HeadlessTest",4,17);let n=e.toDataURL(),r=this.generateHash(n),a=n.length<x.MIN_DATA_LENGTH;return{canvas_hash:r,canvas_suspicious:a}}catch(e){return{canvas_hash:null,canvas_suspicious:!0}}}generateHash(e){let t=0;for(let n=0;n<e.length;n++)t=(t<<5)-t+e.charCodeAt(n),t=t|0;return t.toString(16)}};s(x,"MIN_DATA_LENGTH",100);var C=x;var N=class N{detect(){let e=this.getSampleRate(),t=this.isSuspicious(e);return{audio_sample_rate:e,audio_suspicious:t}}getSampleRate(){let e=null;try{let t=window.AudioContext||window.webkitAudioContext;return t?(e=new t,e.sampleRate):null}catch(t){return null}finally{if(e)try{e.close()}catch(t){}}}isSuspicious(e){return e===null?!0:!N.STANDARD_SAMPLE_RATES.includes(e)}};s(N,"STANDARD_SAMPLE_RATES",[44100,48e3,96e3]);var L=N;var l=class l{detect(){try{let t=document.createElement("canvas").getContext("2d");if(!t)return{fonts_detected_count:0,fonts_suspicious:!0};let n=this.measureBaseFonts(t),r=this.countDetectedFonts(t,n);return{fonts_detected_count:r,fonts_suspicious:r<l.MIN_FONTS_THRESHOLD}}catch(e){return{fonts_detected_count:0,fonts_suspicious:!0}}}measureBaseFonts(e){let t={};return l.BASE_FONTS.forEach(n=>{e.font=`${l.TEST_SIZE} ${n}`,t[n]=e.measureText(l.TEST_STRING).width}),t}countDetectedFonts(e,t){let n=0;return l.TEST_FONTS.forEach(r=>{l.BASE_FONTS.some(u=>(e.font=`${l.TEST_SIZE} '${r}', ${u}`,e.measureText(l.TEST_STRING).width!==t[u]))&&n++}),n}};s(l,"BASE_FONTS",["monospace","sans-serif","serif"]),s(l,"TEST_FONTS",["Arial","Verdana","Times New Roman","Courier New","Georgia","Comic Sans MS","Trebuchet MS","Impact"]),s(l,"TEST_STRING","mmmmmmmmmmlli"),s(l,"TEST_SIZE","72px"),s(l,"MIN_FONTS_THRESHOLD",3);var D=l;var I=class{detect(){return{media_devices_available:this.detectMediaDevicesAvailable(),webrtc_available:this.detectWebRTCAvailable()}}detectMediaDevicesAvailable(){try{if(!navigator.mediaDevices)return!1;let e=typeof navigator.mediaDevices.enumerateDevices=="function",t=typeof navigator.mediaDevices.getUserMedia=="function";return e||t}catch(e){return!1}}detectWebRTCAvailable(){let e=null;try{let t=window.RTCPeerConnection||window.webkitRTCPeerConnection||window.mozRTCPeerConnection;return t?(e=new t,!0):!1}catch(t){return!1}finally{if(e)try{e.close()}catch(t){}}}};var P=class P{detect(){return m(this,null,function*(){if(typeof Worker=="undefined"||typeof Blob=="undefined")return{worker_ua_available:!1,worker_ua_mismatch:!1,worker_platform_mismatch:!1};try{return yield this._runWorkerCheck()}catch(e){return{worker_ua_available:!1,worker_ua_mismatch:!1,worker_platform_mismatch:!1}}})}_runWorkerCheck(){return new Promise(e=>{try{let t=` 12 self.onmessage = function() { 13 self.postMessage({ 14 userAgent: navigator.userAgent, 15 platform: navigator.platform 16 }); 17 }; 18 `,n=new Blob([t],{type:"application/javascript"}),r=URL.createObjectURL(n),a=new Worker(r),u=setTimeout(()=>{a.terminate(),URL.revokeObjectURL(r),e({worker_ua_available:!1,worker_ua_mismatch:!1,worker_platform_mismatch:!1})},P.WORKER_TIMEOUT);a.onmessage=c=>{clearTimeout(u),a.terminate(),URL.revokeObjectURL(r);let o=c.data.userAgent,d=navigator.userAgent,_=c.data.platform,f=navigator.platform;e({worker_ua_available:!0,worker_ua_mismatch:o!==d,worker_platform_mismatch:_!==f})},a.onerror=()=>{clearTimeout(u),a.terminate(),URL.revokeObjectURL(r),e({worker_ua_available:!1,worker_ua_mismatch:!1,worker_platform_mismatch:!1})},a.postMessage({})}catch(t){e({worker_ua_available:!1,worker_ua_mismatch:!1,worker_platform_mismatch:!1})}})}};s(P,"WORKER_TIMEOUT",1e3);var O=P;var h=class h{detect(){try{let e=document.createElement("canvas");e.width=h.CANVAS_SIZE,e.height=h.CANVAS_SIZE;let t=e.getContext("2d");if(!t)return{emoji_rendered:!1,emoji_os_mismatch:!1,emoji_hash:null};t.font="48px Arial",t.fillText(h.TEST_EMOJI,10,50);let n=t.getImageData(0,0,h.CANVAS_SIZE,h.CANVAS_SIZE),r=this._hashImageData(n.data),a=this._isEmojiRendered(n.data);return{emoji_rendered:a,emoji_os_mismatch:!a,emoji_hash:r}}catch(e){return{emoji_rendered:!1,emoji_os_mismatch:!1,emoji_hash:null}}}_isEmojiRendered(e){let t=e[0];for(let n=4;n<e.length;n+=4)if(e[n]!==t)return!0;return!1}_hashImageData(e){let t=0;for(let n=0;n<e.length;n+=100)t=(t<<5)-t+e[n],t=t|0;return t.toString(36)}};s(h,"TEST_EMOJI","\u{1F600}
18\u{1F3A8}\u{1F30D}"),s(h,"CANVAS_SIZE",100);var j=h;var g=class{constructor(){this._cachedResult=null,this._detectors={webdriver:new p,automationFramework:new v,userAgent:new b,browserFeatures:new y,webgl:new E,permissions:new R,cdpLeak:new A,windowDimensions:new k,clientHints:new T,canvasFingerprint:new C,audioContext:new L,font:new D,mediaDevices:new I,workerUA:new O,emojiRendering:new j}}detect(){return m(this,null,function*(){if(this._cachedResult)return this._cachedResult;let e=this._detectors.cdpLeak.detect(),t=this._detectors.windowDimensions.detect(),n=this._detectors.canvasFingerprint.detect(),r=this._detectors.audioContext.detect(),a=this._detectors.font.detect(),u=this._detectors.mediaDevices.detect(),c=this._detectors.emojiRendering.detect(),o=this._detectors.webgl.performRenderingTest(),[d,_]=yield Promise.all([this._detectors.permissions.detect(),this._detectors.workerUA.detect()]),f={webdriver:this._detectors.webdriver.detect(),automation_framework:this._detectors.automationFramework.detect(),headless_ua:this._detectors.userAgent.detect(),no_plugins:this._detectors.browserFeatures.detectNoPlugins(),no_languages:this._detectors.browserFeatures.detectNoLanguages(),chrome_runtime_missing:this._detectors.browserFeatures.detectChromeRuntimeMissing(),webgl_anomaly:this._detectors.webgl.detect(),permissions_inconsistent:d,cdp_stack_trace_leak:e.cdp_stack_trace_leak,cdp_console_debug_leak:e.cdp_console_debug_leak,no_outer_dimensions:t.no_outer_dimensions,inner_equals_outer:t.inner_equals_outer,client_hints_headless:this._detectors.clientHints.detect(),canvas_hash:n.canvas_hash,canvas_suspicious:n.canvas_suspicious,audio_sample_rate:r.audio_sample_rate,audio_suspicious:r.audio_suspicious,fonts_detected_count:a.fonts_detected_count,fonts_suspicious:a.fonts_suspicious,media_devices_available:u.media_devices_available,webrtc_available:u.webrtc_available,screen_suspicious:this._detectors.browserFeatures.detectSuspiciousScreen(),no_battery_api:this._detectors.browserFeatures.detectNoBatteryAPI(),no_connection_api:this._detectors.browserFeatures.detectNoConnectionAPI(),worker_ua_available:_.worker_ua_available,worker_ua_mismatch:_.worker_ua_mismatch,worker_platform_mismatch:_.worker_platform_mismatch,emoji_rendered:c.emoji_rendered,emoji_os_mismatch:c.emoji_os_mismatch,emoji_hash:c.emoji_hash,webgl_rendering_hash:o.webgl_rendering_hash,webgl_rendering_noise:o.webgl_rendering_noise,webgl_rendering_suspicious:o.webgl_rendering_suspicious,check_timestamp:Date.now()};return this._cachedResult=f,f})}clearCache(){this._cachedResult=null}getSimplifiedResult(){return m(this,null,function*(){let e=yield this.detect();return{webdriver:e.webdriver,automation_framework:e.automation_framework,headless_ua:e.headless_ua,no_plugins:e.no_plugins,no_languages:e.no_languages,chrome_runtime_missing:e.chrome_runtime_missing,webgl_anomaly:e.webgl_anomaly,permissions_inconsistent:e.permissions_inconsistent,cdp_stack_trace_leak:e.cdp_stack_trace_leak,cdp_console_debug_leak:e.cdp_console_debug_leak,no_outer_dimensions:e.no_outer_dimensions,inner_equals_outer:e.inner_equals_outer,client_hints_headless:e.client_hints_headless,canvas_hash:e.canvas_hash,canvas_suspicious:e.canvas_suspicious,audio_sample_rate:e.audio_sample_rate,audio_suspicious:e.audio_suspicious,fonts_detected_count:e.fonts_detected_count,fonts_suspicious:e.fonts_suspicious,media_devices_available:e.media_devices_available,webrtc_available:e.webrtc_available,screen_suspicious:e.screen_suspicious,no_battery_api:e.no_battery_api,no_connection_api:e.no_connection_api,worker_ua_available:e.worker_ua_available,worker_ua_mismatch:e.worker_ua_mismatch,worker_platform_mismatch:e.worker_platform_mismatch,emoji_rendered:e.emoji_rendered,emoji_os_mismatch:e.emoji_os_mismatch,emoji_hash:e.emoji_hash,webgl_rendering_hash:e.webgl_rendering_hash,webgl_rendering_noise:e.webgl_rendering_noise,webgl_rendering_suspicious:e.webgl_rendering_suspicious,check_timestamp:e.check_timestamp}})}getWebGLVendor(){return this._detectors.webgl.getVendor()}getWebGLRenderer(){return this._detectors.webgl.getRenderer()}};typeof window.ActiveLayer=="undefined"&&(window.ActiveLayer={});window.ActiveLayer.EnvironmentDetector=g;window.ActiveLayer.environmentDetector=window.ActiveLayer.environmentDetector||new g;window.ActiveLayer._environmentCleanup=window.ActiveLayer._environmentCleanup||[];function H(){return m(this,null,function*(){let e=yield window.ActiveLayer.environmentDetector.getSimplifiedResult(),t=JSON.stringify(e);document.querySelectorAll("input.activelayer-env-signals").forEach(function(r){r.value=t})})}function U(i){if(!i)return;let e=window.ActiveLayer.environmentDetector;if(e&&e._cachedResult){i.value=JSON.stringify({webdriver:e._cachedResult.webdriver,automation_framework:e._cachedResult.automation_framework,headless_ua:e._cachedResult.headless_ua,no_plugins:e._cachedResult.no_plugins,no_languages:e._cachedResult.no_languages,chrome_runtime_missing:e._cachedResult.chrome_runtime_missing,webgl_anomaly:e._cachedResult.webgl_anomaly,permissions_inconsistent:e._cachedResult.permissions_inconsistent,check_timestamp:e._cachedResult.check_timestamp});return}i.value=JSON.stringify({check_timestamp:Date.now()})}function B(){H();var i=function(t){let n=t.target;!n||n.tagName!=="FORM"||U(n.querySelector("input.activelayer-env-signals"))};document.addEventListener("submit",i,!0);var e=function(t){let n=t.target.closest('button[type="submit"], input[type="submit"]');if(!n)return;let r=n.closest("form");r&&U(r.querySelector("input.activelayer-env-signals"))};document.addEventListener("click",e,!0),window.ActiveLayer._environmentCleanup.push(function(){document.removeEventListener("submit",i,!0)},function(){document.removeEventListener("click",e,!0)})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",B):B();typeof jQuery!="undefined"&&jQuery(document).on("nfFormReady",function(){H()});if(typeof MutationObserver!="undefined"){let i=new MutationObserver(function(e){e.forEach(function(t){t.addedNodes.length&&t.addedNodes.forEac
18h(function(n){n.nodeType===1&&(n.querySelectorAll?n.querySelectorAll("input.activelayer-env-signals"):[]).length>0&&H()})})});i.observe(document.body||document.documentElement,{childList:!0,subtree:!0}),window.ActiveLayer._environmentCleanup.push(function(){i.disconnect()})}window.addEventListener("pagehide",function(){window.ActiveLayer&&window.ActiveLayer._environmentCleanup&&(window.ActiveLayer._environmentCleanup.forEach(function(i){i()}),window.ActiveLayer._environmentCleanup=[])});})(); 19/** 20 * WebdriverDetector - Detects navigator.webdriver property. 21 * 22 * The webdriver property is set to true when the browser is controlled 23 * by automation tools like Selenium, Puppeteer, or Playwright. 24 * 25 * @since 1.1.0 26 * @license GPL-2.0-or-later 27 */ 28/** 29 * AutomationFrameworkDetector - Detects automation framework globals. 30 * 31 * Checks for global variables and properties that automation frameworks 32 * inject into the page: Selenium, Puppeteer, Playwright, PhantomJS, Cypress. 33 * 34 * @since 1.1.0 35 * @license GPL-2.0-or-later 36 */ 37/** 38 * UserAgentDetector - Detects headless browser indicators in user agent. 39 * 40 * Checks for known headless browser signatures like "HeadlessChrome" 41 * or "PhantomJS" in the user agent string. 42 * 43 * @since 1.1.0 44 * @license GPL-2.0-or-later 45 */ 46/** 47 * BrowserFeaturesDetector - Detects missing/suspicious browser features. 48 * 49 * Checks for plugins, languages, and Chrome-specific features 50 * that are often missing or anomalous in headless browsers. 51 * 52 * @since 1.1.0 53 * @license GPL-2.0-or-later 54 */ 55/** 56 * WebGLDetector - Detects WebGL rendering anomalies. 57 * 58 * Headless Chrome often uses SwiftShader for software rendering, 59 * which can be detected via WebGL vendor/renderer strings. 60 * Also performs complex rendering tests to verify GPU consistency. 61 * 62 * @since 1.1.0 63 * @license GPL-2.0-or-later 64 */ 65/** 66 * PermissionsDetector - Checks for permissions API inconsistencies. 67 * 68 * Headless browsers sometimes throw errors or return inconsistent 69 * results when querying the Permissions API. 70 * 71 * @since 1.1.0 72 * @license GPL-2.0-or-later 73 */ 74/** 75 * CDPLeakDetector - Detects Chrome DevTools Protocol (CDP) leaks. 76 * 77 * When CDP's Runtime.enable is active (common in headless automation), 78 * certain JavaScript operations behave differently, creating detectable 79 * side effects that can identify automated browsers. 80 * 81 * @since 1.1.0 82 * @license GPL-2.0-or-later 83 */ 84/** 85 * WindowDimensionsDetector - Detects suspicious window dimension patterns. 86 * 87 * Headless browsers often have no outer dimensions (outerWidth/outerHeight = 0) 88 * or have inner dimensions that exactly equal outer dimensions (no browser chrome). 89 * 90 * @since 1.1.0 91 * @license GPL-2.0-or-later 92 */ 93/** 94 * ClientHintsDetector - Detects headless browsers via Client Hints API. 95 * 96 * The User-Agent Client Hints API provides information about the browser 97 * in a more structured way. Headless Chrome exposes "HeadlessChrome" in 98 * the brands array, which can be used for detection. 99 * 100 * @since 1.1.0 101 * @license GPL-2.0-or-later 102 */ 103/** 104 * CanvasFingerprintDetector - Generates canvas fingerprints and detects suspicious output. 105 * 106 * Headless browsers and bots often produce identical or minimal canvas output, 107 * which can be detected by generating a canvas fingerprint and checking for anomalies. 108 * 109 * @since 1.1.0 110 * @license GPL-2.0-or-later 111 */ 112/** 113 * AudioContextDetector - Detects suspicious AudioContext behavior. 114 * 115 * Headless browsers and bots may report non-standard audio sample rates, 116 * which can indicate automated/scripted environments. 117 * 118 * @since 1.1.0 119 * @license GPL-2.0-or-later 120 */ 121/** 122 * FontDetector - Detects available fonts using canvas measureText. 123 * 124 * Headless browsers typically have very few fonts installed, 125 * which can be detected by measuring text width differences. 126 * 127 * @since 1.1.0 128 * @license GPL-2.0-or-later 129 */ 130/** 131 * MediaDevicesDetector - Detects MediaDevices and WebRTC availability. 132 * 133 * Headless browsers often lack or disable MediaDevices and WebRTC APIs, 134 * which can indicate automated/scripted environments. 135 * 136 * @since 1.1.0 137 * @license GPL-2.0-or-later 138 */ 139/** 140 * WorkerUADetector - Detects User-Agent mismatch between main thread and Web Worker. 141 * 142 * Automation tools often fail to patch navigator.userAgent in Worker context, 143 * allowing detection via comparison. Based on Chrome bug fix (2026). 144 * 145 * Reference: https://chromiumdash.appspot.com/commit/4e9b82be3e9feed8952c81eedde553dfeb746ff3 146 * 147 * @since 1.1.0 148 * @license GPL-2.0-or-later 149 */ 150/** 151 * EmojiRenderingDetector - Detects emoji rendering anomalies and OS consistency. 152 * 153 * Different operating systems render emoji differently. Headless browsers 154 * often fail to render emoji at all, or render them inconsistently with 155 * the claimed OS in User-Agent. 156 * 157 * @since 1.1.0 158 * @license GPL-2.0-or-later 159 */ 160/** 161 * ActiveLayer Environment Detector 162 * 163 * Detects headless browsers and automation frameworks (Selenium, Puppeteer, 164 * Playwright, PhantomJS) to identify sophisticated bot attacks. 165 * 166 * Signals are passed to the API for final classification rather than blocking 167 * locally. This is one signal among many used for spam detection. 168 * 169 * @since 1.1.0 170 * @license GPL-2.0-or-later 171 */ 172/** 173 * ActiveLayer Environment Detector Entry Point 174 * 175 * Exports EnvironmentDetector to window.ActiveLayer and sets up form listeners. 176 * 177 * @since 1.1.0 178 * @license GPL-2.0-or-later 179 */
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.