@authme/identity-verification 2.8.37 → 2.8.41
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/assets/locale/en_US.json +3 -2
- package/assets/locale/ja_JP.json +3 -2
- package/assets/locale/zh_Hant_TW.json +3 -2
- package/index.cjs +72 -48
- package/index.js +72 -48
- package/package.json +6 -6
- package/src/lib/interface/config.interface.d.ts +1 -0
package/assets/locale/en_US.json
CHANGED
|
@@ -193,6 +193,7 @@
|
|
|
193
193
|
"sdk.general.verify.error.getCloser": "Move closer",
|
|
194
194
|
"sdk.general.verify.error.missmatch": "Align your ID within the frame",
|
|
195
195
|
"sdk.general.verify.error.motion": "Please keep the ID card and the device still",
|
|
196
|
+
"sdk.liveness.detection.motion": "Please keep your face and device still",
|
|
196
197
|
"sdk.general.verify.error.needCloseMouth": "Close your mouth",
|
|
197
198
|
"sdk.general.verify.error.needDeformationFrontal": "Align the card with the designated shape",
|
|
198
199
|
"sdk.general.verify.error.needFaceToCamera": "Look straight ahead",
|
|
@@ -209,7 +210,7 @@
|
|
|
209
210
|
"sdk.general.verify.error.stagePass": "Starting next direction",
|
|
210
211
|
"sdk.general.verify.error.switchCamera": "Blurry document? Tap to switch the camera",
|
|
211
212
|
"sdk.general.verify.error.wrongCardType": "Wrong document",
|
|
212
|
-
"sdk.general.verify.success": "
|
|
213
|
+
"sdk.general.verify.success": "Identifying...",
|
|
213
214
|
"sdk.guard.verify.allowCamera": "Please allow camera access for identity verification",
|
|
214
215
|
"sdk.guard.verify.content.step1": "Please hold the ID within the frame, ensure the edges are not obscured, and verify the document is clear and without glare.\n\n\n\n\n\n\n",
|
|
215
216
|
"sdk.guard.verify.guide.fraudDescribe": "Please hold your ID, follow the animation prompts to flip it, and make sure each angle turns into a green frame before proceeding",
|
|
@@ -233,7 +234,7 @@
|
|
|
233
234
|
"sdk.liveness.detection.header": "Liveness Detection",
|
|
234
235
|
"sdk.liveness.detection.infopageHint.environment": "Detect in well-lit area",
|
|
235
236
|
"sdk.liveness.detection.infopageHint.face": "Please ensure there are no obstructions on your face",
|
|
236
|
-
"sdk.liveness.detection.needMoreFrame": "
|
|
237
|
+
"sdk.liveness.detection.needMoreFrame": "Identifying...",
|
|
237
238
|
"sdk.liveness.detection.step": "Position your face within the frame",
|
|
238
239
|
"sdk.liveness.detection.subtitle": "Ready to start capturing your face",
|
|
239
240
|
"sdk.liveness.detection.title": "Face Verification",
|
package/assets/locale/ja_JP.json
CHANGED
|
@@ -193,6 +193,7 @@
|
|
|
193
193
|
"sdk.general.verify.error.getCloser": "もっと近づけてください",
|
|
194
194
|
"sdk.general.verify.error.missmatch": "書類を枠内に入れて撮影してください",
|
|
195
195
|
"sdk.general.verify.error.motion": "身分証明書とデバイスを動かさずに静止させてください",
|
|
196
|
+
"sdk.liveness.detection.motion": "顔とデバイスを静止させてください",
|
|
196
197
|
"sdk.general.verify.error.needCloseMouth": "口を閉じてください",
|
|
197
198
|
"sdk.general.verify.error.needDeformationFrontal": "ガイド枠にカードを合わせてください。",
|
|
198
199
|
"sdk.general.verify.error.needFaceToCamera": "カメラに向かって",
|
|
@@ -209,7 +210,7 @@
|
|
|
209
210
|
"sdk.general.verify.error.stagePass": "次の方向へ進み始めます",
|
|
210
211
|
"sdk.general.verify.error.switchCamera": "身分証がぼやけていませんか?\nクリックしてレンズを切り替えましょう",
|
|
211
212
|
"sdk.general.verify.error.wrongCardType": "誤った書類です",
|
|
212
|
-
"sdk.general.verify.success": "
|
|
213
|
+
"sdk.general.verify.success": "識別中です...",
|
|
213
214
|
"sdk.guard.verify.allowCamera": "カメラへのアクセスを許可して身分認証を行ってください",
|
|
214
215
|
"sdk.guard.verify.content.step1": "書類を手に持ち枠内に置いてください。枠を覆わないようにし、証明書がはっきりして反射していないことを確認してください\"。",
|
|
215
216
|
"sdk.guard.verify.guide.fraudDescribe": "身分証明書を手に持ち、アニメーションの指示に従って回転させてください。すべての角度が緑の枠になると通過できます",
|
|
@@ -233,7 +234,7 @@
|
|
|
233
234
|
"sdk.liveness.detection.header": "顔認証",
|
|
234
235
|
"sdk.liveness.detection.infopageHint.environment": "明るい場所で撮影してください",
|
|
235
236
|
"sdk.liveness.detection.infopageHint.face": "顔には何も覆っていないことを確認してください",
|
|
236
|
-
"sdk.liveness.detection.needMoreFrame": "
|
|
237
|
+
"sdk.liveness.detection.needMoreFrame": "識別中です...",
|
|
237
238
|
"sdk.liveness.detection.step": "顔を枠内に入れます",
|
|
238
239
|
"sdk.liveness.detection.subtitle": "顔写真撮影を行います",
|
|
239
240
|
"sdk.liveness.detection.title": "顔認識",
|
|
@@ -193,6 +193,7 @@
|
|
|
193
193
|
"sdk.general.verify.error.getCloser": "靠近一點",
|
|
194
194
|
"sdk.general.verify.error.missmatch": "請將證件置於框內",
|
|
195
195
|
"sdk.general.verify.error.motion": "請保持身分證與裝置靜止",
|
|
196
|
+
"sdk.liveness.detection.motion": "請保持人臉和裝置靜止",
|
|
196
197
|
"sdk.general.verify.error.needCloseMouth": "緊閉嘴巴",
|
|
197
198
|
"sdk.general.verify.error.needDeformationFrontal": "對齊卡片形狀",
|
|
198
199
|
"sdk.general.verify.error.needFaceToCamera": "將臉正對相機",
|
|
@@ -209,7 +210,7 @@
|
|
|
209
210
|
"sdk.general.verify.error.stagePass": "即將開始下個方向",
|
|
210
211
|
"sdk.general.verify.error.switchCamera": "證件模糊?點擊切換鏡頭",
|
|
211
212
|
"sdk.general.verify.error.wrongCardType": "錯誤證件",
|
|
212
|
-
"sdk.general.verify.success": "
|
|
213
|
+
"sdk.general.verify.success": "辨識中…",
|
|
213
214
|
"sdk.guard.verify.allowCamera": "請允許相機存取,以進行身分驗證",
|
|
214
215
|
"sdk.guard.verify.content.step1": "請手持身分證置於方框內,盡量不遮蔽邊框,並確認證件清晰無反光",
|
|
215
216
|
"sdk.guard.verify.guide.fraudDescribe": "請手持證件,依動畫提示翻轉,每個角度皆須變為綠框才能通過",
|
|
@@ -233,7 +234,7 @@
|
|
|
233
234
|
"sdk.liveness.detection.header": "人臉辨識",
|
|
234
235
|
"sdk.liveness.detection.infopageHint.environment": "在環境光線充足的地方進行",
|
|
235
236
|
"sdk.liveness.detection.infopageHint.face": "請確保臉上沒有任何遮蔽物",
|
|
236
|
-
"sdk.liveness.detection.needMoreFrame": "
|
|
237
|
+
"sdk.liveness.detection.needMoreFrame": "辨識中…",
|
|
237
238
|
"sdk.liveness.detection.step": "請依指示拍攝人臉",
|
|
238
239
|
"sdk.liveness.detection.subtitle": "即將進行人臉拍攝",
|
|
239
240
|
"sdk.liveness.detection.title": "人臉辨識",
|
package/index.cjs
CHANGED
|
@@ -29087,18 +29087,22 @@ const fasRecognitionResultMapping = fasRecognitionResult => {
|
|
|
29087
29087
|
[liveness.FasRecognitionResult.Pass]: core.StatusDescription.Pass,
|
|
29088
29088
|
[liveness.FasRecognitionResult.Error]: core.StatusDescription.Error,
|
|
29089
29089
|
[liveness.FasRecognitionResult.NeedMoreFrame]: core.StatusDescription.NeedMoreFrame,
|
|
29090
|
+
[liveness.FasRecognitionResult.Motion]: core.StatusDescription.Motion,
|
|
29090
29091
|
[liveness.FasRecognitionResult.NeedFaceToCamera]: core.StatusDescription.NeedFaceToCamera
|
|
29091
29092
|
};
|
|
29092
29093
|
return (_a = fasServiceStageMap[fasRecognitionResult]) !== null && _a !== void 0 ? _a : core.StatusDescription.Failed;
|
|
29093
29094
|
};
|
|
29094
29095
|
|
|
29096
|
+
/**
|
|
29097
|
+
* 對齊 Android SDK 的 ROI 參數
|
|
29098
|
+
* @see /Users/leoliu/Git/Android/ekyc-sdk-android/AuthMeLiveness/src/main/java/com/authme/lib/liveness/LivenessUseCase.kt
|
|
29099
|
+
*/
|
|
29095
29100
|
var MASK_STYLE;
|
|
29096
29101
|
(function (MASK_STYLE) {
|
|
29097
29102
|
MASK_STYLE[MASK_STYLE["DESKTOP_LIMIT"] = 1024] = "DESKTOP_LIMIT";
|
|
29098
|
-
|
|
29099
|
-
MASK_STYLE[MASK_STYLE["
|
|
29100
|
-
MASK_STYLE[MASK_STYLE["
|
|
29101
|
-
MASK_STYLE[MASK_STYLE["MASK_TOP_PERCENT"] = 25.5] = "MASK_TOP_PERCENT";
|
|
29103
|
+
// Android SDK 參數: widthRatio = 0.7, ratio (height/width) = 1.3
|
|
29104
|
+
MASK_STYLE[MASK_STYLE["WIDTH_RATIO"] = 0.7] = "WIDTH_RATIO";
|
|
29105
|
+
MASK_STYLE[MASK_STYLE["HEIGHT_WIDTH_RATIO"] = 1.3] = "HEIGHT_WIDTH_RATIO";
|
|
29102
29106
|
MASK_STYLE[MASK_STYLE["MASK_TITLE_MARGIN"] = 24] = "MASK_TITLE_MARGIN";
|
|
29103
29107
|
MASK_STYLE[MASK_STYLE["TITLE_TEXT_FONT_SIZE"] = 18] = "TITLE_TEXT_FONT_SIZE";
|
|
29104
29108
|
})(MASK_STYLE || (MASK_STYLE = {}));
|
|
@@ -29123,10 +29127,20 @@ const renderLivenessUI = config => {
|
|
|
29123
29127
|
const faceMask = document.createElement('div');
|
|
29124
29128
|
faceMask.classList.add('face-mask');
|
|
29125
29129
|
config.videoContainer.appendChild(faceMask);
|
|
29126
|
-
//
|
|
29127
|
-
|
|
29128
|
-
const
|
|
29129
|
-
|
|
29130
|
+
// 對齊 Android SDK: 橢圓寬度 = 螢幕寬度 × 0.7, 高度 = 寬度 × 1.3
|
|
29131
|
+
// 橫式螢幕:以高度為基準反推寬度,確保橢圓不會超出螢幕
|
|
29132
|
+
const isLandscape = window.innerWidth > window.innerHeight;
|
|
29133
|
+
let maskWidth;
|
|
29134
|
+
let maskHeight;
|
|
29135
|
+
if (isLandscape) {
|
|
29136
|
+
// 橫式螢幕:以高度為基準
|
|
29137
|
+
maskHeight = window.innerHeight * MASK_STYLE.WIDTH_RATIO;
|
|
29138
|
+
maskWidth = maskHeight / MASK_STYLE.HEIGHT_WIDTH_RATIO;
|
|
29139
|
+
} else {
|
|
29140
|
+
// 直式螢幕:以寬度為基準
|
|
29141
|
+
maskWidth = window.innerWidth * MASK_STYLE.WIDTH_RATIO;
|
|
29142
|
+
maskHeight = maskWidth * MASK_STYLE.HEIGHT_WIDTH_RATIO;
|
|
29143
|
+
}
|
|
29130
29144
|
faceMask.style.width = `${maskWidth}px`;
|
|
29131
29145
|
faceMask.style.height = `${maskHeight}px`;
|
|
29132
29146
|
faceMask.style.setProperty('--authme-liveness-scanner-pass-color', uiThemeConfig.livenessSuccessScanFrame.color);
|
|
@@ -29151,8 +29165,11 @@ const renderLivenessUI = config => {
|
|
|
29151
29165
|
if (uiThemeConfig.isStatementEnabled) {
|
|
29152
29166
|
config.videoContainer.appendChild(statementContainer);
|
|
29153
29167
|
}
|
|
29154
|
-
|
|
29155
|
-
|
|
29168
|
+
// 根據橢圓大小動態計算文字位置,避免壓到橢圓
|
|
29169
|
+
// titleThree (direction: bottom) - 值越小越靠近底部
|
|
29170
|
+
// hint (direction: top) - 值越大越往下
|
|
29171
|
+
util.uiThemeText(titleText, uiThemeConfig.titleThree, '-2vh');
|
|
29172
|
+
util.uiThemeHint(statusText, uiThemeConfig.hint, '7vh');
|
|
29156
29173
|
// Set init text
|
|
29157
29174
|
titleText.textContent = translateService.translate('sdk.liveness.detection.step');
|
|
29158
29175
|
statusText.textContent = translateService.translate('sdk.general.verify.error.noFace');
|
|
@@ -29610,6 +29627,7 @@ function startLiveness(config) {
|
|
|
29610
29627
|
})));
|
|
29611
29628
|
const applyTextByResult = result => {
|
|
29612
29629
|
// debugLog('fas-response', result);
|
|
29630
|
+
console.log('🔍 FAS Status:', result.eStatus, result);
|
|
29613
29631
|
sendStatusDescription$2(fasRecognitionResultMapping(result.eStatus));
|
|
29614
29632
|
switch (result.eStatus) {
|
|
29615
29633
|
case liveness.FasRecognitionResult.NoFace:
|
|
@@ -29667,6 +29685,10 @@ function startLiveness(config) {
|
|
|
29667
29685
|
uiComponentLiveness.statusText.textContent = translateService.translate('sdk.general.verify.success');
|
|
29668
29686
|
setBorderStatus('pass');
|
|
29669
29687
|
break;
|
|
29688
|
+
case liveness.FasRecognitionResult.Motion:
|
|
29689
|
+
uiComponentLiveness.statusText.textContent = translateService.translate('sdk.liveness.detection.motion');
|
|
29690
|
+
setBorderStatus('pass');
|
|
29691
|
+
break;
|
|
29670
29692
|
case liveness.FasRecognitionResult.Pass:
|
|
29671
29693
|
if (result.eStage === liveness.EAuthMeFASServiceStage.Scale) {
|
|
29672
29694
|
setBorderStatus(null);
|
|
@@ -32420,6 +32442,7 @@ function startOCR(config) {
|
|
|
32420
32442
|
fraudRetryTimes: 1,
|
|
32421
32443
|
fraudTimeout: 52,
|
|
32422
32444
|
fraudMaxFps: 2,
|
|
32445
|
+
ocrMaxFps: 2,
|
|
32423
32446
|
captureTimeout: config.ocrConfig.captureTimeout
|
|
32424
32447
|
};
|
|
32425
32448
|
let cardSizeInfo = {
|
|
@@ -33074,7 +33097,7 @@ function startOCR(config) {
|
|
|
33074
33097
|
})), rxjs.tap(() => received = true))))));
|
|
33075
33098
|
};
|
|
33076
33099
|
const autoCapture = canvasSizeInfo => {
|
|
33077
|
-
return rxjs.of(canvasSizeInfo).pipe(handleOcrSendFrame(canvasSizeInfo, uiComponentOCR.image, uiComponentBasic.video, config.recognition,
|
|
33100
|
+
return rxjs.of(canvasSizeInfo).pipe(handleOcrSendFrame(canvasSizeInfo, uiComponentOCR.image, uiComponentBasic.video, config.recognition, ocrEngineConfig.ocrMaxFps, false, config.ocrConfig.resultImageFormat, cardType, type), rxjs.tap(x => applyTextByResult(x.result)), rxjs.filter(({
|
|
33078
33101
|
result
|
|
33079
33102
|
}) => result.eStatus === idRecognition.EAuthMeCardOCRStatus.Pass || result.eStatus === idRecognition.EAuthMeMRZServiceStatus.Success), rxjs.take(1), rxjs.tap(() => {
|
|
33080
33103
|
if (countdownCaptureTimer && countdownCaptureTimer.end && !countdownCaptureTimer.end()) {
|
|
@@ -34604,40 +34627,39 @@ class LivenessModule {
|
|
|
34604
34627
|
frameWidth = canvasSizeInfoCan.canvasWidth;
|
|
34605
34628
|
frameHeight = canvasSizeInfoCan.canvasHeight;
|
|
34606
34629
|
const params = yield this.fasService.getParams();
|
|
34607
|
-
|
|
34608
|
-
|
|
34609
|
-
|
|
34610
|
-
|
|
34611
|
-
|
|
34612
|
-
|
|
34613
|
-
|
|
34614
|
-
|
|
34615
|
-
|
|
34616
|
-
|
|
34617
|
-
|
|
34618
|
-
|
|
34619
|
-
|
|
34620
|
-
|
|
34621
|
-
|
|
34622
|
-
|
|
34623
|
-
|
|
34624
|
-
//
|
|
34625
|
-
|
|
34626
|
-
|
|
34627
|
-
|
|
34628
|
-
|
|
34629
|
-
|
|
34630
|
-
|
|
34631
|
-
}
|
|
34632
|
-
// 如果計算出的寬度比例大於1,表示需要裁剪寬度
|
|
34633
|
-
else {
|
|
34634
|
-
// 維持完整的寬度,但可能需要調整其他參數以保持9:16的比例
|
|
34635
|
-
params.faceROI.fLeft = 0;
|
|
34636
|
-
params.faceROI.fRight = 1;
|
|
34637
|
-
// 這裡可能需要調整垂直方向的ROI,根據實際需求添加
|
|
34638
|
-
}
|
|
34630
|
+
/**
|
|
34631
|
+
* 對齊 Android SDK 的 ROI 參數
|
|
34632
|
+
* @see /Users/leoliu/Git/Android/ekyc-sdk-android/AuthMeLiveness/src/main/java/com/authme/lib/liveness/LivenessUseCase.kt
|
|
34633
|
+
*
|
|
34634
|
+
* Android SDK 參數:
|
|
34635
|
+
* - widthRatio = 0.7 (ROI 寬度 = 螢幕寬度 × 0.7)
|
|
34636
|
+
* - ratio = 1.3 (ROI 高度 = ROI 寬度 × 1.3)
|
|
34637
|
+
*
|
|
34638
|
+
* 橫式螢幕處理:以高度為基準反推寬度,確保橢圓不會超出螢幕
|
|
34639
|
+
*/
|
|
34640
|
+
const WIDTH_RATIO = 0.7;
|
|
34641
|
+
const HEIGHT_WIDTH_RATIO = 1.3;
|
|
34642
|
+
const isLandscape = frameWidth > frameHeight;
|
|
34643
|
+
let ellipseWidth;
|
|
34644
|
+
let ellipseHeight;
|
|
34645
|
+
if (isLandscape) {
|
|
34646
|
+
// 橫式螢幕:以高度為基準,反推寬度
|
|
34647
|
+
// 橢圓高度最多佔螢幕高度的 70%,然後反推寬度
|
|
34648
|
+
ellipseHeight = frameHeight * WIDTH_RATIO;
|
|
34649
|
+
ellipseWidth = ellipseHeight / HEIGHT_WIDTH_RATIO;
|
|
34650
|
+
} else {
|
|
34651
|
+
// 直式螢幕:以寬度為基準(對齊 Android SDK)
|
|
34652
|
+
ellipseWidth = frameWidth * WIDTH_RATIO;
|
|
34653
|
+
ellipseHeight = ellipseWidth * HEIGHT_WIDTH_RATIO;
|
|
34639
34654
|
}
|
|
34640
|
-
|
|
34655
|
+
// 計算正規化 ROI (0-1 範圍)
|
|
34656
|
+
const widthPercent = ellipseWidth / frameWidth;
|
|
34657
|
+
const heightPercent = ellipseHeight / frameHeight;
|
|
34658
|
+
// 置中計算
|
|
34659
|
+
params.faceROI.fLeft = (1 - widthPercent) / 2;
|
|
34660
|
+
params.faceROI.fRight = 1 - (1 - widthPercent) / 2;
|
|
34661
|
+
params.faceROI.fTop = (1 - heightPercent) / 2;
|
|
34662
|
+
params.faceROI.fBottom = 1 - (1 - heightPercent) / 2;
|
|
34641
34663
|
yield this.fasService.setParams(params);
|
|
34642
34664
|
yield this.fasService.setFrameSize(frameWidth, frameHeight);
|
|
34643
34665
|
yield this.fasService.startSession();
|
|
@@ -35107,7 +35129,8 @@ class MRZModule {
|
|
|
35107
35129
|
yield this.mrzService.init();
|
|
35108
35130
|
yield util.waitTime(100);
|
|
35109
35131
|
return Object.assign(Object.assign({}, resp.parameters), {
|
|
35110
|
-
expiredIn: resp.expiredIn
|
|
35132
|
+
expiredIn: resp.expiredIn,
|
|
35133
|
+
ocrMaxFps: 2
|
|
35111
35134
|
});
|
|
35112
35135
|
}),
|
|
35113
35136
|
ocrStart: (points, type, setBorderType, setCardBorderColor, setBorderSuccess, scanAnimationContainer, successAnimationContainer, frameImage, frameText, faceMode, cardType, retry = false) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -35744,7 +35767,8 @@ class OCRModule {
|
|
|
35744
35767
|
yield util.waitTime(100);
|
|
35745
35768
|
return Object.assign(Object.assign({}, resp.parameters), {
|
|
35746
35769
|
expiredIn: resp.expiredIn,
|
|
35747
|
-
captureTimeout: config.captureTimeout
|
|
35770
|
+
captureTimeout: config.captureTimeout,
|
|
35771
|
+
ocrMaxFps: 2
|
|
35748
35772
|
});
|
|
35749
35773
|
}),
|
|
35750
35774
|
ocrStart: (points, type, setBorderType, setCardBorderColor, setBorderSuccess, scanAnimationContainer, successAnimationContainer, frameImage, frameText, faceMode, cardType, retry = false) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -37328,8 +37352,8 @@ class AuthmeIdentityVerification extends engine.AuthmeFunctionModule {
|
|
|
37328
37352
|
}
|
|
37329
37353
|
|
|
37330
37354
|
var name = "authme/sdk";
|
|
37331
|
-
var version$1 = "2.8.
|
|
37332
|
-
var date = "
|
|
37355
|
+
var version$1 = "2.8.41";
|
|
37356
|
+
var date = "2026-01-30T10:27:23+0000";
|
|
37333
37357
|
var packageInfo = {
|
|
37334
37358
|
name: name,
|
|
37335
37359
|
version: version$1,
|
package/index.js
CHANGED
|
@@ -29079,18 +29079,22 @@ const fasRecognitionResultMapping = fasRecognitionResult => {
|
|
|
29079
29079
|
[FasRecognitionResult.Pass]: StatusDescription.Pass,
|
|
29080
29080
|
[FasRecognitionResult.Error]: StatusDescription.Error,
|
|
29081
29081
|
[FasRecognitionResult.NeedMoreFrame]: StatusDescription.NeedMoreFrame,
|
|
29082
|
+
[FasRecognitionResult.Motion]: StatusDescription.Motion,
|
|
29082
29083
|
[FasRecognitionResult.NeedFaceToCamera]: StatusDescription.NeedFaceToCamera
|
|
29083
29084
|
};
|
|
29084
29085
|
return (_a = fasServiceStageMap[fasRecognitionResult]) !== null && _a !== void 0 ? _a : StatusDescription.Failed;
|
|
29085
29086
|
};
|
|
29086
29087
|
|
|
29088
|
+
/**
|
|
29089
|
+
* 對齊 Android SDK 的 ROI 參數
|
|
29090
|
+
* @see /Users/leoliu/Git/Android/ekyc-sdk-android/AuthMeLiveness/src/main/java/com/authme/lib/liveness/LivenessUseCase.kt
|
|
29091
|
+
*/
|
|
29087
29092
|
var MASK_STYLE;
|
|
29088
29093
|
(function (MASK_STYLE) {
|
|
29089
29094
|
MASK_STYLE[MASK_STYLE["DESKTOP_LIMIT"] = 1024] = "DESKTOP_LIMIT";
|
|
29090
|
-
|
|
29091
|
-
MASK_STYLE[MASK_STYLE["
|
|
29092
|
-
MASK_STYLE[MASK_STYLE["
|
|
29093
|
-
MASK_STYLE[MASK_STYLE["MASK_TOP_PERCENT"] = 25.5] = "MASK_TOP_PERCENT";
|
|
29095
|
+
// Android SDK 參數: widthRatio = 0.7, ratio (height/width) = 1.3
|
|
29096
|
+
MASK_STYLE[MASK_STYLE["WIDTH_RATIO"] = 0.7] = "WIDTH_RATIO";
|
|
29097
|
+
MASK_STYLE[MASK_STYLE["HEIGHT_WIDTH_RATIO"] = 1.3] = "HEIGHT_WIDTH_RATIO";
|
|
29094
29098
|
MASK_STYLE[MASK_STYLE["MASK_TITLE_MARGIN"] = 24] = "MASK_TITLE_MARGIN";
|
|
29095
29099
|
MASK_STYLE[MASK_STYLE["TITLE_TEXT_FONT_SIZE"] = 18] = "TITLE_TEXT_FONT_SIZE";
|
|
29096
29100
|
})(MASK_STYLE || (MASK_STYLE = {}));
|
|
@@ -29115,10 +29119,20 @@ const renderLivenessUI = config => {
|
|
|
29115
29119
|
const faceMask = document.createElement('div');
|
|
29116
29120
|
faceMask.classList.add('face-mask');
|
|
29117
29121
|
config.videoContainer.appendChild(faceMask);
|
|
29118
|
-
//
|
|
29119
|
-
|
|
29120
|
-
const
|
|
29121
|
-
|
|
29122
|
+
// 對齊 Android SDK: 橢圓寬度 = 螢幕寬度 × 0.7, 高度 = 寬度 × 1.3
|
|
29123
|
+
// 橫式螢幕:以高度為基準反推寬度,確保橢圓不會超出螢幕
|
|
29124
|
+
const isLandscape = window.innerWidth > window.innerHeight;
|
|
29125
|
+
let maskWidth;
|
|
29126
|
+
let maskHeight;
|
|
29127
|
+
if (isLandscape) {
|
|
29128
|
+
// 橫式螢幕:以高度為基準
|
|
29129
|
+
maskHeight = window.innerHeight * MASK_STYLE.WIDTH_RATIO;
|
|
29130
|
+
maskWidth = maskHeight / MASK_STYLE.HEIGHT_WIDTH_RATIO;
|
|
29131
|
+
} else {
|
|
29132
|
+
// 直式螢幕:以寬度為基準
|
|
29133
|
+
maskWidth = window.innerWidth * MASK_STYLE.WIDTH_RATIO;
|
|
29134
|
+
maskHeight = maskWidth * MASK_STYLE.HEIGHT_WIDTH_RATIO;
|
|
29135
|
+
}
|
|
29122
29136
|
faceMask.style.width = `${maskWidth}px`;
|
|
29123
29137
|
faceMask.style.height = `${maskHeight}px`;
|
|
29124
29138
|
faceMask.style.setProperty('--authme-liveness-scanner-pass-color', uiThemeConfig.livenessSuccessScanFrame.color);
|
|
@@ -29143,8 +29157,11 @@ const renderLivenessUI = config => {
|
|
|
29143
29157
|
if (uiThemeConfig.isStatementEnabled) {
|
|
29144
29158
|
config.videoContainer.appendChild(statementContainer);
|
|
29145
29159
|
}
|
|
29146
|
-
|
|
29147
|
-
|
|
29160
|
+
// 根據橢圓大小動態計算文字位置,避免壓到橢圓
|
|
29161
|
+
// titleThree (direction: bottom) - 值越小越靠近底部
|
|
29162
|
+
// hint (direction: top) - 值越大越往下
|
|
29163
|
+
uiThemeText(titleText, uiThemeConfig.titleThree, '-2vh');
|
|
29164
|
+
uiThemeHint(statusText, uiThemeConfig.hint, '7vh');
|
|
29148
29165
|
// Set init text
|
|
29149
29166
|
titleText.textContent = translateService.translate('sdk.liveness.detection.step');
|
|
29150
29167
|
statusText.textContent = translateService.translate('sdk.general.verify.error.noFace');
|
|
@@ -29602,6 +29619,7 @@ function startLiveness(config) {
|
|
|
29602
29619
|
})));
|
|
29603
29620
|
const applyTextByResult = result => {
|
|
29604
29621
|
// debugLog('fas-response', result);
|
|
29622
|
+
console.log('🔍 FAS Status:', result.eStatus, result);
|
|
29605
29623
|
sendStatusDescription$2(fasRecognitionResultMapping(result.eStatus));
|
|
29606
29624
|
switch (result.eStatus) {
|
|
29607
29625
|
case FasRecognitionResult.NoFace:
|
|
@@ -29659,6 +29677,10 @@ function startLiveness(config) {
|
|
|
29659
29677
|
uiComponentLiveness.statusText.textContent = translateService.translate('sdk.general.verify.success');
|
|
29660
29678
|
setBorderStatus('pass');
|
|
29661
29679
|
break;
|
|
29680
|
+
case FasRecognitionResult.Motion:
|
|
29681
|
+
uiComponentLiveness.statusText.textContent = translateService.translate('sdk.liveness.detection.motion');
|
|
29682
|
+
setBorderStatus('pass');
|
|
29683
|
+
break;
|
|
29662
29684
|
case FasRecognitionResult.Pass:
|
|
29663
29685
|
if (result.eStage === EAuthMeFASServiceStage.Scale) {
|
|
29664
29686
|
setBorderStatus(null);
|
|
@@ -32412,6 +32434,7 @@ function startOCR(config) {
|
|
|
32412
32434
|
fraudRetryTimes: 1,
|
|
32413
32435
|
fraudTimeout: 52,
|
|
32414
32436
|
fraudMaxFps: 2,
|
|
32437
|
+
ocrMaxFps: 2,
|
|
32415
32438
|
captureTimeout: config.ocrConfig.captureTimeout
|
|
32416
32439
|
};
|
|
32417
32440
|
let cardSizeInfo = {
|
|
@@ -33066,7 +33089,7 @@ function startOCR(config) {
|
|
|
33066
33089
|
})), tap(() => received = true))))));
|
|
33067
33090
|
};
|
|
33068
33091
|
const autoCapture = canvasSizeInfo => {
|
|
33069
|
-
return of(canvasSizeInfo).pipe(handleOcrSendFrame(canvasSizeInfo, uiComponentOCR.image, uiComponentBasic.video, config.recognition,
|
|
33092
|
+
return of(canvasSizeInfo).pipe(handleOcrSendFrame(canvasSizeInfo, uiComponentOCR.image, uiComponentBasic.video, config.recognition, ocrEngineConfig.ocrMaxFps, false, config.ocrConfig.resultImageFormat, cardType, type), tap(x => applyTextByResult(x.result)), filter(({
|
|
33070
33093
|
result
|
|
33071
33094
|
}) => result.eStatus === EAuthMeCardOCRStatus.Pass || result.eStatus === EAuthMeMRZServiceStatus.Success), take(1), tap(() => {
|
|
33072
33095
|
if (countdownCaptureTimer && countdownCaptureTimer.end && !countdownCaptureTimer.end()) {
|
|
@@ -34596,40 +34619,39 @@ class LivenessModule {
|
|
|
34596
34619
|
frameWidth = canvasSizeInfoCan.canvasWidth;
|
|
34597
34620
|
frameHeight = canvasSizeInfoCan.canvasHeight;
|
|
34598
34621
|
const params = yield this.fasService.getParams();
|
|
34599
|
-
|
|
34600
|
-
|
|
34601
|
-
|
|
34602
|
-
|
|
34603
|
-
|
|
34604
|
-
|
|
34605
|
-
|
|
34606
|
-
|
|
34607
|
-
|
|
34608
|
-
|
|
34609
|
-
|
|
34610
|
-
|
|
34611
|
-
|
|
34612
|
-
|
|
34613
|
-
|
|
34614
|
-
|
|
34615
|
-
|
|
34616
|
-
//
|
|
34617
|
-
|
|
34618
|
-
|
|
34619
|
-
|
|
34620
|
-
|
|
34621
|
-
|
|
34622
|
-
|
|
34623
|
-
}
|
|
34624
|
-
// 如果計算出的寬度比例大於1,表示需要裁剪寬度
|
|
34625
|
-
else {
|
|
34626
|
-
// 維持完整的寬度,但可能需要調整其他參數以保持9:16的比例
|
|
34627
|
-
params.faceROI.fLeft = 0;
|
|
34628
|
-
params.faceROI.fRight = 1;
|
|
34629
|
-
// 這裡可能需要調整垂直方向的ROI,根據實際需求添加
|
|
34630
|
-
}
|
|
34622
|
+
/**
|
|
34623
|
+
* 對齊 Android SDK 的 ROI 參數
|
|
34624
|
+
* @see /Users/leoliu/Git/Android/ekyc-sdk-android/AuthMeLiveness/src/main/java/com/authme/lib/liveness/LivenessUseCase.kt
|
|
34625
|
+
*
|
|
34626
|
+
* Android SDK 參數:
|
|
34627
|
+
* - widthRatio = 0.7 (ROI 寬度 = 螢幕寬度 × 0.7)
|
|
34628
|
+
* - ratio = 1.3 (ROI 高度 = ROI 寬度 × 1.3)
|
|
34629
|
+
*
|
|
34630
|
+
* 橫式螢幕處理:以高度為基準反推寬度,確保橢圓不會超出螢幕
|
|
34631
|
+
*/
|
|
34632
|
+
const WIDTH_RATIO = 0.7;
|
|
34633
|
+
const HEIGHT_WIDTH_RATIO = 1.3;
|
|
34634
|
+
const isLandscape = frameWidth > frameHeight;
|
|
34635
|
+
let ellipseWidth;
|
|
34636
|
+
let ellipseHeight;
|
|
34637
|
+
if (isLandscape) {
|
|
34638
|
+
// 橫式螢幕:以高度為基準,反推寬度
|
|
34639
|
+
// 橢圓高度最多佔螢幕高度的 70%,然後反推寬度
|
|
34640
|
+
ellipseHeight = frameHeight * WIDTH_RATIO;
|
|
34641
|
+
ellipseWidth = ellipseHeight / HEIGHT_WIDTH_RATIO;
|
|
34642
|
+
} else {
|
|
34643
|
+
// 直式螢幕:以寬度為基準(對齊 Android SDK)
|
|
34644
|
+
ellipseWidth = frameWidth * WIDTH_RATIO;
|
|
34645
|
+
ellipseHeight = ellipseWidth * HEIGHT_WIDTH_RATIO;
|
|
34631
34646
|
}
|
|
34632
|
-
|
|
34647
|
+
// 計算正規化 ROI (0-1 範圍)
|
|
34648
|
+
const widthPercent = ellipseWidth / frameWidth;
|
|
34649
|
+
const heightPercent = ellipseHeight / frameHeight;
|
|
34650
|
+
// 置中計算
|
|
34651
|
+
params.faceROI.fLeft = (1 - widthPercent) / 2;
|
|
34652
|
+
params.faceROI.fRight = 1 - (1 - widthPercent) / 2;
|
|
34653
|
+
params.faceROI.fTop = (1 - heightPercent) / 2;
|
|
34654
|
+
params.faceROI.fBottom = 1 - (1 - heightPercent) / 2;
|
|
34633
34655
|
yield this.fasService.setParams(params);
|
|
34634
34656
|
yield this.fasService.setFrameSize(frameWidth, frameHeight);
|
|
34635
34657
|
yield this.fasService.startSession();
|
|
@@ -35099,7 +35121,8 @@ class MRZModule {
|
|
|
35099
35121
|
yield this.mrzService.init();
|
|
35100
35122
|
yield waitTime(100);
|
|
35101
35123
|
return Object.assign(Object.assign({}, resp.parameters), {
|
|
35102
|
-
expiredIn: resp.expiredIn
|
|
35124
|
+
expiredIn: resp.expiredIn,
|
|
35125
|
+
ocrMaxFps: 2
|
|
35103
35126
|
});
|
|
35104
35127
|
}),
|
|
35105
35128
|
ocrStart: (points, type, setBorderType, setCardBorderColor, setBorderSuccess, scanAnimationContainer, successAnimationContainer, frameImage, frameText, faceMode, cardType, retry = false) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -35736,7 +35759,8 @@ class OCRModule {
|
|
|
35736
35759
|
yield waitTime(100);
|
|
35737
35760
|
return Object.assign(Object.assign({}, resp.parameters), {
|
|
35738
35761
|
expiredIn: resp.expiredIn,
|
|
35739
|
-
captureTimeout: config.captureTimeout
|
|
35762
|
+
captureTimeout: config.captureTimeout,
|
|
35763
|
+
ocrMaxFps: 2
|
|
35740
35764
|
});
|
|
35741
35765
|
}),
|
|
35742
35766
|
ocrStart: (points, type, setBorderType, setCardBorderColor, setBorderSuccess, scanAnimationContainer, successAnimationContainer, frameImage, frameText, faceMode, cardType, retry = false) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -37320,8 +37344,8 @@ class AuthmeIdentityVerification extends AuthmeFunctionModule {
|
|
|
37320
37344
|
}
|
|
37321
37345
|
|
|
37322
37346
|
var name = "authme/sdk";
|
|
37323
|
-
var version$1 = "2.8.
|
|
37324
|
-
var date = "
|
|
37347
|
+
var version$1 = "2.8.41";
|
|
37348
|
+
var date = "2026-01-30T10:27:23+0000";
|
|
37325
37349
|
var packageInfo = {
|
|
37326
37350
|
name: name,
|
|
37327
37351
|
version: version$1,
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@authme/identity-verification",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.41",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"core-js": "^3.6.0",
|
|
6
6
|
"lottie-web": "^5.9.2",
|
|
7
7
|
"rxjs": "^7.4.0",
|
|
8
|
-
"@authme/core": "2.8.
|
|
9
|
-
"@authme/engine": "2.8.
|
|
10
|
-
"@authme/id-recognition": "2.8.
|
|
11
|
-
"@authme/liveness": "2.8.
|
|
12
|
-
"@authme/util": "2.8.
|
|
8
|
+
"@authme/core": "2.8.41",
|
|
9
|
+
"@authme/engine": "2.8.41",
|
|
10
|
+
"@authme/id-recognition": "2.8.41",
|
|
11
|
+
"@authme/liveness": "2.8.41",
|
|
12
|
+
"@authme/util": "2.8.41"
|
|
13
13
|
},
|
|
14
14
|
"module": "./index.js",
|
|
15
15
|
"main": "./index.cjs",
|