idmission-web-sdk 2.3.224 → 2.3.225-feature-per-runtime-capability-probe-e2ff01d

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/dist/sdk2.esm.js CHANGED
@@ -3103,204 +3103,188 @@ function useStateWithCapturedAt() {
3103
3103
  return [value, setWithStamp, capturedAt];
3104
3104
  }
3105
3105
 
3106
- var visionTasksBasePath = "https://websdk-cdn-dev.idmission.com/assets/vision_wasm_internal_0.10.7";
3107
- var visionRuntimeHash = 'tdLjRcm8XLETT+lUxF1oNst5jULaTGDUc2YtazwbGnLVGD0D/4A274KuJF+adneW';
3108
- var wasmStderrPatterns = ['TensorFlow Lite', 'static-sized tensors', 'Attempting to use a delegate'];
3109
- function isWasmStderr(msg) {
3110
- return wasmStderrPatterns.some(function (p) {
3111
- return msg.includes(p);
3112
- });
3106
+ var RUNTIME_NAMES = ['mediapipe', 'litert'];
3107
+ var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
3108
+ var defaultImageSegmenterModelHash = 'A2bQ8+iZyQM3KIGVBUf0FyetqxuynyKpjsjCE8uzoJEnj1ghCu6ge2daiRffAiS5';
3109
+ var imageSegmenterModelSizeInBytes = 256440.32;
3110
+ // We globally set a cache key based on the time at page load so the built-in
3111
+ // speed test isn't fooled by cache hits, but subsequent downloads of the
3112
+ // vision runtime do load from the cache.
3113
+ var tinyModelCacheKey = new Date().getTime();
3114
+ function makeInitialModelCapabilities() {
3115
+ return {
3116
+ networkProbeState: 'notProbed',
3117
+ networkTier: 'untested',
3118
+ networkSpeed: 0,
3119
+ networkTestTime: 0,
3120
+ delegateByRuntime: Object.fromEntries(RUNTIME_NAMES.map(function (name) {
3121
+ return [name, {
3122
+ probeState: 'notProbed',
3123
+ delegate: 'GPU'
3124
+ }];
3125
+ }))
3126
+ };
3113
3127
  }
3114
- var quietWasmRefCount = 0;
3115
- var savedNativeError = null;
3116
- /**
3117
- * Wraps an async operation that initializes WASM/TFLite models, temporarily
3118
- * intercepting console.error to downgrade known-benign TF Lite stderr messages
3119
- * (routed through Emscripten's fd_write -> console.error) to debug level.
3120
- *
3121
- * Uses a reference count so overlapping calls share a single patched handler
3122
- * and only restore the original console.error when the last one completes.
3123
- */
3124
- function withQuietWasm(fn) {
3125
- return __awaiter(this, void 0, void 0, function () {
3126
- return __generator(this, function (_a) {
3127
- if (quietWasmRefCount++ === 0) {
3128
- savedNativeError = console.error; // eslint-disable-line no-console
3129
- console.error = function () {
3130
- var args = [];
3131
- for (var _i = 0; _i < arguments.length; _i++) {
3132
- args[_i] = arguments[_i];
3133
- }
3134
- if (isWasmStderr(String(args[0]))) {
3135
- debug.apply(void 0, args);
3136
- return;
3137
- }
3138
- savedNativeError.apply(void 0, args);
3139
- };
3140
- }
3141
- return [2 /*return*/, fn()["finally"](function () {
3142
- if (--quietWasmRefCount === 0) {
3143
- console.error = savedNativeError; // eslint-disable-line no-console
3144
- savedNativeError = null;
3145
- }
3146
- })];
3147
- });
3148
- });
3128
+ var modelCapabilities = makeInitialModelCapabilities();
3129
+ function getDelegate(runtime) {
3130
+ return modelCapabilities.delegateByRuntime[runtime].delegate;
3149
3131
  }
3150
- var visionRuntimePreloading = false;
3151
- function preloadVisionRuntime() {
3132
+ function setDelegate(runtime, delegate) {
3133
+ modelCapabilities.delegateByRuntime[runtime].delegate = delegate;
3134
+ }
3135
+ // Network speed probe. Runtime-agnostic — just times an HTTP fetch of a
3136
+ // small known artifact. Idempotent across concurrent callers via the
3137
+ // 'probing' wait loop.
3138
+ function probeNetworkSpeed() {
3152
3139
  return __awaiter(this, void 0, void 0, function () {
3153
- function handleDownloadProgress(event) {
3154
- var detail = event.detail;
3155
- if (detail.url !== url) return;
3156
- progressByUseCase.visionRuntime = sumUpProgressForDependencies([url]);
3157
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.visionRuntime', {
3158
- detail: progressByUseCase.visionRuntime
3159
- }));
3160
- }
3161
- var url;
3140
+ var modelAssetPath, startedAt, e_1, time, speedMbps;
3162
3141
  return __generator(this, function (_a) {
3163
3142
  switch (_a.label) {
3164
3143
  case 0:
3165
- if (visionRuntimePreloading) return [2 /*return*/, new Promise(function (resolve) {
3166
- setInterval(function () {
3167
- if (!visionRuntimePreloading) resolve();
3168
- }, 100);
3169
- })];
3170
- visionRuntimePreloading = true;
3171
- url = "".concat(visionTasksBasePath, "/vision_wasm_internal.wasm");
3172
- document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
3144
+ if (modelCapabilities.networkProbeState === 'probed') return [2 /*return*/];
3145
+ if (modelCapabilities.networkProbeState === 'probing') {
3146
+ return [2 /*return*/, new Promise(function (resolve) {
3147
+ var id = setInterval(function () {
3148
+ if (modelCapabilities.networkProbeState === 'probed') {
3149
+ clearInterval(id);
3150
+ resolve();
3151
+ }
3152
+ }, 100);
3153
+ })];
3154
+ }
3155
+ modelCapabilities.networkProbeState = 'probing';
3173
3156
  _a.label = 1;
3174
3157
  case 1:
3175
- _a.trys.push([1,, 3, 4]);
3176
- return [4 /*yield*/, preloadDependency(url, visionRuntimeHash)];
3158
+ _a.trys.push([1,, 6, 7]);
3159
+ modelAssetPath = "".concat(defaultImageSegmenterModelPath, "?_=").concat(tinyModelCacheKey);
3160
+ startedAt = new Date();
3161
+ _a.label = 2;
3177
3162
  case 2:
3178
- _a.sent();
3179
- return [3 /*break*/, 4];
3163
+ _a.trys.push([2, 4,, 5]);
3164
+ return [4 /*yield*/, Promise.race([preloadDependency(modelAssetPath, defaultImageSegmenterModelHash), giveUpAfter(10000)])];
3180
3165
  case 3:
3181
- document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
3182
- visionRuntimePreloading = false;
3183
- return [7 /*endfinally*/];
3166
+ _a.sent();
3167
+ return [3 /*break*/, 5];
3184
3168
  case 4:
3169
+ e_1 = _a.sent();
3170
+ error('speed test failed', e_1);
3171
+ modelCapabilities.networkTier = 'unusable';
3172
+ return [2 /*return*/];
3173
+ case 5:
3174
+ time = (new Date().getTime() - startedAt.getTime()) / 1000.0;
3175
+ modelCapabilities.networkTestTime || (modelCapabilities.networkTestTime = time);
3176
+ modelCapabilities.networkSpeed || (modelCapabilities.networkSpeed = imageSegmenterModelSizeInBytes / time);
3177
+ modelCapabilities.networkTier = time < 0.5 ? 'fast' : time < 2 ? 'medium' : 'slow';
3178
+ speedMbps = modelCapabilities.networkSpeed / 1024 / 1024;
3179
+ log('Model Probing: network speed', speedMbps.toFixed(3), 'Mbps');
3180
+ log('Model Probing: network test took', time);
3181
+ log('Model Probing: network tier', modelCapabilities.networkTier);
3182
+ return [3 /*break*/, 7];
3183
+ case 6:
3184
+ modelCapabilities.networkProbeState = 'probed';
3185
+ return [7 /*endfinally*/];
3186
+ case 7:
3185
3187
  return [2 /*return*/];
3186
3188
  }
3187
3189
  });
3188
3190
  });
3189
3191
  }
