lido-player 0.0.2-alpha-98 → 0.0.2-beta-00

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 (40) hide show
  1. package/dist/cjs/{decode-afeNWInB.js → decode-DweIsOMk.js} +1 -1
  2. package/dist/cjs/{index-DMfHwNdL.js → index-BLk7DH9M.js} +24 -5
  3. package/dist/cjs/{index-Dl8SlqP-.js → index-Bsk4M2Qz.js} +36 -9
  4. package/dist/cjs/index.cjs.js +2 -2
  5. package/dist/cjs/lido-avatar_22.cjs.entry.js +84 -39
  6. package/dist/cjs/lido-player.cjs.js +2 -2
  7. package/dist/cjs/loader.cjs.js +1 -1
  8. package/dist/collection/collection-manifest.json +1 -1
  9. package/dist/collection/components/container/lido-container.js +4 -2
  10. package/dist/collection/components/trace/lido-trace.js +77 -34
  11. package/dist/collection/utils/utils.js +4 -1
  12. package/dist/collection/utils/utilsHandlers/dragDropHandler.js +19 -3
  13. package/dist/components/index.js +1 -1
  14. package/dist/components/lido-container.js +1 -1
  15. package/dist/components/lido-home.js +1 -1
  16. package/dist/components/lido-root.js +1 -1
  17. package/dist/components/lido-trace.js +1 -1
  18. package/dist/components/{p-DsaycW90.js → p-CTJcKeEK.js} +1 -1
  19. package/dist/components/p-CtU7FitD.js +1 -0
  20. package/dist/components/p-Cvme8ibO.js +1 -0
  21. package/dist/esm/{decode-ChEy8Z68.js → decode-C_JRsKjk.js} +1 -1
  22. package/dist/esm/{index-C7XdSFIP.js → index-Dfvjtz8r.js} +36 -9
  23. package/dist/esm/{index-DwX5MikQ.js → index-qr00vrOg.js} +24 -5
  24. package/dist/esm/index.js +2 -2
  25. package/dist/esm/lido-avatar_22.entry.js +84 -39
  26. package/dist/esm/lido-player.js +3 -3
  27. package/dist/esm/loader.js +2 -2
  28. package/dist/lido-player/index.esm.js +1 -1
  29. package/dist/lido-player/lido-player.esm.js +1 -1
  30. package/dist/lido-player/p-CmFYpNuR.js +1 -0
  31. package/dist/lido-player/p-Dfvjtz8r.js +2 -0
  32. package/dist/lido-player/{p-Cn2i_VLp.js → p-DsjGEy2a.js} +1 -1
  33. package/dist/lido-player/{p-a5f04b97.entry.js → p-b5b16f42.entry.js} +1 -1
  34. package/dist/types/components/trace/lido-trace.d.ts +1 -1
  35. package/dist/types/utils/constants.d.ts +3 -1
  36. package/package.json +1 -1
  37. package/dist/components/p-B4Jyt3YL.js +0 -1
  38. package/dist/components/p-BToRx4je.js +0 -1
  39. package/dist/lido-player/p-C-h69UYH.js +0 -1
  40. package/dist/lido-player/p-C7XdSFIP.js +0 -2
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DMfHwNdL.js');
3
+ var index = require('./index-BLk7DH9M.js');
4
4
 
