jclic 2.1.21 → 2.1.23

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 (175) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/jclic-node.js +9 -8
  3. package/dist/jclic-node.js.map +1 -1
  4. package/dist/jclic.min.js +2 -2
  5. package/dist/jclic.min.js.map +1 -1
  6. package/package.json +4 -4
  7. package/src/GlobalData.js +1 -1
  8. package/src/JClicPlayer.js +2 -2
  9. package/src/bags/MediaBag.js +6 -5
  10. package/dist/1078.jclic-node.js +0 -282
  11. package/dist/1078.jclic-node.js.map +0 -1
  12. package/dist/1196.jclic-node.js +0 -808
  13. package/dist/1196.jclic-node.js.map +0 -1
  14. package/dist/1253.jclic-node.js +0 -1432
  15. package/dist/1253.jclic-node.js.map +0 -1
  16. package/dist/13.jclic-node.js +0 -103
  17. package/dist/13.jclic-node.js.map +0 -1
  18. package/dist/1567.jclic-node.js +0 -2313
  19. package/dist/1567.jclic-node.js.map +0 -1
  20. package/dist/1588.jclic-node.js +0 -602
  21. package/dist/1588.jclic-node.js.map +0 -1
  22. package/dist/1725.jclic-node.js +0 -836
  23. package/dist/1725.jclic-node.js.map +0 -1
  24. package/dist/1731.jclic-node.js +0 -438
  25. package/dist/1731.jclic-node.js.map +0 -1
  26. package/dist/1842.jclic-node.js +0 -651
  27. package/dist/1842.jclic-node.js.map +0 -1
  28. package/dist/2160.jclic-node.js +0 -1016
  29. package/dist/2160.jclic-node.js.map +0 -1
  30. package/dist/222.jclic-node.js +0 -129
  31. package/dist/222.jclic-node.js.map +0 -1
  32. package/dist/2316.jclic-node.js +0 -949
  33. package/dist/2316.jclic-node.js.map +0 -1
  34. package/dist/2355.jclic-node.js +0 -371
  35. package/dist/2355.jclic-node.js.map +0 -1
  36. package/dist/2366.jclic-node.js +0 -431
  37. package/dist/2366.jclic-node.js.map +0 -1
  38. package/dist/2379.jclic-node.js +0 -202
  39. package/dist/2379.jclic-node.js.map +0 -1
  40. package/dist/2437.jclic-node.js +0 -450
  41. package/dist/2437.jclic-node.js.map +0 -1
  42. package/dist/2531.jclic-node.js +0 -869
  43. package/dist/2531.jclic-node.js.map +0 -1
  44. package/dist/2608.jclic-node.js +0 -160
  45. package/dist/2608.jclic-node.js.map +0 -1
  46. package/dist/2715.jclic-node.js +0 -554
  47. package/dist/2715.jclic-node.js.map +0 -1
  48. package/dist/277.jclic-node.js +0 -22
  49. package/dist/277.jclic-node.js.map +0 -1
  50. package/dist/2921.jclic-node.js +0 -660
  51. package/dist/2921.jclic-node.js.map +0 -1
  52. package/dist/2952.jclic-node.js +0 -101
  53. package/dist/2952.jclic-node.js.map +0 -1
  54. package/dist/3018.jclic-node.js +0 -421
  55. package/dist/3018.jclic-node.js.map +0 -1
  56. package/dist/3019.jclic-node.js +0 -682
  57. package/dist/3019.jclic-node.js.map +0 -1
  58. package/dist/3231.jclic-node.js +0 -274
  59. package/dist/3231.jclic-node.js.map +0 -1
  60. package/dist/331.jclic-node.js +0 -115
  61. package/dist/331.jclic-node.js.map +0 -1
  62. package/dist/3391.jclic-node.js +0 -276
  63. package/dist/3391.jclic-node.js.map +0 -1
  64. package/dist/3502.jclic-node.js +0 -671
  65. package/dist/3502.jclic-node.js.map +0 -1
  66. package/dist/3653.jclic-node.js +0 -982
  67. package/dist/3653.jclic-node.js.map +0 -1
  68. package/dist/371.jclic.min.js +0 -2
  69. package/dist/371.jclic.min.js.map +0 -1
  70. package/dist/3856.jclic-node.js +0 -575
  71. package/dist/3856.jclic-node.js.map +0 -1
  72. package/dist/4112.jclic-node.js +0 -659
  73. package/dist/4112.jclic-node.js.map +0 -1
  74. package/dist/4123.jclic-node.js +0 -910
  75. package/dist/4123.jclic-node.js.map +0 -1
  76. package/dist/427.jclic-node.js +0 -894
  77. package/dist/427.jclic-node.js.map +0 -1
  78. package/dist/4483.jclic-node.js +0 -327
  79. package/dist/4483.jclic-node.js.map +0 -1
  80. package/dist/4548.jclic-node.js +0 -1078
  81. package/dist/4548.jclic-node.js.map +0 -1
  82. package/dist/466.jclic-node.js +0 -99
  83. package/dist/466.jclic-node.js.map +0 -1
  84. package/dist/485.jclic-node.js +0 -783
  85. package/dist/485.jclic-node.js.map +0 -1
  86. package/dist/4921.jclic-node.js +0 -500
  87. package/dist/4921.jclic-node.js.map +0 -1
  88. package/dist/5091.jclic-node.js +0 -239
  89. package/dist/5091.jclic-node.js.map +0 -1
  90. package/dist/520.jclic-node.js +0 -550
  91. package/dist/520.jclic-node.js.map +0 -1
  92. package/dist/5312.jclic-node.js +0 -1126
  93. package/dist/5312.jclic-node.js.map +0 -1
  94. package/dist/5338.jclic-node.js +0 -212
  95. package/dist/5338.jclic-node.js.map +0 -1
  96. package/dist/5344.jclic-node.js +0 -229
  97. package/dist/5344.jclic-node.js.map +0 -1
  98. package/dist/5550.jclic-node.js +0 -238
  99. package/dist/5550.jclic-node.js.map +0 -1
  100. package/dist/5626.jclic-node.js +0 -614
  101. package/dist/5626.jclic-node.js.map +0 -1
  102. package/dist/5977.jclic-node.js +0 -1081
  103. package/dist/5977.jclic-node.js.map +0 -1
  104. package/dist/6148.jclic-node.js +0 -345
  105. package/dist/6148.jclic-node.js.map +0 -1
  106. package/dist/6176.jclic-node.js +0 -481
  107. package/dist/6176.jclic-node.js.map +0 -1
  108. package/dist/6221.jclic-node.js +0 -1072
  109. package/dist/6221.jclic-node.js.map +0 -1
  110. package/dist/6238.jclic-node.js +0 -718
  111. package/dist/6238.jclic-node.js.map +0 -1
  112. package/dist/6454.jclic-node.js +0 -1413
  113. package/dist/6454.jclic-node.js.map +0 -1
  114. package/dist/6565.jclic-node.js +0 -294
  115. package/dist/6565.jclic-node.js.map +0 -1
  116. package/dist/6579.jclic-node.js +0 -719
  117. package/dist/6579.jclic-node.js.map +0 -1
  118. package/dist/6715.jclic-node.js +0 -148
  119. package/dist/6715.jclic-node.js.map +0 -1
  120. package/dist/6777.jclic-node.js +0 -171
  121. package/dist/6777.jclic-node.js.map +0 -1
  122. package/dist/6782.jclic-node.js +0 -1611
  123. package/dist/6782.jclic-node.js.map +0 -1
  124. package/dist/6847.jclic-node.js +0 -601
  125. package/dist/6847.jclic-node.js.map +0 -1
  126. package/dist/6856.jclic-node.js +0 -252
  127. package/dist/6856.jclic-node.js.map +0 -1
  128. package/dist/696.jclic-node.js +0 -1821
  129. package/dist/696.jclic-node.js.map +0 -1
  130. package/dist/698.jclic-node.js +0 -583
  131. package/dist/698.jclic-node.js.map +0 -1
  132. package/dist/704.jclic-node.js +0 -80
  133. package/dist/704.jclic-node.js.map +0 -1
  134. package/dist/7046.jclic-node.js +0 -735
  135. package/dist/7046.jclic-node.js.map +0 -1
  136. package/dist/7220.jclic-node.js +0 -156
  137. package/dist/7220.jclic-node.js.map +0 -1
  138. package/dist/7257.jclic-node.js +0 -931
  139. package/dist/7257.jclic-node.js.map +0 -1
  140. package/dist/743.jclic-node.js +0 -583
  141. package/dist/743.jclic-node.js.map +0 -1
  142. package/dist/757.jclic-node.js +0 -1072
  143. package/dist/757.jclic-node.js.map +0 -1
  144. package/dist/7781.jclic-node.js +0 -202
  145. package/dist/7781.jclic-node.js.map +0 -1
  146. package/dist/7912.jclic-node.js +0 -2103
  147. package/dist/7912.jclic-node.js.map +0 -1
  148. package/dist/827.jclic-node.js +0 -708
  149. package/dist/827.jclic-node.js.map +0 -1
  150. package/dist/8276.jclic-node.js +0 -409
  151. package/dist/8276.jclic-node.js.map +0 -1
  152. package/dist/8322.jclic-node.js +0 -498
  153. package/dist/8322.jclic-node.js.map +0 -1
  154. package/dist/8641.jclic-node.js +0 -360
  155. package/dist/8641.jclic-node.js.map +0 -1
  156. package/dist/8837.jclic-node.js +0 -651
  157. package/dist/8837.jclic-node.js.map +0 -1
  158. package/dist/8895.jclic-node.js +0 -151
  159. package/dist/8895.jclic-node.js.map +0 -1
  160. package/dist/9072.jclic-node.js +0 -1285
  161. package/dist/9072.jclic-node.js.map +0 -1
  162. package/dist/9078.jclic-node.js +0 -935
  163. package/dist/9078.jclic-node.js.map +0 -1
  164. package/dist/9103.jclic-node.js +0 -718
  165. package/dist/9103.jclic-node.js.map +0 -1
  166. package/dist/9359.jclic-node.js +0 -145
  167. package/dist/9359.jclic-node.js.map +0 -1
  168. package/dist/9409.jclic-node.js +0 -921
  169. package/dist/9409.jclic-node.js.map +0 -1
  170. package/dist/9513.jclic-node.js +0 -720
  171. package/dist/9513.jclic-node.js.map +0 -1
  172. package/dist/9704.jclic-node.js +0 -81
  173. package/dist/9704.jclic-node.js.map +0 -1
  174. package/dist/9950.jclic-node.js +0 -827
  175. package/dist/9950.jclic-node.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"696.jclic-node.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEuB;AACG;AACW;AACiG;AAChE;AACvB;AACQ;AACpB;AACc;AACI;AACX;AACiB;AACf;AACY;;AAExD;AACA;AACA,IAAI;AACJ;AACA,0BAA0B,mDAAmD;AAC7E;AACA;AACA;AACA;AACO,0BAA0B,wDAAS;;AAE1C;AACA;AACA,aAAa,iBAAiB;AAC9B,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;AACA;AACA,cAAc,yDAAI;AAClB,mBAAmB,oDAAQ;AAC3B;AACA,mBAAmB,uFAAuF;AAC1G;AACA,8BAA8B,6CAAC;AAC/B;AACA,uBAAuB,yBAAyB;;AAEhD;AACA;AACA;AACA;AACA,eAAe,8DAAS;AACxB,gBAAgB,8DAAS;AACzB,OAAO;AACP;;AAEA;AACA,0BAA0B,6CAAC,aAAa,sCAAsC;AAC9E,aAAa,+BAA+B;AAC5C;;AAEA;AACA;AACA,gBAAgB,6CAAC,aAAa,sBAAsB;AACpD,uBAAuB,gEAAY;AACnC,8BAA8B,gEAAc;AAC5C,wBAAwB;AACxB,6BAA6B,oDAAK;AAClC;AACA,uBAAuB,yDAAa;AACpC;AACA;AACA,uBAAuB,sDAAI;AAC3B,iBAAiB,sDAAI;AACrB;AACA;AACA,IAAI,wDAAG;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,YAAY,oCAAoC;;AAEhD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,wDAAG;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAG,+BAA+B,WAAW;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe;AACf;AACA;AACA,cAAc,QAAQ,GAAG,GAAG;AAC5B;;AAEA;AACA,iBAAiB,yBAAyB;AAC1C;AACA;AACA;AACA,kBAAkB,qDAAM;AACxB,kBAAkB,qDAAM;AACxB,oBAAoB,qDAAM;AAC1B,mBAAmB,qDAAM,kBAAkB,0EAA0E;AACrH,kBAAkB,qDAAM,iBAAiB,8CAA8C;AACvF,kBAAkB,qDAAM;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP,qBAAqB,qDAAM;AAC3B,mBAAmB,qDAAM;AACzB;AACA;AACA;AACA,QAAQ,6DAAW;AACnB,OAAO;AACP;;AAEA,IAAI,kDAAM;AACV,0CAA0C,uDAAuD;AACjG,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,IAAI,wDAAG;AACP;AACA;AACA,8BAA8B,gEAAc;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,eAAe,kBAAkB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,kCAAkC,yCAAyC;AAC3E,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,4DAAQ;AAC5B;AACA;;AAEA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,qBAAqB,oDAAK;AAC1B;AACA;AACA;AACA;AACA;AACA,KAAK;;AAEL;AACA;AACA;AACA,4BAA4B,oDAAK;AACjC;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,wBAAwB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,0CAA0C;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,gEAAY;AAC9C;AACA;;AAEA;AACA;AACA,aAAa,qBAAqB,yFAAyF,4DAA4D;AACvL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,eAAe,mDAAmD;AAC/E,4EAA4E;AAC5E;AACA,aAAa,QAAQ;AACrB;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,yBAAyB,4DAAO;;AAEhC;AACA;AACA,UAAU,wDAAG,oCAAoC,SAAS;AAC1D,UAAU,qDAAS,mBAAmB,UAAU;AAChD;AACA,4BAA4B,6DAAQ,wBAAwB,6DAAQ;AACpE;AACA,wBAAwB,4DAAO,CAAC,gEAAW;AAC3C,cAAc;AACd,cAAc,wDAAG,qDAAqD,UAAU;AAChF;AACA,WAAW;AACX,8BAA8B,YAAY,GAAG,MAAM,kBAAkB,QAAQ;AAC7E,YAAY,wDAAG;AACf,oCAAoC,OAAO;AAC3C,WAAW;AACX;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,UAAU,wDAAG,8BAA8B,SAAS;;AAEpD;AACA,UAAU,mEAA2B;AACrC;AACA;AACA,cAAc,wDAAG,qCAAqC,eAAe;AACrE;AACA;AACA,gBAAgB,8CAAK;AACrB;AACA;AACA,qCAAqC,gEAAW;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,6DAAQ;AAChC;AACA,gCAAgC,4DAAO;AACvC,sBAAsB;AACtB,sBAAsB,wDAAG,qDAAqD,UAAU;AACxF;AACA,oBAAoB;AACpB,oBAAoB,wDAAG,6CAA6C,SAAS,IAAI,uCAAuC;AACxH;AACA,iBAAiB;AACjB,kBAAkB,wDAAG,qCAAqC,8CAA8C;AACxG,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA;AACA,4BAA4B,4DAAO;AACnC;AACA,kBAAkB,wDAAG;AACrB;AACA;AACA,aAAa;AACb,cAAc,wDAAG,qCAAqC,8CAA8C;AACpG;AACA,aAAa;AACb,WAAW;AACX;AACA,UAAU;AACV;AACA,6BAA6B,SAAS;AACtC;AACA;AACA;AACA;AACA,0DAA0D,6DAAQ;AAClE,uBAAuB;AACvB,uBAAuB;AACvB,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,kDAAkD;;AAElD,iCAAiC,iDAAK,0BAA0B,qDAAS;;AAEzE;AACA;AACA,cAAc,wDAAG,2CAA2C,QAAQ;AACpE;AACA;AACA,4BAA4B,gEAAY;AACxC;AACA,gCAAgC,6CAAC;AACjC;AACA;;AAEA,YAAY,wDAAG,4CAA4C,QAAQ;AACnE;AACA,cAAc,wDAAG,cAAc,aAAa;AAC5C;AACA,aAAa;AACb,YAAY,wDAAG,yCAAyC,SAAS;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,WAAW;AACX,8BAA8B,YAAY,GAAG,YAAY,kBAAkB,QAAQ;AACnF,YAAY,wDAAG;AACf,oCAAoC,OAAO;AAC3C,WAAW;AACX;;;AAGA,QAAQ,wDAAG,6BAA6B,QAAQ;AAChD;;AAEA;AACA;AACA,wBAAwB,oEAAe;AACvC;AACA;AACA,yCAAyC,4DAA4D,gBAAgB,KAAK;AAC1H,aAAa;AACb,cAAc,wDAAG,gCAAgC,MAAM,8BAA8B,8CAA8C;AACnI;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,+DAA+D,gBAAgB,0CAA0C;AAClJ,YAAY;AACZ,YAAY,wDAAG,6BAA6B,SAAS;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA,SAAS,kEAAa;AACtB,MAAM,wDAAG,8BAA8B,SAAS;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAQ,wDAAG,8BAA8B,SAAS;AAClD;AACA,QAAQ,iEAAe;AACvB;AACA;AACA;AACA;AACA,QAAQ;AACR,QAAQ,wDAAG,+BAA+B,SAAS;AACnD;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,0BAA0B,mDAAmD;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,wDAAG,sBAAsB,uBAAuB;AACtD;AACA;AACA;;AAEA;AACA,gBAAgB,2CAA2C,UAAU,mDAAmD;AACxH;AACA;AACA;AACA;AACA;AACA,MAAM,wDAAG;AACT;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX,SAAS;AACT;;AAEA;AACA;AACA;AACA,YAAY,yDAAQ;AACpB,2BAA2B,wDAAS;;AAEpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,wCAAwC;AACrD,aAAa,kCAAkC;AAC/C,aAAa,YAAY;AACzB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,iBAAiB,0DAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,0DAAQ;AACzB;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,QAAQ,wDAAG,iCAAiC,kBAAkB;AAC9D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,IAAI,wDAAG,mDAAmD,IAAI;AAC9D;;AAEA;AACA,kBAAkB,yCAAyC;AAC3D,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA,IAAI,wDAAG;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,gDAAgD;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,mEAAgB;AAChD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,gCAAgC,mCAAmC;AACnE;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;;AAEA;AACA,gBAAgB,0EAA0E,mBAAmB;AAC7G,aAAa,wCAAwC;AACrD,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,0BAA0B;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,0BAA0B;AACvC,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,0BAA0B;AACvC,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,iBAAiB;AAC9B,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,6BAA6B;AAC7D;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA,IAAI,wDAAG,oBAAoB,SAAS;AACpC;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA,UAAU,6DAA6D;AACvE;AACA,YAAY,0CAA0C;AACtD;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA,QAAQ,sBAAsB;AAC9B;AACA;AACA,4BAA4B,QAAQ;AACpC,4BAA4B,QAAQ;AACpC;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,UAAU,mDAAmD;AAC7D;AACA,YAAY,gCAAgC;AAC5C;AACA;AACA;AACA;AACA,YAAY,oCAAoC;AAChD;AACA;AACA;AACA;AACA,YAAY,wBAAwB;AACpC;AACA;AACA;AACA;AACA,YAAY,wBAAwB;AACpC;AACA;AACA,4CAA4C;AAC5C;AACA,YAAY,wBAAwB;AACpC;AACA;AACA;AACA;AACA,YAAY,4CAA4C;AACxD;AACA;AACA;AACA;AACA;AACA,YAAY,iCAAiC;AAC7C;AACA;AACA,oBAAoB,yBAAyB;AAC7C;AACA,YAAY,qBAAqB;AACjC,aAAa;AACb;AACA;AACA;AACA,YAAY,kBAAkB;AAC9B;AACA;AACA;AACA;AACA,YAAY,kBAAkB;AAC9B;AACA;AACA;AACA;AACA,YAAY,mBAAmB;AAC/B;AACA;AACA;AACA,YAAY;AACZ,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA,YAAY,+CAA+C;AAC3D,gBAAgB,+BAA+B;AAC/C;AACA;AACA;AACA,YAAY,kBAAkB;AAC9B;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA,CAAC;;AAED,iEAAe,WAAW,EAAC;;;;;;;;;;;;;;;AC3xC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEuB;AACgD;;AAEvE;AACA;AACA;AACA,sBAAsB,kDAAkD;AACxE;AACO;AACP;AACA;AACA,aAAa,gCAAgC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,6CAAC;AACP;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,aAAa,8BAA8B;AAC3C;AACA;AACA,IAAI,wDAAG;AACP;AACA;AACA,MAAM,iEAAY;AAClB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,2BAA2B,wEAAwE;AACnG,MAAM;AACN,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB,wEAAwE;AAC5F,mCAAmC,kDAAkD;AACrF;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,iEAAY;AACpB;AACA;AACA;AACA,UAAU,wDAAG,sCAAsC,cAAc;AACjE;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6BAA6B,8CAA8C,qBAAqB,kDAAkD;AAClJ;AACA,aAAa,+BAA+B;AAC5C,aAAa,SAAS;AACtB;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,cAAc,wDAAG,sCAAsC,eAAe;AACtE,cAAc;AACd;AACA,iCAAiC,4DAAO;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ,gBAAgB,sEAAsE;AAC3G,aAAa,QAAQ;AACrB,iEAAiE,sEAAsE;AACvI;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA,QAAQ,kEAAa,cAAc,kEAAa;AAChD;AACA,QAAQ,kEAAa;AACrB;AACA;AACA;AACA,WAAW,kEAAa;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU,kDAAkD;AAC5D;AACA,YAAY,gCAAgC;AAC5C;AACA;AACA;AACA;AACA;AACA,YAAY,qDAAqD;AACjE;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ,+DAA+D;AACtF,eAAe,QAAQ,6CAA6C,4BAA4B;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;;AAED,iEAAe,aAAa,EAAC;;;;;;;;;;;;;;AChT7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEuD;AAChB;;AAEvC;AACA,+CAA+C,0EAA0E;AACzH,IAAI,6DAA6D,IAAI,wCAAwC;AAC7G;AACO;AACP;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oBAAoB,0EAA0E;AAC9F,aAAa,wCAAwC;AACrD,aAAa,+BAA+B;AAC5C,aAAa,gCAAgC;AAC7C;AACA,gBAAgB,iDAAiD;AACjE,eAAe;AACf;AACA;AACA;AACA;AACA;AACA,2CAA2C,yDAAQ;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,6DAAiB;AACnC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,oCAAoC,0EAA0E;AAC9G;AACA,aAAa,wCAAwC;AACrD,aAAa,+BAA+B;AAC5C,aAAa,gCAAgC;AAC7C,MAAM,8FAA8F;AACpG,gBAAgB,iDAAiD;AACjE,eAAe;AACf;AACA;AACA;AACA;AACA;;AAEA;AACA,2CAA2C,0EAA0E,0BAA0B,6CAA6C;AAC5L,aAAa,wCAAwC;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,6DAAiB;AACrB;AACA;;AAEA;AACA;AACA,wBAAwB,0EAA0E;AAClG;AACA,YAAY,oDAAoD;AAChE;AACA,CAAC;;AAED,iEAAe,cAAc,EAAC","sources":["webpack://jclic/./src/JClicPlayer.js","webpack://jclic/./src/PlayerHistory.js","webpack://jclic/./src/media/ActiveMediaBag.js"],"sourcesContent":["/**\n * File : JClicPlayer.js\n * Created : 28/04/2015\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2022 Educational Telematic Network of Catalonia (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\n/* global JSON, Promise, location, window, document */\n\nimport $ from 'jquery';\nimport JSZip from 'jszip';\nimport JSZipUtils from 'jszip-utils';\nimport { log, init, settings, getPath, endsWith, getBasePath, getRelativePath, isNullOrUndef, mReplace, toCssSize } from './Utils.js';\nimport { Container, Point, Action, Timer, Rectangle } from './AWT.js';\nimport PlayerHistory from './PlayerHistory.js';\nimport ActiveMediaBag from './media/ActiveMediaBag.js';\nimport Skin from './skins/Skin.js';\nimport EventSounds from './media/EventSounds.js';\nimport JClicProject from './project/JClicProject.js';\nimport JumpInfo from './bags/JumpInfo.js';\nimport ActiveBoxContent from './boxes/ActiveBoxContent.js';\nimport Reporter from './report/Reporter.js';\nimport MediaBagElement from './bags/MediaBagElement.js';\n\n/**\n * JClicPlayer is one of the the main classes of the JClic system. It implements the\n * {@link http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/PlayStation.html PlayStation}\n * interface, needed to host JClic activities.\n * JClicPlayer offers to {@link module:Activity.ActivityPanel ActivityPanel} objects all the necessary resources and functions:\n * media bags (to load and realize images and other media contents), sequence control, management\n * of the reporting system, user interface, display of system messages, etc.\n * @extends module:AWT.Container\n */\nexport class JClicPlayer extends Container {\n\n /**\n * JClicPlayer constructor\n * @param {external:jQuery} $topDiv - The HTML `div` element where this JClicPlayer will deploy.\n * @param {object} [options] - A set of optional customized options.\n */\n constructor($topDiv, options) {\n\n // JClicPlayer extends Container\n super();\n // Build cascading options\n options = init(options);\n this.options = $.extend(Object.create(this.options), options);\n // Generate unique ID\n this.id = `JC${(0x10000 + Math.round(Math.random() * 0xFFFF)).toString(16).toUpperCase().substring(1)}`;\n // Identify the HTML element where this player will deploy\n this.$topDiv = $topDiv || $('<div/>');\n // Avoid side effects of 'align=center' in old HTML pages\n this.$topDiv.css({ 'text-align': 'initial' });\n\n // Special case: $topDiv inside a TD (like in http://clic.xtec.cat/gali)\n if (this.$topDiv.parent().is('td')) {\n // Set explicit width and height to fill-in the TD\n this.$topDiv.css({\n width: toCssSize(this.options.width, null, null, '100%'),\n height: toCssSize(this.options.height, null, null, '100%'),\n });\n }\n\n // Build the main container\n this.$mainContainer = $('<div/>', { class: 'JClicContainer', id: this.id })\n .css({ width: '100%', height: '100%' })\n .appendTo(this.$topDiv);\n\n // Intitialize other elements\n this.localFS = location && location.protocol === 'file:';\n this.$div = $('<div/>', { class: 'JClicPlayer' });\n this.project = new JClicProject();\n this.activeMediaBag = new ActiveMediaBag();\n this.counterVal = { score: 0, actions: 0, time: 0 };\n this.bgImageOrigin = new Point();\n this.buildActions();\n this.history = new PlayerHistory(this);\n this.audioEnabled = this.options.audioEnabled;\n this.navButtonsAlways = this.options.navButtonsAlways;\n this.defaultSkin = Skin.getSkin(this.options.skin, this);\n this.setSkin(Skin.getSkin('@empty.xml', this));\n this.initTimers();\n this.listenTouchEvents();\n log('info', 'JClicPlayer ready');\n }\n\n /**\n *\n * Detects swipe-right, swipe-left and double touch gestures on touch devices,\n * associating them with 'next activity', 'previous activity' and 'toggle full screen' actions\n */\n listenTouchEvents() {\n\n // Enable listeners only in touch devices\n //if ('ontouchstart' in window) {\n\n let startTouch = null;\n let startTouchTime = 0;\n let thisDiv = this.$div[0];\n const { minSwipeX, maxSwipeY, rightToLeft } = this.options;\n\n // Generic handler for touch events\n const touchEventHandler = event => {\n // Process only single-finger events targeted to our main 'div'\n if (event.target === thisDiv && event.changedTouches && event.changedTouches.length === 1) {\n const touch = event.changedTouches[0];\n const dx = startTouch ? touch.clientX - startTouch.clientX : 0;\n const dy = startTouch ? touch.clientY - startTouch.clientY : 0;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n switch (event.type) {\n case 'touchstart':\n const currentTime = new Date();\n // Detect double taps, done in less than 800 ms and at short distance\n if (\n document && document.fullscreenEnabled\n && startTouch && startTouchTime\n && currentTime - startTouchTime < 800\n && dist < minSwipeX\n ) {\n event.preventDefault();\n log('info', 'Toggle full screen mode from double touch');\n this.skin.setScreenFull();\n startTouch = null;\n }\n else {\n startTouch = touch;\n startTouchTime = currentTime;\n }\n break;\n\n case 'touchend':\n // Discard non-horizontal gestures and those that do not have sufficient length\n if (startTouch && Math.abs(dx) > minSwipeX && Math.abs(dy) < maxSwipeY) {\n const actionName = dx < 0 && !rightToLeft ? 'next' : 'prev';\n const action = this.actions[actionName];\n if (action && action.enabled) {\n event.preventDefault();\n log('info', `Performing action \"${actionName}\" from touch gesture`);\n action.actionPerformed(event);\n }\n startTouch = null;\n }\n // Cancel double touch detection when long gestures detected\n else if (dist > minSwipeX)\n startTouch = null;\n break;\n\n case 'touchcancel':\n startTouch = null;\n break;\n }\n }\n else\n // Cancel any started gesture\n startTouch = null;\n };\n\n // Handle touch events\n thisDiv.addEventListener('touchstart', touchEventHandler);\n thisDiv.addEventListener('touchend', touchEventHandler);\n thisDiv.addEventListener('touchcancel', touchEventHandler);\n //}\n }\n\n /**\n * Generates an unique ID for elements being used with this player\n * @param {string} lb - The element's label\n * @returns {string}\n */\n getUniqueId(lb) {\n return `${this.id}-${lb}`;\n }\n\n /**\n * Builds the {@link module:AWT.Action} objects for this player\n */\n buildActions() {\n this.actions = {\n 'next': new Action('next', () => this.history.processJump(this.project.activitySequence.getJump(false, this.reporter), false)),\n 'prev': new Action('prev', () => this.history.processJump(this.project.activitySequence.getJump(true, this.reporter), false)),\n 'return': new Action('return', () => this.history.pop()),\n 'reset': new Action('reset', () => { if (this.actPanel && this.actPanel.act.canReinit()) this.initActivity(); }),\n 'help': new Action('help', () => { if (this.actPanel) this.actPanel.showHelp(); }),\n 'info': new Action('info', () => {\n if (this.actPanel && this.actPanel.act.hasInfo()) {\n if (this.actPanel.act.infoUrl)\n this.displayURL(this.act.infoUrl, true);\n else if (this.actPanel.act.infoCmd)\n this.runCmd(this.actPanel.act.infoCmd);\n }\n }),\n 'reports': new Action('reports', () => this.showReports()),\n 'audio': new Action('audio', () => {\n this.audioEnabled = !this.audioEnabled;\n if (!this.audioEnabled)\n this.stopMedia();\n EventSounds.prototype.globalEnabled = this.audioEnabled;\n })\n };\n\n $.each(this.actions, (key, value) => {\n value.addStatusListener(action => { if (this.skin) this.skin.actionStatusChanged(action); });\n });\n }\n\n /**\n * Resets the main components of this player\n */\n reset() {\n log('info', 'Restoring player');\n this.removeActivity();\n this.end();\n this.activeMediaBag = new ActiveMediaBag();\n this.history.clearHistory();\n this.setSkin(null);\n this.setMsg(null);\n this.setCounterValue('score', 0);\n this.setCounterValue('actions', 0);\n this.setCounterValue('time', 0);\n if (this.skin)\n this.skin.setWaitCursor('reset');\n }\n\n /**\n * Instructs the player to stop working\n */\n stop() {\n this.stopMedia(-1);\n }\n\n /**\n * Executes miscellaneous finalization routines.\n * @returns {external:Promise} - A promise to be fullfilled when all pending tasks are finished.\n */\n end() {\n let result = null;\n this.stopMedia();\n this.closeHelpWindow();\n if (this.reporter) {\n result = this.reporter.end();\n this.reporter = null;\n }\n if (this.actPanel) {\n this.actPanel.end();\n this.actPanel.$div.remove();\n this.actPanel = null;\n }\n if (this.project) {\n this.project.end();\n this.project = null;\n }\n if (this.activeMediaBag)\n this.activeMediaBag.removeAll();\n return result || Promise.resolve(true);\n }\n\n /**\n * Creates and initializes the {@link module:Reporter.Reporter Reporter} member\n * @returns {external:Promise}\n */\n initReporter() {\n if (this.reporter) {\n this.reporter.end();\n this.reporter = null;\n }\n this.reporter = Reporter.getReporter(null, this);\n return this.reporter.init();\n }\n\n /**\n * Creates and initializes objects of type {@link module:AWT.Timer}\n */\n initTimers() {\n // Main timer\n if (this.timer)\n this.timer.stop();\n this.timer = new Timer(() => {\n this.incCounterValue('time');\n if (this.actPanel && this.actPanel.act.maxTime > 0\n && this.actPanel.playing\n && this.counterVal['time'] >= this.actPanel.act.maxTime)\n this.actPanel.finishActivity(false);\n }, 1000, false);\n\n // One-time timer, for delayed actions\n if (this.delayedTimer)\n this.delayedTimer.stop();\n this.delayedTimer = new Timer(() => {\n if (this.delayedAction)\n this.delayedAction.processEvent(this.delayedAction, null);\n }, 1000, false);\n this.delayedTimer.repeats = false;\n }\n\n /**\n * Opens the reports dialog\n */\n showReports() {\n if (this.skin) this.skin.showReports(this.reporter);\n }\n\n /**\n * Closes the help dialog window\n */\n closeHelpWindow() {\n if (this.skin) this.skin._closeDlg(false);\n }\n\n /**\n * Sets the current skin\n * @param {module:skins/Skin.Skin} [newSkin] - The skin to use. When `null`, `defaultSkin` will be used.\n */\n setSkin(newSkin) {\n newSkin = newSkin || (this.project && this.project.skin ? this.project.skin : this.defaultSkin);\n if (newSkin && (this.skin === null || newSkin.name !== this.skin.name)) {\n newSkin.attach(this);\n this.skin = newSkin;\n this.skin.doLayout();\n }\n }\n\n /**\n * Sets the current project of this player, without starting any activity\n * @param {module:project/JClicProject.JClicProject} project - The project to be set\n */\n setProject(project) {\n if (this.project) {\n if (this.project !== project)\n this.project.end();\n this.removeActivity();\n }\n this.project = project || new JClicProject();\n this.project.realize(this);\n }\n\n /**\n * Loads the specified project and starts playing at the specified activity or sequence tag.\n * @param {string|JClicProject} [project] - The project to load (if it's a string) or to use (if it's an object of type {@link module:project/JClicProject.JClicProject JClicProject}).\n * When it's a `string`, it can be the absolute or relative path to:\n * - A `.jclic` project file, in XML format\n * - A `.jclic.json` project file in JSON format\n * - A `.jclic.zip` compressed project file (containing one file of type '.jclic' or '.jclic.json')\n * - A `.scorm.zip` file, as exported by JClic Author.\n * - A `project.json` file, as exported by JClic Author\n * When `null` or `undefined`, refers to the current project.\n * @param {string|number} [sequence] - Sequence tag or numeric order in the {@link module:bags/ActivitySequence.ActivitySequence ActivitySequence}\n * to be loaded. If _sequence_ and _activity_ are both `null`, the first {@link module:bags/ActivitySequenceElement.ActivitySequenceElement ActivitySequenceElement}\n * will be loaded.\n * @param {string} [activity] - Name of the activity to be loaded (usually `null`)\n */\n load(project, sequence, activity) {\n\n this.forceFinishActivity();\n this.setWaitCursor(true);\n\n // The ActivityPanel object to be obtained as a result of the loading process\n let actp = null;\n\n // step one: load the project\n if (project) {\n if (typeof project === 'string') {\n\n // Param `project` is a file name or URL (otherwise, is a realized `JClicProject` object)\n const fullPath = getPath(this.basePath, project);\n\n // Previous step: Check if `project` points to a \"project.json\" file\n if (fullPath.endsWith('project.json')) {\n log('info', `Loading JSON info from: ${fullPath}`);\n $.getJSON(fullPath).done(({ mainFile }) => {\n // Read the `mainFile` field of `project.json`\n if (mainFile && endsWith(mainFile, '.jclic') || endsWith(mainFile, '.jclic.json')) {\n // Load project's main file\n this.load(getPath(getBasePath(fullPath), mainFile), sequence, activity);\n } else {\n log('error', `Invalid or null \"mainFile\" specified in ${fullPath} - \"project.json\".`);\n }\n }).fail((jqhxr, textStatus, error) => {\n const errMsg = `${textStatus} (${error}) while loading ${project}`;\n log(errMsg);\n window.alert(`Error!\\n${errMsg}`);\n }).always(\n () => this.setWaitCursor(false)\n );\n return;\n }\n\n // Step 0: Check if `project` points to a ZIP file\n if (fullPath.endsWith('.zip')) {\n // TODO: Implement register of zip files in PlayerHistory\n this.zip = null;\n log('info', `Loading ZIP file: ${fullPath}`);\n\n // Launch loading of ZIP file in a separated thread\n JSZipUtils.getBinaryContent(fullPath, (err, data) => {\n if (err) {\n this.setWaitCursor(false);\n log('error', `Error loading ZIP file: ${err.toString()}`);\n return;\n }\n new JSZip().loadAsync(data).then(zip => {\n this.zip = zip;\n this.zip.fullZipPath = fullPath;\n this.zip.zipBasePath = getBasePath(fullPath);\n let fileName = null;\n // Check if ZIP contains a \"project.json\" file (as in the \".scorm.zip\" files generated by JClic Author)\n if (this.zip.files['project.json']) {\n this.zip.files['project.json'].async('string').then(content => {\n try {\n const json = JSON.parse(content);\n // Read the `mainFile` field of `project.json`\n if (endsWith(json['mainFile'], '.jclic')) {\n // Load project's main file\n this.load(getPath(this.zip.zipBasePath, json['mainFile']), sequence, activity);\n } else {\n log('error', `Invalid or null \"mainFile\" specified in ${fullPath} - \"project.json\".`);\n }\n } catch (err) {\n log('error', `Error reading \"project.json\" in ${fullPath}: ${err ? err.toString() : 'unknown error'}`);\n }\n }).catch(reason => {\n log('error', `Error reading ZIP file: ${reason ? reason.toString() : 'unknown reason'}`);\n });\n } else {\n // Find first file with extension '.jclic' inside the zip file\n fileName = Object.keys(this.zip.files).find(fn => fn.endsWith('.jclic')) || null;\n if (fileName)\n this.load(getPath(this.zip.zipBasePath, fileName), sequence, activity);\n else\n log('error', 'This ZIP file does not contain any JClic project!');\n }\n this.setWaitCursor(false);\n }).catch(reason => {\n log('error', `Error reading ZIP file: ${reason ? reason.toString() : 'unknown reason'}`);\n this.setWaitCursor(false);\n });\n });\n return;\n } else if (this.localFS && window.JClicObject && !window.JClicObject.projectFiles[fullPath]) {\n const scriptTag = document.createElement('script');\n scriptTag.src = `${fullPath}.js`;\n scriptTag.onload = () => {\n // 25 Mar 20201:\n // Workaround for a bug on Chrome and Firefox XML parsers, throwing errors whith hexadecimal character entities\n if (window.JClicObject.projectFiles[fullPath]) {\n window.JClicObject.projectFiles[fullPath] = mReplace([\n [/&#xD;/g, '\\r'],\n [/&#xA;/g, '\\n'],\n [/&#x9;/g, '\\t'],\n ], window.JClicObject.projectFiles[fullPath]);\n this.load(project, sequence, activity);\n }\n };\n document.head.appendChild(scriptTag);\n this.setWaitCursor(false);\n return;\n }\n\n // Step one: load the project file\n const processProjectFile = fp => {\n const isXml = fp.indexOf('data:text/xml;') === 0 || fp.endsWith('.jclic');\n\n const loader = isXml ? $.get(fp, null, null, 'xml') : $.getJSON(fp);\n\n loader.done(data => {\n if (data === null || typeof data !== 'object') {\n log('error', `Bad data. Project not loaded: ${project}`);\n return;\n }\n const prj = new JClicProject();\n if (isXml)\n prj.setProperties($(data).find('JClicProject'), fullPath, this.zip, this.options);\n else\n prj.setAttributes(data, fullPath, this.zip, this.options);\n\n log('info', `Project file loaded and parsed: ${project}`);\n const elements = prj.mediaBag.buildAll(null, element => {\n log('trace', `\"${element.name}\" ready.`);\n this.incProgress(1);\n }, this);\n log('info', `Media elements to be loaded: ${elements}`);\n this.setProgress(0, elements);\n let loops = 0;\n const interval = 500;\n this.setWaitCursor(true);\n const checkMedia = window.setInterval(() => {\n // Wait for a maximum time of two minutes\n if (++loops > this.options.maxWaitTime / interval) {\n window.clearInterval(checkMedia);\n this.setProgress(-1);\n this.setWaitCursor(false);\n log('error', 'Error loading media');\n }\n const waitingObjects = prj.mediaBag.countWaitingElements();\n // player.setProgress(waiting)\n if (waitingObjects === -1) {\n window.clearInterval(checkMedia);\n this.setProgress(-1);\n this.setWaitCursor(false);\n // Call `load` again, passing the loaded [JClicProject](JClicProject.html) as a parameter\n this.load(prj, sequence, activity);\n }\n }, interval);\n }).fail((jqXHR, textStatus, errorThrown) => {\n const errMsg = `${textStatus} (${errorThrown}) while loading ${project}`;\n log(errMsg);\n window.alert(`Error!\\n${errMsg}`);\n }).always(() => this.setWaitCursor(false));\n };\n\n\n log('info', `Loading project: ${project}`);\n let fp = fullPath;\n\n // Special case for ZIP files\n if (this.zip) {\n const fName = getRelativePath(fp, this.zip.zipBasePath);\n if (this.zip.files[fName]) {\n this.zip.file(fName).async('string').then(text => {\n processProjectFile(`data:${fName.endsWith('.jclic') ? 'text/xml' : 'application/json'};charset=UTF-8,${text}`);\n }).catch(reason => {\n log('error', `Unable to extract \"${fName}\" from ZIP file because of: ${reason ? reason.toString() : 'unknown reason'}`);\n this.setWaitCursor(false);\n });\n return;\n }\n }\n // Special case for local file systems (using `file` protocol)\n else if (this.localFS) {\n // Check if file is already loaded in the global variable `JClicObject`\n if (window.JClicObject && window.JClicObject.projectFiles[fullPath]) {\n fp = `data:${fullPath.endsWith('.jclic') ? 'text/xml' : 'application/json'};charset=UTF-8,${window.JClicObject.projectFiles[fullPath]}`;\n } else {\n log('error', `Unable to load: ${fullPath}.js`);\n this.setWaitCursor(false);\n return;\n }\n }\n processProjectFile(fp);\n return;\n }\n\n // From here, assume that `project` is a [JClicProject](JClicProject.html)\n this.setProject(project);\n\n // If none specified, start with the first element of the sequence\n if (!sequence && !activity)\n sequence = '0';\n\n // start reporter session\n if (this.reporter)\n this.reporter.newSession(project);\n\n }\n\n // Step two: load the ActivitySequenceElement\n if (!isNullOrUndef(sequence)) {\n log('info', `Loading sequence: ${sequence}`);\n this.navButtonsDisabled = false;\n // Try to load sequence by tag\n let ase = null;\n if (typeof sequence === 'string')\n ase = this.project.activitySequence.getElementByTag(sequence, true);\n if (ase === null) {\n // Try to treat 'sequence' as a number\n const n = parseInt(sequence, 10);\n if (typeof n === 'number')\n ase = this.project.activitySequence.getElement(n, true);\n }\n\n if (ase !== null) {\n // Success! We have a real [ActivitySequenceElement](ActivitySequenceElement.html)\n if (this.reporter)\n this.reporter.newSequence(ase);\n activity = ase.activity;\n }\n }\n\n // Step three: load the activity\n if (activity) {\n const act = this.project.getActivity(activity);\n if (act) {\n // Success! We have a real [Activity](Activity.html)\n log('info', `Loading activity: ${activity}`);\n // Clean static references to previous audio elements\n MediaBagElement.resetAudioElements();\n act.prepareMedia(this);\n this.project.activitySequence.checkCurrentActivity(act.name);\n actp = act.getActivityPanel(this);\n actp.buildVisualComponents();\n } else {\n log('error', `Missing activity: ${activity}`);\n }\n }\n\n // Step four: put the activity panel on place\n\n // Remove the current ActivityPanel\n if (this.actPanel !== null) {\n this.actPanel.end();\n this.actPanel.$div.remove();\n this.actPanel = null;\n this.setCounterValue('time', 0);\n }\n\n // Attach the new ActivityPanel\n if (actp) {\n // Sets the actPanel member to this ActivityPanel\n this.actPanel = actp;\n\n if (this.options.fade > 0)\n this.actPanel.$div.css('display', 'none');\n\n // Places the JQuery DOM element of actPanel within the player main panel\n this.$div.prepend(this.actPanel.$div);\n if (this.skin)\n this.skin.resetAllCounters(false);\n\n // Sets the current skin\n if (this.actPanel.skin)\n this.setSkin(this.actPanel.skin);\n else if (this.project.skin) {\n this.setSkin(this.project.skin);\n this.lastProjectSkin = this.project.skin;\n }\n else if (this.lastProjectSkin)\n this.setSkin(this.lastProjectSkin);\n else\n this.setSkin(null);\n\n if (this.skin) {\n // Enable or disable actions\n const hasReturn = this.history.storedElementsCount() > 0 || this.options.returnAsExit;\n const navBtnFlag = this.navButtonsAlways ?\n 'both' : this.navButtonsDisabled ?\n 'none' : this.project.activitySequence.getNavButtonsFlag();\n this.actions['next'].setEnabled((navBtnFlag === 'fwd' || navBtnFlag === 'both') &&\n this.project.activitySequence.hasNextAct(hasReturn));\n this.actions['prev'].setEnabled((navBtnFlag === 'back' || navBtnFlag === 'both') &&\n this.project.activitySequence.hasPrevAct(hasReturn));\n this.actions['return'].setEnabled(hasReturn);\n this.actions['help'].setEnabled(this.actPanel.act.helpWindowAllowed());\n this.actions['reset'].setEnabled(this.actPanel.act.canReinit());\n this.actions['info'].setEnabled(this.actPanel.act.hasInfo());\n }\n this.doLayout();\n this.initActivity();\n\n this.history.pushBrowserHistory();\n\n this.actPanel.$div.fadeIn(this.options.fade, () => this.activityReady());\n }\n this.setWaitCursor(false);\n }\n\n /**\n * Forces the current activity to stop playing.\n */\n forceFinishActivity() {\n this.timer.stop();\n this.delayedTimer.stop();\n if (this.actPanel) {\n this.closeHelpWindow();\n this.actPanel.forceFinishActivity();\n this.stopMedia();\n this.activeMediaBag.removeAll();\n }\n }\n\n /**\n *\n * Removes the current {@link module:Activity.ActivityPanel ActivityPanel} from this player\n */\n removeActivity() {\n this.forceFinishActivity();\n if (this.actPanel) {\n this.actPanel.end();\n this.actPanel.$div.remove();\n this.actPanel = null;\n this.setMsg(null);\n this.doLayout();\n }\n }\n\n /**\n *\n * Initializes the activity\n */\n initActivity() {\n this.setWaitCursor(true);\n this.timer.stop();\n this.delayedTimer.stop();\n this.setCounterValue('time', 0);\n this.stopMedia();\n if (this.actPanel) {\n this.actPanel.initActivity();\n this.timer.start();\n if (!this.actPanel.act.mustPauseSequence())\n this.startAutoPassTimer();\n log('info', `Activity \"${this.actPanel.act.name}\" running`);\n }\n this.setWaitCursor(false);\n }\n\n /**\n * Called by {@link module:JClicPlayer.JClicPlayer#load} when the {@link module:Activity.ActivityPanel ActivityPanel} is fully visible, just\n * after the JQuery animation effect.\n */\n activityReady() {\n if (this.actPanel) {\n this.actPanel.activityReady();\n log('info', 'Activity ready');\n }\n }\n\n /**\n * Starts the activity. This method is usually called from text activities with previous text.\n */\n startActivity() {\n this.setWaitCursor(true);\n if (this.actPanel)\n this.actPanel.startActivity();\n this.setWaitCursor(false);\n }\n\n /**\n * Configures the layout and visual aspect of the player area.\n */\n doLayout() {\n\n // Main player area settings\n const\n width = this.dim.width = this.$div.width(),\n height = this.dim.height = this.$div.height(),\n mainCss = {\n 'background-color': this.actPanel ? this.actPanel.act.bgColor : 'azure',\n 'background-image': ''\n };\n\n if (this.actPanel) {\n const act = this.actPanel.act;\n if (act.bgGradient)\n // Canvas version also available\n mainCss['background-image'] = act.bgGradient.getCss();\n\n if (act.bgImageFile && act.bgImageFile.length > 0) {\n this.project.mediaBag.getElement(act.bgImageFile, true).getFullPathPromise().then(bgImageUrl => {\n this.$div.css({\n 'background-image': 'url(\\'' + bgImageUrl + '\\')',\n 'background-repeat': act.tiledBgImg ? 'repeat' : 'no-repeat',\n 'background-position': act.tiledBgImg ? '' : 'center center'\n });\n });\n }\n\n // Activity panel settings\n // Calc the maximum rectangle available for the activity panel\n const\n m = settings.BoxBase.AC_MARGIN,\n proposedRect = new Rectangle(m, m, width - 2 * m, height - 2 * m);\n\n if (this.actPanel.bgImage && !act.tiledBgImg && act.absolutePositioned) {\n // Special case: when the activity has a background image not tiled, and an absolute\n // position has been specified, the ActivityPanel must be placed at this absolute\n // position, relative to the background image\n this.bgImageOrigin.x = (width - this.actPanel.bgImage.width) / 2;\n this.bgImageOrigin.y = (height - this.actPanel.bgImage.height) / 2;\n proposedRect.pos.moveTo(this.bgImageOrigin);\n proposedRect.dim.width -= this.bgImageOrigin.x - m;\n proposedRect.dim.height -= this.bgImageOrigin.y - m;\n proposedRect.dim.width = Math.min(proposedRect.dim.width, width);\n proposedRect.dim.height = Math.min(proposedRect.dim.height, height);\n }\n\n // ActivityPanel will calculate and set its position and size based on the maximum and optimal\n // available space\n /* TODO: Try with a computed rectangle instead of \"this\", to avoid the loss of the right margin\n * in narrow displays */\n this.actPanel.fitTo(proposedRect, this);\n }\n this.$div.css(mainCss);\n }\n\n /**\n * Plays the specified media.\n * @param {module:media/MediaContent.MediaContent} mediaContent - The media to be played\n * @param {module:boxes/ActiveBox.ActiveBox} [mediaPlacement] - The cell where the graphic component of this media should be placed (used with video objects)\n * @param {function[]} [delayedActions] - If set, store the the action in this array for future execution\n */\n playMedia(mediaContent, mediaPlacement = null, delayedActions = null) {\n\n let ji = null;\n const fn = mediaContent.file;\n let action = null;\n\n switch (mediaContent.type) {\n case 'PLAY_AUDIO':\n case 'PLAY_VIDEO':\n case 'PLAY_MIDI':\n case 'RECORD_AUDIO':\n case 'PLAY_RECORDED_AUDIO':\n if (this.audioEnabled) {\n const amp = this.activeMediaBag.getActiveMediaPlayer(mediaContent, this.project.mediaBag, this);\n if (amp)\n action = () => amp.play(mediaPlacement);\n }\n break;\n\n case 'RUN_CLIC_PACKAGE':\n ji = new JumpInfo('JUMP', fn);\n if (mediaContent.externalParam) {\n // Relative path computed in History.processJump\n ji.projectPath = mediaContent.externalParam;\n }\n action = () => this.history.processJump(ji, true);\n break;\n\n case 'RUN_CLIC_ACTIVITY':\n this.history.push();\n action = () => this.load(null, null, fn);\n break;\n\n case 'RETURN':\n if (this.history.storedElementsCount() > 0 || !this.options.returnAsExit) {\n action = () => this.history.pop();\n break;\n }\n case 'EXIT':\n ji = new JumpInfo('EXIT', fn);\n action = () => this.history.processJump(ji, false);\n break;\n\n case 'RUN_EXTERNAL':\n action = () => this.runCmd(fn);\n break;\n\n case 'URL':\n if (fn)\n // When mediaContent.level is 2 or more, the URL will be opened in a separate window.\n action = () => this.displayURL(fn, mediaContent.level > 1);\n break;\n\n default:\n log('error', `Unknown media type: ${mediaContent.type}`);\n break;\n }\n\n // Execute the action or pass callback\n if (delayedActions && action)\n delayedActions.push(action);\n else if (action)\n action();\n }\n\n /**\n * Stops currently playing media\n * @param {number} [level=-1] - Sets the threshold above which all media objects with equal\n * or greater `level` will also also be muted.\n */\n stopMedia(level) {\n if (typeof level !== 'number')\n level = -1;\n this.activeMediaBag.stopAll(level);\n }\n\n /**\n * Launches the specified system command.\n * Currently not implemented.\n * @param {string} cmd\n */\n runCmd(cmd) {\n log('warn', `Unsupported call to external command: \"${cmd}\"`);\n }\n\n /**\n * Called from {@link module:Activity.Activity Activity} when finished.\n * @param {boolean} _completedOK - `true` when the activity was successfully completed, `false`\n * otherwise.\n */\n activityFinished(_completedOK) {\n this.closeHelpWindow();\n log('info', 'Activity finished');\n this.timer.stop();\n this.startAutoPassTimer();\n }\n\n /**\n * Starts the automatic jump to next activity, when applicable.\n */\n startAutoPassTimer() {\n const ase = this.project.activitySequence.getCurrentAct();\n if (ase !== null && ase.delay > 0 && !this.delayedTimer.isRunning() && !this.navButtonsDisabled) {\n this.delayedAction = this.actions['next'];\n this.delayedTimer.interval = ase.delay * 1000;\n this.delayedTimer.start();\n }\n }\n\n /**\n *\n * Sets the current main message.\n * @param {module:boxes/ActiveBoxContent.ActiveBoxContent} abc - The content of the message\n */\n setMsg(abc) {\n const ab = this.skin ? this.skin.getMsgBox() : null;\n if (ab) {\n ab.clear();\n this.skin.invalidate(ab).update();\n ab.setContent(abc ? abc : ActiveBoxContent.EMPTY_CONTENT);\n // TODO: Move this method to Skin\n this.skin.invalidate(ab).update();\n ab.playMedia(this);\n }\n }\n\n /**\n * Launches the active media content associated to the main message, if any.\n */\n playMsg() {\n if (this.skin && this.skin.getMsgBox())\n this.skin.getMsgBox().playMedia(this);\n }\n\n /**\n * Sets a value to the specified counter\n * @param {string} counter - The id of the counter ('score', 'actions' or 'time')\n * @param {number} newValue - The value to be set\n */\n setCounterValue(counter, newValue) {\n this.counterVal[counter] = newValue;\n if (this.skin && this.skin.counters[counter])\n this.skin.counters[counter].setValue(newValue);\n }\n\n /**\n * Gets the current value for the specified counter\n * @param {string} counter - The id of the counter ('score', 'actions' or 'time')\n * @returns {number}\n */\n getCounterValue(counter) {\n return this.counterVal[counter];\n }\n\n /**\n * Enables or disables a specific counter\n * @param {string} counter - The id of the counter ('score', 'actions' or 'time')\n * @param {boolean} bEnabled - When `true`, the counter will be enabled.\n */\n setCounterEnabled(counter, bEnabled) {\n if (this.skin) {\n this.skin.enableCounter(counter, bEnabled);\n this.setCountDown(counter, 0);\n }\n }\n\n /**\n * Increments by 1 the value of the specified counter\n * @param {string} counter - The id of the counter ('score', 'actions' or 'time')\n */\n incCounterValue(counter) {\n this.counterVal[counter]++;\n\n const\n actp = this.actPanel,\n cnt = this.skin ? this.skin.counters[counter] : null;\n\n if (cnt)\n cnt.setValue(this.counterVal[counter]);\n if (counter === 'actions' && actp !== null && actp.act.maxActions > 0 && actp.playing && this.counterVal['actions'] >= actp.act.maxActions)\n window.setTimeout(() => { actp.finishActivity(actp.solved); }, 0);\n }\n\n /**\n * Sets the specified counter in count-down status, starting at `maxValue`.\n * @param {string} counter - The id of the counter ('score', 'actions' or 'time')\n * @param {number} maxValue - The value from which to start counting down\n */\n setCountDown(counter, maxValue) {\n //this.counterVal[counter] = maxValue\n if (this.skin && this.skin.counters[counter])\n this.skin.counters[counter].setCountDown(maxValue);\n }\n\n /**\n * Set/unset the panel in 'wait' state\n * @param {boolean} status\n */\n setWaitCursor(status) {\n if (this.skin)\n this.skin.setWaitCursor(status);\n }\n\n /**\n * Sets the current value of the progress bar\n * @param {number} val - The current value. Should be less or equal than `max`. When -1, the progress bar will be hidden.\n * @param {number} [max] - Optional parameter representing the maximum value. When passed, the progress bar will be displayed.\n */\n setProgress(val, max) {\n if (this.skin)\n this.skin.setProgress(val, max);\n }\n\n /**\n * Increments the progress bar value by the specified amount, only when the progress bar is running.\n * @param {number} [val=1] - The amount to increment. When not defined, it's 1.\n */\n incProgress(val = 1) {\n if (this.skin)\n this.skin.incProgress(val);\n }\n\n /**\n * Builds an {@link module:media/ActiveMediaPlayer.ActiveMediaPlayer ActiveMediaPlayer} for the specified {@link module:media/MediaContent.MediaContent}\n * @param {module:media/MediaContent.MediaContent} mediaContent - The media content to be played\n * @returns {module:media/ActiveMediaPlayer.ActiveMediaPlayer}\n */\n getActiveMediaPlayer(mediaContent) {\n return this.activeMediaBag && mediaContent ? this.activeMediaBag.getActiveMediaPlayer(mediaContent, this.project.mediaBag, this) : null;\n }\n\n /**\n * Notifies the reporting system that a new activity has started\n * @param {module:Activity.Activity} act - The activity that is sending the notification\n */\n reportNewActivity(act) {\n const ase = this.project.activitySequence.getCurrentAct();\n if (this.reporter) {\n if (ase.tag === this.reporter.getCurrentSequenceTag())\n // Notify that the sequence has changed\n this.reporter.newSequence(ase);\n if (act.includeInReports)\n this.reporter.newActivity(act);\n }\n this.setCounterValue('actions', 0);\n this.setCounterValue('score', 0);\n }\n\n /**\n * Notifies the reporting system that a new action has been performed on the current activity\n * @param {module:Activity.Activity} act - The activity that is sending the notification\n * @param {string} type - Type of action (match, move, switch...)\n * @param {string} source - Object acting as a source of the action (cell, grid, clue...)\n * @param {string} dest - When applicable, object acting as a receiver of the action (cell, grid...)\n * @param {boolean} ok - Whether the action was OK or not\n * @param {number} currentScore - The current score of the activity\n */\n reportNewAction(act, type, source, dest, ok, currentScore) {\n if (this.reporter && act.includeInReports && act.reportActions)\n this.reporter.newAction(type, source, dest, ok);\n if (currentScore >= 0) {\n this.incCounterValue('actions');\n this.setCounterValue('score', currentScore);\n }\n }\n\n /**\n * Notifies the reporting system that the current activity has finished\n * @param {module:Activity.Activity} act - The activity that is sending the notification\n * @param {boolean} solved - Whether the activity was successfully completed or not.\n */\n reportEndActivity(act, solved) {\n if (this.reporter && act.includeInReports)\n this.reporter.endActivity(this.counterVal['score'], this.counterVal['actions'], solved);\n }\n\n /**\n * Shows the help info provided by the activity\n * @param {external:jQuery} $hlpComponent - The jQuery DOM component to be shown.\n * @returns {boolean} - True when the component was successfully displayed\n */\n showHelp($hlpComponent) {\n return this.skin ? this.skin.showHelp($hlpComponent) : false;\n }\n\n /**\n * Navigates to the requested URL\n * @param {string} url - The URL to navigate to\n * @param {boolean} inFrame - When `true` opens in a new frame\n */\n displayURL(url, inFrame) {\n if (url) {\n if (inFrame)\n window.open(url, this.options.infoUrlFrame);\n else {\n this.end().then(() => { window.location.href = url; });\n }\n }\n }\n\n /**\n * Only when `exitUrl` has been specified in `options`, navigates to the specified URL\n * @param {string} url - The URL to navigate to.\n */\n exit(url) {\n this.displayURL(url || this.options.exitUrl, false);\n }\n\n /**\n * Sets a title in a specific HTML element, if provided.\n * @param {string} docTitle\n */\n setWindowTitle(docTitle) {\n log('info', `running ${docTitle}`);\n }\n}\n\nObject.assign(JClicPlayer.prototype, {\n /**\n * Object with miscellaneous options.\n * @name module:JClicPlayer.JClicPlayer#options\n * @type {object} */\n options: {\n //\n // Max waiting time to have all media loaded (milliseconds)\n maxWaitTime: 120000,\n //\n // Name of the frame where to open links\n infoUrlFrame: '_blank',\n //\n // URL where to navigate to on exit\n exitUrl: null,\n //\n // When `true` and no elements on sequence stack, RETURN acts as EXIT\n returnAsExit: false,\n //\n // At the beginning, the audio should be enabled or disabled\n audioEnabled: true,\n //\n // Navigation buttons are always visible (for debugging purposes)\n navButtonsAlways: false,\n //\n // Time (milliseconds) of the fade-in animation of the activity panel. When 0, no animation\n // is performed\n fade: 300,\n // Minimum horizontal swipe length to be considered an activity change gesture\n minSwipeX: 40,\n // Maximum vertical swipe length to be considered an activity change gesture\n maxSwipeY: 100,\n // Read swipe gestures as in right-to-left languages (default is left-to-right)\n rightToLeft: false,\n },\n /**\n * Unique ID of this player, randomly generated by the constructor\n * @name module:JClicPlayer.JClicPlayer#id\n * @type {string} */\n id: 'JC0000',\n /**\n * The JQuery \"div\" element used by this player as stage for activities\n * @name module:JClicPlayer.JClicPlayer#$div\n * @type {external:jQuery} */\n $div: null,\n /**\n * The JQuery top container where this player will deploy\n * @name module:JClicPlayer.JClicPlayer#$topDiv\n * @type {external:jQuery} */\n $topDiv: null,\n /**\n * The main container of all JClic components\n * @name module:JClicPlayer.JClicPlayer#$mainContainer\n * @type {external:jQuery} */\n $mainContainer: null,\n /**\n * Flag indicatig that this player has switched to full screen at least once\n * @name module:JClicPlayer.JClicPlayer#fullScreenChecked\n * @type {boolean} */\n fullScreenChecked: false,\n /**\n * The {@link module:project/JClicProject.JClicProject JClicProject} currently hosted in this player\n * @name module:JClicPlayer.JClicPlayer#project\n * @type {module:project/JClicProject.JClicProject} */\n project: null,\n /**\n * Relative path or absolute URL to be used as a base to access files\n * @name module:JClicPlayer.JClicPlayer#basePath\n * @type {string} */\n basePath: '',\n /**\n * A {@link external:JSZip} object pointing to a `jclic.zip` or `jclic.scorm.zip` file containing\n * the current project.\n * Two extra properties will be added to this object when loaded:\n * - __zip.fullZipPath__ {string} - The full path of the ZIP file\n * - __zip.zipBasePath__ {string} - The path to the folder containing the ZIP file\n * @name module:JClicPlayer.JClicPlayer#zip\n * @type {external:JSZip} */\n zip: null,\n /**\n * This flag indicates if the player is running inside a document loaded by `file:` protocol\n * @name module:JClicPlayer.JClicPlayer#localFS\n * @type {boolean}\n */\n localFS: false,\n /**\n * The {@link module:Activity.ActivityPanel ActivityPanel} currently running on this player.\n * @name module:JClicPlayer.JClicPlayer#actPanel\n * @type {module:Activity.Activity#Panel} */\n actPanel: null,\n /**\n * This object records the list of the activities played during the current session.\n * @name module:JClicPlayer.JClicPlayer#history\n * @type {module:PlayerHistory.PlayerHistory} */\n history: null,\n /**\n * The Skin currently used by this player.\n * @name module:JClicPlayer.JClicPlayer#skin\n * @type {module:skins/Skin.Skin} */\n skin: null,\n /**\n * The default Skin to be used if none specified\n * @name module:JClicPlayer.JClicPlayer#defaultSkin\n * @type {module:skins/Skin.Skin} */\n defaultSkin: null,\n /**\n * The last skin directly specified by a {@link module:project/JClicProject.JClicProject JClicProject}\n * @name module:JClicPlayer.JClicPlayer#defaultSkin\n * @type {module:skins/Skin.Skin} */\n lastProjectSkin: null,\n /**\n * Object containing references to realized media objects, ready to play.\n * @name module:JClicPlayer.JClicPlayer#activeMediaBag\n * @type {module:media/ActiveMediaBag.ActiveMediaBag} */\n activeMediaBag: null,\n /**\n * Object responsible for passing the scores obtained by users to a external reporting systems\n * when playing activities.\n * @name module:JClicPlayer.JClicPlayer#reporter\n * @type {module:report/Reporter.Reporter} */\n reporter: null,\n /**\n * Collection of {@link module:AWT.Action} objects used by this player.\n * @name module:JClicPlayer.JClicPlayer#actions\n * @type {module:AWT.Action[]} */\n actions: {},\n /**\n * Main timer object used to feed the time counter. Ticks every second.\n * @name module:JClicPlayer.JClicPlayer#timer\n * @type {module:AWT.Timer} */\n timer: null,\n /**\n * Timer for delayed actions\n * @name module:JClicPlayer.JClicPlayer#delayedTimer\n * @type {module:AWT.Timer} */\n delayedTimer: null,\n /**\n * This variable holds the action to be executed by `delayedTimer`\n * @name module:JClicPlayer.JClicPlayer#delayedAction\n * @type {module:AWT.Action} */\n delayedAction: null,\n /**\n * @typedef JClicPlayer~counterValType\n * @type {object}\n * @property {number} score\n * @property {number} actions\n * @property {number} time */\n /**\n * Current values of the counters\n * @name module:JClicPlayer.JClicPlayer#counterVal\n * @type {module:JClicPlayer.JClicPlayer~counterValType} */\n counterVal: { score: 0, actions: 0, time: 0 },\n /**\n * Point indicating the upper-left corner of the current background image\n * @name module:JClicPlayer.JClicPlayer#bgImageOrigin\n * @type {module:AWT.Point} */\n bgImageOrigin: null,\n /**\n * Whether the player must play all sounds (including system sounds) and other media content\n * of the activities.\n * @name module:JClicPlayer.JClicPlayer#audioEnabled\n * @type {boolean} */\n audioEnabled: true,\n /**\n * Whether the navigation buttons `next` and `back` are enabled o disabled.\n * @name module:JClicPlayer.JClicPlayer#navButtonsDisabled\n * @type {boolean} */\n navButtonsDisabled: false,\n /**\n * When this flag is `true`, the navigation buttons are always enabled despite\n * of the indications made by the activities or the sequence control system.\n * This is used only to debug projects with complicated sequence chaining.\n * @name module:JClicPlayer.JClicPlayer#navButtonsAlways\n * @type {boolean} */\n navButtonsAlways: false,\n});\n\nexport default JClicPlayer;\n","/**\n * File : PlayerHistory.js\n * Created : 28/04/2015\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\n/* global window */\n\nimport $ from 'jquery';\nimport { log, isEquivalent, getPath, isNullOrUndef } from './Utils.js';\n\n/**\n *\n * PlayerHistory uses an array to store the list of projects and activities done by the user.\n * This class allows {@link module:JClicPlayer.JClicPlayer JClicPlayer} objects to rewind a sequence or to go back to a caller menu.\n */\nexport class PlayerHistory {\n /**\n * PlayerHistory constructor\n * @param {module:JClicPlayer.JClicPlayer} player - The JClicPlayer associated to this history\n */\n constructor(player) {\n this.player = player;\n this.sequenceStack = [];\n if (window && window.history && player.options.browserHistory) {\n this.browserHistory = true;\n $(window).on('popstate', (ev) => {\n const state = ev.originalEvent.state;\n if (state)\n this.processPopStateEvent(state);\n });\n }\n }\n\n /**\n *\n * Process the `state` object received in a `popstate` event\n * @param {PlayerHistory#HistoryElement} state - The previously stored state\n */\n processPopStateEvent(state) {\n log('info', 'Processing History popstate event with state:', state);\n this.processingPop = true;\n if (state.projectPath === this.player.project.path &&\n isEquivalent(state.fullZipPath, this.player.zip ? this.player.zip.fullZipPath : null))\n this.player.load(null, state.activity, null);\n else\n this.player.load(state.fullZipPath || state.projectPath, state.activity, null);\n }\n\n /**\n * Push a new entry on the window.History stack,\n * only when `browserHistory` is true and there is no `popstate` event in progress\n */\n pushBrowserHistory() {\n if (this.browserHistory) {\n\n if (this.processingPop) {\n // A 'popstate' event is currently being processed, so just clear this flag and return\n this.processingPop = false;\n return;\n }\n\n const\n ase = this.player.project.activitySequence,\n act = ase.currentAct,\n title = this.player.actPanel.act.name || 'No name',\n state = new this.HistoryElement(\n this.player.project.path,\n ase.getSequenceForElement(act),\n act,\n this.player.zip ? this.player.zip.fullZipPath : null);\n\n // Push a new history entry, or update the current one if it has no `state`\n if (!window.history.state)\n window.history.replaceState(state, title);\n else\n window.history.pushState(state, title);\n }\n }\n\n /**\n *\n * Counts the number of {@link module:PlayerHistory.PlayerHistory#HistoryElement HistoryElement} objects stored in\n * {@link module:PlayerHistory.PlayerHistory#sequenceStack sequenceStack}\n * @returns {number}\n */\n storedElementsCount() {\n return this.sequenceStack.length;\n }\n\n /**\n *\n * Removes all elements from {@link module:PlayerHistory.PlayerHistory#sequenceStack sequenceStack}\n */\n clearHistory() {\n this.sequenceStack = [0];\n }\n\n /**\n * Adds the current project and activity to the top of the history stack.\n */\n push() {\n if (this.player.project !== null && this.player.project.path !== null) {\n const\n ase = this.player.project.activitySequence,\n act = ase.currentAct;\n if (act >= 0) {\n if (this.sequenceStack.length > 0) {\n const last = this.sequenceStack[this.sequenceStack.length - 1];\n if (last.projectPath === this.player.project.path && last.activity === act)\n return;\n }\n this.sequenceStack.push(\n new this.HistoryElement(\n this.player.project.path,\n ase.getSequenceForElement(act),\n act,\n this.player.zip ? this.player.zip.fullZipPath : null));\n }\n }\n }\n\n /**\n * Retrieves the {@link module:PlayerHistory.PlayerHistory#HistoryElement HistoryElement} placed at the top of the\n * stack (if any) and instructs {@link module:JClicPlayer.JClicPlayer JClicPlayer} to load it. The obtained effect is to\n * \"rewind\" or \"go back\", usually to an activity that acts as a menu.\n * @returns {boolean}\n */\n pop() {\n // todo: check return value\n if (this.sequenceStack.length > 0) {\n const e = this.sequenceStack.pop();\n if (e.projectPath === this.player.project.path &&\n isEquivalent(e.fullZipPath, this.player.zip ? this.player.zip.fullZipPath : null))\n this.player.load(null, e.activity, null);\n else\n if (this.testMode && e.projectPath !== null && e.projectPath.length > 0)\n log('info', `At this point, a jump to \"${e.projectPath}\" should be performed.`);\n else\n this.player.load(e.fullZipPath || e.projectPath, e.activity, null);\n }\n return true;\n }\n\n /**\n *\n * Processes the provided {@link module:bags/JumpInfo.JumpInfo JumpInfo} object, instructing {@link module:JClicPlayer.JClicPlayer JClicPlayer} to go back,\n * stop or jump to another point in the sequence.\n * @param {module:bags/JumpInfo.JumpInfo} ji - The object to be processed\n * @param {boolean} allowReturn - When this parameter is `true`, the jump instructed by `ji` (if any)\n * will be recorded, thus allowing to return to the current activity.\n * @returns {boolean} - `true` if the jump can be processed without errors, `false` otherwise.\n */\n processJump(ji, allowReturn) {\n let result = false;\n if (ji !== null && this.player.project !== null) {\n switch (ji.action) {\n case 'STOP':\n break;\n case 'RETURN':\n if (this.sequenceStack.length > 0 || !this.player.options.returnAsExit) {\n result = this.pop();\n break;\n }\n case 'EXIT':\n if (this.testMode)\n log('info', 'At this point, the program should exit.');\n else\n this.player.exit(ji.sequence);\n break;\n case 'JUMP':\n if (!ji.sequence && !ji.projectPath) {\n const ase = this.player.project.activitySequence.getElement(ji.actNum, true);\n if (ase !== null) {\n if (allowReturn)\n this.push();\n this.player.load(null, null, ase.activity);\n result = true;\n }\n } else {\n if (this.testMode && ji.projectPath !== null && ji.projectPath.length > 0) {\n log('info', `At this point, a jump to \"${ji.projectPath}\" should be performed.`);\n } else {\n result = this.jumpToSequence(ji.sequence,\n ji.projectPath ? getPath(this.player.project.basePath, ji.projectPath) : null,\n allowReturn);\n }\n }\n break;\n }\n }\n return result;\n }\n\n /**\n * Performs a jump to the specified sequence\n * @param {string} sequence - The {@link module:bags/ActivitySequence.ActivitySequence ActivitySequence} tag to jump to.\n * @param {string} [path] - When not `null`, indicates a new project file that must be loaded.\n * Otherwise, the `sequence` parameter refers to a tag on the {@link module:bags/ActivitySequence.ActivitySequence ActivitySequence} of the\n * current project.\n * @param {boolean} [allowReturn] - When this parameter is `true`, the jump will be recorded, thus\n * allowing to return to the current activity.\n */\n jumpToSequence(sequence, path = null, allowReturn = false) {\n if (isNullOrUndef(sequence) && isNullOrUndef(path))\n return false;\n if (isNullOrUndef(path))\n path = this.player.project.path;\n if (this.sequenceStack.length > 0) {\n const e = this.sequenceStack[this.sequenceStack.length - 1];\n if (!isNullOrUndef(sequence) && path === e.projectPath) {\n let same = sequence === e.sequence;\n if (path === this.player.project.path) {\n const ase = this.player.project.activitySequence.getElement(e.activity, false);\n same = ase !== null && sequence === ase.tag;\n }\n if (same)\n return this.pop();\n }\n }\n if (allowReturn)\n this.push();\n if (path === this.player.project.path)\n this.player.load(null, sequence, null);\n else\n this.player.load(path, sequence, null);\n return true;\n }\n}\n\nObject.assign(PlayerHistory.prototype, {\n /**\n * The {@link module:JClicPlayer.JClicPlayer JClicPlayer} object to which this `PlayerHistory` belongs\n * @name module:PlayerHistory.PlayerHistory#player\n * @type {module:JClicPlayer.JClicPlayer} */\n player: null,\n /**\n * This is the main member of the class. PlayerHistory puts and retrieves\n * on it information about the proects and activities done by the current user.\n * @name module:PlayerHistory.PlayerHistory#sequenceStack\n * @type {module:PlayerHistory.PlayerHistory#HistoryElement[]} */\n sequenceStack: [],\n /**\n * When in test mode, jumps are only simulated.\n * @name module:PlayerHistory.PlayerHistory#testMode\n * @type {boolean} */\n testMode: false,\n /**\n * When true, JClic history is in sync with browser history\n * @name PlayerHistory#browserHistory\n * @type {boolean} */\n browserHistory: false,\n /**\n * When true, a window.history event is currently being processed, so window.pushState should not be performed\n * @name PlayerHistory#processingPop\n * @type {boolean} */\n processingPop: false,\n /**\n * Inner class used to store history elements.\n * @name module:PlayerHistory.PlayerHistory#HistoryElement\n */\n HistoryElement: class {\n /**\n * HistoryElement constructor\n * @param {string} projectPath - The full path of the project file\n * @param {string} sequence - The nearest sequence tag\n * @param {number} activity - The index of the current activity on the project's {@link module:bags/ActivitySequence.ActivitySequence ActivitySequence}\n * @param {string} fullZipPath - If `projectPath` resides in a {@link external:JSZip JSZip} object,\n * the full path of the zip file.\n */\n constructor(projectPath, sequence, activity, fullZipPath) {\n this.projectPath = projectPath;\n this.sequence = sequence;\n this.activity = activity;\n this.fullZipPath = fullZipPath;\n }\n }\n});\n\nexport default PlayerHistory;\n","/**\n * File : media/ActiveMediaBag.js\n * Created : 28/04/2015\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\nimport ActiveMediaPlayer from './ActiveMediaPlayer.js';\nimport { settings } from '../Utils.js';\n\n/**\n * This class stores a collection of realized {@link module:media/ActiveMediaPlayer.ActiveMediaPlayer ActiveMediaPlayer} objects, related to a\n * {@link module:project/JClicProject.JClicProject JClicProject} or {@link module:Activity.Activity Activity}.\n */\nexport class ActiveMediaBag {\n /**\n * ActiveMediaBag constructor\n */\n constructor() {\n this.players = [];\n }\n\n /**\n * Creates a new {@link module:media/ActiveMediaPlayer.ActiveMediaPlayer ActiveMediaPlayer} linked to this media bag\n * @param {module:media/MediaContent.MediaContent} mc - The content used by the new player\n * @param {module:bags/MediaBag.MediaBag} mb - The project's MediaBag\n * @param {module:JClicPlayer.JClicPlayer} ps - An object implementing the\n * [PlayStation](http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/PlayStation.html) interface,\n * usually a {@link module:JClicPlayer.JClicPlayer JClicPlayer}.\n * @returns {module:media/ActiveMediaPlayer.ActiveMediaPlayer}\n */\n createActiveMediaPlayer(mc, mb, ps) {\n let amp = null;\n switch (mc.type) {\n case 'RECORD_AUDIO':\n if (mc.length <= 0 || mc.length >= settings.MAX_RECORD_LENGTH)\n break;\n /* falls through */\n case 'PLAY_RECORDED_AUDIO':\n if (mc.recBuffer < 0 || mc.recBuffer >= 10)\n break;\n /* falls through */\n case 'PLAY_AUDIO':\n case 'PLAY_MIDI':\n case 'PLAY_VIDEO':\n amp = new ActiveMediaPlayer(mc, mb, ps);\n break;\n }\n if (amp !== null)\n this.players.push(amp);\n return amp;\n }\n\n /**\n * Looks for an already existing {@link module:media/ActiveMediaPlayer.ActiveMediaPlayer ActiveMediaPlayer} equivalent to the requested.\n * When not found, a new one is created and and returned.\n * @param {module:media/MediaContent.MediaContent} mc - The content used by the new player\n * @param {module:bags/MediaBag.MediaBag} mb - The project's MediaBag\n * @param {module:JClicPlayer.JClicPlayer} ps - An object implementing the\n * {@link http://projectestac.github.io/jclic/apidoc/edu/xtec/jclic/PlayStation.html|PlayStation} interface,\n * usually a {@link module:JClicPlayer.JClicPlayer JClicPlayer}.\n * @returns {module:media/ActiveMediaPlayer.ActiveMediaPlayer}\n */\n getActiveMediaPlayer(mc, mb, ps) {\n return this.players.find(p => p.mc === mc || p.mc.isEquivalent(mc))\n || this.createActiveMediaPlayer(mc, mb, ps);\n }\n\n /**\n * Removes from the list of players the {@link module:media/ActiveMediaPlayer.ActiveMediaPlayer ActiveMediaPlayer} related to the specified {@link module:media/MediaContent.MediaContent}.\n * @param {module:media/MediaContent.MediaContent} mc - The media content to look for.\n */\n removeActiveMediaPlayer(mc) {\n const i = this.players.findIndex(p => p.mc === mc);\n if (i >= 0) {\n this.players[i].clear();\n // removes the element pointed by 'i'\n this.players.splice(i, 1);\n }\n }\n\n /**\n * Realizes all the media elements stored in this bag\n */\n realizeAll() {\n this.players.forEach(p => p.realize());\n }\n\n /**\n * Stops playing all media elements stored in this bag\n * @param {number} level - Level at and below what all media players will be muted.\n */\n stopAll(level) {\n if (typeof level === 'undefined')\n level = -1;\n this.players.forEach(amp => {\n if (level === -1 || amp.mc !== null && amp.mc.level <= level)\n amp.stop();\n });\n }\n\n /**\n * Removes all players from this media bag\n */\n removeAll() {\n this.players.forEach(p => p.clear());\n // Empty the `players` array\n this.players.length = 0;\n ActiveMediaPlayer.prototype.clearAllAudioBuffers();\n }\n}\n\nObject.assign(ActiveMediaBag.prototype, {\n /**\n * The collection of {@link module:media/ActiveMediaPlayer.ActiveMediaPlayer ActiveMediaPlayer} objects stored in this media bag.\n * @name module:media/ActiveMediaBag.ActiveMediaBag#players\n * @type {module:media/ActiveMediaPlayer.ActiveMediaPlayer[]} */\n players: [],\n});\n\nexport default ActiveMediaBag;\n"],"names":[],"sourceRoot":""}