3190
-
3191
- var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
3192
- var defaultImageSegmenterModelHash = 'A2bQ8+iZyQM3KIGVBUf0FyetqxuynyKpjsjCE8uzoJEnj1ghCu6ge2daiRffAiS5';
3193
- var imageSegmenterModelSizeInBytes = 256440.32;
3194
- // The idea here is that we globally set a cache key based on the time at page load. That way our built-in speed test
3195
- // isn't fooled by cache times, but subsequent downloads of the vision runtime still do load from the cache.
3196
- var tinyModelCacheKey = new Date().getTime();
3197
- var initialModelCapabilities = {
3198
- probeState: 'notProbed',
3199
- delegate: 'GPU',
3200
- networkTier: 'untested',
3201
- networkSpeed: 0,
3202
- networkTestTime: 0
3203
- };
3204
- var modelCapabilities = _assign({}, initialModelCapabilities);
3205
- function probeModelCapabilities() {
3192
+ // Probe a specific runtime's GPU/CPU delegate. Lazily dispatches to the
3193
+ // runtime-specific verifier via dynamic import so a customer who never
3194
+ // invokes a particular runtime never loads its WASM payload.
3195
+ function probeDelegateForRuntime(runtime) {
3206
3196
  return __awaiter(this, void 0, void 0, function () {
3207
- var error_1, error_2;
3197
+ var state, firstError_1, secondError_1;
3208
3198
  return __generator(this, function (_a) {
3209
3199
  switch (_a.label) {
3210
3200
  case 0:
3211
- if (modelCapabilities.probeState === 'probed') return [2 /*return*/];
3212
- if (modelCapabilities.probeState === 'probing') return [2 /*return*/, new Promise(function (resolve) {
3213
- var id = setInterval(function () {
3214
- if (modelCapabilities.probeState === 'probed') {
3215
- clearInterval(id);
3216
- resolve();
3217
- }
3218
- }, 100);
3219
- })];
3220
- modelCapabilities.probeState = 'probing';
3221
- return [4 /*yield*/, preloadVisionRuntime()];
3201
+ state = modelCapabilities.delegateByRuntime[runtime];
3202
+ if (state.probeState === 'probed') return [2 /*return*/];
3203
+ if (state.probeState === 'probing') {
3204
+ return [2 /*return*/, new Promise(function (resolve) {
3205
+ var id = setInterval(function () {
3206
+ if (state.probeState === 'probed') {
3207
+ clearInterval(id);
3208
+ resolve();
3209
+ }
3210
+ }, 100);
3211
+ })];
3212
+ }
3213
+ state.probeState = 'probing';
3214
+ _a.label = 1;
3222
3215
  case 1:
3223
- _a.sent();
3224
- _a.label = 2;
3216
+ _a.trys.push([1,, 11, 12]);
3217
+ // Need network speed first because the delegate verifier reuses the
3218
+ // segmenter test model bytes.
3219
+ return [4 /*yield*/, probeNetworkSpeed()];
3225
3220
  case 2:
3226
- _a.trys.push([2, 4, 9, 10]);
3227
- log('Model Probing: testing GPU capabilities...');
3228
- return [4 /*yield*/, loadTinyModel('GPU')];
3221
+ // Need network speed first because the delegate verifier reuses the
3222
+ // segmenter test model bytes.
3223
+ _a.sent();
3224
+ if (modelCapabilities.networkTier === 'unusable') {
3225
+ state.delegate = 'NONE';
3226
+ return [2 /*return*/];
3227
+ }
3228
+ _a.label = 3;
3229
3229
  case 3:
3230
+ _a.trys.push([3, 5,, 10]);
3231
+ log("Model Probing: testing ".concat(runtime, " GPU capabilities..."));
3232
+ return [4 /*yield*/, verifyDelegate(runtime, 'GPU')];
3233
+ case 4:
3230
3234
  _a.sent();
3231
- log('Model Probing: GPU is capable.');
3235
+ log("Model Probing: ".concat(runtime, " GPU is capable."));
3232
3236
  return [3 /*break*/, 10];
3233
- case 4:
3234
- error_1 = _a.sent();
3235
- warn('Model Probing: GPU delegate could not be loaded', error_1);
3236
- modelCapabilities.delegate = 'CPU';
3237
- _a.label = 5;
3238
3237
  case 5:
3239
- _a.trys.push([5, 7,, 8]);
3240
- log('Model Probing: testing CPU capabilities...');
3241
- return [4 /*yield*/, loadTinyModel('CPU')];
3238
+ firstError_1 = _a.sent();
3239
+ warn("Model Probing: ".concat(runtime, " GPU delegate could not be loaded"), firstError_1);
3240
+ state.delegate = 'CPU';
3241
+ _a.label = 6;
3242
3242
  case 6:
3243
- _a.sent();
3244
- log('Model Probing: CPU is capable.');
3245
- return [3 /*break*/, 8];
3243
+ _a.trys.push([6, 8,, 9]);
3244
+ log("Model Probing: testing ".concat(runtime, " CPU capabilities..."));
3245
+ return [4 /*yield*/, verifyDelegate(runtime, 'CPU')];
3246
3246
  case 7:
3247
- error_2 = _a.sent();
3248
- warn('Model Probing: CPU delegate could not be loaded', error_2);
3249
- modelCapabilities.delegate = 'NONE';
3250
- return [3 /*break*/, 8];
3247
+ _a.sent();
3248
+ log("Model Probing: ".concat(runtime, " CPU is capable."));
3249
+ return [3 /*break*/, 9];
3251
3250
  case 8:
3252
- return [3 /*break*/, 10];
3251
+ secondError_1 = _a.sent();
3252
+ warn("Model Probing: ".concat(runtime, " CPU delegate could not be loaded"), secondError_1);
3253
+ state.delegate = 'NONE';
3254
+ return [3 /*break*/, 9];
3253
3255
  case 9:
3254
- modelCapabilities.probeState = 'probed';
3255
- return [7 /*endfinally*/];
3256
+ return [3 /*break*/, 10];
3256
3257
  case 10:
3258
+ return [3 /*break*/, 12];
3259
+ case 11:
3260
+ state.probeState = 'probed';
3261
+ return [7 /*endfinally*/];
3262
+ case 12:
3257
3263
  return [2 /*return*/];
3258
3264
  }
3259
3265
  });
3260
3266
  });
3261
3267
  }
3262
- function loadTinyModel() {
3263
- return __awaiter(this, arguments, void 0, function (delegate, maxTime) {
3264
- var modelAssetPath, startedAt, e_1, time, speedMbps, verifyMediaPipeDelegate;
3265
- if (delegate === void 0) {
3266
- delegate = 'GPU';
3267
- }
3268
- if (maxTime === void 0) {
3269
- maxTime = 10000;
3270
- }
3268
+ function verifyDelegate(runtime, delegate) {
3269
+ return __awaiter(this, void 0, void 0, function () {
3270
+ var modelAssetPath, preloadVisionRuntime, verifyMediaPipeDelegate, exhaustive;
3271
3271
  return __generator(this, function (_a) {
3272
3272
  switch (_a.label) {
3273
3273
  case 0:
3274
3274
  modelAssetPath = "".concat(defaultImageSegmenterModelPath, "?_=").concat(tinyModelCacheKey);
3275
- startedAt = new Date();
3276
- _a.label = 1;
3275
+ return [4 /*yield*/, Promise.resolve().then(function () { return VisionRuntime; })];
3277
3276
  case 1:
3278
- _a.trys.push([1, 3,, 4]);
3279
- return [4 /*yield*/, Promise.race([preloadDependency(modelAssetPath, defaultImageSegmenterModelHash), giveUpAfter(maxTime)])];
3277
+ preloadVisionRuntime = _a.sent().preloadVisionRuntime;
3278
+ return [4 /*yield*/, preloadVisionRuntime()];
3280
3279
  case 2:
3281
3280
  _a.sent();
3282
- return [3 /*break*/, 4];
3283
- case 3:
3284
- e_1 = _a.sent();
3285
- error('speed test failed', e_1);
3286
- modelCapabilities.networkTier = 'unusable';
3287
- return [2 /*return*/];
3288
- case 4:
3289
- time = (new Date().getTime() - startedAt.getTime()) / 1000.0;
3290
- modelCapabilities.networkTestTime || (modelCapabilities.networkTestTime = time);
3291
- modelCapabilities.networkSpeed || (modelCapabilities.networkSpeed = imageSegmenterModelSizeInBytes / time);
3292
- modelCapabilities.networkTier = time < 0.5 ? 'fast' : time < 2 ? 'medium' : 'slow';
3293
- speedMbps = modelCapabilities.networkSpeed / 1024 / 1024;
3294
- log('Model Probing: network speed', speedMbps.toFixed(3), 'Mbps');
3295
- log('Model Probing: network test took', time);
3296
- log('Model Probing: network tier', modelCapabilities.networkTier);
3297
3281
  return [4 /*yield*/, Promise.resolve().then(function () { return CapabilityProbe; })];
3298
- case 5:
3282
+ case 3:
3299
3283
  verifyMediaPipeDelegate = _a.sent().verifyMediaPipeDelegate;
3300
- return [4 /*yield*/, verifyMediaPipeDelegate(delegate, modelAssetPath)];
3301
- case 6:
3302
- _a.sent();
3303
- return [2 /*return*/];
3284
+ return [2 /*return*/, verifyMediaPipeDelegate(delegate, modelAssetPath)];
3285
+ case 4:
3286
+ exhaustive = runtime;
3287
+ throw new Error("Unknown runtime: ".concat(exhaustive));
3304
3288
  }
3305
3289
  });
3306
3290
  });
@@ -3345,7 +3329,7 @@ var defaultModelPaths = {
3345
3329
 
3346
3330
  var preloadModels = function preloadModels(_a) {
3347
3331
  return __awaiter(void 0, [_a], void 0, function (_b) {
3348
- var preloadTasks;
3332
+ var needsMediaPipe, preloadTasks;
3349
3333
  var _c = _b.documentDetectionModel,
3350
3334
  documentDetectionModel = _c === void 0 ? true : _c,
3351
3335
  _d = _b.focusModel,
@@ -3359,9 +3343,24 @@ var preloadModels = function preloadModels(_a) {
3359
3343
  return __generator(this, function (_h) {
3360
3344
  switch (_h.label) {
3361
3345
  case 0:
3362
- return [4 /*yield*/, probeModelCapabilities()];
3346
+ // Network probe is runtime-agnostic. The delegate probe is per-runtime;
3347
+ // every model preloaded by this function is currently MediaPipe-backed,
3348
+ // so probe MP only when at least one such model is in the config. If a
3349
+ // future caller passes only LiteRT-backed models, MP will not be probed.
3350
+ return [4 /*yield*/, probeNetworkSpeed()];
3363
3351
  case 1:
3352
+ // Network probe is runtime-agnostic. The delegate probe is per-runtime;
3353
+ // every model preloaded by this function is currently MediaPipe-backed,
3354
+ // so probe MP only when at least one such model is in the config. If a
3355
+ // future caller passes only LiteRT-backed models, MP will not be probed.
3356
+ _h.sent();
3357
+ needsMediaPipe = !!documentDetectionModel || !!focusModel || !!faceDetectionModel || !!faceLandmarkerModel || !!barcodeReadabilityModel;
3358
+ if (!needsMediaPipe) return [3 /*break*/, 3];
3359
+ return [4 /*yield*/, probeDelegateForRuntime('mediapipe')];
3360
+ case 2:
3364
3361
  _h.sent();
3362
+ _h.label = 3;
3363
+ case 3:
3365
3364
  preloadTasks = [];
3366
3365
  if (documentDetectionModel) {
3367
3366
  preloadTasks.push(preloadDocumentDetectorDependencies);
@@ -3379,7 +3378,7 @@ var preloadModels = function preloadModels(_a) {
3379
3378
  preloadTasks.push(preloadBarcodeReadabilityModelDependencies);
3380
3379
  }
3381
3380
  return [4 /*yield*/, Promise.all(preloadTasks)];
3382
- case 2:
3381
+ case 4:
3383
3382
  _h.sent();
3384
3383
  return [2 /*return*/];
3385
3384
  }
@@ -3540,10 +3539,19 @@ function preloadModelDependencies(model) {
3540
3539
  }, 100);
3541
3540
  })];
3542
3541
  modelsPreloading[model] = true;
3543
- return [4 /*yield*/, probeModelCapabilities()];
3542
+ // All five models in this function are MediaPipe-backed; probe MP's
3543
+ // delegate to surface NONE before we waste bandwidth downloading bytes
3544
+ // for a model the device can't run.
3545
+ return [4 /*yield*/, probeNetworkSpeed()];
3544
3546
  case 1:
3547
+ // All five models in this function are MediaPipe-backed; probe MP's
3548
+ // delegate to surface NONE before we waste bandwidth downloading bytes
3549
+ // for a model the device can't run.
3545
3550
  _a.sent();
3546
- if (modelCapabilities.delegate === 'NONE') {
3551
+ return [4 /*yield*/, probeDelegateForRuntime('mediapipe')];
3552
+ case 2:
3553
+ _a.sent();
3554
+ if (getDelegate('mediapipe') === 'NONE') {
3547
3555
  throw new Error("No available delegate for ".concat(model, " model."));
3548
3556
  }
3549
3557
  dependencies = [{
@@ -3551,20 +3559,20 @@ function preloadModelDependencies(model) {
3551
3559
  hash: defaultModelPaths[model + 'Hash']
3552
3560
  }];
3553
3561
  document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3554
- _a.label = 2;
3555
- case 2:
3556
- _a.trys.push([2,, 4, 5]);
3562
+ _a.label = 3;
3563
+ case 3:
3564
+ _a.trys.push([3,, 5, 6]);
3557
3565
  return [4 /*yield*/, Promise.all(dependencies.map(function (d) {
3558
3566
  return preloadDependency(d.url, d.hash);
3559
3567
  }))];
3560
- case 3:
3561
- _a.sent();
3562
- return [3 /*break*/, 5];
3563
3568
  case 4:
3569
+ _a.sent();
3570
+ return [3 /*break*/, 6];
3571
+ case 5:
3564
3572
  document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3565
3573
  modelsPreloading[model] = false;
3566
3574
  return [7 /*endfinally*/];
3567
- case 5:
3575
+ case 6:
3568
3576
  return [2 /*return*/];
3569
3577
  }
3570
3578
  });
@@ -17184,7 +17192,7 @@ var SelfieCapture = function SelfieCapture(_a) {
17184
17192
  top: top - 2
17185
17193
  }
17186
17194
  });
17187
- })))), debugMode && (/*#__PURE__*/React__default.createElement(DebugStatsPane, null, camera ? (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, "\u2705 Camera: ", camera.label, " (", camera.width, "x", camera.height, ")")) : '❌ Camera not ready', /*#__PURE__*/React__default.createElement("br", null), modelCapabilities.delegate !== 'NONE' ? '✅' : '❌', " Delegate:", ' ', modelCapabilities.delegate, /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotDetected) ? '✅' : '❌', " Face Detected", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotCentered) ? '✅' : '❌', " Face Centered", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) && !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? '✅' : '❌', ' ', "Face", ' ', (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) ? 'Too Close' : (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? 'Too Far' : 'Distance Correct', /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceLookingAway) ? '✅' : '❌', " Face Looking Forward", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceIsStable) ? '✅' : '❌', " Face Is Stable", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.noseIsStable) ? '✅' : '❌', " Nose Is Stable", /*#__PURE__*/React__default.createElement("br", null), !timedOut ? '✅' : '❌', " Time Remaining:", ' ', Math.max(0, timeoutDurationMs - (new Date().getTime() - (timeoutStartedAt !== null && timeoutStartedAt !== void 0 ? timeoutStartedAt : new Date()).getTime())), "ms", /*#__PURE__*/React__default.createElement("br", null), (prediction === null || prediction === void 0 ? void 0 : prediction.faceVisibilityTooLow) ? '❌' : '✅', " Visibility", minCaptureBrightnessThreshold !== undefined && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "\xA0\xA0Brightness:", ' ', (_e = (_d = prediction === null || prediction === void 0 ? void 0 : prediction.brightness) === null || _d === void 0 ? void 0 : _d.toFixed(1)) !== null && _e !== void 0 ? _e : '—', " (min:", ' ', minCaptureBrightnessThreshold, ")")), minCaptureRangeThreshold !== undefined && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "\xA0\xA0Range: ", (_g = (_f = prediction === null || prediction === void 0 ? void 0 : prediction.range) === null || _f === void 0 ? void 0 : _f.toFixed(1)) !== null && _g !== void 0 ? _g : '—', " (min: ", minCaptureRangeThreshold, ")")), minCaptureVarianceThreshold !== undefined && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "\xA0\xA0Variance: ", (_j = (_h = prediction === null || prediction === void 0 ? void 0 : prediction.variance) === null || _h === void 0 ? void 0 : _h.toFixed(1)) !== null && _j !== void 0 ? _j : '—', ' ', "(min: ", minCaptureVarianceThreshold, ")")))), allowManualCapture && (/*#__PURE__*/React__default.createElement(CaptureButtonContainer$1, {
17195
+ })))), debugMode && (/*#__PURE__*/React__default.createElement(DebugStatsPane, null, camera ? (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, "\u2705 Camera: ", camera.label, " (", camera.width, "x", camera.height, ")")) : '❌ Camera not ready', /*#__PURE__*/React__default.createElement("br", null), getDelegate('mediapipe') !== 'NONE' ? '✅' : '❌', " Delegate:", ' ', getDelegate('mediapipe'), /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotDetected) ? '✅' : '❌', " Face Detected", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceNotCentered) ? '✅' : '❌', " Face Centered", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) && !(prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? '✅' : '❌', ' ', "Face", ' ', (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooClose) ? 'Too Close' : (prediction === null || prediction === void 0 ? void 0 : prediction.faceTooFar) ? 'Too Far' : 'Distance Correct', /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceLookingAway) ? '✅' : '❌', " Face Looking Forward", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.faceIsStable) ? '✅' : '❌', " Face Is Stable", /*#__PURE__*/React__default.createElement("br", null), !(prediction === null || prediction === void 0 ? void 0 : prediction.noseIsStable) ? '✅' : '❌', " Nose Is Stable", /*#__PURE__*/React__default.createElement("br", null), !timedOut ? '✅' : '❌', " Time Remaining:", ' ', Math.max(0, timeoutDurationMs - (new Date().getTime() - (timeoutStartedAt !== null && timeoutStartedAt !== void 0 ? timeoutStartedAt : new Date()).getTime())), "ms", /*#__PURE__*/React__default.createElement("br", null), (prediction === null || prediction === void 0 ? void 0 : prediction.faceVisibilityTooLow) ? '❌' : '✅', " Visibility", minCaptureBrightnessThreshold !== undefined && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "\xA0\xA0Brightness:", ' ', (_e = (_d = prediction === null || prediction === void 0 ? void 0 : prediction.brightness) === null || _d === void 0 ? void 0 : _d.toFixed(1)) !== null && _e !== void 0 ? _e : '—', " (min:", ' ', minCaptureBrightnessThreshold, ")")), minCaptureRangeThreshold !== undefined && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "\xA0\xA0Range: ", (_g = (_f = prediction === null || prediction === void 0 ? void 0 : prediction.range) === null || _f === void 0 ? void 0 : _f.toFixed(1)) !== null && _g !== void 0 ? _g : '—', " (min: ", minCaptureRangeThreshold, ")")), minCaptureVarianceThreshold !== undefined && (/*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("br", null), "\xA0\xA0Variance: ", (_j = (_h = prediction === null || prediction === void 0 ? void 0 : prediction.variance) === null || _h === void 0 ? void 0 : _h.toFixed(1)) !== null && _j !== void 0 ? _j : '—', ' ', "(min: ", minCaptureVarianceThreshold, ")")))), allowManualCapture && (/*#__PURE__*/React__default.createElement(CaptureButtonContainer$1, {
17188
17196
  className: classNames.manualCaptureBtnContainer
17189
17197
  }, /*#__PURE__*/React__default.createElement(CaptureButton$1, {
17190
17198
  className: classNames.manualCaptureBtn,
@@ -25505,6 +25513,99 @@ globalThis.IDmissionSDK = {
25505
25513
  setServerUrl: setServerUrl
25506
25514
  };
25507
25515
 
25516
+ var visionTasksBasePath = "https://websdk-cdn-dev.idmission.com/assets/vision_wasm_internal_0.10.7";
25517
+ var visionRuntimeHash = 'tdLjRcm8XLETT+lUxF1oNst5jULaTGDUc2YtazwbGnLVGD0D/4A274KuJF+adneW';
25518
+ var wasmStderrPatterns = ['TensorFlow Lite', 'static-sized tensors', 'Attempting to use a delegate'];
25519
+ function isWasmStderr(msg) {
25520
+ return wasmStderrPatterns.some(function (p) {
25521
+ return msg.includes(p);
25522
+ });
25523
+ }
25524
+ var quietWasmRefCount = 0;
25525
+ var savedNativeError = null;
25526
+ /**
25527
+ * Wraps an async operation that initializes WASM/TFLite models, temporarily
25528
+ * intercepting console.error to downgrade known-benign TF Lite stderr messages
25529
+ * (routed through Emscripten's fd_write -> console.error) to debug level.
25530
+ *
25531
+ * Uses a reference count so overlapping calls share a single patched handler
25532
+ * and only restore the original console.error when the last one completes.
25533
+ */
25534
+ function withQuietWasm(fn) {
25535
+ return __awaiter(this, void 0, void 0, function () {
25536
+ return __generator(this, function (_a) {
25537
+ if (quietWasmRefCount++ === 0) {
25538
+ savedNativeError = console.error; // eslint-disable-line no-console
25539
+ console.error = function () {
25540
+ var args = [];
25541
+ for (var _i = 0; _i < arguments.length; _i++) {
25542
+ args[_i] = arguments[_i];
25543
+ }
25544
+ if (isWasmStderr(String(args[0]))) {
25545
+ debug.apply(void 0, args);
25546
+ return;
25547
+ }
25548
+ savedNativeError.apply(void 0, args);
25549
+ };
25550
+ }
25551
+ return [2 /*return*/, fn()["finally"](function () {
25552
+ if (--quietWasmRefCount === 0) {
25553
+ console.error = savedNativeError; // eslint-disable-line no-console
25554
+ savedNativeError = null;
25555
+ }
25556
+ })];
25557
+ });
25558
+ });
25559
+ }
25560
+ var visionRuntimePreloading = false;
25561
+ function preloadVisionRuntime() {
25562
+ return __awaiter(this, void 0, void 0, function () {
25563
+ function handleDownloadProgress(event) {
25564
+ var detail = event.detail;
25565
+ if (detail.url !== url) return;
25566
+ progressByUseCase.visionRuntime = sumUpProgressForDependencies([url]);
25567
+ document.dispatchEvent(new CustomEvent('idmission.preloadProgress.visionRuntime', {
25568
+ detail: progressByUseCase.visionRuntime
25569
+ }));
25570
+ }
25571
+ var url;
25572
+ return __generator(this, function (_a) {
25573
+ switch (_a.label) {
25574
+ case 0:
25575
+ if (visionRuntimePreloading) return [2 /*return*/, new Promise(function (resolve) {
25576
+ setInterval(function () {
25577
+ if (!visionRuntimePreloading) resolve();
25578
+ }, 100);
25579
+ })];
25580
+ visionRuntimePreloading = true;
25581
+ url = "".concat(visionTasksBasePath, "/vision_wasm_internal.wasm");
25582
+ document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
25583
+ _a.label = 1;
25584
+ case 1:
25585
+ _a.trys.push([1,, 3, 4]);
25586
+ return [4 /*yield*/, preloadDependency(url, visionRuntimeHash)];
25587
+ case 2:
25588
+ _a.sent();
25589
+ return [3 /*break*/, 4];
25590
+ case 3:
25591
+ document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
25592
+ visionRuntimePreloading = false;
25593
+ return [7 /*endfinally*/];
25594
+ case 4:
25595
+ return [2 /*return*/];
25596
+ }
25597
+ });
25598
+ });
25599
+ }
25600
+
25601
+ var VisionRuntime = /*#__PURE__*/Object.freeze({
25602
+ __proto__: null,
25603
+ preloadVisionRuntime: preloadVisionRuntime,
25604
+ visionRuntimeHash: visionRuntimeHash,
25605
+ visionTasksBasePath: visionTasksBasePath,
25606
+ withQuietWasm: withQuietWasm
25607
+ });
25608
+
25508
25609
  // Verify a given delegate (GPU or CPU) can actually run a TFLite model in this
25509
25610
  // browser. Creates an ImageSegmenter, runs it once against an empty canvas,
25510
25611
  // and lets any thrown error propagate up so the caller can fall back. We
@@ -25553,11 +25654,12 @@ var CapabilityProbe = /*#__PURE__*/Object.freeze({
25553
25654
  verifyMediaPipeDelegate: verifyMediaPipeDelegate
25554
25655
  });
25555
25656
 
25657
+ var RUNTIME$3 = 'mediapipe';
25556
25658
  var detector = null;
25557
25659
  var detectorSettings = null;
25558
25660
  function load$3(_a) {
25559
25661
  return __awaiter(this, arguments, void 0, function (_b) {
25560
- var cachedBuffer, delegate;
25662
+ var delegate, cachedBuffer;
25561
25663
  var _this = this;
25562
25664
  var modelAssetPath = _b.modelAssetPath,
25563
25665
  scoreThreshold = _b.scoreThreshold;
@@ -25566,11 +25668,11 @@ function load$3(_a) {
25566
25668
  case 0:
25567
25669
  if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.scoreThreshold) === scoreThreshold) return [2 /*return*/];
25568
25670
  close$3();
25569
- if (modelCapabilities.delegate === 'NONE') {
25671
+ delegate = getDelegate(RUNTIME$3);
25672
+ if (delegate === 'NONE') {
25570
25673
  throw new Error('No available delegate for document detector.');
25571
25674
  }
25572
25675
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
25573
- delegate = modelCapabilities.delegate;
25574
25676
  return [4 /*yield*/, withQuietWasm(function () {
25575
25677
  return __awaiter(_this, void 0, void 0, function () {
25576
25678
  var _a, _b;
@@ -25679,11 +25781,12 @@ var DocumentDetection = /*#__PURE__*/Object.freeze({
25679
25781
  testAgainstKnownImage: testAgainstKnownImage
25680
25782
  });
25681
25783
 
25784
+ var RUNTIME$2 = 'mediapipe';
25682
25785
  var classifier$1 = null;
25683
25786
  var classifierSettings$1 = null;
25684
25787
  function load$2(_a) {
25685
25788
  return __awaiter(this, arguments, void 0, function (_b) {
25686
- var cachedBuffer, delegate;
25789
+ var delegate, cachedBuffer;
25687
25790
  var _this = this;
25688
25791
  var modelAssetPath = _b.modelAssetPath;
25689
25792
  return __generator(this, function (_c) {
@@ -25691,11 +25794,11 @@ function load$2(_a) {
25691
25794
  case 0:
25692
25795
  if (classifier$1 && (classifierSettings$1 === null || classifierSettings$1 === void 0 ? void 0 : classifierSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/];
25693
25796
  close$2();
25694
- if (modelCapabilities.delegate === 'NONE') {
25797
+ delegate = getDelegate(RUNTIME$2);
25798
+ if (delegate === 'NONE') {
25695
25799
  throw new Error('No available delegate for focus detector.');
25696
25800
  }
25697
25801
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
25698
- delegate = modelCapabilities.delegate;
25699
25802
  return [4 /*yield*/, withQuietWasm(function () {
25700
25803
  return __awaiter(_this, void 0, void 0, function () {
25701
25804
  var _a, _b;
@@ -25762,6 +25865,7 @@ var Focus = /*#__PURE__*/Object.freeze({
25762
25865
  predict: predict$2
25763
25866
  });
25764
25867
 
25868
+ var RUNTIME$1 = 'mediapipe';
25765
25869
  var classifier = null;
25766
25870
  var classifierSettings = null;
25767
25871
  function load$1(_a) {
@@ -25774,7 +25878,7 @@ function load$1(_a) {
25774
25878
  case 0:
25775
25879
  if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/];
25776
25880
  close$1();
25777
- if (modelCapabilities.delegate === 'NONE') {
25881
+ if (getDelegate(RUNTIME$1) === 'NONE') {
25778
25882
  throw new Error('No available delegate for barcode readability model.');
25779
25883
  }
25780
25884
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
@@ -25846,6 +25950,7 @@ var BarcodeReadability = /*#__PURE__*/Object.freeze({
25846
25950
  predict: predict$1
25847
25951
  });
25848
25952
 
25953
+ var RUNTIME = 'mediapipe';
25849
25954
  // MediaPipe canonical face mesh (468-point) indices used to construct the
25850
25955
  // BlazeFace-style 6-keypoint Face shape. Order matches FaceDetection.ts:
25851
25956
  // [0] right eye [1] left eye [2] nose tip
@@ -25914,29 +26019,30 @@ function load(_a) {
25914
26019
  });
25915
26020
  });
25916
26021
  }
25917
- var cachedBuffer, firstError_1;
26022
+ var initialDelegate, cachedBuffer, firstError_1;
25918
26023
  var modelAssetPath = _b.modelAssetPath;
25919
26024
  return __generator(this, function (_c) {
25920
26025
  switch (_c.label) {
25921
26026
  case 0:
25922
26027
  if (landmarker && (landmarkerSettings === null || landmarkerSettings === void 0 ? void 0 : landmarkerSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/];
25923
26028
  close();
25924
- if (modelCapabilities.delegate === 'NONE') {
26029
+ initialDelegate = getDelegate(RUNTIME);
26030
+ if (initialDelegate === 'NONE') {
25925
26031
  throw new Error('No available delegate for face landmarker.');
25926
26032
  }
25927
26033
  cachedBuffer = getCachedModelBuffer(modelAssetPath);
25928
26034
  _c.label = 1;
25929
26035
  case 1:
25930
26036
  _c.trys.push([1, 3,, 7]);
25931
- return [4 /*yield*/, tryDelegate(modelCapabilities.delegate)];
26037
+ return [4 /*yield*/, tryDelegate(initialDelegate)];
25932
26038
  case 2:
25933
26039
  landmarker = _c.sent();
25934
26040
  return [3 /*break*/, 7];
25935
26041
  case 3:
25936
26042
  firstError_1 = _c.sent();
25937
- if (!(modelCapabilities.delegate === 'GPU')) return [3 /*break*/, 5];
26043
+ if (!(initialDelegate === 'GPU')) return [3 /*break*/, 5];
25938
26044
  warn('face landmarker failed known-good frame validation on GPU; falling back to CPU', firstError_1);
25939
- modelCapabilities.delegate = 'CPU';
26045
+ setDelegate(RUNTIME, 'CPU');
25940
26046
  return [4 /*yield*/, tryDelegate('CPU')];
25941
26047
  case 4:
25942
26048
  landmarker = _c.sent();