unshared-frontend-sdk 2.0.0-rc.2 → 2.0.0-rc.22

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 ADDED
@@ -0,0 +1,144 @@
1
+ # unshared-frontend-sdk
2
+
3
+ Browser SDK for [Unshared Labs](https://unsharedlabs.com) — collects a device fingerprint and sends it through your own backend. Your API key never touches the browser.
4
+
5
+ ---
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install unshared-frontend-sdk
11
+ ```
12
+
13
+ Or via CDN (no build step) — see [CDN / UMD usage](#cdn--umd-usage) below for the complete example.
14
+
15
+ ---
16
+
17
+ ## Quick Start
18
+
19
+ ```typescript
20
+ import { UnsharedLabsBrowser } from 'unshared-frontend-sdk';
21
+
22
+ // Same-origin (frontend served by the same backend): omit baseUrl
23
+ const client = new UnsharedLabsBrowser({});
24
+
25
+ // Cross-origin (separate domains): set baseUrl via env var
26
+ // const client = new UnsharedLabsBrowser({ baseUrl: process.env.BACKEND_URL });
27
+
28
+ // On page load — fire and forget
29
+ const fingerprint = await client.collect();
30
+ client.submitFingerprintEvent(fingerprint, { userId: currentUser?.id });
31
+ ```
32
+
33
+ That's it. The SDK handles retries, timeouts, and errors silently.
34
+
35
+ ---
36
+
37
+ ## Configuration
38
+
39
+ ```typescript
40
+ new UnsharedLabsBrowser({
41
+ baseUrl: process.env.BACKEND_URL, // optional — omit for same-origin
42
+ maxRetries: 3, // optional, default: 3
43
+ timeout: 30_000, // optional, default: 30s per attempt
44
+ });
45
+ ```
46
+
47
+ | Option | Type | Default | Description |
48
+ |--------|------|---------|-------------|
49
+ | `baseUrl` | `string` | `""` (same-origin) | Base URL of your backend. Omit if your frontend and backend share the same domain. |
50
+ | `maxRetries` | `number` | `3` | How many times to retry on failure |
51
+ | `timeout` | `number` | `30000` | Per-attempt timeout in milliseconds |
52
+
53
+ ---
54
+
55
+ ## Methods
56
+
57
+ ### `collect()`
58
+
59
+ Collect a browser fingerprint. Returns a `FingerprintWireFormat` object ready to pass to `submitFingerprintEvent`.
60
+
61
+ ```typescript
62
+ const fingerprint = await client.collect();
63
+ ```
64
+
65
+ ---
66
+
67
+ ### `submitFingerprintEvent(fingerprint, opts?)`
68
+
69
+ Send the fingerprint to your backend's `/unshared/submit-fingerprint-event` route. Fire-and-forget — you don't need to await this unless you want delivery confirmation.
70
+
71
+ ```typescript
72
+ // Fire and forget (recommended)
73
+ client.submitFingerprintEvent(fingerprint, {
74
+ userId: currentUser?.id, // optional
75
+ eventType: 'page_view', // optional
76
+ });
77
+
78
+ // Awaited (if you need delivery confirmation)
79
+ const result = await client.submitFingerprintEvent(fingerprint);
80
+ if (!result.success) {
81
+ console.warn('Delivery failed:', result.error?.message);
82
+ }
83
+ ```
84
+
85
+ **Options:**
86
+
87
+ | Option | Type | Description |
88
+ |--------|------|-------------|
89
+ | `userId` | `string` | ID of the logged-in user |
90
+ | `eventType` | `string` | Event label (e.g. `"page_view"`, `"login"`) |
91
+
92
+ ---
93
+
94
+ ## Backend requirement
95
+
96
+ The SDK sends fingerprints to `{baseUrl}/unshared/submit-fingerprint-event`. Your backend must handle this route. If you're using `unshared-clientjs-sdk`, the `createUnsharedMiddleware` sets this up automatically:
97
+
98
+ ```typescript
99
+ // On your Express backend
100
+ import express from 'express';
101
+ import { UnsharedLabsClient } from 'unshared-clientjs-sdk';
102
+ import { createUnsharedMiddleware } from 'unshared-clientjs-sdk/middleware';
103
+
104
+ const app = express();
105
+ const unshared = new UnsharedLabsClient({ apiKey: process.env.UNSHARED_API_KEY });
106
+
107
+ app.use(express.json());
108
+ app.use(createUnsharedMiddleware(unshared));
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Error handling
114
+
115
+ All methods follow a **never-throw** contract. Errors are always returned as a result object — the SDK will not throw or reject under any circumstances.
116
+
117
+ ```typescript
118
+ const result = await client.submitFingerprintEvent(fingerprint);
119
+
120
+ // result.success === false means delivery failed
121
+ // result.error.code === 'DELIVERY_FAILED'
122
+ ```
123
+
124
+ Retries happen automatically on network errors, timeouts, and server errors (5xx). Client errors (4xx) are not retried.
125
+
126
+ ---
127
+
128
+ ## CDN / UMD usage
129
+
130
+ The UMD bundle exposes a `window.UnsharedLabsBrowser` namespace object. Destructure the class from it first:
131
+
132
+ ```html
133
+ <script src="https://unpkg.com/unshared-frontend-sdk@2.0.0-rc.4/dist/index.umd.js"></script>
134
+ <script>
135
+ const { UnsharedLabsBrowser } = window.UnsharedLabsBrowser;
136
+
137
+ // Omit baseUrl for same-origin. Set it for cross-origin: { baseUrl: 'https://api.example.com' }
138
+ const client = new UnsharedLabsBrowser({});
139
+
140
+ client.collect().then(fp => {
141
+ client.submitFingerprintEvent(fp);
142
+ });
143
+ </script>
144
+ ```
package/dist/browser.d.ts CHANGED
@@ -2,24 +2,38 @@ import type { FingerprintWireFormat } from '@unshared-labs/shared-types';
2
2
  export interface BrowserConfig {
3
3
  /**
4
4
  * Base URL of the customer's own backend.
5
- * Must implement the Fingerprint HTTP Contract (§4 of spec).
6
- * Example: "https://app.example.com"
5
+ * Omit when the backend serves the frontend from the same origin.
7
6
  */
8
- baseUrl: string;
7
+ baseUrl?: string;
8
+ /** Max number of delivery retries per request. @default 3 */
9
+ maxRetries?: number;
10
+ /** Per-request fetch timeout in milliseconds. @default 30_000 */
11
+ timeout?: number;
12
+ /** When set, events are only submitted for paths matching one of these prefixes. */
13
+ includePathPrefix?: string[];
14
+ /** Paths to skip entirely — prefix match against location.pathname. */
15
+ skipPaths?: string[];
9
16
  /**
10
- * Max number of delivery retries per request.
11
- * @default 3
17
+ * Custom session ID resolver. Called at construction time.
18
+ * When it returns a string, that value is used instead of the auto-generated UUID.
19
+ * The value is still persisted to the __unshared_sid cookie.
20
+ * Falls back to existing cookie/UUID behavior when undefined is returned.
12
21
  */
13
- maxRetries?: number;
22
+ sessionId?: () => string | undefined;
14
23
  /**
15
- * Per-request fetch timeout in milliseconds. The timer resets on each retry
16
- * attempt. On timeout the request is treated as a network error and retried.
17
- * @default 30_000
24
+ * Custom device ID resolver. Called at construction time and during init().
25
+ * When it returns a string, that value is used instead of the fingerprint hash.
26
+ * The value is still persisted to localStorage.
27
+ * Falls back to existing localStorage/fingerprint behavior when undefined is returned.
18
28
  */
19
- timeout?: number;
29
+ deviceId?: () => string | undefined;
30
+ }
31
+ export interface InitOptions {
32
+ userId: string;
33
+ emailAddress: string;
20
34
  }
21
35
  export interface SubmitFingerprintOptions {
22
- userId?: string;
36
+ userId: string;
23
37
  eventType?: string;
24
38
  }
25
39
  export interface SubmitFingerprintResult {
@@ -35,49 +49,122 @@ export interface BrowserApiResult<T = unknown> {
35
49
  message: string;
36
50
  };
37
51
  }
52
+ export interface FlaggedInterceptorOptions {
53
+ onFlagged: () => void;
54
+ }
38
55
  /**
39
- * Browser library for Unshared Labs.
56
+ * Browser SDK for Unshared Labs.
40
57
  *
41
58
  * Routes fingerprint events through the customer's own backend — no API key
42
- * is ever present in the browser. The customer's backend attaches the secret
43
- * key before forwarding to Unshared Labs.
59
+ * is ever present in the browser.
44
60
  *
45
61
  * Never-throw contract: all public methods catch all errors and never reject.
46
62
  *
47
63
  * @example
48
64
  * ```typescript
49
- * const client = new UnsharedLabsBrowser({
50
- * baseUrl: "https://app.example.com",
51
- * });
65
+ * const sdk = new UnsharedLabsBrowser({ baseUrl: 'https://app.example.com' });
66
+ * await sdk.init({ userId: 'u_123', emailAddress: 'user@example.com' });
52
67
  *
53
- * // Fire-and-forget
54
- * client.submitFingerprintEvent(fingerprintData, { userId: "u_123" });
68
+ * // SPA: call on route changes
69
+ * sdk.onRouteChange();
55
70
  *
56
- * // Awaitable when you need confirmation
57
- * const result = await client.submitFingerprintEvent(fingerprintData);
71
+ * // Logout
72
+ * sdk.destroy();
58
73
  * ```
59
74
  */
60
75
  export declare class UnsharedLabsBrowser {
61
76
  private readonly _baseUrl;
62
77
  private readonly _maxRetries;
63
78
  private readonly _timeout;
64
- private readonly _sessionId;
65
- constructor(config: BrowserConfig);
79
+ private readonly _includePathPrefix;
80
+ private readonly _skipPaths;
81
+ private readonly _resolveSessionId?;
82
+ private readonly _resolveDeviceId?;
83
+ private _sessionId;
84
+ private _deviceId;
85
+ private _userId;
86
+ private _emailAddress;
87
+ private _mpaHandler;
66
88
  /**
67
- * Collect a browser fingerprint and return it as a FingerprintWireFormat
68
- * ready to pass to submitFingerprintEvent.
89
+ * Dedup key for the last fingerprint submission: `${userId}|${route}`.
90
+ * Modern SPAs fire pushState/replaceState multiple times during hydration
91
+ * with the same URL — without this guard each call would generate a
92
+ * redundant FP row with an identical stable_hash. Mirrors the same
93
+ * dedup behavior in the auto-injected inline script.
69
94
  *
70
- * Never throws / never rejects.
95
+ * Persisted to sessionStorage so that hard reloads, framework double-boots,
96
+ * and SDK re-instantiation within the same tab all still dedupe. The backend
97
+ * `ON CONFLICT (idempotency_key)` check handles the cross-tab and cross-reload
98
+ * cases that sessionStorage can't (sessionStorage is tab-scoped).
71
99
  */
72
- collect(): Promise<FingerprintWireFormat>;
100
+ private _lastSubmitKey;
101
+ constructor(config?: BrowserConfig);
73
102
  /**
74
- * Submit a fingerprint event. Fire-and-forget by default — do not await
75
- * unless you need delivery confirmation.
103
+ * Initialize the SDK after user login.
76
104
  *
77
- * Never throws / never rejects — transport failures are returned as
78
- * `{ success: false, error: { code: "DELIVERY_FAILED" } }`.
105
+ * 1. Stores userId and emailAddress
106
+ * 2. Persists emailAddress to sessionStorage
107
+ * 3. Sets __unshared_uid cookie
108
+ * 4. Collects fingerprint (once per tab — cached in sessionStorage)
109
+ * 5. Submits initial fingerprint event (fire-and-forget)
79
110
  */
80
- submitFingerprintEvent(fingerprint: FingerprintWireFormat, opts?: SubmitFingerprintOptions): Promise<BrowserApiResult<SubmitFingerprintResult>>;
111
+ init(opts: InitOptions): Promise<void>;
112
+ /**
113
+ * Call on SPA route changes. Submits a fingerprint event if the user
114
+ * is identified (email in sessionStorage). No-op otherwise.
115
+ */
116
+ onRouteChange(): void;
117
+ /**
118
+ * Clean up all SDK state. Must be called on user logout.
119
+ *
120
+ * If not called, MPA auto-submit on DOMContentLoaded will continue
121
+ * firing events with the previous user's email until the tab is closed.
122
+ */
123
+ destroy(): void;
124
+ /**
125
+ * Collect a browser fingerprint.
126
+ * @deprecated Prefer sdk.init() — fingerprint collection is handled automatically.
127
+ */
128
+ collect(options?: {
129
+ exclude?: string[];
130
+ }): Promise<FingerprintWireFormat>;
131
+ /**
132
+ * Submit a fingerprint event directly.
133
+ * @deprecated Prefer sdk.init() and sdk.onRouteChange().
134
+ */
135
+ submitFingerprintEvent(fingerprint: FingerprintWireFormat, opts: SubmitFingerprintOptions): Promise<BrowserApiResult<SubmitFingerprintResult>>;
136
+ private _getStoredEmail;
137
+ private _getCachedFingerprint;
138
+ private _cacheFingerprint;
139
+ private _shouldProcessPath;
140
+ private _submitEvent;
141
+ private _attachMpaListener;
81
142
  private _sendWithRetry;
82
143
  private _buildBody;
83
144
  }
145
+ /**
146
+ * Creates an Axios response error interceptor that calls onFlagged
147
+ * when the backend returns an account_flagged 403.
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * import { createAxiosInterceptor } from 'unshared-frontend-sdk';
152
+ * axios.interceptors.response.use(null, createAxiosInterceptor({
153
+ * onFlagged: () => router.push('/account-suspended'),
154
+ * }));
155
+ * ```
156
+ */
157
+ export declare function createAxiosInterceptor(opts: FlaggedInterceptorOptions): (error: any) => Promise<never>;
158
+ /**
159
+ * Creates a wrapped fetch function that calls onFlagged
160
+ * when the backend returns an account_flagged 403.
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * import { createFetchInterceptor } from 'unshared-frontend-sdk';
165
+ * const myFetch = createFetchInterceptor(fetch, {
166
+ * onFlagged: () => router.push('/account-suspended'),
167
+ * });
168
+ * ```
169
+ */
170
+ export declare function createFetchInterceptor(originalFetch: typeof fetch, opts: FlaggedInterceptorOptions): typeof fetch;
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const e="1.0.0",t=1282368115,n={exclude:[],include:[],timeout:3e3,stabilize:["private","iframe","always"],experimental:!1,debug:!1,salt:""},r=new Set(["audio","timing","navigatorConnection","domrect","permissions","fonts"]),o={always:[{exclude:["speech"],browsers:["brave","firefox"]},{exclude:["keyboard"],browsers:["firefox","safari"]},{exclude:["workers"],browsers:["firefox"]},{exclude:["hardwareSensitive","navigatorProps"],browsers:["brave"]}],private:[{exclude:["fonts"],browsers:["firefox"]},{exclude:["audio"],browsers:["safari","brave"]}],iframe:[{exclude:["applePay"],browsers:["safari"]},{exclude:["permissions"]},{exclude:["keyboard"]}]};let a=null;function i(){if(a)return a;const e=navigator.userAgent;return a=function(){const e=navigator.brave;return!!e&&"function"==typeof e.isBrave}()?{name:"brave",version:s(e,/Chrome\/([\d.]+)/)}:/Edg\//i.test(e)?{name:"edge",version:s(e,/Edg\/([\d.]+)/)}:/OPR\//i.test(e)||/Opera/i.test(e)?{name:"opera",version:s(e,/OPR\/([\d.]+)/)||s(e,/Opera\/([\d.]+)/)}:/SamsungBrowser/i.test(e)?{name:"samsung",version:s(e,/SamsungBrowser\/([\d.]+)/)}:/Firefox\//i.test(e)?{name:"firefox",version:s(e,/Firefox\/([\d.]+)/)}:/Safari\//i.test(e)&&!/Chrome/i.test(e)?{name:"safari",version:s(e,/Version\/([\d.]+)/)}:/Chrome\//i.test(e)?{name:"chrome",version:s(e,/Chrome\/([\d.]+)/)}:{name:"unknown",version:""},a}function s(e,t){const n=e.match(t);return n?.[1]??""}async function c(e){try{switch(e){case"chrome":case"edge":case"opera":default:return await l();case"brave":return await async function(){return!1}();case"safari":return await async function(){if(navigator.storage?.estimate){const{quota:e}=await navigator.storage.estimate();if(void 0!==e)return e<4294967296}try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"NotFoundError"===e?.name}}();case"firefox":return await async function(){if(!("serviceWorker"in navigator))return!0;try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"SecurityError"===e?.name}}()}}catch{return!1}}async function l(){if(!navigator.storage?.estimate)return!1;const{quota:e}=await navigator.storage.estimate();return void 0!==e&&e<4294967296}function u(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,a=65535&e[1],i=t[0]>>>16,s=65535&t[0],c=t[1]>>>16;let u=0,l=0,f=0,m=0,d=0;return l=a+(65535&t[1]),u=l>>>16,l&=65535,f=o+c+u,u=f>>>16,f&=65535,m=r+s+u,u=m>>>16,m&=65535,d=n+i+u,d&=65535,[d<<16|m,f<<16|l]}function m(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,a=65535&e[1],i=t[0]>>>16,s=65535&t[0],c=t[1]>>>16,u=65535&t[1];let l=0,f=0,m=0,d=0,p=0;return f=a*u,l=f>>>16,f&=65535,m=o*u+l,l=m>>>16,m&=65535,m+=a*c,l+=m>>>16,m&=65535,d=r*u+l,l=d>>>16,d&=65535,d+=o*c,l+=d>>>16,d&=65535,d+=a*s,l+=d>>>16,d&=65535,p=n*u+r*c+o*s+a*i+l,p&=65535,[p<<16|d,m<<16|f]}function d(e,t){return 32==(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])}function f(e,t){return 0==(t%=64)?[e[0],e[1]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]}function p(e,t){return[e[0]^t[0],e[1]^t[1]]}function g(e){let t=[e[0],e[1]];return t=p(t,[0,t[0]>>>1]),t=m(t,[4283543511,3981806797]),t=p(t,[0,t[0]>>>1]),t=m(t,[3301882366,444984403]),t=p(t,[0,t[0]>>>1]),t}function h(e){return("00000000"+(e>>>0).toString(16)).slice(-8)}function y(e,t=0){const n=e.length%16,r=e.length-n;let o=[0,t],a=[0,t];const i=[2277735313,289559509],s=[1291169091,658871167];for(let t=0;t<r;t+=16){let n=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],r=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24];n=m(n,i),n=d(n,31),n=m(n,s),o=p(o,n),o=d(o,27),o=u(o,a),o=u(m(o,[0,5]),[0,1390208809]),r=m(r,s),r=d(r,33),r=m(r,i),a=p(a,r),a=d(a,31),a=u(a,o),a=u(m(a,[0,5]),[0,944331445])}let c=[0,0],l=[0,0];switch(n){case 15:l=p(l,f([0,e.charCodeAt(r+14)],48));case 14:l=p(l,f([0,e.charCodeAt(r+13)],40));case 13:l=p(l,f([0,e.charCodeAt(r+12)],32));case 12:l=p(l,f([0,e.charCodeAt(r+11)],24));case 11:l=p(l,f([0,e.charCodeAt(r+10)],16));case 10:l=p(l,f([0,e.charCodeAt(r+9)],8));case 9:l=p(l,[0,e.charCodeAt(r+8)]),l=m(l,s),l=d(l,33),l=m(l,i),a=p(a,l);case 8:c=p(c,f([0,e.charCodeAt(r+7)],56));case 7:c=p(c,f([0,e.charCodeAt(r+6)],48));case 6:c=p(c,f([0,e.charCodeAt(r+5)],40));case 5:c=p(c,f([0,e.charCodeAt(r+4)],32));case 4:c=p(c,f([0,e.charCodeAt(r+3)],24));case 3:c=p(c,f([0,e.charCodeAt(r+2)],16));case 2:c=p(c,f([0,e.charCodeAt(r+1)],8));case 1:c=p(c,[0,e.charCodeAt(r)]),c=m(c,i),c=d(c,31),c=m(c,s),o=p(o,c)}return o=p(o,[0,e.length]),a=p(a,[0,e.length]),o=u(o,a),a=u(a,o),o=g(o),a=g(a),o=u(o,a),a=u(a,o),h(o[0])+h(o[1])+h(a[0])+h(a[1])}function v(e){return x(e,new Set)}function x(e,t){if(null===e)return"null";if(void 0===e)return"undefined";const n=typeof e;if("boolean"===n||"number"===n)return String(e);if("string"===n)return JSON.stringify(e);if(Array.isArray(e)){if(t.has(e))return'"[Circular]"';t.add(e);const n=e.map(e=>x(e,t));return t.delete(e),"["+n.join(",")+"]"}if("object"===n){const n=e;if(t.has(n))return'"[Circular]"';t.add(n);const r=Object.keys(n).sort().filter(e=>void 0!==n[e]).map(e=>JSON.stringify(e)+":"+x(n[e],t));return t.delete(n),"{"+r.join(",")+"}"}return String(e)}const S=y("",t);function C(e,n){const r=function(e){if(0===e.length)return y("",t);if(1===e.length)return y(e[0],t);let n=[...e];for(;n.length>1;){const e=[];for(let r=0;r<n.length;r+=2){const o=r+1<n.length?n[r+1]:S;e.push(y(n[r]+o,t))}n=e}return n[0]}(Object.keys(e).sort().map(n=>{const r=function(e){let n=t;for(let t=0;t<e.length;t++)n=Math.imul(n^e.charCodeAt(t),1540483477),n^=n>>>13;return n>>>0}(n);return y(v(e[n]),r)})),o=String.fromCharCode(76,111,98,115),a=n?y(n,t):"";return y(r+o+a,t)}function w(e){try{const t=e.getExtension("EXT_texture_filter_anisotropic")??e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")??e.getExtension("MOZ_EXT_texture_filter_anisotropic");return t?e.getParameter(t.MAX_TEXTURE_MAX_ANISOTROPY_EXT):null}catch{return null}}function b(e){try{const t=e.getContext("webgl2");if(!t)return null;const n={version:t.getParameter(t.VERSION),maxSamples:t.getParameter(t.MAX_SAMPLES),max3DTextureSize:t.getParameter(t.MAX_3D_TEXTURE_SIZE),maxArrayTextureLayers:t.getParameter(t.MAX_ARRAY_TEXTURE_LAYERS),maxUniformBlockSize:t.getParameter(t.MAX_UNIFORM_BLOCK_SIZE),maxVertexUniformComponents:t.getParameter(t.MAX_VERTEX_UNIFORM_COMPONENTS),maxFragmentUniformComponents:t.getParameter(t.MAX_FRAGMENT_UNIFORM_COMPONENTS),maxColorAttachments:t.getParameter(t.MAX_COLOR_ATTACHMENTS),maxDrawBuffers:t.getParameter(t.MAX_DRAW_BUFFERS)};return t.getExtension("WEBGL_lose_context")?.loseContext(),n}catch{return null}}function A(){const e=navigator.userAgentData;if(e?.platform)return e.platform;const t=navigator.userAgent??"";return/Windows/.test(t)?"Windows":/Macintosh|Mac OS X/.test(t)?"macOS":/CrOS/.test(t)?"Chrome OS":/Android/.test(t)?"Android":/Linux/.test(t)?"Linux":/iPhone|iPad|iPod/.test(t)?"iOS":""}function E(){try{const e=new ArrayBuffer(4),t=new Float32Array(e),n=new Uint8Array(e);return t[0]=1/0,n[3]}catch{return 0}}function M(e,t,n,r){const o=(n-t)/r;let a=e(t)+e(n);for(let n=1;n<r;n++)a+=e(t+n*o)*(n%2==0?2:4);return a*o/3}function P(){try{const e=(new Intl.DateTimeFormat).resolvedOptions();return{locale:e.locale,calendar:e.calendar,numberingSystem:e.numberingSystem,timeZone:e.timeZone}}catch{return{}}}function T(){try{const e=(new Intl.NumberFormat).resolvedOptions();return{locale:e.locale,numberingSystem:e.numberingSystem,style:e.style,minimumIntegerDigits:e.minimumIntegerDigits,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,useGrouping:e.useGrouping}}catch{return{}}}function _(){try{const e=(new Intl.Collator).resolvedOptions();return{locale:e.locale,usage:e.usage,sensitivity:e.sensitivity,collation:e.collation,numeric:e.numeric,caseFirst:e.caseFirst}}catch{return{}}}function I(){try{const e=(new Intl.PluralRules).resolvedOptions(),t=new Intl.PluralRules(void 0,{type:"ordinal"}).resolvedOptions();return{locale:e.locale,type:e.type,cardinalCategories:(new Intl.PluralRules).select(0)+","+(new Intl.PluralRules).select(1)+","+(new Intl.PluralRules).select(2)+","+(new Intl.PluralRules).select(5)+","+(new Intl.PluralRules).select(11)+","+(new Intl.PluralRules).select(100),ordinalCategory1:t.type,minimumIntegerDigits:e.minimumIntegerDigits}}catch{return{}}}function R(){try{const e=new Intl.RelativeTimeFormat;if(!e)return{};const t=e.resolvedOptions();return{locale:t.locale,style:t.style,numeric:t.numeric,numberingSystem:t.numberingSystem}}catch{return{}}}function O(){try{const e=new Intl.ListFormat;if(!e)return{};const t=e.resolvedOptions(),n=["X","Y","Z"],r=new Intl.ListFormat(void 0,{type:"conjunction",style:"long"}),o=new Intl.ListFormat(void 0,{type:"disjunction",style:"long"});return{locale:t.locale,type:t.type,style:t.style,conjunctionSample:r.format(n),disjunctionSample:o.format(n)}}catch{return{}}}const k=[["backdrop-filter","blur(1px)"],["container-type","inline-size"],["text-wrap","balance"],["overscroll-behavior","contain"],["hanging-punctuation","first"],["-webkit-line-clamp","1"],["appearance","none"],["font-size-adjust","ex-height 0.5"],["font-palette","normal"],["field-sizing","content"],["-webkit-text-stroke","1px black"],["zoom","1"],["scrollbar-width","thin"],["scrollbar-color","red blue"],["animation-timeline","auto"],["mask-composite","add"],["offset-path","none"],["text-decoration-thickness","1px"],["content-visibility","auto"],["contain-intrinsic-size","auto 100px"],["aspect-ratio","16/9"],["gap","10px"],["color-mix","in srgb, red 50%, blue"],["linear-gradient(in oklch, red, blue)",""]];function D(){try{const e=document.createElement("div");e.style.cssText="visibility:hidden;overflow:scroll;position:absolute;top:-9999px;width:100px;height:100px",document.body.appendChild(e);const t=document.createElement("div");e.appendChild(t);const n=e.offsetWidth-t.offsetWidth;return document.body.removeChild(e),n}catch{return-1}}function L(){const e={};if("undefined"==typeof CSS||"function"!=typeof CSS.supports)return e;for(const[t,n]of k)e[t]=n?CSS.supports(t,n):CSS.supports(t);return e}function N(){try{const e=document.createElement("div");e.style.cssText=["position:fixed","top:0","left:0","width:0","height:0","visibility:hidden","padding-top:env(safe-area-inset-top,0px)","padding-bottom:env(safe-area-inset-bottom,0px)","padding-left:env(safe-area-inset-left,0px)","padding-right:env(safe-area-inset-right,0px)"].join(";"),document.body.appendChild(e);const t=getComputedStyle(e),n={top:t.paddingTop,bottom:t.paddingBottom,left:t.paddingLeft,right:t.paddingRight};return document.body.removeChild(e),n}catch{return null}}function F(){try{const e=performance.now();let t=1/0,n=e;for(let r=0;r<50;r++){const r=performance.now(),o=r-n;if(o>0&&o<t&&(t=o),n=r,r-e>=1)break}if(t===1/0)return-1;const r=1e3*t;if(r<=0)return-1;const o=Math.max(0,Math.round(Math.log10(r)));return Math.pow(10,o)}catch{return-1}}const B=["Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Bookman Old Style","Bradley Hand","Calibri","Cambria","Cambria Math","Century","Century Gothic","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Gill Sans","Helvetica","Helvetica Neue","Impact","Lucida Console","Lucida Grande","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3","Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Ubuntu","Merriweather","Playfair Display","Source Sans Pro","Source Code Pro","Fira Code","JetBrains Mono","Cascadia Code","Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","SF Pro","SF Pro Display","SF Mono","San Francisco","Menlo","Andale Mono","Futura","MS Gothic","MS Mincho","MS PGothic","MS PMincho","Yu Gothic","Meiryo","Hiragino Sans","Hiragino Kaku Gothic Pro","SimSun","SimHei","Microsoft YaHei","PingFang SC","Noto Sans CJK","Malgun Gothic","Arial Hebrew"],U=["monospace","sans-serif","serif"],V="mmMwWLliI0O&1";function W(e,t){const n=[],r=e.split("\r\n");let o=!1;for(const e of r)if(e.startsWith(`m=${t}`))o=!0;else{if(e.startsWith("m=")&&o)break;if(o&&e.startsWith("a=rtpmap:")){const t=e.match(/^a=rtpmap:\d+\s+(.+)$/);t&&n.push(t[1])}}return n}const X=["accelerometer","accessibility-events","ambient-light-sensor","background-fetch","background-sync","bluetooth","camera","clipboard-read","clipboard-write","display-capture","geolocation","gyroscope","local-fonts","magnetometer","microphone","midi","nfc","notifications","payment-handler","persistent-storage","push","screen-wake-lock","speaker-selection","storage-access","top-level-storage-access","window-management","xr-spatial-tracking"];function z(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;let n=e[0],r=0;for(const[e,o]of Object.entries(t))o>r&&(n=e,r=o);return n}const G=[{name:"prefers-contrast",values:["no-preference","more","less","custom"]},{name:"any-hover",values:["none","hover"]},{name:"any-pointer",values:["none","coarse","fine"]},{name:"pointer",values:["none","coarse","fine"]},{name:"hover",values:["none","hover"]},{name:"update",values:["none","slow","fast"]},{name:"inverted-colors",values:["none","inverted"]},{name:"prefers-reduced-motion",values:["no-preference","reduce"]},{name:"prefers-reduced-transparency",values:["no-preference","reduce"]},{name:"scripting",values:["none","initial-only","enabled"]},{name:"forced-colors",values:["none","active"]},{name:"prefers-color-scheme",values:["light","dark"]},{name:"color-gamut",values:["srgb","p3","rec2020"]},{name:"dynamic-range",values:["standard","high"]}],H=["KeyQ","KeyW","KeyA","KeyS","KeyZ","KeyX","KeyY","KeyM","Semicolon","BracketLeft","Quote","Digit1","Digit2","Digit3"];function j(e){const t=e.KeyQ,n=e.KeyZ,r=e.KeyY;return t?"a"===t?"azerty":"q"===t&&"z"===r?"qwertz":"q"===t&&"z"===n?"qwerty":"'"===t?"dvorak":"other":null}const K=[{name:"webgl",tier:1,async collect(){const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!(t&&t instanceof WebGLRenderingContext))return null;const n=t.getExtension("WEBGL_debug_renderer_info"),r=t.getSupportedExtensions()??[],o=function(e){const t={},n=[e.VERTEX_SHADER,e.FRAGMENT_SHADER],r=[e.LOW_FLOAT,e.MEDIUM_FLOAT,e.HIGH_FLOAT,e.LOW_INT,e.MEDIUM_INT,e.HIGH_INT],o=["vertex","fragment"],a=["lowFloat","mediumFloat","highFloat","lowInt","mediumInt","highInt"];for(let i=0;i<n.length;i++){const s={};for(let t=0;t<r.length;t++){const o=e.getShaderPrecisionFormat(n[i],r[t]);o&&(s[a[t]]={rangeMin:o.rangeMin,rangeMax:o.rangeMax,precision:o.precision})}t[o[i]]=s}return t}(t),a={vendor:t.getParameter(t.VENDOR),renderer:t.getParameter(t.RENDERER),version:t.getParameter(t.VERSION),shadingLanguageVersion:t.getParameter(t.SHADING_LANGUAGE_VERSION),unmaskedVendor:n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):null,unmaskedRenderer:n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):null,extensions:r.sort(),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE),maxViewportDims:Array.from(t.getParameter(t.MAX_VIEWPORT_DIMS)),maxVertexAttribs:t.getParameter(t.MAX_VERTEX_ATTRIBS),maxVertexUniformVectors:t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),maxFragmentUniformVectors:t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:t.getParameter(t.MAX_VARYING_VECTORS),aliasedLineWidthRange:Array.from(t.getParameter(t.ALIASED_LINE_WIDTH_RANGE)),aliasedPointSizeRange:Array.from(t.getParameter(t.ALIASED_POINT_SIZE_RANGE)),maxCombinedTextureImageUnits:t.getParameter(t.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxTextureImageUnits:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextureImageUnits:t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),shaderPrecision:o,maxAnisotropy:w(t),webgl2:b(e)};return t.getExtension("WEBGL_lose_context")?.loseContext(),a}},{name:"hardware",tier:1,collect:async()=>({architecture:E(),platform:A()})},{name:"hardwareSensitive",tier:1,collect:async()=>({deviceMemory:navigator.deviceMemory??null,hardwareConcurrency:navigator.hardwareConcurrency??null})},{name:"math",tier:1,collect:async()=>({acos:Math.acos(.5),asin:M(Math.asin,-1,1,97),cos:M(Math.cos,0,Math.PI,97),cosLarge:Math.cos(1e20),sinLarge:Math.sin(1e20),tanLarge:Math.tan(1e20),sin:M(Math.sin,0,Math.PI,97),tan:M(Math.tan,0,Math.PI/4,97)})},{name:"i18n",tier:1,collect:async()=>({dateTimeFormat:P(),numberFormat:T(),collator:_(),pluralRules:I(),relativeTimeFormat:R(),listFormat:O()})},{name:"domrect",tier:1,collect:async()=>({basic:function(){const e=document.createElement("div");e.style.cssText="position:fixed;left:-9999px;width:100px;height:100px;",document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}(),precision:function(){const e=document.createElement("div");e.style.cssText=`position:absolute;left:-9999px;width:${Math.PI}px;height:${Math.E}px;`,document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{width:t.width,height:t.height}}(),fromRect:"undefined"!=typeof DOMRectReadOnly&&"function"==typeof DOMRectReadOnly.fromRect})},{name:"touch",tier:1,collect:async()=>({supported:"ontouchstart"in window||navigator.maxTouchPoints>0,maxTouchPoints:navigator.maxTouchPoints??0})},{name:"display",tier:1,collect:async()=>({colorDepth:screen.colorDepth??0,pixelDepth:screen.pixelDepth??0})},{name:"locale",tier:1,collect:async()=>({timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"",language:navigator.language??""})},{name:"workers",tier:1,collect:async()=>({webWorker:"undefined"!=typeof Worker,sharedWorker:"undefined"!=typeof SharedWorker,serviceWorker:"serviceWorker"in navigator})},{name:"plugins",tier:1,async collect(){const e=[];if(navigator.plugins)for(let t=0;t<navigator.plugins.length;t++){const n=navigator.plugins[t];"internal-pdf-viewer"===n.filename&&e.push(`${n.name}|${n.filename}|${n.description}`)}return{plugins:e.sort(),pdfViewerEnabled:navigator.pdfViewerEnabled??!1}}},{name:"css",tier:1,collect:async()=>({scrollbarWidth:D(),supports:L(),safeArea:N()})},{name:"navigatorProps",tier:1,collect:async()=>({vendor:navigator.vendor??"",productSub:navigator.productSub??"",cookieEnabled:navigator.cookieEnabled})},{name:"timing",tier:2,collect:async()=>({performancePrecisionUs:F()})},{name:"navigatorConnection",tier:2,async collect(){const e=navigator,t=e.connection??e.mozConnection??e.webkitConnection??null,n=performance.memory??null;return{connection:t?{type:t.type??null,effectiveType:t.effectiveType??null,downlink:t.downlink??null,rtt:t.rtt??null,saveData:t.saveData??null}:null,memory:n?{jsHeapSizeLimit:n.jsHeapSizeLimit,totalJSHeapSize:n.totalJSHeapSize}:null}}},{name:"webgpu",tier:2,async collect(){const e=navigator.gpu;if(!e)return null;const t=await e.requestAdapter();if(!t)return null;let n="",r="",o="",a="";if(t.info)n=t.info.vendor??"",r=t.info.architecture??"",o=t.info.device??"",a=t.info.description??"";else if("function"==typeof t.requestAdapterInfo){const e=await t.requestAdapterInfo();n=e.vendor??"",r=e.architecture??"",o=e.device??"",a=e.description??""}const i=[];t.features&&(t.features.forEach(e=>i.push(e)),i.sort());const s={};if(t.limits){const e=["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderComponents","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension"];for(const n of e){const e=t.limits[n];void 0!==e&&(s[n]=e)}}return{vendor:n,architecture:r,device:o,description:a,features:i,limits:s}}},{name:"audio",tier:2,async collect(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return null;let t=null;try{t=new e;const n=t.destination;return{sampleRate:t.sampleRate,maxChannelCount:n.maxChannelCount,channelCount:n.channelCount,channelCountMode:n.channelCountMode,channelInterpretation:n.channelInterpretation,baseLatency:t.baseLatency??null,outputLatency:t.outputLatency??null}}finally{if(t&&"closed"!==t.state)try{await t.close()}catch{}}}},{name:"fonts",tier:2,collect:()=>new Promise(e=>{const t=()=>e(function(){try{if("undefined"==typeof document)return{available:[],method:"css-layout"};const e=new Set,t=[];if("function"==typeof document.fonts?.check)for(const n of B)document.fonts.check(`72px "${n}"`)?e.add(n):t.push(n);else t.push(...B);const n=new Set;if(t.length>0){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px;left:-9999px;pointer-events:none;";const r=U.map(t=>{const n=document.createElement("span");return n.style.cssText=`font-size:72px;font-family:${t};white-space:nowrap;display:inline-block`,n.textContent=V,e.appendChild(n),n}),o=t.map(t=>U.map(n=>{const r=document.createElement("span");return r.style.cssText=`font-size:72px;font-family:'${t}',${n};white-space:nowrap;display:inline-block`,r.textContent=V,e.appendChild(r),r}));document.body.appendChild(e);const a=r.map(e=>e.getBoundingClientRect().width),i=o.map(e=>e.map(e=>e.getBoundingClientRect().width));document.body.removeChild(e);for(let e=0;e<t.length;e++)for(let r=0;r<U.length;r++)if(i[e][r]!==a[r]){n.add(t[e]);break}}return{available:B.filter(t=>e.has(t)||n.has(t)),method:"css-layout"}}catch{return{available:[],method:"css-layout"}}}());"undefined"!=typeof requestIdleCallback?requestIdleCallback(t,{timeout:2e3}):setTimeout(t,0)})},{name:"webrtc",tier:2,async collect(){if("undefined"==typeof RTCPeerConnection)return{supported:!1,audioCodecCount:0,videoCodecCount:0,audioCodecs:[],videoCodecs:[],extensions:[]};const e=new RTCPeerConnection({iceServers:[]});try{e.addTransceiver("audio"),e.addTransceiver("video");const t=(await e.createOffer()).sdp??"",n=W(t,"audio"),r=W(t,"video"),o=function(e){const t=new Set,n=e.split("\r\n");for(const e of n)if(e.startsWith("a=extmap:")){const n=e.match(/^a=extmap:\d+(?:\/\w+)?\s+(.+)$/);n&&t.add(n[1].trim())}return Array.from(t)}(t);return{supported:!0,audioCodecCount:n.length,videoCodecCount:r.length,audioCodecs:n.sort(),videoCodecs:r.sort(),extensions:o.sort()}}finally{e.close()}}},{name:"permissions",tier:2,async collect(){if(!navigator.permissions?.query)return{states:{}};const e=()=>Promise.allSettled(X.map(async e=>{try{return{name:e,state:(await navigator.permissions.query({name:e})).state}}catch{return{name:e,state:"error"}}})),t=await Promise.all([e(),e(),e()]),n={};for(const e of t)for(const t of e)if("fulfilled"===t.status){const{name:e,state:r}=t.value;n[e]||(n[e]=[]),n[e].push(r)}const r={};for(const[e,t]of Object.entries(n))r[e]=z(t);return{states:r}}},{name:"speech",tier:2,async collect(){if("undefined"==typeof speechSynthesis)return{supported:!1,voiceCount:0,voices:[]};const e=await new Promise(e=>{const t=speechSynthesis.getVoices();if(t.length>0)return void e(t);const n=setTimeout(()=>e([]),800);speechSynthesis.addEventListener("voiceschanged",()=>{clearTimeout(n),e(speechSynthesis.getVoices())},{once:!0})}),t=e.map(e=>`${e.name}|${e.lang}|${e.localService}`).sort();return{supported:!0,voiceCount:e.length,voices:t}}},{name:"mediaQueries",tier:2,async collect(){if("function"!=typeof matchMedia){const e={};for(const t of G)e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]="unsupported";return{...e,monochrome:0}}const e={};for(const t of G){let n="unknown";for(const e of t.values){const r=matchMedia(`(${t.name}: ${e})`);if(r?.matches){n=e;break}}e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]=n}let t=0;for(let e=100;e>=0;e--)if(matchMedia(`(monochrome: ${e})`)?.matches){t=e;break}return{...e,monochrome:t}}},{name:"applePay",tier:2,async collect(){const e=window.ApplePaySession;if(!e||"function"!=typeof e.supportsVersion)return{supported:!1,maxVersion:0};let t=0;for(let n=15;n>=1;n--)try{if(e.supportsVersion(n)){t=n;break}}catch{continue}return{supported:!0,maxVersion:t}}},{name:"keyboard",tier:2,async collect(){const e=navigator.keyboard;if(!e||"function"!=typeof e.getLayoutMap)return{supported:!1,layoutKeys:null,layoutHint:null};try{const t=await e.getLayoutMap(),n={};for(const e of H){const r=t.get(e);void 0!==r&&(n[e]=r)}return{supported:!0,layoutKeys:n,layoutHint:j(n)}}catch{return{supported:!1,layoutKeys:null,layoutHint:null}}}}];async function $(e,t,n){const r={},o=[],a=K.filter(t=>!e.has(t.name)&&(n||3!==t.tier)),i=await Promise.allSettled(a.map(async e=>{const n=await(r=e.collect(),o=t,new Promise((e,t)=>{const n=setTimeout(()=>e(null),o);r.then(t=>{clearTimeout(n),e(t)},e=>{clearTimeout(n),t(e)})}));var r,o;return{name:e.name,value:n}}));for(let e=0;e<i.length;e++){const t=i[e],n=a[e].name;"fulfilled"===t.status&&null!==t.value.value?r[n]=t.value.value:"rejected"===t.status&&o.push({signal:n,error:String(t.reason?.message??t.reason)})}return{components:r,errors:o}}async function q(t){const a={...n},s=i(),u=function(){try{return window.self!==window.top}catch{return!0}}();let l=!1;try{l=await c(s.name)}catch{}const f=function(e,t,n,r){const a=new Set;for(const i of e){if("private"===i&&!n)continue;if("iframe"===i&&!r)continue;const e=o[i];if(e)for(const n of e)if(!n.browsers||n.browsers.includes(t))for(const e of n.exclude)a.add(e)}return a}(a.stabilize,s.name,l,u),m=new Set(f);for(const e of a.exclude)m.add(e);for(const e of a.include)m.delete(e);const{components:d,errors:p}=await $(m,a.timeout,a.experimental),y=C({...d,t:e},a.salt),h={t:e};for(const[e,t]of Object.entries(d))r.has(e)||(h[e]=t);const g=C(h,a.salt),v={hash:y,stableHash:g,components:{...d,t:e},timestamp:(new Date).toISOString(),version:e,isIncognito:l,errors:p};return a.debug&&(console.log("[fingerprint] components:",d),console.log("[fingerprint] hash:",y,"stableHash:",g),p.length>0&&console.warn("[fingerprint] errors:",p)),v}const DEFAULT_MAX_RETRIES=3,DEFAULT_TIMEOUT_MS=3e4,MAX_DELAY_MS=3e4,BASE_DELAY_MS=1e3,FINGERPRINT_PATH="/unshared/submit-fingerprint-event";function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function sleep(e){return new Promise(t=>setTimeout(t,e))}function retryDelay(e){const t=Math.min(1e3*Math.pow(2,e-1),3e4),n=500*Math.random()-250;return Math.max(0,t+n)}class UnsharedLabsBrowser{constructor(e){if(!e.baseUrl||!isValidUrl(e.baseUrl))throw new Error("baseUrl is required and must be a valid URL");this.o=e.baseUrl.replace(/\/$/,""),this.i=e.maxRetries??3,this.u=e.timeout??3e4,this.l=generateUUID()}async collect(){const e=await q();return{fingerprint_id:e.stableHash,full_hash:e.hash,components:e.components,timestamp:e.timestamp,isIncognito:e.isIncognito,version:e.version}}async submitFingerprintEvent(e,t){try{const n=this.m(e,t),r=generateUUID(),o=`${this.o}${FINGERPRINT_PATH}`,a=JSON.stringify(n);return await this.p(o,a,r)}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}async p(e,t,n){const r=this.i+1;let o={success:!1,error:{code:"DELIVERY_FAILED",message:"Request failed"}};for(let a=1;a<=r;a++){a>1&&await sleep(retryDelay(a-1));const r=new AbortController,i=setTimeout(()=>r.abort(),this.u);try{const a=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Idempotency-Key":n,"X-Session-Id":this.l},body:t,signal:r.signal});if(clearTimeout(i),a.status>=500){o={success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${a.status}`}};continue}if(a.status>=400)return{success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${a.status}`}};const s=await a.text().catch(()=>"{}");let c;try{c=JSON.parse(s)}catch{c={}}return!1===c?.success?{success:!1,error:c.error??{code:"UPSTREAM_ERROR",message:"Upstream failed"}}:{success:!0,data:c?.data}}catch(e){clearTimeout(i),o={success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}return o}m(e,t){const n={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:e.timestamp,is_incognito:e.isIncognito,components:e.components,version:e.version};return null!=t?.userId&&(n.user_id=t.userId),null!=t?.eventType&&(n.event_type=t.eventType),n}}function isValidUrl(e){try{return new URL(e),!0}catch{return!1}}exports.UnsharedLabsBrowser=UnsharedLabsBrowser;
1
+ "use strict";const e="1.3.1",t=1282368115,n={exclude:[],include:[],timeout:3e3,stabilize:["private","iframe","always"],experimental:!1,debug:!1,salt:""},r=new Set(["audio","timing","navigatorConnection","domrect","permissions","fonts","speech"]),o=new Set(["domrect"]),a={always:[{exclude:["speech"],browsers:["brave","firefox"]},{exclude:["keyboard"],browsers:["firefox","safari"]},{exclude:["workers"],browsers:["firefox"]},{exclude:["hardwareSensitive","navigatorProps"],browsers:["brave"]}],private:[{exclude:["fonts"],browsers:["firefox"]},{exclude:["audio"],browsers:["safari","brave"]}],iframe:[{exclude:["applePay"],browsers:["safari"]},{exclude:["permissions"]},{exclude:["keyboard"]}]};let i=null;function s(){if(i)return i;const e=navigator.userAgent;return i=function(){const e=navigator.brave;return!!e&&"function"==typeof e.isBrave}()?{name:"brave",version:c(e,/Chrome\/([\d.]+)/)}:/Edg\//i.test(e)?{name:"edge",version:c(e,/Edg\/([\d.]+)/)}:/OPR\//i.test(e)||/Opera/i.test(e)?{name:"opera",version:c(e,/OPR\/([\d.]+)/)||c(e,/Opera\/([\d.]+)/)}:/SamsungBrowser/i.test(e)?{name:"samsung",version:c(e,/SamsungBrowser\/([\d.]+)/)}:/Firefox\//i.test(e)?{name:"firefox",version:c(e,/Firefox\/([\d.]+)/)}:/Safari\//i.test(e)&&!/Chrome/i.test(e)?{name:"safari",version:c(e,/Version\/([\d.]+)/)}:/Chrome\//i.test(e)?{name:"chrome",version:c(e,/Chrome\/([\d.]+)/)}:{name:"unknown",version:""},i}function c(e,t){const n=e.match(t);return n?.[1]??""}async function l(e){try{switch(e){case"chrome":case"edge":case"opera":default:return await u();case"brave":return await async function(){return!1}();case"safari":return await async function(){if(navigator.storage?.estimate){const{quota:e}=await navigator.storage.estimate();if(void 0!==e)return e<4294967296}try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"NotFoundError"===e?.name}}();case"firefox":return await async function(){if(!("serviceWorker"in navigator))return!0;try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"SecurityError"===e?.name}}()}}catch{return!1}}async function u(){if(!navigator.storage?.estimate)return!1;const{quota:e}=await navigator.storage.estimate();return void 0!==e&&e<4294967296}function m(e,t){const n=e[0]>>>16,o=65535&e[0],r=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16;let u=0,l=0,d=0,f=0,m=0;return l=i+(65535&t[1]),u=l>>>16,l&=65535,d=r+c+u,u=d>>>16,d&=65535,f=o+s+u,u=f>>>16,f&=65535,m=n+a+u,m&=65535,[m<<16|f,d<<16|l]}function d(e,t){const n=e[0]>>>16,o=65535&e[0],r=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16,u=65535&t[1];let l=0,d=0,f=0,m=0,p=0;return d=i*u,l=d>>>16,d&=65535,f=r*u+l,l=f>>>16,f&=65535,f+=i*c,l+=f>>>16,f&=65535,m=o*u+l,l=m>>>16,m&=65535,m+=r*c,l+=m>>>16,m&=65535,m+=i*s,l+=m>>>16,m&=65535,p=n*u+o*c+r*s+i*a+l,p&=65535,[p<<16|m,f<<16|d]}function f(e,t){return 32==(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])}function p(e,t){return 0==(t%=64)?[e[0],e[1]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]}function g(e,t){return[e[0]^t[0],e[1]^t[1]]}function h(e){let t=[e[0],e[1]];return t=g(t,[0,t[0]>>>1]),t=d(t,[4283543511,3981806797]),t=g(t,[0,t[0]>>>1]),t=d(t,[3301882366,444984403]),t=g(t,[0,t[0]>>>1]),t}function y(e){return("00000000"+(e>>>0).toString(16)).slice(-8)}function v(e,t=0){const n=e.length%16,o=e.length-n;let r=[0,t],i=[0,t];const a=[2277735313,289559509],s=[1291169091,658871167];for(let t=0;t<o;t+=16){let n=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],o=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24];n=d(n,a),n=f(n,31),n=d(n,s),r=g(r,n),r=f(r,27),r=m(r,i),r=m(d(r,[0,5]),[0,1390208809]),o=d(o,s),o=f(o,33),o=d(o,a),i=g(i,o),i=f(i,31),i=m(i,r),i=m(d(i,[0,5]),[0,944331445])}let c=[0,0],u=[0,0];switch(n){case 15:u=g(u,p([0,e.charCodeAt(o+14)],48));case 14:u=g(u,p([0,e.charCodeAt(o+13)],40));case 13:u=g(u,p([0,e.charCodeAt(o+12)],32));case 12:u=g(u,p([0,e.charCodeAt(o+11)],24));case 11:u=g(u,p([0,e.charCodeAt(o+10)],16));case 10:u=g(u,p([0,e.charCodeAt(o+9)],8));case 9:u=g(u,[0,e.charCodeAt(o+8)]),u=d(u,s),u=f(u,33),u=d(u,a),i=g(i,u);case 8:c=g(c,p([0,e.charCodeAt(o+7)],56));case 7:c=g(c,p([0,e.charCodeAt(o+6)],48));case 6:c=g(c,p([0,e.charCodeAt(o+5)],40));case 5:c=g(c,p([0,e.charCodeAt(o+4)],32));case 4:c=g(c,p([0,e.charCodeAt(o+3)],24));case 3:c=g(c,p([0,e.charCodeAt(o+2)],16));case 2:c=g(c,p([0,e.charCodeAt(o+1)],8));case 1:c=g(c,[0,e.charCodeAt(o)]),c=d(c,a),c=f(c,31),c=d(c,s),r=g(r,c)}return r=g(r,[0,e.length]),i=g(i,[0,e.length]),r=m(r,i),i=m(i,r),r=h(r),i=h(i),r=m(r,i),i=m(i,r),y(r[0])+y(r[1])+y(i[0])+y(i[1])}function x(e){return S(e,new Set)}function S(e,t){if(null===e)return"null";if(void 0===e)return"undefined";const n=typeof e;if("boolean"===n||"number"===n)return String(e);if("string"===n)return JSON.stringify(e);if(Array.isArray(e)){if(t.has(e))return'"[Circular]"';t.add(e);const n=e.map(e=>S(e,t));return t.delete(e),"["+n.join(",")+"]"}if("object"===n){const n=e;if(t.has(n))return'"[Circular]"';t.add(n);const o=Object.keys(n).sort().filter(e=>void 0!==n[e]).map(e=>JSON.stringify(e)+":"+S(n[e],t));return t.delete(n),"{"+o.join(",")+"}"}return String(e)}const b=v("",t);function w(e,n){const o=function(e){if(0===e.length)return v("",t);if(1===e.length)return v(e[0],t);let n=[...e];for(;n.length>1;){const e=[];for(let o=0;o<n.length;o+=2){const r=o+1<n.length?n[o+1]:b;e.push(v(n[o]+r,t))}n=e}return n[0]}(Object.keys(e).sort().map(n=>{const o=function(e){let n=t;for(let t=0;t<e.length;t++)n=Math.imul(n^e.charCodeAt(t),1540483477),n^=n>>>13;return n>>>0}(n);return v(x(e[n]),o)})),r=String.fromCharCode(76,111,98,115),i=n?v(n,t):"";return v(o+r+i,t)}function C(e){try{const t=e.getExtension("EXT_texture_filter_anisotropic")??e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")??e.getExtension("MOZ_EXT_texture_filter_anisotropic");return t?e.getParameter(t.MAX_TEXTURE_MAX_ANISOTROPY_EXT):null}catch{return null}}function A(e){try{const t=e.getContext("webgl2");if(!t)return null;const n={version:t.getParameter(t.VERSION),maxSamples:t.getParameter(t.MAX_SAMPLES),max3DTextureSize:t.getParameter(t.MAX_3D_TEXTURE_SIZE),maxArrayTextureLayers:t.getParameter(t.MAX_ARRAY_TEXTURE_LAYERS),maxUniformBlockSize:t.getParameter(t.MAX_UNIFORM_BLOCK_SIZE),maxVertexUniformComponents:t.getParameter(t.MAX_VERTEX_UNIFORM_COMPONENTS),maxFragmentUniformComponents:t.getParameter(t.MAX_FRAGMENT_UNIFORM_COMPONENTS),maxColorAttachments:t.getParameter(t.MAX_COLOR_ATTACHMENTS),maxDrawBuffers:t.getParameter(t.MAX_DRAW_BUFFERS)};return t.getExtension("WEBGL_lose_context")?.loseContext(),n}catch{return null}}function E(){const e=navigator.userAgentData;if(e?.platform)return e.platform;const t=navigator.userAgent??"";return/Windows/.test(t)?"Windows":/Macintosh|Mac OS X/.test(t)?"macOS":/CrOS/.test(t)?"Chrome OS":/Android/.test(t)?"Android":/Linux/.test(t)?"Linux":/iPhone|iPad|iPod/.test(t)?"iOS":""}function M(){try{const e=new ArrayBuffer(4),t=new Float32Array(e),n=new Uint8Array(e);return t[0]=1/0,n[3]}catch{return 0}}function P(e,t,n,o){const r=(n-t)/o;let i=e(t)+e(n);for(let n=1;n<o;n++)i+=e(t+n*r)*(n%2==0?2:4);return i*r/3}function T(){try{const e=(new Intl.DateTimeFormat).resolvedOptions();return{locale:e.locale,calendar:e.calendar,numberingSystem:e.numberingSystem,timeZone:e.timeZone}}catch{return{}}}function _(){try{const e=(new Intl.NumberFormat).resolvedOptions();return{locale:e.locale,numberingSystem:e.numberingSystem,style:e.style,minimumIntegerDigits:e.minimumIntegerDigits,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,useGrouping:e.useGrouping}}catch{return{}}}function R(){try{const e=(new Intl.Collator).resolvedOptions();return{locale:e.locale,usage:e.usage,sensitivity:e.sensitivity,collation:e.collation,numeric:e.numeric,caseFirst:e.caseFirst}}catch{return{}}}function I(){try{const e=(new Intl.PluralRules).resolvedOptions(),t=new Intl.PluralRules(void 0,{type:"ordinal"}).resolvedOptions();return{locale:e.locale,type:e.type,cardinalCategories:(new Intl.PluralRules).select(0)+","+(new Intl.PluralRules).select(1)+","+(new Intl.PluralRules).select(2)+","+(new Intl.PluralRules).select(5)+","+(new Intl.PluralRules).select(11)+","+(new Intl.PluralRules).select(100),ordinalCategory1:t.type,minimumIntegerDigits:e.minimumIntegerDigits}}catch{return{}}}function k(){try{const e=new Intl.RelativeTimeFormat;if(!e)return{};const t=e.resolvedOptions();return{locale:t.locale,style:t.style,numeric:t.numeric,numberingSystem:t.numberingSystem}}catch{return{}}}function O(){try{const e=new Intl.ListFormat;if(!e)return{};const t=e.resolvedOptions(),n=["X","Y","Z"],o=new Intl.ListFormat(void 0,{type:"conjunction",style:"long"}),r=new Intl.ListFormat(void 0,{type:"disjunction",style:"long"});return{locale:t.locale,type:t.type,style:t.style,conjunctionSample:o.format(n),disjunctionSample:r.format(n)}}catch{return{}}}const D=[["backdrop-filter","blur(1px)"],["container-type","inline-size"],["text-wrap","balance"],["overscroll-behavior","contain"],["hanging-punctuation","first"],["-webkit-line-clamp","1"],["appearance","none"],["font-size-adjust","ex-height 0.5"],["font-palette","normal"],["field-sizing","content"],["-webkit-text-stroke","1px black"],["zoom","1"],["scrollbar-width","thin"],["scrollbar-color","red blue"],["animation-timeline","auto"],["mask-composite","add"],["offset-path","none"],["text-decoration-thickness","1px"],["content-visibility","auto"],["contain-intrinsic-size","auto 100px"],["aspect-ratio","16/9"],["gap","10px"],["color-mix","in srgb, red 50%, blue"],["linear-gradient(in oklch, red, blue)",""]];function L(){try{const e=document.createElement("div");e.style.cssText="visibility:hidden;overflow:scroll;position:absolute;top:-9999px;width:100px;height:100px",document.body.appendChild(e);const t=document.createElement("div");e.appendChild(t);const n=e.offsetWidth-t.offsetWidth;return document.body.removeChild(e),n}catch{return-1}}function N(){const e={};if("undefined"==typeof CSS||"function"!=typeof CSS.supports)return e;for(const[t,n]of D)e[t]=n?CSS.supports(t,n):CSS.supports(t);return e}function F(){try{const e=document.createElement("div");e.style.cssText=["position:fixed","top:0","left:0","width:0","height:0","visibility:hidden","padding-top:env(safe-area-inset-top,0px)","padding-bottom:env(safe-area-inset-bottom,0px)","padding-left:env(safe-area-inset-left,0px)","padding-right:env(safe-area-inset-right,0px)"].join(";"),document.body.appendChild(e);const t=getComputedStyle(e),n={top:t.paddingTop,bottom:t.paddingBottom,left:t.paddingLeft,right:t.paddingRight};return document.body.removeChild(e),n}catch{return null}}function B(){try{const e=performance.now();let t=1/0,n=e;for(let o=0;o<50;o++){const o=performance.now(),r=o-n;if(r>0&&r<t&&(t=r),n=o,o-e>=1)break}if(t===1/0)return-1;const o=1e3*t;if(o<=0)return-1;const r=Math.max(0,Math.round(Math.log10(o)));return Math.pow(10,r)}catch{return-1}}const U=["Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Bookman Old Style","Bradley Hand","Calibri","Cambria","Cambria Math","Century","Century Gothic","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Gill Sans","Helvetica","Helvetica Neue","Impact","Lucida Console","Lucida Grande","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3","Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Ubuntu","Merriweather","Playfair Display","Source Sans Pro","Source Code Pro","Fira Code","JetBrains Mono","Cascadia Code","Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","SF Pro","SF Pro Display","SF Mono","San Francisco","Menlo","Andale Mono","Futura","MS Gothic","MS Mincho","MS PGothic","MS PMincho","Yu Gothic","Meiryo","Hiragino Sans","Hiragino Kaku Gothic Pro","SimSun","SimHei","Microsoft YaHei","PingFang SC","Noto Sans CJK","Malgun Gothic","Arial Hebrew"],V=["monospace","sans-serif","serif"],W="mmMwWLliI0O&1";function X(e,t){const n=[],o=e.split("\r\n");let r=!1;for(const e of o)if(e.startsWith(`m=${t}`))r=!0;else{if(e.startsWith("m=")&&r)break;if(r&&e.startsWith("a=rtpmap:")){const t=e.match(/^a=rtpmap:\d+\s+(.+)$/);t&&n.push(t[1])}}return n}const z=["accelerometer","accessibility-events","ambient-light-sensor","background-fetch","background-sync","bluetooth","camera","clipboard-read","clipboard-write","display-capture","geolocation","gyroscope","local-fonts","magnetometer","microphone","midi","nfc","notifications","payment-handler","persistent-storage","push","screen-wake-lock","speaker-selection","storage-access","top-level-storage-access","window-management","xr-spatial-tracking"];function G(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;let n=e[0],o=0;for(const[e,r]of Object.entries(t))r>o&&(n=e,o=r);return n}const j=[{name:"prefers-contrast",values:["no-preference","more","less","custom"]},{name:"any-hover",values:["none","hover"]},{name:"any-pointer",values:["none","coarse","fine"]},{name:"pointer",values:["none","coarse","fine"]},{name:"hover",values:["none","hover"]},{name:"update",values:["none","slow","fast"]},{name:"inverted-colors",values:["none","inverted"]},{name:"prefers-reduced-motion",values:["no-preference","reduce"]},{name:"prefers-reduced-transparency",values:["no-preference","reduce"]},{name:"scripting",values:["none","initial-only","enabled"]},{name:"forced-colors",values:["none","active"]},{name:"prefers-color-scheme",values:["light","dark"]},{name:"color-gamut",values:["srgb","p3","rec2020"]},{name:"dynamic-range",values:["standard","high"]}],H=["KeyQ","KeyW","KeyA","KeyS","KeyZ","KeyX","KeyY","KeyM","Semicolon","BracketLeft","Quote","Digit1","Digit2","Digit3"];function K(e){const t=e.KeyQ,n=e.KeyZ,o=e.KeyY;return t?"a"===t?"azerty":"q"===t&&"z"===o?"qwertz":"q"===t&&"z"===n?"qwerty":"'"===t?"dvorak":"other":null}const $=[{name:"webgl",tier:1,async collect(){const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!(t&&t instanceof WebGLRenderingContext))return null;const n=t.getExtension("WEBGL_debug_renderer_info"),o=t.getSupportedExtensions()??[],r=function(e){const t={},n=[e.VERTEX_SHADER,e.FRAGMENT_SHADER],o=[e.LOW_FLOAT,e.MEDIUM_FLOAT,e.HIGH_FLOAT,e.LOW_INT,e.MEDIUM_INT,e.HIGH_INT],r=["vertex","fragment"],i=["lowFloat","mediumFloat","highFloat","lowInt","mediumInt","highInt"];for(let a=0;a<n.length;a++){const s={};for(let t=0;t<o.length;t++){const r=e.getShaderPrecisionFormat(n[a],o[t]);r&&(s[i[t]]={rangeMin:r.rangeMin,rangeMax:r.rangeMax,precision:r.precision})}t[r[a]]=s}return t}(t),i={vendor:t.getParameter(t.VENDOR),renderer:t.getParameter(t.RENDERER),version:t.getParameter(t.VERSION),shadingLanguageVersion:t.getParameter(t.SHADING_LANGUAGE_VERSION),unmaskedVendor:n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):null,unmaskedRenderer:n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):null,extensions:o.sort(),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE),maxViewportDims:Array.from(t.getParameter(t.MAX_VIEWPORT_DIMS)),maxVertexAttribs:t.getParameter(t.MAX_VERTEX_ATTRIBS),maxVertexUniformVectors:t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),maxFragmentUniformVectors:t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:t.getParameter(t.MAX_VARYING_VECTORS),aliasedLineWidthRange:Array.from(t.getParameter(t.ALIASED_LINE_WIDTH_RANGE)),aliasedPointSizeRange:Array.from(t.getParameter(t.ALIASED_POINT_SIZE_RANGE)),maxCombinedTextureImageUnits:t.getParameter(t.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxTextureImageUnits:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextureImageUnits:t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),shaderPrecision:r,maxAnisotropy:C(t),webgl2:A(e)};return t.getExtension("WEBGL_lose_context")?.loseContext(),i}},{name:"hardware",tier:1,collect:async()=>({architecture:M(),platform:E()})},{name:"hardwareSensitive",tier:1,collect:async()=>({deviceMemory:navigator.deviceMemory??null,hardwareConcurrency:navigator.hardwareConcurrency??null})},{name:"math",tier:1,collect:async()=>({acos:Math.acos(.5),asin:P(Math.asin,-1,1,97),cos:P(Math.cos,0,Math.PI,97),cosLarge:Math.cos(1e20),sinLarge:Math.sin(1e20),tanLarge:Math.tan(1e20),sin:P(Math.sin,0,Math.PI,97),tan:P(Math.tan,0,Math.PI/4,97)})},{name:"i18n",tier:1,collect:async()=>({dateTimeFormat:T(),numberFormat:_(),collator:R(),pluralRules:I(),relativeTimeFormat:k(),listFormat:O()})},{name:"domrect",tier:1,collect:async()=>({basic:function(){const e=document.createElement("div");e.style.cssText="position:fixed;left:-9999px;width:100px;height:100px;",document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}(),precision:function(){const e=document.createElement("div");e.style.cssText=`position:absolute;left:-9999px;width:${Math.PI}px;height:${Math.E}px;`,document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{width:t.width,height:t.height}}(),fromRect:"undefined"!=typeof DOMRectReadOnly&&"function"==typeof DOMRectReadOnly.fromRect})},{name:"touch",tier:1,collect:async()=>({supported:"ontouchstart"in window||navigator.maxTouchPoints>0,maxTouchPoints:navigator.maxTouchPoints??0})},{name:"display",tier:1,collect:async()=>({colorDepth:screen.colorDepth??0,pixelDepth:screen.pixelDepth??0})},{name:"locale",tier:1,collect:async()=>({timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"",language:navigator.language??""})},{name:"workers",tier:1,collect:async()=>({webWorker:"undefined"!=typeof Worker,sharedWorker:"undefined"!=typeof SharedWorker,serviceWorker:"serviceWorker"in navigator})},{name:"plugins",tier:1,async collect(){const e=[];if(navigator.plugins)for(let t=0;t<navigator.plugins.length;t++){const n=navigator.plugins[t];"internal-pdf-viewer"===n.filename&&e.push(`${n.name}|${n.filename}|${n.description}`)}return{plugins:e.sort(),pdfViewerEnabled:navigator.pdfViewerEnabled??!1}}},{name:"css",tier:1,collect:async()=>({scrollbarWidth:L(),supports:N(),safeArea:F()})},{name:"navigatorProps",tier:1,collect:async()=>({vendor:navigator.vendor??"",productSub:navigator.productSub??"",cookieEnabled:navigator.cookieEnabled})},{name:"timing",tier:2,collect:async()=>({performancePrecisionUs:B()})},{name:"navigatorConnection",tier:2,async collect(){const e=navigator,t=e.connection??e.mozConnection??e.webkitConnection??null,n=performance.memory??null;return{connection:t?{type:t.type??null,effectiveType:t.effectiveType??null,saveData:t.saveData??null}:null,memory:n?{jsHeapSizeLimit:n.jsHeapSizeLimit}:null}}},{name:"webgpu",tier:2,async collect(){const e=navigator.gpu;if(!e)return null;const t=await e.requestAdapter();if(!t)return null;let n="",o="",r="",i="";if(t.info)n=t.info.vendor??"",o=t.info.architecture??"",r=t.info.device??"",i=t.info.description??"";else if("function"==typeof t.requestAdapterInfo){const e=await t.requestAdapterInfo();n=e.vendor??"",o=e.architecture??"",r=e.device??"",i=e.description??""}const a=[];t.features&&(t.features.forEach(e=>a.push(e)),a.sort());const s={};if(t.limits){const e=["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderComponents","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension"];for(const n of e){const e=t.limits[n];void 0!==e&&(s[n]=e)}}return{vendor:n,architecture:o,device:r,description:i,features:a,limits:s}}},{name:"audio",tier:2,async collect(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return null;let t=null;try{t=new e;const n=t.destination;return{sampleRate:t.sampleRate,maxChannelCount:n.maxChannelCount,channelCount:n.channelCount,channelCountMode:n.channelCountMode,channelInterpretation:n.channelInterpretation,baseLatency:t.baseLatency??null,outputLatency:t.outputLatency??null}}finally{if(t&&"closed"!==t.state)try{await t.close()}catch{}}}},{name:"fonts",tier:2,collect:()=>new Promise(e=>{const t=()=>e(function(){try{if("undefined"==typeof document)return{available:[],method:"css-layout"};const e=new Set,t=[];if("function"==typeof document.fonts?.check)for(const n of U)document.fonts.check(`72px "${n}"`)?e.add(n):t.push(n);else t.push(...U);const n=new Set;if(t.length>0){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px;left:-9999px;pointer-events:none;";const o=V.map(t=>{const n=document.createElement("span");return n.style.cssText=`font-size:72px;font-family:${t};white-space:nowrap;display:inline-block`,n.textContent=W,e.appendChild(n),n}),r=t.map(t=>V.map(n=>{const o=document.createElement("span");return o.style.cssText=`font-size:72px;font-family:'${t}',${n};white-space:nowrap;display:inline-block`,o.textContent=W,e.appendChild(o),o}));document.body.appendChild(e);const i=o.map(e=>e.getBoundingClientRect().width),a=r.map(e=>e.map(e=>e.getBoundingClientRect().width));document.body.removeChild(e);for(let e=0;e<t.length;e++)for(let o=0;o<V.length;o++)if(a[e][o]!==i[o]){n.add(t[e]);break}}return{available:U.filter(t=>e.has(t)||n.has(t)),method:"css-layout"}}catch{return{available:[],method:"css-layout"}}}());"undefined"!=typeof requestIdleCallback?requestIdleCallback(t,{timeout:2e3}):setTimeout(t,0)})},{name:"webrtc",tier:2,async collect(){if("undefined"==typeof RTCPeerConnection)return{supported:!1,audioCodecCount:0,videoCodecCount:0,audioCodecs:[],videoCodecs:[],extensions:[]};const e=new RTCPeerConnection({iceServers:[]});try{e.addTransceiver("audio"),e.addTransceiver("video");const t=(await e.createOffer()).sdp??"",n=X(t,"audio"),o=X(t,"video"),r=function(e){const t=new Set,n=e.split("\r\n");for(const e of n)if(e.startsWith("a=extmap:")){const n=e.match(/^a=extmap:\d+(?:\/\w+)?\s+(.+)$/);n&&t.add(n[1].trim())}return Array.from(t)}(t);return{supported:!0,audioCodecCount:n.length,videoCodecCount:o.length,audioCodecs:n.sort(),videoCodecs:o.sort(),extensions:r.sort()}}finally{e.close()}}},{name:"permissions",tier:2,async collect(){if(!navigator.permissions?.query)return{states:{}};const e=()=>Promise.allSettled(z.map(async e=>{try{return{name:e,state:(await navigator.permissions.query({name:e})).state}}catch{return{name:e,state:"error"}}})),t=await Promise.all([e(),e(),e()]),n={};for(const e of t)for(const t of e)if("fulfilled"===t.status){const{name:e,state:o}=t.value;n[e]||(n[e]=[]),n[e].push(o)}const o={};for(const[e,t]of Object.entries(n))o[e]=G(t);return{states:o}}},{name:"speech",tier:2,async collect(){if("undefined"==typeof speechSynthesis)return{supported:!1,voiceCount:0,voices:[]};const e=await new Promise(e=>{const t=speechSynthesis.getVoices();if(t.length>0)return void e(t);const n=setTimeout(()=>e([]),800);speechSynthesis.addEventListener("voiceschanged",()=>{clearTimeout(n),e(speechSynthesis.getVoices())},{once:!0})}),t=e.map(e=>`${e.name}|${e.lang}|${e.localService}`).sort();return{supported:!0,voiceCount:e.length,voices:t}}},{name:"mediaQueries",tier:2,async collect(){if("function"!=typeof matchMedia){const e={};for(const t of j)e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]="unsupported";return{...e,monochrome:0}}const e={};for(const t of j){let n="unknown";for(const e of t.values){const o=matchMedia(`(${t.name}: ${e})`);if(o?.matches){n=e;break}}e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]=n}let t=0;for(let e=100;e>=0;e--)if(matchMedia(`(monochrome: ${e})`)?.matches){t=e;break}return{...e,monochrome:t}}},{name:"applePay",tier:2,async collect(){const e=window.ApplePaySession;if(!e||"function"!=typeof e.supportsVersion)return{supported:!1,maxVersion:0};let t=0;for(let n=15;n>=1;n--)try{if(e.supportsVersion(n)){t=n;break}}catch{continue}return{supported:!0,maxVersion:t}}},{name:"keyboard",tier:2,async collect(){const e=navigator.keyboard;if(!e||"function"!=typeof e.getLayoutMap)return{supported:!1,layoutKeys:null,layoutHint:null};try{const t=await e.getLayoutMap(),n={};for(const e of H){const o=t.get(e);void 0!==o&&(n[e]=o)}return{supported:!0,layoutKeys:n,layoutHint:K(n)}}catch{return{supported:!1,layoutKeys:null,layoutHint:null}}}}];async function q(e,t,n){const o={},r=[],i=$.filter(t=>!e.has(t.name)&&(n||3!==t.tier)),a=await Promise.allSettled(i.map(async e=>{const n=await(o=e.collect(),r=t,new Promise((e,t)=>{const n=setTimeout(()=>e(null),r);o.then(t=>{clearTimeout(n),e(t)},e=>{clearTimeout(n),t(e)})}));var o,r;return{name:e.name,value:n}}));for(let e=0;e<a.length;e++){const t=a[e],n=i[e].name;"fulfilled"===t.status&&null!==t.value.value?o[n]=t.value.value:"rejected"===t.status&&r.push({signal:n,error:String(t.reason?.message??t.reason)})}return{components:o,errors:r}}async function Z(t){const i=function(e){return e?{exclude:e.exclude??n.exclude,include:e.include??n.include,timeout:e.timeout??n.timeout,stabilize:e.stabilize??n.stabilize,experimental:e.experimental??n.experimental,debug:e.debug??n.debug,salt:e.salt??n.salt}:{...n}}(t),c=s(),u=function(){try{return window.self!==window.top}catch{return!0}}();let d=!1;try{d=await l(c.name)}catch{}const f=function(e,t,n,o){const r=new Set;for(const i of e){if("private"===i&&!n)continue;if("iframe"===i&&!o)continue;const e=a[i];if(e)for(const n of e)if(!n.browsers||n.browsers.includes(t))for(const e of n.exclude)r.add(e)}return r}(i.stabilize,c.name,d,u),m=new Set(f);for(const e of i.exclude)m.add(e);for(const e of i.include)m.delete(e);const{components:p,errors:h}=await q(m,i.timeout,i.experimental),g={t:e};for(const[e,t]of Object.entries(p))o.has(e)||(g[e]=t);const y=w(g,i.salt),S={t:e};for(const[e,t]of Object.entries(p))r.has(e)||(S[e]=t);const v=w(S,i.salt),x={hash:y,stableHash:v,components:{...p,t:e},timestamp:(new Date).toISOString(),version:e,isIncognito:d,errors:h};return i.debug&&(console.log("[fingerprint] components:",p),console.log("[fingerprint] hash:",y,"stableHash:",v),h.length>0&&console.warn("[fingerprint] errors:",h)),x}const Q=new RegExp(["googlebot","bingbot","slurp","baiduspider","duckduckbot","yandex","sogou","exabot","ia_archiver","curl","wget","python-requests","python-urllib","axios","node-fetch","go-http-client","java/","libwww-perl","okhttp","apache-httpclient","http_request","httpie","headlesschrome","phantomjs","puppeteer","playwright","cypress","selenium","webdriver","electron","jsdom","vercel-screenshot","screenshot","prerender","lighthouse","chrome-lighthouse","pagespeed","gtmetrix","pingdom","nessus","nikto","sqlmap","burp","zap","qualys","openvas","nmap","masscan","facebookexternalhit","twitterbot","linkedinbot","whatsapp","telegrambot","slackbot","discordbot","bot","crawl","spider","scrape","fetch","scan"].join("|"),"i");function ee(e){return!!e&&Q.test(e)}const SENTINEL_USER_IDS=new Set(["__pre_auth__","anonymous","guest","undefined","null"]);function isSentinelUserId(e){return"string"==typeof e&&SENTINEL_USER_IDS.has(e)}const DEFAULT_MAX_RETRIES=3,DEFAULT_TIMEOUT_MS=3e4,MAX_DELAY_MS=3e4,BASE_DELAY_MS=1e3,SUBMIT_FP_PATH="/__unshared/submit-fp",SS_EMAIL_KEY="__unshared_email",SS_FP_KEY="__unshared_fp",SS_LAST_SUBMIT_KEY="__unshared_last_submit",LS_DEVICE_ID="__unshared_device_id",COOKIE_UID="__unshared_uid",COOKIE_SID="__unshared_sid";function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function sleep(e){return new Promise(t=>setTimeout(t,e))}function retryDelay(e){const t=Math.min(1e3*Math.pow(2,e-1),3e4),n=500*Math.random()-250;return Math.max(0,t+n)}function getCookie(e){if("undefined"==typeof document)return;const t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):void 0}function setCookie(e,t){"undefined"!=typeof document&&(document.cookie=`${e}=${encodeURIComponent(t)}; Path=/; SameSite=Lax`)}function deleteCookie(e){"undefined"!=typeof document&&(document.cookie=`${e}=; Path=/; SameSite=Lax; Expires=Thu, 01 Jan 1970 00:00:00 GMT`)}function getLocalStorageItem(e){if("undefined"!=typeof localStorage)try{return localStorage.getItem(e)??void 0}catch{return}}function setLocalStorageItem(e,t){if("undefined"!=typeof localStorage)try{localStorage.setItem(e,t)}catch{}}function getSessionStorageItem(e){if("undefined"!=typeof sessionStorage)try{return sessionStorage.getItem(e)??void 0}catch{return}}function setSessionStorageItem(e,t){if("undefined"!=typeof sessionStorage)try{sessionStorage.setItem(e,t)}catch{}}function isValidUrl(e){try{return new URL(e),!0}catch{return!1}}class UnsharedLabsBrowser{constructor(e={}){if(this.o="",e.baseUrl&&!isValidUrl(e.baseUrl))throw new Error('baseUrl must be a valid URL (e.g. "https://app.example.com")');let t,n;this.i=e.baseUrl?e.baseUrl.replace(/\/$/,""):"",this.u=e.maxRetries??3,this.l=e.timeout??3e4,this.m=e.includePathPrefix,this.p=e.skipPaths,this.h=e.sessionId,this.S=e.deviceId,this.o=getSessionStorageItem(SS_LAST_SUBMIT_KEY)??"";try{t=this.h?.()}catch{}this.v=t??getCookie(COOKIE_SID)??generateUUID(),setCookie(COOKIE_SID,this.v);try{n=this.S?.()}catch{}n?(this._=n,setLocalStorageItem(LS_DEVICE_ID,n)):this._=getLocalStorageItem(LS_DEVICE_ID)??"",this.I()}async init(e){try{if("undefined"!=typeof navigator&&ee(navigator.userAgent))return;if(isSentinelUserId(e.userId))return void this.C;this.C=e.userId,this.M=e.emailAddress,"undefined"!=typeof sessionStorage&&sessionStorage.setItem(SS_EMAIL_KEY,e.emailAddress),setCookie(COOKIE_UID,e.userId);let t,n=this.k();n||(n=await this.collect(),this.D(n));try{t=this.S?.()}catch{}t?(this._=t,setLocalStorageItem(LS_DEVICE_ID,t)):n.fingerprint_id&&(this._=n.fingerprint_id,setLocalStorageItem(LS_DEVICE_ID,n.fingerprint_id)),this.L(n).catch(()=>{})}catch{}}onRouteChange(){try{if(!this.P())return;const e=this.k();if(!e)return;this.L(e).catch(()=>{})}catch{}}destroy(){try{"undefined"!=typeof sessionStorage&&(sessionStorage.removeItem(SS_EMAIL_KEY),sessionStorage.removeItem(SS_FP_KEY),sessionStorage.removeItem(SS_LAST_SUBMIT_KEY)),this.o="",deleteCookie(COOKIE_UID),this.T&&"undefined"!=typeof document&&(document.removeEventListener("DOMContentLoaded",this.T),this.T=void 0),this.C=void 0,this.M=void 0}catch{}}async collect(e){const t=[...new Set(["timing","speech",...e?.exclude??[]])],n=await Z({...e,exclude:t});return{fingerprint_id:n.stableHash,full_hash:n.hash,components:n.components,timestamp:n.timestamp,isIncognito:n.isIncognito,version:n.version}}async submitFingerprintEvent(e,t){try{const n=this.A(e,t),o=generateUUID(),r=`${this.i}${SUBMIT_FP_PATH}`;return await this.U(r,JSON.stringify(n),o)}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}P(){if("undefined"!=typeof sessionStorage)return sessionStorage.getItem(SS_EMAIL_KEY)??void 0}k(){if("undefined"==typeof sessionStorage)return;const e=sessionStorage.getItem(SS_FP_KEY);if(e)try{return JSON.parse(e)}catch{return}}D(e){"undefined"!=typeof sessionStorage&&sessionStorage.setItem(SS_FP_KEY,JSON.stringify(e))}O(){if("undefined"==typeof location)return!0;const e=location.pathname||"/";if(this.p)for(const t of this.p)if(e.startsWith(t))return!1;return!this.m||this.m.some(t=>e.startsWith(t))}async L(e){if("undefined"!=typeof navigator&&ee(navigator.userAgent))return{success:!0};if(!this.O())return{success:!0};const t=this.M??this.P(),n=this.C??getCookie(COOKIE_UID),o="undefined"!=typeof location?(location.pathname||"/")+(location.search||""):"/";if(n){const e=`${n}|${o}`;if(e===this.o)return{success:!0};this.o=e,setSessionStorageItem(SS_LAST_SUBMIT_KEY,e)}const r={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:(new Date).toISOString(),is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.v,event_type:o};n&&(r.user_id=n),t&&(r.email=t);const i=`${e.fingerprint_id}|${n??""}|${o}`,a=`${this.i}${SUBMIT_FP_PATH}`;return this.U(a,JSON.stringify(r),i)}I(){"undefined"!=typeof document&&(this.T&&document.removeEventListener("DOMContentLoaded",this.T),this.T=()=>{if(!this.P())return;const e=this.k();e&&this.L(e).catch(()=>{})},document.addEventListener("DOMContentLoaded",this.T))}async U(e,t,n){const o=this.u+1;let r={success:!1,error:{code:"DELIVERY_FAILED",message:"Request failed"}};for(let i=1;i<=o;i++){i>1&&await sleep(retryDelay(i-1));const o=new AbortController,a=setTimeout(()=>o.abort(),this.l);try{const i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Idempotency-Key":n,"X-Session-Id":this.v,"X-Device-Id":this._},body:t,signal:o.signal});if(clearTimeout(a),i.status>=500){r={success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${i.status}`}};continue}if(i.status>=400)return{success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${i.status}`}};const s=await i.text().catch(()=>"{}");let c;try{c=JSON.parse(s)}catch{c={}}return!1===c?.success?{success:!1,error:c.error??{code:"UPSTREAM_ERROR",message:"Upstream failed"}}:{success:!0,data:c?.data}}catch(e){clearTimeout(a),r={success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}return r}A(e,t){const n={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:e.timestamp,is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.v};n.user_id=t.userId,null!=t?.eventType&&(n.event_type=t.eventType);const o=this.M??this.P();return o&&(n.email=o),n}}function createAxiosInterceptor(e){return t=>{if(403===t?.response?.status&&"account_flagged"===t?.response?.data?.error)try{e.onFlagged()}catch{}return Promise.reject(t)}}function createFetchInterceptor(e,t){return async(...n)=>{const o=await e(...n);if(403===o.status){const e=o.clone();try{const n=await e.json();if("account_flagged"===n?.error)try{t.onFlagged()}catch{}}catch{}}return o}}exports.UnsharedLabsBrowser=UnsharedLabsBrowser,exports.createAxiosInterceptor=createAxiosInterceptor,exports.createFetchInterceptor=createFetchInterceptor;
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { UnsharedLabsBrowser } from './browser';
2
- export type { BrowserConfig, SubmitFingerprintOptions, SubmitFingerprintResult, BrowserApiResult, } from './browser';
1
+ export { UnsharedLabsBrowser, createAxiosInterceptor, createFetchInterceptor } from './browser';
2
+ export type { BrowserConfig, InitOptions, SubmitFingerprintOptions, SubmitFingerprintResult, BrowserApiResult, FlaggedInterceptorOptions, } from './browser';
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const e="1.0.0",t=1282368115,n={exclude:[],include:[],timeout:3e3,stabilize:["private","iframe","always"],experimental:!1,debug:!1,salt:""},r=new Set(["audio","timing","navigatorConnection","domrect","permissions","fonts"]),o={always:[{exclude:["speech"],browsers:["brave","firefox"]},{exclude:["keyboard"],browsers:["firefox","safari"]},{exclude:["workers"],browsers:["firefox"]},{exclude:["hardwareSensitive","navigatorProps"],browsers:["brave"]}],private:[{exclude:["fonts"],browsers:["firefox"]},{exclude:["audio"],browsers:["safari","brave"]}],iframe:[{exclude:["applePay"],browsers:["safari"]},{exclude:["permissions"]},{exclude:["keyboard"]}]};let a=null;function i(){if(a)return a;const e=navigator.userAgent;return a=function(){const e=navigator.brave;return!!e&&"function"==typeof e.isBrave}()?{name:"brave",version:s(e,/Chrome\/([\d.]+)/)}:/Edg\//i.test(e)?{name:"edge",version:s(e,/Edg\/([\d.]+)/)}:/OPR\//i.test(e)||/Opera/i.test(e)?{name:"opera",version:s(e,/OPR\/([\d.]+)/)||s(e,/Opera\/([\d.]+)/)}:/SamsungBrowser/i.test(e)?{name:"samsung",version:s(e,/SamsungBrowser\/([\d.]+)/)}:/Firefox\//i.test(e)?{name:"firefox",version:s(e,/Firefox\/([\d.]+)/)}:/Safari\//i.test(e)&&!/Chrome/i.test(e)?{name:"safari",version:s(e,/Version\/([\d.]+)/)}:/Chrome\//i.test(e)?{name:"chrome",version:s(e,/Chrome\/([\d.]+)/)}:{name:"unknown",version:""},a}function s(e,t){const n=e.match(t);return n?.[1]??""}async function c(e){try{switch(e){case"chrome":case"edge":case"opera":default:return await l();case"brave":return await async function(){return!1}();case"safari":return await async function(){if(navigator.storage?.estimate){const{quota:e}=await navigator.storage.estimate();if(void 0!==e)return e<4294967296}try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"NotFoundError"===e?.name}}();case"firefox":return await async function(){if(!("serviceWorker"in navigator))return!0;try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"SecurityError"===e?.name}}()}}catch{return!1}}async function l(){if(!navigator.storage?.estimate)return!1;const{quota:e}=await navigator.storage.estimate();return void 0!==e&&e<4294967296}function u(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,a=65535&e[1],i=t[0]>>>16,s=65535&t[0],c=t[1]>>>16;let u=0,l=0,f=0,m=0,d=0;return l=a+(65535&t[1]),u=l>>>16,l&=65535,f=o+c+u,u=f>>>16,f&=65535,m=r+s+u,u=m>>>16,m&=65535,d=n+i+u,d&=65535,[d<<16|m,f<<16|l]}function m(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,a=65535&e[1],i=t[0]>>>16,s=65535&t[0],c=t[1]>>>16,u=65535&t[1];let l=0,f=0,m=0,d=0,p=0;return f=a*u,l=f>>>16,f&=65535,m=o*u+l,l=m>>>16,m&=65535,m+=a*c,l+=m>>>16,m&=65535,d=r*u+l,l=d>>>16,d&=65535,d+=o*c,l+=d>>>16,d&=65535,d+=a*s,l+=d>>>16,d&=65535,p=n*u+r*c+o*s+a*i+l,p&=65535,[p<<16|d,m<<16|f]}function d(e,t){return 32==(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])}function f(e,t){return 0==(t%=64)?[e[0],e[1]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]}function p(e,t){return[e[0]^t[0],e[1]^t[1]]}function g(e){let t=[e[0],e[1]];return t=p(t,[0,t[0]>>>1]),t=m(t,[4283543511,3981806797]),t=p(t,[0,t[0]>>>1]),t=m(t,[3301882366,444984403]),t=p(t,[0,t[0]>>>1]),t}function h(e){return("00000000"+(e>>>0).toString(16)).slice(-8)}function y(e,t=0){const n=e.length%16,r=e.length-n;let o=[0,t],a=[0,t];const i=[2277735313,289559509],s=[1291169091,658871167];for(let t=0;t<r;t+=16){let n=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],r=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24];n=m(n,i),n=d(n,31),n=m(n,s),o=p(o,n),o=d(o,27),o=u(o,a),o=u(m(o,[0,5]),[0,1390208809]),r=m(r,s),r=d(r,33),r=m(r,i),a=p(a,r),a=d(a,31),a=u(a,o),a=u(m(a,[0,5]),[0,944331445])}let c=[0,0],l=[0,0];switch(n){case 15:l=p(l,f([0,e.charCodeAt(r+14)],48));case 14:l=p(l,f([0,e.charCodeAt(r+13)],40));case 13:l=p(l,f([0,e.charCodeAt(r+12)],32));case 12:l=p(l,f([0,e.charCodeAt(r+11)],24));case 11:l=p(l,f([0,e.charCodeAt(r+10)],16));case 10:l=p(l,f([0,e.charCodeAt(r+9)],8));case 9:l=p(l,[0,e.charCodeAt(r+8)]),l=m(l,s),l=d(l,33),l=m(l,i),a=p(a,l);case 8:c=p(c,f([0,e.charCodeAt(r+7)],56));case 7:c=p(c,f([0,e.charCodeAt(r+6)],48));case 6:c=p(c,f([0,e.charCodeAt(r+5)],40));case 5:c=p(c,f([0,e.charCodeAt(r+4)],32));case 4:c=p(c,f([0,e.charCodeAt(r+3)],24));case 3:c=p(c,f([0,e.charCodeAt(r+2)],16));case 2:c=p(c,f([0,e.charCodeAt(r+1)],8));case 1:c=p(c,[0,e.charCodeAt(r)]),c=m(c,i),c=d(c,31),c=m(c,s),o=p(o,c)}return o=p(o,[0,e.length]),a=p(a,[0,e.length]),o=u(o,a),a=u(a,o),o=g(o),a=g(a),o=u(o,a),a=u(a,o),h(o[0])+h(o[1])+h(a[0])+h(a[1])}function v(e){return x(e,new Set)}function x(e,t){if(null===e)return"null";if(void 0===e)return"undefined";const n=typeof e;if("boolean"===n||"number"===n)return String(e);if("string"===n)return JSON.stringify(e);if(Array.isArray(e)){if(t.has(e))return'"[Circular]"';t.add(e);const n=e.map(e=>x(e,t));return t.delete(e),"["+n.join(",")+"]"}if("object"===n){const n=e;if(t.has(n))return'"[Circular]"';t.add(n);const r=Object.keys(n).sort().filter(e=>void 0!==n[e]).map(e=>JSON.stringify(e)+":"+x(n[e],t));return t.delete(n),"{"+r.join(",")+"}"}return String(e)}const S=y("",t);function C(e,n){const r=function(e){if(0===e.length)return y("",t);if(1===e.length)return y(e[0],t);let n=[...e];for(;n.length>1;){const e=[];for(let r=0;r<n.length;r+=2){const o=r+1<n.length?n[r+1]:S;e.push(y(n[r]+o,t))}n=e}return n[0]}(Object.keys(e).sort().map(n=>{const r=function(e){let n=t;for(let t=0;t<e.length;t++)n=Math.imul(n^e.charCodeAt(t),1540483477),n^=n>>>13;return n>>>0}(n);return y(v(e[n]),r)})),o=String.fromCharCode(76,111,98,115),a=n?y(n,t):"";return y(r+o+a,t)}function w(e){try{const t=e.getExtension("EXT_texture_filter_anisotropic")??e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")??e.getExtension("MOZ_EXT_texture_filter_anisotropic");return t?e.getParameter(t.MAX_TEXTURE_MAX_ANISOTROPY_EXT):null}catch{return null}}function b(e){try{const t=e.getContext("webgl2");if(!t)return null;const n={version:t.getParameter(t.VERSION),maxSamples:t.getParameter(t.MAX_SAMPLES),max3DTextureSize:t.getParameter(t.MAX_3D_TEXTURE_SIZE),maxArrayTextureLayers:t.getParameter(t.MAX_ARRAY_TEXTURE_LAYERS),maxUniformBlockSize:t.getParameter(t.MAX_UNIFORM_BLOCK_SIZE),maxVertexUniformComponents:t.getParameter(t.MAX_VERTEX_UNIFORM_COMPONENTS),maxFragmentUniformComponents:t.getParameter(t.MAX_FRAGMENT_UNIFORM_COMPONENTS),maxColorAttachments:t.getParameter(t.MAX_COLOR_ATTACHMENTS),maxDrawBuffers:t.getParameter(t.MAX_DRAW_BUFFERS)};return t.getExtension("WEBGL_lose_context")?.loseContext(),n}catch{return null}}function A(){const e=navigator.userAgentData;if(e?.platform)return e.platform;const t=navigator.userAgent??"";return/Windows/.test(t)?"Windows":/Macintosh|Mac OS X/.test(t)?"macOS":/CrOS/.test(t)?"Chrome OS":/Android/.test(t)?"Android":/Linux/.test(t)?"Linux":/iPhone|iPad|iPod/.test(t)?"iOS":""}function E(){try{const e=new ArrayBuffer(4),t=new Float32Array(e),n=new Uint8Array(e);return t[0]=1/0,n[3]}catch{return 0}}function M(e,t,n,r){const o=(n-t)/r;let a=e(t)+e(n);for(let n=1;n<r;n++)a+=e(t+n*o)*(n%2==0?2:4);return a*o/3}function P(){try{const e=(new Intl.DateTimeFormat).resolvedOptions();return{locale:e.locale,calendar:e.calendar,numberingSystem:e.numberingSystem,timeZone:e.timeZone}}catch{return{}}}function T(){try{const e=(new Intl.NumberFormat).resolvedOptions();return{locale:e.locale,numberingSystem:e.numberingSystem,style:e.style,minimumIntegerDigits:e.minimumIntegerDigits,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,useGrouping:e.useGrouping}}catch{return{}}}function _(){try{const e=(new Intl.Collator).resolvedOptions();return{locale:e.locale,usage:e.usage,sensitivity:e.sensitivity,collation:e.collation,numeric:e.numeric,caseFirst:e.caseFirst}}catch{return{}}}function I(){try{const e=(new Intl.PluralRules).resolvedOptions(),t=new Intl.PluralRules(void 0,{type:"ordinal"}).resolvedOptions();return{locale:e.locale,type:e.type,cardinalCategories:(new Intl.PluralRules).select(0)+","+(new Intl.PluralRules).select(1)+","+(new Intl.PluralRules).select(2)+","+(new Intl.PluralRules).select(5)+","+(new Intl.PluralRules).select(11)+","+(new Intl.PluralRules).select(100),ordinalCategory1:t.type,minimumIntegerDigits:e.minimumIntegerDigits}}catch{return{}}}function R(){try{const e=new Intl.RelativeTimeFormat;if(!e)return{};const t=e.resolvedOptions();return{locale:t.locale,style:t.style,numeric:t.numeric,numberingSystem:t.numberingSystem}}catch{return{}}}function O(){try{const e=new Intl.ListFormat;if(!e)return{};const t=e.resolvedOptions(),n=["X","Y","Z"],r=new Intl.ListFormat(void 0,{type:"conjunction",style:"long"}),o=new Intl.ListFormat(void 0,{type:"disjunction",style:"long"});return{locale:t.locale,type:t.type,style:t.style,conjunctionSample:r.format(n),disjunctionSample:o.format(n)}}catch{return{}}}const k=[["backdrop-filter","blur(1px)"],["container-type","inline-size"],["text-wrap","balance"],["overscroll-behavior","contain"],["hanging-punctuation","first"],["-webkit-line-clamp","1"],["appearance","none"],["font-size-adjust","ex-height 0.5"],["font-palette","normal"],["field-sizing","content"],["-webkit-text-stroke","1px black"],["zoom","1"],["scrollbar-width","thin"],["scrollbar-color","red blue"],["animation-timeline","auto"],["mask-composite","add"],["offset-path","none"],["text-decoration-thickness","1px"],["content-visibility","auto"],["contain-intrinsic-size","auto 100px"],["aspect-ratio","16/9"],["gap","10px"],["color-mix","in srgb, red 50%, blue"],["linear-gradient(in oklch, red, blue)",""]];function D(){try{const e=document.createElement("div");e.style.cssText="visibility:hidden;overflow:scroll;position:absolute;top:-9999px;width:100px;height:100px",document.body.appendChild(e);const t=document.createElement("div");e.appendChild(t);const n=e.offsetWidth-t.offsetWidth;return document.body.removeChild(e),n}catch{return-1}}function L(){const e={};if("undefined"==typeof CSS||"function"!=typeof CSS.supports)return e;for(const[t,n]of k)e[t]=n?CSS.supports(t,n):CSS.supports(t);return e}function N(){try{const e=document.createElement("div");e.style.cssText=["position:fixed","top:0","left:0","width:0","height:0","visibility:hidden","padding-top:env(safe-area-inset-top,0px)","padding-bottom:env(safe-area-inset-bottom,0px)","padding-left:env(safe-area-inset-left,0px)","padding-right:env(safe-area-inset-right,0px)"].join(";"),document.body.appendChild(e);const t=getComputedStyle(e),n={top:t.paddingTop,bottom:t.paddingBottom,left:t.paddingLeft,right:t.paddingRight};return document.body.removeChild(e),n}catch{return null}}function F(){try{const e=performance.now();let t=1/0,n=e;for(let r=0;r<50;r++){const r=performance.now(),o=r-n;if(o>0&&o<t&&(t=o),n=r,r-e>=1)break}if(t===1/0)return-1;const r=1e3*t;if(r<=0)return-1;const o=Math.max(0,Math.round(Math.log10(r)));return Math.pow(10,o)}catch{return-1}}const B=["Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Bookman Old Style","Bradley Hand","Calibri","Cambria","Cambria Math","Century","Century Gothic","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Gill Sans","Helvetica","Helvetica Neue","Impact","Lucida Console","Lucida Grande","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3","Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Ubuntu","Merriweather","Playfair Display","Source Sans Pro","Source Code Pro","Fira Code","JetBrains Mono","Cascadia Code","Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","SF Pro","SF Pro Display","SF Mono","San Francisco","Menlo","Andale Mono","Futura","MS Gothic","MS Mincho","MS PGothic","MS PMincho","Yu Gothic","Meiryo","Hiragino Sans","Hiragino Kaku Gothic Pro","SimSun","SimHei","Microsoft YaHei","PingFang SC","Noto Sans CJK","Malgun Gothic","Arial Hebrew"],U=["monospace","sans-serif","serif"],V="mmMwWLliI0O&1";function W(e,t){const n=[],r=e.split("\r\n");let o=!1;for(const e of r)if(e.startsWith(`m=${t}`))o=!0;else{if(e.startsWith("m=")&&o)break;if(o&&e.startsWith("a=rtpmap:")){const t=e.match(/^a=rtpmap:\d+\s+(.+)$/);t&&n.push(t[1])}}return n}const X=["accelerometer","accessibility-events","ambient-light-sensor","background-fetch","background-sync","bluetooth","camera","clipboard-read","clipboard-write","display-capture","geolocation","gyroscope","local-fonts","magnetometer","microphone","midi","nfc","notifications","payment-handler","persistent-storage","push","screen-wake-lock","speaker-selection","storage-access","top-level-storage-access","window-management","xr-spatial-tracking"];function z(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;let n=e[0],r=0;for(const[e,o]of Object.entries(t))o>r&&(n=e,r=o);return n}const G=[{name:"prefers-contrast",values:["no-preference","more","less","custom"]},{name:"any-hover",values:["none","hover"]},{name:"any-pointer",values:["none","coarse","fine"]},{name:"pointer",values:["none","coarse","fine"]},{name:"hover",values:["none","hover"]},{name:"update",values:["none","slow","fast"]},{name:"inverted-colors",values:["none","inverted"]},{name:"prefers-reduced-motion",values:["no-preference","reduce"]},{name:"prefers-reduced-transparency",values:["no-preference","reduce"]},{name:"scripting",values:["none","initial-only","enabled"]},{name:"forced-colors",values:["none","active"]},{name:"prefers-color-scheme",values:["light","dark"]},{name:"color-gamut",values:["srgb","p3","rec2020"]},{name:"dynamic-range",values:["standard","high"]}],H=["KeyQ","KeyW","KeyA","KeyS","KeyZ","KeyX","KeyY","KeyM","Semicolon","BracketLeft","Quote","Digit1","Digit2","Digit3"];function j(e){const t=e.KeyQ,n=e.KeyZ,r=e.KeyY;return t?"a"===t?"azerty":"q"===t&&"z"===r?"qwertz":"q"===t&&"z"===n?"qwerty":"'"===t?"dvorak":"other":null}const K=[{name:"webgl",tier:1,async collect(){const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!(t&&t instanceof WebGLRenderingContext))return null;const n=t.getExtension("WEBGL_debug_renderer_info"),r=t.getSupportedExtensions()??[],o=function(e){const t={},n=[e.VERTEX_SHADER,e.FRAGMENT_SHADER],r=[e.LOW_FLOAT,e.MEDIUM_FLOAT,e.HIGH_FLOAT,e.LOW_INT,e.MEDIUM_INT,e.HIGH_INT],o=["vertex","fragment"],a=["lowFloat","mediumFloat","highFloat","lowInt","mediumInt","highInt"];for(let i=0;i<n.length;i++){const s={};for(let t=0;t<r.length;t++){const o=e.getShaderPrecisionFormat(n[i],r[t]);o&&(s[a[t]]={rangeMin:o.rangeMin,rangeMax:o.rangeMax,precision:o.precision})}t[o[i]]=s}return t}(t),a={vendor:t.getParameter(t.VENDOR),renderer:t.getParameter(t.RENDERER),version:t.getParameter(t.VERSION),shadingLanguageVersion:t.getParameter(t.SHADING_LANGUAGE_VERSION),unmaskedVendor:n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):null,unmaskedRenderer:n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):null,extensions:r.sort(),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE),maxViewportDims:Array.from(t.getParameter(t.MAX_VIEWPORT_DIMS)),maxVertexAttribs:t.getParameter(t.MAX_VERTEX_ATTRIBS),maxVertexUniformVectors:t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),maxFragmentUniformVectors:t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:t.getParameter(t.MAX_VARYING_VECTORS),aliasedLineWidthRange:Array.from(t.getParameter(t.ALIASED_LINE_WIDTH_RANGE)),aliasedPointSizeRange:Array.from(t.getParameter(t.ALIASED_POINT_SIZE_RANGE)),maxCombinedTextureImageUnits:t.getParameter(t.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxTextureImageUnits:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextureImageUnits:t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),shaderPrecision:o,maxAnisotropy:w(t),webgl2:b(e)};return t.getExtension("WEBGL_lose_context")?.loseContext(),a}},{name:"hardware",tier:1,collect:async()=>({architecture:E(),platform:A()})},{name:"hardwareSensitive",tier:1,collect:async()=>({deviceMemory:navigator.deviceMemory??null,hardwareConcurrency:navigator.hardwareConcurrency??null})},{name:"math",tier:1,collect:async()=>({acos:Math.acos(.5),asin:M(Math.asin,-1,1,97),cos:M(Math.cos,0,Math.PI,97),cosLarge:Math.cos(1e20),sinLarge:Math.sin(1e20),tanLarge:Math.tan(1e20),sin:M(Math.sin,0,Math.PI,97),tan:M(Math.tan,0,Math.PI/4,97)})},{name:"i18n",tier:1,collect:async()=>({dateTimeFormat:P(),numberFormat:T(),collator:_(),pluralRules:I(),relativeTimeFormat:R(),listFormat:O()})},{name:"domrect",tier:1,collect:async()=>({basic:function(){const e=document.createElement("div");e.style.cssText="position:fixed;left:-9999px;width:100px;height:100px;",document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}(),precision:function(){const e=document.createElement("div");e.style.cssText=`position:absolute;left:-9999px;width:${Math.PI}px;height:${Math.E}px;`,document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{width:t.width,height:t.height}}(),fromRect:"undefined"!=typeof DOMRectReadOnly&&"function"==typeof DOMRectReadOnly.fromRect})},{name:"touch",tier:1,collect:async()=>({supported:"ontouchstart"in window||navigator.maxTouchPoints>0,maxTouchPoints:navigator.maxTouchPoints??0})},{name:"display",tier:1,collect:async()=>({colorDepth:screen.colorDepth??0,pixelDepth:screen.pixelDepth??0})},{name:"locale",tier:1,collect:async()=>({timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"",language:navigator.language??""})},{name:"workers",tier:1,collect:async()=>({webWorker:"undefined"!=typeof Worker,sharedWorker:"undefined"!=typeof SharedWorker,serviceWorker:"serviceWorker"in navigator})},{name:"plugins",tier:1,async collect(){const e=[];if(navigator.plugins)for(let t=0;t<navigator.plugins.length;t++){const n=navigator.plugins[t];"internal-pdf-viewer"===n.filename&&e.push(`${n.name}|${n.filename}|${n.description}`)}return{plugins:e.sort(),pdfViewerEnabled:navigator.pdfViewerEnabled??!1}}},{name:"css",tier:1,collect:async()=>({scrollbarWidth:D(),supports:L(),safeArea:N()})},{name:"navigatorProps",tier:1,collect:async()=>({vendor:navigator.vendor??"",productSub:navigator.productSub??"",cookieEnabled:navigator.cookieEnabled})},{name:"timing",tier:2,collect:async()=>({performancePrecisionUs:F()})},{name:"navigatorConnection",tier:2,async collect(){const e=navigator,t=e.connection??e.mozConnection??e.webkitConnection??null,n=performance.memory??null;return{connection:t?{type:t.type??null,effectiveType:t.effectiveType??null,downlink:t.downlink??null,rtt:t.rtt??null,saveData:t.saveData??null}:null,memory:n?{jsHeapSizeLimit:n.jsHeapSizeLimit,totalJSHeapSize:n.totalJSHeapSize}:null}}},{name:"webgpu",tier:2,async collect(){const e=navigator.gpu;if(!e)return null;const t=await e.requestAdapter();if(!t)return null;let n="",r="",o="",a="";if(t.info)n=t.info.vendor??"",r=t.info.architecture??"",o=t.info.device??"",a=t.info.description??"";else if("function"==typeof t.requestAdapterInfo){const e=await t.requestAdapterInfo();n=e.vendor??"",r=e.architecture??"",o=e.device??"",a=e.description??""}const i=[];t.features&&(t.features.forEach(e=>i.push(e)),i.sort());const s={};if(t.limits){const e=["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderComponents","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension"];for(const n of e){const e=t.limits[n];void 0!==e&&(s[n]=e)}}return{vendor:n,architecture:r,device:o,description:a,features:i,limits:s}}},{name:"audio",tier:2,async collect(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return null;let t=null;try{t=new e;const n=t.destination;return{sampleRate:t.sampleRate,maxChannelCount:n.maxChannelCount,channelCount:n.channelCount,channelCountMode:n.channelCountMode,channelInterpretation:n.channelInterpretation,baseLatency:t.baseLatency??null,outputLatency:t.outputLatency??null}}finally{if(t&&"closed"!==t.state)try{await t.close()}catch{}}}},{name:"fonts",tier:2,collect:()=>new Promise(e=>{const t=()=>e(function(){try{if("undefined"==typeof document)return{available:[],method:"css-layout"};const e=new Set,t=[];if("function"==typeof document.fonts?.check)for(const n of B)document.fonts.check(`72px "${n}"`)?e.add(n):t.push(n);else t.push(...B);const n=new Set;if(t.length>0){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px;left:-9999px;pointer-events:none;";const r=U.map(t=>{const n=document.createElement("span");return n.style.cssText=`font-size:72px;font-family:${t};white-space:nowrap;display:inline-block`,n.textContent=V,e.appendChild(n),n}),o=t.map(t=>U.map(n=>{const r=document.createElement("span");return r.style.cssText=`font-size:72px;font-family:'${t}',${n};white-space:nowrap;display:inline-block`,r.textContent=V,e.appendChild(r),r}));document.body.appendChild(e);const a=r.map(e=>e.getBoundingClientRect().width),i=o.map(e=>e.map(e=>e.getBoundingClientRect().width));document.body.removeChild(e);for(let e=0;e<t.length;e++)for(let r=0;r<U.length;r++)if(i[e][r]!==a[r]){n.add(t[e]);break}}return{available:B.filter(t=>e.has(t)||n.has(t)),method:"css-layout"}}catch{return{available:[],method:"css-layout"}}}());"undefined"!=typeof requestIdleCallback?requestIdleCallback(t,{timeout:2e3}):setTimeout(t,0)})},{name:"webrtc",tier:2,async collect(){if("undefined"==typeof RTCPeerConnection)return{supported:!1,audioCodecCount:0,videoCodecCount:0,audioCodecs:[],videoCodecs:[],extensions:[]};const e=new RTCPeerConnection({iceServers:[]});try{e.addTransceiver("audio"),e.addTransceiver("video");const t=(await e.createOffer()).sdp??"",n=W(t,"audio"),r=W(t,"video"),o=function(e){const t=new Set,n=e.split("\r\n");for(const e of n)if(e.startsWith("a=extmap:")){const n=e.match(/^a=extmap:\d+(?:\/\w+)?\s+(.+)$/);n&&t.add(n[1].trim())}return Array.from(t)}(t);return{supported:!0,audioCodecCount:n.length,videoCodecCount:r.length,audioCodecs:n.sort(),videoCodecs:r.sort(),extensions:o.sort()}}finally{e.close()}}},{name:"permissions",tier:2,async collect(){if(!navigator.permissions?.query)return{states:{}};const e=()=>Promise.allSettled(X.map(async e=>{try{return{name:e,state:(await navigator.permissions.query({name:e})).state}}catch{return{name:e,state:"error"}}})),t=await Promise.all([e(),e(),e()]),n={};for(const e of t)for(const t of e)if("fulfilled"===t.status){const{name:e,state:r}=t.value;n[e]||(n[e]=[]),n[e].push(r)}const r={};for(const[e,t]of Object.entries(n))r[e]=z(t);return{states:r}}},{name:"speech",tier:2,async collect(){if("undefined"==typeof speechSynthesis)return{supported:!1,voiceCount:0,voices:[]};const e=await new Promise(e=>{const t=speechSynthesis.getVoices();if(t.length>0)return void e(t);const n=setTimeout(()=>e([]),800);speechSynthesis.addEventListener("voiceschanged",()=>{clearTimeout(n),e(speechSynthesis.getVoices())},{once:!0})}),t=e.map(e=>`${e.name}|${e.lang}|${e.localService}`).sort();return{supported:!0,voiceCount:e.length,voices:t}}},{name:"mediaQueries",tier:2,async collect(){if("function"!=typeof matchMedia){const e={};for(const t of G)e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]="unsupported";return{...e,monochrome:0}}const e={};for(const t of G){let n="unknown";for(const e of t.values){const r=matchMedia(`(${t.name}: ${e})`);if(r?.matches){n=e;break}}e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]=n}let t=0;for(let e=100;e>=0;e--)if(matchMedia(`(monochrome: ${e})`)?.matches){t=e;break}return{...e,monochrome:t}}},{name:"applePay",tier:2,async collect(){const e=window.ApplePaySession;if(!e||"function"!=typeof e.supportsVersion)return{supported:!1,maxVersion:0};let t=0;for(let n=15;n>=1;n--)try{if(e.supportsVersion(n)){t=n;break}}catch{continue}return{supported:!0,maxVersion:t}}},{name:"keyboard",tier:2,async collect(){const e=navigator.keyboard;if(!e||"function"!=typeof e.getLayoutMap)return{supported:!1,layoutKeys:null,layoutHint:null};try{const t=await e.getLayoutMap(),n={};for(const e of H){const r=t.get(e);void 0!==r&&(n[e]=r)}return{supported:!0,layoutKeys:n,layoutHint:j(n)}}catch{return{supported:!1,layoutKeys:null,layoutHint:null}}}}];async function $(e,t,n){const r={},o=[],a=K.filter(t=>!e.has(t.name)&&(n||3!==t.tier)),i=await Promise.allSettled(a.map(async e=>{const n=await(r=e.collect(),o=t,new Promise((e,t)=>{const n=setTimeout(()=>e(null),o);r.then(t=>{clearTimeout(n),e(t)},e=>{clearTimeout(n),t(e)})}));var r,o;return{name:e.name,value:n}}));for(let e=0;e<i.length;e++){const t=i[e],n=a[e].name;"fulfilled"===t.status&&null!==t.value.value?r[n]=t.value.value:"rejected"===t.status&&o.push({signal:n,error:String(t.reason?.message??t.reason)})}return{components:r,errors:o}}async function q(t){const a={...n},s=i(),u=function(){try{return window.self!==window.top}catch{return!0}}();let l=!1;try{l=await c(s.name)}catch{}const f=function(e,t,n,r){const a=new Set;for(const i of e){if("private"===i&&!n)continue;if("iframe"===i&&!r)continue;const e=o[i];if(e)for(const n of e)if(!n.browsers||n.browsers.includes(t))for(const e of n.exclude)a.add(e)}return a}(a.stabilize,s.name,l,u),m=new Set(f);for(const e of a.exclude)m.add(e);for(const e of a.include)m.delete(e);const{components:d,errors:p}=await $(m,a.timeout,a.experimental),y=C({...d,t:e},a.salt),h={t:e};for(const[e,t]of Object.entries(d))r.has(e)||(h[e]=t);const g=C(h,a.salt),v={hash:y,stableHash:g,components:{...d,t:e},timestamp:(new Date).toISOString(),version:e,isIncognito:l,errors:p};return a.debug&&(console.log("[fingerprint] components:",d),console.log("[fingerprint] hash:",y,"stableHash:",g),p.length>0&&console.warn("[fingerprint] errors:",p)),v}const DEFAULT_MAX_RETRIES=3,DEFAULT_TIMEOUT_MS=3e4,MAX_DELAY_MS=3e4,BASE_DELAY_MS=1e3,FINGERPRINT_PATH="/unshared/submit-fingerprint-event";function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function sleep(e){return new Promise(t=>setTimeout(t,e))}function retryDelay(e){const t=Math.min(1e3*Math.pow(2,e-1),3e4),n=500*Math.random()-250;return Math.max(0,t+n)}class UnsharedLabsBrowser{constructor(e){if(!e.baseUrl||!isValidUrl(e.baseUrl))throw new Error("baseUrl is required and must be a valid URL");this.o=e.baseUrl.replace(/\/$/,""),this.i=e.maxRetries??3,this.u=e.timeout??3e4,this.l=generateUUID()}async collect(){const e=await q();return{fingerprint_id:e.stableHash,full_hash:e.hash,components:e.components,timestamp:e.timestamp,isIncognito:e.isIncognito,version:e.version}}async submitFingerprintEvent(e,t){try{const n=this.m(e,t),r=generateUUID(),o=`${this.o}${FINGERPRINT_PATH}`,a=JSON.stringify(n);return await this.p(o,a,r)}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}async p(e,t,n){const r=this.i+1;let o={success:!1,error:{code:"DELIVERY_FAILED",message:"Request failed"}};for(let a=1;a<=r;a++){a>1&&await sleep(retryDelay(a-1));const r=new AbortController,i=setTimeout(()=>r.abort(),this.u);try{const a=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Idempotency-Key":n,"X-Session-Id":this.l},body:t,signal:r.signal});if(clearTimeout(i),a.status>=500){o={success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${a.status}`}};continue}if(a.status>=400)return{success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${a.status}`}};const s=await a.text().catch(()=>"{}");let c;try{c=JSON.parse(s)}catch{c={}}return!1===c?.success?{success:!1,error:c.error??{code:"UPSTREAM_ERROR",message:"Upstream failed"}}:{success:!0,data:c?.data}}catch(e){clearTimeout(i),o={success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}return o}m(e,t){const n={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:e.timestamp,is_incognito:e.isIncognito,components:e.components,version:e.version};return null!=t?.userId&&(n.user_id=t.userId),null!=t?.eventType&&(n.event_type=t.eventType),n}}function isValidUrl(e){try{return new URL(e),!0}catch{return!1}}export{UnsharedLabsBrowser};
1
+ const e="1.3.1",t=1282368115,n={exclude:[],include:[],timeout:3e3,stabilize:["private","iframe","always"],experimental:!1,debug:!1,salt:""},r=new Set(["audio","timing","navigatorConnection","domrect","permissions","fonts","speech"]),o=new Set(["domrect"]),a={always:[{exclude:["speech"],browsers:["brave","firefox"]},{exclude:["keyboard"],browsers:["firefox","safari"]},{exclude:["workers"],browsers:["firefox"]},{exclude:["hardwareSensitive","navigatorProps"],browsers:["brave"]}],private:[{exclude:["fonts"],browsers:["firefox"]},{exclude:["audio"],browsers:["safari","brave"]}],iframe:[{exclude:["applePay"],browsers:["safari"]},{exclude:["permissions"]},{exclude:["keyboard"]}]};let i=null;function s(){if(i)return i;const e=navigator.userAgent;return i=function(){const e=navigator.brave;return!!e&&"function"==typeof e.isBrave}()?{name:"brave",version:c(e,/Chrome\/([\d.]+)/)}:/Edg\//i.test(e)?{name:"edge",version:c(e,/Edg\/([\d.]+)/)}:/OPR\//i.test(e)||/Opera/i.test(e)?{name:"opera",version:c(e,/OPR\/([\d.]+)/)||c(e,/Opera\/([\d.]+)/)}:/SamsungBrowser/i.test(e)?{name:"samsung",version:c(e,/SamsungBrowser\/([\d.]+)/)}:/Firefox\//i.test(e)?{name:"firefox",version:c(e,/Firefox\/([\d.]+)/)}:/Safari\//i.test(e)&&!/Chrome/i.test(e)?{name:"safari",version:c(e,/Version\/([\d.]+)/)}:/Chrome\//i.test(e)?{name:"chrome",version:c(e,/Chrome\/([\d.]+)/)}:{name:"unknown",version:""},i}function c(e,t){const n=e.match(t);return n?.[1]??""}async function l(e){try{switch(e){case"chrome":case"edge":case"opera":default:return await u();case"brave":return await async function(){return!1}();case"safari":return await async function(){if(navigator.storage?.estimate){const{quota:e}=await navigator.storage.estimate();if(void 0!==e)return e<4294967296}try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"NotFoundError"===e?.name}}();case"firefox":return await async function(){if(!("serviceWorker"in navigator))return!0;try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"SecurityError"===e?.name}}()}}catch{return!1}}async function u(){if(!navigator.storage?.estimate)return!1;const{quota:e}=await navigator.storage.estimate();return void 0!==e&&e<4294967296}function m(e,t){const n=e[0]>>>16,o=65535&e[0],r=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16;let u=0,l=0,d=0,f=0,m=0;return l=i+(65535&t[1]),u=l>>>16,l&=65535,d=r+c+u,u=d>>>16,d&=65535,f=o+s+u,u=f>>>16,f&=65535,m=n+a+u,m&=65535,[m<<16|f,d<<16|l]}function d(e,t){const n=e[0]>>>16,o=65535&e[0],r=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16,u=65535&t[1];let l=0,d=0,f=0,m=0,p=0;return d=i*u,l=d>>>16,d&=65535,f=r*u+l,l=f>>>16,f&=65535,f+=i*c,l+=f>>>16,f&=65535,m=o*u+l,l=m>>>16,m&=65535,m+=r*c,l+=m>>>16,m&=65535,m+=i*s,l+=m>>>16,m&=65535,p=n*u+o*c+r*s+i*a+l,p&=65535,[p<<16|m,f<<16|d]}function f(e,t){return 32==(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])}function p(e,t){return 0==(t%=64)?[e[0],e[1]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]}function g(e,t){return[e[0]^t[0],e[1]^t[1]]}function h(e){let t=[e[0],e[1]];return t=g(t,[0,t[0]>>>1]),t=d(t,[4283543511,3981806797]),t=g(t,[0,t[0]>>>1]),t=d(t,[3301882366,444984403]),t=g(t,[0,t[0]>>>1]),t}function y(e){return("00000000"+(e>>>0).toString(16)).slice(-8)}function v(e,t=0){const n=e.length%16,o=e.length-n;let r=[0,t],i=[0,t];const a=[2277735313,289559509],s=[1291169091,658871167];for(let t=0;t<o;t+=16){let n=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],o=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24];n=d(n,a),n=f(n,31),n=d(n,s),r=g(r,n),r=f(r,27),r=m(r,i),r=m(d(r,[0,5]),[0,1390208809]),o=d(o,s),o=f(o,33),o=d(o,a),i=g(i,o),i=f(i,31),i=m(i,r),i=m(d(i,[0,5]),[0,944331445])}let c=[0,0],u=[0,0];switch(n){case 15:u=g(u,p([0,e.charCodeAt(o+14)],48));case 14:u=g(u,p([0,e.charCodeAt(o+13)],40));case 13:u=g(u,p([0,e.charCodeAt(o+12)],32));case 12:u=g(u,p([0,e.charCodeAt(o+11)],24));case 11:u=g(u,p([0,e.charCodeAt(o+10)],16));case 10:u=g(u,p([0,e.charCodeAt(o+9)],8));case 9:u=g(u,[0,e.charCodeAt(o+8)]),u=d(u,s),u=f(u,33),u=d(u,a),i=g(i,u);case 8:c=g(c,p([0,e.charCodeAt(o+7)],56));case 7:c=g(c,p([0,e.charCodeAt(o+6)],48));case 6:c=g(c,p([0,e.charCodeAt(o+5)],40));case 5:c=g(c,p([0,e.charCodeAt(o+4)],32));case 4:c=g(c,p([0,e.charCodeAt(o+3)],24));case 3:c=g(c,p([0,e.charCodeAt(o+2)],16));case 2:c=g(c,p([0,e.charCodeAt(o+1)],8));case 1:c=g(c,[0,e.charCodeAt(o)]),c=d(c,a),c=f(c,31),c=d(c,s),r=g(r,c)}return r=g(r,[0,e.length]),i=g(i,[0,e.length]),r=m(r,i),i=m(i,r),r=h(r),i=h(i),r=m(r,i),i=m(i,r),y(r[0])+y(r[1])+y(i[0])+y(i[1])}function x(e){return S(e,new Set)}function S(e,t){if(null===e)return"null";if(void 0===e)return"undefined";const n=typeof e;if("boolean"===n||"number"===n)return String(e);if("string"===n)return JSON.stringify(e);if(Array.isArray(e)){if(t.has(e))return'"[Circular]"';t.add(e);const n=e.map(e=>S(e,t));return t.delete(e),"["+n.join(",")+"]"}if("object"===n){const n=e;if(t.has(n))return'"[Circular]"';t.add(n);const o=Object.keys(n).sort().filter(e=>void 0!==n[e]).map(e=>JSON.stringify(e)+":"+S(n[e],t));return t.delete(n),"{"+o.join(",")+"}"}return String(e)}const b=v("",t);function w(e,n){const o=function(e){if(0===e.length)return v("",t);if(1===e.length)return v(e[0],t);let n=[...e];for(;n.length>1;){const e=[];for(let o=0;o<n.length;o+=2){const r=o+1<n.length?n[o+1]:b;e.push(v(n[o]+r,t))}n=e}return n[0]}(Object.keys(e).sort().map(n=>{const o=function(e){let n=t;for(let t=0;t<e.length;t++)n=Math.imul(n^e.charCodeAt(t),1540483477),n^=n>>>13;return n>>>0}(n);return v(x(e[n]),o)})),r=String.fromCharCode(76,111,98,115),i=n?v(n,t):"";return v(o+r+i,t)}function C(e){try{const t=e.getExtension("EXT_texture_filter_anisotropic")??e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")??e.getExtension("MOZ_EXT_texture_filter_anisotropic");return t?e.getParameter(t.MAX_TEXTURE_MAX_ANISOTROPY_EXT):null}catch{return null}}function A(e){try{const t=e.getContext("webgl2");if(!t)return null;const n={version:t.getParameter(t.VERSION),maxSamples:t.getParameter(t.MAX_SAMPLES),max3DTextureSize:t.getParameter(t.MAX_3D_TEXTURE_SIZE),maxArrayTextureLayers:t.getParameter(t.MAX_ARRAY_TEXTURE_LAYERS),maxUniformBlockSize:t.getParameter(t.MAX_UNIFORM_BLOCK_SIZE),maxVertexUniformComponents:t.getParameter(t.MAX_VERTEX_UNIFORM_COMPONENTS),maxFragmentUniformComponents:t.getParameter(t.MAX_FRAGMENT_UNIFORM_COMPONENTS),maxColorAttachments:t.getParameter(t.MAX_COLOR_ATTACHMENTS),maxDrawBuffers:t.getParameter(t.MAX_DRAW_BUFFERS)};return t.getExtension("WEBGL_lose_context")?.loseContext(),n}catch{return null}}function E(){const e=navigator.userAgentData;if(e?.platform)return e.platform;const t=navigator.userAgent??"";return/Windows/.test(t)?"Windows":/Macintosh|Mac OS X/.test(t)?"macOS":/CrOS/.test(t)?"Chrome OS":/Android/.test(t)?"Android":/Linux/.test(t)?"Linux":/iPhone|iPad|iPod/.test(t)?"iOS":""}function M(){try{const e=new ArrayBuffer(4),t=new Float32Array(e),n=new Uint8Array(e);return t[0]=1/0,n[3]}catch{return 0}}function P(e,t,n,o){const r=(n-t)/o;let i=e(t)+e(n);for(let n=1;n<o;n++)i+=e(t+n*r)*(n%2==0?2:4);return i*r/3}function T(){try{const e=(new Intl.DateTimeFormat).resolvedOptions();return{locale:e.locale,calendar:e.calendar,numberingSystem:e.numberingSystem,timeZone:e.timeZone}}catch{return{}}}function _(){try{const e=(new Intl.NumberFormat).resolvedOptions();return{locale:e.locale,numberingSystem:e.numberingSystem,style:e.style,minimumIntegerDigits:e.minimumIntegerDigits,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,useGrouping:e.useGrouping}}catch{return{}}}function R(){try{const e=(new Intl.Collator).resolvedOptions();return{locale:e.locale,usage:e.usage,sensitivity:e.sensitivity,collation:e.collation,numeric:e.numeric,caseFirst:e.caseFirst}}catch{return{}}}function I(){try{const e=(new Intl.PluralRules).resolvedOptions(),t=new Intl.PluralRules(void 0,{type:"ordinal"}).resolvedOptions();return{locale:e.locale,type:e.type,cardinalCategories:(new Intl.PluralRules).select(0)+","+(new Intl.PluralRules).select(1)+","+(new Intl.PluralRules).select(2)+","+(new Intl.PluralRules).select(5)+","+(new Intl.PluralRules).select(11)+","+(new Intl.PluralRules).select(100),ordinalCategory1:t.type,minimumIntegerDigits:e.minimumIntegerDigits}}catch{return{}}}function k(){try{const e=new Intl.RelativeTimeFormat;if(!e)return{};const t=e.resolvedOptions();return{locale:t.locale,style:t.style,numeric:t.numeric,numberingSystem:t.numberingSystem}}catch{return{}}}function O(){try{const e=new Intl.ListFormat;if(!e)return{};const t=e.resolvedOptions(),n=["X","Y","Z"],o=new Intl.ListFormat(void 0,{type:"conjunction",style:"long"}),r=new Intl.ListFormat(void 0,{type:"disjunction",style:"long"});return{locale:t.locale,type:t.type,style:t.style,conjunctionSample:o.format(n),disjunctionSample:r.format(n)}}catch{return{}}}const D=[["backdrop-filter","blur(1px)"],["container-type","inline-size"],["text-wrap","balance"],["overscroll-behavior","contain"],["hanging-punctuation","first"],["-webkit-line-clamp","1"],["appearance","none"],["font-size-adjust","ex-height 0.5"],["font-palette","normal"],["field-sizing","content"],["-webkit-text-stroke","1px black"],["zoom","1"],["scrollbar-width","thin"],["scrollbar-color","red blue"],["animation-timeline","auto"],["mask-composite","add"],["offset-path","none"],["text-decoration-thickness","1px"],["content-visibility","auto"],["contain-intrinsic-size","auto 100px"],["aspect-ratio","16/9"],["gap","10px"],["color-mix","in srgb, red 50%, blue"],["linear-gradient(in oklch, red, blue)",""]];function L(){try{const e=document.createElement("div");e.style.cssText="visibility:hidden;overflow:scroll;position:absolute;top:-9999px;width:100px;height:100px",document.body.appendChild(e);const t=document.createElement("div");e.appendChild(t);const n=e.offsetWidth-t.offsetWidth;return document.body.removeChild(e),n}catch{return-1}}function N(){const e={};if("undefined"==typeof CSS||"function"!=typeof CSS.supports)return e;for(const[t,n]of D)e[t]=n?CSS.supports(t,n):CSS.supports(t);return e}function F(){try{const e=document.createElement("div");e.style.cssText=["position:fixed","top:0","left:0","width:0","height:0","visibility:hidden","padding-top:env(safe-area-inset-top,0px)","padding-bottom:env(safe-area-inset-bottom,0px)","padding-left:env(safe-area-inset-left,0px)","padding-right:env(safe-area-inset-right,0px)"].join(";"),document.body.appendChild(e);const t=getComputedStyle(e),n={top:t.paddingTop,bottom:t.paddingBottom,left:t.paddingLeft,right:t.paddingRight};return document.body.removeChild(e),n}catch{return null}}function B(){try{const e=performance.now();let t=1/0,n=e;for(let o=0;o<50;o++){const o=performance.now(),r=o-n;if(r>0&&r<t&&(t=r),n=o,o-e>=1)break}if(t===1/0)return-1;const o=1e3*t;if(o<=0)return-1;const r=Math.max(0,Math.round(Math.log10(o)));return Math.pow(10,r)}catch{return-1}}const U=["Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Bookman Old Style","Bradley Hand","Calibri","Cambria","Cambria Math","Century","Century Gothic","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Gill Sans","Helvetica","Helvetica Neue","Impact","Lucida Console","Lucida Grande","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3","Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Ubuntu","Merriweather","Playfair Display","Source Sans Pro","Source Code Pro","Fira Code","JetBrains Mono","Cascadia Code","Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","SF Pro","SF Pro Display","SF Mono","San Francisco","Menlo","Andale Mono","Futura","MS Gothic","MS Mincho","MS PGothic","MS PMincho","Yu Gothic","Meiryo","Hiragino Sans","Hiragino Kaku Gothic Pro","SimSun","SimHei","Microsoft YaHei","PingFang SC","Noto Sans CJK","Malgun Gothic","Arial Hebrew"],V=["monospace","sans-serif","serif"],W="mmMwWLliI0O&1";function X(e,t){const n=[],o=e.split("\r\n");let r=!1;for(const e of o)if(e.startsWith(`m=${t}`))r=!0;else{if(e.startsWith("m=")&&r)break;if(r&&e.startsWith("a=rtpmap:")){const t=e.match(/^a=rtpmap:\d+\s+(.+)$/);t&&n.push(t[1])}}return n}const z=["accelerometer","accessibility-events","ambient-light-sensor","background-fetch","background-sync","bluetooth","camera","clipboard-read","clipboard-write","display-capture","geolocation","gyroscope","local-fonts","magnetometer","microphone","midi","nfc","notifications","payment-handler","persistent-storage","push","screen-wake-lock","speaker-selection","storage-access","top-level-storage-access","window-management","xr-spatial-tracking"];function G(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;let n=e[0],o=0;for(const[e,r]of Object.entries(t))r>o&&(n=e,o=r);return n}const j=[{name:"prefers-contrast",values:["no-preference","more","less","custom"]},{name:"any-hover",values:["none","hover"]},{name:"any-pointer",values:["none","coarse","fine"]},{name:"pointer",values:["none","coarse","fine"]},{name:"hover",values:["none","hover"]},{name:"update",values:["none","slow","fast"]},{name:"inverted-colors",values:["none","inverted"]},{name:"prefers-reduced-motion",values:["no-preference","reduce"]},{name:"prefers-reduced-transparency",values:["no-preference","reduce"]},{name:"scripting",values:["none","initial-only","enabled"]},{name:"forced-colors",values:["none","active"]},{name:"prefers-color-scheme",values:["light","dark"]},{name:"color-gamut",values:["srgb","p3","rec2020"]},{name:"dynamic-range",values:["standard","high"]}],H=["KeyQ","KeyW","KeyA","KeyS","KeyZ","KeyX","KeyY","KeyM","Semicolon","BracketLeft","Quote","Digit1","Digit2","Digit3"];function K(e){const t=e.KeyQ,n=e.KeyZ,o=e.KeyY;return t?"a"===t?"azerty":"q"===t&&"z"===o?"qwertz":"q"===t&&"z"===n?"qwerty":"'"===t?"dvorak":"other":null}const $=[{name:"webgl",tier:1,async collect(){const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!(t&&t instanceof WebGLRenderingContext))return null;const n=t.getExtension("WEBGL_debug_renderer_info"),o=t.getSupportedExtensions()??[],r=function(e){const t={},n=[e.VERTEX_SHADER,e.FRAGMENT_SHADER],o=[e.LOW_FLOAT,e.MEDIUM_FLOAT,e.HIGH_FLOAT,e.LOW_INT,e.MEDIUM_INT,e.HIGH_INT],r=["vertex","fragment"],i=["lowFloat","mediumFloat","highFloat","lowInt","mediumInt","highInt"];for(let a=0;a<n.length;a++){const s={};for(let t=0;t<o.length;t++){const r=e.getShaderPrecisionFormat(n[a],o[t]);r&&(s[i[t]]={rangeMin:r.rangeMin,rangeMax:r.rangeMax,precision:r.precision})}t[r[a]]=s}return t}(t),i={vendor:t.getParameter(t.VENDOR),renderer:t.getParameter(t.RENDERER),version:t.getParameter(t.VERSION),shadingLanguageVersion:t.getParameter(t.SHADING_LANGUAGE_VERSION),unmaskedVendor:n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):null,unmaskedRenderer:n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):null,extensions:o.sort(),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE),maxViewportDims:Array.from(t.getParameter(t.MAX_VIEWPORT_DIMS)),maxVertexAttribs:t.getParameter(t.MAX_VERTEX_ATTRIBS),maxVertexUniformVectors:t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),maxFragmentUniformVectors:t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:t.getParameter(t.MAX_VARYING_VECTORS),aliasedLineWidthRange:Array.from(t.getParameter(t.ALIASED_LINE_WIDTH_RANGE)),aliasedPointSizeRange:Array.from(t.getParameter(t.ALIASED_POINT_SIZE_RANGE)),maxCombinedTextureImageUnits:t.getParameter(t.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxTextureImageUnits:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextureImageUnits:t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),shaderPrecision:r,maxAnisotropy:C(t),webgl2:A(e)};return t.getExtension("WEBGL_lose_context")?.loseContext(),i}},{name:"hardware",tier:1,collect:async()=>({architecture:M(),platform:E()})},{name:"hardwareSensitive",tier:1,collect:async()=>({deviceMemory:navigator.deviceMemory??null,hardwareConcurrency:navigator.hardwareConcurrency??null})},{name:"math",tier:1,collect:async()=>({acos:Math.acos(.5),asin:P(Math.asin,-1,1,97),cos:P(Math.cos,0,Math.PI,97),cosLarge:Math.cos(1e20),sinLarge:Math.sin(1e20),tanLarge:Math.tan(1e20),sin:P(Math.sin,0,Math.PI,97),tan:P(Math.tan,0,Math.PI/4,97)})},{name:"i18n",tier:1,collect:async()=>({dateTimeFormat:T(),numberFormat:_(),collator:R(),pluralRules:I(),relativeTimeFormat:k(),listFormat:O()})},{name:"domrect",tier:1,collect:async()=>({basic:function(){const e=document.createElement("div");e.style.cssText="position:fixed;left:-9999px;width:100px;height:100px;",document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}(),precision:function(){const e=document.createElement("div");e.style.cssText=`position:absolute;left:-9999px;width:${Math.PI}px;height:${Math.E}px;`,document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{width:t.width,height:t.height}}(),fromRect:"undefined"!=typeof DOMRectReadOnly&&"function"==typeof DOMRectReadOnly.fromRect})},{name:"touch",tier:1,collect:async()=>({supported:"ontouchstart"in window||navigator.maxTouchPoints>0,maxTouchPoints:navigator.maxTouchPoints??0})},{name:"display",tier:1,collect:async()=>({colorDepth:screen.colorDepth??0,pixelDepth:screen.pixelDepth??0})},{name:"locale",tier:1,collect:async()=>({timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"",language:navigator.language??""})},{name:"workers",tier:1,collect:async()=>({webWorker:"undefined"!=typeof Worker,sharedWorker:"undefined"!=typeof SharedWorker,serviceWorker:"serviceWorker"in navigator})},{name:"plugins",tier:1,async collect(){const e=[];if(navigator.plugins)for(let t=0;t<navigator.plugins.length;t++){const n=navigator.plugins[t];"internal-pdf-viewer"===n.filename&&e.push(`${n.name}|${n.filename}|${n.description}`)}return{plugins:e.sort(),pdfViewerEnabled:navigator.pdfViewerEnabled??!1}}},{name:"css",tier:1,collect:async()=>({scrollbarWidth:L(),supports:N(),safeArea:F()})},{name:"navigatorProps",tier:1,collect:async()=>({vendor:navigator.vendor??"",productSub:navigator.productSub??"",cookieEnabled:navigator.cookieEnabled})},{name:"timing",tier:2,collect:async()=>({performancePrecisionUs:B()})},{name:"navigatorConnection",tier:2,async collect(){const e=navigator,t=e.connection??e.mozConnection??e.webkitConnection??null,n=performance.memory??null;return{connection:t?{type:t.type??null,effectiveType:t.effectiveType??null,saveData:t.saveData??null}:null,memory:n?{jsHeapSizeLimit:n.jsHeapSizeLimit}:null}}},{name:"webgpu",tier:2,async collect(){const e=navigator.gpu;if(!e)return null;const t=await e.requestAdapter();if(!t)return null;let n="",o="",r="",i="";if(t.info)n=t.info.vendor??"",o=t.info.architecture??"",r=t.info.device??"",i=t.info.description??"";else if("function"==typeof t.requestAdapterInfo){const e=await t.requestAdapterInfo();n=e.vendor??"",o=e.architecture??"",r=e.device??"",i=e.description??""}const a=[];t.features&&(t.features.forEach(e=>a.push(e)),a.sort());const s={};if(t.limits){const e=["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderComponents","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension"];for(const n of e){const e=t.limits[n];void 0!==e&&(s[n]=e)}}return{vendor:n,architecture:o,device:r,description:i,features:a,limits:s}}},{name:"audio",tier:2,async collect(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return null;let t=null;try{t=new e;const n=t.destination;return{sampleRate:t.sampleRate,maxChannelCount:n.maxChannelCount,channelCount:n.channelCount,channelCountMode:n.channelCountMode,channelInterpretation:n.channelInterpretation,baseLatency:t.baseLatency??null,outputLatency:t.outputLatency??null}}finally{if(t&&"closed"!==t.state)try{await t.close()}catch{}}}},{name:"fonts",tier:2,collect:()=>new Promise(e=>{const t=()=>e(function(){try{if("undefined"==typeof document)return{available:[],method:"css-layout"};const e=new Set,t=[];if("function"==typeof document.fonts?.check)for(const n of U)document.fonts.check(`72px "${n}"`)?e.add(n):t.push(n);else t.push(...U);const n=new Set;if(t.length>0){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px;left:-9999px;pointer-events:none;";const o=V.map(t=>{const n=document.createElement("span");return n.style.cssText=`font-size:72px;font-family:${t};white-space:nowrap;display:inline-block`,n.textContent=W,e.appendChild(n),n}),r=t.map(t=>V.map(n=>{const o=document.createElement("span");return o.style.cssText=`font-size:72px;font-family:'${t}',${n};white-space:nowrap;display:inline-block`,o.textContent=W,e.appendChild(o),o}));document.body.appendChild(e);const i=o.map(e=>e.getBoundingClientRect().width),a=r.map(e=>e.map(e=>e.getBoundingClientRect().width));document.body.removeChild(e);for(let e=0;e<t.length;e++)for(let o=0;o<V.length;o++)if(a[e][o]!==i[o]){n.add(t[e]);break}}return{available:U.filter(t=>e.has(t)||n.has(t)),method:"css-layout"}}catch{return{available:[],method:"css-layout"}}}());"undefined"!=typeof requestIdleCallback?requestIdleCallback(t,{timeout:2e3}):setTimeout(t,0)})},{name:"webrtc",tier:2,async collect(){if("undefined"==typeof RTCPeerConnection)return{supported:!1,audioCodecCount:0,videoCodecCount:0,audioCodecs:[],videoCodecs:[],extensions:[]};const e=new RTCPeerConnection({iceServers:[]});try{e.addTransceiver("audio"),e.addTransceiver("video");const t=(await e.createOffer()).sdp??"",n=X(t,"audio"),o=X(t,"video"),r=function(e){const t=new Set,n=e.split("\r\n");for(const e of n)if(e.startsWith("a=extmap:")){const n=e.match(/^a=extmap:\d+(?:\/\w+)?\s+(.+)$/);n&&t.add(n[1].trim())}return Array.from(t)}(t);return{supported:!0,audioCodecCount:n.length,videoCodecCount:o.length,audioCodecs:n.sort(),videoCodecs:o.sort(),extensions:r.sort()}}finally{e.close()}}},{name:"permissions",tier:2,async collect(){if(!navigator.permissions?.query)return{states:{}};const e=()=>Promise.allSettled(z.map(async e=>{try{return{name:e,state:(await navigator.permissions.query({name:e})).state}}catch{return{name:e,state:"error"}}})),t=await Promise.all([e(),e(),e()]),n={};for(const e of t)for(const t of e)if("fulfilled"===t.status){const{name:e,state:o}=t.value;n[e]||(n[e]=[]),n[e].push(o)}const o={};for(const[e,t]of Object.entries(n))o[e]=G(t);return{states:o}}},{name:"speech",tier:2,async collect(){if("undefined"==typeof speechSynthesis)return{supported:!1,voiceCount:0,voices:[]};const e=await new Promise(e=>{const t=speechSynthesis.getVoices();if(t.length>0)return void e(t);const n=setTimeout(()=>e([]),800);speechSynthesis.addEventListener("voiceschanged",()=>{clearTimeout(n),e(speechSynthesis.getVoices())},{once:!0})}),t=e.map(e=>`${e.name}|${e.lang}|${e.localService}`).sort();return{supported:!0,voiceCount:e.length,voices:t}}},{name:"mediaQueries",tier:2,async collect(){if("function"!=typeof matchMedia){const e={};for(const t of j)e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]="unsupported";return{...e,monochrome:0}}const e={};for(const t of j){let n="unknown";for(const e of t.values){const o=matchMedia(`(${t.name}: ${e})`);if(o?.matches){n=e;break}}e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]=n}let t=0;for(let e=100;e>=0;e--)if(matchMedia(`(monochrome: ${e})`)?.matches){t=e;break}return{...e,monochrome:t}}},{name:"applePay",tier:2,async collect(){const e=window.ApplePaySession;if(!e||"function"!=typeof e.supportsVersion)return{supported:!1,maxVersion:0};let t=0;for(let n=15;n>=1;n--)try{if(e.supportsVersion(n)){t=n;break}}catch{continue}return{supported:!0,maxVersion:t}}},{name:"keyboard",tier:2,async collect(){const e=navigator.keyboard;if(!e||"function"!=typeof e.getLayoutMap)return{supported:!1,layoutKeys:null,layoutHint:null};try{const t=await e.getLayoutMap(),n={};for(const e of H){const o=t.get(e);void 0!==o&&(n[e]=o)}return{supported:!0,layoutKeys:n,layoutHint:K(n)}}catch{return{supported:!1,layoutKeys:null,layoutHint:null}}}}];async function q(e,t,n){const o={},r=[],i=$.filter(t=>!e.has(t.name)&&(n||3!==t.tier)),a=await Promise.allSettled(i.map(async e=>{const n=await(o=e.collect(),r=t,new Promise((e,t)=>{const n=setTimeout(()=>e(null),r);o.then(t=>{clearTimeout(n),e(t)},e=>{clearTimeout(n),t(e)})}));var o,r;return{name:e.name,value:n}}));for(let e=0;e<a.length;e++){const t=a[e],n=i[e].name;"fulfilled"===t.status&&null!==t.value.value?o[n]=t.value.value:"rejected"===t.status&&r.push({signal:n,error:String(t.reason?.message??t.reason)})}return{components:o,errors:r}}async function Z(t){const i=function(e){return e?{exclude:e.exclude??n.exclude,include:e.include??n.include,timeout:e.timeout??n.timeout,stabilize:e.stabilize??n.stabilize,experimental:e.experimental??n.experimental,debug:e.debug??n.debug,salt:e.salt??n.salt}:{...n}}(t),c=s(),u=function(){try{return window.self!==window.top}catch{return!0}}();let d=!1;try{d=await l(c.name)}catch{}const f=function(e,t,n,o){const r=new Set;for(const i of e){if("private"===i&&!n)continue;if("iframe"===i&&!o)continue;const e=a[i];if(e)for(const n of e)if(!n.browsers||n.browsers.includes(t))for(const e of n.exclude)r.add(e)}return r}(i.stabilize,c.name,d,u),m=new Set(f);for(const e of i.exclude)m.add(e);for(const e of i.include)m.delete(e);const{components:p,errors:h}=await q(m,i.timeout,i.experimental),g={t:e};for(const[e,t]of Object.entries(p))o.has(e)||(g[e]=t);const y=w(g,i.salt),S={t:e};for(const[e,t]of Object.entries(p))r.has(e)||(S[e]=t);const v=w(S,i.salt),x={hash:y,stableHash:v,components:{...p,t:e},timestamp:(new Date).toISOString(),version:e,isIncognito:d,errors:h};return i.debug&&(console.log("[fingerprint] components:",p),console.log("[fingerprint] hash:",y,"stableHash:",v),h.length>0&&console.warn("[fingerprint] errors:",h)),x}const Q=new RegExp(["googlebot","bingbot","slurp","baiduspider","duckduckbot","yandex","sogou","exabot","ia_archiver","curl","wget","python-requests","python-urllib","axios","node-fetch","go-http-client","java/","libwww-perl","okhttp","apache-httpclient","http_request","httpie","headlesschrome","phantomjs","puppeteer","playwright","cypress","selenium","webdriver","electron","jsdom","vercel-screenshot","screenshot","prerender","lighthouse","chrome-lighthouse","pagespeed","gtmetrix","pingdom","nessus","nikto","sqlmap","burp","zap","qualys","openvas","nmap","masscan","facebookexternalhit","twitterbot","linkedinbot","whatsapp","telegrambot","slackbot","discordbot","bot","crawl","spider","scrape","fetch","scan"].join("|"),"i");function ee(e){return!!e&&Q.test(e)}const SENTINEL_USER_IDS=new Set(["__pre_auth__","anonymous","guest","undefined","null"]);function isSentinelUserId(e){return"string"==typeof e&&SENTINEL_USER_IDS.has(e)}const DEFAULT_MAX_RETRIES=3,DEFAULT_TIMEOUT_MS=3e4,MAX_DELAY_MS=3e4,BASE_DELAY_MS=1e3,SUBMIT_FP_PATH="/__unshared/submit-fp",SS_EMAIL_KEY="__unshared_email",SS_FP_KEY="__unshared_fp",SS_LAST_SUBMIT_KEY="__unshared_last_submit",LS_DEVICE_ID="__unshared_device_id",COOKIE_UID="__unshared_uid",COOKIE_SID="__unshared_sid";function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function sleep(e){return new Promise(t=>setTimeout(t,e))}function retryDelay(e){const t=Math.min(1e3*Math.pow(2,e-1),3e4),n=500*Math.random()-250;return Math.max(0,t+n)}function getCookie(e){if("undefined"==typeof document)return;const t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):void 0}function setCookie(e,t){"undefined"!=typeof document&&(document.cookie=`${e}=${encodeURIComponent(t)}; Path=/; SameSite=Lax`)}function deleteCookie(e){"undefined"!=typeof document&&(document.cookie=`${e}=; Path=/; SameSite=Lax; Expires=Thu, 01 Jan 1970 00:00:00 GMT`)}function getLocalStorageItem(e){if("undefined"!=typeof localStorage)try{return localStorage.getItem(e)??void 0}catch{return}}function setLocalStorageItem(e,t){if("undefined"!=typeof localStorage)try{localStorage.setItem(e,t)}catch{}}function getSessionStorageItem(e){if("undefined"!=typeof sessionStorage)try{return sessionStorage.getItem(e)??void 0}catch{return}}function setSessionStorageItem(e,t){if("undefined"!=typeof sessionStorage)try{sessionStorage.setItem(e,t)}catch{}}function isValidUrl(e){try{return new URL(e),!0}catch{return!1}}class UnsharedLabsBrowser{constructor(e={}){if(this.o="",e.baseUrl&&!isValidUrl(e.baseUrl))throw new Error('baseUrl must be a valid URL (e.g. "https://app.example.com")');let t,n;this.i=e.baseUrl?e.baseUrl.replace(/\/$/,""):"",this.u=e.maxRetries??3,this.l=e.timeout??3e4,this.m=e.includePathPrefix,this.p=e.skipPaths,this.h=e.sessionId,this.S=e.deviceId,this.o=getSessionStorageItem(SS_LAST_SUBMIT_KEY)??"";try{t=this.h?.()}catch{}this.v=t??getCookie(COOKIE_SID)??generateUUID(),setCookie(COOKIE_SID,this.v);try{n=this.S?.()}catch{}n?(this._=n,setLocalStorageItem(LS_DEVICE_ID,n)):this._=getLocalStorageItem(LS_DEVICE_ID)??"",this.I()}async init(e){try{if("undefined"!=typeof navigator&&ee(navigator.userAgent))return;if(isSentinelUserId(e.userId))return void this.C;this.C=e.userId,this.M=e.emailAddress,"undefined"!=typeof sessionStorage&&sessionStorage.setItem(SS_EMAIL_KEY,e.emailAddress),setCookie(COOKIE_UID,e.userId);let t,n=this.k();n||(n=await this.collect(),this.D(n));try{t=this.S?.()}catch{}t?(this._=t,setLocalStorageItem(LS_DEVICE_ID,t)):n.fingerprint_id&&(this._=n.fingerprint_id,setLocalStorageItem(LS_DEVICE_ID,n.fingerprint_id)),this.L(n).catch(()=>{})}catch{}}onRouteChange(){try{if(!this.P())return;const e=this.k();if(!e)return;this.L(e).catch(()=>{})}catch{}}destroy(){try{"undefined"!=typeof sessionStorage&&(sessionStorage.removeItem(SS_EMAIL_KEY),sessionStorage.removeItem(SS_FP_KEY),sessionStorage.removeItem(SS_LAST_SUBMIT_KEY)),this.o="",deleteCookie(COOKIE_UID),this.T&&"undefined"!=typeof document&&(document.removeEventListener("DOMContentLoaded",this.T),this.T=void 0),this.C=void 0,this.M=void 0}catch{}}async collect(e){const t=[...new Set(["timing","speech",...e?.exclude??[]])],n=await Z({...e,exclude:t});return{fingerprint_id:n.stableHash,full_hash:n.hash,components:n.components,timestamp:n.timestamp,isIncognito:n.isIncognito,version:n.version}}async submitFingerprintEvent(e,t){try{const n=this.A(e,t),o=generateUUID(),r=`${this.i}${SUBMIT_FP_PATH}`;return await this.U(r,JSON.stringify(n),o)}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}P(){if("undefined"!=typeof sessionStorage)return sessionStorage.getItem(SS_EMAIL_KEY)??void 0}k(){if("undefined"==typeof sessionStorage)return;const e=sessionStorage.getItem(SS_FP_KEY);if(e)try{return JSON.parse(e)}catch{return}}D(e){"undefined"!=typeof sessionStorage&&sessionStorage.setItem(SS_FP_KEY,JSON.stringify(e))}O(){if("undefined"==typeof location)return!0;const e=location.pathname||"/";if(this.p)for(const t of this.p)if(e.startsWith(t))return!1;return!this.m||this.m.some(t=>e.startsWith(t))}async L(e){if("undefined"!=typeof navigator&&ee(navigator.userAgent))return{success:!0};if(!this.O())return{success:!0};const t=this.M??this.P(),n=this.C??getCookie(COOKIE_UID),o="undefined"!=typeof location?(location.pathname||"/")+(location.search||""):"/";if(n){const e=`${n}|${o}`;if(e===this.o)return{success:!0};this.o=e,setSessionStorageItem(SS_LAST_SUBMIT_KEY,e)}const r={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:(new Date).toISOString(),is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.v,event_type:o};n&&(r.user_id=n),t&&(r.email=t);const i=`${e.fingerprint_id}|${n??""}|${o}`,a=`${this.i}${SUBMIT_FP_PATH}`;return this.U(a,JSON.stringify(r),i)}I(){"undefined"!=typeof document&&(this.T&&document.removeEventListener("DOMContentLoaded",this.T),this.T=()=>{if(!this.P())return;const e=this.k();e&&this.L(e).catch(()=>{})},document.addEventListener("DOMContentLoaded",this.T))}async U(e,t,n){const o=this.u+1;let r={success:!1,error:{code:"DELIVERY_FAILED",message:"Request failed"}};for(let i=1;i<=o;i++){i>1&&await sleep(retryDelay(i-1));const o=new AbortController,a=setTimeout(()=>o.abort(),this.l);try{const i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Idempotency-Key":n,"X-Session-Id":this.v,"X-Device-Id":this._},body:t,signal:o.signal});if(clearTimeout(a),i.status>=500){r={success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${i.status}`}};continue}if(i.status>=400)return{success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${i.status}`}};const s=await i.text().catch(()=>"{}");let c;try{c=JSON.parse(s)}catch{c={}}return!1===c?.success?{success:!1,error:c.error??{code:"UPSTREAM_ERROR",message:"Upstream failed"}}:{success:!0,data:c?.data}}catch(e){clearTimeout(a),r={success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}return r}A(e,t){const n={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:e.timestamp,is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.v};n.user_id=t.userId,null!=t?.eventType&&(n.event_type=t.eventType);const o=this.M??this.P();return o&&(n.email=o),n}}function createAxiosInterceptor(e){return t=>{if(403===t?.response?.status&&"account_flagged"===t?.response?.data?.error)try{e.onFlagged()}catch{}return Promise.reject(t)}}function createFetchInterceptor(e,t){return async(...n)=>{const o=await e(...n);if(403===o.status){const e=o.clone();try{const n=await e.json();if("account_flagged"===n?.error)try{t.onFlagged()}catch{}}catch{}}return o}}export{UnsharedLabsBrowser,createAxiosInterceptor,createFetchInterceptor};
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).UnsharedLabsBrowser={})}(this,function(e){"use strict";const t="1.0.0",n=1282368115,r={exclude:[],include:[],timeout:3e3,stabilize:["private","iframe","always"],experimental:!1,debug:!1,salt:""},o=new Set(["audio","timing","navigatorConnection","domrect","permissions","fonts"]),a={always:[{exclude:["speech"],browsers:["brave","firefox"]},{exclude:["keyboard"],browsers:["firefox","safari"]},{exclude:["workers"],browsers:["firefox"]},{exclude:["hardwareSensitive","navigatorProps"],browsers:["brave"]}],private:[{exclude:["fonts"],browsers:["firefox"]},{exclude:["audio"],browsers:["safari","brave"]}],iframe:[{exclude:["applePay"],browsers:["safari"]},{exclude:["permissions"]},{exclude:["keyboard"]}]};let i=null;function c(){if(i)return i;const e=navigator.userAgent;return i=function(){const e=navigator.brave;return!!e&&"function"==typeof e.isBrave}()?{name:"brave",version:s(e,/Chrome\/([\d.]+)/)}:/Edg\//i.test(e)?{name:"edge",version:s(e,/Edg\/([\d.]+)/)}:/OPR\//i.test(e)||/Opera/i.test(e)?{name:"opera",version:s(e,/OPR\/([\d.]+)/)||s(e,/Opera\/([\d.]+)/)}:/SamsungBrowser/i.test(e)?{name:"samsung",version:s(e,/SamsungBrowser\/([\d.]+)/)}:/Firefox\//i.test(e)?{name:"firefox",version:s(e,/Firefox\/([\d.]+)/)}:/Safari\//i.test(e)&&!/Chrome/i.test(e)?{name:"safari",version:s(e,/Version\/([\d.]+)/)}:/Chrome\//i.test(e)?{name:"chrome",version:s(e,/Chrome\/([\d.]+)/)}:{name:"unknown",version:""},i}function s(e,t){const n=e.match(t);return n?.[1]??""}function u(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,a=65535&e[1],i=t[0]>>>16,c=65535&t[0],s=t[1]>>>16;let u=0,l=0,f=0,m=0,d=0;return l=a+(65535&t[1]),u=l>>>16,l&=65535,f=o+s+u,u=f>>>16,f&=65535,m=r+c+u,u=m>>>16,m&=65535,d=n+i+u,d&=65535,[d<<16|m,f<<16|l]}function l(e,t){const n=e[0]>>>16,r=65535&e[0],o=e[1]>>>16,a=65535&e[1],i=t[0]>>>16,c=65535&t[0],s=t[1]>>>16,u=65535&t[1];let l=0,f=0,m=0,d=0,p=0;return f=a*u,l=f>>>16,f&=65535,m=o*u+l,l=m>>>16,m&=65535,m+=a*s,l+=m>>>16,m&=65535,d=r*u+l,l=d>>>16,d&=65535,d+=o*s,l+=d>>>16,d&=65535,d+=a*c,l+=d>>>16,d&=65535,p=n*u+r*s+o*c+a*i+l,p&=65535,[p<<16|d,m<<16|f]}function f(e,t){return 32==(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])}function m(e,t){return 0==(t%=64)?[e[0],e[1]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]}function d(e,t){return[e[0]^t[0],e[1]^t[1]]}function p(e){let t=[e[0],e[1]];return t=d(t,[0,t[0]>>>1]),t=l(t,[4283543511,3981806797]),t=d(t,[0,t[0]>>>1]),t=l(t,[3301882366,444984403]),t=d(t,[0,t[0]>>>1]),t}function h(e){return("00000000"+(e>>>0).toString(16)).slice(-8)}function y(e,t=0){const n=e.length%16,r=e.length-n;let o=[0,t],a=[0,t];const i=[2277735313,289559509],c=[1291169091,658871167];for(let t=0;t<r;t+=16){let n=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],r=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24];n=l(n,i),n=f(n,31),n=l(n,c),o=d(o,n),o=f(o,27),o=u(o,a),o=u(l(o,[0,5]),[0,1390208809]),r=l(r,c),r=f(r,33),r=l(r,i),a=d(a,r),a=f(a,31),a=u(a,o),a=u(l(a,[0,5]),[0,944331445])}let s=[0,0],y=[0,0];switch(n){case 15:y=d(y,m([0,e.charCodeAt(r+14)],48));case 14:y=d(y,m([0,e.charCodeAt(r+13)],40));case 13:y=d(y,m([0,e.charCodeAt(r+12)],32));case 12:y=d(y,m([0,e.charCodeAt(r+11)],24));case 11:y=d(y,m([0,e.charCodeAt(r+10)],16));case 10:y=d(y,m([0,e.charCodeAt(r+9)],8));case 9:y=d(y,[0,e.charCodeAt(r+8)]),y=l(y,c),y=f(y,33),y=l(y,i),a=d(a,y);case 8:s=d(s,m([0,e.charCodeAt(r+7)],56));case 7:s=d(s,m([0,e.charCodeAt(r+6)],48));case 6:s=d(s,m([0,e.charCodeAt(r+5)],40));case 5:s=d(s,m([0,e.charCodeAt(r+4)],32));case 4:s=d(s,m([0,e.charCodeAt(r+3)],24));case 3:s=d(s,m([0,e.charCodeAt(r+2)],16));case 2:s=d(s,m([0,e.charCodeAt(r+1)],8));case 1:s=d(s,[0,e.charCodeAt(r)]),s=l(s,i),s=f(s,31),s=l(s,c),o=d(o,s)}return o=d(o,[0,e.length]),a=d(a,[0,e.length]),o=u(o,a),a=u(a,o),o=p(o),a=p(a),o=u(o,a),a=u(a,o),h(o[0])+h(o[1])+h(a[0])+h(a[1])}function g(e){return v(e,new Set)}function v(e,t){if(null===e)return"null";if(void 0===e)return"undefined";const n=typeof e;if("boolean"===n||"number"===n)return String(e);if("string"===n)return JSON.stringify(e);if(Array.isArray(e)){if(t.has(e))return'"[Circular]"';t.add(e);const n=e.map(e=>v(e,t));return t.delete(e),"["+n.join(",")+"]"}if("object"===n){const n=e;if(t.has(n))return'"[Circular]"';t.add(n);const r=Object.keys(n).sort().filter(e=>void 0!==n[e]).map(e=>JSON.stringify(e)+":"+v(n[e],t));return t.delete(n),"{"+r.join(",")+"}"}return String(e)}const x=y("",n);function w(e,t){const r=function(e){if(0===e.length)return y("",n);if(1===e.length)return y(e[0],n);let t=[...e];for(;t.length>1;){const e=[];for(let r=0;r<t.length;r+=2){const o=r+1<t.length?t[r+1]:x;e.push(y(t[r]+o,n))}t=e}return t[0]}(Object.keys(e).sort().map(t=>{const r=function(e){let t=n;for(let n=0;n<e.length;n++)t=Math.imul(t^e.charCodeAt(n),1540483477),t^=t>>>13;return t>>>0}(t);return y(g(e[t]),r)})),o=String.fromCharCode(76,111,98,115),a=t?y(t,n):"";return y(r+o+a,n)}function S(e){try{const t=e.getExtension("EXT_texture_filter_anisotropic")??e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")??e.getExtension("MOZ_EXT_texture_filter_anisotropic");return t?e.getParameter(t.MAX_TEXTURE_MAX_ANISOTROPY_EXT):null}catch{return null}}function b(e){try{const t=e.getContext("webgl2");if(!t)return null;const n={version:t.getParameter(t.VERSION),maxSamples:t.getParameter(t.MAX_SAMPLES),max3DTextureSize:t.getParameter(t.MAX_3D_TEXTURE_SIZE),maxArrayTextureLayers:t.getParameter(t.MAX_ARRAY_TEXTURE_LAYERS),maxUniformBlockSize:t.getParameter(t.MAX_UNIFORM_BLOCK_SIZE),maxVertexUniformComponents:t.getParameter(t.MAX_VERTEX_UNIFORM_COMPONENTS),maxFragmentUniformComponents:t.getParameter(t.MAX_FRAGMENT_UNIFORM_COMPONENTS),maxColorAttachments:t.getParameter(t.MAX_COLOR_ATTACHMENTS),maxDrawBuffers:t.getParameter(t.MAX_DRAW_BUFFERS)};return t.getExtension("WEBGL_lose_context")?.loseContext(),n}catch{return null}}function C(){const e=navigator.userAgentData;if(e?.platform)return e.platform;const t=navigator.userAgent??"";return/Windows/.test(t)?"Windows":/Macintosh|Mac OS X/.test(t)?"macOS":/CrOS/.test(t)?"Chrome OS":/Android/.test(t)?"Android":/Linux/.test(t)?"Linux":/iPhone|iPad|iPod/.test(t)?"iOS":""}function M(){try{const e=new ArrayBuffer(4),t=new Float32Array(e),n=new Uint8Array(e);return t[0]=1/0,n[3]}catch{return 0}}function k(e,t,n,r){const o=(n-t)/r;let a=e(t)+e(n);for(let n=1;n<r;n++)a+=e(t+n*o)*(n%2==0?2:4);return a*o/3}function P(){try{const e=(new Intl.DateTimeFormat).resolvedOptions();return{locale:e.locale,calendar:e.calendar,numberingSystem:e.numberingSystem,timeZone:e.timeZone}}catch{return{}}}function I(){try{const e=(new Intl.NumberFormat).resolvedOptions();return{locale:e.locale,numberingSystem:e.numberingSystem,style:e.style,minimumIntegerDigits:e.minimumIntegerDigits,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,useGrouping:e.useGrouping}}catch{return{}}}function T(){try{const e=(new Intl.Collator).resolvedOptions();return{locale:e.locale,usage:e.usage,sensitivity:e.sensitivity,collation:e.collation,numeric:e.numeric,caseFirst:e.caseFirst}}catch{return{}}}function A(){try{const e=(new Intl.PluralRules).resolvedOptions(),t=new Intl.PluralRules(void 0,{type:"ordinal"}).resolvedOptions();return{locale:e.locale,type:e.type,cardinalCategories:(new Intl.PluralRules).select(0)+","+(new Intl.PluralRules).select(1)+","+(new Intl.PluralRules).select(2)+","+(new Intl.PluralRules).select(5)+","+(new Intl.PluralRules).select(11)+","+(new Intl.PluralRules).select(100),ordinalCategory1:t.type,minimumIntegerDigits:e.minimumIntegerDigits}}catch{return{}}}function B(){try{const e=new Intl.RelativeTimeFormat;if(!e)return{};const t=e.resolvedOptions();return{locale:t.locale,style:t.style,numeric:t.numeric,numberingSystem:t.numberingSystem}}catch{return{}}}function D(){try{const e=new Intl.ListFormat;if(!e)return{};const t=e.resolvedOptions(),n=["X","Y","Z"],r=new Intl.ListFormat(void 0,{type:"conjunction",style:"long"}),o=new Intl.ListFormat(void 0,{type:"disjunction",style:"long"});return{locale:t.locale,type:t.type,style:t.style,conjunctionSample:r.format(n),disjunctionSample:o.format(n)}}catch{return{}}}const E=[["backdrop-filter","blur(1px)"],["container-type","inline-size"],["text-wrap","balance"],["overscroll-behavior","contain"],["hanging-punctuation","first"],["-webkit-line-clamp","1"],["appearance","none"],["font-size-adjust","ex-height 0.5"],["font-palette","normal"],["field-sizing","content"],["-webkit-text-stroke","1px black"],["zoom","1"],["scrollbar-width","thin"],["scrollbar-color","red blue"],["animation-timeline","auto"],["mask-composite","add"],["offset-path","none"],["text-decoration-thickness","1px"],["content-visibility","auto"],["contain-intrinsic-size","auto 100px"],["aspect-ratio","16/9"],["gap","10px"],["color-mix","in srgb, red 50%, blue"],["linear-gradient(in oklch, red, blue)",""]];function L(){try{const e=document.createElement("div");e.style.cssText="visibility:hidden;overflow:scroll;position:absolute;top:-9999px;width:100px;height:100px",document.body.appendChild(e);const t=document.createElement("div");e.appendChild(t);const n=e.offsetWidth-t.offsetWidth;return document.body.removeChild(e),n}catch{return-1}}function _(){const e={};if("undefined"==typeof CSS||"function"!=typeof CSS.supports)return e;for(const[t,n]of E)e[t]=n?CSS.supports(t,n):CSS.supports(t);return e}function R(){try{const e=document.createElement("div");e.style.cssText=["position:fixed","top:0","left:0","width:0","height:0","visibility:hidden","padding-top:env(safe-area-inset-top,0px)","padding-bottom:env(safe-area-inset-bottom,0px)","padding-left:env(safe-area-inset-left,0px)","padding-right:env(safe-area-inset-right,0px)"].join(";"),document.body.appendChild(e);const t=getComputedStyle(e),n={top:t.paddingTop,bottom:t.paddingBottom,left:t.paddingLeft,right:t.paddingRight};return document.body.removeChild(e),n}catch{return null}}function O(){try{const e=performance.now();let t=1/0,n=e;for(let r=0;r<50;r++){const r=performance.now(),o=r-n;if(o>0&&o<t&&(t=o),n=r,r-e>=1)break}if(t===1/0)return-1;const r=1e3*t;if(r<=0)return-1;const o=Math.max(0,Math.round(Math.log10(r)));return Math.pow(10,o)}catch{return-1}}const z=["Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Bookman Old Style","Bradley Hand","Calibri","Cambria","Cambria Math","Century","Century Gothic","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Gill Sans","Helvetica","Helvetica Neue","Impact","Lucida Console","Lucida Grande","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3","Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Ubuntu","Merriweather","Playfair Display","Source Sans Pro","Source Code Pro","Fira Code","JetBrains Mono","Cascadia Code","Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","SF Pro","SF Pro Display","SF Mono","San Francisco","Menlo","Andale Mono","Futura","MS Gothic","MS Mincho","MS PGothic","MS PMincho","Yu Gothic","Meiryo","Hiragino Sans","Hiragino Kaku Gothic Pro","SimSun","SimHei","Microsoft YaHei","PingFang SC","Noto Sans CJK","Malgun Gothic","Arial Hebrew"],F=["monospace","sans-serif","serif"],W="mmMwWLliI0O&1";function $(e,t){const n=[],r=e.split("\r\n");let o=!1;for(const e of r)if(e.startsWith(`m=${t}`))o=!0;else{if(e.startsWith("m=")&&o)break;if(o&&e.startsWith("a=rtpmap:")){const t=e.match(/^a=rtpmap:\d+\s+(.+)$/);t&&n.push(t[1])}}return n}const V=["accelerometer","accessibility-events","ambient-light-sensor","background-fetch","background-sync","bluetooth","camera","clipboard-read","clipboard-write","display-capture","geolocation","gyroscope","local-fonts","magnetometer","microphone","midi","nfc","notifications","payment-handler","persistent-storage","push","screen-wake-lock","speaker-selection","storage-access","top-level-storage-access","window-management","xr-spatial-tracking"];function U(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;let n=e[0],r=0;for(const[e,o]of Object.entries(t))o>r&&(n=e,r=o);return n}const G=[{name:"prefers-contrast",values:["no-preference","more","less","custom"]},{name:"any-hover",values:["none","hover"]},{name:"any-pointer",values:["none","coarse","fine"]},{name:"pointer",values:["none","coarse","fine"]},{name:"hover",values:["none","hover"]},{name:"update",values:["none","slow","fast"]},{name:"inverted-colors",values:["none","inverted"]},{name:"prefers-reduced-motion",values:["no-preference","reduce"]},{name:"prefers-reduced-transparency",values:["no-preference","reduce"]},{name:"scripting",values:["none","initial-only","enabled"]},{name:"forced-colors",values:["none","active"]},{name:"prefers-color-scheme",values:["light","dark"]},{name:"color-gamut",values:["srgb","p3","rec2020"]},{name:"dynamic-range",values:["standard","high"]}],j=["KeyQ","KeyW","KeyA","KeyS","KeyZ","KeyX","KeyY","KeyM","Semicolon","BracketLeft","Quote","Digit1","Digit2","Digit3"];function H(e){const t=e.KeyQ,n=e.KeyZ,r=e.KeyY;return t?"a"===t?"azerty":"q"===t&&"z"===r?"qwertz":"q"===t&&"z"===n?"qwerty":"'"===t?"dvorak":"other":null}const K=[{name:"webgl",tier:1,async collect(){const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!(t&&t instanceof WebGLRenderingContext))return null;const n=t.getExtension("WEBGL_debug_renderer_info"),r=t.getSupportedExtensions()??[],o=function(e){const t={},n=[e.VERTEX_SHADER,e.FRAGMENT_SHADER],r=[e.LOW_FLOAT,e.MEDIUM_FLOAT,e.HIGH_FLOAT,e.LOW_INT,e.MEDIUM_INT,e.HIGH_INT],o=["vertex","fragment"],a=["lowFloat","mediumFloat","highFloat","lowInt","mediumInt","highInt"];for(let i=0;i<n.length;i++){const c={};for(let t=0;t<r.length;t++){const o=e.getShaderPrecisionFormat(n[i],r[t]);o&&(c[a[t]]={rangeMin:o.rangeMin,rangeMax:o.rangeMax,precision:o.precision})}t[o[i]]=c}return t}(t),a={vendor:t.getParameter(t.VENDOR),renderer:t.getParameter(t.RENDERER),version:t.getParameter(t.VERSION),shadingLanguageVersion:t.getParameter(t.SHADING_LANGUAGE_VERSION),unmaskedVendor:n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):null,unmaskedRenderer:n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):null,extensions:r.sort(),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE),maxViewportDims:Array.from(t.getParameter(t.MAX_VIEWPORT_DIMS)),maxVertexAttribs:t.getParameter(t.MAX_VERTEX_ATTRIBS),maxVertexUniformVectors:t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),maxFragmentUniformVectors:t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:t.getParameter(t.MAX_VARYING_VECTORS),aliasedLineWidthRange:Array.from(t.getParameter(t.ALIASED_LINE_WIDTH_RANGE)),aliasedPointSizeRange:Array.from(t.getParameter(t.ALIASED_POINT_SIZE_RANGE)),maxCombinedTextureImageUnits:t.getParameter(t.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxTextureImageUnits:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextureImageUnits:t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),shaderPrecision:o,maxAnisotropy:S(t),webgl2:b(e)};return t.getExtension("WEBGL_lose_context")?.loseContext(),a}},{name:"hardware",tier:1,collect:async()=>({architecture:M(),platform:C()})},{name:"hardwareSensitive",tier:1,collect:async()=>({deviceMemory:navigator.deviceMemory??null,hardwareConcurrency:navigator.hardwareConcurrency??null})},{name:"math",tier:1,collect:async()=>({acos:Math.acos(.5),asin:k(Math.asin,-1,1,97),cos:k(Math.cos,0,Math.PI,97),cosLarge:Math.cos(1e20),sinLarge:Math.sin(1e20),tanLarge:Math.tan(1e20),sin:k(Math.sin,0,Math.PI,97),tan:k(Math.tan,0,Math.PI/4,97)})},{name:"i18n",tier:1,collect:async()=>({dateTimeFormat:P(),numberFormat:I(),collator:T(),pluralRules:A(),relativeTimeFormat:B(),listFormat:D()})},{name:"domrect",tier:1,collect:async()=>({basic:function(){const e=document.createElement("div");e.style.cssText="position:fixed;left:-9999px;width:100px;height:100px;",document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}(),precision:function(){const e=document.createElement("div");e.style.cssText=`position:absolute;left:-9999px;width:${Math.PI}px;height:${Math.E}px;`,document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{width:t.width,height:t.height}}(),fromRect:"undefined"!=typeof DOMRectReadOnly&&"function"==typeof DOMRectReadOnly.fromRect})},{name:"touch",tier:1,collect:async()=>({supported:"ontouchstart"in window||navigator.maxTouchPoints>0,maxTouchPoints:navigator.maxTouchPoints??0})},{name:"display",tier:1,collect:async()=>({colorDepth:screen.colorDepth??0,pixelDepth:screen.pixelDepth??0})},{name:"locale",tier:1,collect:async()=>({timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"",language:navigator.language??""})},{name:"workers",tier:1,collect:async()=>({webWorker:"undefined"!=typeof Worker,sharedWorker:"undefined"!=typeof SharedWorker,serviceWorker:"serviceWorker"in navigator})},{name:"plugins",tier:1,async collect(){const e=[];if(navigator.plugins)for(let t=0;t<navigator.plugins.length;t++){const n=navigator.plugins[t];"internal-pdf-viewer"===n.filename&&e.push(`${n.name}|${n.filename}|${n.description}`)}return{plugins:e.sort(),pdfViewerEnabled:navigator.pdfViewerEnabled??!1}}},{name:"css",tier:1,collect:async()=>({scrollbarWidth:L(),supports:_(),safeArea:R()})},{name:"navigatorProps",tier:1,collect:async()=>({vendor:navigator.vendor??"",productSub:navigator.productSub??"",cookieEnabled:navigator.cookieEnabled})},{name:"timing",tier:2,collect:async()=>({performancePrecisionUs:O()})},{name:"navigatorConnection",tier:2,async collect(){const e=navigator,t=e.connection??e.mozConnection??e.webkitConnection??null,n=performance.memory??null;return{connection:t?{type:t.type??null,effectiveType:t.effectiveType??null,downlink:t.downlink??null,rtt:t.rtt??null,saveData:t.saveData??null}:null,memory:n?{jsHeapSizeLimit:n.jsHeapSizeLimit,totalJSHeapSize:n.totalJSHeapSize}:null}}},{name:"webgpu",tier:2,async collect(){const e=navigator.gpu;if(!e)return null;const t=await e.requestAdapter();if(!t)return null;let n="",r="",o="",a="";if(t.info)n=t.info.vendor??"",r=t.info.architecture??"",o=t.info.device??"",a=t.info.description??"";else if("function"==typeof t.requestAdapterInfo){const e=await t.requestAdapterInfo();n=e.vendor??"",r=e.architecture??"",o=e.device??"",a=e.description??""}const i=[];t.features&&(t.features.forEach(e=>i.push(e)),i.sort());const c={};if(t.limits){const e=["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderComponents","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension"];for(const n of e){const e=t.limits[n];void 0!==e&&(c[n]=e)}}return{vendor:n,architecture:r,device:o,description:a,features:i,limits:c}}},{name:"audio",tier:2,async collect(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return null;let t=null;try{t=new e;const n=t.destination;return{sampleRate:t.sampleRate,maxChannelCount:n.maxChannelCount,channelCount:n.channelCount,channelCountMode:n.channelCountMode,channelInterpretation:n.channelInterpretation,baseLatency:t.baseLatency??null,outputLatency:t.outputLatency??null}}finally{if(t&&"closed"!==t.state)try{await t.close()}catch{}}}},{name:"fonts",tier:2,collect:()=>new Promise(e=>{const t=()=>e(function(){try{if("undefined"==typeof document)return{available:[],method:"css-layout"};const e=new Set,t=[];if("function"==typeof document.fonts?.check)for(const n of z)document.fonts.check(`72px "${n}"`)?e.add(n):t.push(n);else t.push(...z);const n=new Set;if(t.length>0){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px;left:-9999px;pointer-events:none;";const r=F.map(t=>{const n=document.createElement("span");return n.style.cssText=`font-size:72px;font-family:${t};white-space:nowrap;display:inline-block`,n.textContent=W,e.appendChild(n),n}),o=t.map(t=>F.map(n=>{const r=document.createElement("span");return r.style.cssText=`font-size:72px;font-family:'${t}',${n};white-space:nowrap;display:inline-block`,r.textContent=W,e.appendChild(r),r}));document.body.appendChild(e);const a=r.map(e=>e.getBoundingClientRect().width),i=o.map(e=>e.map(e=>e.getBoundingClientRect().width));document.body.removeChild(e);for(let e=0;e<t.length;e++)for(let r=0;r<F.length;r++)if(i[e][r]!==a[r]){n.add(t[e]);break}}return{available:z.filter(t=>e.has(t)||n.has(t)),method:"css-layout"}}catch{return{available:[],method:"css-layout"}}}());"undefined"!=typeof requestIdleCallback?requestIdleCallback(t,{timeout:2e3}):setTimeout(t,0)})},{name:"webrtc",tier:2,async collect(){if("undefined"==typeof RTCPeerConnection)return{supported:!1,audioCodecCount:0,videoCodecCount:0,audioCodecs:[],videoCodecs:[],extensions:[]};const e=new RTCPeerConnection({iceServers:[]});try{e.addTransceiver("audio"),e.addTransceiver("video");const t=(await e.createOffer()).sdp??"",n=$(t,"audio"),r=$(t,"video"),o=function(e){const t=new Set,n=e.split("\r\n");for(const e of n)if(e.startsWith("a=extmap:")){const n=e.match(/^a=extmap:\d+(?:\/\w+)?\s+(.+)$/);n&&t.add(n[1].trim())}return Array.from(t)}(t);return{supported:!0,audioCodecCount:n.length,videoCodecCount:r.length,audioCodecs:n.sort(),videoCodecs:r.sort(),extensions:o.sort()}}finally{e.close()}}},{name:"permissions",tier:2,async collect(){if(!navigator.permissions?.query)return{states:{}};const e=()=>Promise.allSettled(V.map(async e=>{try{return{name:e,state:(await navigator.permissions.query({name:e})).state}}catch{return{name:e,state:"error"}}})),t=await Promise.all([e(),e(),e()]),n={};for(const e of t)for(const t of e)if("fulfilled"===t.status){const{name:e,state:r}=t.value;n[e]||(n[e]=[]),n[e].push(r)}const r={};for(const[e,t]of Object.entries(n))r[e]=U(t);return{states:r}}},{name:"speech",tier:2,async collect(){if("undefined"==typeof speechSynthesis)return{supported:!1,voiceCount:0,voices:[]};const e=await new Promise(e=>{const t=speechSynthesis.getVoices();if(t.length>0)return void e(t);const n=setTimeout(()=>e([]),800);speechSynthesis.addEventListener("voiceschanged",()=>{clearTimeout(n),e(speechSynthesis.getVoices())},{once:!0})}),t=e.map(e=>`${e.name}|${e.lang}|${e.localService}`).sort();return{supported:!0,voiceCount:e.length,voices:t}}},{name:"mediaQueries",tier:2,async collect(){if("function"!=typeof matchMedia){const e={};for(const t of G)e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]="unsupported";return{...e,monochrome:0}}const e={};for(const t of G){let n="unknown";for(const e of t.values){const r=matchMedia(`(${t.name}: ${e})`);if(r?.matches){n=e;break}}e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]=n}let t=0;for(let e=100;e>=0;e--)if(matchMedia(`(monochrome: ${e})`)?.matches){t=e;break}return{...e,monochrome:t}}},{name:"applePay",tier:2,async collect(){const e=window.ApplePaySession;if(!e||"function"!=typeof e.supportsVersion)return{supported:!1,maxVersion:0};let t=0;for(let n=15;n>=1;n--)try{if(e.supportsVersion(n)){t=n;break}}catch{continue}return{supported:!0,maxVersion:t}}},{name:"keyboard",tier:2,async collect(){const e=navigator.keyboard;if(!e||"function"!=typeof e.getLayoutMap)return{supported:!1,layoutKeys:null,layoutHint:null};try{const t=await e.getLayoutMap(),n={};for(const e of j){const r=t.get(e);void 0!==r&&(n[e]=r)}return{supported:!0,layoutKeys:n,layoutHint:H(n)}}catch{return{supported:!1,layoutKeys:null,layoutHint:null}}}}];async function N(e){const n={...r},i=c(),s=function(){try{return window.self!==window.top}catch{return!0}}();let u=!1;try{u=await async function(e){try{switch(e){case"chrome":case"edge":case"opera":default:return await async function(){if(!navigator.storage?.estimate)return!1;const{quota:e}=await navigator.storage.estimate();return void 0!==e&&e<4294967296}();case"brave":return await async function(){return!1}();case"safari":return await async function(){if(navigator.storage?.estimate){const{quota:e}=await navigator.storage.estimate();if(void 0!==e)return e<4294967296}try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"NotFoundError"===e?.name}}();case"firefox":return await async function(){if(!("serviceWorker"in navigator))return!0;try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"SecurityError"===e?.name}}()}}catch{return!1}}(i.name)}catch{}const l=function(e,t,n,r){const o=new Set;for(const i of e){if("private"===i&&!n)continue;if("iframe"===i&&!r)continue;const e=a[i];if(e)for(const n of e)if(!n.browsers||n.browsers.includes(t))for(const e of n.exclude)o.add(e)}return o}(n.stabilize,i.name,u,s),f=new Set(l);for(const e of n.exclude)f.add(e);for(const e of n.include)f.delete(e);const{components:m,errors:d}=await async function(e,t,n){const r={},o=[],a=K.filter(t=>!e.has(t.name)&&(n||3!==t.tier)),i=await Promise.allSettled(a.map(async e=>{const n=await(r=e.collect(),o=t,new Promise((e,t)=>{const n=setTimeout(()=>e(null),o);r.then(t=>{clearTimeout(n),e(t)},e=>{clearTimeout(n),t(e)})}));var r,o;return{name:e.name,value:n}}));for(let e=0;e<i.length;e++){const t=i[e],n=a[e].name;"fulfilled"===t.status&&null!==t.value.value?r[n]=t.value.value:"rejected"===t.status&&o.push({signal:n,error:String(t.reason?.message??t.reason)})}return{components:r,errors:o}}(f,n.timeout,n.experimental),p=w({...m,t:t},n.salt),h={t:t};for(const[e,t]of Object.entries(m))o.has(e)||(h[e]=t);const y=w(h,n.salt),g={hash:p,stableHash:y,components:{...m,t:t},timestamp:(new Date).toISOString(),version:t,isIncognito:u,errors:d};return n.debug&&(console.log("[fingerprint] components:",m),console.log("[fingerprint] hash:",p,"stableHash:",y),d.length>0&&console.warn("[fingerprint] errors:",d)),g}function q(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function Y(e){return new Promise(t=>setTimeout(t,e))}function X(e){const t=Math.min(1e3*Math.pow(2,e-1),3e4),n=500*Math.random()-250;return Math.max(0,t+n)}e.UnsharedLabsBrowser=class{constructor(e){if(!e.baseUrl||!function(e){try{return new URL(e),!0}catch{return!1}}(e.baseUrl))throw new Error("baseUrl is required and must be a valid URL");this.o=e.baseUrl.replace(/\/$/,""),this.i=e.maxRetries??3,this.u=e.timeout??3e4,this.l=q()}async collect(){const e=await N();return{fingerprint_id:e.stableHash,full_hash:e.hash,components:e.components,timestamp:e.timestamp,isIncognito:e.isIncognito,version:e.version}}async submitFingerprintEvent(e,t){try{const n=this.m(e,t),r=q(),o=`${this.o}/unshared/submit-fingerprint-event`,a=JSON.stringify(n);return await this.p(o,a,r)}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}async p(e,t,n){const r=this.i+1;let o={success:!1,error:{code:"DELIVERY_FAILED",message:"Request failed"}};for(let a=1;a<=r;a++){a>1&&await Y(X(a-1));const r=new AbortController,i=setTimeout(()=>r.abort(),this.u);try{const a=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Idempotency-Key":n,"X-Session-Id":this.l},body:t,signal:r.signal});if(clearTimeout(i),a.status>=500){o={success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${a.status}`}};continue}if(a.status>=400)return{success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${a.status}`}};const c=await a.text().catch(()=>"{}");let s;try{s=JSON.parse(c)}catch{s={}}return!1===s?.success?{success:!1,error:s.error??{code:"UPSTREAM_ERROR",message:"Upstream failed"}}:{success:!0,data:s?.data}}catch(e){clearTimeout(i),o={success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}return o}m(e,t){const n={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:e.timestamp,is_incognito:e.isIncognito,components:e.components,version:e.version};return null!=t?.userId&&(n.user_id=t.userId),null!=t?.eventType&&(n.event_type=t.eventType),n}}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).UnsharedLabsBrowser={})}(this,function(e){"use strict";const t="1.3.1",n=1282368115,o={exclude:[],include:[],timeout:3e3,stabilize:["private","iframe","always"],experimental:!1,debug:!1,salt:""},r=new Set(["audio","timing","navigatorConnection","domrect","permissions","fonts","speech"]),i=new Set(["domrect"]),a={always:[{exclude:["speech"],browsers:["brave","firefox"]},{exclude:["keyboard"],browsers:["firefox","safari"]},{exclude:["workers"],browsers:["firefox"]},{exclude:["hardwareSensitive","navigatorProps"],browsers:["brave"]}],private:[{exclude:["fonts"],browsers:["firefox"]},{exclude:["audio"],browsers:["safari","brave"]}],iframe:[{exclude:["applePay"],browsers:["safari"]},{exclude:["permissions"]},{exclude:["keyboard"]}]};let s=null;function c(){if(s)return s;const e=navigator.userAgent;return s=function(){const e=navigator.brave;return!!e&&"function"==typeof e.isBrave}()?{name:"brave",version:u(e,/Chrome\/([\d.]+)/)}:/Edg\//i.test(e)?{name:"edge",version:u(e,/Edg\/([\d.]+)/)}:/OPR\//i.test(e)||/Opera/i.test(e)?{name:"opera",version:u(e,/OPR\/([\d.]+)/)||u(e,/Opera\/([\d.]+)/)}:/SamsungBrowser/i.test(e)?{name:"samsung",version:u(e,/SamsungBrowser\/([\d.]+)/)}:/Firefox\//i.test(e)?{name:"firefox",version:u(e,/Firefox\/([\d.]+)/)}:/Safari\//i.test(e)&&!/Chrome/i.test(e)?{name:"safari",version:u(e,/Version\/([\d.]+)/)}:/Chrome\//i.test(e)?{name:"chrome",version:u(e,/Chrome\/([\d.]+)/)}:{name:"unknown",version:""},s}function u(e,t){const n=e.match(t);return n?.[1]??""}function l(e,t){const n=e[0]>>>16,o=65535&e[0],r=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16;let u=0,l=0,f=0,d=0,m=0;return l=i+(65535&t[1]),u=l>>>16,l&=65535,f=r+c+u,u=f>>>16,f&=65535,d=o+s+u,u=d>>>16,d&=65535,m=n+a+u,m&=65535,[m<<16|d,f<<16|l]}function f(e,t){const n=e[0]>>>16,o=65535&e[0],r=e[1]>>>16,i=65535&e[1],a=t[0]>>>16,s=65535&t[0],c=t[1]>>>16,u=65535&t[1];let l=0,f=0,d=0,m=0,p=0;return f=i*u,l=f>>>16,f&=65535,d=r*u+l,l=d>>>16,d&=65535,d+=i*c,l+=d>>>16,d&=65535,m=o*u+l,l=m>>>16,m&=65535,m+=r*c,l+=m>>>16,m&=65535,m+=i*s,l+=m>>>16,m&=65535,p=n*u+o*c+r*s+i*a+l,p&=65535,[p<<16|m,d<<16|f]}function d(e,t){return 32==(t%=64)?[e[1],e[0]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t|e[0]>>>32-t]:(t-=32,[e[1]<<t|e[0]>>>32-t,e[0]<<t|e[1]>>>32-t])}function m(e,t){return 0==(t%=64)?[e[0],e[1]]:t<32?[e[0]<<t|e[1]>>>32-t,e[1]<<t]:[e[1]<<t-32,0]}function p(e,t){return[e[0]^t[0],e[1]^t[1]]}function h(e){let t=[e[0],e[1]];return t=p(t,[0,t[0]>>>1]),t=f(t,[4283543511,3981806797]),t=p(t,[0,t[0]>>>1]),t=f(t,[3301882366,444984403]),t=p(t,[0,t[0]>>>1]),t}function g(e){return("00000000"+(e>>>0).toString(16)).slice(-8)}function y(e,t=0){const n=e.length%16,o=e.length-n;let r=[0,t],i=[0,t];const a=[2277735313,289559509],s=[1291169091,658871167];for(let t=0;t<o;t+=16){let n=[255&e.charCodeAt(t+4)|(255&e.charCodeAt(t+5))<<8|(255&e.charCodeAt(t+6))<<16|(255&e.charCodeAt(t+7))<<24,255&e.charCodeAt(t)|(255&e.charCodeAt(t+1))<<8|(255&e.charCodeAt(t+2))<<16|(255&e.charCodeAt(t+3))<<24],o=[255&e.charCodeAt(t+12)|(255&e.charCodeAt(t+13))<<8|(255&e.charCodeAt(t+14))<<16|(255&e.charCodeAt(t+15))<<24,255&e.charCodeAt(t+8)|(255&e.charCodeAt(t+9))<<8|(255&e.charCodeAt(t+10))<<16|(255&e.charCodeAt(t+11))<<24];n=f(n,a),n=d(n,31),n=f(n,s),r=p(r,n),r=d(r,27),r=l(r,i),r=l(f(r,[0,5]),[0,1390208809]),o=f(o,s),o=d(o,33),o=f(o,a),i=p(i,o),i=d(i,31),i=l(i,r),i=l(f(i,[0,5]),[0,944331445])}let c=[0,0],u=[0,0];switch(n){case 15:u=p(u,m([0,e.charCodeAt(o+14)],48));case 14:u=p(u,m([0,e.charCodeAt(o+13)],40));case 13:u=p(u,m([0,e.charCodeAt(o+12)],32));case 12:u=p(u,m([0,e.charCodeAt(o+11)],24));case 11:u=p(u,m([0,e.charCodeAt(o+10)],16));case 10:u=p(u,m([0,e.charCodeAt(o+9)],8));case 9:u=p(u,[0,e.charCodeAt(o+8)]),u=f(u,s),u=d(u,33),u=f(u,a),i=p(i,u);case 8:c=p(c,m([0,e.charCodeAt(o+7)],56));case 7:c=p(c,m([0,e.charCodeAt(o+6)],48));case 6:c=p(c,m([0,e.charCodeAt(o+5)],40));case 5:c=p(c,m([0,e.charCodeAt(o+4)],32));case 4:c=p(c,m([0,e.charCodeAt(o+3)],24));case 3:c=p(c,m([0,e.charCodeAt(o+2)],16));case 2:c=p(c,m([0,e.charCodeAt(o+1)],8));case 1:c=p(c,[0,e.charCodeAt(o)]),c=f(c,a),c=d(c,31),c=f(c,s),r=p(r,c)}return r=p(r,[0,e.length]),i=p(i,[0,e.length]),r=l(r,i),i=l(i,r),r=h(r),i=h(i),r=l(r,i),i=l(i,r),g(r[0])+g(r[1])+g(i[0])+g(i[1])}function v(e){return w(e,new Set)}function w(e,t){if(null===e)return"null";if(void 0===e)return"undefined";const n=typeof e;if("boolean"===n||"number"===n)return String(e);if("string"===n)return JSON.stringify(e);if(Array.isArray(e)){if(t.has(e))return'"[Circular]"';t.add(e);const n=e.map(e=>w(e,t));return t.delete(e),"["+n.join(",")+"]"}if("object"===n){const n=e;if(t.has(n))return'"[Circular]"';t.add(n);const o=Object.keys(n).sort().filter(e=>void 0!==n[e]).map(e=>JSON.stringify(e)+":"+w(n[e],t));return t.delete(n),"{"+o.join(",")+"}"}return String(e)}const x=y("",n);function S(e,t){const o=function(e){if(0===e.length)return y("",n);if(1===e.length)return y(e[0],n);let t=[...e];for(;t.length>1;){const e=[];for(let o=0;o<t.length;o+=2){const r=o+1<t.length?t[o+1]:x;e.push(y(t[o]+r,n))}t=e}return t[0]}(Object.keys(e).sort().map(t=>{const o=function(e){let t=n;for(let n=0;n<e.length;n++)t=Math.imul(t^e.charCodeAt(n),1540483477),t^=t>>>13;return t>>>0}(t);return y(v(e[t]),o)})),r=String.fromCharCode(76,111,98,115),i=t?y(t,n):"";return y(o+r+i,n)}function b(e){try{const t=e.getExtension("EXT_texture_filter_anisotropic")??e.getExtension("WEBKIT_EXT_texture_filter_anisotropic")??e.getExtension("MOZ_EXT_texture_filter_anisotropic");return t?e.getParameter(t.MAX_TEXTURE_MAX_ANISOTROPY_EXT):null}catch{return null}}function C(e){try{const t=e.getContext("webgl2");if(!t)return null;const n={version:t.getParameter(t.VERSION),maxSamples:t.getParameter(t.MAX_SAMPLES),max3DTextureSize:t.getParameter(t.MAX_3D_TEXTURE_SIZE),maxArrayTextureLayers:t.getParameter(t.MAX_ARRAY_TEXTURE_LAYERS),maxUniformBlockSize:t.getParameter(t.MAX_UNIFORM_BLOCK_SIZE),maxVertexUniformComponents:t.getParameter(t.MAX_VERTEX_UNIFORM_COMPONENTS),maxFragmentUniformComponents:t.getParameter(t.MAX_FRAGMENT_UNIFORM_COMPONENTS),maxColorAttachments:t.getParameter(t.MAX_COLOR_ATTACHMENTS),maxDrawBuffers:t.getParameter(t.MAX_DRAW_BUFFERS)};return t.getExtension("WEBGL_lose_context")?.loseContext(),n}catch{return null}}function _(){const e=navigator.userAgentData;if(e?.platform)return e.platform;const t=navigator.userAgent??"";return/Windows/.test(t)?"Windows":/Macintosh|Mac OS X/.test(t)?"macOS":/CrOS/.test(t)?"Chrome OS":/Android/.test(t)?"Android":/Linux/.test(t)?"Linux":/iPhone|iPad|iPod/.test(t)?"iOS":""}function k(){try{const e=new ArrayBuffer(4),t=new Float32Array(e),n=new Uint8Array(e);return t[0]=1/0,n[3]}catch{return 0}}function M(e,t,n,o){const r=(n-t)/o;let i=e(t)+e(n);for(let n=1;n<o;n++)i+=e(t+n*r)*(n%2==0?2:4);return i*r/3}function P(){try{const e=(new Intl.DateTimeFormat).resolvedOptions();return{locale:e.locale,calendar:e.calendar,numberingSystem:e.numberingSystem,timeZone:e.timeZone}}catch{return{}}}function I(){try{const e=(new Intl.NumberFormat).resolvedOptions();return{locale:e.locale,numberingSystem:e.numberingSystem,style:e.style,minimumIntegerDigits:e.minimumIntegerDigits,minimumFractionDigits:e.minimumFractionDigits,maximumFractionDigits:e.maximumFractionDigits,useGrouping:e.useGrouping}}catch{return{}}}function T(){try{const e=(new Intl.Collator).resolvedOptions();return{locale:e.locale,usage:e.usage,sensitivity:e.sensitivity,collation:e.collation,numeric:e.numeric,caseFirst:e.caseFirst}}catch{return{}}}function L(){try{const e=(new Intl.PluralRules).resolvedOptions(),t=new Intl.PluralRules(void 0,{type:"ordinal"}).resolvedOptions();return{locale:e.locale,type:e.type,cardinalCategories:(new Intl.PluralRules).select(0)+","+(new Intl.PluralRules).select(1)+","+(new Intl.PluralRules).select(2)+","+(new Intl.PluralRules).select(5)+","+(new Intl.PluralRules).select(11)+","+(new Intl.PluralRules).select(100),ordinalCategory1:t.type,minimumIntegerDigits:e.minimumIntegerDigits}}catch{return{}}}function D(){try{const e=new Intl.RelativeTimeFormat;if(!e)return{};const t=e.resolvedOptions();return{locale:t.locale,style:t.style,numeric:t.numeric,numberingSystem:t.numberingSystem}}catch{return{}}}function E(){try{const e=new Intl.ListFormat;if(!e)return{};const t=e.resolvedOptions(),n=["X","Y","Z"],o=new Intl.ListFormat(void 0,{type:"conjunction",style:"long"}),r=new Intl.ListFormat(void 0,{type:"disjunction",style:"long"});return{locale:t.locale,type:t.type,style:t.style,conjunctionSample:o.format(n),disjunctionSample:r.format(n)}}catch{return{}}}const A=[["backdrop-filter","blur(1px)"],["container-type","inline-size"],["text-wrap","balance"],["overscroll-behavior","contain"],["hanging-punctuation","first"],["-webkit-line-clamp","1"],["appearance","none"],["font-size-adjust","ex-height 0.5"],["font-palette","normal"],["field-sizing","content"],["-webkit-text-stroke","1px black"],["zoom","1"],["scrollbar-width","thin"],["scrollbar-color","red blue"],["animation-timeline","auto"],["mask-composite","add"],["offset-path","none"],["text-decoration-thickness","1px"],["content-visibility","auto"],["contain-intrinsic-size","auto 100px"],["aspect-ratio","16/9"],["gap","10px"],["color-mix","in srgb, red 50%, blue"],["linear-gradient(in oklch, red, blue)",""]];function $(){try{const e=document.createElement("div");e.style.cssText="visibility:hidden;overflow:scroll;position:absolute;top:-9999px;width:100px;height:100px",document.body.appendChild(e);const t=document.createElement("div");e.appendChild(t);const n=e.offsetWidth-t.offsetWidth;return document.body.removeChild(e),n}catch{return-1}}function R(){const e={};if("undefined"==typeof CSS||"function"!=typeof CSS.supports)return e;for(const[t,n]of A)e[t]=n?CSS.supports(t,n):CSS.supports(t);return e}function B(){try{const e=document.createElement("div");e.style.cssText=["position:fixed","top:0","left:0","width:0","height:0","visibility:hidden","padding-top:env(safe-area-inset-top,0px)","padding-bottom:env(safe-area-inset-bottom,0px)","padding-left:env(safe-area-inset-left,0px)","padding-right:env(safe-area-inset-right,0px)"].join(";"),document.body.appendChild(e);const t=getComputedStyle(e),n={top:t.paddingTop,bottom:t.paddingBottom,left:t.paddingLeft,right:t.paddingRight};return document.body.removeChild(e),n}catch{return null}}function O(){try{const e=performance.now();let t=1/0,n=e;for(let o=0;o<50;o++){const o=performance.now(),r=o-n;if(r>0&&r<t&&(t=r),n=o,o-e>=1)break}if(t===1/0)return-1;const o=1e3*t;if(o<=0)return-1;const r=Math.max(0,Math.round(Math.log10(o)));return Math.pow(10,r)}catch{return-1}}const F=["Arial","Arial Black","Arial Narrow","Arial Rounded MT Bold","Bookman Old Style","Bradley Hand","Calibri","Cambria","Cambria Math","Century","Century Gothic","Comic Sans MS","Consolas","Courier","Courier New","Garamond","Geneva","Georgia","Gill Sans","Helvetica","Helvetica Neue","Impact","Lucida Console","Lucida Grande","Lucida Sans Unicode","Microsoft Sans Serif","Monaco","Palatino","Palatino Linotype","Segoe Print","Segoe Script","Segoe UI","Tahoma","Times","Times New Roman","Trebuchet MS","Verdana","Wingdings","Wingdings 2","Wingdings 3","Inter","Roboto","Open Sans","Lato","Montserrat","Poppins","Nunito","Raleway","Ubuntu","Merriweather","Playfair Display","Source Sans Pro","Source Code Pro","Fira Code","JetBrains Mono","Cascadia Code","Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","SF Pro","SF Pro Display","SF Mono","San Francisco","Menlo","Andale Mono","Futura","MS Gothic","MS Mincho","MS PGothic","MS PMincho","Yu Gothic","Meiryo","Hiragino Sans","Hiragino Kaku Gothic Pro","SimSun","SimHei","Microsoft YaHei","PingFang SC","Noto Sans CJK","Malgun Gothic","Arial Hebrew"],z=["monospace","sans-serif","serif"],W="mmMwWLliI0O&1";function U(e,t){const n=[],o=e.split("\r\n");let r=!1;for(const e of o)if(e.startsWith(`m=${t}`))r=!0;else{if(e.startsWith("m=")&&r)break;if(r&&e.startsWith("a=rtpmap:")){const t=e.match(/^a=rtpmap:\d+\s+(.+)$/);t&&n.push(t[1])}}return n}const V=["accelerometer","accessibility-events","ambient-light-sensor","background-fetch","background-sync","bluetooth","camera","clipboard-read","clipboard-write","display-capture","geolocation","gyroscope","local-fonts","magnetometer","microphone","midi","nfc","notifications","payment-handler","persistent-storage","push","screen-wake-lock","speaker-selection","storage-access","top-level-storage-access","window-management","xr-spatial-tracking"];function j(e){const t={};for(const n of e)t[n]=(t[n]??0)+1;let n=e[0],o=0;for(const[e,r]of Object.entries(t))r>o&&(n=e,o=r);return n}const G=[{name:"prefers-contrast",values:["no-preference","more","less","custom"]},{name:"any-hover",values:["none","hover"]},{name:"any-pointer",values:["none","coarse","fine"]},{name:"pointer",values:["none","coarse","fine"]},{name:"hover",values:["none","hover"]},{name:"update",values:["none","slow","fast"]},{name:"inverted-colors",values:["none","inverted"]},{name:"prefers-reduced-motion",values:["no-preference","reduce"]},{name:"prefers-reduced-transparency",values:["no-preference","reduce"]},{name:"scripting",values:["none","initial-only","enabled"]},{name:"forced-colors",values:["none","active"]},{name:"prefers-color-scheme",values:["light","dark"]},{name:"color-gamut",values:["srgb","p3","rec2020"]},{name:"dynamic-range",values:["standard","high"]}],K=["KeyQ","KeyW","KeyA","KeyS","KeyZ","KeyX","KeyY","KeyM","Semicolon","BracketLeft","Quote","Digit1","Digit2","Digit3"];function N(e){const t=e.KeyQ,n=e.KeyZ,o=e.KeyY;return t?"a"===t?"azerty":"q"===t&&"z"===o?"qwertz":"q"===t&&"z"===n?"qwerty":"'"===t?"dvorak":"other":null}const H=[{name:"webgl",tier:1,async collect(){const e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");if(!(t&&t instanceof WebGLRenderingContext))return null;const n=t.getExtension("WEBGL_debug_renderer_info"),o=t.getSupportedExtensions()??[],r=function(e){const t={},n=[e.VERTEX_SHADER,e.FRAGMENT_SHADER],o=[e.LOW_FLOAT,e.MEDIUM_FLOAT,e.HIGH_FLOAT,e.LOW_INT,e.MEDIUM_INT,e.HIGH_INT],r=["vertex","fragment"],i=["lowFloat","mediumFloat","highFloat","lowInt","mediumInt","highInt"];for(let a=0;a<n.length;a++){const s={};for(let t=0;t<o.length;t++){const r=e.getShaderPrecisionFormat(n[a],o[t]);r&&(s[i[t]]={rangeMin:r.rangeMin,rangeMax:r.rangeMax,precision:r.precision})}t[r[a]]=s}return t}(t),i={vendor:t.getParameter(t.VENDOR),renderer:t.getParameter(t.RENDERER),version:t.getParameter(t.VERSION),shadingLanguageVersion:t.getParameter(t.SHADING_LANGUAGE_VERSION),unmaskedVendor:n?t.getParameter(n.UNMASKED_VENDOR_WEBGL):null,unmaskedRenderer:n?t.getParameter(n.UNMASKED_RENDERER_WEBGL):null,extensions:o.sort(),maxTextureSize:t.getParameter(t.MAX_TEXTURE_SIZE),maxRenderbufferSize:t.getParameter(t.MAX_RENDERBUFFER_SIZE),maxViewportDims:Array.from(t.getParameter(t.MAX_VIEWPORT_DIMS)),maxVertexAttribs:t.getParameter(t.MAX_VERTEX_ATTRIBS),maxVertexUniformVectors:t.getParameter(t.MAX_VERTEX_UNIFORM_VECTORS),maxFragmentUniformVectors:t.getParameter(t.MAX_FRAGMENT_UNIFORM_VECTORS),maxVaryingVectors:t.getParameter(t.MAX_VARYING_VECTORS),aliasedLineWidthRange:Array.from(t.getParameter(t.ALIASED_LINE_WIDTH_RANGE)),aliasedPointSizeRange:Array.from(t.getParameter(t.ALIASED_POINT_SIZE_RANGE)),maxCombinedTextureImageUnits:t.getParameter(t.MAX_COMBINED_TEXTURE_IMAGE_UNITS),maxTextureImageUnits:t.getParameter(t.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextureImageUnits:t.getParameter(t.MAX_VERTEX_TEXTURE_IMAGE_UNITS),shaderPrecision:r,maxAnisotropy:b(t),webgl2:C(e)};return t.getExtension("WEBGL_lose_context")?.loseContext(),i}},{name:"hardware",tier:1,collect:async()=>({architecture:k(),platform:_()})},{name:"hardwareSensitive",tier:1,collect:async()=>({deviceMemory:navigator.deviceMemory??null,hardwareConcurrency:navigator.hardwareConcurrency??null})},{name:"math",tier:1,collect:async()=>({acos:Math.acos(.5),asin:M(Math.asin,-1,1,97),cos:M(Math.cos,0,Math.PI,97),cosLarge:Math.cos(1e20),sinLarge:Math.sin(1e20),tanLarge:Math.tan(1e20),sin:M(Math.sin,0,Math.PI,97),tan:M(Math.tan,0,Math.PI/4,97)})},{name:"i18n",tier:1,collect:async()=>({dateTimeFormat:P(),numberFormat:I(),collator:T(),pluralRules:L(),relativeTimeFormat:D(),listFormat:E()})},{name:"domrect",tier:1,collect:async()=>({basic:function(){const e=document.createElement("div");e.style.cssText="position:fixed;left:-9999px;width:100px;height:100px;",document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{x:t.x,y:t.y,width:t.width,height:t.height,top:t.top,right:t.right,bottom:t.bottom,left:t.left}}(),precision:function(){const e=document.createElement("div");e.style.cssText=`position:absolute;left:-9999px;width:${Math.PI}px;height:${Math.E}px;`,document.body.appendChild(e);const t=e.getBoundingClientRect();return document.body.removeChild(e),{width:t.width,height:t.height}}(),fromRect:"undefined"!=typeof DOMRectReadOnly&&"function"==typeof DOMRectReadOnly.fromRect})},{name:"touch",tier:1,collect:async()=>({supported:"ontouchstart"in window||navigator.maxTouchPoints>0,maxTouchPoints:navigator.maxTouchPoints??0})},{name:"display",tier:1,collect:async()=>({colorDepth:screen.colorDepth??0,pixelDepth:screen.pixelDepth??0})},{name:"locale",tier:1,collect:async()=>({timezone:Intl.DateTimeFormat().resolvedOptions().timeZone??"",language:navigator.language??""})},{name:"workers",tier:1,collect:async()=>({webWorker:"undefined"!=typeof Worker,sharedWorker:"undefined"!=typeof SharedWorker,serviceWorker:"serviceWorker"in navigator})},{name:"plugins",tier:1,async collect(){const e=[];if(navigator.plugins)for(let t=0;t<navigator.plugins.length;t++){const n=navigator.plugins[t];"internal-pdf-viewer"===n.filename&&e.push(`${n.name}|${n.filename}|${n.description}`)}return{plugins:e.sort(),pdfViewerEnabled:navigator.pdfViewerEnabled??!1}}},{name:"css",tier:1,collect:async()=>({scrollbarWidth:$(),supports:R(),safeArea:B()})},{name:"navigatorProps",tier:1,collect:async()=>({vendor:navigator.vendor??"",productSub:navigator.productSub??"",cookieEnabled:navigator.cookieEnabled})},{name:"timing",tier:2,collect:async()=>({performancePrecisionUs:O()})},{name:"navigatorConnection",tier:2,async collect(){const e=navigator,t=e.connection??e.mozConnection??e.webkitConnection??null,n=performance.memory??null;return{connection:t?{type:t.type??null,effectiveType:t.effectiveType??null,saveData:t.saveData??null}:null,memory:n?{jsHeapSizeLimit:n.jsHeapSizeLimit}:null}}},{name:"webgpu",tier:2,async collect(){const e=navigator.gpu;if(!e)return null;const t=await e.requestAdapter();if(!t)return null;let n="",o="",r="",i="";if(t.info)n=t.info.vendor??"",o=t.info.architecture??"",r=t.info.device??"",i=t.info.description??"";else if("function"==typeof t.requestAdapterInfo){const e=await t.requestAdapterInfo();n=e.vendor??"",o=e.architecture??"",r=e.device??"",i=e.description??""}const a=[];t.features&&(t.features.forEach(e=>a.push(e)),a.sort());const s={};if(t.limits){const e=["maxTextureDimension1D","maxTextureDimension2D","maxTextureDimension3D","maxTextureArrayLayers","maxBindGroups","maxBindGroupsPlusVertexBuffers","maxBindingsPerBindGroup","maxDynamicUniformBuffersPerPipelineLayout","maxDynamicStorageBuffersPerPipelineLayout","maxSampledTexturesPerShaderStage","maxSamplersPerShaderStage","maxStorageBuffersPerShaderStage","maxStorageTexturesPerShaderStage","maxUniformBuffersPerShaderStage","maxUniformBufferBindingSize","maxStorageBufferBindingSize","minUniformBufferOffsetAlignment","minStorageBufferOffsetAlignment","maxVertexBuffers","maxBufferSize","maxVertexAttributes","maxVertexBufferArrayStride","maxInterStageShaderComponents","maxInterStageShaderVariables","maxColorAttachments","maxColorAttachmentBytesPerSample","maxComputeWorkgroupStorageSize","maxComputeInvocationsPerWorkgroup","maxComputeWorkgroupSizeX","maxComputeWorkgroupSizeY","maxComputeWorkgroupSizeZ","maxComputeWorkgroupsPerDimension"];for(const n of e){const e=t.limits[n];void 0!==e&&(s[n]=e)}}return{vendor:n,architecture:o,device:r,description:i,features:a,limits:s}}},{name:"audio",tier:2,async collect(){const e=window.AudioContext||window.webkitAudioContext;if(!e)return null;let t=null;try{t=new e;const n=t.destination;return{sampleRate:t.sampleRate,maxChannelCount:n.maxChannelCount,channelCount:n.channelCount,channelCountMode:n.channelCountMode,channelInterpretation:n.channelInterpretation,baseLatency:t.baseLatency??null,outputLatency:t.outputLatency??null}}finally{if(t&&"closed"!==t.state)try{await t.close()}catch{}}}},{name:"fonts",tier:2,collect:()=>new Promise(e=>{const t=()=>e(function(){try{if("undefined"==typeof document)return{available:[],method:"css-layout"};const e=new Set,t=[];if("function"==typeof document.fonts?.check)for(const n of F)document.fonts.check(`72px "${n}"`)?e.add(n):t.push(n);else t.push(...F);const n=new Set;if(t.length>0){const e=document.createElement("div");e.style.cssText="position:absolute;visibility:hidden;top:-9999px;left:-9999px;pointer-events:none;";const o=z.map(t=>{const n=document.createElement("span");return n.style.cssText=`font-size:72px;font-family:${t};white-space:nowrap;display:inline-block`,n.textContent=W,e.appendChild(n),n}),r=t.map(t=>z.map(n=>{const o=document.createElement("span");return o.style.cssText=`font-size:72px;font-family:'${t}',${n};white-space:nowrap;display:inline-block`,o.textContent=W,e.appendChild(o),o}));document.body.appendChild(e);const i=o.map(e=>e.getBoundingClientRect().width),a=r.map(e=>e.map(e=>e.getBoundingClientRect().width));document.body.removeChild(e);for(let e=0;e<t.length;e++)for(let o=0;o<z.length;o++)if(a[e][o]!==i[o]){n.add(t[e]);break}}return{available:F.filter(t=>e.has(t)||n.has(t)),method:"css-layout"}}catch{return{available:[],method:"css-layout"}}}());"undefined"!=typeof requestIdleCallback?requestIdleCallback(t,{timeout:2e3}):setTimeout(t,0)})},{name:"webrtc",tier:2,async collect(){if("undefined"==typeof RTCPeerConnection)return{supported:!1,audioCodecCount:0,videoCodecCount:0,audioCodecs:[],videoCodecs:[],extensions:[]};const e=new RTCPeerConnection({iceServers:[]});try{e.addTransceiver("audio"),e.addTransceiver("video");const t=(await e.createOffer()).sdp??"",n=U(t,"audio"),o=U(t,"video"),r=function(e){const t=new Set,n=e.split("\r\n");for(const e of n)if(e.startsWith("a=extmap:")){const n=e.match(/^a=extmap:\d+(?:\/\w+)?\s+(.+)$/);n&&t.add(n[1].trim())}return Array.from(t)}(t);return{supported:!0,audioCodecCount:n.length,videoCodecCount:o.length,audioCodecs:n.sort(),videoCodecs:o.sort(),extensions:r.sort()}}finally{e.close()}}},{name:"permissions",tier:2,async collect(){if(!navigator.permissions?.query)return{states:{}};const e=()=>Promise.allSettled(V.map(async e=>{try{return{name:e,state:(await navigator.permissions.query({name:e})).state}}catch{return{name:e,state:"error"}}})),t=await Promise.all([e(),e(),e()]),n={};for(const e of t)for(const t of e)if("fulfilled"===t.status){const{name:e,state:o}=t.value;n[e]||(n[e]=[]),n[e].push(o)}const o={};for(const[e,t]of Object.entries(n))o[e]=j(t);return{states:o}}},{name:"speech",tier:2,async collect(){if("undefined"==typeof speechSynthesis)return{supported:!1,voiceCount:0,voices:[]};const e=await new Promise(e=>{const t=speechSynthesis.getVoices();if(t.length>0)return void e(t);const n=setTimeout(()=>e([]),800);speechSynthesis.addEventListener("voiceschanged",()=>{clearTimeout(n),e(speechSynthesis.getVoices())},{once:!0})}),t=e.map(e=>`${e.name}|${e.lang}|${e.localService}`).sort();return{supported:!0,voiceCount:e.length,voices:t}}},{name:"mediaQueries",tier:2,async collect(){if("function"!=typeof matchMedia){const e={};for(const t of G)e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]="unsupported";return{...e,monochrome:0}}const e={};for(const t of G){let n="unknown";for(const e of t.values){const o=matchMedia(`(${t.name}: ${e})`);if(o?.matches){n=e;break}}e[t.name.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())]=n}let t=0;for(let e=100;e>=0;e--)if(matchMedia(`(monochrome: ${e})`)?.matches){t=e;break}return{...e,monochrome:t}}},{name:"applePay",tier:2,async collect(){const e=window.ApplePaySession;if(!e||"function"!=typeof e.supportsVersion)return{supported:!1,maxVersion:0};let t=0;for(let n=15;n>=1;n--)try{if(e.supportsVersion(n)){t=n;break}}catch{continue}return{supported:!0,maxVersion:t}}},{name:"keyboard",tier:2,async collect(){const e=navigator.keyboard;if(!e||"function"!=typeof e.getLayoutMap)return{supported:!1,layoutKeys:null,layoutHint:null};try{const t=await e.getLayoutMap(),n={};for(const e of K){const o=t.get(e);void 0!==o&&(n[e]=o)}return{supported:!0,layoutKeys:n,layoutHint:N(n)}}catch{return{supported:!1,layoutKeys:null,layoutHint:null}}}}];async function q(e){const n=function(e){return e?{exclude:e.exclude??o.exclude,include:e.include??o.include,timeout:e.timeout??o.timeout,stabilize:e.stabilize??o.stabilize,experimental:e.experimental??o.experimental,debug:e.debug??o.debug,salt:e.salt??o.salt}:{...o}}(e),s=c(),u=function(){try{return window.self!==window.top}catch{return!0}}();let l=!1;try{l=await async function(e){try{switch(e){case"chrome":case"edge":case"opera":default:return await async function(){if(!navigator.storage?.estimate)return!1;const{quota:e}=await navigator.storage.estimate();return void 0!==e&&e<4294967296}();case"brave":return await async function(){return!1}();case"safari":return await async function(){if(navigator.storage?.estimate){const{quota:e}=await navigator.storage.estimate();if(void 0!==e)return e<4294967296}try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"NotFoundError"===e?.name}}();case"firefox":return await async function(){if(!("serviceWorker"in navigator))return!0;try{return!!navigator.storage?.getDirectory&&(await navigator.storage.getDirectory(),!1)}catch(e){return"SecurityError"===e?.name}}()}}catch{return!1}}(s.name)}catch{}const f=function(e,t,n,o){const r=new Set;for(const i of e){if("private"===i&&!n)continue;if("iframe"===i&&!o)continue;const e=a[i];if(e)for(const n of e)if(!n.browsers||n.browsers.includes(t))for(const e of n.exclude)r.add(e)}return r}(n.stabilize,s.name,l,u),d=new Set(f);for(const e of n.exclude)d.add(e);for(const e of n.include)d.delete(e);const{components:m,errors:p}=await async function(e,t,n){const o={},r=[],i=H.filter(t=>!e.has(t.name)&&(n||3!==t.tier)),a=await Promise.allSettled(i.map(async e=>{const n=await(o=e.collect(),r=t,new Promise((e,t)=>{const n=setTimeout(()=>e(null),r);o.then(t=>{clearTimeout(n),e(t)},e=>{clearTimeout(n),t(e)})}));var o,r;return{name:e.name,value:n}}));for(let e=0;e<a.length;e++){const t=a[e],n=i[e].name;"fulfilled"===t.status&&null!==t.value.value?o[n]=t.value.value:"rejected"===t.status&&r.push({signal:n,error:String(t.reason?.message??t.reason)})}return{components:o,errors:r}}(d,n.timeout,n.experimental),h={t:t};for(const[e,t]of Object.entries(m))i.has(e)||(h[e]=t);const g=S(h,n.salt),y={t:t};for(const[e,t]of Object.entries(m))r.has(e)||(y[e]=t);const v=S(y,n.salt),w={hash:g,stableHash:v,components:{...m,t:t},timestamp:(new Date).toISOString(),version:t,isIncognito:l,errors:p};return n.debug&&(console.log("[fingerprint] components:",m),console.log("[fingerprint] hash:",g,"stableHash:",v),p.length>0&&console.warn("[fingerprint] errors:",p)),w}const J=new RegExp(["googlebot","bingbot","slurp","baiduspider","duckduckbot","yandex","sogou","exabot","ia_archiver","curl","wget","python-requests","python-urllib","axios","node-fetch","go-http-client","java/","libwww-perl","okhttp","apache-httpclient","http_request","httpie","headlesschrome","phantomjs","puppeteer","playwright","cypress","selenium","webdriver","electron","jsdom","vercel-screenshot","screenshot","prerender","lighthouse","chrome-lighthouse","pagespeed","gtmetrix","pingdom","nessus","nikto","sqlmap","burp","zap","qualys","openvas","nmap","masscan","facebookexternalhit","twitterbot","linkedinbot","whatsapp","telegrambot","slackbot","discordbot","bot","crawl","spider","scrape","fetch","scan"].join("|"),"i");function X(e){return!!e&&J.test(e)}const Y=new Set(["__pre_auth__","anonymous","guest","undefined","null"]),Z="/__unshared/submit-fp",Q="__unshared_email",ee="__unshared_fp",te="__unshared_last_submit",ne="__unshared_device_id",oe="__unshared_uid",re="__unshared_sid";function ie(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=15&e[6]|64,e[8]=63&e[8]|128;const t=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function ae(e){return new Promise(t=>setTimeout(t,e))}function se(e){const t=Math.min(1e3*Math.pow(2,e-1),3e4),n=500*Math.random()-250;return Math.max(0,t+n)}function ce(e){if("undefined"==typeof document)return;const t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):void 0}function ue(e,t){"undefined"!=typeof document&&(document.cookie=`${e}=${encodeURIComponent(t)}; Path=/; SameSite=Lax`)}function le(e,t){if("undefined"!=typeof localStorage)try{localStorage.setItem(e,t)}catch{}}e.UnsharedLabsBrowser=class{constructor(e={}){if(this.o="",e.baseUrl&&!function(e){try{return new URL(e),!0}catch{return!1}}(e.baseUrl))throw new Error('baseUrl must be a valid URL (e.g. "https://app.example.com")');let t,n;this.i=e.baseUrl?e.baseUrl.replace(/\/$/,""):"",this.u=e.maxRetries??3,this.l=e.timeout??3e4,this.m=e.includePathPrefix,this.p=e.skipPaths,this.h=e.sessionId,this.v=e.deviceId,this.o=function(e){if("undefined"!=typeof sessionStorage)try{return sessionStorage.getItem(e)??void 0}catch{return}}(te)??"";try{t=this.h?.()}catch{}this.S=t??ce(re)??ie(),ue(re,this.S);try{n=this.v?.()}catch{}n?(this.C=n,le(ne,n)):this.C=function(e){if("undefined"!=typeof localStorage)try{return localStorage.getItem(e)??void 0}catch{return}}(ne)??"",this._()}async init(e){try{if("undefined"!=typeof navigator&&X(navigator.userAgent))return;if("string"==typeof(t=e.userId)&&Y.has(t))return void this.k;this.k=e.userId,this.M=e.emailAddress,"undefined"!=typeof sessionStorage&&sessionStorage.setItem(Q,e.emailAddress),ue(oe,e.userId);let n,o=this.P();o||(o=await this.collect(),this.I(o));try{n=this.v?.()}catch{}n?(this.C=n,le(ne,n)):o.fingerprint_id&&(this.C=o.fingerprint_id,le(ne,o.fingerprint_id)),this.T(o).catch(()=>{})}catch{}var t}onRouteChange(){try{if(!this.L())return;const e=this.P();if(!e)return;this.T(e).catch(()=>{})}catch{}}destroy(){try{"undefined"!=typeof sessionStorage&&(sessionStorage.removeItem(Q),sessionStorage.removeItem(ee),sessionStorage.removeItem(te)),this.o="",e=oe,"undefined"!=typeof document&&(document.cookie=`${e}=; Path=/; SameSite=Lax; Expires=Thu, 01 Jan 1970 00:00:00 GMT`),this.D&&"undefined"!=typeof document&&(document.removeEventListener("DOMContentLoaded",this.D),this.D=void 0),this.k=void 0,this.M=void 0}catch{}var e}async collect(e){const t=[...new Set(["timing","speech",...e?.exclude??[]])],n=await q({...e,exclude:t});return{fingerprint_id:n.stableHash,full_hash:n.hash,components:n.components,timestamp:n.timestamp,isIncognito:n.isIncognito,version:n.version}}async submitFingerprintEvent(e,t){try{const n=this.A(e,t),o=ie(),r=`${this.i}${Z}`;return await this.$(r,JSON.stringify(n),o)}catch(e){return{success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}L(){if("undefined"!=typeof sessionStorage)return sessionStorage.getItem(Q)??void 0}P(){if("undefined"==typeof sessionStorage)return;const e=sessionStorage.getItem(ee);if(e)try{return JSON.parse(e)}catch{return}}I(e){"undefined"!=typeof sessionStorage&&sessionStorage.setItem(ee,JSON.stringify(e))}R(){if("undefined"==typeof location)return!0;const e=location.pathname||"/";if(this.p)for(const t of this.p)if(e.startsWith(t))return!1;return!this.m||this.m.some(t=>e.startsWith(t))}async T(e){if("undefined"!=typeof navigator&&X(navigator.userAgent))return{success:!0};if(!this.R())return{success:!0};const t=this.M??this.L(),n=this.k??ce(oe),o="undefined"!=typeof location?(location.pathname||"/")+(location.search||""):"/";if(n){const e=`${n}|${o}`;if(e===this.o)return{success:!0};this.o=e,function(e,t){if("undefined"!=typeof sessionStorage)try{sessionStorage.setItem(e,t)}catch{}}(te,e)}const r={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:(new Date).toISOString(),is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.S,event_type:o};n&&(r.user_id=n),t&&(r.email=t);const i=`${e.fingerprint_id}|${n??""}|${o}`,a=`${this.i}${Z}`;return this.$(a,JSON.stringify(r),i)}_(){"undefined"!=typeof document&&(this.D&&document.removeEventListener("DOMContentLoaded",this.D),this.D=()=>{if(!this.L())return;const e=this.P();e&&this.T(e).catch(()=>{})},document.addEventListener("DOMContentLoaded",this.D))}async $(e,t,n){const o=this.u+1;let r={success:!1,error:{code:"DELIVERY_FAILED",message:"Request failed"}};for(let i=1;i<=o;i++){i>1&&await ae(se(i-1));const o=new AbortController,a=setTimeout(()=>o.abort(),this.l);try{const i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Idempotency-Key":n,"X-Session-Id":this.S,"X-Device-Id":this.C},body:t,signal:o.signal});if(clearTimeout(a),i.status>=500){r={success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${i.status}`}};continue}if(i.status>=400)return{success:!1,error:{code:"DELIVERY_FAILED",message:`Backend returned ${i.status}`}};const s=await i.text().catch(()=>"{}");let c;try{c=JSON.parse(s)}catch{c={}}return!1===c?.success?{success:!1,error:c.error??{code:"UPSTREAM_ERROR",message:"Upstream failed"}}:{success:!0,data:c?.data}}catch(e){clearTimeout(a),r={success:!1,error:{code:"DELIVERY_FAILED",message:e instanceof Error?e.message:String(e)}}}}return r}A(e,t){const n={hash:e.full_hash,stable_hash:e.fingerprint_id,collected_at:e.timestamp,is_incognito:e.isIncognito,components:e.components,version:e.version,session_id:this.S};n.user_id=t.userId,null!=t?.eventType&&(n.event_type=t.eventType);const o=this.M??this.L();return o&&(n.email=o),n}},e.createAxiosInterceptor=function(e){return t=>{if(403===t?.response?.status&&"account_flagged"===t?.response?.data?.error)try{e.onFlagged()}catch{}return Promise.reject(t)}},e.createFetchInterceptor=function(e,t){return async(...n)=>{const o=await e(...n);if(403===o.status){const e=o.clone();try{const n=await e.json();if("account_flagged"===n?.error)try{t.onFlagged()}catch{}}catch{}}return o}}});
@@ -0,0 +1 @@
1
+ export declare function isSentinelUserId(value: string | undefined | null): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unshared-frontend-sdk",
3
- "version": "2.0.0-rc.2",
3
+ "version": "2.0.0-rc.22",
4
4
  "description": "Browser SDK for Unshared Labs — routes fingerprint events through the customer's own backend",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -42,7 +42,7 @@
42
42
  "vitest": "^3.0.0"
43
43
  },
44
44
  "dependencies": {
45
- "unshared-fingerprint-lib": "1.0.0",
45
+ "unshared-fingerprint-lib": "1.3.1",
46
46
  "tslib": "^2.8.1"
47
47
  }
48
48
  }