lido-player 0.0.2-beta-24 → 0.0.2-beta-25-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 (60) hide show
  1. package/dist/cjs/{decode-BCvdWRyT.js → decode-BSImuLEU.js} +1 -1
  2. package/dist/cjs/{index-DjM03fsg.js → index-DRw2yVbg.js} +112 -27
  3. package/dist/cjs/index.cjs.js +1 -1
  4. package/dist/cjs/lido-avatar_22.cjs.entry.js +117 -17
  5. package/dist/cjs/lido-player.cjs.js +1 -1
  6. package/dist/cjs/loader.cjs.js +1 -1
  7. package/dist/collection/components/container/lido-container.css +24 -0
  8. package/dist/collection/components/container/lido-container.js +48 -2
  9. package/dist/collection/components/flashCard/lido-flash-card.js +14 -5
  10. package/dist/collection/components/home/lido-home.js +3 -6
  11. package/dist/collection/components/root/lido-root.js +1 -1
  12. package/dist/collection/components/text/lido-text.js +1 -1
  13. package/dist/collection/utils/audioPlayer.js +3 -1
  14. package/dist/collection/utils/utils.js +50 -7
  15. package/dist/collection/utils/utilsHandlers/slideHandler.js +58 -19
  16. package/dist/components/index.js +1 -1
  17. package/dist/components/lido-calculator.js +1 -1
  18. package/dist/components/lido-container.js +1 -1
  19. package/dist/components/lido-flash-card.js +1 -1
  20. package/dist/components/lido-float.js +1 -1
  21. package/dist/components/lido-home.js +1 -1
  22. package/dist/components/lido-image.js +1 -1
  23. package/dist/components/lido-keyboard.js +1 -1
  24. package/dist/components/lido-math-matrix.js +1 -1
  25. package/dist/components/lido-root.js +1 -1
  26. package/dist/components/lido-slide-fill.js +1 -1
  27. package/dist/components/lido-text.js +1 -1
  28. package/dist/components/lido-trace.js +1 -1
  29. package/dist/components/p-AaE392x7.js +1 -0
  30. package/dist/components/p-B-mIxynb.js +1 -0
  31. package/dist/components/{p-CFPSty2U.js → p-BSWrnLbC.js} +1 -1
  32. package/dist/components/{p-Bv1hunWk.js → p-BW0855oZ.js} +1 -1
  33. package/dist/components/{p-CFWohOId.js → p-BfJG1wmU.js} +1 -1
  34. package/dist/components/{p-B8nzzM8c.js → p-CK9M0Kcf.js} +1 -1
  35. package/dist/components/{p-DLyacZap.js → p-CSxwfvl3.js} +1 -1
  36. package/dist/components/{p-Bh_vemY3.js → p-CVZEVfip.js} +1 -1
  37. package/dist/components/{p-C5jvgiPE.js → p-Cf85Nc-6.js} +1 -1
  38. package/dist/components/{p-C-pHQRbp.js → p-CuDMRxx_.js} +1 -1
  39. package/dist/components/{p-Gwko4CTL.js → p-DPGOqpde.js} +1 -1
  40. package/dist/components/p-i3W5bJbL.js +12 -0
  41. package/dist/esm/{decode-BxzUG5XP.js → decode-D2f5bktc.js} +1 -1
  42. package/dist/esm/{index-C_uxZLF-.js → index-BB56Mo3L.js} +112 -28
  43. package/dist/esm/index.js +1 -1
  44. package/dist/esm/lido-avatar_22.entry.js +117 -17
  45. package/dist/esm/lido-player.js +1 -1
  46. package/dist/esm/loader.js +1 -1
  47. package/dist/lido-player/index.esm.js +1 -1
  48. package/dist/lido-player/lido-player.esm.js +1 -1
  49. package/dist/lido-player/p-53d245b0.entry.js +12 -0
  50. package/dist/lido-player/p-DKuh-2gv.js +1 -0
  51. package/dist/lido-player/{p-CsCr7DlS.js → p-DSlo480E.js} +1 -1
  52. package/dist/types/components/container/lido-container.d.ts +7 -0
  53. package/dist/types/utils/utils.d.ts +7 -0
  54. package/dist/types/utils/utilsHandlers/slideHandler.d.ts +1 -1
  55. package/package.json +1 -1
  56. package/dist/components/p-CgBwmr9A.js +0 -12
  57. package/dist/components/p-Ckb8QhUV.js +0 -1
  58. package/dist/components/p-DDwqmTYM.js +0 -1
  59. package/dist/lido-player/p-00993d1a.entry.js +0 -12
  60. package/dist/lido-player/p-v3GBrpv9.js +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DjM03fsg.js');
3
+ var index = require('./index-DRw2yVbg.js');
4
4
 
