smartcomply-web-sdk 1.0.24 → 1.0.30

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