lido-player 0.0.2-beta-22-dev → 0.0.2-beta-23-dev

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.
Files changed (30) hide show
  1. package/dist/cjs/{decode-Cr5DANqc.js → decode-BDs2S8om.js} +1 -1
  2. package/dist/cjs/{index-0BvcfeCt.js → index-D5olYRJo.js} +130 -21
  3. package/dist/cjs/index.cjs.js +1 -1
  4. package/dist/cjs/lido-avatar_22.cjs.entry.js +38 -18
  5. package/dist/collection/components/flashCard/lido-flash-card.js +30 -3
  6. package/dist/collection/components/trace/lido-trace.js +6 -13
  7. package/dist/collection/stories/Templates/balancing/balancing.stories.js +2 -2
  8. package/dist/collection/utils/utilsHandlers/dragDropHandler.js +129 -20
  9. package/dist/components/index.js +1 -1
  10. package/dist/components/lido-flash-card.js +1 -1
  11. package/dist/components/lido-home.js +1 -1
  12. package/dist/components/lido-root.js +1 -1
  13. package/dist/components/lido-trace.js +1 -1
  14. package/dist/components/p-D0cGjo5e.js +1 -0
  15. package/dist/components/{p-CkxAm8rY.js → p-Ds-d6wd0.js} +2 -2
  16. package/dist/components/p-Lg85waqZ.js +1 -0
  17. package/dist/esm/{decode-DkSXjv7K.js → decode-CAwfe7ub.js} +1 -1
  18. package/dist/esm/{index-D9-TTsdZ.js → index-bo7729YG.js} +130 -21
  19. package/dist/esm/index.js +1 -1
  20. package/dist/esm/lido-avatar_22.entry.js +38 -18
  21. package/dist/lido-player/index.esm.js +1 -1
  22. package/dist/lido-player/lido-player.esm.js +1 -1
  23. package/dist/lido-player/{p-35fa0b8b.entry.js → p-461a3d23.entry.js} +2 -2
  24. package/dist/lido-player/{p-Dc8j8Hxw.js → p-D4kAEWCU.js} +1 -1
  25. package/dist/lido-player/p-VRJMO_sg.js +1 -0
  26. package/dist/types/components/flashCard/lido-flash-card.d.ts +4 -0
  27. package/package.json +1 -1
  28. package/dist/components/p-BUfCIPRa.js +0 -1
  29. package/dist/components/p-u3czV7QM.js +0 -1
  30. package/dist/lido-player/p-D2iINRNN.js +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-0BvcfeCt.js');
3
+ var index = require('./index-D5olYRJo.js');
4
4
 
