fpscanner 0.9.5-beta.1 → 1.0.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 +15 -4
- package/dist/detections/hasPlatformMismatch.d.ts.map +1 -1
- package/dist/fpScanner.cjs.js +4 -3
- package/dist/fpScanner.es.js +30 -29
- package/dist/signals/worker.d.ts.map +1 -1
- package/package.json +1 -1
- package/scripts/build-custom.js +41 -8
- package/src/detections/hasPlatformMismatch.ts +6 -14
- package/src/signals/worker.ts +2 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Fingerprint Scanner
|
|
2
2
|
|
|
3
|
-
> **News:** After more than 7 years without any updates,
|
|
3
|
+
> **News:** After more than 7 years without any updates, the first release of the new FPScanner is here. This version combines fingerprinting and bot detection in a single library. Try the live demo at [fpscanner.com](https://fpscanner.com/). Expect new fingerprinting signals and more detection logic over time.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/antoinevastel/fpscanner/actions/workflows/ci.yml)
|
|
6
6
|
|
|
@@ -497,9 +497,12 @@ npx fpscanner build --key=your-secret-key-here
|
|
|
497
497
|
```
|
|
498
498
|
|
|
499
499
|
This will:
|
|
500
|
-
1.
|
|
501
|
-
2.
|
|
502
|
-
3.
|
|
500
|
+
1. Create backups of original files (for idempotent rebuilds)
|
|
501
|
+
2. Inject your encryption key into the library
|
|
502
|
+
3. Obfuscate the output to protect the key
|
|
503
|
+
4. Overwrite the files in `node_modules/fpscanner/dist/`
|
|
504
|
+
|
|
505
|
+
> **Note**: The build command is idempotent - you can run it multiple times safely. Original files are backed up as `.original` and restored before each build, preventing issues with re-obfuscating already-obfuscated code. This makes the build safe to use in watch mode or repeated CI/CD runs.
|
|
503
506
|
|
|
504
507
|
### Key Injection Methods
|
|
505
508
|
|
|
@@ -649,6 +652,14 @@ Make sure you're using the **exact same key** on your server that you used when
|
|
|
649
652
|
|
|
650
653
|
Use `--no-obfuscate` during development. Only enable obfuscation for production builds.
|
|
651
654
|
|
|
655
|
+
### Build fails with "heap out of memory" in watch mode
|
|
656
|
+
|
|
657
|
+
If you're running the build command repeatedly (e.g., in a watch task), this is now fixed. The build script automatically backs up and restores original files to prevent re-obfuscating already-obfuscated code. If you still encounter this issue:
|
|
658
|
+
|
|
659
|
+
1. Update to the latest version of fpscanner
|
|
660
|
+
2. Use `--no-obfuscate` for development/watch mode (recommended)
|
|
661
|
+
3. Only enable obfuscation for production builds
|
|
662
|
+
|
|
652
663
|
### `postinstall` fails in CI
|
|
653
664
|
|
|
654
665
|
Ensure `FINGERPRINT_KEY` is set as an environment variable before `npm install` runs.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hasPlatformMismatch.d.ts","sourceRoot":"","sources":["../../src/detections/hasPlatformMismatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGvC,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"hasPlatformMismatch.d.ts","sourceRoot":"","sources":["../../src/detections/hasPlatformMismatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGvC,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,WAkC3D"}
|
package/dist/fpScanner.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function ne(){return navigator.webdriver}function ie(){return navigator.userAgent}function ae(){return navigator.platform}const l="ERROR",r="INIT",s="NA",f="SKIPPED",d="high",b="low",oe="medium";function p(t){let e=0;for(let n=0,i=t.length;n<i;n++){let a=t.charCodeAt(n);e=(e<<5)-e+a,e|=0}return e.toString(16).padStart(8,"0")}function
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function ne(){return navigator.webdriver}function ie(){return navigator.userAgent}function ae(){return navigator.platform}const l="ERROR",r="INIT",s="NA",f="SKIPPED",d="high",b="low",oe="medium";function p(t){let e=0;for(let n=0,i=t.length;n<i;n++){let a=t.charCodeAt(n);e=(e<<5)-e+a,e|=0}return e.toString(16).padStart(8,"0")}function g(t,e){for(const n in t)t[n]=e}function se(){return navigator.buildID==="20181001000000"}function ce(){try{let t=!1;const e=Error.prepareStackTrace;Error.prepareStackTrace=function(){return t=!0,e};const n=new Error("");return console.log(n),t}catch{return l}}function le(){const t={vendor:r,renderer:r};if(se())return g(t,s),t;try{var e=document.createElement("canvas"),n=e.getContext("webgl")||e.getContext("experimental-webgl");n.getSupportedExtensions().indexOf("WEBGL_debug_renderer_info")>=0?(t.vendor=n.getParameter(n.getExtension("WEBGL_debug_renderer_info").UNMASKED_VENDOR_WEBGL),t.renderer=n.getParameter(n.getExtension("WEBGL_debug_renderer_info").UNMASKED_RENDERER_WEBGL)):g(t,s)}catch{g(t,l)}return t}function ue(){return"__pwInitScripts"in window||"__playwright__binding__"in window}function de(){return navigator.hardwareConcurrency||s}function ge(){const t=[],e=.123456789;return["E","LN10","LN2","LOG10E","LOG2E","PI","SQRT1_2","SQRT2"].forEach(function(a){try{t.push(Math[a])}catch{t.push(-1)}}),["tan","sin","exp","atan","acosh","asinh","atanh","expm1","log1p","sinh"].forEach(function(a){try{t.push(Math[a](e))}catch{t.push(-1)}}),p(t.map(String).join(","))}function he(){return navigator.deviceMemory||s}function me(){return eval.toString().length}function pe(){const t={timezone:r,localeLanguage:r};try{if(typeof Intl<"u"&&typeof Intl.DateTimeFormat<"u"){const e=Intl.DateTimeFormat().resolvedOptions();t.timezone=e.timeZone,t.localeLanguage=e.locale}else t.timezone=s,t.localeLanguage=s}catch{t.timezone=l,t.localeLanguage=l}return t}function fe(){return{width:window.screen.width,height:window.screen.height,pixelDepth:window.screen.pixelDepth,colorDepth:window.screen.colorDepth,availableWidth:window.screen.availWidth,availableHeight:window.screen.availHeight,innerWidth:window.innerWidth,innerHeight:window.innerHeight,hasMultipleDisplays:typeof screen.isExtended<"u"?screen.isExtended:s}}function ve(){return{languages:navigator.languages,language:navigator.language}}async function we(){const t={vendor:r,architecture:r,device:r,description:r};if("gpu"in navigator)try{const e=await navigator.gpu.requestAdapter();e&&(t.vendor=e.info.vendor,t.architecture=e.info.architecture,t.device=e.info.device,t.description=e.info.description)}catch{g(t,l)}else g(t,s);return t}function ye(){const t=["__driver_evaluate","__webdriver_evaluate","__selenium_evaluate","__fxdriver_evaluate","__driver_unwrapped","__webdriver_unwrapped","__selenium_unwrapped","__fxdriver_unwrapped","_Selenium_IDE_Recorder","_selenium","calledSelenium","$cdc_asdjflasutopfhvcZLmcfl_","$chrome_asyncScriptInfo","__$webdriverAsyncExecutor","webdriver","__webdriverFunc","domAutomation","domAutomationController","__lastWatirAlert","__lastWatirConfirm","__lastWatirPrompt","__webdriver_script_fn","_WEBDRIVER_ELEM_CACHE"];let e=!1;for(let n=0;n<t.length;n++)if(t[n]in window){e=!0;break}return e=e||!!document.__webdriver_script_fn||!!window.domAutomation||!!window.domAutomationController,e}function be(){try{const t="webdriver",e=window.navigator;if(!e[t]&&!e.hasOwnProperty(t)){e[t]=1;const n=e[t]===1;return delete e[t],n}return!0}catch{return!1}}async function Se(){const t=window.navigator,e={architecture:r,bitness:r,brands:r,mobile:r,model:r,platform:r,platformVersion:r,uaFullVersion:r};if("userAgentData"in t)try{const n=await t.userAgentData.getHighEntropyValues(["architecture","bitness","brands","mobile","model","platform","platformVersion","uaFullVersion"]);e.architecture=n.architecture,e.bitness=n.bitness,e.brands=n.brands,e.mobile=n.mobile,e.model=n.model,e.platform=n.platform,e.platformVersion=n.platformVersion,e.uaFullVersion=n.uaFullVersion}catch{g(e,l)}else g(e,s);return e}function Ce(){if(!navigator.plugins)return!1;const t=typeof navigator.plugins.toString=="function"?navigator.plugins.toString():navigator.plugins.constructor&&typeof navigator.plugins.constructor.toString=="function"?navigator.plugins.constructor.toString():typeof navigator.plugins;return t==="[object PluginArray]"||t==="[object MSPluginsCollection]"||t==="[object HTMLPluginsCollection]"}function Ae(){if(!navigator.plugins)return s;const t=[];for(let e=0;e<navigator.plugins.length;e++)t.push(navigator.plugins[e].name);return p(t.join(","))}function Pe(){return navigator.plugins?navigator.plugins.length:s}function Me(){if(!navigator.plugins)return s;try{return navigator.plugins[0]===navigator.plugins[0][0].enabledPlugin}catch{return l}}function xe(){if(!navigator.plugins)return s;try{return navigator.plugins.item(4294967296)!==navigator.plugins[0]}catch{return l}}function We(){const t={isValidPluginArray:r,pluginCount:r,pluginNamesHash:r,pluginConsistency1:r,pluginOverflow:r};try{t.isValidPluginArray=Ce(),t.pluginCount=Pe(),t.pluginNamesHash=Ae(),t.pluginConsistency1=Me(),t.pluginOverflow=xe()}catch{g(t,l)}return t}async function Ee(){return new Promise(async function(t){var e={audiooutput:0,audioinput:0,videoinput:0};if(navigator.mediaDevices&&navigator.mediaDevices.enumerateDevices){const a=await navigator.mediaDevices.enumerateDevices();if(typeof a<"u"){for(var n=0;n<a.length;n++){var i=a[n].kind;e[i]=e[i]+1}return t({speakers:e.audiooutput,microphones:e.audioinput,webcams:e.videoinput})}else return g(e,s),t(e)}else return g(e,s),t(e)})}function ke(){const t={webdriver:r,userAgent:r,platform:r,memory:r,cpuCount:r,language:r},e=document.createElement("iframe");let n=!1;try{e.style.display="none",e.src="about:blank",document.body.appendChild(e),n=!0;const i=e.contentWindow?.navigator;t.webdriver=i.webdriver??!1,t.userAgent=i.userAgent??s,t.platform=i.platform??s,t.memory=i.deviceMemory??s,t.cpuCount=i.hardwareConcurrency??s,t.language=i.language??s}catch{g(t,l)}finally{if(n)try{document.body.removeChild(e)}catch{}}return t}async function De(){return new Promise(t=>{const e={vendor:r,renderer:r,userAgent:r,language:r,platform:r,memory:r,cpuCount:r};let n=null,i=null,a=null;const h=()=>{a&&clearTimeout(a),n&&n.terminate(),i&&URL.revokeObjectURL(i)};try{const m=`try {
|
|
2
2
|
var fingerprintWorker = {};
|
|
3
3
|
|
|
4
4
|
fingerprintWorker.userAgent = navigator.userAgent;
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
fingerprintWorker.vendor = 'INIT';
|
|
13
13
|
fingerprintWorker.renderer = 'INIT';
|
|
14
14
|
var gl = canvas.getContext('webgl');
|
|
15
|
+
const isFirefox = navigator.userAgent.includes('Firefox');
|
|
15
16
|
try {
|
|
16
|
-
if (gl) {
|
|
17
|
+
if (gl && !isFirefox) {
|
|
17
18
|
var glExt = gl.getExtension('WEBGL_debug_renderer_info');
|
|
18
19
|
fingerprintWorker.vendor = gl.getParameter(glExt.UNMASKED_VENDOR_WEBGL);
|
|
19
20
|
fingerprintWorker.renderer = gl.getParameter(glExt.UNMASKED_RENDERER_WEBGL);
|
|
@@ -28,4 +29,4 @@
|
|
|
28
29
|
self.postMessage(fingerprintWorker);
|
|
29
30
|
} catch (e) {
|
|
30
31
|
self.postMessage(fingerprintWorker);
|
|
31
|
-
}`,w=new Blob([m],{type:"application/javascript"});i=URL.createObjectURL(w),n=new Worker(i),a=window.setTimeout(()=>{g(),h(e,l),t(e)},2e3),n.onmessage=function(o){try{e.vendor=o.data.vendor,e.renderer=o.data.renderer,e.userAgent=o.data.userAgent,e.language=o.data.language,e.platform=o.data.platform,e.memory=o.data.memory,e.cpuCount=o.data.cpuCount}catch{h(e,l)}finally{g(),t(e)}},n.onerror=function(){g(),h(e,l),t(e)}}catch{g(),h(e,l),t(e)}})}function _e(){const t={toSourceError:r,hasToSource:!1};try{null.usdfsh}catch(e){t.toSourceError=e.toString()}try{throw"xyz"}catch(e){try{e.toSource(),t.hasToSource=!0}catch{t.hasToSource=!1}}return t}const S=['audio/mp4; codecs="mp4a.40.2"',"audio/mpeg;",'audio/webm; codecs="vorbis"','audio/ogg; codecs="vorbis"','audio/wav; codecs="1"','audio/ogg; codecs="speex"','audio/ogg; codecs="flac"','audio/3gpp; codecs="samr"'],C=['video/mp4; codecs="avc1.42E01E, mp4a.40.2"','video/mp4; codecs="avc1.42E01E"','video/mp4; codecs="avc1.58A01E"','video/mp4; codecs="avc1.4D401E"','video/mp4; codecs="avc1.64001E"','video/mp4; codecs="mp4v.20.8"','video/mp4; codecs="mp4v.20.240"','video/webm; codecs="vp8"','video/ogg; codecs="theora"','video/ogg; codecs="dirac"','video/3gpp; codecs="mp4v.20.8"','video/x-matroska; codecs="theora"'];function A(t,e){const n={};try{const i=document.createElement(e);for(const a of t)try{n[a]=i.canPlayType(a)||null}catch{n[a]=null}}catch{for(const i of t)n[i]=null}return n}function P(t){const e={},n=window.MediaSource;if(!n||typeof n.isTypeSupported!="function"){for(const i of t)e[i]=null;return e}for(const i of t)try{e[i]=n.isTypeSupported(i)}catch{e[i]=null}return e}function M(t){try{const e=window.RTCRtpReceiver;if(e&&typeof e.getCapabilities=="function"){const n=e.getCapabilities(t);return p(JSON.stringify(n))}return s}catch{return l}}function Re(){const t={audioCanPlayTypeHash:s,videoCanPlayTypeHash:s,audioMediaSourceHash:s,videoMediaSourceHash:s,rtcAudioCapabilitiesHash:s,rtcVideoCapabilitiesHash:s,hasMediaSource:!1};try{t.hasMediaSource=!!window.MediaSource;const e=A(S,"audio"),n=A(C,"video");t.audioCanPlayTypeHash=p(JSON.stringify(e)),t.videoCanPlayTypeHash=p(JSON.stringify(n));const i=P(S),a=P(C);t.audioMediaSourceHash=p(JSON.stringify(i)),t.videoMediaSourceHash=p(JSON.stringify(a)),t.rtcAudioCapabilitiesHash=M("audio"),t.rtcVideoCapabilitiesHash=M("video")}catch{h(t,l)}return t}async function Ie(){return new Promise(t=>{try{const e=new Image,n=document.createElement("canvas").getContext("2d");e.onload=()=>{n.drawImage(e,0,0),t(n.getImageData(0,0,1,1).data.filter(i=>i===0).length!=4)},e.onerror=()=>{t(l)},e.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII="}catch{t(l)}})}function Te(){var t=document.createElement("canvas");t.width=400,t.height=200,t.style.display="inline";var e=t.getContext("2d");try{return e.rect(0,0,10,10),e.rect(2,2,6,6),e.textBaseline="alphabetic",e.fillStyle="#f60",e.fillRect(125,1,62,20),e.fillStyle="#069",e.font="11pt no-real-font-123",e.fillText("Cwm fjordbank glyphs vext quiz, 😃",2,15),e.fillStyle="rgba(102, 204, 0, 0.2)",e.font="18pt Arial",e.fillText("Cwm fjordbank glyphs vext quiz, 😃",4,45),e.globalCompositeOperation="multiply",e.fillStyle="rgb(255,0,255)",e.beginPath(),e.arc(50,50,50,0,2*Math.PI,!0),e.closePath(),e.fill(),e.fillStyle="rgb(0,255,255)",e.beginPath(),e.arc(100,50,50,0,2*Math.PI,!0),e.closePath(),e.fill(),e.fillStyle="rgb(255,255,0)",e.beginPath(),e.arc(75,100,50,0,2*Math.PI,!0),e.closePath(),e.fill(),e.fillStyle="rgb(255,0,255)",e.arc(75,75,75,0,2*Math.PI,!0),e.arc(75,75,25,0,2*Math.PI,!0),e.fill("evenodd"),p(t.toDataURL())}catch{return l}}async function Le(){const t={hasModifiedCanvas:r,canvasFingerprint:r};return t.hasModifiedCanvas=await Ie(),t.canvasFingerprint=Te(),t}function Oe(){const t=["deviceMemory","hardwareConcurrency","language","languages","platform"],e=[];for(const n of t){const i=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(navigator),n);i&&i.value?e.push("1"):e.push("0")}return e.join("")}function He(){return Math.random().toString(36).substring(2,15)}function Ue(){return new Date().getTime()}function Ve(){return window.location.href}function E(t,e){const n=t.signals;return e==="iframe"?n.contexts.iframe.webdriver!==n.automation.webdriver||n.contexts.iframe.userAgent!==n.browser.userAgent||n.contexts.iframe.platform!==n.device.platform||n.contexts.iframe.memory!==n.device.memory||n.contexts.iframe.cpuCount!==n.device.cpuCount:n.contexts.webWorker.webdriver!==n.automation.webdriver||n.contexts.webWorker.userAgent!==n.browser.userAgent||n.contexts.webWorker.platform!==n.device.platform||n.contexts.webWorker.memory!==n.device.memory||n.contexts.webWorker.cpuCount!==n.device.cpuCount}function Fe(){const t={bitmask:r,extensions:[]},e=document.body.hasAttribute("data-gr-ext-installed"),n=typeof window.ethereum<"u",i=document.getElementById("coupon-birds-drop-div")!==null,a=document.querySelector("deepl-input-controller")!==null,g=document.getElementById("monica-content-root")!==null,m=document.querySelector("chatgpt-sidebar")!==null,w=typeof window.__REQUESTLY__<"u",o=Array.from(document.querySelectorAll("*")).filter(v=>v.tagName.toLowerCase().startsWith("veepn-")).length>0;return t.bitmask=[e?"1":"0",n?"1":"0",i?"1":"0",a?"1":"0",g?"1":"0",m?"1":"0",w?"1":"0",o?"1":"0"].join(""),e&&t.extensions.push("grammarly"),n&&t.extensions.push("metamask"),i&&t.extensions.push("coupon-birds"),a&&t.extensions.push("deepl"),g&&t.extensions.push("monica-ai"),m&&t.extensions.push("sider-ai"),w&&t.extensions.push("requestly"),o&&t.extensions.push("veepn"),t}function c(t){try{return t()}catch{return!1}}function Ge(){const t={bitmask:r,chrome:c(()=>"chrome"in window),brave:c(()=>"brave"in navigator),applePaySupport:c(()=>"ApplePaySetup"in window),opera:c(()=>typeof window.opr<"u"||typeof window.onoperadetachedviewchange=="object"),serial:c(()=>window.navigator.serial!==void 0),attachShadow:c(()=>!!Element.prototype.attachShadow),caches:c(()=>!!window.caches),webAssembly:c(()=>!!window.WebAssembly&&!!window.WebAssembly.instantiate),buffer:c(()=>"Buffer"in window),showModalDialog:c(()=>"showModalDialog"in window),safari:c(()=>"safari"in window),webkitPrefixedFunction:c(()=>"webkitCancelAnimationFrame"in window),mozPrefixedFunction:c(()=>"mozGetUserMedia"in navigator),usb:c(()=>typeof window.USB=="function"),browserCapture:c(()=>typeof window.BrowserCaptureMediaStreamTrack=="function"),paymentRequestUpdateEvent:c(()=>typeof window.PaymentRequestUpdateEvent=="function"),pressureObserver:c(()=>typeof window.PressureObserver=="function"),audioSession:c(()=>"audioSession"in navigator),selectAudioOutput:c(()=>typeof navigator<"u"&&typeof navigator.mediaDevices<"u"&&typeof navigator.mediaDevices.selectAudioOutput=="function"),barcodeDetector:c(()=>"BarcodeDetector"in window),battery:c(()=>"getBattery"in navigator),devicePosture:c(()=>"DevicePosture"in window),documentPictureInPicture:c(()=>"documentPictureInPicture"in window),eyeDropper:c(()=>"EyeDropper"in window),editContext:c(()=>"EditContext"in window),fencedFrame:c(()=>"FencedFrameConfig"in window),sanitizer:c(()=>"Sanitizer"in window),otpCredential:c(()=>"OTPCredential"in window)},e=Object.keys(t).filter(n=>n!=="bitmask").map(n=>t[n]?"1":"0").join("");return t.bitmask=e,t}function je(){const t={prefersColorScheme:r,prefersReducedMotion:r,prefersReducedTransparency:r,colorGamut:r,pointer:r,anyPointer:r,hover:r,anyHover:r,colorDepth:r};try{window.matchMedia("(prefers-color-scheme: dark)").matches?t.prefersColorScheme="dark":window.matchMedia("(prefers-color-scheme: light)").matches?t.prefersColorScheme="light":t.prefersColorScheme=null,t.prefersReducedMotion=window.matchMedia("(prefers-reduced-motion: reduce)").matches,t.prefersReducedTransparency=window.matchMedia("(prefers-reduced-transparency: reduce)").matches,window.matchMedia("(color-gamut: rec2020)").matches?t.colorGamut="rec2020":window.matchMedia("(color-gamut: p3)").matches?t.colorGamut="p3":window.matchMedia("(color-gamut: srgb)").matches?t.colorGamut="srgb":t.colorGamut=null,window.matchMedia("(pointer: fine)").matches?t.pointer="fine":window.matchMedia("(pointer: coarse)").matches?t.pointer="coarse":window.matchMedia("(pointer: none)").matches?t.pointer="none":t.pointer=null,window.matchMedia("(any-pointer: fine)").matches?t.anyPointer="fine":window.matchMedia("(any-pointer: coarse)").matches?t.anyPointer="coarse":window.matchMedia("(any-pointer: none)").matches?t.anyPointer="none":t.anyPointer=null,t.hover=window.matchMedia("(hover: hover)").matches,t.anyHover=window.matchMedia("(any-hover: hover)").matches;let e=0;for(let n=0;n<=16;n++)window.matchMedia(`(color: ${n})`).matches&&(e=n);t.colorDepth=e}catch{h(t,l)}return t}function Be(t){const e=t.signals.device.screenResolution;return e.width===600&&e.height===800||e.availableWidth===600&&e.availableHeight===800||e.innerWidth===600&&e.innerHeight===800}function Ne(t){return t.signals.automation.webdriver===!0}function ze(t){return!!t.signals.automation.selenium}function $e(t){return t.signals.automation.cdp===!0}function Qe(t){return t.signals.automation.playwright===!0}function qe(t){return typeof t.signals.device.memory!="number"?!1:t.signals.device.memory>32||t.signals.device.memory<.25}function Ke(t){return typeof t.signals.device.cpuCount!="number"?!1:t.signals.device.cpuCount>70}function Je(t){const e=t.signals.browser.userAgent;return t.signals.browser.features.chrome===!1&&typeof e=="string"&&e.includes("Chrome")}function Ye(t){return t.signals.contexts.iframe.webdriver===!0}function Ze(t){return t.signals.contexts.webWorker.webdriver===!0}function Xe(t){const e=t.signals.contexts.webWorker,n=t.signals.graphics.webGL;return e.vendor===l||e.renderer===l||n.vendor===s||n.renderer===s||e.vendor===f?!1:e.vendor!==n.vendor||e.renderer!==n.renderer}function et(t){return t.signals.contexts.webWorker.platform===s||t.signals.contexts.webWorker.platform===l||t.signals.contexts.webWorker.platform===f?!1:t.signals.device.platform!==t.signals.contexts.webWorker.platform}function tt(t){return t.signals.contexts.iframe.platform===s||t.signals.contexts.iframe.platform===l?!1:t.signals.device.platform!==t.signals.contexts.iframe.platform}function rt(t){return t.signals.automation.webdriverWritable===!0}function nt(t){return t.signals.graphics.webGL.renderer.includes("SwiftShader")}function it(t){return t.signals.locale.internationalization.timezone==="UTC"}function at(t){const e=t.signals.locale.languages.languages,n=t.signals.locale.languages.language;return n&&e&&Array.isArray(e)&&e.length>0?e[0]!==n:!1}function ot(t){return!!(t.signals.browser.features.chrome&&t.signals.browser.etsl!==33||t.signals.browser.features.safari&&t.signals.browser.etsl!==37||t.signals.browser.userAgent.includes("Firefox")&&t.signals.browser.etsl!==37)}function st(t){return[t.signals.browser.userAgent,t.signals.contexts.iframe.userAgent,t.signals.contexts.webWorker.userAgent].some(n=>/bot|headless/i.test(n.toLowerCase()))}function ct(t){const e=t.signals.graphics.webgpu,n=t.signals.graphics.webGL,i=t.signals.browser.userAgent;return!!((n.vendor.includes("Apple")||n.renderer.includes("Apple"))&&!i.includes("Mac")||e.vendor.includes("apple")&&!i.includes("Mac")||e.vendor.includes("apple")&&!n.renderer.includes("Apple"))}function lt(t){const e=t.signals.device.platform,n=t.signals.browser.userAgent,i=t.signals.browser.highEntropyValues.platform;return!!(n.includes("Mac")&&!e.includes("Mac")||n.includes("Windows")&&!e.includes("Win")||n.includes("Linux")&&!e.includes("Linux")||i!==l&&i!==s&&(i.includes("Mac")&&!e.includes("Mac")||i.includes("Windows")&&!e.includes("Win")||i.includes("Linux")&&!e.includes("Linux")||i.includes("Android")&&!e.includes("Android")||i.includes("iOS")&&!e.includes("iOS")))}async function ut(t,e){const n=new TextEncoder().encode(e),i=new TextEncoder().encode(t),a=new Uint8Array(i.length);for(let m=0;m<i.length;m++)a[m]=i[m]^n[m%n.length];const g=String.fromCharCode(...a);return btoa(g)}class dt{constructor(){this.fingerprint={signals:{automation:{webdriver:r,webdriverWritable:r,selenium:r,cdp:r,playwright:r,navigatorPropertyDescriptors:r},device:{cpuCount:r,memory:r,platform:r,screenResolution:{width:r,height:r,pixelDepth:r,colorDepth:r,availableWidth:r,availableHeight:r,innerWidth:r,innerHeight:r,hasMultipleDisplays:r},multimediaDevices:{speakers:r,microphones:r,webcams:r},mediaQueries:{prefersColorScheme:r,prefersReducedMotion:r,prefersReducedTransparency:r,colorGamut:r,pointer:r,anyPointer:r,hover:r,anyHover:r,colorDepth:r}},browser:{userAgent:r,features:{bitmask:r,chrome:r,brave:r,applePaySupport:r,opera:r,serial:r,attachShadow:r,caches:r,webAssembly:r,buffer:r,showModalDialog:r,safari:r,webkitPrefixedFunction:r,mozPrefixedFunction:r,usb:r,browserCapture:r,paymentRequestUpdateEvent:r,pressureObserver:r,audioSession:r,selectAudioOutput:r,barcodeDetector:r,battery:r,devicePosture:r,documentPictureInPicture:r,eyeDropper:r,editContext:r,fencedFrame:r,sanitizer:r,otpCredential:r},plugins:{isValidPluginArray:r,pluginCount:r,pluginNamesHash:r,pluginConsistency1:r,pluginOverflow:r},extensions:{bitmask:r,extensions:r},highEntropyValues:{architecture:r,bitness:r,brands:r,mobile:r,model:r,platform:r,platformVersion:r,uaFullVersion:r},etsl:r,maths:r,toSourceError:{toSourceError:r,hasToSource:r}},graphics:{webGL:{vendor:r,renderer:r},webgpu:{vendor:r,architecture:r,device:r,description:r},canvas:{hasModifiedCanvas:r,canvasFingerprint:r}},codecs:{audioCanPlayTypeHash:r,videoCanPlayTypeHash:r,audioMediaSourceHash:r,videoMediaSourceHash:r,rtcAudioCapabilitiesHash:r,rtcVideoCapabilitiesHash:r,hasMediaSource:r},locale:{internationalization:{timezone:r,localeLanguage:r},languages:{languages:r,language:r}},contexts:{iframe:{webdriver:r,userAgent:r,platform:r,memory:r,cpuCount:r,language:r},webWorker:{webdriver:r,userAgent:r,platform:r,memory:r,cpuCount:r,language:r,vendor:r,renderer:r}}},fsid:r,nonce:r,time:r,url:r,fastBotDetection:!1,fastBotDetectionDetails:{headlessChromeScreenResolution:{detected:!1,severity:"high"},hasWebdriver:{detected:!1,severity:"high"},hasWebdriverWritable:{detected:!1,severity:"high"},hasSeleniumProperty:{detected:!1,severity:"high"},hasCDP:{detected:!1,severity:"high"},hasPlaywright:{detected:!1,severity:"high"},hasImpossibleDeviceMemory:{detected:!1,severity:"high"},hasHighCPUCount:{detected:!1,severity:"high"},hasMissingChromeObject:{detected:!1,severity:"high"},hasWebdriverIframe:{detected:!1,severity:"high"},hasWebdriverWorker:{detected:!1,severity:"high"},hasMismatchWebGLInWorker:{detected:!1,severity:"high"},hasMismatchPlatformIframe:{detected:!1,severity:"high"},hasMismatchPlatformWorker:{detected:!1,severity:"high"},hasSwiftshaderRenderer:{detected:!1,severity:"low"},hasUTCTimezone:{detected:!1,severity:"medium"},hasMismatchLanguages:{detected:!1,severity:"low"},hasInconsistentEtsl:{detected:!1,severity:"high"},hasBotUserAgent:{detected:!1,severity:"high"},hasGPUMismatch:{detected:!1,severity:"high"},hasPlatformMismatch:{detected:!1,severity:"high"}}}}async collectSignal(e){try{return await e()}catch{return l}}generateFingerprintScannerId(){try{const e=this.fingerprint.signals,n=this.fingerprint.fastBotDetectionDetails,i="FS1",g=[n.headlessChromeScreenResolution.detected,n.hasWebdriver.detected,n.hasWebdriverWritable.detected,n.hasSeleniumProperty.detected,n.hasCDP.detected,n.hasPlaywright.detected,n.hasImpossibleDeviceMemory.detected,n.hasHighCPUCount.detected,n.hasMissingChromeObject.detected,n.hasWebdriverIframe.detected,n.hasWebdriverWorker.detected,n.hasMismatchWebGLInWorker.detected,n.hasMismatchPlatformIframe.detected,n.hasMismatchPlatformWorker.detected,n.hasSwiftshaderRenderer.detected,n.hasUTCTimezone.detected,n.hasMismatchLanguages.detected,n.hasInconsistentEtsl.detected,n.hasBotUserAgent.detected,n.hasGPUMismatch.detected,n.hasPlatformMismatch.detected].map(u=>u?"1":"0").join(""),m=[e.automation.webdriver===!0,e.automation.webdriverWritable===!0,e.automation.selenium===!0,e.automation.cdp===!0,e.automation.playwright===!0].map(u=>u?"1":"0").join(""),w=p(String(e.automation.navigatorPropertyDescriptors)).slice(0,4),o=`${m}h${w}`,v=typeof e.device.screenResolution.width=="number"?e.device.screenResolution.width:0,y=typeof e.device.screenResolution.height=="number"?e.device.screenResolution.height:0,W=typeof e.device.cpuCount=="number"?String(e.device.cpuCount).padStart(2,"0"):"00",x=typeof e.device.memory=="number"?String(Math.round(e.device.memory)).padStart(2,"0"):"00",k=[e.device.screenResolution.hasMultipleDisplays===!0,e.device.mediaQueries.prefersReducedMotion===!0,e.device.mediaQueries.prefersReducedTransparency===!0,e.device.mediaQueries.hover===!0,e.device.mediaQueries.anyHover===!0].map(u=>u?"1":"0").join(""),D=[e.device.platform,e.device.screenResolution.pixelDepth,e.device.screenResolution.colorDepth,e.device.multimediaDevices.speakers,e.device.multimediaDevices.microphones,e.device.multimediaDevices.webcams,e.device.mediaQueries.prefersColorScheme,e.device.mediaQueries.colorGamut,e.device.mediaQueries.pointer,e.device.mediaQueries.anyPointer,e.device.mediaQueries.colorDepth].map(u=>String(u)).join("|"),_=p(D).slice(0,6),R=`${v}x${y}c${W}m${x}b${k}h${_}`,I=typeof e.browser.features.bitmask=="string"?e.browser.features.bitmask:"0000000000",T=typeof e.browser.extensions.bitmask=="string"?e.browser.extensions.bitmask:"00000000",L=[e.browser.plugins.isValidPluginArray===!0,e.browser.plugins.pluginConsistency1===!0,e.browser.plugins.pluginOverflow===!0,e.browser.toSourceError.hasToSource===!0].map(u=>u?"1":"0").join(""),O=[e.browser.userAgent,e.browser.etsl,e.browser.maths,e.browser.plugins.pluginCount,e.browser.plugins.pluginNamesHash,e.browser.toSourceError.toSourceError,e.browser.highEntropyValues.architecture,e.browser.highEntropyValues.bitness,e.browser.highEntropyValues.platform,e.browser.highEntropyValues.platformVersion,e.browser.highEntropyValues.uaFullVersion,e.browser.highEntropyValues.mobile].map(u=>String(u)).join("|"),H=p(O).slice(0,6),U=`f${I}e${T}p${L}h${H}`,V=[e.graphics.canvas.hasModifiedCanvas===!0].map(u=>u?"1":"0").join(""),F=[e.graphics.webGL.vendor,e.graphics.webGL.renderer,e.graphics.webgpu.vendor,e.graphics.webgpu.architecture,e.graphics.webgpu.device,e.graphics.webgpu.description,e.graphics.canvas.canvasFingerprint].map(u=>String(u)).join("|"),G=p(F).slice(0,6),j=`${V}h${G}`,B=[e.codecs.hasMediaSource===!0].map(u=>u?"1":"0").join(""),N=[e.codecs.audioCanPlayTypeHash,e.codecs.videoCanPlayTypeHash,e.codecs.audioMediaSourceHash,e.codecs.videoMediaSourceHash,e.codecs.rtcAudioCapabilitiesHash,e.codecs.rtcVideoCapabilitiesHash].map(u=>String(u)).join("|"),z=p(N).slice(0,6),$=`${B}h${z}`,Q=typeof e.locale.languages.language=="string"?e.locale.languages.language.slice(0,2).toLowerCase():"xx",q=Array.isArray(e.locale.languages.languages)?e.locale.languages.languages.length:0,K=(typeof e.locale.internationalization.timezone=="string"?e.locale.internationalization.timezone:"unknown").replace(/[\/\s]/g,"-"),J=[e.locale.internationalization.timezone,e.locale.internationalization.localeLanguage,Array.isArray(e.locale.languages.languages)?e.locale.languages.languages.join(","):e.locale.languages.languages,e.locale.languages.language].map(u=>String(u)).join("|"),Y=p(J).slice(0,4),Z=`${Q}${q}t${K}_h${Y}`,X=[E(this.fingerprint,"iframe"),E(this.fingerprint,"worker"),e.contexts.iframe.webdriver===!0,e.contexts.webWorker.webdriver===!0].map(u=>u?"1":"0").join(""),ee=[e.contexts.iframe.userAgent,e.contexts.iframe.platform,e.contexts.iframe.memory,e.contexts.iframe.cpuCount,e.contexts.iframe.language,e.contexts.webWorker.userAgent,e.contexts.webWorker.platform,e.contexts.webWorker.memory,e.contexts.webWorker.cpuCount,e.contexts.webWorker.language,e.contexts.webWorker.vendor,e.contexts.webWorker.renderer].map(u=>String(u)).join("|"),te=p(ee).slice(0,6),re=`${X}h${te}`;return[i,g,o,R,U,j,$,Z,re].join("_")}catch(e){return console.error("Error generating fingerprint scanner id",e),l}}async encryptFingerprint(e){const n="__DEFAULT_FPSCANNER_KEY__";return n.length>20&&n.indexOf("DEFAULT")>0&&n.indexOf("FPSCANNER")>0&&console.warn('[fpscanner] WARNING: Using default encryption key! Run "npx fpscanner build --key=your-secret-key" to inject your own key. See: https://github.com/antoinevastel/fpscanner#advanced-custom-builds'),await ut(JSON.stringify(e),n)}getDetectionRules(){return[{name:"headlessChromeScreenResolution",severity:d,test:Be},{name:"hasWebdriver",severity:d,test:Ne},{name:"hasWebdriverWritable",severity:d,test:rt},{name:"hasSeleniumProperty",severity:d,test:ze},{name:"hasCDP",severity:d,test:$e},{name:"hasPlaywright",severity:d,test:Qe},{name:"hasImpossibleDeviceMemory",severity:d,test:qe},{name:"hasHighCPUCount",severity:d,test:Ke},{name:"hasMissingChromeObject",severity:d,test:Je},{name:"hasWebdriverIframe",severity:d,test:Ye},{name:"hasWebdriverWorker",severity:d,test:Ze},{name:"hasMismatchWebGLInWorker",severity:d,test:Xe},{name:"hasMismatchPlatformIframe",severity:d,test:tt},{name:"hasMismatchPlatformWorker",severity:d,test:et},{name:"hasSwiftshaderRenderer",severity:b,test:nt},{name:"hasUTCTimezone",severity:oe,test:it},{name:"hasMismatchLanguages",severity:b,test:at},{name:"hasInconsistentEtsl",severity:d,test:ot},{name:"hasBotUserAgent",severity:d,test:st},{name:"hasGPUMismatch",severity:d,test:ct},{name:"hasPlatformMismatch",severity:d,test:lt}]}runDetectionRules(){const e=this.getDetectionRules(),n={headlessChromeScreenResolution:{detected:!1,severity:"high"},hasWebdriver:{detected:!1,severity:"high"},hasWebdriverWritable:{detected:!1,severity:"high"},hasSeleniumProperty:{detected:!1,severity:"high"},hasCDP:{detected:!1,severity:"high"},hasPlaywright:{detected:!1,severity:"high"},hasImpossibleDeviceMemory:{detected:!1,severity:"high"},hasHighCPUCount:{detected:!1,severity:"high"},hasMissingChromeObject:{detected:!1,severity:"high"},hasWebdriverIframe:{detected:!1,severity:"high"},hasWebdriverWorker:{detected:!1,severity:"high"},hasMismatchWebGLInWorker:{detected:!1,severity:"high"},hasMismatchPlatformIframe:{detected:!1,severity:"high"},hasMismatchPlatformWorker:{detected:!1,severity:"high"},hasSwiftshaderRenderer:{detected:!1,severity:"low"},hasUTCTimezone:{detected:!1,severity:"medium"},hasMismatchLanguages:{detected:!1,severity:"low"},hasInconsistentEtsl:{detected:!1,severity:"high"},hasBotUserAgent:{detected:!1,severity:"high"},hasGPUMismatch:{detected:!1,severity:"high"},hasPlatformMismatch:{detected:!1,severity:"high"}};for(const i of e)try{const a=i.test(this.fingerprint);n[i.name]={detected:a,severity:i.severity}}catch{n[i.name]={detected:!1,severity:i.severity}}return n}async collectFingerprint(e={encrypt:!0}){const{encrypt:n=!0,skipWorker:i=!1}=e,a=this.fingerprint.signals,g={webdriver:this.collectSignal(ne),webdriverWritable:this.collectSignal(be),selenium:this.collectSignal(ye),cdp:this.collectSignal(ce),playwright:this.collectSignal(ue),navigatorPropertyDescriptors:this.collectSignal(Oe),cpuCount:this.collectSignal(de),memory:this.collectSignal(ge),platform:this.collectSignal(ae),screenResolution:this.collectSignal(fe),multimediaDevices:this.collectSignal(xe),mediaQueries:this.collectSignal(je),userAgent:this.collectSignal(ie),browserFeatures:this.collectSignal(Ge),plugins:this.collectSignal(We),browserExtensions:this.collectSignal(Fe),highEntropyValues:this.collectSignal(Se),etsl:this.collectSignal(me),maths:this.collectSignal(he),toSourceError:this.collectSignal(_e),webGL:this.collectSignal(le),webgpu:this.collectSignal(we),canvas:this.collectSignal(Le),mediaCodecs:this.collectSignal(Re),internationalization:this.collectSignal(pe),languages:this.collectSignal(ve),iframe:this.collectSignal(ke),webWorker:i?Promise.resolve({webdriver:f,userAgent:f,platform:f,memory:f,cpuCount:f,language:f,vendor:f,renderer:f}):this.collectSignal(De),nonce:this.collectSignal(He),time:this.collectSignal(Ue),url:this.collectSignal(Ve)},m=Object.keys(g),w=await Promise.all(Object.values(g)),o=Object.fromEntries(m.map((v,y)=>[v,w[y]]));return a.automation.webdriver=o.webdriver,a.automation.webdriverWritable=o.webdriverWritable,a.automation.selenium=o.selenium,a.automation.cdp=o.cdp,a.automation.playwright=o.playwright,a.automation.navigatorPropertyDescriptors=o.navigatorPropertyDescriptors,a.device.cpuCount=o.cpuCount,a.device.memory=o.memory,a.device.platform=o.platform,a.device.screenResolution=o.screenResolution,a.device.multimediaDevices=o.multimediaDevices,a.device.mediaQueries=o.mediaQueries,a.browser.userAgent=o.userAgent,a.browser.features=o.browserFeatures,a.browser.plugins=o.plugins,a.browser.extensions=o.browserExtensions,a.browser.highEntropyValues=o.highEntropyValues,a.browser.etsl=o.etsl,a.browser.maths=o.maths,a.browser.toSourceError=o.toSourceError,a.graphics.webGL=o.webGL,a.graphics.webgpu=o.webgpu,a.graphics.canvas=o.canvas,a.codecs=o.mediaCodecs,a.locale.internationalization=o.internationalization,a.locale.languages=o.languages,a.contexts.iframe=o.iframe,a.contexts.webWorker=o.webWorker,this.fingerprint.nonce=o.nonce,this.fingerprint.time=o.time,this.fingerprint.url=o.url,this.fingerprint.fastBotDetectionDetails=this.runDetectionRules(),this.fingerprint.fastBotDetection=Object.values(this.fingerprint.fastBotDetectionDetails).some(v=>v.detected),this.fingerprint.fsid=this.generateFingerprintScannerId(),n?await this.encryptFingerprint(JSON.stringify(this.fingerprint)):this.fingerprint}}exports.default=dt;
|
|
32
|
+
}`,w=new Blob([m],{type:"application/javascript"});i=URL.createObjectURL(w),n=new Worker(i),a=window.setTimeout(()=>{h(),g(e,l),t(e)},2e3),n.onmessage=function(o){try{e.vendor=o.data.vendor,e.renderer=o.data.renderer,e.userAgent=o.data.userAgent,e.language=o.data.language,e.platform=o.data.platform,e.memory=o.data.memory,e.cpuCount=o.data.cpuCount}catch{g(e,l)}finally{h(),t(e)}},n.onerror=function(){h(),g(e,l),t(e)}}catch{h(),g(e,l),t(e)}})}function _e(){const t={toSourceError:r,hasToSource:!1};try{null.usdfsh}catch(e){t.toSourceError=e.toString()}try{throw"xyz"}catch(e){try{e.toSource(),t.hasToSource=!0}catch{t.hasToSource=!1}}return t}const S=['audio/mp4; codecs="mp4a.40.2"',"audio/mpeg;",'audio/webm; codecs="vorbis"','audio/ogg; codecs="vorbis"','audio/wav; codecs="1"','audio/ogg; codecs="speex"','audio/ogg; codecs="flac"','audio/3gpp; codecs="samr"'],C=['video/mp4; codecs="avc1.42E01E, mp4a.40.2"','video/mp4; codecs="avc1.42E01E"','video/mp4; codecs="avc1.58A01E"','video/mp4; codecs="avc1.4D401E"','video/mp4; codecs="avc1.64001E"','video/mp4; codecs="mp4v.20.8"','video/mp4; codecs="mp4v.20.240"','video/webm; codecs="vp8"','video/ogg; codecs="theora"','video/ogg; codecs="dirac"','video/3gpp; codecs="mp4v.20.8"','video/x-matroska; codecs="theora"'];function A(t,e){const n={};try{const i=document.createElement(e);for(const a of t)try{n[a]=i.canPlayType(a)||null}catch{n[a]=null}}catch{for(const i of t)n[i]=null}return n}function P(t){const e={},n=window.MediaSource;if(!n||typeof n.isTypeSupported!="function"){for(const i of t)e[i]=null;return e}for(const i of t)try{e[i]=n.isTypeSupported(i)}catch{e[i]=null}return e}function M(t){try{const e=window.RTCRtpReceiver;if(e&&typeof e.getCapabilities=="function"){const n=e.getCapabilities(t);return p(JSON.stringify(n))}return s}catch{return l}}function Re(){const t={audioCanPlayTypeHash:s,videoCanPlayTypeHash:s,audioMediaSourceHash:s,videoMediaSourceHash:s,rtcAudioCapabilitiesHash:s,rtcVideoCapabilitiesHash:s,hasMediaSource:!1};try{t.hasMediaSource=!!window.MediaSource;const e=A(S,"audio"),n=A(C,"video");t.audioCanPlayTypeHash=p(JSON.stringify(e)),t.videoCanPlayTypeHash=p(JSON.stringify(n));const i=P(S),a=P(C);t.audioMediaSourceHash=p(JSON.stringify(i)),t.videoMediaSourceHash=p(JSON.stringify(a)),t.rtcAudioCapabilitiesHash=M("audio"),t.rtcVideoCapabilitiesHash=M("video")}catch{g(t,l)}return t}async function Ie(){return new Promise(t=>{try{const e=new Image,n=document.createElement("canvas").getContext("2d");e.onload=()=>{n.drawImage(e,0,0),t(n.getImageData(0,0,1,1).data.filter(i=>i===0).length!=4)},e.onerror=()=>{t(l)},e.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII="}catch{t(l)}})}function Te(){var t=document.createElement("canvas");t.width=400,t.height=200,t.style.display="inline";var e=t.getContext("2d");try{return e.rect(0,0,10,10),e.rect(2,2,6,6),e.textBaseline="alphabetic",e.fillStyle="#f60",e.fillRect(125,1,62,20),e.fillStyle="#069",e.font="11pt no-real-font-123",e.fillText("Cwm fjordbank glyphs vext quiz, 😃",2,15),e.fillStyle="rgba(102, 204, 0, 0.2)",e.font="18pt Arial",e.fillText("Cwm fjordbank glyphs vext quiz, 😃",4,45),e.globalCompositeOperation="multiply",e.fillStyle="rgb(255,0,255)",e.beginPath(),e.arc(50,50,50,0,2*Math.PI,!0),e.closePath(),e.fill(),e.fillStyle="rgb(0,255,255)",e.beginPath(),e.arc(100,50,50,0,2*Math.PI,!0),e.closePath(),e.fill(),e.fillStyle="rgb(255,255,0)",e.beginPath(),e.arc(75,100,50,0,2*Math.PI,!0),e.closePath(),e.fill(),e.fillStyle="rgb(255,0,255)",e.arc(75,75,75,0,2*Math.PI,!0),e.arc(75,75,25,0,2*Math.PI,!0),e.fill("evenodd"),p(t.toDataURL())}catch{return l}}async function Le(){const t={hasModifiedCanvas:r,canvasFingerprint:r};return t.hasModifiedCanvas=await Ie(),t.canvasFingerprint=Te(),t}function Oe(){const t=["deviceMemory","hardwareConcurrency","language","languages","platform"],e=[];for(const n of t){const i=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(navigator),n);i&&i.value?e.push("1"):e.push("0")}return e.join("")}function He(){return Math.random().toString(36).substring(2,15)}function Fe(){return new Date().getTime()}function Ue(){return window.location.href}function x(t,e){const n=t.signals;return e==="iframe"?n.contexts.iframe.webdriver!==n.automation.webdriver||n.contexts.iframe.userAgent!==n.browser.userAgent||n.contexts.iframe.platform!==n.device.platform||n.contexts.iframe.memory!==n.device.memory||n.contexts.iframe.cpuCount!==n.device.cpuCount:n.contexts.webWorker.webdriver!==n.automation.webdriver||n.contexts.webWorker.userAgent!==n.browser.userAgent||n.contexts.webWorker.platform!==n.device.platform||n.contexts.webWorker.memory!==n.device.memory||n.contexts.webWorker.cpuCount!==n.device.cpuCount}function Ve(){const t={bitmask:r,extensions:[]},e=document.body.hasAttribute("data-gr-ext-installed"),n=typeof window.ethereum<"u",i=document.getElementById("coupon-birds-drop-div")!==null,a=document.querySelector("deepl-input-controller")!==null,h=document.getElementById("monica-content-root")!==null,m=document.querySelector("chatgpt-sidebar")!==null,w=typeof window.__REQUESTLY__<"u",o=Array.from(document.querySelectorAll("*")).filter(v=>v.tagName.toLowerCase().startsWith("veepn-")).length>0;return t.bitmask=[e?"1":"0",n?"1":"0",i?"1":"0",a?"1":"0",h?"1":"0",m?"1":"0",w?"1":"0",o?"1":"0"].join(""),e&&t.extensions.push("grammarly"),n&&t.extensions.push("metamask"),i&&t.extensions.push("coupon-birds"),a&&t.extensions.push("deepl"),h&&t.extensions.push("monica-ai"),m&&t.extensions.push("sider-ai"),w&&t.extensions.push("requestly"),o&&t.extensions.push("veepn"),t}function c(t){try{return t()}catch{return!1}}function Ge(){const t={bitmask:r,chrome:c(()=>"chrome"in window),brave:c(()=>"brave"in navigator),applePaySupport:c(()=>"ApplePaySetup"in window),opera:c(()=>typeof window.opr<"u"||typeof window.onoperadetachedviewchange=="object"),serial:c(()=>window.navigator.serial!==void 0),attachShadow:c(()=>!!Element.prototype.attachShadow),caches:c(()=>!!window.caches),webAssembly:c(()=>!!window.WebAssembly&&!!window.WebAssembly.instantiate),buffer:c(()=>"Buffer"in window),showModalDialog:c(()=>"showModalDialog"in window),safari:c(()=>"safari"in window),webkitPrefixedFunction:c(()=>"webkitCancelAnimationFrame"in window),mozPrefixedFunction:c(()=>"mozGetUserMedia"in navigator),usb:c(()=>typeof window.USB=="function"),browserCapture:c(()=>typeof window.BrowserCaptureMediaStreamTrack=="function"),paymentRequestUpdateEvent:c(()=>typeof window.PaymentRequestUpdateEvent=="function"),pressureObserver:c(()=>typeof window.PressureObserver=="function"),audioSession:c(()=>"audioSession"in navigator),selectAudioOutput:c(()=>typeof navigator<"u"&&typeof navigator.mediaDevices<"u"&&typeof navigator.mediaDevices.selectAudioOutput=="function"),barcodeDetector:c(()=>"BarcodeDetector"in window),battery:c(()=>"getBattery"in navigator),devicePosture:c(()=>"DevicePosture"in window),documentPictureInPicture:c(()=>"documentPictureInPicture"in window),eyeDropper:c(()=>"EyeDropper"in window),editContext:c(()=>"EditContext"in window),fencedFrame:c(()=>"FencedFrameConfig"in window),sanitizer:c(()=>"Sanitizer"in window),otpCredential:c(()=>"OTPCredential"in window)},e=Object.keys(t).filter(n=>n!=="bitmask").map(n=>t[n]?"1":"0").join("");return t.bitmask=e,t}function je(){const t={prefersColorScheme:r,prefersReducedMotion:r,prefersReducedTransparency:r,colorGamut:r,pointer:r,anyPointer:r,hover:r,anyHover:r,colorDepth:r};try{window.matchMedia("(prefers-color-scheme: dark)").matches?t.prefersColorScheme="dark":window.matchMedia("(prefers-color-scheme: light)").matches?t.prefersColorScheme="light":t.prefersColorScheme=null,t.prefersReducedMotion=window.matchMedia("(prefers-reduced-motion: reduce)").matches,t.prefersReducedTransparency=window.matchMedia("(prefers-reduced-transparency: reduce)").matches,window.matchMedia("(color-gamut: rec2020)").matches?t.colorGamut="rec2020":window.matchMedia("(color-gamut: p3)").matches?t.colorGamut="p3":window.matchMedia("(color-gamut: srgb)").matches?t.colorGamut="srgb":t.colorGamut=null,window.matchMedia("(pointer: fine)").matches?t.pointer="fine":window.matchMedia("(pointer: coarse)").matches?t.pointer="coarse":window.matchMedia("(pointer: none)").matches?t.pointer="none":t.pointer=null,window.matchMedia("(any-pointer: fine)").matches?t.anyPointer="fine":window.matchMedia("(any-pointer: coarse)").matches?t.anyPointer="coarse":window.matchMedia("(any-pointer: none)").matches?t.anyPointer="none":t.anyPointer=null,t.hover=window.matchMedia("(hover: hover)").matches,t.anyHover=window.matchMedia("(any-hover: hover)").matches;let e=0;for(let n=0;n<=16;n++)window.matchMedia(`(color: ${n})`).matches&&(e=n);t.colorDepth=e}catch{g(t,l)}return t}function Be(t){const e=t.signals.device.screenResolution;return e.width===600&&e.height===800||e.availableWidth===600&&e.availableHeight===800||e.innerWidth===600&&e.innerHeight===800}function Ne(t){return t.signals.automation.webdriver===!0}function ze(t){return!!t.signals.automation.selenium}function $e(t){return t.signals.automation.cdp===!0}function Qe(t){return t.signals.automation.playwright===!0}function qe(t){return typeof t.signals.device.memory!="number"?!1:t.signals.device.memory>32||t.signals.device.memory<.25}function Ke(t){return typeof t.signals.device.cpuCount!="number"?!1:t.signals.device.cpuCount>70}function Je(t){const e=t.signals.browser.userAgent;return t.signals.browser.features.chrome===!1&&typeof e=="string"&&e.includes("Chrome")}function Ye(t){return t.signals.contexts.iframe.webdriver===!0}function Ze(t){return t.signals.contexts.webWorker.webdriver===!0}function Xe(t){const e=t.signals.contexts.webWorker,n=t.signals.graphics.webGL;return e.vendor===l||e.renderer===l||n.vendor===s||n.renderer===s||e.vendor===f?!1:e.vendor!==n.vendor||e.renderer!==n.renderer}function et(t){return t.signals.contexts.webWorker.platform===s||t.signals.contexts.webWorker.platform===l||t.signals.contexts.webWorker.platform===f?!1:t.signals.device.platform!==t.signals.contexts.webWorker.platform}function tt(t){return t.signals.contexts.iframe.platform===s||t.signals.contexts.iframe.platform===l?!1:t.signals.device.platform!==t.signals.contexts.iframe.platform}function rt(t){return t.signals.automation.webdriverWritable===!0}function nt(t){return t.signals.graphics.webGL.renderer.includes("SwiftShader")}function it(t){return t.signals.locale.internationalization.timezone==="UTC"}function at(t){const e=t.signals.locale.languages.languages,n=t.signals.locale.languages.language;return n&&e&&Array.isArray(e)&&e.length>0?e[0]!==n:!1}function ot(t){return!!(t.signals.browser.features.chrome&&t.signals.browser.etsl!==33||t.signals.browser.features.safari&&t.signals.browser.etsl!==37||t.signals.browser.userAgent.includes("Firefox")&&t.signals.browser.etsl!==37)}function st(t){return[t.signals.browser.userAgent,t.signals.contexts.iframe.userAgent,t.signals.contexts.webWorker.userAgent].some(n=>/bot|headless/i.test(n.toLowerCase()))}function ct(t){const e=t.signals.graphics.webgpu,n=t.signals.graphics.webGL,i=t.signals.browser.userAgent;return!!((n.vendor.includes("Apple")||n.renderer.includes("Apple"))&&!i.includes("Mac")||e.vendor.includes("apple")&&!i.includes("Mac")||e.vendor.includes("apple")&&!n.renderer.includes("Apple"))}function lt(t){const e=t.signals.device.platform,n=t.signals.browser.userAgent,i=t.signals.browser.highEntropyValues.platform;return!!(n.includes("Mac")&&(e.includes("Win")||e.includes("Linux"))||n.includes("Windows")&&(e.includes("Mac")||e.includes("Linux"))||n.includes("Linux")&&(e.includes("Mac")||e.includes("Win"))||i!==l&&i!==s&&(i.includes("Mac")&&(e.includes("Win")||e.includes("Linux"))||i.includes("Windows")&&(e.includes("Mac")||e.includes("Linux"))||i.includes("Linux")&&(e.includes("Mac")||e.includes("Win"))))}async function ut(t,e){const n=new TextEncoder().encode(e),i=new TextEncoder().encode(t),a=new Uint8Array(i.length);for(let m=0;m<i.length;m++)a[m]=i[m]^n[m%n.length];const h=String.fromCharCode(...a);return btoa(h)}class dt{constructor(){this.fingerprint={signals:{automation:{webdriver:r,webdriverWritable:r,selenium:r,cdp:r,playwright:r,navigatorPropertyDescriptors:r},device:{cpuCount:r,memory:r,platform:r,screenResolution:{width:r,height:r,pixelDepth:r,colorDepth:r,availableWidth:r,availableHeight:r,innerWidth:r,innerHeight:r,hasMultipleDisplays:r},multimediaDevices:{speakers:r,microphones:r,webcams:r},mediaQueries:{prefersColorScheme:r,prefersReducedMotion:r,prefersReducedTransparency:r,colorGamut:r,pointer:r,anyPointer:r,hover:r,anyHover:r,colorDepth:r}},browser:{userAgent:r,features:{bitmask:r,chrome:r,brave:r,applePaySupport:r,opera:r,serial:r,attachShadow:r,caches:r,webAssembly:r,buffer:r,showModalDialog:r,safari:r,webkitPrefixedFunction:r,mozPrefixedFunction:r,usb:r,browserCapture:r,paymentRequestUpdateEvent:r,pressureObserver:r,audioSession:r,selectAudioOutput:r,barcodeDetector:r,battery:r,devicePosture:r,documentPictureInPicture:r,eyeDropper:r,editContext:r,fencedFrame:r,sanitizer:r,otpCredential:r},plugins:{isValidPluginArray:r,pluginCount:r,pluginNamesHash:r,pluginConsistency1:r,pluginOverflow:r},extensions:{bitmask:r,extensions:r},highEntropyValues:{architecture:r,bitness:r,brands:r,mobile:r,model:r,platform:r,platformVersion:r,uaFullVersion:r},etsl:r,maths:r,toSourceError:{toSourceError:r,hasToSource:r}},graphics:{webGL:{vendor:r,renderer:r},webgpu:{vendor:r,architecture:r,device:r,description:r},canvas:{hasModifiedCanvas:r,canvasFingerprint:r}},codecs:{audioCanPlayTypeHash:r,videoCanPlayTypeHash:r,audioMediaSourceHash:r,videoMediaSourceHash:r,rtcAudioCapabilitiesHash:r,rtcVideoCapabilitiesHash:r,hasMediaSource:r},locale:{internationalization:{timezone:r,localeLanguage:r},languages:{languages:r,language:r}},contexts:{iframe:{webdriver:r,userAgent:r,platform:r,memory:r,cpuCount:r,language:r},webWorker:{webdriver:r,userAgent:r,platform:r,memory:r,cpuCount:r,language:r,vendor:r,renderer:r}}},fsid:r,nonce:r,time:r,url:r,fastBotDetection:!1,fastBotDetectionDetails:{headlessChromeScreenResolution:{detected:!1,severity:"high"},hasWebdriver:{detected:!1,severity:"high"},hasWebdriverWritable:{detected:!1,severity:"high"},hasSeleniumProperty:{detected:!1,severity:"high"},hasCDP:{detected:!1,severity:"high"},hasPlaywright:{detected:!1,severity:"high"},hasImpossibleDeviceMemory:{detected:!1,severity:"high"},hasHighCPUCount:{detected:!1,severity:"high"},hasMissingChromeObject:{detected:!1,severity:"high"},hasWebdriverIframe:{detected:!1,severity:"high"},hasWebdriverWorker:{detected:!1,severity:"high"},hasMismatchWebGLInWorker:{detected:!1,severity:"high"},hasMismatchPlatformIframe:{detected:!1,severity:"high"},hasMismatchPlatformWorker:{detected:!1,severity:"high"},hasSwiftshaderRenderer:{detected:!1,severity:"low"},hasUTCTimezone:{detected:!1,severity:"medium"},hasMismatchLanguages:{detected:!1,severity:"low"},hasInconsistentEtsl:{detected:!1,severity:"high"},hasBotUserAgent:{detected:!1,severity:"high"},hasGPUMismatch:{detected:!1,severity:"high"},hasPlatformMismatch:{detected:!1,severity:"high"}}}}async collectSignal(e){try{return await e()}catch{return l}}generateFingerprintScannerId(){try{const e=this.fingerprint.signals,n=this.fingerprint.fastBotDetectionDetails,i="FS1",h=[n.headlessChromeScreenResolution.detected,n.hasWebdriver.detected,n.hasWebdriverWritable.detected,n.hasSeleniumProperty.detected,n.hasCDP.detected,n.hasPlaywright.detected,n.hasImpossibleDeviceMemory.detected,n.hasHighCPUCount.detected,n.hasMissingChromeObject.detected,n.hasWebdriverIframe.detected,n.hasWebdriverWorker.detected,n.hasMismatchWebGLInWorker.detected,n.hasMismatchPlatformIframe.detected,n.hasMismatchPlatformWorker.detected,n.hasSwiftshaderRenderer.detected,n.hasUTCTimezone.detected,n.hasMismatchLanguages.detected,n.hasInconsistentEtsl.detected,n.hasBotUserAgent.detected,n.hasGPUMismatch.detected,n.hasPlatformMismatch.detected].map(u=>u?"1":"0").join(""),m=[e.automation.webdriver===!0,e.automation.webdriverWritable===!0,e.automation.selenium===!0,e.automation.cdp===!0,e.automation.playwright===!0].map(u=>u?"1":"0").join(""),w=p(String(e.automation.navigatorPropertyDescriptors)).slice(0,4),o=`${m}h${w}`,v=typeof e.device.screenResolution.width=="number"?e.device.screenResolution.width:0,y=typeof e.device.screenResolution.height=="number"?e.device.screenResolution.height:0,W=typeof e.device.cpuCount=="number"?String(e.device.cpuCount).padStart(2,"0"):"00",E=typeof e.device.memory=="number"?String(Math.round(e.device.memory)).padStart(2,"0"):"00",k=[e.device.screenResolution.hasMultipleDisplays===!0,e.device.mediaQueries.prefersReducedMotion===!0,e.device.mediaQueries.prefersReducedTransparency===!0,e.device.mediaQueries.hover===!0,e.device.mediaQueries.anyHover===!0].map(u=>u?"1":"0").join(""),D=[e.device.platform,e.device.screenResolution.pixelDepth,e.device.screenResolution.colorDepth,e.device.multimediaDevices.speakers,e.device.multimediaDevices.microphones,e.device.multimediaDevices.webcams,e.device.mediaQueries.prefersColorScheme,e.device.mediaQueries.colorGamut,e.device.mediaQueries.pointer,e.device.mediaQueries.anyPointer,e.device.mediaQueries.colorDepth].map(u=>String(u)).join("|"),_=p(D).slice(0,6),R=`${v}x${y}c${W}m${E}b${k}h${_}`,I=typeof e.browser.features.bitmask=="string"?e.browser.features.bitmask:"0000000000",T=typeof e.browser.extensions.bitmask=="string"?e.browser.extensions.bitmask:"00000000",L=[e.browser.plugins.isValidPluginArray===!0,e.browser.plugins.pluginConsistency1===!0,e.browser.plugins.pluginOverflow===!0,e.browser.toSourceError.hasToSource===!0].map(u=>u?"1":"0").join(""),O=[e.browser.userAgent,e.browser.etsl,e.browser.maths,e.browser.plugins.pluginCount,e.browser.plugins.pluginNamesHash,e.browser.toSourceError.toSourceError,e.browser.highEntropyValues.architecture,e.browser.highEntropyValues.bitness,e.browser.highEntropyValues.platform,e.browser.highEntropyValues.platformVersion,e.browser.highEntropyValues.uaFullVersion,e.browser.highEntropyValues.mobile].map(u=>String(u)).join("|"),H=p(O).slice(0,6),F=`f${I}e${T}p${L}h${H}`,U=[e.graphics.canvas.hasModifiedCanvas===!0].map(u=>u?"1":"0").join(""),V=[e.graphics.webGL.vendor,e.graphics.webGL.renderer,e.graphics.webgpu.vendor,e.graphics.webgpu.architecture,e.graphics.webgpu.device,e.graphics.webgpu.description,e.graphics.canvas.canvasFingerprint].map(u=>String(u)).join("|"),G=p(V).slice(0,6),j=`${U}h${G}`,B=[e.codecs.hasMediaSource===!0].map(u=>u?"1":"0").join(""),N=[e.codecs.audioCanPlayTypeHash,e.codecs.videoCanPlayTypeHash,e.codecs.audioMediaSourceHash,e.codecs.videoMediaSourceHash,e.codecs.rtcAudioCapabilitiesHash,e.codecs.rtcVideoCapabilitiesHash].map(u=>String(u)).join("|"),z=p(N).slice(0,6),$=`${B}h${z}`,Q=typeof e.locale.languages.language=="string"?e.locale.languages.language.slice(0,2).toLowerCase():"xx",q=Array.isArray(e.locale.languages.languages)?e.locale.languages.languages.length:0,K=(typeof e.locale.internationalization.timezone=="string"?e.locale.internationalization.timezone:"unknown").replace(/[\/\s]/g,"-"),J=[e.locale.internationalization.timezone,e.locale.internationalization.localeLanguage,Array.isArray(e.locale.languages.languages)?e.locale.languages.languages.join(","):e.locale.languages.languages,e.locale.languages.language].map(u=>String(u)).join("|"),Y=p(J).slice(0,4),Z=`${Q}${q}t${K}_h${Y}`,X=[x(this.fingerprint,"iframe"),x(this.fingerprint,"worker"),e.contexts.iframe.webdriver===!0,e.contexts.webWorker.webdriver===!0].map(u=>u?"1":"0").join(""),ee=[e.contexts.iframe.userAgent,e.contexts.iframe.platform,e.contexts.iframe.memory,e.contexts.iframe.cpuCount,e.contexts.iframe.language,e.contexts.webWorker.userAgent,e.contexts.webWorker.platform,e.contexts.webWorker.memory,e.contexts.webWorker.cpuCount,e.contexts.webWorker.language,e.contexts.webWorker.vendor,e.contexts.webWorker.renderer].map(u=>String(u)).join("|"),te=p(ee).slice(0,6),re=`${X}h${te}`;return[i,h,o,R,F,j,$,Z,re].join("_")}catch(e){return console.error("Error generating fingerprint scanner id",e),l}}async encryptFingerprint(e){const n="__DEFAULT_FPSCANNER_KEY__";return n.length>20&&n.indexOf("DEFAULT")>0&&n.indexOf("FPSCANNER")>0&&console.warn('[fpscanner] WARNING: Using default encryption key! Run "npx fpscanner build --key=your-secret-key" to inject your own key. See: https://github.com/antoinevastel/fpscanner#advanced-custom-builds'),await ut(JSON.stringify(e),n)}getDetectionRules(){return[{name:"headlessChromeScreenResolution",severity:d,test:Be},{name:"hasWebdriver",severity:d,test:Ne},{name:"hasWebdriverWritable",severity:d,test:rt},{name:"hasSeleniumProperty",severity:d,test:ze},{name:"hasCDP",severity:d,test:$e},{name:"hasPlaywright",severity:d,test:Qe},{name:"hasImpossibleDeviceMemory",severity:d,test:qe},{name:"hasHighCPUCount",severity:d,test:Ke},{name:"hasMissingChromeObject",severity:d,test:Je},{name:"hasWebdriverIframe",severity:d,test:Ye},{name:"hasWebdriverWorker",severity:d,test:Ze},{name:"hasMismatchWebGLInWorker",severity:d,test:Xe},{name:"hasMismatchPlatformIframe",severity:d,test:tt},{name:"hasMismatchPlatformWorker",severity:d,test:et},{name:"hasSwiftshaderRenderer",severity:b,test:nt},{name:"hasUTCTimezone",severity:oe,test:it},{name:"hasMismatchLanguages",severity:b,test:at},{name:"hasInconsistentEtsl",severity:d,test:ot},{name:"hasBotUserAgent",severity:d,test:st},{name:"hasGPUMismatch",severity:d,test:ct},{name:"hasPlatformMismatch",severity:d,test:lt}]}runDetectionRules(){const e=this.getDetectionRules(),n={headlessChromeScreenResolution:{detected:!1,severity:"high"},hasWebdriver:{detected:!1,severity:"high"},hasWebdriverWritable:{detected:!1,severity:"high"},hasSeleniumProperty:{detected:!1,severity:"high"},hasCDP:{detected:!1,severity:"high"},hasPlaywright:{detected:!1,severity:"high"},hasImpossibleDeviceMemory:{detected:!1,severity:"high"},hasHighCPUCount:{detected:!1,severity:"high"},hasMissingChromeObject:{detected:!1,severity:"high"},hasWebdriverIframe:{detected:!1,severity:"high"},hasWebdriverWorker:{detected:!1,severity:"high"},hasMismatchWebGLInWorker:{detected:!1,severity:"high"},hasMismatchPlatformIframe:{detected:!1,severity:"high"},hasMismatchPlatformWorker:{detected:!1,severity:"high"},hasSwiftshaderRenderer:{detected:!1,severity:"low"},hasUTCTimezone:{detected:!1,severity:"medium"},hasMismatchLanguages:{detected:!1,severity:"low"},hasInconsistentEtsl:{detected:!1,severity:"high"},hasBotUserAgent:{detected:!1,severity:"high"},hasGPUMismatch:{detected:!1,severity:"high"},hasPlatformMismatch:{detected:!1,severity:"high"}};for(const i of e)try{const a=i.test(this.fingerprint);n[i.name]={detected:a,severity:i.severity}}catch{n[i.name]={detected:!1,severity:i.severity}}return n}async collectFingerprint(e={encrypt:!0}){const{encrypt:n=!0,skipWorker:i=!1}=e,a=this.fingerprint.signals,h={webdriver:this.collectSignal(ne),webdriverWritable:this.collectSignal(be),selenium:this.collectSignal(ye),cdp:this.collectSignal(ce),playwright:this.collectSignal(ue),navigatorPropertyDescriptors:this.collectSignal(Oe),cpuCount:this.collectSignal(de),memory:this.collectSignal(he),platform:this.collectSignal(ae),screenResolution:this.collectSignal(fe),multimediaDevices:this.collectSignal(Ee),mediaQueries:this.collectSignal(je),userAgent:this.collectSignal(ie),browserFeatures:this.collectSignal(Ge),plugins:this.collectSignal(We),browserExtensions:this.collectSignal(Ve),highEntropyValues:this.collectSignal(Se),etsl:this.collectSignal(me),maths:this.collectSignal(ge),toSourceError:this.collectSignal(_e),webGL:this.collectSignal(le),webgpu:this.collectSignal(we),canvas:this.collectSignal(Le),mediaCodecs:this.collectSignal(Re),internationalization:this.collectSignal(pe),languages:this.collectSignal(ve),iframe:this.collectSignal(ke),webWorker:i?Promise.resolve({webdriver:f,userAgent:f,platform:f,memory:f,cpuCount:f,language:f,vendor:f,renderer:f}):this.collectSignal(De),nonce:this.collectSignal(He),time:this.collectSignal(Fe),url:this.collectSignal(Ue)},m=Object.keys(h),w=await Promise.all(Object.values(h)),o=Object.fromEntries(m.map((v,y)=>[v,w[y]]));return a.automation.webdriver=o.webdriver,a.automation.webdriverWritable=o.webdriverWritable,a.automation.selenium=o.selenium,a.automation.cdp=o.cdp,a.automation.playwright=o.playwright,a.automation.navigatorPropertyDescriptors=o.navigatorPropertyDescriptors,a.device.cpuCount=o.cpuCount,a.device.memory=o.memory,a.device.platform=o.platform,a.device.screenResolution=o.screenResolution,a.device.multimediaDevices=o.multimediaDevices,a.device.mediaQueries=o.mediaQueries,a.browser.userAgent=o.userAgent,a.browser.features=o.browserFeatures,a.browser.plugins=o.plugins,a.browser.extensions=o.browserExtensions,a.browser.highEntropyValues=o.highEntropyValues,a.browser.etsl=o.etsl,a.browser.maths=o.maths,a.browser.toSourceError=o.toSourceError,a.graphics.webGL=o.webGL,a.graphics.webgpu=o.webgpu,a.graphics.canvas=o.canvas,a.codecs=o.mediaCodecs,a.locale.internationalization=o.internationalization,a.locale.languages=o.languages,a.contexts.iframe=o.iframe,a.contexts.webWorker=o.webWorker,this.fingerprint.nonce=o.nonce,this.fingerprint.time=o.time,this.fingerprint.url=o.url,this.fingerprint.fastBotDetectionDetails=this.runDetectionRules(),this.fingerprint.fastBotDetection=Object.values(this.fingerprint.fastBotDetectionDetails).some(v=>v.detected),this.fingerprint.fsid=this.generateFingerprintScannerId(),n?await this.encryptFingerprint(JSON.stringify(this.fingerprint)):this.fingerprint}}exports.default=dt;
|
package/dist/fpScanner.es.js
CHANGED
|
@@ -225,7 +225,7 @@ function Ae() {
|
|
|
225
225
|
function Pe() {
|
|
226
226
|
return navigator.plugins ? navigator.plugins.length : s;
|
|
227
227
|
}
|
|
228
|
-
function
|
|
228
|
+
function xe() {
|
|
229
229
|
if (!navigator.plugins) return s;
|
|
230
230
|
try {
|
|
231
231
|
return navigator.plugins[0] === navigator.plugins[0][0].enabledPlugin;
|
|
@@ -250,13 +250,13 @@ function Me() {
|
|
|
250
250
|
pluginOverflow: r
|
|
251
251
|
};
|
|
252
252
|
try {
|
|
253
|
-
t.isValidPluginArray = Ce(), t.pluginCount = Pe(), t.pluginNamesHash = Ae(), t.pluginConsistency1 =
|
|
253
|
+
t.isValidPluginArray = Ce(), t.pluginCount = Pe(), t.pluginNamesHash = Ae(), t.pluginConsistency1 = xe(), t.pluginOverflow = We();
|
|
254
254
|
} catch {
|
|
255
255
|
h(t, l);
|
|
256
256
|
}
|
|
257
257
|
return t;
|
|
258
258
|
}
|
|
259
|
-
async function
|
|
259
|
+
async function Ee() {
|
|
260
260
|
return new Promise(async function(t) {
|
|
261
261
|
var e = {
|
|
262
262
|
audiooutput: 0,
|
|
@@ -336,8 +336,9 @@ async function De() {
|
|
|
336
336
|
fingerprintWorker.vendor = 'INIT';
|
|
337
337
|
fingerprintWorker.renderer = 'INIT';
|
|
338
338
|
var gl = canvas.getContext('webgl');
|
|
339
|
+
const isFirefox = navigator.userAgent.includes('Firefox');
|
|
339
340
|
try {
|
|
340
|
-
if (gl) {
|
|
341
|
+
if (gl && !isFirefox) {
|
|
341
342
|
var glExt = gl.getExtension('WEBGL_debug_renderer_info');
|
|
342
343
|
fingerprintWorker.vendor = gl.getParameter(glExt.UNMASKED_VENDOR_WEBGL);
|
|
343
344
|
fingerprintWorker.renderer = gl.getParameter(glExt.UNMASKED_RENDERER_WEBGL);
|
|
@@ -446,7 +447,7 @@ function P(t) {
|
|
|
446
447
|
}
|
|
447
448
|
return e;
|
|
448
449
|
}
|
|
449
|
-
function
|
|
450
|
+
function x(t) {
|
|
450
451
|
try {
|
|
451
452
|
const e = window.RTCRtpReceiver;
|
|
452
453
|
if (e && typeof e.getCapabilities == "function") {
|
|
@@ -473,7 +474,7 @@ function Re() {
|
|
|
473
474
|
const e = A(S, "audio"), n = A(C, "video");
|
|
474
475
|
t.audioCanPlayTypeHash = p(JSON.stringify(e)), t.videoCanPlayTypeHash = p(JSON.stringify(n));
|
|
475
476
|
const i = P(S), a = P(C);
|
|
476
|
-
t.audioMediaSourceHash = p(JSON.stringify(i)), t.videoMediaSourceHash = p(JSON.stringify(a)), t.rtcAudioCapabilitiesHash =
|
|
477
|
+
t.audioMediaSourceHash = p(JSON.stringify(i)), t.videoMediaSourceHash = p(JSON.stringify(a)), t.rtcAudioCapabilitiesHash = x("audio"), t.rtcVideoCapabilitiesHash = x("video");
|
|
477
478
|
} catch {
|
|
478
479
|
h(t, l);
|
|
479
480
|
}
|
|
@@ -493,7 +494,7 @@ async function Ie() {
|
|
|
493
494
|
}
|
|
494
495
|
});
|
|
495
496
|
}
|
|
496
|
-
function
|
|
497
|
+
function Le() {
|
|
497
498
|
var t = document.createElement("canvas");
|
|
498
499
|
t.width = 400, t.height = 200, t.style.display = "inline";
|
|
499
500
|
var e = t.getContext("2d");
|
|
@@ -503,14 +504,14 @@ function Te() {
|
|
|
503
504
|
return l;
|
|
504
505
|
}
|
|
505
506
|
}
|
|
506
|
-
async function
|
|
507
|
+
async function Te() {
|
|
507
508
|
const t = {
|
|
508
509
|
hasModifiedCanvas: r,
|
|
509
510
|
canvasFingerprint: r
|
|
510
511
|
};
|
|
511
|
-
return t.hasModifiedCanvas = await Ie(), t.canvasFingerprint =
|
|
512
|
+
return t.hasModifiedCanvas = await Ie(), t.canvasFingerprint = Le(), t;
|
|
512
513
|
}
|
|
513
|
-
function
|
|
514
|
+
function He() {
|
|
514
515
|
const t = ["deviceMemory", "hardwareConcurrency", "language", "languages", "platform"], e = [];
|
|
515
516
|
for (const n of t) {
|
|
516
517
|
const i = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(navigator), n);
|
|
@@ -518,20 +519,20 @@ function Oe() {
|
|
|
518
519
|
}
|
|
519
520
|
return e.join("");
|
|
520
521
|
}
|
|
521
|
-
function
|
|
522
|
+
function Oe() {
|
|
522
523
|
return Math.random().toString(36).substring(2, 15);
|
|
523
524
|
}
|
|
524
|
-
function
|
|
525
|
+
function Fe() {
|
|
525
526
|
return (/* @__PURE__ */ new Date()).getTime();
|
|
526
527
|
}
|
|
527
|
-
function
|
|
528
|
+
function Ue() {
|
|
528
529
|
return window.location.href;
|
|
529
530
|
}
|
|
530
531
|
function W(t, e) {
|
|
531
532
|
const n = t.signals;
|
|
532
533
|
return e === "iframe" ? n.contexts.iframe.webdriver !== n.automation.webdriver || n.contexts.iframe.userAgent !== n.browser.userAgent || n.contexts.iframe.platform !== n.device.platform || n.contexts.iframe.memory !== n.device.memory || n.contexts.iframe.cpuCount !== n.device.cpuCount : n.contexts.webWorker.webdriver !== n.automation.webdriver || n.contexts.webWorker.userAgent !== n.browser.userAgent || n.contexts.webWorker.platform !== n.device.platform || n.contexts.webWorker.memory !== n.device.memory || n.contexts.webWorker.cpuCount !== n.device.cpuCount;
|
|
533
534
|
}
|
|
534
|
-
function
|
|
535
|
+
function Ve() {
|
|
535
536
|
const t = {
|
|
536
537
|
bitmask: r,
|
|
537
538
|
extensions: []
|
|
@@ -682,7 +683,7 @@ function ct(t) {
|
|
|
682
683
|
}
|
|
683
684
|
function lt(t) {
|
|
684
685
|
const e = t.signals.device.platform, n = t.signals.browser.userAgent, i = t.signals.browser.highEntropyValues.platform;
|
|
685
|
-
return !!(n.includes("Mac") &&
|
|
686
|
+
return !!(n.includes("Mac") && (e.includes("Win") || e.includes("Linux")) || n.includes("Windows") && (e.includes("Mac") || e.includes("Linux")) || n.includes("Linux") && (e.includes("Mac") || e.includes("Win")) || i !== l && i !== s && (i.includes("Mac") && (e.includes("Win") || e.includes("Linux")) || i.includes("Windows") && (e.includes("Mac") || e.includes("Linux")) || i.includes("Linux") && (e.includes("Mac") || e.includes("Win"))));
|
|
686
687
|
}
|
|
687
688
|
async function ut(t, e) {
|
|
688
689
|
const n = new TextEncoder().encode(e), i = new TextEncoder().encode(t), a = new Uint8Array(i.length);
|
|
@@ -949,7 +950,7 @@ class ht {
|
|
|
949
950
|
e.automation.selenium === !0,
|
|
950
951
|
e.automation.cdp === !0,
|
|
951
952
|
e.automation.playwright === !0
|
|
952
|
-
].map((u) => u ? "1" : "0").join(""), w = p(String(e.automation.navigatorPropertyDescriptors)).slice(0, 4), o = `${m}h${w}`, v = typeof e.device.screenResolution.width == "number" ? e.device.screenResolution.width : 0, y = typeof e.device.screenResolution.height == "number" ? e.device.screenResolution.height : 0, M = typeof e.device.cpuCount == "number" ? String(e.device.cpuCount).padStart(2, "0") : "00",
|
|
953
|
+
].map((u) => u ? "1" : "0").join(""), w = p(String(e.automation.navigatorPropertyDescriptors)).slice(0, 4), o = `${m}h${w}`, v = typeof e.device.screenResolution.width == "number" ? e.device.screenResolution.width : 0, y = typeof e.device.screenResolution.height == "number" ? e.device.screenResolution.height : 0, M = typeof e.device.cpuCount == "number" ? String(e.device.cpuCount).padStart(2, "0") : "00", E = typeof e.device.memory == "number" ? String(Math.round(e.device.memory)).padStart(2, "0") : "00", k = [
|
|
953
954
|
e.device.screenResolution.hasMultipleDisplays === !0,
|
|
954
955
|
e.device.mediaQueries.prefersReducedMotion === !0,
|
|
955
956
|
e.device.mediaQueries.prefersReducedTransparency === !0,
|
|
@@ -967,12 +968,12 @@ class ht {
|
|
|
967
968
|
e.device.mediaQueries.pointer,
|
|
968
969
|
e.device.mediaQueries.anyPointer,
|
|
969
970
|
e.device.mediaQueries.colorDepth
|
|
970
|
-
].map((u) => String(u)).join("|"), _ = p(D).slice(0, 6), R = `${v}x${y}c${M}m${
|
|
971
|
+
].map((u) => String(u)).join("|"), _ = p(D).slice(0, 6), R = `${v}x${y}c${M}m${E}b${k}h${_}`, I = typeof e.browser.features.bitmask == "string" ? e.browser.features.bitmask : "0000000000", L = typeof e.browser.extensions.bitmask == "string" ? e.browser.extensions.bitmask : "00000000", T = [
|
|
971
972
|
e.browser.plugins.isValidPluginArray === !0,
|
|
972
973
|
e.browser.plugins.pluginConsistency1 === !0,
|
|
973
974
|
e.browser.plugins.pluginOverflow === !0,
|
|
974
975
|
e.browser.toSourceError.hasToSource === !0
|
|
975
|
-
].map((u) => u ? "1" : "0").join(""),
|
|
976
|
+
].map((u) => u ? "1" : "0").join(""), H = [
|
|
976
977
|
e.browser.userAgent,
|
|
977
978
|
e.browser.etsl,
|
|
978
979
|
e.browser.maths,
|
|
@@ -985,9 +986,9 @@ class ht {
|
|
|
985
986
|
e.browser.highEntropyValues.platformVersion,
|
|
986
987
|
e.browser.highEntropyValues.uaFullVersion,
|
|
987
988
|
e.browser.highEntropyValues.mobile
|
|
988
|
-
].map((u) => String(u)).join("|"),
|
|
989
|
+
].map((u) => String(u)).join("|"), O = p(H).slice(0, 6), F = `f${I}e${L}p${T}h${O}`, U = [
|
|
989
990
|
e.graphics.canvas.hasModifiedCanvas === !0
|
|
990
|
-
].map((u) => u ? "1" : "0").join(""),
|
|
991
|
+
].map((u) => u ? "1" : "0").join(""), V = [
|
|
991
992
|
e.graphics.webGL.vendor,
|
|
992
993
|
e.graphics.webGL.renderer,
|
|
993
994
|
e.graphics.webgpu.vendor,
|
|
@@ -995,7 +996,7 @@ class ht {
|
|
|
995
996
|
e.graphics.webgpu.device,
|
|
996
997
|
e.graphics.webgpu.description,
|
|
997
998
|
e.graphics.canvas.canvasFingerprint
|
|
998
|
-
].map((u) => String(u)).join("|"), G = p(
|
|
999
|
+
].map((u) => String(u)).join("|"), G = p(V).slice(0, 6), B = `${U}h${G}`, j = [
|
|
999
1000
|
e.codecs.hasMediaSource === !0
|
|
1000
1001
|
].map((u) => u ? "1" : "0").join(""), N = [
|
|
1001
1002
|
e.codecs.audioCanPlayTypeHash,
|
|
@@ -1033,7 +1034,7 @@ class ht {
|
|
|
1033
1034
|
g,
|
|
1034
1035
|
o,
|
|
1035
1036
|
R,
|
|
1036
|
-
|
|
1037
|
+
F,
|
|
1037
1038
|
B,
|
|
1038
1039
|
$,
|
|
1039
1040
|
Z,
|
|
@@ -1118,19 +1119,19 @@ class ht {
|
|
|
1118
1119
|
selenium: this.collectSignal(ye),
|
|
1119
1120
|
cdp: this.collectSignal(ce),
|
|
1120
1121
|
playwright: this.collectSignal(ue),
|
|
1121
|
-
navigatorPropertyDescriptors: this.collectSignal(
|
|
1122
|
+
navigatorPropertyDescriptors: this.collectSignal(He),
|
|
1122
1123
|
// Device signals
|
|
1123
1124
|
cpuCount: this.collectSignal(de),
|
|
1124
1125
|
memory: this.collectSignal(ge),
|
|
1125
1126
|
platform: this.collectSignal(ae),
|
|
1126
1127
|
screenResolution: this.collectSignal(fe),
|
|
1127
|
-
multimediaDevices: this.collectSignal(
|
|
1128
|
+
multimediaDevices: this.collectSignal(Ee),
|
|
1128
1129
|
mediaQueries: this.collectSignal(Be),
|
|
1129
1130
|
// Browser signals
|
|
1130
1131
|
userAgent: this.collectSignal(ie),
|
|
1131
1132
|
browserFeatures: this.collectSignal(Ge),
|
|
1132
1133
|
plugins: this.collectSignal(Me),
|
|
1133
|
-
browserExtensions: this.collectSignal(
|
|
1134
|
+
browserExtensions: this.collectSignal(Ve),
|
|
1134
1135
|
highEntropyValues: this.collectSignal(Se),
|
|
1135
1136
|
etsl: this.collectSignal(me),
|
|
1136
1137
|
maths: this.collectSignal(he),
|
|
@@ -1138,7 +1139,7 @@ class ht {
|
|
|
1138
1139
|
// Graphics signals
|
|
1139
1140
|
webGL: this.collectSignal(le),
|
|
1140
1141
|
webgpu: this.collectSignal(we),
|
|
1141
|
-
canvas: this.collectSignal(
|
|
1142
|
+
canvas: this.collectSignal(Te),
|
|
1142
1143
|
// Codecs
|
|
1143
1144
|
mediaCodecs: this.collectSignal(Re),
|
|
1144
1145
|
// Locale signals
|
|
@@ -1157,9 +1158,9 @@ class ht {
|
|
|
1157
1158
|
renderer: f
|
|
1158
1159
|
}) : this.collectSignal(De),
|
|
1159
1160
|
// Meta signals
|
|
1160
|
-
nonce: this.collectSignal(
|
|
1161
|
-
time: this.collectSignal(
|
|
1162
|
-
url: this.collectSignal(
|
|
1161
|
+
nonce: this.collectSignal(Oe),
|
|
1162
|
+
time: this.collectSignal(Fe),
|
|
1163
|
+
url: this.collectSignal(Ue)
|
|
1163
1164
|
}, m = Object.keys(g), w = await Promise.all(Object.values(g)), o = Object.fromEntries(m.map((v, y) => [v, w[y]]));
|
|
1164
1165
|
return a.automation.webdriver = o.webdriver, a.automation.webdriverWritable = o.webdriverWritable, a.automation.selenium = o.selenium, a.automation.cdp = o.cdp, a.automation.playwright = o.playwright, a.automation.navigatorPropertyDescriptors = o.navigatorPropertyDescriptors, a.device.cpuCount = o.cpuCount, a.device.memory = o.memory, a.device.platform = o.platform, a.device.screenResolution = o.screenResolution, a.device.multimediaDevices = o.multimediaDevices, a.device.mediaQueries = o.mediaQueries, a.browser.userAgent = o.userAgent, a.browser.features = o.browserFeatures, a.browser.plugins = o.plugins, a.browser.extensions = o.browserExtensions, a.browser.highEntropyValues = o.highEntropyValues, a.browser.etsl = o.etsl, a.browser.maths = o.maths, a.browser.toSourceError = o.toSourceError, a.graphics.webGL = o.webGL, a.graphics.webgpu = o.webgpu, a.graphics.canvas = o.canvas, a.codecs = o.mediaCodecs, a.locale.internationalization = o.internationalization, a.locale.languages = o.languages, a.contexts.iframe = o.iframe, a.contexts.webWorker = o.webWorker, this.fingerprint.nonce = o.nonce, this.fingerprint.time = o.time, this.fingerprint.url = o.url, this.fingerprint.fastBotDetectionDetails = this.runDetectionRules(), this.fingerprint.fastBotDetection = Object.values(this.fingerprint.fastBotDetectionDetails).some((v) => v.detected), this.fingerprint.fsid = this.generateFingerprintScannerId(), n ? await this.encryptFingerprint(JSON.stringify(this.fingerprint)) : this.fingerprint;
|
|
1165
1166
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/signals/worker.ts"],"names":[],"mappings":"AAEA,wBAAsB,MAAM,
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/signals/worker.ts"],"names":[],"mappings":"AAEA,wBAAsB,MAAM,qBAkG3B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fpscanner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "A lightweight browser fingerprinting and bot detection library with encryption, obfuscation, and cross-context validation",
|
|
5
5
|
"main": "dist/fpScanner.cjs.js",
|
|
6
6
|
"module": "dist/fpScanner.es.js",
|
package/scripts/build-custom.js
CHANGED
|
@@ -39,6 +39,35 @@ module.exports = async function build(args) {
|
|
|
39
39
|
console.log(` Obfuscation: ${skipObfuscation ? 'disabled' : 'enabled'}`);
|
|
40
40
|
console.log('');
|
|
41
41
|
|
|
42
|
+
// Step 0: Backup/Restore mechanism to ensure idempotent builds
|
|
43
|
+
// This allows running the build multiple times without re-obfuscating already obfuscated code
|
|
44
|
+
console.log('🔄 Step 0/6: Ensuring clean build state...');
|
|
45
|
+
let restoredFromBackup = false;
|
|
46
|
+
|
|
47
|
+
for (const file of files) {
|
|
48
|
+
const filePath = path.join(distDir, file);
|
|
49
|
+
const backupPath = filePath + '.original';
|
|
50
|
+
|
|
51
|
+
if (!fs.existsSync(filePath)) {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (fs.existsSync(backupPath)) {
|
|
56
|
+
// Backup exists - restore from it to ensure clean state
|
|
57
|
+
fs.copyFileSync(backupPath, filePath);
|
|
58
|
+
restoredFromBackup = true;
|
|
59
|
+
} else {
|
|
60
|
+
// First run - create backup of pristine files
|
|
61
|
+
fs.copyFileSync(filePath, backupPath);
|
|
62
|
+
console.log(` 📦 Created backup: ${file}.original`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (restoredFromBackup) {
|
|
67
|
+
console.log(' ✓ Restored files from backups (clean state for build)');
|
|
68
|
+
}
|
|
69
|
+
console.log('');
|
|
70
|
+
|
|
42
71
|
// Check if we can build from source (more reliable than string replacement)
|
|
43
72
|
const viteConfigPath = path.join(packageDir, 'vite.config.ts');
|
|
44
73
|
const canBuildFromSource = fs.existsSync(viteConfigPath);
|
|
@@ -46,7 +75,7 @@ module.exports = async function build(args) {
|
|
|
46
75
|
if (canBuildFromSource) {
|
|
47
76
|
// Preferred method: Build from source with key injected via environment variable
|
|
48
77
|
// This is more reliable as Vite's define properly replaces the key during the build
|
|
49
|
-
console.log('📦 Step
|
|
78
|
+
console.log('📦 Step 1/6: Building from source with injected key...');
|
|
50
79
|
console.log(' (This is more reliable than post-build string replacement)');
|
|
51
80
|
try {
|
|
52
81
|
execSync('npm run build:vite', {
|
|
@@ -64,14 +93,14 @@ module.exports = async function build(args) {
|
|
|
64
93
|
stdio: 'inherit',
|
|
65
94
|
});
|
|
66
95
|
console.log('');
|
|
67
|
-
console.log('
|
|
96
|
+
console.log(' ✓ Key injected during build');
|
|
68
97
|
} catch (err) {
|
|
69
98
|
throw new Error('Build from source failed. Make sure vite is installed (npm install)');
|
|
70
99
|
}
|
|
71
100
|
} else {
|
|
72
101
|
// Fallback method: String replacement in pre-built dist files
|
|
73
102
|
// Used when vite.config.ts is not available (npm consumers without dev dependencies)
|
|
74
|
-
console.log('📦 Step 1/
|
|
103
|
+
console.log('📦 Step 1/6: Injecting encryption key via string replacement...');
|
|
75
104
|
console.log(' (Fallback method - vite.config.ts not found)');
|
|
76
105
|
|
|
77
106
|
let keyInjected = false;
|
|
@@ -120,12 +149,12 @@ module.exports = async function build(args) {
|
|
|
120
149
|
|
|
121
150
|
// Step 2: Skip TypeScript declarations (already generated)
|
|
122
151
|
console.log('');
|
|
123
|
-
console.log('⏭️ Step 2/
|
|
152
|
+
console.log('⏭️ Step 2/6: TypeScript declarations already present, skipping...');
|
|
124
153
|
|
|
125
154
|
// Step 3: Obfuscate (optional)
|
|
126
155
|
if (!skipObfuscation) {
|
|
127
156
|
console.log('');
|
|
128
|
-
console.log('🔒 Step 3/
|
|
157
|
+
console.log('🔒 Step 3/6: Obfuscating output...');
|
|
129
158
|
|
|
130
159
|
let JavaScriptObfuscator;
|
|
131
160
|
try {
|
|
@@ -171,7 +200,7 @@ module.exports = async function build(args) {
|
|
|
171
200
|
|
|
172
201
|
// Step 4: Minify with Terser
|
|
173
202
|
console.log('');
|
|
174
|
-
console.log('📦 Step 4/
|
|
203
|
+
console.log('📦 Step 4/6: Minifying with Terser...');
|
|
175
204
|
|
|
176
205
|
let terser;
|
|
177
206
|
try {
|
|
@@ -215,7 +244,7 @@ module.exports = async function build(args) {
|
|
|
215
244
|
|
|
216
245
|
// Step 5: Delete all source map files so DevTools can't show original source
|
|
217
246
|
console.log('');
|
|
218
|
-
console.log('🗑️ Step 5/
|
|
247
|
+
console.log('🗑️ Step 5/6: Removing source maps...');
|
|
219
248
|
|
|
220
249
|
function deleteMapFiles(dir, prefix = '') {
|
|
221
250
|
if (!fs.existsSync(dir)) {
|
|
@@ -239,9 +268,13 @@ module.exports = async function build(args) {
|
|
|
239
268
|
}
|
|
240
269
|
} else {
|
|
241
270
|
console.log('');
|
|
242
|
-
console.log('⏭️ Steps 3-5/
|
|
271
|
+
console.log('⏭️ Steps 3-5/6: Skipping obfuscation, minification, and source map removal (--no-obfuscate)');
|
|
243
272
|
}
|
|
244
273
|
|
|
274
|
+
// Step 6: Note about backups
|
|
275
|
+
console.log('');
|
|
276
|
+
console.log('💡 Note: Original files backed up as *.original for future rebuilds');
|
|
277
|
+
|
|
245
278
|
console.log('');
|
|
246
279
|
console.log('✅ Build complete!');
|
|
247
280
|
console.log('');
|
|
@@ -6,40 +6,32 @@ export function hasPlatformMismatch(fingerprint: Fingerprint) {
|
|
|
6
6
|
const userAgent = fingerprint.signals.browser.userAgent;
|
|
7
7
|
const highEntropyPlatform = fingerprint.signals.browser.highEntropyValues.platform;
|
|
8
8
|
|
|
9
|
-
if (userAgent.includes('Mac') &&
|
|
9
|
+
if (userAgent.includes('Mac') && (platform.includes('Win') || platform.includes('Linux'))) {
|
|
10
10
|
return true;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
if (userAgent.includes('Windows') &&
|
|
13
|
+
if (userAgent.includes('Windows') && (platform.includes('Mac') || platform.includes('Linux'))) {
|
|
14
14
|
return true;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
if (userAgent.includes('Linux') &&
|
|
17
|
+
if (userAgent.includes('Linux') && (platform.includes('Mac') || platform.includes('Win'))) {
|
|
18
18
|
return true;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
// Check applied only if highEntropyPlatform is not ERROR or NA
|
|
23
23
|
if (highEntropyPlatform !== ERROR && highEntropyPlatform !== NA) {
|
|
24
|
-
if (highEntropyPlatform.includes('Mac') &&
|
|
24
|
+
if (highEntropyPlatform.includes('Mac') && (platform.includes('Win') || platform.includes('Linux'))) {
|
|
25
25
|
return true;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
if (highEntropyPlatform.includes('Windows') &&
|
|
28
|
+
if (highEntropyPlatform.includes('Windows') && (platform.includes('Mac') || platform.includes('Linux'))) {
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
if (highEntropyPlatform.includes('Linux') &&
|
|
32
|
+
if (highEntropyPlatform.includes('Linux') && (platform.includes('Mac') || platform.includes('Win'))) {
|
|
33
33
|
return true;
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
if (highEntropyPlatform.includes('Android') && !platform.includes('Android')) {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (highEntropyPlatform.includes('iOS') && !platform.includes('iOS')) {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
return false;
|
package/src/signals/worker.ts
CHANGED
|
@@ -37,8 +37,9 @@ export async function worker() {
|
|
|
37
37
|
fingerprintWorker.vendor = 'INIT';
|
|
38
38
|
fingerprintWorker.renderer = 'INIT';
|
|
39
39
|
var gl = canvas.getContext('webgl');
|
|
40
|
+
const isFirefox = navigator.userAgent.includes('Firefox');
|
|
40
41
|
try {
|
|
41
|
-
if (gl) {
|
|
42
|
+
if (gl && !isFirefox) {
|
|
42
43
|
var glExt = gl.getExtension('WEBGL_debug_renderer_info');
|
|
43
44
|
fingerprintWorker.vendor = gl.getParameter(glExt.UNMASKED_VENDOR_WEBGL);
|
|
44
45
|
fingerprintWorker.renderer = gl.getParameter(glExt.UNMASKED_RENDERER_WEBGL);
|