5
5
  function _mergeNamespaces(n, m) {
6
6
  m.forEach(function (e) {
@@ -2066,7 +2066,9 @@ class AudioPlayer {
2066
2066
  const duration = timeline[timeline.length - 1].endMs - timeline[0].startMs;
2067
2067
  const averageWordMs = duration / timeline.length;
2068
2068
  const speedLead = averageWordMs < 190 ? 120 : averageWordMs < 260 ? 90 : 60;
2069
- return Math.max(profile.preemptiveOffsetMs, speedLead);
2069
+ // Advance the estimated highlight slightly to compensate for perceived lag.
2070
+ const playbackLeadAdjustmentMs = 40;
2071
+ return Math.max(profile.preemptiveOffsetMs, speedLead) + playbackLeadAdjustmentMs;
2070
2072
  }
2071
2073
  getTimelineIndex(timeline, currentMs) {
2072
2074
  if (!timeline.length)
@@ -2739,6 +2741,7 @@ function slidingWithScaling(element) {
2739
2741
  };
2740
2742
  // Start observing the element
2741
2743
  observer.observe(parentElement, observerConfig);
2744
+ let mostOverlappedElement;
2742
2745
  const onMove = (event) => {
2743
2746
  if (!isDragging)
2744
2747
  return;
@@ -2759,12 +2762,14 @@ function slidingWithScaling(element) {
2759
2762
  // Get the dimensions and scale-corrected position of the container and element
2760
2763
  const containerRect = parentElement.getBoundingClientRect();
2761
2764
  const elementRect = element.getBoundingClientRect();
2762
- const numbers = element.style.transform.match(/-?\d+(\.\d+)?/g);
2763
- const result = numbers.map(Number);
2764
- const initialElementLeftPx = elementRect.left / parentElementScale - result[0];
2765
- const initialElementTopPx = elementRect.top - result[1];
2766
- const initialElementRightPx = elementRect.right / parentElementScale - result[0];
2767
- const initialElementBottomPx = elementRect.bottom - result[1];
2765
+ // Firefox serializes translate(x, 0) as translate(x), so parsing the
2766
+ // inline string can lose Y and produce NaN. Read the computed matrix instead.
2767
+ const transform = window.getComputedStyle(element).transform;
2768
+ const translation = new DOMMatrixReadOnly(transform === 'none' ? undefined : transform);
2769
+ const initialElementLeftPx = elementRect.left / parentElementScale - translation.m41;
2770
+ const initialElementTopPx = elementRect.top - translation.m42;
2771
+ const initialElementRightPx = elementRect.right / parentElementScale - translation.m41;
2772
+ const initialElementBottomPx = elementRect.bottom - translation.m42;
2768
2773
  const maxRight = containerRect.right - initialElementRightPx;
2769
2774
  const maxLeft = containerRect.left - initialElementLeftPx;
2770
2775
  const maxTop = containerRect.top - initialElementTopPx;
@@ -2774,7 +2779,7 @@ function slidingWithScaling(element) {
2774
2779
  // Apply transform with translation within boundaries
2775
2780
  element.style.transform = `translate(${newLeftClamp}px, ${newTopClamp}px)`;
2776
2781
  // Check for overlaps and highlight only the most overlapping element
2777
- let mostOverlappedElement = findMostoverlappedElement$1(element, 'slide');
2782
+ mostOverlappedElement = findMostoverlappedElement$1(element, 'slide');
2778
2783
  // Apply styles only to the most overlapped element
2779
2784
  if (mostOverlappedElement) {
2780
2785
  if (mostOverlappedElement != element) {
@@ -2835,6 +2840,7 @@ function slidingWithScaling(element) {
2835
2840
  setTimeout(() => {
2836
2841
  if (overlapElement) {
2837
2842
  void slideCompleted(element);
2843
+ updateReorderCorrectness(container, element, mostOverlappedElement);
2838
2844
  overlapElement = false;
2839
2845
  }
2840
2846
  }, 300);
@@ -2877,18 +2883,50 @@ const isArrangeLettersComplete = (slideValues, objectiveString) => {
2877
2883
  return slideValues.length === objectiveValues.length
2878
2884
  && slideValues.every((value, index) => value === objectiveValues[index]);
2879
2885
  };
2880
- const updateReorderCorrectness = (container, slideValues, objectiveValues) => {
2881
- const slideElements = Array.from(container.querySelectorAll('[type="slide"]'));
2882
- slideElements.forEach((element, index) => {
2883
- const isCorrect = index < objectiveValues.length && slideValues[index] === objectiveValues[index].trim();
2884
- if (isCorrect) {
2885
- applyBorderToClickableCell(element, '#65BC46');
2886
- }
2887
- else {
2888
- element.style.removeProperty('box-shadow');
2889
- }
2890
- });
2886
+ const updateReorderCorrectness = (container, slideElement, overlappedElement) => {
2887
+ const allSlideElements = Array.from(container.querySelectorAll('[type="slide"]'));
2888
+ const elementIndex = allSlideElements.indexOf(slideElement);
2889
+ const overlappedElementIndex = allSlideElements.indexOf(overlappedElement);
2890
+ const objectiveString = document.getElementById(LidoContainer)['objective'];
2891
+ const objectiveArray = objectiveString.split(',');
2892
+ const slideValues = getSlideValuesForValidation(container, allSlideElements);
2893
+ const isCorrect = elementIndex >= 0 && elementIndex < objectiveArray.length
2894
+ ? matchStringPattern(slideValues[elementIndex], [objectiveArray[elementIndex].trim()])
2895
+ : false;
2896
+ const isCorrectOverlap = overlappedElementIndex >= 0 && overlappedElementIndex < objectiveArray.length
2897
+ ? matchStringPattern(slideValues[overlappedElementIndex], [objectiveArray[overlappedElementIndex].trim()])
2898
+ : false;
2899
+ if (isCorrect && isCorrectOverlap) {
2900
+ updateElementCategoryClass(slideElement, true);
2901
+ updateElementCategoryClass(overlappedElement, true);
2902
+ }
2903
+ else if (isCorrect) {
2904
+ updateElementCategoryClass(slideElement, true);
2905
+ updateElementCategoryClass(overlappedElement, false);
2906
+ }
2907
+ else if (isCorrectOverlap) {
2908
+ updateElementCategoryClass(slideElement, false);
2909
+ updateElementCategoryClass(overlappedElement, true);
2910
+ }
2911
+ else {
2912
+ updateElementCategoryClass(slideElement, false);
2913
+ updateElementCategoryClass(overlappedElement, false);
2914
+ }
2891
2915
  };
2916
+ function updateElementCategoryClass(element, isCorrect) {
2917
+ if (!element)
2918
+ return;
2919
+ const correctClass = 'category-dropped-onCorrect';
2920
+ const incorrectClass = 'category-dropped-onInCorrect';
2921
+ if (isCorrect) {
2922
+ element.classList.add(correctClass);
2923
+ element.classList.remove(incorrectClass);
2924
+ }
2925
+ else {
2926
+ element.classList.add(incorrectClass);
2927
+ element.classList.remove(correctClass);
2928
+ }
2929
+ }
2892
2930
  const isReorderComplete = (slideValues, objectiveString) => {
2893
2931
  if (!objectiveString)
2894
2932
  return false;
@@ -2916,7 +2954,10 @@ const slideCompleted = async (slideElement) => {
2916
2954
  updateArrangeLettersCorrectness(container, slideValues, objectiveArray);
2917
2955
  }
2918
2956
  else if (isReorderContainer(container)) {
2919
- updateReorderCorrectness(container, slideValues, objectiveArray);
2957
+ if (isReorderComplete(slideValues, objectiveString)) {
2958
+ allSlideElements.forEach(item => updateElementCategoryClass(item, true));
2959
+ }
2960
+ // updateReorderCorrectness(container, slideValues, objectiveArray);
2920
2961
  }
2921
2962
  if (container.getAttribute('is-continue-on-correct') === 'true') {
2922
2963
  storingEachActivityScore(true);
@@ -72973,6 +73014,22 @@ const initEventsForElement = async (element, type) => {
72973
73014
  }
72974
73015
  onTouchListenerForOnTouch(element);
72975
73016
  };
73017
+ /**
73018
+ * Re-enable the gameplay handlers for interactive children that were created
73019
+ * while the player was in edit mode. This is intentionally limited to the
73020
+ * drag/drop elements used by Food Jar; other templates retain their existing
73021
+ * component-load initialization path.
73022
+ */
73023
+ const initializePlayModeDragDropElements = async (root) => {
73024
+ const elements = root.querySelectorAll('[type="drag"], [type="drop"]');
73025
+ for (const element of Array.from(elements)) {
73026
+ const type = element.getAttribute('type') || undefined;
73027
+ const initializedElement = element;
73028
+ if (initializedElement.__lidoInitializationKey === `${type || ''}:true`)
73029
+ continue;
73030
+ await initEventsForElement(element, type);
73031
+ }
73032
+ };
72976
73033
  // Function to execute actions parsed from the onMatch string
72977
73034
  const executeActions = async (actionsString, thisElement, element, options = {}) => {
72978
73035
  var _a, _b, _c, _d, _e, _f, _g, _h;
@@ -73256,12 +73313,25 @@ const afterDropDragHandling = (dragElement, dropElement) => {
73256
73313
  const element = dragElement;
73257
73314
  const isAppend = container.getAttribute('drop-action') === exports.DropAction.Move;
73258
73315
  const isInfinite = container.getAttribute('drop-action') === exports.DropAction.InfiniteDrop;
73316
+ const isCreateSentence = container.getAttribute('template-id') === 'createSentence';
73317
+ // Reserve the source slot synchronously so an overlapping drag sees the
73318
+ // updated source layout before the dropped element is reparented.
73319
+ let sourcePlaceholder = null;
73320
+ if (isAppend && isCreateSentence) {
73321
+ const computedStyle = window.getComputedStyle(dragElement);
73322
+ sourcePlaceholder = document.createElement('div');
73323
+ sourcePlaceholder.style.width = `${dragElement.offsetWidth}px`;
73324
+ sourcePlaceholder.style.height = `${dragElement.offsetHeight}px`;
73325
+ sourcePlaceholder.style.margin = computedStyle.margin;
73326
+ sourcePlaceholder.style.visibility = 'hidden';
73327
+ dragElement.replaceWith(sourcePlaceholder);
73328
+ }
73259
73329
  if (isAppend || isInfinite) {
73260
- setTimeout(() => {
73330
+ const finishDrop = () => {
73261
73331
  var _a, _b;
73262
73332
  dragElement.style.transform = 'translate(0,0)';
73263
73333
  dragElement.style.transition = '';
73264
- let dummyElement = document.createElement('div');
73334
+ let dummyElement = sourcePlaceholder || document.createElement('div');
73265
73335
  if (isInfinite) {
73266
73336
  dummyElement = cloneElementWithComputedStyles(dragElement);
73267
73337
  dummyElement.classList.remove('dropped');
@@ -73276,7 +73346,9 @@ const afterDropDragHandling = (dragElement, dropElement) => {
73276
73346
  }, 100);
73277
73347
  }
73278
73348
  dummyElement.setAttribute('id', dragElement.getAttribute('id'));
73279
- dragElement.replaceWith(dummyElement);
73349
+ if (!sourcePlaceholder) {
73350
+ dragElement.replaceWith(dummyElement);
73351
+ }
73280
73352
  const keyframes = `
73281
73353
  @keyframes widthDecrease {
73282
73354
  0% { width: ${dragElement.style.width}; height: ${dragElement.style.height}; margin: ${dragElement.style.margin}; }
@@ -73284,9 +73356,15 @@ const afterDropDragHandling = (dragElement, dropElement) => {
73284
73356
  }
73285
73357
  `;
73286
73358
  if (!isInfinite) {
73287
- dummyElement.style.width = element.style.width;
73288
- dummyElement.style.height = element.style.height;
73289
- dummyElement.style.margin = element.style.margin;
73359
+ dummyElement.style.width = sourcePlaceholder
73360
+ ? sourcePlaceholder.style.width
73361
+ : element.style.width;
73362
+ dummyElement.style.height = sourcePlaceholder
73363
+ ? sourcePlaceholder.style.height
73364
+ : element.style.height;
73365
+ dummyElement.style.margin = sourcePlaceholder
73366
+ ? sourcePlaceholder.style.margin
73367
+ : element.style.margin;
73290
73368
  const styleSheet = document.styleSheets[0];
73291
73369
  styleSheet.insertRule(keyframes, styleSheet.cssRules.length);
73292
73370
  dummyElement.style.animation = `widthDecrease 0.5s`;
@@ -73316,7 +73394,13 @@ const afterDropDragHandling = (dragElement, dropElement) => {
73316
73394
  const scaledLeft = (dropCenterX - dragCenterX) / containerScale;
73317
73395
  const scaledTop = (dropCenterY - dragCenterY) / containerScale;
73318
73396
  dragElement.style.transform = `translate(${scaledLeft}px, ${scaledTop}px)`;
73319
- }, 700);
73397
+ };
73398
+ if (isAppend && isCreateSentence) {
73399
+ finishDrop();
73400
+ }
73401
+ else {
73402
+ setTimeout(finishDrop, 700);
73403
+ }
73320
73404
  }
73321
73405
  };
73322
73406
  // function cloneElementWithComputedStyles(originalEl: HTMLElement): HTMLElement {
@@ -74584,6 +74668,7 @@ exports.handleFloatElementPosition = handleFloatElementPosition;
74584
74668
  exports.handlingChildElements = handlingChildElements;
74585
74669
  exports.highlightElement = highlightElement;
74586
74670
  exports.initEventsForElement = initEventsForElement;
74671
+ exports.initializePlayModeDragDropElements = initializePlayModeDragDropElements;
74587
74672
  exports.matchStringPattern = matchStringPattern;
74588
74673
  exports.nextUrl = nextUrl;
74589
74674
  exports.parseProp = parseProp;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-DjM03fsg.js');
3
+ var index = require('./index-DRw2yVbg.js');
4
4
  require('./index-DBCFoh1I.js');
5
5
 
6
6
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-DBCFoh1I.js');
4
- var index$1 = require('./index-DjM03fsg.js');
4
+ var index$1 = require('./index-DRw2yVbg.js');
5
5
 
6
6
  var rive$1 = {exports: {}};
7
7
 
@@ -11776,6 +11776,22 @@ const instruction$4 = {
11776
11776
  palegramcqimages: "palegramcqimagesEngAudio"
11777
11777
  };
11778
11778
  var en = {
11779
+ " balloon": "Balloon",
11780
+ " box": "Box",
11781
+ " egg": "Egg",
11782
+ " flower": "Flower",
11783
+ " heart": "Heart",
11784
+ " house": "House",
11785
+ " lamp": "Lamp",
11786
+ " moon": "Moon",
11787
+ " rectangle": "Rectangle",
11788
+ " star": "Star",
11789
+ " watermelon": "Watermelon",
11790
+ " trophy": "Trophy",
11791
+ " dog": "Dog",
11792
+ " fish": "Fish",
11793
+ " bird": "Bird",
11794
+ " arrow": "Arrow",
11779
11795
  "Do you want to exit? button": "Do you want to exit?",
11780
11796
  "Exit button": "Exit",
11781
11797
  "Continue playing button": "Continue playing",
@@ -11833,6 +11849,22 @@ const instruction$2 = {
11833
11849
  palegramcqimages: "palegramcqimagesHiAudio"
11834
11850
  };
11835
11851
  var hi = {
11852
+ " balloon": "गुब्बारा",
11853
+ " box": "डिब्बा",
11854
+ " egg": "अंडा",
11855
+ " flower": "फूल",
11856
+ " heart": "दिल",
11857
+ " house": "घर",
11858
+ " lamp": "दीपक",
11859
+ " moon": "चंद्रमा",
11860
+ " rectangle": "आयत",
11861
+ " star": "तारा",
11862
+ " watermelon": "तरबूज",
11863
+ " trophy": "ट्रॉफी",
11864
+ " dog": "कुत्ता",
11865
+ " fish": "मछली",
11866
+ " bird": "चिड़िया",
11867
+ " arrow": "तीर",
11836
11868
  "Do you want to exit? button": "क्या आप बाहर निकलना चाहते हैं?",
11837
11869
  "Exit button": "बाहर निकलें",
11838
11870
  "Continue playing button": "खेलना जारी रखें",
@@ -11875,6 +11907,22 @@ const instruction$1 = {
11875
11907
  palegramcqimages: "palegramcqimagesKaAudio"
11876
11908
  };
11877
11909
  var kn = {
11910
+ " balloon": "ಪುಗ್ಗ",
11911
+ " box": "ಡಬ್ಬ",
11912
+ " egg": "ಮೊಟ್ಟೆ",
11913
+ " flower": "ಹೂವು",
11914
+ " heart": "ಹೃದಯ",
11915
+ " house": "ಮನೆ",
11916
+ " lamp": "ದೀಪ",
11917
+ " moon": "ಚಂದ್ರ",
11918
+ " rectangle": "ಆಯತ",
11919
+ " star": "ನಕ್ಷತ್ರ",
11920
+ " watermelon": "ಕಲ್ಲಂಗಡಿ",
11921
+ " trophy": "ಟ್ರೋಫಿ",
11922
+ " dog": "ನಾಯಿ",
11923
+ " fish": "ಮೀನು",
11924
+ " bird": "ಹಕ್ಕಿ",
11925
+ " arrow": "ಬಾಣ",
11878
11926
  "Do you want to exit? button": "ನೀವು ನಿರ್ಗಮಿಸಲು ಬಯಸುವಿರಾ?",
11879
11927
  "Exit button": "ನಿರ್ಗಮಿಸು",
11880
11928
  "Continue playing button": "ಆಟವನ್ನು ಮುಂದುವರಿಸಿ",
@@ -11936,7 +11984,7 @@ instance
11936
11984
  },
11937
11985
  });
11938
11986
 
11939
- const lidoContainerCss = () => `.lido-container{position:relative;height:100%;width:100%;background-color:var(--bgColor, transparent);display:flex;flex-direction:column;justify-content:center;align-items:center}`;
11987
+ const lidoContainerCss = () => `.lido-container{position:relative;height:100%;width:100%;background-color:var(--bgColor, transparent);display:flex;flex-direction:column;justify-content:center;align-items:center}lido-container[template-id="writeCard"] #arrow{box-sizing:border-box;border:10px solid transparent;box-shadow:0px 8px 0px 0px #8b310f;animation:flash-card-next-attention 1.4s ease-in-out infinite}lido-container[template-id="writeCard"] #arrow.fading{opacity:1 !important}@keyframes flash-card-next-attention{0%,100%{border-color:#ffc34d;filter:drop-shadow(0 0 0 rgba(255, 195, 77, 0))}50%{border-color:#fff1a8;filter:drop-shadow(0 0 10px rgba(255, 195, 77, 0.95))}}`;
11940
11988
 
11941
11989
  const LidoContainer = class {
11942
11990
  constructor(hostRef) {
@@ -12096,6 +12144,33 @@ const LidoContainer = class {
12096
12144
  this.speakFlag = false;
12097
12145
  this.handleWindowResize = () => this.scaleContainer(this.el);
12098
12146
  this.handleWindowLoad = () => this.scaleContainer(this.el);
12147
+ this.shouldInitializePlayModeDragDrop = false;
12148
+ this.isWriteCardContainer = () => this.templateId === 'writeCard';
12149
+ this.syncWriteCardArrowHighlight = () => {
12150
+ if (!this.isWriteCardContainer())
12151
+ return;
12152
+ const arrow = this.el.querySelector('#arrow');
12153
+ if (!arrow)
12154
+ return;
12155
+ const style = window.getComputedStyle(arrow);
12156
+ const hidden = style.display === 'none' ||
12157
+ style.visibility === 'hidden' ||
12158
+ style.opacity === '0';
12159
+ arrow.classList.toggle('flash-card-next-glowing', !hidden);
12160
+ };
12161
+ this.observeWriteCardArrow = () => {
12162
+ var _a;
12163
+ if (!this.isWriteCardContainer())
12164
+ return;
12165
+ (_a = this.writeCardArrowObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
12166
+ this.writeCardArrowObserver = new MutationObserver(() => this.syncWriteCardArrowHighlight());
12167
+ this.writeCardArrowObserver.observe(this.el, {
12168
+ subtree: true,
12169
+ attributes: true,
12170
+ attributeFilter: ['class', 'style', 'visible'],
12171
+ });
12172
+ this.syncWriteCardArrowHighlight();
12173
+ };
12099
12174
  }
12100
12175
  cleanupInteractionHandlers() {
12101
12176
  this.el.querySelectorAll('[type="drag"], [type="slide"], [move="true"]').forEach(element => {
@@ -12106,6 +12181,17 @@ const LidoContainer = class {
12106
12181
  const langToApply = newLang || this.resolveLanguage();
12107
12182
  this.updateChildTextLanguage(langToApply);
12108
12183
  }
12184
+ canplayChanged(newValue, oldValue) {
12185
+ if (this.templateId !== 'foodJar' || !newValue || oldValue !== false)
12186
+ return;
12187
+ this.shouldInitializePlayModeDragDrop = true;
12188
+ }
12189
+ componentDidRender() {
12190
+ if (!this.shouldInitializePlayModeDragDrop || !this.canplay)
12191
+ return;
12192
+ this.shouldInitializePlayModeDragDrop = false;
12193
+ void index$1.initializePlayModeDragDropElements(this.el);
12194
+ }
12109
12195
  componentWillLoad() {
12110
12196
  const langToApply = this.resolveLanguage();
12111
12197
  this.updateChildTextLanguage(langToApply);
@@ -12341,10 +12427,12 @@ const LidoContainer = class {
12341
12427
  setTimeout(() => {
12342
12428
  this.el.setAttribute("onEntry", `${this.templateId}.speak='${!this.speakFlag}'; ` + this.el.getAttribute("onEntry"));
12343
12429
  index$1.initEventsForElement(this.el, this.type);
12430
+ this.observeWriteCardArrow();
12344
12431
  }, 100);
12345
12432
  }
12346
12433
  else {
12347
12434
  index$1.initEventsForElement(this.el, this.type);
12435
+ this.observeWriteCardArrow();
12348
12436
  }
12349
12437
  if (this.customStyle) {
12350
12438
  const styleElement = document.createElement('style');
@@ -12360,9 +12448,12 @@ const LidoContainer = class {
12360
12448
  index$1.Timer.getI().start();
12361
12449
  }
12362
12450
  disconnectedCallback() {
12451
+ var _a;
12363
12452
  this.cleanupInteractionHandlers();
12364
12453
  window.removeEventListener('resize', this.handleWindowResize);
12365
12454
  window.removeEventListener('load', this.handleWindowLoad);
12455
+ (_a = this.writeCardArrowObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
12456
+ this.writeCardArrowObserver = undefined;
12366
12457
  document.body.style.backgroundColor = '';
12367
12458
  document.body.style.backgroundImage = '';
12368
12459
  index$1.resetFloatState();
@@ -12379,12 +12470,15 @@ const LidoContainer = class {
12379
12470
  margin: this.margin,
12380
12471
  userSelect: 'none', // Prevent any field selection
12381
12472
  };
12382
- return (index.h(index.Host, { key: '9dd374c6cdfcc88a5b18e7dc7fec527c853a4719', 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: '8295782a74ce6ef8ca9a623de8a28b539d9f6d4f', visible: "false", id: this.templateId, audio: "", string: this.instructName }), index.h("slot", { key: 'eb3c995b777986e07dcb6aa935ef38d41aa1e7e7' })));
12473
+ return (index.h(index.Host, { key: 'c4063b11ee7b13e43701fa1573129c043f20bce3', 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: 'de5f9d8a8711ddc533dd105640e64152035dee9f', visible: "false", id: this.templateId, audio: "", string: this.instructName }), index.h("slot", { key: 'ec46b584fa6d4982e69d8b8b2e72e8991bdc2458' })));
12383
12474
  }
12384
12475
  get el() { return index.getElement(this); }
12385
12476
  static get watchers() { return {
12386
12477
  "Lang": [{
12387
12478
  "languageChanged": 0
12479
+ }],
12480
+ "canplay": [{
12481
+ "canplayChanged": 0
12388
12482
  }]
12389
12483
  }; }
12390
12484
  };
@@ -12500,7 +12594,7 @@ const LidoFlash = class {
12500
12594
  arrow.classList.add('flash-card-next-glowing');
12501
12595
  };
12502
12596
  this.onAudioEnded = (event) => {
12503
- var _a, _b, _c, _d;
12597
+ var _a, _b, _c;
12504
12598
  const target = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.target;
12505
12599
  const instruction = this.instructionText();
12506
12600
  if (!target || (target !== instruction && target.id !== 'lido-avatar' && !this.el.contains(target)))
@@ -12537,7 +12631,6 @@ const LidoFlash = class {
12537
12631
  if (playbackContext !== this.goodJobPlaybackContext || playbackId !== this.goodJobPlaybackId)
12538
12632
  return;
12539
12633
  this.goodJobPlaybackId = undefined;
12540
- (_d = this.nextArrow()) === null || _d === void 0 ? void 0 : _d.classList.remove('flash-card-next-glowing');
12541
12634
  index$1.executeActions("this.avatarAnimate='Idle'", target);
12542
12635
  }
12543
12636
  };
@@ -12608,11 +12701,19 @@ const LidoFlash = class {
12608
12701
  (_a = this.nextArrow()) === null || _a === void 0 ? void 0 : _a.classList.remove('flash-card-next-glowing');
12609
12702
  };
12610
12703
  this.speakFront = () => {
12611
- var _a;
12704
+ var _a, _b;
12612
12705
  const text = this.frontText();
12613
12706
  if (this.instructionDone && !this.flipped && text && ((_a = text.textContent) === null || _a === void 0 ? void 0 : _a.trim())) {
12614
12707
  this.startNarration(text);
12615
12708
  }
12709
+ else if (this.instructionDone && !this.flipped && (!text || !((_b = text.textContent) === null || _b === void 0 ? void 0 : _b.trim()))) {
12710
+ if (this.autoFlipTimer)
12711
+ window.clearTimeout(this.autoFlipTimer);
12712
+ this.autoFlipTimer = window.setTimeout(() => {
12713
+ if (!this.flipped)
12714
+ this.handleFlip();
12715
+ }, this.autoFlipAfter);
12716
+ }
12616
12717
  };
12617
12718
  this.clearNarrationTimers = () => {
12618
12719
  if (this.narrationGraceTimer)
@@ -12678,6 +12779,8 @@ const LidoFlash = class {
12678
12779
  mascot.setAttribute('audio', scaffoldAudio);
12679
12780
  }
12680
12781
  this.setArrowVisible(true);
12782
+ // Keep the next action highlighted after mascot audio ends.
12783
+ arrow.classList.add('flash-card-next-glowing');
12681
12784
  if (mascot) {
12682
12785
  this.goodJobPlaybackContext = {};
12683
12786
  this.goodJobPlaybackId = undefined;
@@ -12758,12 +12861,12 @@ const LidoFlash = class {
12758
12861
  }
12759
12862
  /* ---------- Render ---------- */
12760
12863
  render() {
12761
- return (index.h(index.Host, { key: '9098ad4c1f41ac70e6737438209f2f3027153b3b', 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: (event) => {
12864
+ return (index.h(index.Host, { key: '57b9dc5ecf618dc381a58e107fa2990b84f5517a', 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: (event) => {
12762
12865
  var _a, _b;
12763
12866
  if ((_b = (_a = event.target) === null || _a === void 0 ? void 0 : _a.closest) === null || _b === void 0 ? void 0 : _b.call(_a, '#lido-avatar'))
12764
12867
  return;
12765
12868
  this.handleFlip();
12766
- }, "disable-speak": this.disableSpeak }, index.h("div", { key: 'b235e008f35e29db21991d76bd83fccac471ba75', class: `card ${this.flipped ? 'flipped' : ''}` }, index.h("div", { key: '7b2306efdc5a4dac6edfe5004ae34ef486b73dd5', class: "card-face card-front" }, this.front != null ? this.front : index.h("slot", { name: "front" })), index.h("div", { key: '3d164fa2faa72b7ffcbaf20482bfea2148aeaaf4', class: "card-face card-back" }, this.back != null ? this.back : index.h("slot", { name: "back" })))));
12869
+ }, "disable-speak": this.disableSpeak }, index.h("div", { key: '3712fc66e33323bdd55e0abb747370ee461dc808', class: `card ${this.flipped ? 'flipped' : ''}` }, index.h("div", { key: 'eb8af2e445393592c0e8a3e4c5934c71dcab4b4e', class: "card-face card-front" }, this.front != null ? this.front : index.h("slot", { name: "front" })), index.h("div", { key: 'efa14cc7ea506714342151b12a9724bdcdb1eba8', class: "card-face card-back" }, this.back != null ? this.back : index.h("slot", { name: "back" })))));
12767
12870
  }
12768
12871
  get el() { return index.getElement(this); }
12769
12872
  static get watchers() { return {
@@ -13104,8 +13207,8 @@ const LidoHome = class {
13104
13207
  }
13105
13208
  translateHomeText(key) {
13106
13209
  var _a;
13107
- const lang = (_a = this.Lang) === null || _a === void 0 ? void 0 : _a.trim();
13108
- return lang ? instance.getFixedT(lang)(key) : instance.t(key);
13210
+ const lang = ((_a = this.Lang) === null || _a === void 0 ? void 0 : _a.trim()) || instance.language || 'en';
13211
+ return instance.getFixedT(lang)(key);
13109
13212
  }
13110
13213
  onCommonAudioPathChange(path) {
13111
13214
  this.publishCommonAudioPath(path);
@@ -13211,7 +13314,7 @@ const LidoHome = class {
13211
13314
  }
13212
13315
  // Pure-JS fallback (no wasm asset required)
13213
13316
  try {
13214
- const brotliDecodeModule = await Promise.resolve().then(function () { return require('./decode-BCvdWRyT.js'); }).then(function (n) { return n.decode; });
13317
+ const brotliDecodeModule = await Promise.resolve().then(function () { return require('./decode-BSImuLEU.js'); }).then(function (n) { return n.decode; });
13215
13318
  const brotliDecompressBuffer = brotliDecodeModule.BrotliDecompressBuffer || ((_a = brotliDecodeModule.default) === null || _a === void 0 ? void 0 : _a.BrotliDecompressBuffer);
13216
13319
  if (typeof brotliDecompressBuffer !== 'function') {
13217
13320
  throw new Error('BrotliDecompressBuffer function not found in brotli/dec/decode');
@@ -13445,10 +13548,7 @@ const LidoHome = class {
13445
13548
  })
13446
13549
  .filter(Boolean);
13447
13550
  if (tagName === 'lido-text' && props.string) {
13448
- props.string = instance.t(props.string);
13449
- }
13450
- if (tagName === 'lido-text' && props.string) {
13451
- props.string = instance.t(props.string);
13551
+ props.string = this.translateHomeText(props.string);
13452
13552
  }
13453
13553
  // Map XML tags to Stencil components
13454
13554
  const componentMapping = {
@@ -17561,7 +17661,7 @@ const LidoRoot = class {
17561
17661
  return index.h("div", null, "Error loading XML data. Please check the path or URL.");
17562
17662
  }
17563
17663
  // Once the XML data is loaded, pass it to the `lido-home` component
17564
- return (index.h("lido-home", Object.assign({ showNav: true, activeContainerIndexes: [], initialIndex: this.initialIndex, canplay: this.canplay, xmlData: this.xmlData, baseUrl: this.baseUrl }, (this.zipUrl ? { zipUrl: this.zipUrl } : {}), { exitButtonUrl: this.exitButtonUrl, prevButtonUrl: this.prevButtonUrl, nextButtonUrl: this.nextButtonUrl, speakerButtonUrl: this.speakerButtonUrl })));
17664
+ return (index.h("lido-home", Object.assign({ showNav: true, activeContainerIndexes: [], initialIndex: this.initialIndex, canplay: this.canplay, Lang: this.Lang, xmlData: this.xmlData, baseUrl: this.baseUrl }, (this.zipUrl ? { zipUrl: this.zipUrl } : {}), { exitButtonUrl: this.exitButtonUrl, prevButtonUrl: this.prevButtonUrl, nextButtonUrl: this.nextButtonUrl, speakerButtonUrl: this.speakerButtonUrl })));
17565
17665
  }
17566
17666
  static get assetsDirs() { return ["assets"]; }
17567
17667
  static get watchers() { return {
@@ -18319,7 +18419,7 @@ const LidoText = class {
18319
18419
  }
18320
18420
  render() {
18321
18421
  const displayText = instance.t(this.string).replace(/_phonics?/gi, '');
18322
- return (index.h(index.Host, { key: 'f15f324ad2bf6bf540e1b99bebc18aee13e0f76e', class: "lido-text", value: this.value, "required-drops": this.requiredDrops, type: this.type, "tab-index": this.tabIndex, audio: this.audio, onTouch: this.onTouch, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, onEntry: this.onEntry, minDrops: this.minDrops, maxDrops: this.maxDrops, id: this.id, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, move: this.move, "span-type": this.spanType, "disable-speak": `${this.disableSpeak}` }, this.spanType !== '' ? index.h("div", { class: "lido-text-content" }, " ", displayText) : displayText));
18422
+ return (index.h(index.Host, { key: '4fd148b3700fa894e6dc38810453a08a1c6858d1', class: "lido-text", value: this.value, "required-drops": this.requiredDrops, type: this.type, "tab-index": this.tabIndex, audio: this.audio, onTouch: this.onTouch, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, onEntry: this.onEntry, minDrops: this.minDrops, maxDrops: this.maxDrops, id: this.id, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, move: this.move, "span-type": this.spanType, "disable-speak": `${this.disableSpeak}` }, this.spanType !== '' ? index.h("div", { class: "lido-text-content" }, " ", displayText) : displayText));
18323
18423
  }
18324
18424
  get el() { return index.getElement(this); }
18325
18425
  };