lido-player 0.0.2-beta-16-dev → 0.0.2-beta-17-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 (76) hide show
  1. package/dist/cjs/{decode-C08Ujimj.js → decode-DUZYNXIv.js} +1 -1
  2. package/dist/cjs/{index-BkBqiwe8.js → index-BEjUmVtH.js} +189 -53
  3. package/dist/cjs/{index-Dy19zuTX.js → index-DnqQXD5x.js} +53 -12
  4. package/dist/cjs/index.cjs.js +2 -2
  5. package/dist/cjs/lido-avatar_22.cjs.entry.js +60 -54
  6. package/dist/cjs/lido-player.cjs.js +3 -3
  7. package/dist/cjs/loader.cjs.js +2 -2
  8. package/dist/collection/collection-manifest.json +1 -1
  9. package/dist/collection/components/calculator/lido-calculator.js +3 -3
  10. package/dist/collection/components/mathMatrix/lido-math-matrix.js +12 -2
  11. package/dist/collection/components/scale/assets/Shadow.svg +9 -0
  12. package/dist/collection/components/scale/lido-balance.css +1 -1
  13. package/dist/collection/components/scale/lido-balance.js +13 -11
  14. package/dist/collection/components/text/lido-text.js +28 -2
  15. package/dist/collection/components/trace/assets/Tracing-hand.svg +8 -0
  16. package/dist/collection/components/trace/lido-trace.js +25 -38
  17. package/dist/collection/css/index.css +7 -4
  18. package/dist/collection/stories/Templates/blender/blender.stories.js +9 -5
  19. package/dist/collection/utils/audioPlayer.js +31 -9
  20. package/dist/collection/utils/utils.js +20 -10
  21. package/dist/collection/utils/utilsHandlers/animationHandler.js +9 -2
  22. package/dist/collection/utils/utilsHandlers/clickHandler.js +8 -0
  23. package/dist/collection/utils/utilsHandlers/dragDropHandler.js +28 -8
  24. package/dist/collection/utils/utilsHandlers/lidoCalculatorHandler.js +12 -15
  25. package/dist/collection/utils/utilsHandlers/slideHandler.js +76 -17
  26. package/dist/components/index.js +1 -1
  27. package/dist/components/lido-balance.js +1 -1
  28. package/dist/components/lido-calculator.js +1 -1
  29. package/dist/components/lido-container.js +1 -1
  30. package/dist/components/lido-home.js +1 -1
  31. package/dist/components/lido-keyboard.js +1 -1
  32. package/dist/components/lido-math-matrix.js +1 -1
  33. package/dist/components/lido-root.js +1 -1
  34. package/dist/components/lido-text.js +1 -1
  35. package/dist/components/lido-trace.js +1 -1
  36. package/dist/components/p-BNNX1Pew.js +12 -0
  37. package/dist/components/p-CTlwn9r7.js +1 -0
  38. package/dist/components/{p-C2p0KZh4.js → p-Cj-6tqzU.js} +1 -1
  39. package/dist/components/p-CjdDpXfk.js +1 -0
  40. package/dist/components/{p-Uluc7jQ7.js → p-D54c-ybm.js} +1 -1
  41. package/dist/components/p-DdQ1eqJr.js +1 -0
  42. package/dist/components/{p-D-IYWSAa.js → p-SPZTb5fI.js} +1 -1
  43. package/dist/components/p-yT7udDfd.js +1 -0
  44. package/dist/esm/{decode-CGJIPA4t.js → decode-BgBfbPZu.js} +1 -1
  45. package/dist/esm/{index-Dq-Z8Dx0.js → index-BeHFCsWf.js} +54 -13
  46. package/dist/esm/{index-C854B63S.js → index-D-29PaRa.js} +189 -53
  47. package/dist/esm/index.js +2 -2
  48. package/dist/esm/lido-avatar_22.entry.js +60 -54
  49. package/dist/esm/lido-player.js +4 -4
  50. package/dist/esm/loader.js +3 -3
  51. package/dist/lido-player/assets/Shadow.svg +9 -0
  52. package/dist/lido-player/assets/Tracing-hand.svg +8 -0
  53. package/dist/lido-player/index.esm.js +1 -1
  54. package/dist/lido-player/lido-player.css +1 -1
  55. package/dist/lido-player/lido-player.esm.js +1 -1
  56. package/dist/lido-player/p-856e1956.entry.js +12 -0
  57. package/dist/lido-player/{p-Bg5mBsd9.js → p-BA2X6O7O.js} +1 -1
  58. package/dist/lido-player/p-BeHFCsWf.js +3 -0
  59. package/dist/lido-player/p-TuBmCgtK.js +1 -0
  60. package/dist/types/components/scale/lido-balance.d.ts +2 -2
  61. package/dist/types/components/text/lido-text.d.ts +6 -1
  62. package/dist/types/components/trace/lido-trace.d.ts +1 -1
  63. package/dist/types/components.d.ts +21 -10
  64. package/dist/types/stencil-public-runtime.d.ts +12 -0
  65. package/dist/types/utils/audioPlayer.d.ts +2 -0
  66. package/dist/types/utils/utilsHandlers/slideHandler.d.ts +5 -0
  67. package/loader/index.d.ts +1 -1
  68. package/package.json +1 -1
  69. package/dist/components/p-C7U1h9gI.js +0 -1
  70. package/dist/components/p-CS6iRQJh.js +0 -1
  71. package/dist/components/p-DGvzMlyn.js +0 -12
  72. package/dist/components/p-DPAlnts-.js +0 -1
  73. package/dist/components/p-DYs8s-uh.js +0 -1
  74. package/dist/lido-player/p-C4OTDhbr.js +0 -1
  75. package/dist/lido-player/p-Dq-Z8Dx0.js +0 -2
  76. package/dist/lido-player/p-f0e333c6.entry.js +0 -12
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BkBqiwe8.js');
3
+ var index = require('./index-BEjUmVtH.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-Dy19zuTX.js');
3
+ var index$1 = require('./index-DnqQXD5x.js');
4
4
 