5
5
  function _mergeNamespaces(n, m) {
6
6
  m.forEach(function (e) {
@@ -453,6 +453,19 @@ function enableDraggingWithScaling(element) {
453
453
  let clone = null;
454
454
  let duplicateElement = null;
455
455
  let mutationFlag = false;
456
+ let pendingMoveFrame = null;
457
+ let latestClientX = 0;
458
+ let latestClientY = 0;
459
+ let hasPendingMove = false;
460
+ let touchTransformUpdated = false;
461
+ let touchDragScale = 1;
462
+ let touchDragScaleY = 1;
463
+ let touchOffsetX = 0;
464
+ let touchOffsetY = 0;
465
+ let touchStartElementLeft = 0;
466
+ let touchStartElementTop = 0;
467
+ let touchStartRect = null;
468
+ let isTouchDragging = false;
456
469
  // Fetch the container element
457
470
  const container = document.getElementById(LidoContainer);
458
471
  if (!container) {
@@ -463,6 +476,33 @@ function enableDraggingWithScaling(element) {
463
476
  return;
464
477
  handlingElementFlexibleWidth(element, 'drag');
465
478
  let dragingElementTransform;
479
+ const getContainerScale = () => {
480
+ const transform = window.getComputedStyle(container).transform;
481
+ const matrix3dMatch = transform.match(/matrix3d\(([^)]+)\)/);
482
+ const matrixMatch = transform.match(/matrix\(([^)]+)\)/);
483
+ if (matrix3dMatch) {
484
+ const values = matrix3dMatch[1].split(',').map(value => parseFloat(value.trim()));
485
+ return {
486
+ scaleX: Math.sqrt(values[0] ** 2 + values[1] ** 2) || 1,
487
+ scaleY: Math.sqrt(values[4] ** 2 + values[5] ** 2) || 1,
488
+ };
489
+ }
490
+ if (matrixMatch) {
491
+ const values = matrixMatch[1].split(',').map(value => parseFloat(value.trim()));
492
+ return {
493
+ scaleX: Math.sqrt(values[0] ** 2 + values[1] ** 2) || 1,
494
+ scaleY: Math.sqrt(values[2] ** 2 + values[3] ** 2) || 1,
495
+ };
496
+ }
497
+ return { scaleX: 1, scaleY: 1 };
498
+ };
499
+ const updateTouchDragScale = () => {
500
+ if (isTouchDragging) {
501
+ const { scaleX, scaleY } = getContainerScale();
502
+ touchDragScale = scaleX;
503
+ touchDragScaleY = scaleY;
504
+ }
505
+ };
466
506
  const onStart = (event) => {
467
507
  var _a, _b;
468
508
  if (container && container.getAttribute("game-completed") === "true")
@@ -479,17 +519,29 @@ function enableDraggingWithScaling(element) {
479
519
  if (event instanceof MouseEvent) {
480
520
  startX = event.clientX;
481
521
  startY = event.clientY;
522
+ touchStartRect = null;
482
523
  }
483
524
  else {
484
525
  startX = event.touches[0].clientX;
485
526
  startY = event.touches[0].clientY;
527
+ isTouchDragging = true;
528
+ touchStartRect = element.getBoundingClientRect();
529
+ touchOffsetX = startX - touchStartRect.left;
530
+ touchOffsetY = startY - touchStartRect.top;
531
+ touchStartElementLeft = touchStartRect.left;
532
+ touchStartElementTop = touchStartRect.top;
533
+ const { scaleX, scaleY } = getContainerScale();
534
+ touchDragScale = scaleX;
535
+ touchDragScaleY = scaleY;
536
+ element.style.willChange = 'transform';
537
+ window.addEventListener('resize', updateTouchDragScale);
486
538
  }
487
539
  // Apply dragging styles to the element
488
540
  element.style.opacity = '1';
489
541
  element.style.cursor = 'grabbing';
490
542
  if (((_a = element.getAttribute('dropAttr')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === DropMode.Diagonal) {
491
543
  const computedStyle = window.getComputedStyle(element);
492
- const rect = element.getBoundingClientRect();
544
+ const rect = touchStartRect || element.getBoundingClientRect();
493
545
  if (!clone) {
494
546
  clone = element.cloneNode(true);
495
547
  clone.style.left = `${rect.left}px`;
@@ -508,7 +560,7 @@ function enableDraggingWithScaling(element) {
508
560
  const imgElement = element.querySelector('img');
509
561
  const src = imgElement === null || imgElement === void 0 ? void 0 : imgElement.getAttribute('src');
510
562
  const computedStyle = window.getComputedStyle(element);
511
- const rect = element.getBoundingClientRect();
563
+ const rect = touchStartRect || element.getBoundingClientRect();
512
564
  if (!duplicateElement) {
513
565
  duplicateElement = element.cloneNode(false);
514
566
  duplicateElement.setAttribute('src', src);
@@ -581,31 +633,31 @@ function enableDraggingWithScaling(element) {
581
633
  target.style.opacity = value;
582
634
  }
583
635
  };
584
- const onMove = (event) => {
585
- if (!isDragging)
636
+ const processMove = () => {
637
+ pendingMoveFrame = null;
638
+ if (!isDragging || !hasPendingMove)
586
639
  return;
640
+ hasPendingMove = false;
641
+ const deferTouchDropValidation = touchTransformUpdated;
587
642
  if (isDraggingDisabled) {
588
643
  isDragging = false;
644
+ touchTransformUpdated = false;
589
645
  return;
590
646
  }
591
- isClicked = false;
592
647
  element.style.transition = 'none';
593
- const containerScale = calculateScale();
594
- let dx = 0;
595
- let dy = 0;
596
- if (event instanceof MouseEvent) {
597
- dx = (event.clientX - startX) / containerScale;
598
- dy = (event.clientY - startY) / containerScale;
599
- }
600
- else {
601
- dx = (event.touches[0].clientX - startX) / containerScale;
602
- dy = (event.touches[0].clientY - startY) / containerScale;
603
- }
604
- // Calculate the new position considering scaling
605
- const newLeft = initialX + dx;
606
- const newTop = initialY + dy;
607
- // Apply transform with translation without boundaries
608
- element.style.transform = `translate(${newLeft}px, ${newTop}px)`;
648
+ if (!touchTransformUpdated) {
649
+ const containerScale = calculateScale();
650
+ const dx = (latestClientX - startX) / containerScale;
651
+ const dy = (latestClientY - startY) / containerScale;
652
+ // Calculate the new position considering scaling
653
+ const newLeft = initialX + dx;
654
+ const newTop = initialY + dy;
655
+ // Apply transform with translation without boundaries
656
+ element.style.transform = `translate(${newLeft}px, ${newTop}px)`;
657
+ }
658
+ touchTransformUpdated = false;
659
+ if (deferTouchDropValidation)
660
+ return;
609
661
  // Check for overlaps and highlight only the most overlapping element
610
662
  let mostOverlappedElement = findMostoverlappedElement$1(element, 'drop');
611
663
  const allElements = document.querySelectorAll("[type='drop']");
@@ -644,6 +696,44 @@ function enableDraggingWithScaling(element) {
644
696
  }
645
697
  }
646
698
  };
699
+ const onMove = (event) => {
700
+ if (!isDragging)
701
+ return;
702
+ if (isDraggingDisabled) {
703
+ isDragging = false;
704
+ return;
705
+ }
706
+ if (event instanceof MouseEvent) {
707
+ touchTransformUpdated = false;
708
+ latestClientX = event.clientX;
709
+ latestClientY = event.clientY;
710
+ }
711
+ else {
712
+ const touch = event.touches[0];
713
+ if (!touch)
714
+ return;
715
+ latestClientX = touch.clientX;
716
+ latestClientY = touch.clientY;
717
+ }
718
+ if (!(event instanceof MouseEvent)) {
719
+ element.style.transition = 'none';
720
+ const desiredLeft = latestClientX - touchOffsetX;
721
+ const desiredTop = latestClientY - touchOffsetY;
722
+ const dx = (desiredLeft - touchStartElementLeft) / touchDragScale;
723
+ const dy = (desiredTop - touchStartElementTop) / touchDragScaleY;
724
+ const newLeft = initialX + dx;
725
+ const newTop = initialY + dy;
726
+ element.style.transform = `translate3d(${newLeft}px, ${newTop}px, 0)`;
727
+ touchTransformUpdated = true;
728
+ }
729
+ isClicked = false;
730
+ if (event instanceof MouseEvent) {
731
+ hasPendingMove = true;
732
+ if (pendingMoveFrame === null) {
733
+ pendingMoveFrame = requestAnimationFrame(processMove);
734
+ }
735
+ }
736
+ };
647
737
  let lastOverlappedElement = null;
648
738
  const removeDocumentDragListeners = () => {
649
739
  document.removeEventListener('mousemove', onMove);
@@ -651,9 +741,19 @@ function enableDraggingWithScaling(element) {
651
741
  document.removeEventListener('touchmove', onMove);
652
742
  document.removeEventListener('touchend', onEnd);
653
743
  };
744
+ const flushPendingMove = () => {
745
+ if (pendingMoveFrame === null)
746
+ return;
747
+ cancelAnimationFrame(pendingMoveFrame);
748
+ processMove();
749
+ };
654
750
  const onEnd = (endEv) => {
655
751
  var _a, _b, _c;
752
+ flushPendingMove();
656
753
  isDragging = false;
754
+ isTouchDragging = false;
755
+ element.style.willChange = '';
756
+ window.removeEventListener('resize', updateTouchDragScale);
657
757
  removeDocumentDragListeners();
658
758
  if (isClicked) {
659
759
  if (clone) {
@@ -759,6 +859,15 @@ function enableDraggingWithScaling(element) {
759
859
  };
760
860
  const cleanup = () => {
761
861
  isDragging = false;
862
+ isTouchDragging = false;
863
+ element.style.willChange = '';
864
+ window.removeEventListener('resize', updateTouchDragScale);
865
+ if (pendingMoveFrame !== null) {
866
+ cancelAnimationFrame(pendingMoveFrame);
867
+ pendingMoveFrame = null;
868
+ }
869
+ hasPendingMove = false;
870
+ touchTransformUpdated = false;
762
871
  observer.disconnect();
763
872
  removeDocumentDragListeners();
764
873
  element.removeEventListener('mousedown', onStart);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-0BvcfeCt.js');
3
+ var index = require('./index-D5olYRJo.js');
4
4
  require('./index-DnaH8sO-.js');
5
5
 
6
6
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-DnaH8sO-.js');
4
- var index$1 = require('./index-0BvcfeCt.js');
4
+ var index$1 = require('./index-D5olYRJo.js');
5
5
 
6
6
  var rive$1 = {exports: {}};
7
7
 
@@ -12465,6 +12465,13 @@ const LidoFlash = class {
12465
12465
  this.flipped = false;
12466
12466
  this.autoFlipAfter = 4500;
12467
12467
  this.instructionDone = false;
12468
+ this.instructionStarted = false;
12469
+ this.onAudioStarted = (event) => {
12470
+ var _a;
12471
+ const target = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.target;
12472
+ if (target === this.instructionText())
12473
+ this.instructionStarted = true;
12474
+ };
12468
12475
  this.onAudioEnded = (event) => {
12469
12476
  var _a;
12470
12477
  const target = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.target;
@@ -12473,7 +12480,7 @@ const LidoFlash = class {
12473
12480
  return;
12474
12481
  if (target === this.instructionText()) {
12475
12482
  this.instructionDone = true;
12476
- window.setTimeout(() => {
12483
+ this.frontStartTimer = window.setTimeout(() => {
12477
12484
  this.speakFront();
12478
12485
  }, 1200);
12479
12486
  }
@@ -12545,7 +12552,11 @@ const LidoFlash = class {
12545
12552
  this.speakFront();
12546
12553
  }
12547
12554
  };
12548
- this.instructionText = () => { var _a; return document.getElementById(((_a = this.el.closest('lido-container')) === null || _a === void 0 ? void 0 : _a.getAttribute('template-id')) || ''); };
12555
+ this.instructionText = () => {
12556
+ const container = this.el.closest('lido-container');
12557
+ const id = container === null || container === void 0 ? void 0 : container.getAttribute('template-id');
12558
+ return id ? container === null || container === void 0 ? void 0 : container.querySelector(`[id="${id}"]`) : null;
12559
+ };
12549
12560
  this.frontText = () => this.el.querySelector('.card-front lido-text');
12550
12561
  this.backText = () => this.el.querySelector('.card-back lido-text');
12551
12562
  this.speakFront = () => {
@@ -12613,19 +12624,35 @@ const LidoFlash = class {
12613
12624
  componentDidLoad() {
12614
12625
  index$1.setVisibilityWithDelay(this.el, this.delayVisible);
12615
12626
  index$1.initEventsForElement(this.el, this.type);
12627
+ window.addEventListener('lidoAudioStarted', this.onAudioStarted);
12616
12628
  window.addEventListener('lidoAudioEnded', this.onAudioEnded);
12629
+ const container = this.el.closest('lido-container');
12630
+ if ((container === null || container === void 0 ? void 0 : container.getAttribute('template-id')) === 'flashcardtemplate') {
12631
+ this.instructionStartTimer = window.setTimeout(() => {
12632
+ if (!this.instructionStarted && !this.instructionDone) {
12633
+ const instruction = this.instructionText();
12634
+ if (instruction)
12635
+ index$1.executeActions("this.speak='true';", instruction);
12636
+ }
12637
+ }, 150);
12638
+ }
12617
12639
  // handlingChildElements(this.el, this.minLength, this.maxLength, this.childElementsLength, 'inline-block');
12618
12640
  }
12619
12641
  disconnectedCallback() {
12620
12642
  window.removeEventListener('lidoAudioEnded', this.onAudioEnded);
12643
+ window.removeEventListener('lidoAudioStarted', this.onAudioStarted);
12621
12644
  if (this.autoFlipTimer)
12622
12645
  window.clearTimeout(this.autoFlipTimer);
12646
+ if (this.instructionStartTimer)
12647
+ window.clearTimeout(this.instructionStartTimer);
12648
+ if (this.frontStartTimer)
12649
+ window.clearTimeout(this.frontStartTimer);
12623
12650
  window.removeEventListener('resize', this.updateStyles);
12624
12651
  window.removeEventListener('load', this.updateStyles);
12625
12652
  }
12626
12653
  /* ---------- Render ---------- */
12627
12654
  render() {
12628
- return (index.h(index.Host, { key: '8d65b494352e0c0aefb3815c87a798967ccb65aa', value: this.value, "tab-index": this.tabIndex, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, onEntry: this.onEntry, type: this.type, onClick: this.handleFlip, "disable-speak": this.disableSpeak }, index.h("div", { key: 'db3d4fce4f9f54437485ab1274b1f9bd3b3486bc', class: `card ${this.flipped ? 'flipped' : ''}` }, index.h("div", { key: 'd37770b0b08eac533265d7f8049c598df047aa37', class: "card-face card-front" }, this.front != null ? this.front : index.h("slot", { name: "front" })), index.h("div", { key: '2f8431017cfed9f9adb679442be833a65704d41e', class: "card-face card-back" }, this.back != null ? this.back : index.h("slot", { name: "back" })))));
12655
+ return (index.h(index.Host, { key: '6650cc9f75b42c06eacbad9c56112fd343b8d02c', value: this.value, "tab-index": this.tabIndex, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, onEntry: this.onEntry, type: this.type, onClick: this.handleFlip, "disable-speak": this.disableSpeak }, index.h("div", { key: 'e680750d80c7b7b44149d11940059114a4293b3d', class: `card ${this.flipped ? 'flipped' : ''}` }, index.h("div", { key: '0ab8261e7aa931809add9cf1677f8cb594f990d6', class: "card-face card-front" }, this.front != null ? this.front : index.h("slot", { name: "front" })), index.h("div", { key: '3cf08684c987fcca398f1f491f254f80c7cff518', class: "card-face card-back" }, this.back != null ? this.back : index.h("slot", { name: "back" })))));
12629
12656
  }
12630
12657
  get el() { return index.getElement(this); }
12631
12658
  static get watchers() { return {
@@ -13072,7 +13099,7 @@ const LidoHome = class {
13072
13099
  }
13073
13100
  // Pure-JS fallback (no wasm asset required)
13074
13101
  try {
13075
- const brotliDecodeModule = await Promise.resolve().then(function () { return require('./decode-Cr5DANqc.js'); }).then(function (n) { return n.decode; });
13102
+ const brotliDecodeModule = await Promise.resolve().then(function () { return require('./decode-BDs2S8om.js'); }).then(function (n) { return n.decode; });
13076
13103
  const brotliDecompressBuffer = brotliDecodeModule.BrotliDecompressBuffer || ((_a = brotliDecodeModule.default) === null || _a === void 0 ? void 0 : _a.BrotliDecompressBuffer);
13077
13104
  if (typeof brotliDecompressBuffer !== 'function') {
13078
13105
  throw new Error('BrotliDecompressBuffer function not found in brotli/dec/decode');
@@ -18776,16 +18803,9 @@ const LidoTrace = class {
18776
18803
  const proximitySquared = proximityThreshold * proximityThreshold;
18777
18804
  // Calculate the distance between the pointer and the draggable circle
18778
18805
  const distanceSquared = this.getDistanceSquared(pointerPos, circlePos);
18779
- // The red circle can lag behind a touch pointer when a lower-end device
18780
- // drops frames. Do not reject the touch solely because it has moved ahead
18781
- // of the circle: the path-distance check below still ensures the pointer
18782
- // remains on the trace. This prevents long, narrow curves from becoming
18783
- // stuck halfway through a stroke.
18784
- const pointerLeadThreshold = evt.pointerType === 'touch'
18785
- ? Math.max(proximityThreshold * 4, 180)
18786
- : Math.max(proximityThreshold * 2, 120);
18787
- if (distanceSquared > pointerLeadThreshold * pointerLeadThreshold) {
18788
- return;
18806
+ // If the pointer is outside the proximity threshold, do not proceed with drawing or moving
18807
+ if (distanceSquared > proximitySquared) {
18808
+ return; // Skip any further actions
18789
18809
  }
18790
18810
  const isFreeTraceMode = state.mode === index$1.TraceMode.FreeTrace || state.mode === index$1.TraceMode.BlindFreeTrace;
18791
18811
  const closestPoint = this.getClosestPointOnPath(currentPath, pointerPos, isFreeTraceMode ? undefined : state.lastLength);
@@ -18825,7 +18845,7 @@ const LidoTrace = class {
18825
18845
  state.freeTracePointsCount = 1;
18826
18846
  }
18827
18847
  // Limit the number of points in the free trace path for performance
18828
- const MAX_FREE_TRACE_POINTS = 10;
18848
+ const MAX_FREE_TRACE_POINTS = 5;
18829
18849
  state.freeTracePointsCount = (state.freeTracePointsCount || 1) + 1;
18830
18850
  if (state.freeTracePointsCount > MAX_FREE_TRACE_POINTS) {
18831
18851
  // If limit reached, skip adding more points
@@ -18861,7 +18881,7 @@ const LidoTrace = class {
18861
18881
  // In normal modes, allow movement and drawing only within the general proximity threshold
18862
18882
  const BACKWARD_TOLERANCE = 20; // allow slight backward movement
18863
18883
  const MAX_FORWARD_JUMP = 80; // prevent jumping to wrong segment
18864
- const RECOVERY_FORWARD_JUMP = Math.min(evt.pointerType === 'touch' ? 480 : 320, Math.max(evt.pointerType === 'touch' ? 220 : 160, state.totalPathLength * 0.45)); // recover on long strokes without skipping short paths
18884
+ const RECOVERY_FORWARD_JUMP = Math.min(320, Math.max(160, state.totalPathLength * 0.45)); // recover on long strokes without skipping short paths
18865
18885
  const RECOVERY_END_BUFFER = Math.min(60, Math.max(24, state.totalPathLength * 0.12)); // don't let recovery auto-finish the last part
18866
18886
  const RECOVERY_POINTER_MOVE_THRESHOLD = 8; // only recover after a meaningful drag, not during slow tracing
18867
18887
  let guidedClosestPoint = closestPoint;
@@ -19318,7 +19338,7 @@ const LidoTrace = class {
19318
19338
  };
19319
19339
  }
19320
19340
  render() {
19321
- return (index.h(index.Host, { key: 'fecd265e2c8a5f7d391fe99e35739f76759da5b6', class: "lido-trace", id: this.id, audio: this.audio, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, tabindex: this.tabIndex, "disable-speak": this.disableSpeak }, index.h("div", { key: '677681edfa9da3e7f8bea5f79d62900322262460', style: this.style, id: "lido-svgContainer" })));
19341
+ return (index.h(index.Host, { key: '07506adee10b4f0348ba7b7c4d0f338d7e61cfd9', class: "lido-trace", id: this.id, audio: this.audio, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, tabindex: this.tabIndex, "disable-speak": this.disableSpeak }, index.h("div", { key: '9b3c311582a7246cded868234a47293ae78a3932', style: this.style, id: "lido-svgContainer" })));
19322
19342
  }
19323
19343
  static get assetsDirs() { return ["assets"]; }
19324
19344
  get el() { return index.getElement(this); }
@@ -85,6 +85,13 @@ export class LidoFlash {
85
85
  this.flipped = false;
86
86
  this.autoFlipAfter = 4500;
87
87
  this.instructionDone = false;
88
+ this.instructionStarted = false;
89
+ this.onAudioStarted = (event) => {
90
+ var _a;
91
+ const target = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.target;
92
+ if (target === this.instructionText())
93
+ this.instructionStarted = true;
94
+ };
88
95
  this.onAudioEnded = (event) => {
89
96
  var _a;
90
97
  const target = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.target;
@@ -93,7 +100,7 @@ export class LidoFlash {
93
100
  return;
94
101
  if (target === this.instructionText()) {
95
102
  this.instructionDone = true;
96
- window.setTimeout(() => {
103
+ this.frontStartTimer = window.setTimeout(() => {
97
104
  this.speakFront();
98
105
  }, 1200);
99
106
  }
@@ -165,7 +172,11 @@ export class LidoFlash {
165
172
  this.speakFront();
166
173
  }
167
174
  };
168
- this.instructionText = () => { var _a; return document.getElementById(((_a = this.el.closest('lido-container')) === null || _a === void 0 ? void 0 : _a.getAttribute('template-id')) || ''); };
175
+ this.instructionText = () => {
176
+ const container = this.el.closest('lido-container');
177
+ const id = container === null || container === void 0 ? void 0 : container.getAttribute('template-id');
178
+ return id ? container === null || container === void 0 ? void 0 : container.querySelector(`[id="${id}"]`) : null;
179
+ };
169
180
  this.frontText = () => this.el.querySelector('.card-front lido-text');
170
181
  this.backText = () => this.el.querySelector('.card-back lido-text');
171
182
  this.speakFront = () => {
@@ -233,19 +244,35 @@ export class LidoFlash {
233
244
  componentDidLoad() {
234
245
  setVisibilityWithDelay(this.el, this.delayVisible);
235
246
  initEventsForElement(this.el, this.type);
247
+ window.addEventListener('lidoAudioStarted', this.onAudioStarted);
236
248
  window.addEventListener('lidoAudioEnded', this.onAudioEnded);
249
+ const container = this.el.closest('lido-container');
250
+ if ((container === null || container === void 0 ? void 0 : container.getAttribute('template-id')) === 'flashcardtemplate') {
251
+ this.instructionStartTimer = window.setTimeout(() => {
252
+ if (!this.instructionStarted && !this.instructionDone) {
253
+ const instruction = this.instructionText();
254
+ if (instruction)
255
+ executeActions("this.speak='true';", instruction);
256
+ }
257
+ }, 150);
258
+ }
237
259
  // handlingChildElements(this.el, this.minLength, this.maxLength, this.childElementsLength, 'inline-block');
238
260
  }
239
261
  disconnectedCallback() {
240
262
  window.removeEventListener('lidoAudioEnded', this.onAudioEnded);
263
+ window.removeEventListener('lidoAudioStarted', this.onAudioStarted);
241
264
  if (this.autoFlipTimer)
242
265
  window.clearTimeout(this.autoFlipTimer);
266
+ if (this.instructionStartTimer)
267
+ window.clearTimeout(this.instructionStartTimer);
268
+ if (this.frontStartTimer)
269
+ window.clearTimeout(this.frontStartTimer);
243
270
  window.removeEventListener('resize', this.updateStyles);
244
271
  window.removeEventListener('load', this.updateStyles);
245
272
  }
246
273
  /* ---------- Render ---------- */
247
274
  render() {
248
- return (h(Host, { key: '8d65b494352e0c0aefb3815c87a798967ccb65aa', value: this.value, "tab-index": this.tabIndex, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, onEntry: this.onEntry, type: this.type, onClick: this.handleFlip, "disable-speak": this.disableSpeak }, h("div", { key: 'db3d4fce4f9f54437485ab1274b1f9bd3b3486bc', class: `card ${this.flipped ? 'flipped' : ''}` }, h("div", { key: 'd37770b0b08eac533265d7f8049c598df047aa37', class: "card-face card-front" }, this.front != null ? this.front : h("slot", { name: "front" })), h("div", { key: '2f8431017cfed9f9adb679442be833a65704d41e', class: "card-face card-back" }, this.back != null ? this.back : h("slot", { name: "back" })))));
275
+ return (h(Host, { key: '6650cc9f75b42c06eacbad9c56112fd343b8d02c', value: this.value, "tab-index": this.tabIndex, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, audio: this.audio, onTouch: this.onTouch, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, onEntry: this.onEntry, type: this.type, onClick: this.handleFlip, "disable-speak": this.disableSpeak }, h("div", { key: 'e680750d80c7b7b44149d11940059114a4293b3d', class: `card ${this.flipped ? 'flipped' : ''}` }, h("div", { key: '0ab8261e7aa931809add9cf1677f8cb594f990d6', class: "card-face card-front" }, this.front != null ? this.front : h("slot", { name: "front" })), h("div", { key: '3cf08684c987fcca398f1f491f254f80c7cff518', class: "card-face card-back" }, this.back != null ? this.back : h("slot", { name: "back" })))));
249
276
  }
250
277
  static get is() { return "lido-flash-card"; }
251
278
  static get originalStyleUrls() {
@@ -589,16 +589,9 @@ export class LidoTrace {
589
589
  const proximitySquared = proximityThreshold * proximityThreshold;
590
590
  // Calculate the distance between the pointer and the draggable circle
591
591
  const distanceSquared = this.getDistanceSquared(pointerPos, circlePos);
592
- // The red circle can lag behind a touch pointer when a lower-end device
593
- // drops frames. Do not reject the touch solely because it has moved ahead
594
- // of the circle: the path-distance check below still ensures the pointer
595
- // remains on the trace. This prevents long, narrow curves from becoming
596
- // stuck halfway through a stroke.
597
- const pointerLeadThreshold = evt.pointerType === 'touch'
598
- ? Math.max(proximityThreshold * 4, 180)
599
- : Math.max(proximityThreshold * 2, 120);
600
- if (distanceSquared > pointerLeadThreshold * pointerLeadThreshold) {
601
- return;
592
+ // If the pointer is outside the proximity threshold, do not proceed with drawing or moving
593
+ if (distanceSquared > proximitySquared) {
594
+ return; // Skip any further actions
602
595
  }
603
596
  const isFreeTraceMode = state.mode === TraceMode.FreeTrace || state.mode === TraceMode.BlindFreeTrace;
604
597
  const closestPoint = this.getClosestPointOnPath(currentPath, pointerPos, isFreeTraceMode ? undefined : state.lastLength);
@@ -638,7 +631,7 @@ export class LidoTrace {
638
631
  state.freeTracePointsCount = 1;
639
632
  }
640
633
  // Limit the number of points in the free trace path for performance
641
- const MAX_FREE_TRACE_POINTS = 10;
634
+ const MAX_FREE_TRACE_POINTS = 5;
642
635
  state.freeTracePointsCount = (state.freeTracePointsCount || 1) + 1;
643
636
  if (state.freeTracePointsCount > MAX_FREE_TRACE_POINTS) {
644
637
  // If limit reached, skip adding more points
@@ -674,7 +667,7 @@ export class LidoTrace {
674
667
  // In normal modes, allow movement and drawing only within the general proximity threshold
675
668
  const BACKWARD_TOLERANCE = 20; // allow slight backward movement
676
669
  const MAX_FORWARD_JUMP = 80; // prevent jumping to wrong segment
677
- const RECOVERY_FORWARD_JUMP = Math.min(evt.pointerType === 'touch' ? 480 : 320, Math.max(evt.pointerType === 'touch' ? 220 : 160, state.totalPathLength * 0.45)); // recover on long strokes without skipping short paths
670
+ const RECOVERY_FORWARD_JUMP = Math.min(320, Math.max(160, state.totalPathLength * 0.45)); // recover on long strokes without skipping short paths
678
671
  const RECOVERY_END_BUFFER = Math.min(60, Math.max(24, state.totalPathLength * 0.12)); // don't let recovery auto-finish the last part
679
672
  const RECOVERY_POINTER_MOVE_THRESHOLD = 8; // only recover after a meaningful drag, not during slow tracing
680
673
  let guidedClosestPoint = closestPoint;
@@ -1131,7 +1124,7 @@ export class LidoTrace {
1131
1124
  };
1132
1125
  }
1133
1126
  render() {
1134
- return (h(Host, { key: 'fecd265e2c8a5f7d391fe99e35739f76759da5b6', class: "lido-trace", id: this.id, audio: this.audio, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, tabindex: this.tabIndex, "disable-speak": this.disableSpeak }, h("div", { key: '677681edfa9da3e7f8bea5f79d62900322262460', style: this.style, id: "lido-svgContainer" })));
1127
+ return (h(Host, { key: '07506adee10b4f0348ba7b7c4d0f338d7e61cfd9', class: "lido-trace", id: this.id, audio: this.audio, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, tabindex: this.tabIndex, "disable-speak": this.disableSpeak }, h("div", { key: '9b3c311582a7246cded868234a47293ae78a3932', style: this.style, id: "lido-svgContainer" })));
1135
1128
  }
1136
1129
  static get is() { return "lido-trace"; }
1137
1130
  static get originalStyleUrls() {
@@ -34,7 +34,7 @@ function getContainerXml(args) {
34
34
  const rightValue = escapeXml(args.rightValue);
35
35
  return `
36
36
  <main>
37
- <lido-container visible="true" show-next-button="true" objective="${objective}" equationCheck="$#lefthandle1,$#righthandle1" id="lido-container" onCorrect="lido-avatar.avatarAnimate='Success';this.sleep='2000';" show-Check="true" bg-image="https://aeakbcdznktpsbrfsgys.supabase.co/storage/v1/object/public/template-assets/background-images/Balancing.png" onInCorrect="lido-avatar.avatarAnimate='Fail'; this.sleep='2000';" is-continue-on-correct="true">
37
+ <lido-container visible="true" show-next-button="true" drop-action="move" objective="${objective}" equationCheck="$#lefthandle1,$#righthandle1" id="lido-container" onCorrect="lido-avatar.avatarAnimate='Success';this.sleep='2000';" show-Check="true" bg-image="https://aeakbcdznktpsbrfsgys.supabase.co/storage/v1/object/public/template-assets/background-images/Balancing.png" onInCorrect="lido-avatar.avatarAnimate='Fail'; this.sleep='2000';" is-continue-on-correct="true">
38
38
  <!-- Chimple Avatar -->
39
39
  <lido-cell layout="pos" id="pos1" disable-edit="true" value="pos2" height="landscape.396px,portrait.400px" width="landscape.298px,portrait.369px" x="landscape.82%, portrait.32%" y="landscape.63%, portrait.78%" aria-hidden="true" z="1" bg-color="transparent" visible="true" onEntry="">
40
40
  <lido-avatar id="lido-avatar" disable-edit="true" visible="true" height="100%" width="100%" src="https://aeakbcdznktpsbrfsgys.supabase.co/storage/v1/object/public/template-assets/temp2/chimplecharacter.riv" alt-text="{chimpleCharacterRive}">
@@ -46,7 +46,7 @@ function getContainerXml(args) {
46
46
  <!-- question -->
47
47
  <lido-text visible="true" audio="" id="heading" tab-index="12" height="landscape.100px,portrait.175px" font-family="'Baloo Bhai 2'" font-size="60px" width="landscape.auto,portrait.86%" string="Drop the elements to match the given symbol '${objective}'" font-color="black" bg-color="white" y="landscape.0%,portrait.-12%" onEntry="this.speak='true';this.font-weight='600'; this.position='relative';">
48
48
  </lido-text>
49
- <lido-balance tilt="0" operation="add" visible="true" show-symbol="true" balance-symbol="${objective}" height="landscape.456px,portrait.500px" y="landscape.4%,portrait.0%" width="landscape.1136px,portrait.876px">
49
+ <lido-balance tilt="0" operation="add" visible="true" height="landscape.456px,portrait.500px" y="landscape.4%,portrait.0%" width="landscape.1136px,portrait.876px">
50
50
  <!-- drop Element -->
51
51
  <lido-cell layout="row" visible="true" id="leftparent" height="126px" width="120px" bg-color="transparent" y="landscape.22%,portrait.28%" x="landscape.14%,portrait.12%" onEntry="this.position='relative';">
52
52
  <lido-text visible="true" id="lefthandle1" tab-index="1" value="" height="126px" width="120px" type="drop"></lido-text>