smartcomply-web-sdk 1.0.26 → 1.0.31

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.
@@ -4428,13 +4428,13 @@ var SmartComplySDK = (() => {
4428
4428
 
4429
4429
  // src/camera/ActionDetector.ts
4430
4430
  var ACTION_CONFIGS = {
4431
- BLINK: { threshold: 0.28, holdFrames: 2 },
4432
- TURN_LEFT: { threshold: 0.35, holdFrames: 5 },
4433
- TURN_RIGHT: { threshold: 0.35, holdFrames: 5 },
4434
- TURN_HEAD: { threshold: 0.35, holdFrames: 5 },
4435
- OPEN_MOUTH: { threshold: 0.35, holdFrames: 3 }
4431
+ BLINK: { threshold: 0.25, holdFrames: 2 },
4432
+ TURN_LEFT: { threshold: 0.3, holdFrames: 3 },
4433
+ TURN_RIGHT: { threshold: 0.3, holdFrames: 3 },
4434
+ TURN_HEAD: { threshold: 0.3, holdFrames: 3 },
4435
+ OPEN_MOUTH: { threshold: 0.3, holdFrames: 2 }
4436
4436
  };
4437
- var DEFAULT_CONFIG = { threshold: 0.45, holdFrames: 6 };
4437
+ var DEFAULT_CONFIG = { threshold: 0.4, holdFrames: 4 };
4438
4438
  var ActionDetector = class {
4439
4439
  constructor(requiredActions) {
4440
4440
  this.requiredActions = requiredActions;
@@ -4486,16 +4486,16 @@ var SmartComplySDK = (() => {
4486
4486
  return (left + right) / 2;
4487
4487
  }
4488
4488
  case "TURN_LEFT": {
4489
- const yaw = this.getHeadYaw(matrix);
4490
- return yaw < -8 ? Math.min(1, Math.abs(yaw) / 25) : 0;
4489
+ const yaw = Math.abs(this.getHeadYaw(matrix));
4490
+ return yaw > 5 ? Math.min(1, yaw / 20) : 0;
4491
4491
  }
4492
4492
  case "TURN_RIGHT": {
4493
- const yaw = this.getHeadYaw(matrix);
4494
- return yaw > 8 ? Math.min(1, yaw / 25) : 0;
4493
+ const yaw = Math.abs(this.getHeadYaw(matrix));
4494
+ return yaw > 5 ? Math.min(1, yaw / 20) : 0;
4495
4495
  }
4496
4496
  case "TURN_HEAD": {
4497
4497
  const yaw = Math.abs(this.getHeadYaw(matrix));
4498
- return yaw > 10 ? Math.min(1, yaw / 25) : 0;
4498
+ return yaw > 5 ? Math.min(1, yaw / 20) : 0;
4499
4499
  }
4500
4500
  case "OPEN_MOUTH":
4501
4501
  return bs2.get("jawOpen") || 0;
@@ -4521,40 +4521,23 @@ var SmartComplySDK = (() => {
4521
4521
 
4522
4522
  // src/modules/liveness/LivenessUI.ts
4523
4523
  var ICONS = {
4524
- BLINK: "\u{1F609}",
4525
- TURN_LEFT: "\u27A1",
4526
- // ➡️ — user turns RIGHT (mirror correction)
4527
- TURN_RIGHT: "\u2B05",
4528
- // ⬅️ — user turns LEFT (mirror correction)
4529
- TURN_HEAD: "\u{1F642}",
4524
+ BLINK: "\u{1F441}",
4525
+ TURN_LEFT: "\u2194",
4526
+ TURN_RIGHT: "\u2194",
4527
+ TURN_HEAD: "\u2194",
4530
4528
  OPEN_MOUTH: "\u{1F62E}"
4531
4529
  };
4532
4530
  var ACTION_CUES = {
4533
- BLINK: `
4534
- <div style="display:flex;flex-direction:column;align-items:center;gap:10px;">
4535
- <div style="font-size:64px;line-height:1;animation:sc-blink 1.2s ease-in-out infinite;">\u{1F441}\uFE0F</div>
4536
- <div style="font-size:13px;font-weight:600;color:#fff;opacity:0.9;letter-spacing:0.5px;">BLINK YOUR EYES</div>
4537
- </div>`,
4538
- TURN_LEFT: `
4539
- <div style="display:flex;flex-direction:column;align-items:center;gap:10px;">
4540
- <div style="font-size:56px;line-height:1;animation:sc-slide-right 1s ease-in-out infinite;">\u27A1\uFE0F</div>
4541
- <div style="font-size:13px;font-weight:600;color:#fff;opacity:0.9;letter-spacing:0.5px;">TURN HEAD RIGHT</div>
4542
- </div>`,
4543
- TURN_RIGHT: `
4544
- <div style="display:flex;flex-direction:column;align-items:center;gap:10px;">
4545
- <div style="font-size:56px;line-height:1;animation:sc-slide-left 1s ease-in-out infinite;">\u2B05\uFE0F</div>
4546
- <div style="font-size:13px;font-weight:600;color:#fff;opacity:0.9;letter-spacing:0.5px;">TURN HEAD LEFT</div>
4547
- </div>`,
4548
- TURN_HEAD: `
4549
- <div style="display:flex;flex-direction:column;align-items:center;gap:10px;">
4550
- <div style="font-size:56px;line-height:1;animation:sc-turn-head 1.4s ease-in-out infinite;">\u2194\uFE0F</div>
4551
- <div style="font-size:13px;font-weight:600;color:#fff;opacity:0.9;letter-spacing:0.5px;">TURN HEAD SIDE TO SIDE</div>
4552
- </div>`,
4553
- OPEN_MOUTH: `
4554
- <div style="display:flex;flex-direction:column;align-items:center;gap:10px;">
4555
- <div style="font-size:64px;line-height:1;animation:sc-mouth 1.2s ease-in-out infinite;">\u{1F62E}</div>
4556
- <div style="font-size:13px;font-weight:600;color:#fff;opacity:0.9;letter-spacing:0.5px;">OPEN YOUR MOUTH</div>
4557
- </div>`
4531
+ BLINK: `<div style="font-size:52px;line-height:1;animation:sc-blink 1.2s ease-in-out infinite;">\u{1F441}\uFE0F</div>
4532
+ <div style="font-size:12px;font-weight:600;color:#fff;margin-top:6px;letter-spacing:0.5px;">BLINK YOUR EYES</div>`,
4533
+ TURN_LEFT: `<div style="font-size:52px;line-height:1;animation:sc-turn-head 1.4s ease-in-out infinite;">\u2194\uFE0F</div>
4534
+ <div style="font-size:12px;font-weight:600;color:#fff;margin-top:6px;letter-spacing:0.5px;">TURN HEAD SIDEWAYS</div>`,
4535
+ TURN_RIGHT: `<div style="font-size:52px;line-height:1;animation:sc-turn-head 1.4s ease-in-out infinite;">\u2194\uFE0F</div>
4536
+ <div style="font-size:12px;font-weight:600;color:#fff;margin-top:6px;letter-spacing:0.5px;">TURN HEAD SIDEWAYS</div>`,
4537
+ TURN_HEAD: `<div style="font-size:52px;line-height:1;animation:sc-turn-head 1.4s ease-in-out infinite;">\u2194\uFE0F</div>
4538
+ <div style="font-size:12px;font-weight:600;color:#fff;margin-top:6px;letter-spacing:0.5px;">TURN HEAD SIDE TO SIDE</div>`,
4539
+ OPEN_MOUTH: `<div style="font-size:52px;line-height:1;animation:sc-mouth 1.2s ease-in-out infinite;">\u{1F62E}</div>
4540
+ <div style="font-size:12px;font-weight:600;color:#fff;margin-top:6px;letter-spacing:0.5px;">OPEN YOUR MOUTH</div>`
4558
4541
  };
4559
4542
  function injectLivenessKeyframes() {
4560
4543
  if (document.getElementById("sc-liveness-kf")) return;
@@ -4563,37 +4546,23 @@ var SmartComplySDK = (() => {
4563
4546
  s2.textContent = `
4564
4547
  @keyframes sc-blink {
4565
4548
  0%,100% { transform:scaleY(1); }
4566
- 40% { transform:scaleY(0.1); }
4567
- 50% { transform:scaleY(1); }
4568
- }
4569
- @keyframes sc-slide-left {
4570
- 0%,100% { transform:translateX(0); opacity:1; }
4571
- 50% { transform:translateX(-14px); opacity:0.6; }
4572
- }
4573
- @keyframes sc-slide-right {
4574
- 0%,100% { transform:translateX(0); opacity:1; }
4575
- 50% { transform:translateX(14px); opacity:0.6; }
4549
+ 40% { transform:scaleY(0.1); }
4550
+ 50% { transform:scaleY(1); }
4576
4551
  }
4577
4552
  @keyframes sc-turn-head {
4578
- 0%,100% { transform:translateX(0); }
4579
- 25% { transform:translateX(-12px); }
4580
- 75% { transform:translateX(12px); }
4553
+ 0%,100% { transform:translateX(0); }
4554
+ 25% { transform:translateX(-12px); }
4555
+ 75% { transform:translateX(12px); }
4581
4556
  }
4582
4557
  @keyframes sc-mouth {
4583
- 0%,100% { transform:scaleY(1); }
4584
- 40% { transform:scaleY(1.25); }
4585
- 60% { transform:scaleY(1); }
4558
+ 0%,100% { transform:scaleY(1); }
4559
+ 40% { transform:scaleY(1.25); }
4560
+ 60% { transform:scaleY(1); }
4586
4561
  }
4587
4562
  @keyframes sc-pop-in {
4588
4563
  0% { transform:scale(0.7); opacity:0; }
4589
4564
  60% { transform:scale(1.05); }
4590
- 100% { transform:scale(1); opacity:1; }
4591
- }
4592
- @keyframes sc-cue-fade {
4593
- 0% { opacity:0; transform:translateY(8px); }
4594
- 20% { opacity:1; transform:translateY(0); }
4595
- 80% { opacity:1; transform:translateY(0); }
4596
- 100% { opacity:0; transform:translateY(-8px); }
4565
+ 100% { transform:scale(1); opacity:1; }
4597
4566
  }
4598
4567
  `;
4599
4568
  document.head.appendChild(s2);
@@ -4619,81 +4588,107 @@ var SmartComplySDK = (() => {
4619
4588
  this.totalActions = challenge.actions.length;
4620
4589
  this.root = document.createElement("div");
4621
4590
  this.root.style.cssText = `
4622
- position:relative;width:100%;max-width:420px;margin:0 auto;
4591
+ display:flex;flex-direction:row;width:100%;max-width:560px;margin:0 auto;
4623
4592
  background:#0a0a0a;border-radius:16px;overflow:hidden;
4624
4593
  font-family:system-ui,-apple-system,sans-serif;
4625
4594
  box-shadow:0 8px 32px rgba(0,0,0,0.4);
4595
+ min-height:340px;
4596
+ `;
4597
+ const camCol = document.createElement("div");
4598
+ camCol.style.cssText = `
4599
+ position:relative;flex:0 0 58%;
4600
+ background:#000;overflow:hidden;
4626
4601
  `;
4627
4602
  this.videoEl = document.createElement("video");
4628
4603
  this.videoEl.autoplay = true;
4629
4604
  this.videoEl.playsInline = true;
4630
4605
  this.videoEl.muted = true;
4631
- this.videoEl.style.cssText = "width:100%;display:block;transform:scaleX(-1);aspect-ratio:3/4;object-fit:cover;";
4606
+ this.videoEl.style.cssText = `
4607
+ width:100%;height:100%;display:block;
4608
+ transform:scaleX(-1);object-fit:cover;
4609
+ min-height:320px;
4610
+ `;
4632
4611
  const guideWrap = document.createElement("div");
4633
4612
  guideWrap.style.cssText = `
4634
- position:absolute;top:8%;left:50%;transform:translateX(-50%);
4635
- width:180px;height:240px;pointer-events:none;
4613
+ position:absolute;top:50%;left:50%;
4614
+ transform:translate(-50%,-55%);
4615
+ width:140px;height:180px;pointer-events:none;
4636
4616
  `;
4637
4617
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
4638
- svg.setAttribute("viewBox", "0 0 180 240");
4618
+ svg.setAttribute("viewBox", "0 0 140 180");
4639
4619
  svg.style.cssText = "width:100%;height:100%;";
4640
- const bgOval = document.createElementNS(
4641
- "http://www.w3.org/2000/svg",
4642
- "ellipse"
4643
- );
4644
- bgOval.setAttribute("cx", "90");
4645
- bgOval.setAttribute("cy", "120");
4646
- bgOval.setAttribute("rx", "85");
4647
- bgOval.setAttribute("ry", "115");
4620
+ const bgOval = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
4621
+ bgOval.setAttribute("cx", "70");
4622
+ bgOval.setAttribute("cy", "90");
4623
+ bgOval.setAttribute("rx", "64");
4624
+ bgOval.setAttribute("ry", "86");
4648
4625
  bgOval.setAttribute("fill", "none");
4649
- bgOval.setAttribute("stroke", "rgba(255,255,255,0.25)");
4650
- bgOval.setAttribute("stroke-width", "2.5");
4651
- bgOval.setAttribute("stroke-dasharray", "8 4");
4652
- const confOval = document.createElementNS(
4653
- "http://www.w3.org/2000/svg",
4654
- "ellipse"
4655
- );
4656
- confOval.setAttribute("cx", "90");
4657
- confOval.setAttribute("cy", "120");
4658
- confOval.setAttribute("rx", "85");
4659
- confOval.setAttribute("ry", "115");
4626
+ bgOval.setAttribute("stroke", "rgba(255,255,255,0.3)");
4627
+ bgOval.setAttribute("stroke-width", "2");
4628
+ bgOval.setAttribute("stroke-dasharray", "6 3");
4629
+ const confOval = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
4630
+ confOval.setAttribute("cx", "70");
4631
+ confOval.setAttribute("cy", "90");
4632
+ confOval.setAttribute("rx", "64");
4633
+ confOval.setAttribute("ry", "86");
4660
4634
  confOval.setAttribute("fill", "none");
4661
4635
  confOval.setAttribute("stroke", "#22c55e");
4662
- confOval.setAttribute("stroke-width", "3.5");
4663
- const circumference = 2 * Math.PI * Math.sqrt((85 * 85 + 115 * 115) / 2);
4664
- confOval.setAttribute(
4665
- "stroke-dasharray",
4666
- `${circumference}`
4667
- );
4668
- confOval.setAttribute("stroke-dashoffset", `${circumference}`);
4669
- confOval.style.cssText = "transition:stroke-dashoffset 0.15s ease;transform:rotate(-90deg);transform-origin:90px 120px;";
4636
+ confOval.setAttribute("stroke-width", "3");
4637
+ const circ = 2 * Math.PI * Math.sqrt((64 * 64 + 86 * 86) / 2);
4638
+ confOval.setAttribute("stroke-dasharray", `${circ}`);
4639
+ confOval.setAttribute("stroke-dashoffset", `${circ}`);
4640
+ confOval.style.cssText = "transition:stroke-dashoffset 0.15s ease;transform:rotate(-90deg);transform-origin:70px 90px;";
4670
4641
  this.confidenceRingEl = confOval;
4671
4642
  svg.appendChild(bgOval);
4672
4643
  svg.appendChild(confOval);
4673
4644
  guideWrap.appendChild(svg);
4674
- const topBar = document.createElement("div");
4675
- topBar.style.cssText = `
4645
+ const camTop = document.createElement("div");
4646
+ camTop.style.cssText = `
4676
4647
  position:absolute;top:0;left:0;right:0;
4677
- background:linear-gradient(180deg,rgba(0,0,0,0.7) 0%,transparent 100%);
4678
- padding:16px 16px 32px;
4648
+ background:linear-gradient(180deg,rgba(0,0,0,0.8) 0%,transparent 100%);
4649
+ padding:10px 12px 28px;
4679
4650
  `;
4680
4651
  this.instructionEl = document.createElement("div");
4681
4652
  this.instructionEl.style.cssText = `
4682
- color:#fff;font-size:15px;font-weight:600;text-align:center;
4683
- line-height:1.4;
4653
+ color:#fff;font-size:13px;font-weight:600;text-align:center;line-height:1.4;
4684
4654
  `;
4685
4655
  this.instructionEl.textContent = challenge.instruction;
4686
- topBar.appendChild(this.instructionEl);
4687
- const bottomPanel = document.createElement("div");
4688
- bottomPanel.style.cssText = `
4656
+ camTop.appendChild(this.instructionEl);
4657
+ const camBottom = document.createElement("div");
4658
+ camBottom.style.cssText = `
4689
4659
  position:absolute;bottom:0;left:0;right:0;
4690
- background:linear-gradient(0deg,rgba(0,0,0,0.85) 0%,rgba(0,0,0,0.6) 60%,transparent 100%);
4691
- padding:24px 16px 16px;
4660
+ background:linear-gradient(0deg,rgba(0,0,0,0.7) 0%,transparent 100%);
4661
+ padding:24px 10px 8px;text-align:center;
4662
+ `;
4663
+ this.timerEl = document.createElement("div");
4664
+ this.timerEl.style.cssText = `
4665
+ color:rgba(255,255,255,0.5);font-size:11px;font-variant-numeric:tabular-nums;
4666
+ `;
4667
+ camBottom.appendChild(this.timerEl);
4668
+ this.actionCueEl = document.createElement("div");
4669
+ this.actionCueEl.style.cssText = `
4670
+ position:absolute;bottom:36px;left:50%;transform:translateX(-50%);
4671
+ z-index:5;pointer-events:none;display:none;text-align:center;
4672
+ background:rgba(0,0,0,0.6);backdrop-filter:blur(4px);
4673
+ border-radius:14px;padding:10px 18px;min-width:130px;
4674
+ border:1.5px solid rgba(255,255,255,0.12);
4675
+ `;
4676
+ camCol.appendChild(this.videoEl);
4677
+ camCol.appendChild(guideWrap);
4678
+ camCol.appendChild(camTop);
4679
+ camCol.appendChild(camBottom);
4680
+ camCol.appendChild(this.actionCueEl);
4681
+ const stepsCol = document.createElement("div");
4682
+ stepsCol.style.cssText = `
4683
+ flex:1;display:flex;flex-direction:column;
4684
+ padding:16px 14px;gap:8px;
4685
+ background:#111;border-left:1px solid rgba(255,255,255,0.06);
4686
+ justify-content:space-between;
4692
4687
  `;
4693
4688
  const progressWrap = document.createElement("div");
4694
4689
  progressWrap.style.cssText = `
4695
- height:3px;background:rgba(255,255,255,0.15);border-radius:2px;
4696
- margin-bottom:14px;overflow:hidden;
4690
+ height:3px;background:rgba(255,255,255,0.1);border-radius:2px;overflow:hidden;
4691
+ margin-bottom:4px;
4697
4692
  `;
4698
4693
  this.progressBarEl = document.createElement("div");
4699
4694
  this.progressBarEl.style.cssText = `
@@ -4701,80 +4696,52 @@ var SmartComplySDK = (() => {
4701
4696
  border-radius:2px;transition:width 0.4s ease;
4702
4697
  `;
4703
4698
  progressWrap.appendChild(this.progressBarEl);
4704
- bottomPanel.appendChild(progressWrap);
4705
4699
  this.stepsEl = document.createElement("div");
4706
- this.stepsEl.style.cssText = `
4707
- position:absolute;top:10px;right:10px;
4708
- display:flex;flex-direction:row;gap:6px;
4709
- flex-wrap:wrap;justify-content:flex-end;
4710
- z-index:6;pointer-events:none;
4711
- max-width:calc(100% - 20px);
4712
- `;
4700
+ this.stepsEl.style.cssText = "display:flex;flex-direction:column;gap:6px;flex:1;";
4713
4701
  for (let i2 = 0; i2 < challenge.actions.length; i2++) {
4714
4702
  const action = challenge.actions[i2];
4715
4703
  const step = document.createElement("div");
4716
4704
  step.dataset.action = action;
4717
4705
  step.style.cssText = `
4718
- display:flex;align-items:center;gap:5px;
4719
- padding:5px 10px;border-radius:20px;
4720
- background:rgba(0,0,0,0.55);
4721
- backdrop-filter:blur(4px);
4722
- border:1.5px solid rgba(255,255,255,0.15);
4706
+ display:flex;align-items:center;gap:8px;
4707
+ padding:8px 10px;border-radius:10px;
4708
+ background:rgba(255,255,255,0.04);
4709
+ border:1px solid rgba(255,255,255,0.06);
4723
4710
  transition:all 0.3s ease;
4724
- opacity:${i2 === 0 ? "1" : "0.5"};
4711
+ opacity:${i2 === 0 ? "1" : "0.45"};
4725
4712
  `;
4726
4713
  const num = document.createElement("div");
4727
4714
  num.className = "sc-step-num";
4728
4715
  num.style.cssText = `
4729
- width:20px;height:20px;border-radius:50%;
4716
+ width:24px;height:24px;border-radius:50%;flex-shrink:0;
4730
4717
  display:flex;align-items:center;justify-content:center;
4731
- font-size:11px;font-weight:700;color:#fff;
4732
- background:rgba(255,255,255,0.12);
4733
- border:1.5px solid rgba(255,255,255,0.25);
4734
- transition:all 0.3s ease;flex-shrink:0;
4718
+ font-size:12px;font-weight:700;color:#fff;
4719
+ background:rgba(255,255,255,0.1);
4720
+ border:1.5px solid rgba(255,255,255,0.2);
4721
+ transition:all 0.3s ease;
4735
4722
  `;
4736
4723
  num.textContent = String(i2 + 1);
4724
+ const label = document.createElement("div");
4725
+ label.style.cssText = "color:#fff;font-size:12px;font-weight:500;flex:1;line-height:1.3;";
4726
+ label.textContent = this.describeAction(action);
4737
4727
  const icon = document.createElement("div");
4738
- icon.className = "sc-step-icon";
4739
- icon.style.cssText = "font-size:14px;flex-shrink:0;";
4728
+ icon.style.cssText = "font-size:16px;flex-shrink:0;";
4740
4729
  icon.textContent = ICONS[action] || "";
4741
4730
  step.appendChild(num);
4731
+ step.appendChild(label);
4742
4732
  step.appendChild(icon);
4743
4733
  this.stepsEl.appendChild(step);
4744
4734
  }
4745
- this.timerEl = document.createElement("div");
4746
- this.timerEl.style.cssText = `
4747
- text-align:center;color:rgba(255,255,255,0.5);
4748
- font-size:11px;font-variant-numeric:tabular-nums;
4749
- `;
4750
- bottomPanel.appendChild(this.timerEl);
4735
+ stepsCol.appendChild(progressWrap);
4736
+ stepsCol.appendChild(this.stepsEl);
4751
4737
  this.overlayEl = document.createElement("div");
4752
4738
  this.overlayEl.style.cssText = `
4753
4739
  position:absolute;inset:0;display:none;align-items:center;
4754
4740
  justify-content:center;z-index:10;
4755
- background:rgba(0,0,0,0.85);backdrop-filter:blur(8px);
4756
- transition:opacity 0.3s ease;
4757
- `;
4758
- this.actionCueEl = document.createElement("div");
4759
- this.actionCueEl.style.cssText = `
4760
- position:absolute;
4761
- top:50%;left:50%;transform:translate(-50%,-50%);
4762
- z-index:5;pointer-events:none;
4763
- display:none;
4764
- text-align:center;
4765
- background:rgba(0,0,0,0.55);
4766
- backdrop-filter:blur(4px);
4767
- border-radius:20px;
4768
- padding:18px 28px;
4769
- min-width:160px;
4770
- border:1.5px solid rgba(255,255,255,0.15);
4741
+ background:rgba(0,0,0,0.88);backdrop-filter:blur(8px);
4771
4742
  `;
4772
- this.root.appendChild(this.videoEl);
4773
- this.root.appendChild(guideWrap);
4774
- this.root.appendChild(topBar);
4775
- this.root.appendChild(this.stepsEl);
4776
- this.root.appendChild(bottomPanel);
4777
- this.root.appendChild(this.actionCueEl);
4743
+ this.root.appendChild(camCol);
4744
+ this.root.appendChild(stepsCol);
4778
4745
  this.root.appendChild(this.overlayEl);
4779
4746
  container.appendChild(this.root);
4780
4747
  this.startTimer(challenge.time_limit_seconds);
@@ -4784,7 +4751,6 @@ var SmartComplySDK = (() => {
4784
4751
  if (!this.stepsEl || !this.progressBarEl) return;
4785
4752
  let completed = 0;
4786
4753
  const activeState = states.find((s2) => s2.active && !s2.detected) ?? null;
4787
- const activeAction = activeState?.action ?? null;
4788
4754
  for (const state of states) {
4789
4755
  const step = this.stepsEl.querySelector(
4790
4756
  `[data-action="${state.action}"]`
@@ -4794,7 +4760,8 @@ var SmartComplySDK = (() => {
4794
4760
  if (state.detected) {
4795
4761
  completed++;
4796
4762
  step.style.opacity = "1";
4797
- step.style.background = "rgba(34,197,94,0.15)";
4763
+ step.style.background = "rgba(34,197,94,0.12)";
4764
+ step.style.borderColor = "rgba(34,197,94,0.3)";
4798
4765
  if (num) {
4799
4766
  num.style.background = "#22c55e";
4800
4767
  num.style.borderColor = "#22c55e";
@@ -4802,7 +4769,8 @@ var SmartComplySDK = (() => {
4802
4769
  }
4803
4770
  } else if (state.active) {
4804
4771
  step.style.opacity = "1";
4805
- step.style.background = "rgba(59,130,246,0.15)";
4772
+ step.style.background = "rgba(59,130,246,0.12)";
4773
+ step.style.borderColor = "rgba(59,130,246,0.3)";
4806
4774
  if (num) {
4807
4775
  num.style.borderColor = "#3b82f6";
4808
4776
  num.style.background = "rgba(59,130,246,0.3)";
@@ -4812,16 +4780,12 @@ var SmartComplySDK = (() => {
4812
4780
  const pct = this.totalActions > 0 ? completed / this.totalActions * 100 : 0;
4813
4781
  this.progressBarEl.style.width = `${pct}%`;
4814
4782
  if (this.confidenceRingEl) {
4815
- const circumference = 2 * Math.PI * Math.sqrt((85 * 85 + 115 * 115) / 2);
4783
+ const circ = 2 * Math.PI * Math.sqrt((64 * 64 + 86 * 86) / 2);
4816
4784
  const conf = activeState ? activeState.confidence : 0;
4817
- const offset = circumference * (1 - conf);
4818
- this.confidenceRingEl.setAttribute("stroke-dashoffset", `${offset}`);
4819
- this.confidenceRingEl.setAttribute(
4820
- "stroke",
4821
- conf > 0.6 ? "#22c55e" : "#3b82f6"
4822
- );
4785
+ this.confidenceRingEl.setAttribute("stroke-dashoffset", `${circ * (1 - conf)}`);
4786
+ this.confidenceRingEl.setAttribute("stroke", conf > 0.6 ? "#22c55e" : "#3b82f6");
4823
4787
  }
4824
- this.updateActionCue(activeAction);
4788
+ this.updateActionCue(activeState?.action ?? null);
4825
4789
  }
4826
4790
  updateActionCue(action) {
4827
4791
  if (!this.actionCueEl) return;
@@ -4844,18 +4808,14 @@ var SmartComplySDK = (() => {
4844
4808
  this.actionCueEl.style.animation = "sc-pop-in 0.3s ease forwards";
4845
4809
  }
4846
4810
  updateInstruction(text) {
4847
- if (this.instructionEl) {
4848
- this.instructionEl.textContent = text;
4849
- }
4811
+ if (this.instructionEl) this.instructionEl.textContent = text;
4850
4812
  }
4851
4813
  stopTimer() {
4852
4814
  if (this.timerInterval) {
4853
4815
  clearInterval(this.timerInterval);
4854
4816
  this.timerInterval = null;
4855
4817
  }
4856
- if (this.timerEl) {
4857
- this.timerEl.textContent = "";
4858
- }
4818
+ if (this.timerEl) this.timerEl.textContent = "";
4859
4819
  }
4860
4820
  showResult(status, verificationId) {
4861
4821
  return new Promise((resolve) => {
@@ -4865,38 +4825,22 @@ var SmartComplySDK = (() => {
4865
4825
  }
4866
4826
  if (this.actionCueEl) this.actionCueEl.style.display = "none";
4867
4827
  this.stopTimer();
4868
- const isProcessing = status === "processing";
4828
+ const ok = status === "processing";
4869
4829
  this.overlayEl.style.display = "flex";
4870
4830
  this.overlayEl.innerHTML = `
4871
4831
  <div style="text-align:center;color:#fff;animation:sc-pop-in 0.35s ease;padding:24px;">
4872
- <div style="
4873
- width:80px;height:80px;border-radius:50%;margin:0 auto 20px;
4874
- display:flex;align-items:center;justify-content:center;
4875
- font-size:36px;
4876
- background:${isProcessing ? "rgba(34,197,94,0.2)" : "rgba(239,68,68,0.2)"};
4877
- border:3px solid ${isProcessing ? "#22c55e" : "#ef4444"};
4878
- ">${isProcessing ? "\u2713" : "\u2717"}</div>
4879
- <div style="font-size:19px;font-weight:700;margin-bottom:8px;">
4880
- ${isProcessing ? "Identity Check Submitted" : "Submission Failed"}
4832
+ <div style="width:72px;height:72px;border-radius:50%;margin:0 auto 16px;display:flex;align-items:center;justify-content:center;font-size:32px;
4833
+ background:${ok ? "rgba(34,197,94,0.2)" : "rgba(239,68,68,0.2)"};
4834
+ border:3px solid ${ok ? "#22c55e" : "#ef4444"};">
4835
+ ${ok ? "\u2713" : "\u2715"}
4881
4836
  </div>
4882
- <div style="font-size:13px;opacity:0.65;line-height:1.6;margin-bottom:${verificationId ? "16px" : "0"};">
4883
- ${isProcessing ? "Your identity is being verified.<br>You'll be notified of the outcome shortly." : "Something went wrong. Please try again."}
4884
- </div>
4885
- ${verificationId ? `
4886
- <div style="
4887
- margin-top:4px;padding:8px 14px;border-radius:8px;
4888
- background:rgba(255,255,255,0.08);display:inline-block;
4889
- font-size:11px;color:rgba(255,255,255,0.5);letter-spacing:0.3px;
4890
- ">Ref: #${verificationId}</div>` : ""}
4891
- </div>
4892
- `;
4837
+ <div style="font-size:17px;font-weight:700;margin-bottom:8px;">${ok ? "Identity Check Submitted" : "Submission Failed"}</div>
4838
+ <div style="font-size:12px;opacity:0.6;line-height:1.6;">${ok ? "Your identity is being verified.<br>You'll be notified of the outcome shortly." : "Something went wrong. Please try again."}</div>
4839
+ ${verificationId ? `<div style="margin-top:12px;padding:6px 12px;border-radius:8px;background:rgba(255,255,255,0.07);display:inline-block;font-size:11px;color:rgba(255,255,255,0.4);">Ref: #${verificationId}</div>` : ""}
4840
+ </div>`;
4893
4841
  setTimeout(resolve, 2800);
4894
4842
  });
4895
4843
  }
4896
- /**
4897
- * Show timeout screen with an optional retry callback.
4898
- * Resolves immediately so the orchestrator can move to next step.
4899
- */
4900
4844
  showTimeout(onRetry) {
4901
4845
  return new Promise((resolve) => {
4902
4846
  if (!this.overlayEl) {
@@ -4908,29 +4852,14 @@ var SmartComplySDK = (() => {
4908
4852
  this.overlayEl.style.display = "flex";
4909
4853
  this.overlayEl.innerHTML = `
4910
4854
  <div style="text-align:center;color:#fff;animation:sc-pop-in 0.35s ease;padding:24px;">
4911
- <div style="
4912
- width:80px;height:80px;border-radius:50%;margin:0 auto 16px;
4913
- display:flex;align-items:center;justify-content:center;
4914
- font-size:36px;
4915
- background:rgba(251,191,36,0.15);
4916
- border:3px solid #fbbf24;
4917
- ">\u23F1</div>
4918
- <div style="font-size:18px;font-weight:700;margin-bottom:8px;">Time's Up</div>
4919
- <div style="font-size:13px;opacity:0.65;margin-bottom:20px;">
4920
- You ran out of time. Please try again.
4921
- </div>
4922
- <button id="sc-retry-btn" style="
4923
- padding:12px 28px;border-radius:10px;
4924
- background:#3b82f6;color:#fff;
4925
- border:none;cursor:pointer;
4926
- font-size:14px;font-weight:600;
4927
- width:100%;max-width:200px;
4928
- ">Try Again</button>
4929
- </div>
4930
- `;
4931
- const retryBtn = this.overlayEl.querySelector("#sc-retry-btn");
4932
- if (retryBtn) {
4933
- retryBtn.addEventListener("click", () => {
4855
+ <div style="width:72px;height:72px;border-radius:50%;margin:0 auto 14px;display:flex;align-items:center;justify-content:center;font-size:32px;background:rgba(251,191,36,0.15);border:3px solid #fbbf24;">\u23F1</div>
4856
+ <div style="font-size:17px;font-weight:700;margin-bottom:8px;">Time's Up</div>
4857
+ <div style="font-size:12px;opacity:0.6;margin-bottom:18px;">You ran out of time. Please try again.</div>
4858
+ <button id="sc-retry-btn" style="padding:11px 28px;border-radius:10px;background:#3b82f6;color:#fff;border:none;cursor:pointer;font-size:14px;font-weight:600;width:100%;max-width:180px;">Try Again</button>
4859
+ </div>`;
4860
+ const btn = this.overlayEl.querySelector("#sc-retry-btn");
4861
+ if (btn) {
4862
+ btn.addEventListener("click", () => {
4934
4863
  onRetry();
4935
4864
  resolve();
4936
4865
  });
@@ -4942,21 +4871,11 @@ var SmartComplySDK = (() => {
4942
4871
  getVideoElement() {
4943
4872
  return this.videoEl;
4944
4873
  }
4945
- /**
4946
- * Mount a document scanning step before the liveness challenge.
4947
- * Reuses the already-open camera stream — no second permission prompt.
4948
- * Resolves with the captured document Blob.
4949
- */
4950
4874
  mountDocumentCapture(container, stream) {
4951
4875
  return new Promise((resolve, reject) => {
4952
4876
  injectLivenessKeyframes();
4953
4877
  const docRoot = document.createElement("div");
4954
- docRoot.style.cssText = `
4955
- position:relative;width:100%;max-width:420px;margin:0 auto;
4956
- background:#0a0a0a;border-radius:16px;overflow:hidden;
4957
- font-family:system-ui,-apple-system,sans-serif;
4958
- box-shadow:0 8px 32px rgba(0,0,0,0.4);
4959
- `;
4878
+ docRoot.style.cssText = `position:relative;width:100%;max-width:420px;margin:0 auto;background:#0a0a0a;border-radius:16px;overflow:hidden;font-family:system-ui,-apple-system,sans-serif;box-shadow:0 8px 32px rgba(0,0,0,0.4);`;
4960
4879
  this.docCaptureRoot = docRoot;
4961
4880
  const docVideo = document.createElement("video");
4962
4881
  docVideo.autoplay = true;
@@ -4966,36 +4885,13 @@ var SmartComplySDK = (() => {
4966
4885
  docVideo.srcObject = stream;
4967
4886
  const guideOverlay = document.createElement("div");
4968
4887
  guideOverlay.style.cssText = "position:absolute;inset:0;pointer-events:none;display:flex;align-items:center;justify-content:center;";
4969
- guideOverlay.innerHTML = `
4970
- <div style="width:83%;height:53%;border:2px dashed rgba(255,255,255,0.55);border-radius:10px;box-shadow:0 0 0 2000px rgba(0,0,0,0.45);position:relative;">
4971
- <div style="position:absolute;top:-2px;left:-2px;width:18px;height:18px;border-top:3px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:4px 0 0 0;"></div>
4972
- <div style="position:absolute;top:-2px;right:-2px;width:18px;height:18px;border-top:3px solid #3b82f6;border-right:3px solid #3b82f6;border-radius:0 4px 0 0;"></div>
4973
- <div style="position:absolute;bottom:-2px;left:-2px;width:18px;height:18px;border-bottom:3px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:0 0 0 4px;"></div>
4974
- <div style="position:absolute;bottom:-2px;right:-2px;width:18px;height:18px;border-bottom:3px solid #3b82f6;border-right:3px solid #3b82f6;border-radius:0 0 4px 0;"></div>
4975
- </div>
4976
- `;
4888
+ guideOverlay.innerHTML = `<div style="width:83%;height:53%;border:2px dashed rgba(255,255,255,0.55);border-radius:10px;box-shadow:0 0 0 2000px rgba(0,0,0,0.45);position:relative;"><div style="position:absolute;top:-2px;left:-2px;width:18px;height:18px;border-top:3px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:4px 0 0 0;"></div><div style="position:absolute;top:-2px;right:-2px;width:18px;height:18px;border-top:3px solid #3b82f6;border-right:3px solid #3b82f6;border-radius:0 4px 0 0;"></div><div style="position:absolute;bottom:-2px;left:-2px;width:18px;height:18px;border-bottom:3px solid #3b82f6;border-left:3px solid #3b82f6;border-radius:0 0 0 4px;"></div><div style="position:absolute;bottom:-2px;right:-2px;width:18px;height:18px;border-bottom:3px solid #3b82f6;border-right:3px solid #3b82f6;border-radius:0 0 4px 0;"></div></div>`;
4977
4889
  const header = document.createElement("div");
4978
4890
  header.style.cssText = "position:absolute;top:0;left:0;right:0;background:linear-gradient(180deg,rgba(0,0,0,0.88) 0%,transparent 100%);padding:18px 16px 40px;text-align:center;";
4979
- header.innerHTML = `
4980
- <div style="color:#fff;font-size:16px;font-weight:700;margin-bottom:6px;">Scan Your ID Document</div>
4981
- <div style="color:rgba(255,255,255,0.6);font-size:12px;line-height:1.6;">
4982
- Fit your document inside the frame.<br>Make sure all text and corners are visible.
4983
- </div>
4984
- `;
4891
+ header.innerHTML = `<div style="color:#fff;font-size:16px;font-weight:700;margin-bottom:6px;">Scan Your ID Document</div><div style="color:rgba(255,255,255,0.6);font-size:12px;line-height:1.6;">Fit your document inside the frame.<br>Make sure all text and corners are visible.</div>`;
4985
4892
  const bottomPanel = document.createElement("div");
4986
- bottomPanel.style.cssText = "position:absolute;bottom:0;left:0;right:0;background:linear-gradient(0deg,rgba(0,0,0,0.92) 0%,rgba(0,0,0,0.6) 70%,transparent 100%);padding:16px 16px;";
4987
- bottomPanel.innerHTML = `
4988
- <div style="font-size:11px;color:rgba(255,255,255,0.4);text-align:center;margin-bottom:12px;">
4989
- \u{1F4A1} Good lighting &nbsp;\xB7&nbsp; No glare &nbsp;\xB7&nbsp; All 4 corners visible
4990
- </div>
4991
- <button id="sc-capture-doc-btn" style="width:100%;padding:12px;border-radius:12px;background:#3b82f6;color:#fff;border:none;cursor:pointer;font-size:15px;font-weight:700;margin-bottom:8px;">
4992
- Capture Document
4993
- </button>
4994
- <label style="width:100%;display:flex;align-items:center;justify-content:center;gap:6px;padding:9px;border-radius:12px;border:1.5px solid rgba(255,255,255,0.18);cursor:pointer;color:rgba(255,255,255,0.6);font-size:13px;font-weight:500;">
4995
- <span>\u{1F4C1}</span><span>Upload from gallery instead</span>
4996
- <input id="sc-upload-doc-input" type="file" accept="image/*" style="display:none;" />
4997
- </label>
4998
- `;
4893
+ bottomPanel.style.cssText = "position:absolute;bottom:0;left:0;right:0;background:linear-gradient(0deg,rgba(0,0,0,0.92) 0%,rgba(0,0,0,0.6) 70%,transparent 100%);padding:16px;";
4894
+ bottomPanel.innerHTML = `<div style="font-size:11px;color:rgba(255,255,255,0.4);text-align:center;margin-bottom:12px;">\u{1F4A1} Good lighting \xB7 No glare \xB7 All 4 corners visible</div><button id="sc-capture-doc-btn" style="width:100%;padding:12px;border-radius:12px;background:#3b82f6;color:#fff;border:none;cursor:pointer;font-size:15px;font-weight:700;margin-bottom:8px;">Capture Document</button><label style="width:100%;display:flex;align-items:center;justify-content:center;gap:6px;padding:9px;border-radius:12px;border:1.5px solid rgba(255,255,255,0.18);cursor:pointer;color:rgba(255,255,255,0.6);font-size:13px;font-weight:500;"><span>\u{1F4C1}</span><span>Upload from gallery instead</span><input id="sc-upload-doc-input" type="file" accept="image/*" style="display:none;" /></label>`;
4999
4895
  docRoot.appendChild(docVideo);
5000
4896
  docRoot.appendChild(guideOverlay);
5001
4897
  docRoot.appendChild(header);
@@ -5047,11 +4943,11 @@ var SmartComplySDK = (() => {
5047
4943
  }
5048
4944
  unmount() {
5049
4945
  this.stopTimer();
5050
- if (this.docCaptureRoot && this.docCaptureRoot.parentElement) {
4946
+ if (this.docCaptureRoot?.parentElement) {
5051
4947
  this.docCaptureRoot.parentElement.removeChild(this.docCaptureRoot);
5052
4948
  this.docCaptureRoot = null;
5053
4949
  }
5054
- if (this.root && this.root.parentElement) {
4950
+ if (this.root?.parentElement) {
5055
4951
  this.root.parentElement.removeChild(this.root);
5056
4952
  }
5057
4953
  this.root = null;
@@ -5070,11 +4966,8 @@ var SmartComplySDK = (() => {
5070
4966
  if (!this.timerEl) return;
5071
4967
  const m2 = Math.floor(remaining / 60);
5072
4968
  const s2 = remaining % 60;
5073
- const display = m2 > 0 ? `${m2}:${String(s2).padStart(2, "0")}` : `${s2}s`;
5074
- this.timerEl.textContent = `${display} remaining`;
5075
- if (remaining <= 5) {
5076
- this.timerEl.style.color = "#ef4444";
5077
- }
4969
+ this.timerEl.textContent = `${m2 > 0 ? `${m2}:${String(s2).padStart(2, "0")}` : `${s2}s`} remaining`;
4970
+ if (remaining <= 5) this.timerEl.style.color = "#ef4444";
5078
4971
  };
5079
4972
  update();
5080
4973
  this.timerInterval = setInterval(() => {
@@ -5088,10 +4981,8 @@ var SmartComplySDK = (() => {
5088
4981
  describeAction(action) {
5089
4982
  const labels = {
5090
4983
  BLINK: "Blink your eyes",
5091
- TURN_LEFT: "Turn your head right",
5092
- // camera-left = user's right (mirror)
5093
- TURN_RIGHT: "Turn your head left",
5094
- // camera-right = user's left (mirror)
4984
+ TURN_LEFT: "Turn your head to the side",
4985
+ TURN_RIGHT: "Turn your head to the side",
5095
4986
  TURN_HEAD: "Turn your head side to side",
5096
4987
  OPEN_MOUTH: "Open your mouth wide"
5097
4988
  };
@@ -5472,10 +5363,8 @@ var SmartComplySDK = (() => {
5472
5363
  describeAction(action) {
5473
5364
  const descriptions = {
5474
5365
  BLINK: "Blink your eyes",
5475
- TURN_LEFT: "Turn your head right",
5476
- // camera-left = user's right (mirror)
5477
- TURN_RIGHT: "Turn your head left",
5478
- // camera-right = user's left (mirror)
5366
+ TURN_LEFT: "Turn your head to the side",
5367
+ TURN_RIGHT: "Turn your head to the side",
5479
5368
  TURN_HEAD: "Turn your head side to side",
5480
5369
  OPEN_MOUTH: "Open your mouth wide"
5481
5370
  };
@@ -7604,9 +7493,9 @@ var SmartComplySDK = (() => {
7604
7493
  applyPassed();
7605
7494
  return;
7606
7495
  }
7607
- if (result.status === "failed" || result.status === "expired_document") {
7496
+ if (result.status === "failed") {
7608
7497
  onResolved(result.status);
7609
- const reason = result.failure_reason || (result.status === "expired_document" ? "Your document has expired. Please use a valid ID." : "Verification could not be completed. Please try again.");
7498
+ const reason = result.failure_reason || "Verification could not be completed. Please try again.";
7610
7499
  applyFailed(reason);
7611
7500
  return;
7612
7501
  }