5
5
  function _mergeNamespaces(n, m) {
6
6
  m.forEach(function (e) {
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index$1 = require('./index-Dl8SlqP-.js');
3
+ var index$1 = require('./index-Bsk4M2Qz.js');
4
4
 
5
5
  const DragMapKey = 'lidoDragMap';
6
6
  const SelectedValuesKey = 'lidoSelectedValues';
@@ -401,6 +401,7 @@ function enableDraggingWithScaling(element) {
401
401
  duplicateElement.style.transform = computedStyle.transform;
402
402
  duplicateElement.style.position = 'absolute';
403
403
  duplicateElement.style.zIndex = '0';
404
+ duplicateElement.style.pointerEvents = "";
404
405
  element.style.zIndex = '100';
405
406
  document.body.appendChild(duplicateElement);
406
407
  }
@@ -567,6 +568,8 @@ function enableDraggingWithScaling(element) {
567
568
  handleResetDragElement(element, mostOverlappedElement, dropHasDrag, null, dragSelectedData);
568
569
  return;
569
570
  }
571
+ element.style.pointerEvents = 'none'; // Disable pointer events on drag element to prevent interference during drop handling
572
+ mostOverlappedElement.style.pointerEvents = 'none';
570
573
  onElementDropComplete(element, mostOverlappedElement);
571
574
  if (templateId === "blender" && element && mostOverlappedElement) {
572
575
  const allElements = document.querySelectorAll(`*`);
@@ -576,6 +579,11 @@ function enableDraggingWithScaling(element) {
576
579
  mostOverlappedElement.classList.add("highlight-element");
577
580
  }
578
581
  executeActions("this.updateCountBlender='true'", container);
582
+ setTimeout(() => {
583
+ element.style.pointerEvents = '';
584
+ mostOverlappedElement.style.pointerEvents = '';
585
+ }, 1000);
586
+ // element.style.pointerEvents = ''; // Re-enable pointer events on drag element after drop handling
579
587
  if (((_b = element.getAttribute('dropAttr')) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === DropMode.Diagonal) {
580
588
  if (mostOverlappedElement) {
581
589
  if (element) {
@@ -1053,6 +1061,7 @@ async function onClickDropOrDragElement(element, type) {
1053
1061
  // Remove the highlight class from elements matching the selector
1054
1062
  const highlightedElements = document.querySelectorAll(`[type='${type}']`);
1055
1063
  highlightedElements.forEach(el => {
1064
+ el.style.pointerEvents = ''; // Re-enable pointer events
1056
1065
  removeHighlight(el);
1057
1066
  });
1058
1067
  // Dynamically create the highlight class if it doesn't exist
@@ -1071,17 +1080,22 @@ async function onClickDropOrDragElement(element, type) {
1071
1080
  document.head.appendChild(style);
1072
1081
  }
1073
1082
  element === null || element === void 0 ? void 0 : element.classList.add('highlight-element');
1083
+ element.style.pointerEvents = "none";
1074
1084
  element.ariaPressed = 'true';
1075
1085
  const selectedDropElement = type === 'drop' ? element : document.querySelector("[type='drop'].highlight-element");
1076
1086
  const selectedDragElement = type === 'drag' ? element : document.querySelector("[type='drag'].highlight-element");
1087
+ setTimeout(() => {
1088
+ element.style.pointerEvents = "";
1089
+ }, 1000);
1077
1090
  if (!selectedDropElement || element.classList.contains("dropped")) {
1078
- console.log("hello");
1079
1091
  onClickDragElement(element);
1080
1092
  return;
1081
1093
  }
1082
1094
  if (element.classList.contains("drop-element"))
1083
1095
  return;
1084
1096
  if (selectedDropElement && selectedDragElement) {
1097
+ selectedDropElement.style.pointerEvents = 'none'; // Disable pointer events on drop element during animation
1098
+ selectedDragElement.style.pointerEvents = 'none'; // Disable pointer events on drag element during animation
1085
1099
  if (selectedDragElement.getAttribute('drop-to'))
1086
1100
  return;
1087
1101
  // Add a transition for a smooth, slower movement
@@ -1108,10 +1122,12 @@ async function onClickDropOrDragElement(element, type) {
1108
1122
  }
1109
1123
  // await new Promise(resolve => setTimeout(resolve, 500));
1110
1124
  await onElementDropComplete(selectedDragElement, selectedDropElement);
1125
+ if (container.getAttribute("drop-action") !== exports.DropAction.InfiniteDrop && container.getAttribute("drop-action") !== exports.DropAction.Move) {
1126
+ selectedDragElement.style.pointerEvents = '';
1127
+ }
1128
+ selectedDropElement.style.pointerEvents = ''; // Re-enable pointer events on drop element after animation
1111
1129
  // ensure count update for click-to-drop flow
1112
1130
  await executeActions("this.updateCountBlender='true'", container);
1113
- // await new Promise(resolve => setTimeout(resolve, 500));
1114
- // selectedDragElement.style.transform = 'translate(0px, 0px)';
1115
1131
  }
1116
1132
  }
1117
1133
  const dragToDropMap = new Map();
@@ -72548,6 +72564,9 @@ const afterDropDragHandling = (dragElement, dropElement) => {
72548
72564
  dragElement.style.width = dropElement.style.width;
72549
72565
  dragElement.style.height = dropElement.style.height;
72550
72566
  dragElement.setAttribute('hasDummy', 'true');
72567
+ setTimeout(() => {
72568
+ dummyElement.style.pointerEvents = "";
72569
+ }, 1000);
72551
72570
  }
72552
72571
  dummyElement.setAttribute('id', dragElement.getAttribute('id'));
72553
72572
  dragElement.replaceWith(dummyElement);
@@ -73630,7 +73649,7 @@ function placeElementInDropZone(dropElement, dragElement, orientation, dropAttr)
73630
73649
  const scale = typeof calculateScale === "function" ? calculateScale() : 1;
73631
73650
  if (!dropElement.dataset.dropCount)
73632
73651
  dropElement.dataset.dropCount = "0";
73633
- let dropCount = parseInt(dropElement.dataset.dropCount, 10);
73652
+ let dropCount = parseInt(dropElement.childElementCount) - 1;
73634
73653
  // === READ DROP ZONE SIZE ===
73635
73654
  const dropWidth = dropRect.width;
73636
73655
  const dropHeight = dropRect.height;
@@ -25,7 +25,7 @@ const globalScripts = () => {};
25
25
  const globalStyles = "@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Baloo+2:wght@400..800&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Baloo+Bhai+2:wght@400..800&display=swap'); body{overflow:hidden;background-position:center;background-size:cover;background-repeat:no-repeat;height:100vh}*{user-select:none}.lido-disable-check-button{pointer-events:none;background-color:#9393935c !important;color:white}.lido-element-selected{border:2px solid;background-color:#ffdf7d !important}.diagonal-target,.diagonal-drop *{transform:scale(0.8) !important;opacity:1 !important}.cloned-element{display:flex !important;position:absolute !important;filter:grayscale(100%);pointer-events:none}.removeShadow{box-shadow:0px 0px 0px 0px #ff8900 !important}.highlight-element{border:2px solid white;box-shadow:rgb(243, 77, 8) 0px 0px 40px !important}.drop-element.empty{border:4px dashed #f34d08 !important}.drop-element.filled{border:'none' !important}.drag-element{box-shadow:0px 15px 11px rgba(43, 0, 0, 0.3) !important}.drag-element.dropped{box-shadow:none !important}.click-element{background-color:var(--btn-bg-color, rgba(255, 172, 76, 1)) !important;box-shadow:var(--btn-shadow-px) var(--btn-shadow-color, rgba(225, 121, 76, 1)) !important;cursor:pointer;transition:box-shadow 0.1s ease-out, transform 0.2s ease-out;}.click-element:active{box-shadow:0px 0px 0px var(--btn-shadow-color, rgba(225, 121, 76, 1)) !important;transform:translateY(var(--btn-active));}.click-element:focus{outline:2px solid dodgerblue;outline-offset:3px}.after-drop-popup-container{width:200%;height:200%;background-color:rgba(0, 0, 0, 0.8);position:absolute;display:flex;flex-direction:row-reverse;align-items:center;justify-content:center !important;gap:80px}.after-drop-popup-drag-element{scale:1.5;border-radius:8px;transform:none !important;position:unset !important}.after-drop-popup-drop-element{scale:1.5;border:unset;border-radius:8px;transform:none !important;position:unset !important}@keyframes zoomFadeIn{0%{transform:scale(0.6);opacity:0}100%{transform:scale(1);opacity:1}}.zoom-fade-in{animation:zoomFadeIn 0.8s ease-out forwards}@keyframes zoomFadeOut{0%{transform:scale(1);opacity:1}100%{transform:scale(0.6);opacity:0}}.zoom-fade-out{animation:zoomFadeOut 0.8s ease-in forwards}.slide-numbers{width:70px;height:70px;border:1px solid #f57139;background-color:white;font-weight:500;color:#f57139;font-size:44px;border-radius:40px;display:flex;align-items:center;justify-content:center;font-family:'Baloo Bhai 2', serif}.slide-numbers-bottom{position:absolute;display:flex;justify-content:space-around;align-items:center;bottom:-25px;width:100%;height:50px}.slide-numbers-left{position:absolute;display:flex;flex-direction:column;justify-content:space-around;height:100%;width:50px;left:-25px;bottom:0px}.lido-speak-icon{width:56px;height:56px;position:absolute;top:-25px;right:-25px;z-index:10;background-image:url(\"https://aeakbcdznktpsbrfsgys.supabase.co/storage/v1/object/public/template-assets/template/audioIcon.png\");background-color:white;border:4px solid #F34D08;border-radius:16px;box-shadow:0px 4px 0px 0px #F34D08;background-size:contain;background-repeat:no-repeat;cursor:pointer}.lido-speak-icon:active{transform:translateY(8px);box-shadow:0px 0px 0px 0px !important}.lido-strong-shake{animation:strongShake 0.3s ease}.lido-scaled-shake{animation:scaledShake 0.6s ease-in-out}.lido-horizontal-shake{animation:horizontalShake 0.6s ease-in-out;border-radius:20px}.lido-vertical-shake{animation:verticalShake 0.6s ease-in-out;border-radius:20px}.lido-diagonal-shake{animation:diagonalShake 0.5s ease-in-out;border-radius:20px;will-change:transform}.lido-glow{animation:glowPulse 1s infinite alternate;transition:opacity 0.5s ease-in-out}.lido-box-highlight{animation:topToPlace 0.3s linear}.lido-display-hiddenvalue{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-size:80px;font-weight:1000;color:brown;-webkit-text-stroke:2px white;font-family:'Baloo Bhai 2', sans-serif;pointer-events:none}.lido-image-colorize{position:relative;display:inline-block}.lido-image-colorize::after{content:'';position:absolute;inset:0;background:var(--tint-color);mix-blend-mode:multiply;opacity:0.8;pointer-events:none;mask-image:var(--mask-url);mask-size:cover;mask-repeat:no-repeat;mask-position:center}.lido-tts-highlight-overlay{position:fixed;pointer-events:none;z-index:9999;background:linear-gradient(\r\n 180deg,\r\n rgba(255, 235, 59, 0.95),\r\n rgba(255, 214, 0, 0.95)\r\n );border-radius:6px;box-shadow:0 2px 6px rgba(0, 0, 0, 0.18),\r\n inset 0 -1px 0 rgba(255, 255, 255, 0.25);transition:left 55ms linear,\r\n top 55ms linear,\r\n width 55ms ease-out,\r\n height 55ms ease-out,\r\n opacity 80ms ease-out;opacity:0.95;will-change:transform, width, height}";
26
26
 
27
27
  /*
28
- Stencil Client Platform v4.43.3 | MIT Licensed | https://stenciljs.com
28
+ Stencil Client Platform v4.43.4 | MIT Licensed | https://stenciljs.com
29
29
  */
30
30
 
31
31
 
@@ -599,6 +599,31 @@ var newVNode = (tag, text) => {
599
599
  var Host = {};
600
600
  var isHost = (node) => node && node.$tag$ === Host;
601
601
 
602
+ // src/runtime/normalize-watchers.ts
603
+ var normalizeWatchers = (raw) => {
604
+ if (!raw) return void 0;
605
+ const keys = Object.keys(raw);
606
+ if (keys.length === 0) return void 0;
607
+ let hasLegacy = false;
608
+ for (const propName of keys) {
609
+ if (hasLegacy) break;
610
+ for (const h2 of raw[propName]) {
611
+ if (typeof h2 === "string") {
612
+ hasLegacy = true;
613
+ break;
614
+ }
615
+ }
616
+ }
617
+ if (!hasLegacy) return raw;
618
+ const out = {};
619
+ for (const propName of keys) {
620
+ out[propName] = raw[propName].map(
621
+ (h2) => typeof h2 === "string" ? { [h2]: 0 } : h2
622
+ );
623
+ }
624
+ return out;
625
+ };
626
+
602
627
  // src/runtime/parse-property-value.ts
603
628
  var parsePropertyValue = (propValue, propType, isFormAssociated) => {
604
629
  if (propValue != null && !isComplexType(propValue)) {
@@ -1582,7 +1607,7 @@ var proxyComponent = (Cstr, cmpMeta, flags) => {
1582
1607
  if (cmpMeta.$members$ || BUILD.propChangeCallback) {
1583
1608
  {
1584
1609
  if (Cstr.watchers && !cmpMeta.$watchers$) {
1585
- cmpMeta.$watchers$ = Cstr.watchers;
1610
+ cmpMeta.$watchers$ = normalizeWatchers(Cstr.watchers);
1586
1611
  }
1587
1612
  if (Cstr.deserializers && !cmpMeta.$deserializers$) {
1588
1613
  cmpMeta.$deserializers$ = Cstr.deserializers;
@@ -1708,11 +1733,13 @@ var proxyComponent = (Cstr, cmpMeta, flags) => {
1708
1733
  return;
1709
1734
  }
1710
1735
  const propFlags = members.find(([m]) => m === propName);
1711
- if (propFlags && propFlags[1][0] & 4 /* Boolean */) {
1736
+ const isBooleanTarget = propFlags && propFlags[1][0] & 4 /* Boolean */;
1737
+ const isSpuriousBooleanRemoval = isBooleanTarget && newValue === null && this[propName] === void 0;
1738
+ if (isBooleanTarget) {
1712
1739
  newValue = newValue === null || newValue === "false" ? false : true;
1713
1740
  }
1714
1741
  const propDesc = Object.getOwnPropertyDescriptor(prototype, propName);
1715
- if (newValue != this[propName] && (!propDesc.get || !!propDesc.set)) {
1742
+ if (!isSpuriousBooleanRemoval && newValue != this[propName] && (!propDesc.get || !!propDesc.set)) {
1716
1743
  this[propName] = newValue;
1717
1744
  }
1718
1745
  });
@@ -1757,7 +1784,7 @@ var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
1757
1784
  }
1758
1785
  if (!Cstr.isProxied) {
1759
1786
  {
1760
- cmpMeta.$watchers$ = Cstr.watchers;
1787
+ cmpMeta.$watchers$ = normalizeWatchers(Cstr.watchers);
1761
1788
  cmpMeta.$serializers$ = Cstr.serializers;
1762
1789
  cmpMeta.$deserializers$ = Cstr.deserializers;
1763
1790
  }
@@ -1930,7 +1957,7 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
1930
1957
  let hasSlotRelocation = false;
1931
1958
  lazyBundles.map((lazyBundle) => {
1932
1959
  lazyBundle[1].map((compactMeta) => {
1933
- var _a2, _b, _c;
1960
+ var _a2, _b;
1934
1961
  const cmpMeta = {
1935
1962
  $flags$: compactMeta[0],
1936
1963
  $tagName$: compactMeta[1],
@@ -1947,9 +1974,9 @@ var bootstrapLazy = (lazyBundles, options = {}) => {
1947
1974
  cmpMeta.$attrsToReflect$ = [];
1948
1975
  }
1949
1976
  {
1950
- cmpMeta.$watchers$ = (_a2 = compactMeta[4]) != null ? _a2 : {};
1951
- cmpMeta.$serializers$ = (_b = compactMeta[5]) != null ? _b : {};
1952
- cmpMeta.$deserializers$ = (_c = compactMeta[6]) != null ? _c : {};
1977
+ cmpMeta.$watchers$ = normalizeWatchers(compactMeta[4]);
1978
+ cmpMeta.$serializers$ = (_a2 = compactMeta[5]) != null ? _a2 : {};
1979
+ cmpMeta.$deserializers$ = (_b = compactMeta[6]) != null ? _b : {};
1953
1980
  }
1954
1981
  const tagName = transformTag(cmpMeta.$tagName$);
1955
1982
  const HostElement = class extends HTMLElement {
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DMfHwNdL.js');
4
- require('./index-Dl8SlqP-.js');
3
+ var index = require('./index-BLk7DH9M.js');
4
+ require('./index-Bsk4M2Qz.js');
5
5
 
6
6
 
7
7
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Dl8SlqP-.js');
4
- var index$1 = require('./index-DMfHwNdL.js');
3
+ var index = require('./index-Bsk4M2Qz.js');
4
+ var index$1 = require('./index-BLk7DH9M.js');
5
5
 
6
6
  var rive$1 = {exports: {}};
7
7
 
@@ -12177,7 +12177,9 @@ const LidoContainer = class {
12177
12177
  "palegmamultioption": "palegmamultioptionAudio" /* templateAudio.palegmamultioption */,
12178
12178
  "palegraoptionaudio": "palegraoptionAudio" /* templateAudio.palegraoptionaudio */,
12179
12179
  "palegrawordmatch": "palegrawordmatchAudio" /* templateAudio.palegrawordmatch */,
12180
- "palegramcqimages": "palegramcqimagesAudio" /* templateAudio.palegramcqimages */
12180
+ "palegramcqimages": "palegramcqimagesAudio" /* templateAudio.palegramcqimages */,
12181
+ "drawShape": "drawshape" /* templateAudio.drawShape */,
12182
+ "drawshape": "drawshape" /* templateAudio.drawshape */,
12181
12183
  }[this.templateId]) !== null && _a !== void 0 ? _a : '';
12182
12184
  const home = document.querySelector('lido-home');
12183
12185
  if (!home)
@@ -12334,7 +12336,7 @@ const LidoContainer = class {
12334
12336
  userSelect: 'none', // Prevent any field selection
12335
12337
  };
12336
12338
  console.log('🚀 ~ LidoContainer ~ canplay:', this.canplay);
12337
- return (index.h(index.Host, { key: 'b94060e2432a7e7d8580ffb53ceef4124a4fba25', id: "lido-container", Lang: this.Lang, "tab-index": 0, class: "lido-container", objective: this.objective, baseUrl: this.baseUrl, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, onTouch: this.onTouch, onInCorrect: this.onInCorrect, onCorrect: this.onCorrect, onEntry: this.onEntry, "show-check": `${this.showCheck}`, "is-continue-on-correct": `${this.isContinueOnCorrect}`, "is-allow-only-correct": `${this.isAllowOnlyCorrect}`, canplay: `${this.canplay}`, appendToDropOnCompletion: `${this.appendToDropOnCompletion}`, "show-prev-button": `${this.showPrevButton}`, "show-next-button": `${this.showNextButton}`, "show-drop-border": `${this.showDropBorder}`, "bg-image": this.bgImage, "exit-button-url": this.exitButtonUrl, "prev-button-url": this.prevButtonUrl, "next-button-url": this.nextButtonUrl, "speaker-button-url": this.speakerButtonUrl, "disable-speak": `${this.disableSpeak}`, "template-id": this.templateId, audio: this.audio, "highlight-word-by-word": `${this.highlightWordByWord}` }, index.h("lido-text", { key: '7b433aa25be08cef849e9cefda243cebd7f6aef6', visible: "false", id: this.templateId, audio: "", string: this.instructName }), index.h("slot", { key: '95705c210ed7efbcf06e0ad7779b8c00fa4e1818' })));
12339
+ return (index.h(index.Host, { key: '00435f1640abcc2d786ab2987e5bcda22816b987', id: "lido-container", Lang: this.Lang, "tab-index": 0, class: "lido-container", objective: this.objective, baseUrl: this.baseUrl, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, onTouch: this.onTouch, onInCorrect: this.onInCorrect, onCorrect: this.onCorrect, onEntry: this.onEntry, "show-check": `${this.showCheck}`, "is-continue-on-correct": `${this.isContinueOnCorrect}`, "is-allow-only-correct": `${this.isAllowOnlyCorrect}`, canplay: `${this.canplay}`, appendToDropOnCompletion: `${this.appendToDropOnCompletion}`, "show-prev-button": `${this.showPrevButton}`, "show-next-button": `${this.showNextButton}`, "show-drop-border": `${this.showDropBorder}`, "bg-image": this.bgImage, "exit-button-url": this.exitButtonUrl, "prev-button-url": this.prevButtonUrl, "next-button-url": this.nextButtonUrl, "speaker-button-url": this.speakerButtonUrl, "disable-speak": `${this.disableSpeak}`, "template-id": this.templateId, audio: this.audio, "highlight-word-by-word": `${this.highlightWordByWord}` }, index.h("lido-text", { key: '9a680e74b6595888174b8ad7a13cc54943292020', visible: "false", id: this.templateId, audio: "", string: this.instructName }), index.h("slot", { key: '5832050a7c60b9fca20544619b3ebc9f56c3ef67' })));
12338
12340
  }
12339
12341
  get el() { return index.getElement(this); }
12340
12342
  static get watchers() { return {
@@ -12874,7 +12876,7 @@ const LidoHome = class {
12874
12876
  }
12875
12877
  // Pure-JS fallback (no wasm asset required)
12876
12878
  try {
12877
- const brotliDecodeModule = await Promise.resolve().then(function () { return require('./decode-afeNWInB.js'); }).then(function (n) { return n.decode; });
12879
+ const brotliDecodeModule = await Promise.resolve().then(function () { return require('./decode-DweIsOMk.js'); }).then(function (n) { return n.decode; });
12878
12880
  const brotliDecompressBuffer = brotliDecodeModule.BrotliDecompressBuffer || ((_a = brotliDecodeModule.default) === null || _a === void 0 ? void 0 : _a.BrotliDecompressBuffer);
12879
12881
  if (typeof brotliDecompressBuffer !== 'function') {
12880
12882
  throw new Error('BrotliDecompressBuffer function not found in brotli/dec/decode');
@@ -18015,6 +18017,7 @@ const LidoTrace = class {
18015
18017
  freeTraceLines: [],
18016
18018
  currentFreePath: [],
18017
18019
  lastPointerPos: null,
18020
+ isCompletingPath: false,
18018
18021
  };
18019
18022
  const url = this.svgUrls[this.currentSvgIndex];
18020
18023
  console.log('Loading SVG from URL:', url);
@@ -18308,6 +18311,7 @@ const LidoTrace = class {
18308
18311
  state.isDragging = true;
18309
18312
  state.activePointerId = evt.pointerId;
18310
18313
  state.circle.setPointerCapture(evt.pointerId);
18314
+ state.lastPointerPos = pointerPos;
18311
18315
  }
18312
18316
  this.hideFingerHint(); // ← NEW
18313
18317
  this.resetIdleTimer(state); // ← NEW
@@ -18329,6 +18333,7 @@ const LidoTrace = class {
18329
18333
  if (evt.pointerId === state.activePointerId) {
18330
18334
  state.isDragging = false;
18331
18335
  state.activePointerId = null;
18336
+ state.lastPointerPos = null;
18332
18337
  this.hideFingerHint(); // ← NEW
18333
18338
  this.resetIdleTimer(state); // ← NEW
18334
18339
  }
@@ -18347,6 +18352,8 @@ const LidoTrace = class {
18347
18352
  return;
18348
18353
  if (!state.circle || !state.paths || state.paths.length === 0)
18349
18354
  return;
18355
+ if (state.isCompletingPath)
18356
+ return;
18350
18357
  this.hideFingerHint(); // user is active, remove hint
18351
18358
  const evt = state.pointerMoveEvent;
18352
18359
  const pointerPos = this.getPointerPosition(evt, state.svg);
@@ -18356,10 +18363,12 @@ const LidoTrace = class {
18356
18363
  };
18357
18364
  // Only update if pointer moved a minimum distance (to reduce unnecessary updates)
18358
18365
  const MOVE_THRESHOLD = 1; // px
18366
+ let pointerMoveDistanceSquared = Infinity;
18359
18367
  if (state.lastPointerPos) {
18360
18368
  const dx = pointerPos.x - state.lastPointerPos.x;
18361
18369
  const dy = pointerPos.y - state.lastPointerPos.y;
18362
- if (dx * dx + dy * dy < MOVE_THRESHOLD * MOVE_THRESHOLD) {
18370
+ pointerMoveDistanceSquared = dx * dx + dy * dy;
18371
+ if (pointerMoveDistanceSquared < MOVE_THRESHOLD * MOVE_THRESHOLD) {
18363
18372
  return;
18364
18373
  }
18365
18374
  }
@@ -18382,14 +18391,15 @@ const LidoTrace = class {
18382
18391
  if (distanceSquared > proximitySquared) {
18383
18392
  return; // Skip any further actions
18384
18393
  }
18385
- const closestPoint = this.getClosestPointOnPath(currentPath, pointerPos);
18394
+ const isFreeTraceMode = state.mode === index$1.TraceMode.FreeTrace || state.mode === index$1.TraceMode.BlindFreeTrace;
18395
+ const closestPoint = this.getClosestPointOnPath(currentPath, pointerPos, isFreeTraceMode ? undefined : state.lastLength);
18386
18396
  // Ensure drawing happens only within proximity threshold
18387
18397
  const distanceToPathSquared = this.getDistanceSquared(pointerPos, closestPoint);
18388
18398
  if (distanceToPathSquared > proximitySquared) {
18389
18399
  return; // Skip drawing if too far from the path
18390
18400
  }
18391
18401
  // For free trace mode and blind free trace mode, allow free drawing only if within the reduced proximity threshold
18392
- if (state.mode === index$1.TraceMode.FreeTrace || state.mode === index$1.TraceMode.BlindFreeTrace) {
18402
+ if (isFreeTraceMode) {
18393
18403
  // Throttle: Only update every 2nd event (for reducing excessive dom updates)
18394
18404
  this.freeTraceUpdateCounter = (this.freeTraceUpdateCounter || 0) + 1;
18395
18405
  if (this.freeTraceUpdateCounter % 2 !== 0) {
@@ -18463,12 +18473,34 @@ const LidoTrace = class {
18463
18473
  return; // Exit early since we're in free trace or blind free trace mode
18464
18474
  }
18465
18475
  // In normal modes, allow movement and drawing only within the general proximity threshold
18466
- if (state.isDragging && closestPoint.length >= state.lastLength) {
18467
- state.lastLength = closestPoint.length;
18476
+ const BACKWARD_TOLERANCE = 20; // allow slight backward movement
18477
+ const MAX_FORWARD_JUMP = 80; // prevent jumping to wrong segment
18478
+ const RECOVERY_FORWARD_JUMP = Math.min(320, Math.max(160, state.totalPathLength * 0.45)); // recover on long strokes without skipping short paths
18479
+ const RECOVERY_END_BUFFER = Math.min(60, Math.max(24, state.totalPathLength * 0.12)); // don't let recovery auto-finish the last part
18480
+ const RECOVERY_POINTER_MOVE_THRESHOLD = 8; // only recover after a meaningful drag, not during slow tracing
18481
+ let guidedClosestPoint = closestPoint;
18482
+ let isValidProgress = guidedClosestPoint.length >= state.lastLength - BACKWARD_TOLERANCE &&
18483
+ guidedClosestPoint.length - state.lastLength <= MAX_FORWARD_JUMP;
18484
+ if (!isValidProgress) {
18485
+ const recoveryPoint = this.getClosestPointOnPath(currentPath, pointerPos);
18486
+ const recoveryDistanceSquared = this.getDistanceSquared(pointerPos, recoveryPoint);
18487
+ const canRecover = pointerMoveDistanceSquared >= RECOVERY_POINTER_MOVE_THRESHOLD * RECOVERY_POINTER_MOVE_THRESHOLD &&
18488
+ recoveryDistanceSquared <= proximitySquared &&
18489
+ recoveryPoint.length >= state.lastLength - BACKWARD_TOLERANCE &&
18490
+ recoveryPoint.length - state.lastLength <= RECOVERY_FORWARD_JUMP &&
18491
+ recoveryPoint.length < state.totalPathLength - RECOVERY_END_BUFFER;
18492
+ if (canRecover) {
18493
+ guidedClosestPoint = recoveryPoint;
18494
+ isValidProgress = true;
18495
+ }
18496
+ }
18497
+ if (state.isDragging && isValidProgress) {
18498
+ state.lastLength = Math.max(state.lastLength, guidedClosestPoint.length);
18499
+ state.lastPointerPos = pointerPos;
18468
18500
  // Only update the circle if it moved enough
18469
- if (Math.abs(closestPoint.x - circlePos.x) > MOVE_THRESHOLD || Math.abs(closestPoint.y - circlePos.y) > MOVE_THRESHOLD) {
18470
- state.circle.setAttribute('cx', closestPoint.x.toString());
18471
- state.circle.setAttribute('cy', closestPoint.y.toString());
18501
+ if (Math.abs(guidedClosestPoint.x - circlePos.x) > MOVE_THRESHOLD || Math.abs(guidedClosestPoint.y - circlePos.y) > MOVE_THRESHOLD) {
18502
+ state.circle.setAttribute('cx', guidedClosestPoint.x.toString());
18503
+ state.circle.setAttribute('cy', guidedClosestPoint.y.toString());
18472
18504
  }
18473
18505
  // Only re-append if not already children list
18474
18506
  const childNodes = (_d = state.svg) === null || _d === void 0 ? void 0 : _d.childNodes;
@@ -18493,6 +18525,9 @@ const LidoTrace = class {
18493
18525
  let pathIsClosed = this.getDistanceSquared(startPoint, endPoint) < 200; // threshold for overlap
18494
18526
  if (pathIsClosed && state.totalPathLength > 50) {
18495
18527
  if (percentComplete >= COMPLETION_THRESHOLD) {
18528
+ if (state.isCompletingPath)
18529
+ return;
18530
+ state.isCompletingPath = true;
18496
18531
  // Animate the draggable circle & green trace to the very end, then proceed
18497
18532
  await this.animatePathToEnd(state, currentPath);
18498
18533
  if (state.currentPathIndex < state.paths.length - 1) {
@@ -18506,9 +18541,15 @@ const LidoTrace = class {
18506
18541
  else {
18507
18542
  // For open paths, allow completion if near the end
18508
18543
  if (state.totalPathLength - 1 - state.lastLength < 5 && state.currentPathIndex < state.paths.length - 1) {
18544
+ if (state.isCompletingPath)
18545
+ return;
18546
+ state.isCompletingPath = true;
18509
18547
  this.moveToNextPath(state);
18510
18548
  }
18511
18549
  else if (state.totalPathLength - 1 - state.lastLength < 5 && state.currentPathIndex === state.paths.length - 1) {
18550
+ if (state.isCompletingPath)
18551
+ return;
18552
+ state.isCompletingPath = true;
18512
18553
  this.moveToNextContainer();
18513
18554
  }
18514
18555
  }
@@ -18617,36 +18658,39 @@ const LidoTrace = class {
18617
18658
  return dx * dx + dy * dy;
18618
18659
  }
18619
18660
  // Find the closest point on the given path to the specified point using two-pass sampling (optimized)
18620
- getClosestPointOnPath(pathNode, point) {
18661
+ getClosestPointOnPath(pathNode, point, lastLength) {
18621
18662
  const pathLength = pathNode.getTotalLength();
18622
18663
  let closestPoint = { x: 0, y: 0, length: 0 };
18623
18664
  let minDistanceSquared = Infinity;
18624
- // Optimized: Increase coarse steps for better performance
18625
- const coarseStep = 40; // was 20
18626
- let coarseClosestPoint = { length: 0 };
18627
- let coarseMinDistanceSquared = Infinity;
18628
- for (let i = 0; i <= pathLength; i += coarseStep) {
18629
- const pointOnPath = pathNode.getPointAtLength(i);
18630
- const distanceSquared = this.getDistanceSquared(point, pointOnPath);
18631
- if (distanceSquared < coarseMinDistanceSquared) {
18632
- coarseMinDistanceSquared = distanceSquared;
18633
- coarseClosestPoint = {
18634
- x: pointOnPath.x,
18635
- y: pointOnPath.y,
18636
- length: i,
18637
- };
18665
+ const coarseStep = 40;
18666
+ const fineStep = 6;
18667
+ // dynamic search window (prevents jump)
18668
+ const SEARCH_WINDOW = 150;
18669
+ let searchStart = 0;
18670
+ let searchEnd = pathLength;
18671
+ // If lastLength exists → restrict search (smooth tracing)
18672
+ if (lastLength !== undefined) {
18673
+ searchStart = Math.max(0, lastLength - SEARCH_WINDOW);
18674
+ searchEnd = Math.min(pathLength, lastLength + SEARCH_WINDOW);
18675
+ }
18676
+ let coarseClosest = { length: searchStart };
18677
+ for (let i = searchStart; i <= searchEnd; i += coarseStep) {
18678
+ const pt = pathNode.getPointAtLength(i);
18679
+ const dist = this.getDistanceSquared(point, pt);
18680
+ if (dist < minDistanceSquared) {
18681
+ minDistanceSquared = dist;
18682
+ coarseClosest = { x: pt.x, y: pt.y, length: i };
18638
18683
  }
18639
18684
  }
18640
- // Second pass: fine sampling around coarseClosestPoint
18641
- const fineStep = 6; // was 2
18642
- const searchStart = Math.max(coarseClosestPoint.length - coarseStep, 0);
18643
- const searchEnd = Math.min(coarseClosestPoint.length + coarseStep, pathLength);
18644
- for (let i = searchStart; i <= searchEnd; i += fineStep) {
18645
- const pointOnPath = pathNode.getPointAtLength(i);
18646
- const distanceSquared = this.getDistanceSquared(point, pointOnPath);
18647
- if (distanceSquared < minDistanceSquared) {
18648
- minDistanceSquared = distanceSquared;
18649
- closestPoint = { x: pointOnPath.x, y: pointOnPath.y, length: i };
18685
+ const fineStart = Math.max(0, coarseClosest.length - coarseStep);
18686
+ const fineEnd = Math.min(pathLength, coarseClosest.length + coarseStep);
18687
+ minDistanceSquared = Infinity;
18688
+ for (let i = fineStart; i <= fineEnd; i += fineStep) {
18689
+ const pt = pathNode.getPointAtLength(i);
18690
+ const dist = this.getDistanceSquared(point, pt);
18691
+ if (dist < minDistanceSquared) {
18692
+ minDistanceSquared = dist;
18693
+ closestPoint = { x: pt.x, y: pt.y, length: i };
18650
18694
  }
18651
18695
  }
18652
18696
  return closestPoint;
@@ -18699,6 +18743,7 @@ const LidoTrace = class {
18699
18743
  state.isDragging = false;
18700
18744
  state.currentPathIndex++;
18701
18745
  state.lastLength = 0;
18746
+ state.isCompletingPath = false;
18702
18747
  this.hideFingerHint(); // remove hint when changing path
18703
18748
  if (state.currentPathIndex >= state.paths.length) {
18704
18749
  this.moveToNextContainer();
@@ -18809,7 +18854,7 @@ const LidoTrace = class {
18809
18854
  };
18810
18855
  }
18811
18856
  render() {
18812
- return (index.h(index.Host, { key: '3f7da73f3c075a90ea0ce27022ed06a60c814fb4', 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: '209d9faf31cf0ec234ee2fd34521eec8bbbf8ac4', style: this.style, id: "lido-svgContainer" })));
18857
+ return (index.h(index.Host, { key: '47a5947638a6a6c84cd294d6b3d8062a36553fc1', 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: '13e10f42f4747405ebe8c9ef5826f386a1e894e9', style: this.style, id: "lido-svgContainer" })));
18813
18858
  }
18814
18859
  static get assetsDirs() { return ["svg", "images"]; }
18815
18860
  get el() { return index.getElement(this); }
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Dl8SlqP-.js');
3
+ var index = require('./index-Bsk4M2Qz.js');
4
4
 
5
5
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
6
6
  /*
7
- Stencil Client Patch Browser v4.43.3 | MIT Licensed | https://stenciljs.com
7
+ Stencil Client Patch Browser v4.43.4 | MIT Licensed | https://stenciljs.com
8
8
  */
9
9
 
10
10
  var patchBrowser = () => {
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-Dl8SlqP-.js');
3
+ var index = require('./index-Bsk4M2Qz.js');
4
4
 
5
5
  const defineCustomElements = async (win, options) => {
6
6
  if (typeof window === 'undefined') return undefined;
@@ -26,7 +26,7 @@
26
26
  "mixins": [],
27
27
  "compiler": {
28
28
  "name": "@stencil/core",
29
- "version": "4.43.3",
29
+ "version": "4.43.4",
30
30
  "typescriptVersion": "5.8.3"
31
31
  },
32
32
  "collections": [],
@@ -288,7 +288,9 @@ export class LidoContainer {
288
288
  "palegmamultioption": "palegmamultioptionAudio" /* templateAudio.palegmamultioption */,
289
289
  "palegraoptionaudio": "palegraoptionAudio" /* templateAudio.palegraoptionaudio */,
290
290
  "palegrawordmatch": "palegrawordmatchAudio" /* templateAudio.palegrawordmatch */,
291
- "palegramcqimages": "palegramcqimagesAudio" /* templateAudio.palegramcqimages */
291
+ "palegramcqimages": "palegramcqimagesAudio" /* templateAudio.palegramcqimages */,
292
+ "drawShape": "drawshape" /* templateAudio.drawShape */,
293
+ "drawshape": "drawshape" /* templateAudio.drawshape */,
292
294
  }[this.templateId]) !== null && _a !== void 0 ? _a : '';
293
295
  const home = document.querySelector('lido-home');
294
296
  if (!home)
@@ -445,7 +447,7 @@ export class LidoContainer {
445
447
  userSelect: 'none', // Prevent any field selection
446
448
  };
447
449
  console.log('🚀 ~ LidoContainer ~ canplay:', this.canplay);
448
- return (h(Host, { key: 'b94060e2432a7e7d8580ffb53ceef4124a4fba25', id: "lido-container", Lang: this.Lang, "tab-index": 0, class: "lido-container", objective: this.objective, baseUrl: this.baseUrl, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, onTouch: this.onTouch, onInCorrect: this.onInCorrect, onCorrect: this.onCorrect, onEntry: this.onEntry, "show-check": `${this.showCheck}`, "is-continue-on-correct": `${this.isContinueOnCorrect}`, "is-allow-only-correct": `${this.isAllowOnlyCorrect}`, canplay: `${this.canplay}`, appendToDropOnCompletion: `${this.appendToDropOnCompletion}`, "show-prev-button": `${this.showPrevButton}`, "show-next-button": `${this.showNextButton}`, "show-drop-border": `${this.showDropBorder}`, "bg-image": this.bgImage, "exit-button-url": this.exitButtonUrl, "prev-button-url": this.prevButtonUrl, "next-button-url": this.nextButtonUrl, "speaker-button-url": this.speakerButtonUrl, "disable-speak": `${this.disableSpeak}`, "template-id": this.templateId, audio: this.audio, "highlight-word-by-word": `${this.highlightWordByWord}` }, h("lido-text", { key: '7b433aa25be08cef849e9cefda243cebd7f6aef6', visible: "false", id: this.templateId, audio: "", string: this.instructName }), h("slot", { key: '95705c210ed7efbcf06e0ad7779b8c00fa4e1818' })));
450
+ return (h(Host, { key: '00435f1640abcc2d786ab2987e5bcda22816b987', id: "lido-container", Lang: this.Lang, "tab-index": 0, class: "lido-container", objective: this.objective, baseUrl: this.baseUrl, style: style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, onTouch: this.onTouch, onInCorrect: this.onInCorrect, onCorrect: this.onCorrect, onEntry: this.onEntry, "show-check": `${this.showCheck}`, "is-continue-on-correct": `${this.isContinueOnCorrect}`, "is-allow-only-correct": `${this.isAllowOnlyCorrect}`, canplay: `${this.canplay}`, appendToDropOnCompletion: `${this.appendToDropOnCompletion}`, "show-prev-button": `${this.showPrevButton}`, "show-next-button": `${this.showNextButton}`, "show-drop-border": `${this.showDropBorder}`, "bg-image": this.bgImage, "exit-button-url": this.exitButtonUrl, "prev-button-url": this.prevButtonUrl, "next-button-url": this.nextButtonUrl, "speaker-button-url": this.speakerButtonUrl, "disable-speak": `${this.disableSpeak}`, "template-id": this.templateId, audio: this.audio, "highlight-word-by-word": `${this.highlightWordByWord}` }, h("lido-text", { key: '9a680e74b6595888174b8ad7a13cc54943292020', visible: "false", id: this.templateId, audio: "", string: this.instructName }), h("slot", { key: '5832050a7c60b9fca20544619b3ebc9f56c3ef67' })));
449
451
  }
450
452
  static get is() { return "lido-container"; }
451
453
  static get originalStyleUrls() {