5
5
  const DragMapKey = 'lidoDragMap';
6
6
  const SelectedValuesKey = 'lidoSelectedValues';
@@ -321,7 +321,7 @@ function dragDropAnimation(container, dragElement, dropElement) {
321
321
  dropElement.classList.remove('zoom-fade-in');
322
322
  dragElement.classList.add('zoom-fade-out');
323
323
  dropElement.classList.add('zoom-fade-out');
324
- setTimeout(() => {
324
+ const cleanup = () => {
325
325
  div.remove();
326
326
  container.style.pointerEvents = 'auto';
327
327
  if (isObjectiveComplete) {
@@ -329,10 +329,18 @@ function dragDropAnimation(container, dragElement, dropElement) {
329
329
  triggerNextContainer();
330
330
  container.removeAttribute(AnimationVanishedValuesKey);
331
331
  }
332
- }, 800); // match animation duration
332
+ };
333
+ const templateId = (container.getAttribute('template-id') || '').toLowerCase();
334
+ if (templateId === 'letterpairing' || templateId === 'numberpair') {
335
+ cleanup();
336
+ }
337
+ else {
338
+ setTimeout(cleanup, 800); // match animation duration
339
+ }
333
340
  }, 250);
334
341
  }
335
342
 
343
+ const isBlenderTemplate = (container) => (container === null || container === void 0 ? void 0 : container.getAttribute('template-id')) === 'blender';
336
344
  function buildDropHasDragFromDOM() {
337
345
  const dropHasDrag = {};
338
346
  const dropElements = document.querySelectorAll("[type='drop']");
@@ -390,7 +398,6 @@ function enableDraggingWithScaling(element) {
390
398
  let mutationFlag = false;
391
399
  // Fetch the container element
392
400
  const container = document.getElementById(LidoContainer);
393
- const templateId = container.getAttribute("template-id");
394
401
  if (!container) {
395
402
  console.error(`Container with ID "container" not found.`);
396
403
  return;
@@ -551,7 +558,7 @@ function enableDraggingWithScaling(element) {
551
558
  allElements.forEach(otherElement => {
552
559
  var _a;
553
560
  if (storedTabIndexes.includes(JSON.parse(otherElement.getAttribute('tab-index')))) {
554
- if (!(((_a = element.getAttribute('dropAttr')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === DropMode.Diagonal) && container.getAttribute("template-id") !== "blender") {
561
+ if (!(((_a = element.getAttribute('dropAttr')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === DropMode.Diagonal) && !isBlenderTemplate(container)) {
555
562
  if (otherElement) {
556
563
  setOpacityIfChanged(otherElement, "0.3");
557
564
  }
@@ -639,7 +646,7 @@ function enableDraggingWithScaling(element) {
639
646
  else {
640
647
  onElementDropComplete(element, mostOverlappedElement);
641
648
  }
642
- if (templateId === "blender" && element && mostOverlappedElement) {
649
+ if (isBlenderTemplate(container) && element && mostOverlappedElement) {
643
650
  const allElements = document.querySelectorAll(`*`);
644
651
  allElements.forEach(el => {
645
652
  removeHighlight(el);
@@ -867,7 +874,7 @@ async function handleResetDragElement(dragElement, dropElement, dropHasDrag, sel
867
874
  highlightElement();
868
875
  }
869
876
  async function onElementDropComplete(dragElement, dropElement) {
870
- var _a, _b, _c, _d, _e, _f, _g, _h;
877
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
871
878
  const container = document.getElementById(LidoContainer);
872
879
  const selectedValueData = (_a = container.getAttribute(SelectedValuesKey)) !== null && _a !== void 0 ? _a : "[]";
873
880
  const dragSelectedData = JSON.stringify(buildDragSelectedMapFromDOM());
@@ -1089,28 +1096,48 @@ async function onElementDropComplete(dragElement, dropElement) {
1089
1096
  // Add pulse and highlight effect for a successful match
1090
1097
  const isCorrect = dropElement['value'].toLowerCase().includes(dragElement['value'].toLowerCase());
1091
1098
  dispatchElementDropEvent(dragElement, dropElement, isCorrect);
1092
- if (container.getAttribute("template-id") !== "blender") {
1099
+ if (!isBlenderTemplate(container)) {
1093
1100
  storingEachActivityScore(isCorrect);
1094
1101
  }
1095
1102
  dragElement.style.opacity = '1';
1096
1103
  const allDropElements = document.querySelectorAll('.drop-element');
1097
1104
  allDropElements.forEach(el => updateDropBorder(el));
1105
+ if (isBlenderTemplate(container)) {
1106
+ const requiredDrops = Number((_j = dropElement.getAttribute('required-drops')) !== null && _j !== void 0 ? _j : 0);
1107
+ const placedDrops = document.querySelectorAll(`[${DropToAttr}="${dropElement.id}"]`).length;
1108
+ const action = placedDrops > 0 && placedDrops <= requiredDrops
1109
+ ? dropElement.getAttribute('onCorrect')
1110
+ : dropElement.getAttribute('onInCorrect');
1111
+ if (action) {
1112
+ await executeActions(action, dropElement, dragElement);
1113
+ }
1114
+ }
1098
1115
  highlightElement();
1099
1116
  await onActivityComplete(dragElement, dropElement);
1100
1117
  }
1101
1118
  function updateDropBorder(element) {
1119
+ var _a;
1102
1120
  if (!element || !element.classList.contains('drop-element'))
1103
1121
  return;
1104
1122
  const container = document.getElementById(LidoContainer);
1105
1123
  if (!container)
1106
1124
  return;
1107
1125
  const showBorder = container.getAttribute('show-drop-border');
1108
- if (showBorder !== 'true') {
1126
+ if (showBorder !== 'true' && !isBlenderTemplate(container)) {
1109
1127
  return;
1110
1128
  }
1111
1129
  const dropId = element.id;
1112
1130
  const dragSelectedElements = document.querySelectorAll(`[${DropToAttr}="${dropId}"]`);
1113
- if (dragSelectedElements.length > 0 && container.getAttribute("template-id") !== "blender") {
1131
+ if (isBlenderTemplate(container)) {
1132
+ const requiredDrops = Number((_a = element.getAttribute('required-drops')) !== null && _a !== void 0 ? _a : 0);
1133
+ const placedDrops = dragSelectedElements.length;
1134
+ const showCorrectBorder = placedDrops > 0 && placedDrops <= requiredDrops;
1135
+ element.classList.toggle('empty', !showCorrectBorder);
1136
+ element.classList.remove('filled');
1137
+ element.style.setProperty('border', showCorrectBorder ? '5px dashed green' : '5px dashed #f34d08', 'important');
1138
+ return;
1139
+ }
1140
+ if (dragSelectedElements.length > 0 && !isBlenderTemplate(container)) {
1114
1141
  element.classList.add('filled');
1115
1142
  element.classList.remove('empty');
1116
1143
  element.classList.remove('highlight-element');
@@ -1197,7 +1224,7 @@ async function onClickDropOrDragElement(element, type) {
1197
1224
  // Move the drag element to the drop position
1198
1225
  selectedDragElement.style.transform = `translate(${translateX}px, ${translateY}px)`;
1199
1226
  // Remove highlights after moving the element
1200
- if (container.getAttribute("template-id") !== "blender") {
1227
+ if (!isBlenderTemplate(container)) {
1201
1228
  const allElements = document.querySelectorAll(`*`);
1202
1229
  allElements.forEach(el => {
1203
1230
  removeHighlight(el);
@@ -1439,9 +1466,18 @@ function highlightElement() {
1439
1466
  }
1440
1467
 
1441
1468
  class AudioPlayer {
1469
+ resolvePlaybackWait() {
1470
+ if (!this.endPromiseResolve) {
1471
+ return;
1472
+ }
1473
+ const resolve = this.endPromiseResolve;
1474
+ this.endPromiseResolve = null;
1475
+ resolve();
1476
+ }
1442
1477
  constructor() {
1443
1478
  this.currentTargetElement = null;
1444
1479
  this.pendingReplayElement = null;
1480
+ this.playbackHasStarted = false;
1445
1481
  this.highlightOverlay = null;
1446
1482
  this.wordRects = [];
1447
1483
  this.activeWordIndex = -1;
@@ -1499,15 +1535,12 @@ class AudioPlayer {
1499
1535
  window.speechSynthesis.cancel();
1500
1536
  }
1501
1537
  // Resolve any pending "ended" wait so callers can continue.
1502
- if (this.endPromiseResolve) {
1503
- const resolve = this.endPromiseResolve;
1504
- this.endPromiseResolve = null;
1505
- resolve();
1506
- }
1538
+ this.resolvePlaybackWait();
1507
1539
  if (!preserveReplay) {
1508
1540
  this.pendingReplayElement = null;
1509
1541
  }
1510
1542
  this.currentTargetElement = null;
1543
+ this.playbackHasStarted = false;
1511
1544
  this.audioElement.pause();
1512
1545
  this.audioElement.currentTime = 0;
1513
1546
  this.audioElement.src = '';
@@ -1545,6 +1578,7 @@ class AudioPlayer {
1545
1578
  }
1546
1579
  async play(targetElement) {
1547
1580
  this.registerVisibilityEvents();
1581
+ this.playbackHasStarted = false;
1548
1582
  if (!this.isWindowVisible()) {
1549
1583
  this.pendingReplayElement = targetElement;
1550
1584
  await this.stop(true);
@@ -1598,6 +1632,24 @@ class AudioPlayer {
1598
1632
  if (audioUrl) {
1599
1633
  audioUrl = convertUrlToRelative(audioUrl);
1600
1634
  this.audioElement.src = audioUrl;
1635
+ this.audioElement.onplaying = () => {
1636
+ this.playbackHasStarted = true;
1637
+ };
1638
+ this.audioElement.onpause = () => {
1639
+ if (this.playbackHasStarted && !this.audioElement.ended) {
1640
+ this.resolvePlaybackWait();
1641
+ }
1642
+ };
1643
+ this.audioElement.onstalled = () => {
1644
+ if (this.playbackHasStarted) {
1645
+ this.resolvePlaybackWait();
1646
+ }
1647
+ };
1648
+ this.audioElement.onerror = () => {
1649
+ if (this.playbackHasStarted) {
1650
+ this.resolvePlaybackWait();
1651
+ }
1652
+ };
1601
1653
  try {
1602
1654
  // setDraggingDisabled(true);
1603
1655
  const language = container.getAttribute('Lang') || 'en';
@@ -1627,10 +1679,7 @@ class AudioPlayer {
1627
1679
  await new Promise(resolve => {
1628
1680
  this.endPromiseResolve = resolve;
1629
1681
  this.audioElement.onended = () => {
1630
- if (this.endPromiseResolve === resolve) {
1631
- this.endPromiseResolve = null;
1632
- }
1633
- resolve();
1682
+ this.resolvePlaybackWait();
1634
1683
  };
1635
1684
  });
1636
1685
  }
@@ -2413,6 +2462,9 @@ function slidingWithScaling(element) {
2413
2462
  if (container.getAttribute('canplay') === 'false')
2414
2463
  return;
2415
2464
  const onStart = (event) => {
2465
+ const templateId = container.getAttribute('template-id');
2466
+ if ((templateId === 'arrangeLetters' || templateId === 'reorder') && container.getAttribute('game-completed') === 'true')
2467
+ return;
2416
2468
  removeHighlight(element);
2417
2469
  isDragging = true;
2418
2470
  elementRect = element.getBoundingClientRect();
@@ -2560,7 +2612,7 @@ function slidingWithScaling(element) {
2560
2612
  element.style.transform = 'translate(0, 0)';
2561
2613
  setTimeout(() => {
2562
2614
  if (overlapElement) {
2563
- slideCompleted(element);
2615
+ void slideCompleted(element);
2564
2616
  overlapElement = false;
2565
2617
  }
2566
2618
  }, 300);
@@ -2584,27 +2636,95 @@ function slidingWithScaling(element) {
2584
2636
  element.addEventListener('touchstart', onStart);
2585
2637
  element.addEventListener(LIDO_INTERACTION_CLEANUP_EVENT, cleanup);
2586
2638
  }
2587
- const slideCompleted = (slideElement) => {
2639
+ const isArrangeLettersContainer = (container) => container.getAttribute('template-id') === 'arrangeLetters';
2640
+ const isReorderContainer = (container) => container.getAttribute('template-id') === 'reorder';
2641
+ const getSlideValuesForValidation = (container, slideElements) => {
2642
+ if (isReorderContainer(container)) {
2643
+ return slideElements.map(element => element.id);
2644
+ }
2645
+ return slideElements.map(element => element['value']);
2646
+ };
2647
+ const updateArrangeLettersCorrectness = (container, slideValues, objectiveValues) => {
2648
+ const slideElements = Array.from(container.querySelectorAll('[type="slide"]'));
2649
+ slideElements.forEach((element, index) => {
2650
+ const isCorrect = index < objectiveValues.length && slideValues[index] === objectiveValues[index].trim();
2651
+ if (isCorrect) {
2652
+ applyBorderToClickableCell(element, '#65BC46');
2653
+ }
2654
+ else {
2655
+ element.style.removeProperty('box-shadow');
2656
+ }
2657
+ });
2658
+ };
2659
+ const isArrangeLettersComplete = (slideValues, objectiveString) => {
2660
+ if (!objectiveString)
2661
+ return false;
2662
+ const objectiveValues = objectiveString.split(',').map(value => value.trim());
2663
+ return slideValues.length === objectiveValues.length
2664
+ && slideValues.every((value, index) => value === objectiveValues[index]);
2665
+ };
2666
+ const updateReorderCorrectness = (container, slideValues, objectiveValues) => {
2667
+ const slideElements = Array.from(container.querySelectorAll('[type="slide"]'));
2668
+ slideElements.forEach((element, index) => {
2669
+ const isCorrect = index < objectiveValues.length && slideValues[index] === objectiveValues[index].trim();
2670
+ if (isCorrect) {
2671
+ applyBorderToClickableCell(element, '#65BC46');
2672
+ }
2673
+ else {
2674
+ element.style.removeProperty('box-shadow');
2675
+ }
2676
+ });
2677
+ };
2678
+ const isReorderComplete = (slideValues, objectiveString) => {
2679
+ if (!objectiveString)
2680
+ return false;
2681
+ const objectiveValues = objectiveString.split(',').map(value => value.trim());
2682
+ return slideValues.length === objectiveValues.length
2683
+ && slideValues.every((value, index) => value === objectiveValues[index]);
2684
+ };
2685
+ const slideCompleted = async (slideElement) => {
2588
2686
  var _a;
2589
2687
  const container = document.getElementById(LidoContainer);
2590
2688
  const slideArr = JSON.parse((_a = container.getAttribute(SelectedValuesKey)) !== null && _a !== void 0 ? _a : '[]');
2591
- const allSlideElements = document.querySelectorAll("[type='slide']");
2592
- let index = 0;
2593
- allSlideElements.forEach(item => {
2594
- slideArr[index++] = item['value'];
2689
+ const allSlideElements = Array.from(document.querySelectorAll("[type='slide']"));
2690
+ const slideValues = getSlideValuesForValidation(container, allSlideElements);
2691
+ slideValues.forEach((value, index) => {
2692
+ slideArr[index] = value;
2595
2693
  });
2596
2694
  container.setAttribute(SelectedValuesKey, JSON.stringify(slideArr));
2597
2695
  const objectiveString = document.getElementById(LidoContainer)['objective'];
2598
2696
  const objectiveArray = objectiveString.split(',');
2599
- const elementIndex = slideArr.indexOf(slideElement['value']);
2600
- const isCorrect = matchStringPattern(slideElement['value'], [objectiveArray[elementIndex].trim()]);
2697
+ const elementIndex = allSlideElements.indexOf(slideElement);
2698
+ const isCorrect = elementIndex >= 0 && elementIndex < objectiveArray.length
2699
+ ? matchStringPattern(slideValues[elementIndex], [objectiveArray[elementIndex].trim()])
2700
+ : false;
2701
+ if (isArrangeLettersContainer(container)) {
2702
+ updateArrangeLettersCorrectness(container, slideValues, objectiveArray);
2703
+ }
2704
+ else if (isReorderContainer(container)) {
2705
+ updateReorderCorrectness(container, slideValues, objectiveArray);
2706
+ }
2601
2707
  if (container.getAttribute('is-continue-on-correct') === 'true') {
2602
2708
  storingEachActivityScore(true);
2603
- // validationForSlideHandler();
2604
2709
  }
2605
2710
  else {
2606
2711
  storingEachActivityScore(isCorrect);
2607
2712
  }
2713
+ if (isArrangeLettersContainer(container) || isReorderContainer(container)) {
2714
+ await validationForSlideHandler(slideValues);
2715
+ }
2716
+ };
2717
+ const validationForSlideHandler = async (slideValues) => {
2718
+ const container = document.getElementById(LidoContainer);
2719
+ if (!container || (!isArrangeLettersContainer(container) && !isReorderContainer(container)) || container.getAttribute('game-completed') === 'true')
2720
+ return;
2721
+ const objectiveString = document.getElementById(LidoContainer)['objective'];
2722
+ const isComplete = isArrangeLettersContainer(container)
2723
+ ? isArrangeLettersComplete(slideValues, objectiveString)
2724
+ : isReorderComplete(slideValues, objectiveString);
2725
+ if (isComplete) {
2726
+ await validateObjectiveStatus();
2727
+ }
2608
2728
  };
2609
2729
 
2610
2730
  const getContainerScale = (container) => {
@@ -3957,6 +4077,14 @@ function addClickListenerForClickType(element) {
3957
4077
  const container = document.getElementById(LidoContainer);
3958
4078
  if (container.getAttribute('canplay') === 'false')
3959
4079
  return;
4080
+ const isBubbleTypeKeyboardKey = (container === null || container === void 0 ? void 0 : container.getAttribute('template-id')) === 'bubbleType' &&
4081
+ element.closest('lido-keyboard') !== null;
4082
+ // BubbleType manages key clicks and audio in lido-keyboard.tsx directly.
4083
+ // Letting the generic click handler attach here creates a competing stop/play
4084
+ // path that can interrupt the first bubble audio.
4085
+ if (isBubbleTypeKeyboardKey) {
4086
+ return;
4087
+ }
3960
4088
  element.style.cursor = 'pointer';
3961
4089
  if (!element) {
3962
4090
  console.error('No element provided.');
@@ -72045,27 +72173,24 @@ const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
72045
72173
  /* ------------------ animation ------------------ */
72046
72174
  const animationToRemoveEquationSolvedCellForNimbleTable = (activeCell, container) => {
72047
72175
  return new Promise((resolve) => {
72048
- const keyframes = `
72049
- @keyframes widthDecrease {
72050
- 0% {
72051
- background-color: ${activeCell.style.backgroundColor};
72052
- height: ${activeCell.style.height};
72053
- margin: ${activeCell.style.margin};
72054
- }
72055
- 100% { background-color: transparent; height: 0px; margin: 0px; }
72056
- }`;
72057
- const styleSheet = document.styleSheets[0];
72058
- styleSheet.insertRule(keyframes, styleSheet.cssRules.length);
72059
- activeCell.style.animation = `widthDecrease 0s`;
72060
- activeCell.addEventListener("animationend", () => {
72061
- activeCell.remove();
72176
+ let removed = false;
72177
+ const removeActiveCell = () => {
72178
+ if (removed)
72179
+ return;
72180
+ removed = true;
72181
+ if (activeCell.isConnected) {
72182
+ activeCell.remove();
72183
+ }
72062
72184
  // Trigger next container only after the last calculate cell is removed
72063
72185
  const remainingCalculateTypes = container.querySelectorAll("[type='calculate']");
72064
72186
  if (remainingCalculateTypes.length === 0) {
72065
72187
  setTimeout(() => triggerNextContainer(), 2000);
72066
72188
  }
72067
72189
  resolve();
72068
- }, { once: true });
72190
+ };
72191
+ // Nimble uses a zero-duration removal; remove synchronously so progression
72192
+ // does not depend on a browser animationend event.
72193
+ removeActiveCell();
72069
72194
  });
72070
72195
  };
72071
72196
  /* ------------------ PRACTICE MODE ------------------ */
@@ -72819,9 +72944,11 @@ const executeActions = async (actionsString, thisElement, element) => {
72819
72944
  if (dropTo === "hundredsDrop")
72820
72945
  hundreds++;
72821
72946
  });
72822
- const unitsValue = units * 1;
72823
- const tensValue = tens * 10;
72824
- const hundredsValue = hundreds * 100;
72947
+ // Blender displays the number of blocks placed in each column.
72948
+ // Blender's drag/drop values are also the required block counts.
72949
+ const unitsValue = units;
72950
+ const tensValue = tens;
72951
+ const hundredsValue = hundreds;
72825
72952
  // ✅ Update Lido Text Boxes
72826
72953
  const unitsBox = document.getElementById("units");
72827
72954
  const tensBox = document.getElementById("tens");
@@ -73082,18 +73209,27 @@ const calculateScore = () => {
73082
73209
  gameScore.totalRightMovesCount += rightMoves;
73083
73210
  gameScore.totalWrongMovesCount += wrongMoves;
73084
73211
  let finalScore = Math.floor((rightMoves / (rightMoves + wrongMoves)) * 100);
73212
+ console.log('[Activity Score]', { rightMoves, wrongMoves, activityScore: finalScore });
73085
73213
  storeActivityScore(finalScore);
73086
73214
  gameScore.rightMoves = 0;
73087
73215
  gameScore.wrongMoves = 0;
73088
73216
  };
73089
73217
  async function onActivityComplete(dragElement, dropElement) {
73090
- var _a, _b;
73218
+ var _a, _b, _c;
73091
73219
  const container = document.getElementById(LidoContainer);
73092
73220
  if (!container)
73093
73221
  return;
73222
+ const isBlender = container.getAttribute('template-id') === 'blender';
73094
73223
  await executeActions("this.alignMatch='true'", dropElement, dragElement);
73095
73224
  if (dragElement && dropElement) {
73096
- const isCorrect = dropElement['value'].toLowerCase().includes(dragElement['value'].toLowerCase());
73225
+ let isCorrect = dropElement['value'].toLowerCase().includes(dragElement['value'].toLowerCase());
73226
+ if (isBlender) {
73227
+ const requiredDrops = Number((_a = dropElement.getAttribute('required-drops')) !== null && _a !== void 0 ? _a : 0);
73228
+ const placedDrops = document.querySelectorAll(`[drop-to="${dropElement.id}"]`).length;
73229
+ // Blender accepts every count from 1 through the required count.
73230
+ // Zero or an overfilled drop zone uses the incorrect action.
73231
+ isCorrect = placedDrops > 0 && placedDrops <= requiredDrops;
73232
+ }
73097
73233
  // storing each activity score based on isCorrect for (all drag-drop events)
73098
73234
  // storingEachActivityScore(isCorrect);
73099
73235
  if (isCorrect) {
@@ -73102,10 +73238,10 @@ async function onActivityComplete(dragElement, dropElement) {
73102
73238
  console.log("Right Moves : ", gameScore.rightMoves);
73103
73239
  console.log("Wrong Moves : ", gameScore.wrongMoves);
73104
73240
  }
73105
- const onCorrect = ((_a = container.getAttribute('dropAttr')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === DropMode.EnableAnimation.toLowerCase()
73241
+ const onCorrect = ((_b = container.getAttribute('dropAttr')) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === DropMode.EnableAnimation.toLowerCase()
73106
73242
  ? ''
73107
73243
  : dropElement.getAttribute('onCorrect');
73108
- if (onCorrect) {
73244
+ if (onCorrect && !isBlender) {
73109
73245
  await executeActions(onCorrect, dropElement, dragElement);
73110
73246
  }
73111
73247
  //for multiply beeds
@@ -73120,7 +73256,7 @@ async function onActivityComplete(dragElement, dropElement) {
73120
73256
  console.log("Wrong Moves : ", gameScore.wrongMoves);
73121
73257
  }
73122
73258
  const onInCorrect = dropElement.getAttribute('onInCorrect');
73123
- if (onInCorrect) {
73259
+ if (onInCorrect && !isBlender) {
73124
73260
  await executeActions(onInCorrect, dropElement, dragElement);
73125
73261
  }
73126
73262
  }
@@ -73129,7 +73265,7 @@ async function onActivityComplete(dragElement, dropElement) {
73129
73265
  const sortedValues = getSortedValuesArrayFromMap(dragScore);
73130
73266
  container.setAttribute(SelectedValuesKey, JSON.stringify(sortedValues));
73131
73267
  //localStorage
73132
- let drag = JSON.parse((_b = localStorage.getItem(DragMapKey)) !== null && _b !== void 0 ? _b : '{}');
73268
+ let drag = JSON.parse((_c = localStorage.getItem(DragMapKey)) !== null && _c !== void 0 ? _c : '{}');
73133
73269
  const index = dropElement.getAttribute('tab-index');
73134
73270
  if (!drag[index]) {
73135
73271
  drag[index] = [];