@sssxyd/face-liveness-detector 0.2.2
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 +21 -0
- package/README.md +530 -0
- package/dist/index.esm.js +2175 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2183 -0
- package/dist/index.js.map +1 -0
- package/dist/types/__tests__/config.test.d.ts +5 -0
- package/dist/types/__tests__/config.test.d.ts.map +1 -0
- package/dist/types/__tests__/enums.test.d.ts +5 -0
- package/dist/types/__tests__/enums.test.d.ts.map +1 -0
- package/dist/types/__tests__/event-emitter.test.d.ts +5 -0
- package/dist/types/__tests__/event-emitter.test.d.ts.map +1 -0
- package/dist/types/__tests__/face-detection-engine.test.d.ts +7 -0
- package/dist/types/__tests__/face-detection-engine.test.d.ts.map +1 -0
- package/dist/types/config.d.ts +15 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/enums.d.ts +43 -0
- package/dist/types/enums.d.ts.map +1 -0
- package/dist/types/event-emitter.d.ts +48 -0
- package/dist/types/event-emitter.d.ts.map +1 -0
- package/dist/types/exports.d.ts +11 -0
- package/dist/types/exports.d.ts.map +1 -0
- package/dist/types/face-frontal-checker.d.ts +168 -0
- package/dist/types/face-frontal-checker.d.ts.map +1 -0
- package/dist/types/image-quality-checker.d.ts +65 -0
- package/dist/types/image-quality-checker.d.ts.map +1 -0
- package/dist/types/index.d.ts +200 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/library-loader.d.ts +26 -0
- package/dist/types/library-loader.d.ts.map +1 -0
- package/dist/types/types.d.ts +146 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Face Detection Engine - Core Detection Engine
|
|
3
|
+
* Framework-agnostic face liveness detection engine
|
|
4
|
+
*/
|
|
5
|
+
import type { FaceDetectionEngineConfig, FaceDetectedEventData, DetectorFinishEventData, DetectorErrorEventData, DetectorDebugEventData, StatusPromptEventData, ActionPromptEventData, EventMap, FaceFrontalFeatures, ImageQualityFeatures, EventListener } from './types';
|
|
6
|
+
import { SimpleEventEmitter } from './event-emitter';
|
|
7
|
+
/**
|
|
8
|
+
* Framework-agnostic face liveness detection engine
|
|
9
|
+
* Provides core detection logic without UI dependencies
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const engine = new FaceDetectionEngine({
|
|
14
|
+
* min_face_ratio: 0.5,
|
|
15
|
+
* max_face_ratio: 0.9,
|
|
16
|
+
* liveness_action_count: 1
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* engine.on('detector-loaded', () => {
|
|
20
|
+
* console.log('Engine ready')
|
|
21
|
+
* engine.startDetection(videoElement, canvasElement)
|
|
22
|
+
* })
|
|
23
|
+
*
|
|
24
|
+
* engine.on('detector-finish', (data) => {
|
|
25
|
+
* console.log('Liveness detection completed:', data)
|
|
26
|
+
* })
|
|
27
|
+
*
|
|
28
|
+
* engine.on('detector-error', (error) => {
|
|
29
|
+
* console.error('Detection error:', error)
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* await engine.initialize()
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class FaceDetectionEngine extends SimpleEventEmitter {
|
|
36
|
+
private config;
|
|
37
|
+
private human;
|
|
38
|
+
private stream;
|
|
39
|
+
private isDetecting;
|
|
40
|
+
private isReady;
|
|
41
|
+
private isInitializing;
|
|
42
|
+
private videoElement;
|
|
43
|
+
private frameCanvasElement;
|
|
44
|
+
private frameCanvasContext;
|
|
45
|
+
private faceCanvasElement;
|
|
46
|
+
private faceCanvasContext;
|
|
47
|
+
private detectionFrameId;
|
|
48
|
+
private actualVideoWidth;
|
|
49
|
+
private actualVideoHeight;
|
|
50
|
+
private detectionState;
|
|
51
|
+
/**
|
|
52
|
+
* Constructor
|
|
53
|
+
* @param config - Configuration object
|
|
54
|
+
*/
|
|
55
|
+
constructor(config?: Partial<FaceDetectionEngineConfig>);
|
|
56
|
+
/**
|
|
57
|
+
* Initialize the detection engine
|
|
58
|
+
* Loads Human.js and OpenCV.js libraries
|
|
59
|
+
*
|
|
60
|
+
* @returns Promise that resolves when initialization is complete
|
|
61
|
+
* @throws Error if initialization fails
|
|
62
|
+
*/
|
|
63
|
+
initialize(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Start face detection
|
|
66
|
+
* Requires initialize() to be called first and a video element to be provided
|
|
67
|
+
*
|
|
68
|
+
* @param videoElement - HTMLVideoElement to capture from
|
|
69
|
+
* @returns Promise that resolves when detection starts
|
|
70
|
+
* @throws Error if not initialized or video setup fails
|
|
71
|
+
*/
|
|
72
|
+
startDetection(videoElement: HTMLVideoElement): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* Stop face detection
|
|
75
|
+
* @param success - Whether to display the best collected image
|
|
76
|
+
*/
|
|
77
|
+
stopDetection(success: boolean): void;
|
|
78
|
+
/**
|
|
79
|
+
* Update configuration
|
|
80
|
+
* Note: Some settings may not take effect if called during detection
|
|
81
|
+
*
|
|
82
|
+
* @param config - Configuration overrides
|
|
83
|
+
*/
|
|
84
|
+
updateConfig(config: Partial<FaceDetectionEngineConfig>): void;
|
|
85
|
+
/**
|
|
86
|
+
* Get current configuration
|
|
87
|
+
* @returns Current configuration
|
|
88
|
+
*/
|
|
89
|
+
getConfig(): FaceDetectionEngineConfig;
|
|
90
|
+
/**
|
|
91
|
+
* Get detection status
|
|
92
|
+
* @returns Object with status information
|
|
93
|
+
*/
|
|
94
|
+
getStatus(): {
|
|
95
|
+
isReady: boolean;
|
|
96
|
+
isDetecting: boolean;
|
|
97
|
+
isInitializing: boolean;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Reset detection state
|
|
101
|
+
*/
|
|
102
|
+
private resetDetectionState;
|
|
103
|
+
/**
|
|
104
|
+
* Schedule next detection frame
|
|
105
|
+
*/
|
|
106
|
+
private scheduleNextDetection;
|
|
107
|
+
/**
|
|
108
|
+
* Cancel pending detection frame
|
|
109
|
+
*/
|
|
110
|
+
private cancelPendingDetection;
|
|
111
|
+
/**
|
|
112
|
+
* Main detection loop
|
|
113
|
+
*/
|
|
114
|
+
private detect;
|
|
115
|
+
private getPerformActionCount;
|
|
116
|
+
/**
|
|
117
|
+
* Handle single face detection
|
|
118
|
+
*/
|
|
119
|
+
private handleSingleFace;
|
|
120
|
+
/**
|
|
121
|
+
* Validate face box existence
|
|
122
|
+
*/
|
|
123
|
+
private validateFaceBox;
|
|
124
|
+
/**
|
|
125
|
+
* Validate face size ratio
|
|
126
|
+
*/
|
|
127
|
+
private validateFaceSize;
|
|
128
|
+
/**
|
|
129
|
+
* Validate face frontal angle
|
|
130
|
+
*/
|
|
131
|
+
private validateFaceFrontal;
|
|
132
|
+
/**
|
|
133
|
+
* Validate image quality
|
|
134
|
+
*/
|
|
135
|
+
private validateImageQuality;
|
|
136
|
+
/**
|
|
137
|
+
* Validate silent liveness scores
|
|
138
|
+
*/
|
|
139
|
+
private validateSilentLiveness;
|
|
140
|
+
/**
|
|
141
|
+
* Handle detect phase
|
|
142
|
+
*/
|
|
143
|
+
private handleDetectPhase;
|
|
144
|
+
/**
|
|
145
|
+
* Handle collect phase
|
|
146
|
+
*/
|
|
147
|
+
private handleCollectPhase;
|
|
148
|
+
/**
|
|
149
|
+
* Handle verify phase
|
|
150
|
+
*/
|
|
151
|
+
private handleVerifyPhase;
|
|
152
|
+
/**
|
|
153
|
+
* Handle multiple or no faces
|
|
154
|
+
*/
|
|
155
|
+
private handleMultipleFaces;
|
|
156
|
+
private collectHighQualityImage;
|
|
157
|
+
private emitLivenessDetected;
|
|
158
|
+
/**
|
|
159
|
+
* Select next action
|
|
160
|
+
*/
|
|
161
|
+
private selectNextAction;
|
|
162
|
+
/**
|
|
163
|
+
* Clear action verify timeout
|
|
164
|
+
*/
|
|
165
|
+
private clearActionVerifyTimeout;
|
|
166
|
+
/**
|
|
167
|
+
* Detect specific action
|
|
168
|
+
*/
|
|
169
|
+
private detectAction;
|
|
170
|
+
/**
|
|
171
|
+
* Emit status prompt event
|
|
172
|
+
*/
|
|
173
|
+
private emitStatusPrompt;
|
|
174
|
+
/**
|
|
175
|
+
* Emit debug event
|
|
176
|
+
*/
|
|
177
|
+
private emitDebug;
|
|
178
|
+
/**
|
|
179
|
+
* Draw video frame to canvas (internal use, not converted to Base64)
|
|
180
|
+
* @returns {HTMLCanvasElement | null} Canvas after drawing, returns null if failed
|
|
181
|
+
*/
|
|
182
|
+
private drawVideoToCanvas;
|
|
183
|
+
private clearFrameCanvas;
|
|
184
|
+
private clearFaceCanvas;
|
|
185
|
+
/**
|
|
186
|
+
* 将 canvas 转换为 Base64 JPEG 图片数据
|
|
187
|
+
* @param {HTMLCanvasElement} canvas - 输入的 canvas
|
|
188
|
+
* @returns {string | null} Base64 格式的 JPEG 图片数据
|
|
189
|
+
*/
|
|
190
|
+
private canvasToBase64;
|
|
191
|
+
/**
|
|
192
|
+
* Capture current video frame (returns Base64)
|
|
193
|
+
* @param {Box} box - Face box
|
|
194
|
+
* @returns {string | null} Base64 encoded JPEG image data
|
|
195
|
+
*/
|
|
196
|
+
private captureFrame;
|
|
197
|
+
}
|
|
198
|
+
export type { FaceDetectionEngineConfig, FaceFrontalFeatures, ImageQualityFeatures, StatusPromptEventData, ActionPromptEventData, FaceDetectedEventData, DetectorFinishEventData, DetectorErrorEventData, DetectorDebugEventData, EventListener, EventMap, };
|
|
199
|
+
export default FaceDetectionEngine;
|
|
200
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Face Detection Engine - Library Loader
|
|
3
|
+
* Handles loading of Human.js and OpenCV.js
|
|
4
|
+
*/
|
|
5
|
+
import Human from '@vladmandic/human';
|
|
6
|
+
import cvModule from '@techstark/opencv-js';
|
|
7
|
+
/**
|
|
8
|
+
* Load OpenCV.js
|
|
9
|
+
* @returns Promise that resolves with cv module
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadOpenCV(): Promise<{
|
|
12
|
+
cv: any;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Get OpenCV module synchronously (if already loaded)
|
|
16
|
+
* @returns cv module or null
|
|
17
|
+
*/
|
|
18
|
+
export declare function getCvSync(): typeof cvModule | null;
|
|
19
|
+
/**
|
|
20
|
+
* Load Human.js
|
|
21
|
+
* @param modelPath - Path to model files (optional)
|
|
22
|
+
* @param wasmPath - Path to WASM files (optional)
|
|
23
|
+
* @returns Promise that resolves with Human instance
|
|
24
|
+
*/
|
|
25
|
+
export declare function loadHuman(modelPath?: string, wasmPath?: string): Promise<Human>;
|
|
26
|
+
//# sourceMappingURL=library-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"library-loader.d.ts","sourceRoot":"","sources":["../src/library-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,mBAAmB,CAAA;AACrC,OAAO,QAAQ,MAAM,sBAAsB,CAAA;AAsC3C;;;GAGG;AACH,wBAAsB,UAAU;;GAwB/B;AAED;;;GAGG;AACH,wBAAgB,SAAS,2BAKxB;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAsCrF"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Face Detection Engine - Type Definitions
|
|
3
|
+
* Framework-agnostic type definitions for face liveness detection
|
|
4
|
+
*/
|
|
5
|
+
import type { LivenessAction, LivenessActionStatus, PromptCode, ErrorCode } from './enums';
|
|
6
|
+
export interface FaceFrontalFeatures {
|
|
7
|
+
yaw_threshold: number;
|
|
8
|
+
pitch_threshold: number;
|
|
9
|
+
roll_threshold: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ImageQualityFeatures {
|
|
12
|
+
require_full_face_in_bounds: boolean;
|
|
13
|
+
use_opencv_enhancement: boolean;
|
|
14
|
+
min_laplacian_variance: number;
|
|
15
|
+
min_gradient_sharpness: number;
|
|
16
|
+
min_blur_score: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Main configuration interface for FaceDetectionEngine
|
|
20
|
+
* All settings are flattened as individual properties
|
|
21
|
+
*/
|
|
22
|
+
export interface FaceDetectionEngineConfig {
|
|
23
|
+
human_model_path?: string;
|
|
24
|
+
tensorflow_wasm_path?: string;
|
|
25
|
+
video_width?: number;
|
|
26
|
+
video_height?: number;
|
|
27
|
+
video_mirror?: boolean;
|
|
28
|
+
video_load_timeout?: number;
|
|
29
|
+
detection_frame_delay?: number;
|
|
30
|
+
error_retry_delay?: number;
|
|
31
|
+
silent_detect_count?: number;
|
|
32
|
+
min_face_ratio?: number;
|
|
33
|
+
max_face_ratio?: number;
|
|
34
|
+
min_face_frontal?: number;
|
|
35
|
+
min_image_quality?: number;
|
|
36
|
+
min_live_score?: number;
|
|
37
|
+
min_real_score?: number;
|
|
38
|
+
suspected_frauds_count?: number;
|
|
39
|
+
face_frontal_features?: FaceFrontalFeatures;
|
|
40
|
+
image_quality_features?: ImageQualityFeatures;
|
|
41
|
+
liveness_action_list?: LivenessAction[];
|
|
42
|
+
liveness_action_count?: number;
|
|
43
|
+
liveness_action_randomize?: boolean;
|
|
44
|
+
liveness_verify_timeout?: number;
|
|
45
|
+
min_mouth_open_percent?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface ResolvedEngineConfig {
|
|
48
|
+
human_model_path: string;
|
|
49
|
+
tensorflow_wasm_path: string;
|
|
50
|
+
video_width: number;
|
|
51
|
+
video_height: number;
|
|
52
|
+
video_mirror: boolean;
|
|
53
|
+
video_load_timeout: number;
|
|
54
|
+
detection_frame_delay: number;
|
|
55
|
+
error_retry_delay: number;
|
|
56
|
+
silent_detect_count: number;
|
|
57
|
+
min_face_ratio: number;
|
|
58
|
+
max_face_ratio: number;
|
|
59
|
+
min_face_frontal: number;
|
|
60
|
+
min_image_quality: number;
|
|
61
|
+
min_real_score: number;
|
|
62
|
+
min_live_score: number;
|
|
63
|
+
suspected_frauds_count: number;
|
|
64
|
+
face_frontal_features: FaceFrontalFeatures;
|
|
65
|
+
image_quality_features: ImageQualityFeatures;
|
|
66
|
+
liveness_action_list: LivenessAction[];
|
|
67
|
+
liveness_action_count: number;
|
|
68
|
+
liveness_action_randomize: boolean;
|
|
69
|
+
liveness_verify_timeout: number;
|
|
70
|
+
min_mouth_open_percent: number;
|
|
71
|
+
}
|
|
72
|
+
export interface DetectorLoadedEventData {
|
|
73
|
+
success: boolean;
|
|
74
|
+
error?: string;
|
|
75
|
+
opencv_version?: string;
|
|
76
|
+
human_version?: string;
|
|
77
|
+
}
|
|
78
|
+
export interface StatusPromptEventData {
|
|
79
|
+
code: PromptCode;
|
|
80
|
+
size?: number;
|
|
81
|
+
frontal?: number;
|
|
82
|
+
real?: number;
|
|
83
|
+
live?: number;
|
|
84
|
+
quality?: number;
|
|
85
|
+
}
|
|
86
|
+
export interface ActionPromptEventData {
|
|
87
|
+
action: LivenessAction;
|
|
88
|
+
status: LivenessActionStatus;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Silent liveness detection data
|
|
92
|
+
*/
|
|
93
|
+
export interface FaceDetectedEventData {
|
|
94
|
+
passed: boolean;
|
|
95
|
+
size: number;
|
|
96
|
+
frontal: number;
|
|
97
|
+
quality: number;
|
|
98
|
+
real: number;
|
|
99
|
+
live: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Action/silent liveness detection completion data
|
|
103
|
+
*/
|
|
104
|
+
export interface DetectorFinishEventData {
|
|
105
|
+
success: boolean;
|
|
106
|
+
silentPassedCount: number;
|
|
107
|
+
actionPassedCount: number;
|
|
108
|
+
totalTime: number;
|
|
109
|
+
bestQualityScore: number;
|
|
110
|
+
bestFrameImage: string | null;
|
|
111
|
+
bestFaceImage: string | null;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Error data
|
|
115
|
+
*/
|
|
116
|
+
export interface DetectorErrorEventData {
|
|
117
|
+
code: ErrorCode;
|
|
118
|
+
message: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Debug information data
|
|
122
|
+
*/
|
|
123
|
+
export interface DetectorDebugEventData {
|
|
124
|
+
level: 'info' | 'warn' | 'error';
|
|
125
|
+
stage: string;
|
|
126
|
+
message: string;
|
|
127
|
+
details?: Record<string, any>;
|
|
128
|
+
timestamp: number;
|
|
129
|
+
}
|
|
130
|
+
export type EventListener<T> = (data: T) => void;
|
|
131
|
+
export interface EventEmitter {
|
|
132
|
+
on<K extends keyof EventMap>(event: K, listener: EventListener<EventMap[K]>): void;
|
|
133
|
+
off<K extends keyof EventMap>(event: K, listener: EventListener<EventMap[K]>): void;
|
|
134
|
+
once<K extends keyof EventMap>(event: K, listener: EventListener<EventMap[K]>): void;
|
|
135
|
+
emit<K extends keyof EventMap>(event: K, data: EventMap[K]): void;
|
|
136
|
+
}
|
|
137
|
+
export interface EventMap {
|
|
138
|
+
'detector-loaded': DetectorLoadedEventData;
|
|
139
|
+
'status-prompt': StatusPromptEventData;
|
|
140
|
+
'face-detected': FaceDetectedEventData;
|
|
141
|
+
'action-prompt': ActionPromptEventData;
|
|
142
|
+
'detector-finish': DetectorFinishEventData;
|
|
143
|
+
'detector-error': DetectorErrorEventData;
|
|
144
|
+
'detector-debug': DetectorDebugEventData;
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sssxyd/face-liveness-detector",
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Pure JS/TS implementation of liveness face detection based on human.js and opencv.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.esm.js",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"types": "./types/index.d.ts"
|
|
13
|
+
},
|
|
14
|
+
"./config": {
|
|
15
|
+
"import": "./dist/config.esm.js",
|
|
16
|
+
"require": "./dist/config.js",
|
|
17
|
+
"types": "./types/config.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"./types": {
|
|
20
|
+
"import": "./dist/types.esm.js",
|
|
21
|
+
"require": "./dist/types.js",
|
|
22
|
+
"types": "./types/types.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"types",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "rollup -c rollup.config.js",
|
|
33
|
+
"build:watch": "rollup -c rollup.config.js -w",
|
|
34
|
+
"dev": "npm run build:watch",
|
|
35
|
+
"clean": "rm -rf dist types",
|
|
36
|
+
"type-check": "tsc --noEmit",
|
|
37
|
+
"test": "jest",
|
|
38
|
+
"test:watch": "jest --watch",
|
|
39
|
+
"test:coverage": "jest --coverage"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"face-detection",
|
|
43
|
+
"liveness-detection",
|
|
44
|
+
"face-recognition",
|
|
45
|
+
"anti-spoofing",
|
|
46
|
+
"typescript"
|
|
47
|
+
],
|
|
48
|
+
"author": "xuyd <sssxyd@gmail.com>",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@techstark/opencv-js": "^4.12.0-release.1",
|
|
52
|
+
"@vladmandic/human": "^3.3.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@babel/preset-env": "^7.28.5",
|
|
56
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
57
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
58
|
+
"@rollup/plugin-node-resolve": "^15.1.0",
|
|
59
|
+
"@rollup/plugin-typescript": "^11.1.5",
|
|
60
|
+
"@types/jest": "^30.0.0",
|
|
61
|
+
"@types/node": "^20.8.0",
|
|
62
|
+
"jest": "^30.2.0",
|
|
63
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
64
|
+
"rollup": "^3.29.4",
|
|
65
|
+
"ts-jest": "^29.4.5",
|
|
66
|
+
"tslib": "^2.8.1",
|
|
67
|
+
"typescript": "^5.2.2"
|
|
68
|
+
},
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "https://github.com/sssxyd/face-liveness-detector.git"
|
|
72
|
+
},
|
|
73
|
+
"bugs": {
|
|
74
|
+
"url": "https://github.com/sssxyd/face-liveness-detector/issues"
|
|
75
|
+
},
|
|
76
|
+
"homepage": "https://github.com/sssxyd/face-liveness-detector#readme"
|
|
77
|
+
}
|