@keverdjs/fraud-sdk-react 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Keverd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,340 @@
1
+ # @keverdjs/fraud-sdk-react
2
+
3
+ React SDK for Keverd fraud detection and device fingerprinting. This SDK provides real-time risk assessment by analyzing device characteristics, behavioral biometrics, and session patterns.
4
+
5
+ ## Installation
6
+
7
+ Install the package via npm or yarn:
8
+
9
+ ```bash
10
+ npm install @keverdjs/fraud-sdk-react
11
+ ```
12
+
13
+ or
14
+
15
+ ```bash
16
+ yarn add @keverdjs/fraud-sdk-react
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ### 1. Wrap your application with KeverdProvider
22
+
23
+ In your `_app.tsx` (Next.js) or root component:
24
+
25
+ ```tsx
26
+ import { KeverdProvider } from '@keverdjs/fraud-sdk-react';
27
+
28
+ function MyApp({ Component, pageProps }) {
29
+ return (
30
+ <KeverdProvider
31
+ loadOptions={{
32
+ apiKey: 'your-api-key-here',
33
+ }}
34
+ >
35
+ <Component {...pageProps} />
36
+ </KeverdProvider>
37
+ );
38
+ }
39
+
40
+ export default MyApp;
41
+ ```
42
+
43
+ ### 2. Use the hook in your components
44
+
45
+ ```tsx
46
+ import { useKeverdVisitorData } from '@keverdjs/fraud-sdk-react';
47
+
48
+ export default function Home() {
49
+ const { isLoading, error, data, getData } = useKeverdVisitorData({
50
+ immediate: true, // Automatically fetch on mount
51
+ extendedResult: true,
52
+ });
53
+
54
+ if (isLoading) return <div>Loading...</div>;
55
+ if (error) return <div>Error: {error.message}</div>;
56
+
57
+ return (
58
+ <div>
59
+ <h1>Risk Score: {data?.riskScore}%</h1>
60
+ <p>Action: {data?.action}</p>
61
+ <p>Reasons: {data?.reasons.join(', ')}</p>
62
+ <button onClick={() => getData()}>Refresh Data</button>
63
+ </div>
64
+ );
65
+ }
66
+ ```
67
+
68
+ ## API Reference
69
+
70
+ ### KeverdProvider
71
+
72
+ The provider component that initializes the SDK and makes it available to child components.
73
+
74
+ **Props:**
75
+
76
+ ```typescript
77
+ interface KeverdProviderProps {
78
+ loadOptions: KeverdLoadOptions;
79
+ children: React.ReactNode;
80
+ }
81
+ ```
82
+
83
+ **KeverdLoadOptions:**
84
+
85
+ ```typescript
86
+ interface KeverdLoadOptions {
87
+ apiKey: string; // Required: Your Keverd API key
88
+ endpoint?: string; // Optional: Custom API endpoint (default: https://app.keverd.com)
89
+ debug?: boolean; // Optional: Enable debug logging (default: false)
90
+ }
91
+ ```
92
+
93
+ ### useKeverdVisitorData
94
+
95
+ Hook to access visitor data and risk assessment results.
96
+
97
+ **Usage:**
98
+
99
+ ```tsx
100
+ const {
101
+ data, // KeverdVisitorData | null
102
+ isLoading, // boolean
103
+ error, // KeverdError | null
104
+ getData // () => Promise<void>
105
+ } = useKeverdVisitorData(options?);
106
+ ```
107
+
108
+ **Options:**
109
+
110
+ ```typescript
111
+ interface KeverdVisitorDataHookOptions {
112
+ extendedResult?: boolean; // Include extended device/session info (default: false)
113
+ immediate?: boolean; // Automatically fetch data on mount (default: false)
114
+ ignoreCache?: boolean; // Ignore cached data (default: false)
115
+ }
116
+ ```
117
+
118
+ **Return Value:**
119
+
120
+ ```typescript
121
+ interface KeverdVisitorDataResult {
122
+ isLoading: boolean; // Loading state
123
+ error: KeverdError | null; // Error if any
124
+ data: KeverdVisitorData | null; // Visitor data
125
+ getData: (options?: KeverdVisitorDataOptions) => Promise<KeverdVisitorData>;
126
+ }
127
+
128
+ interface KeverdVisitorData {
129
+ visitorId: string;
130
+ riskScore: number; // 0-100
131
+ score: number; // 0.0-1.0
132
+ action: 'allow' | 'soft_challenge' | 'hard_challenge' | 'block';
133
+ reasons: string[]; // Array of risk reasons
134
+ sessionId: string; // Session identifier
135
+ requestId: string; // Request identifier
136
+ simSwapEngine?: KeverdSimSwapEngine; // SIM swap detection (null for web)
137
+ confidence?: number; // Confidence score (if available)
138
+ }
139
+ ```
140
+
141
+ ### useKeverdContext
142
+
143
+ Hook to access the underlying SDK instance (for advanced usage).
144
+
145
+ ```tsx
146
+ import { useKeverdContext } from '@keverdjs/fraud-sdk-react';
147
+
148
+ const sdk = useKeverdContext();
149
+ // Use sdk methods directly
150
+ ```
151
+
152
+ ## Configuration
153
+
154
+ ### Custom Endpoint
155
+
156
+ If you're using a custom backend endpoint:
157
+
158
+ ```tsx
159
+ <KeverdProvider
160
+ loadOptions={{
161
+ apiKey: 'your-api-key',
162
+ endpoint: 'https://api.yourdomain.com/v1/fingerprint/score',
163
+ }}
164
+ >
165
+ {children}
166
+ </KeverdProvider>
167
+ ```
168
+
169
+ ### Debug Mode
170
+
171
+ Enable debug logging for development:
172
+
173
+ ```tsx
174
+ <KeverdProvider
175
+ loadOptions={{
176
+ apiKey: 'your-api-key',
177
+ debug: true,
178
+ }}
179
+ >
180
+ {children}
181
+ </KeverdProvider>
182
+ ```
183
+
184
+ ## Data Collection
185
+
186
+ The SDK automatically collects:
187
+
188
+ - **Device Information**: Screen resolution, timezone, language, user agent
189
+ - **Device Fingerprinting**: Canvas, WebGL fingerprints
190
+ - **Behavioral Biometrics**: Typing patterns, mouse movements, scroll behavior
191
+ - **Session Information**: Session duration, page views, interactions
192
+
193
+ **Note**: SIM data is not collected for web applications (only for mobile SDKs).
194
+
195
+ ## Error Handling
196
+
197
+ The SDK provides error information through the `error` property:
198
+
199
+ ```tsx
200
+ const { error } = useKeverdVisitorData();
201
+
202
+ if (error) {
203
+ switch (error.code) {
204
+ case 'NETWORK_ERROR':
205
+ // Handle network issues
206
+ break;
207
+ case 'INVALID_API_KEY':
208
+ // Handle invalid API key
209
+ break;
210
+ case 'SDK_NOT_INITIALIZED':
211
+ // SDK not initialized
212
+ break;
213
+ default:
214
+ // Handle other errors
215
+ }
216
+ }
217
+ ```
218
+
219
+ ## TypeScript Support
220
+
221
+ The SDK is written in TypeScript and includes full type definitions. All types are exported for use in your code:
222
+
223
+ ```typescript
224
+ import type {
225
+ KeverdConfig,
226
+ KeverdLoadOptions,
227
+ KeverdVisitorData,
228
+ KeverdVisitorDataOptions,
229
+ KeverdVisitorDataHookOptions,
230
+ KeverdVisitorDataResult,
231
+ KeverdDeviceInfo,
232
+ KeverdSessionInfo,
233
+ KeverdBehavioralData,
234
+ KeverdError,
235
+ } from '@keverdjs/fraud-sdk-react';
236
+
237
+ ## Next.js Integration
238
+
239
+ The SDK works seamlessly with Next.js. Wrap your app in `_app.tsx`:
240
+
241
+ ```tsx
242
+ // pages/_app.tsx
243
+ import type { AppProps } from 'next/app';
244
+ import { KeverdProvider } from '@keverdjs/fraud-sdk-react';
245
+
246
+ function MyApp({ Component, pageProps }: AppProps) {
247
+ return (
248
+ <KeverdProvider
249
+ loadOptions={{
250
+ apiKey: process.env.NEXT_PUBLIC_KEVERD_API_KEY!,
251
+ }}
252
+ >
253
+ <Component {...pageProps} />
254
+ </KeverdProvider>
255
+ );
256
+ }
257
+
258
+ export default MyApp;
259
+ ```
260
+
261
+ For Next.js App Router, wrap your root layout:
262
+
263
+ ```tsx
264
+ // app/layout.tsx
265
+ import { KeverdProvider } from '@keverdjs/fraud-sdk-react';
266
+
267
+ export default function RootLayout({
268
+ children,
269
+ }: {
270
+ children: React.ReactNode;
271
+ }) {
272
+ return (
273
+ <html>
274
+ <body>
275
+ <KeverdProvider
276
+ loadOptions={{
277
+ apiKey: process.env.NEXT_PUBLIC_KEVERD_API_KEY!,
278
+ }}
279
+ >
280
+ {children}
281
+ </KeverdProvider>
282
+ </body>
283
+ </html>
284
+ );
285
+ }
286
+ ```
287
+
288
+ ## Advanced Usage
289
+
290
+ ### Manual Data Collection
291
+
292
+ You can access the SDK instance directly for manual operations:
293
+
294
+ ```tsx
295
+ import { useKeverdContext } from '@keverdjs/fraud-sdk-react';
296
+
297
+ function MyComponent() {
298
+ const sdk = useKeverdContext();
299
+
300
+ const handleManualCheck = async () => {
301
+ const result = await sdk.getVisitorData({ extendedResult: true });
302
+ console.log('Risk assessment:', result);
303
+ };
304
+
305
+ return <button onClick={handleManualCheck}>Check Risk</button>;
306
+ }
307
+ ```
308
+
309
+ ### Using Collectors Directly
310
+
311
+ For advanced use cases, you can use collectors directly:
312
+
313
+ ```tsx
314
+ import { KeverdDeviceCollector, KeverdBehavioralCollector } from '@keverd/fraud-sdk-react';
315
+
316
+ const deviceCollector = new KeverdDeviceCollector();
317
+ const behavioralCollector = new KeverdBehavioralCollector();
318
+
319
+ // Start collectors
320
+ behavioralCollector.start();
321
+
322
+ // Collect data manually
323
+ const deviceInfo = deviceCollector.collect();
324
+ const behavioralData = behavioralCollector.getData();
325
+ ```
326
+
327
+ ## Browser Support
328
+
329
+ - Chrome (latest)
330
+ - Firefox (latest)
331
+ - Safari (latest)
332
+ - Edge (latest)
333
+
334
+ ## License
335
+
336
+ MIT
337
+
338
+ ## Support
339
+
340
+ For issues, questions, or contributions, please visit the [GitHub repository](https://github.com/keverd/keverd-fraud-sdk-web).
@@ -0,0 +1,365 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ /**
5
+ * Keverd Fraud SDK React - Type Definitions
6
+ */
7
+ interface KeverdDeviceInfo {
8
+ deviceId: string;
9
+ fingerprint: string;
10
+ manufacturer?: string;
11
+ model?: string;
12
+ brand?: string;
13
+ device?: string;
14
+ product?: string;
15
+ hardware?: string;
16
+ sdkVersion?: string;
17
+ osVersion?: string;
18
+ screenWidth?: string;
19
+ screenHeight?: string;
20
+ screenDensity?: string;
21
+ locale?: string;
22
+ timezone: string;
23
+ }
24
+ interface KeverdSessionInfo {
25
+ sessionId?: string;
26
+ installId?: string;
27
+ sessionCount?: string;
28
+ firstSession?: string;
29
+ timestamp?: string;
30
+ }
31
+ interface KeverdBehavioralData {
32
+ typing_dwell_ms?: number[];
33
+ typing_flight_ms?: number[];
34
+ swipe_velocity?: number;
35
+ session_entropy?: number;
36
+ }
37
+ interface KeverdFingerprintRequest {
38
+ userId?: string;
39
+ device: KeverdDeviceInfo;
40
+ session?: KeverdSessionInfo;
41
+ behavioral?: KeverdBehavioralData;
42
+ }
43
+ interface KeverdSimSwapEngine {
44
+ userId?: string;
45
+ risk: number;
46
+ flags: {
47
+ sim_changed?: boolean;
48
+ device_changed?: boolean;
49
+ behavior_anomaly?: boolean;
50
+ time_anomaly?: boolean;
51
+ velocity_anomaly?: boolean;
52
+ };
53
+ updatedProfile?: Record<string, unknown>;
54
+ }
55
+ interface KeverdFingerprintResponse {
56
+ risk_score: number;
57
+ score: number;
58
+ action: 'allow' | 'soft_challenge' | 'hard_challenge' | 'block';
59
+ reason: string[];
60
+ session_id: string;
61
+ requestId: string;
62
+ sim_swap_engine?: KeverdSimSwapEngine;
63
+ }
64
+ interface KeverdVisitorData {
65
+ visitorId: string;
66
+ riskScore: number;
67
+ score: number;
68
+ action: 'allow' | 'soft_challenge' | 'hard_challenge' | 'block';
69
+ reasons: string[];
70
+ sessionId: string;
71
+ requestId: string;
72
+ simSwapEngine?: KeverdSimSwapEngine;
73
+ confidence?: number;
74
+ }
75
+ interface KeverdConfig {
76
+ apiKey: string;
77
+ endpoint?: string;
78
+ userId?: string;
79
+ debug?: boolean;
80
+ extendedResult?: boolean;
81
+ ignoreCache?: boolean;
82
+ }
83
+ interface KeverdLoadOptions {
84
+ apiKey: string;
85
+ endpoint?: string;
86
+ debug?: boolean;
87
+ }
88
+ interface KeverdVisitorDataOptions {
89
+ extendedResult?: boolean;
90
+ ignoreCache?: boolean;
91
+ tag?: string;
92
+ }
93
+ interface KeverdVisitorDataHookOptions {
94
+ extendedResult?: boolean;
95
+ immediate?: boolean;
96
+ ignoreCache?: boolean;
97
+ }
98
+ interface KeverdError {
99
+ message: string;
100
+ code?: string;
101
+ statusCode?: number;
102
+ }
103
+ interface KeverdVisitorDataResult$1 {
104
+ isLoading: boolean;
105
+ error: KeverdError | null;
106
+ data: KeverdVisitorData | null;
107
+ getData: (options?: KeverdVisitorDataOptions) => Promise<KeverdVisitorData>;
108
+ }
109
+
110
+ /**
111
+ * Keverd Fraud SDK Core
112
+ * Main SDK class for fingerprinting and risk assessment
113
+ */
114
+
115
+ declare class KeverdSDK {
116
+ private config;
117
+ private deviceCollector;
118
+ private behavioralCollector;
119
+ private isInitialized;
120
+ private sessionId;
121
+ constructor();
122
+ /**
123
+ * Initialize the SDK with configuration
124
+ */
125
+ init(config: KeverdConfig): void;
126
+ /**
127
+ * Get visitor data (fingerprint and risk assessment)
128
+ */
129
+ getVisitorData(options?: KeverdVisitorDataOptions): Promise<KeverdVisitorData>;
130
+ /**
131
+ * Send fingerprint request to backend
132
+ */
133
+ private sendFingerprintRequest;
134
+ /**
135
+ * Transform API response to visitor data format
136
+ */
137
+ private transformResponse;
138
+ /**
139
+ * Get default endpoint
140
+ */
141
+ private getDefaultEndpoint;
142
+ /**
143
+ * Generate a session ID
144
+ */
145
+ private generateSessionId;
146
+ /**
147
+ * Destroy the SDK instance
148
+ */
149
+ destroy(): void;
150
+ /**
151
+ * Get current configuration
152
+ */
153
+ getConfig(): KeverdConfig | null;
154
+ /**
155
+ * Check if SDK is initialized
156
+ */
157
+ isReady(): boolean;
158
+ }
159
+
160
+ interface KeverdContextValue {
161
+ sdk: KeverdSDK;
162
+ isReady: boolean;
163
+ }
164
+ interface KeverdProviderProps {
165
+ loadOptions: KeverdLoadOptions;
166
+ children: ReactNode;
167
+ }
168
+ /**
169
+ * KeverdProvider - Wrap your app with this component to enable Keverd SDK
170
+ */
171
+ declare function KeverdProvider({ loadOptions, children }: KeverdProviderProps): react_jsx_runtime.JSX.Element;
172
+ /**
173
+ * Hook to access Keverd SDK from context
174
+ */
175
+ declare function useKeverdContext(): KeverdContextValue;
176
+
177
+ /**
178
+ * useKeverdVisitorData Hook
179
+ * React hook for accessing visitor data and risk assessment
180
+ */
181
+
182
+ interface KeverdVisitorDataResult {
183
+ isLoading: boolean;
184
+ error: KeverdError | null;
185
+ data: KeverdVisitorData | null;
186
+ getData: (options?: KeverdVisitorDataOptions) => Promise<KeverdVisitorData>;
187
+ }
188
+ /**
189
+ * Hook to get visitor data and risk assessment
190
+ *
191
+ * @param options - Configuration options for the hook
192
+ * @returns Object containing loading state, error, data, and getData function
193
+ *
194
+ * @example
195
+ * ```tsx
196
+ * function MyComponent() {
197
+ * const { isLoading, error, data, getData } = useKeverdVisitorData({
198
+ * extendedResult: true,
199
+ * immediate: true
200
+ * });
201
+ *
202
+ * if (isLoading) return <div>Loading...</div>;
203
+ * if (error) return <div>Error: {error.message}</div>;
204
+ *
205
+ * return (
206
+ * <div>
207
+ * <p>Risk Score: {data?.riskScore}</p>
208
+ * <p>Action: {data?.action}</p>
209
+ * <button onClick={() => getData({ ignoreCache: true })}>
210
+ * Reload data
211
+ * </button>
212
+ * </div>
213
+ * );
214
+ * }
215
+ * ```
216
+ */
217
+ declare function useKeverdVisitorData(options?: KeverdVisitorDataHookOptions): KeverdVisitorDataResult;
218
+
219
+ /**
220
+ * Keverd Device Fingerprint Collector
221
+ * Collects device information, canvas fingerprint, WebGL fingerprint, and generates a stable device ID
222
+ */
223
+
224
+ declare class KeverdDeviceCollector {
225
+ private cachedDeviceInfo;
226
+ /**
227
+ * Collect all device information and generate fingerprint
228
+ */
229
+ collect(): KeverdDeviceInfo;
230
+ /**
231
+ * Generate a stable device fingerprint using multiple browser characteristics
232
+ * Returns SHA-256 hash (64 hex characters) as required by backend
233
+ */
234
+ private generateDeviceFingerprint;
235
+ /**
236
+ * Generate canvas fingerprint
237
+ */
238
+ private getCanvasFingerprint;
239
+ /**
240
+ * Generate WebGL fingerprint
241
+ */
242
+ private getWebGLFingerprint;
243
+ /**
244
+ * Generate a stable device ID from fingerprint
245
+ */
246
+ private generateDeviceId;
247
+ /**
248
+ * Get manufacturer from user agent
249
+ */
250
+ private getManufacturer;
251
+ /**
252
+ * Get model from user agent
253
+ */
254
+ private getModel;
255
+ /**
256
+ * Get brand from user agent
257
+ */
258
+ private getBrand;
259
+ /**
260
+ * Get device type
261
+ */
262
+ private getDevice;
263
+ /**
264
+ * Get product name
265
+ */
266
+ private getProduct;
267
+ /**
268
+ * Get hardware info
269
+ */
270
+ private getHardware;
271
+ /**
272
+ * Get OS version
273
+ */
274
+ private getOSVersion;
275
+ /**
276
+ * Get screen density
277
+ */
278
+ private getScreenDensity;
279
+ /**
280
+ * Hash a string using SHA-256 (required for backend compatibility)
281
+ * Backend expects SHA-256 hash (64 hex characters)
282
+ * Uses Web Crypto API synchronously via a cached approach
283
+ */
284
+ private hashString;
285
+ /**
286
+ * SHA-256-like hash function (synchronous, deterministic)
287
+ * Produces 64-character hex string matching SHA-256 format
288
+ * This is a deterministic hash that mimics SHA-256 characteristics
289
+ */
290
+ private sha256LikeHash;
291
+ /**
292
+ * Clear cached device info (useful for testing)
293
+ */
294
+ clearCache(): void;
295
+ }
296
+
297
+ /**
298
+ * Keverd Behavioral Data Collector
299
+ * Collects typing patterns, mouse movements, swipe gestures, and calculates session entropy
300
+ */
301
+
302
+ declare class KeverdBehavioralCollector {
303
+ private keystrokes;
304
+ private mouseMovements;
305
+ private lastKeyDownTime;
306
+ private lastKeyUpTime;
307
+ private isActive;
308
+ private sessionStartTime;
309
+ private typingDwellTimes;
310
+ private typingFlightTimes;
311
+ private swipeVelocities;
312
+ private sessionEvents;
313
+ private touchStartPositions;
314
+ private keyDownHandler;
315
+ private keyUpHandler;
316
+ private mouseMoveHandler;
317
+ private touchStartHandler;
318
+ private touchEndHandler;
319
+ /**
320
+ * Start collecting behavioral data
321
+ */
322
+ start(): void;
323
+ /**
324
+ * Stop collecting behavioral data
325
+ */
326
+ stop(): void;
327
+ /**
328
+ * Get collected behavioral data
329
+ */
330
+ getData(): KeverdBehavioralData;
331
+ /**
332
+ * Reset collected data
333
+ */
334
+ reset(): void;
335
+ /**
336
+ * Handle keydown event
337
+ */
338
+ private handleKeyDown;
339
+ /**
340
+ * Handle keyup event
341
+ */
342
+ private handleKeyUp;
343
+ /**
344
+ * Handle mouse move event
345
+ */
346
+ private handleMouseMove;
347
+ /**
348
+ * Handle touch start (for swipe detection)
349
+ */
350
+ private handleTouchStart;
351
+ /**
352
+ * Handle touch end (calculate swipe velocity)
353
+ */
354
+ private handleTouchEnd;
355
+ /**
356
+ * Calculate session entropy based on event diversity
357
+ */
358
+ private calculateSessionEntropy;
359
+ /**
360
+ * Check if key should be ignored
361
+ */
362
+ private shouldIgnoreKey;
363
+ }
364
+
365
+ export { KeverdBehavioralCollector, type KeverdBehavioralData, type KeverdConfig, KeverdDeviceCollector, type KeverdDeviceInfo, type KeverdError, type KeverdFingerprintRequest, type KeverdFingerprintResponse, type KeverdLoadOptions, KeverdProvider, KeverdSDK, type KeverdSessionInfo, type KeverdSimSwapEngine, type KeverdVisitorData, type KeverdVisitorDataHookOptions, type KeverdVisitorDataOptions, type KeverdVisitorDataResult$1 as KeverdVisitorDataResult, useKeverdContext, useKeverdVisitorData };