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,808 +0,0 @@
1
- "use strict";
2
- exports.id = 1196;
3
- exports.ids = [1196,3391];
4
- exports.modules = {
5
-
6
- /***/ 1196:
7
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8
-
9
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10
- /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
11
- /* harmony export */ });
12
- /* unused harmony export MediaBagElement */
13
- /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7750);
14
- /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
15
- /* harmony import */ var _media_MidiAudioPlayer_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3391);
16
- /* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(1253);
17
- /* harmony import */ var _AWT_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7912);
18
- /**
19
- * File : bags/MediaBagElement.js
20
- * Created : 07/04/2015
21
- * By : Francesc Busquets <francesc@gmail.com>
22
- *
23
- * JClic.js
24
- * An HTML5 player of JClic activities
25
- * https://projectestac.github.io/jclic.js
26
- *
27
- * @source https://github.com/projectestac/jclic.js
28
- *
29
- * @license EUPL-1.2
30
- * @licstart
31
- * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
32
- *
33
- * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
34
- * the European Commission- subsequent versions of the EUPL (the "Licence");
35
- * You may not use this work except in compliance with the Licence.
36
- *
37
- * You may obtain a copy of the Licence at:
38
- * https://joinup.ec.europa.eu/software/page/eupl
39
- *
40
- * Unless required by applicable law or agreed to in writing, software
41
- * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
42
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
43
- * Licence for the specific language governing permissions and limitations
44
- * under the Licence.
45
- * @licend
46
- * @module
47
- */
48
-
49
- /* global URL, Uint8Array, XMLHttpRequest, Image, document */
50
-
51
-
52
-
53
-
54
-
55
-
56
- /**
57
- * This kind of objects are the components of {@link module:bags/MediaBag.MediaBag MediaBag}.
58
- *
59
- * Media elements have a name, a reference to a file (the `file` field) and, when initialized,
60
- * a `data` field pointing to a object containing the real media. They have also a flag indicating
61
- * if the data must be saved on the {@link module:project/JClicProject.JClicProject JClicProject} zip file or just maintained as a reference
62
- * to an external file.
63
- */
64
- class MediaBagElement {
65
- /**
66
- * MediaBagElement constructor
67
- * @param {string} basePath - Path to be used as a prefix of the file name
68
- * @param {string} file - The media file name
69
- * @param {external:JSZip} [zip] - An optional JSZip object from which the file must be extracted.
70
- */
71
- constructor(basePath, file, zip) {
72
- if (basePath)
73
- this.basePath = basePath;
74
- if (file) {
75
- this.file = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .nSlash */ .c4)(file);
76
- this.name = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .nSlash */ .c4)(file);
77
- this.ext = this.file.toLowerCase().split('.').pop();
78
- this.type = this.getFileType(this.ext);
79
- if (this.ext === 'gif')
80
- this.checkAnimatedGif();
81
- }
82
- if (zip)
83
- this.zip = zip;
84
- this.timeout = Date.now() + _Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .settings */ .W0.LOAD_TIMEOUT;
85
- }
86
-
87
-
88
- /**
89
- * Private static array of {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement HTMLAudioElements},
90
- * to be reused between all media elements of type 'audio'. One for each priority level
91
- * @name module:bags/MediaBagElement#_audioPlayers
92
- * @type {external:HTMLAudioElement[]}
93
- */
94
- static _audioPlayers = [];
95
-
96
- /**
97
- * Gets the static {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLAudioElement HTMLAudioElement}
98
- * associated to the requested priority level.
99
- * @param {number} level=1 - The priority level
100
- * @returns {external:HTMLAudioElement}
101
- */
102
- static getAudioPlayer(level = 1) {
103
- if (!MediaBagElement._audioPlayers[level])
104
- MediaBagElement._audioPlayers[level] = document.createElement('audio');
105
- return MediaBagElement._audioPlayers[level];
106
- }
107
-
108
- /**
109
- * Private static array of {@link bags/MediaBagElement MediaBagElements},
110
- * used to store a reference to the element using each `audioPlayer`
111
- * @name module:bags/MediaBagElement#_currentAudioElements
112
- * @type {bags/MediaBagElement[]}
113
- */
114
- static _currentAudioElements = [];
115
-
116
- /**
117
- * Clear all references to audio players and audio elements
118
- * To be called when a new activity starts
119
- */
120
- static resetAudioElements() {
121
- MediaBagElement._audioPlayers.fill(null);
122
- MediaBagElement._currentAudioElements.fill(null);
123
- }
124
-
125
- /**
126
- * Loads this object settings from a specific JQuery XML element
127
- * @param {external:jQuery} $xml - The XML element to parse
128
- */
129
- setProperties($xml) {
130
- this.name = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .nSlash */ .c4)($xml.attr('name'));
131
- this.file = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .nSlash */ .c4)($xml.attr('file'));
132
- this.ext = this.file.toLowerCase().split('.').pop();
133
- this.type = this.getFileType(this.ext);
134
- // Check if it's an animated GIF
135
- if (this.ext === 'gif') {
136
- const anim = $xml.attr('animated');
137
- if (typeof anim === 'undefined')
138
- this.checkAnimatedGif();
139
- else
140
- this.animated = anim === 'true';
141
- }
142
- if (this.type === 'font') {
143
- this.fontName = this.name === this.file && this.name.lastIndexOf('.') > 0 ?
144
- this.name.substring(0, this.name.lastIndexOf('.')) :
145
- this.name;
146
- }
147
- return this;
148
- }
149
-
150
- /**
151
- * Gets a object with the basic attributes needed to rebuild this instance excluding functions,
152
- * parent references, constants and also attributes retaining the default value.
153
- * The resulting object is commonly usued to serialize elements in JSON format.
154
- * @returns {object} - The resulting object, with minimal attrributes
155
- */
156
- getAttributes() {
157
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .getAttr */ .iu)(this, ['name', 'file', 'animated']);
158
- }
159
-
160
- /**
161
- * Loads the element properties from a data object
162
- * @param {object} data - The data object to parse
163
- */
164
- setAttributes(data) {
165
- ['name', 'file', 'animated'].forEach(attr => {
166
- if (!(0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .isEmpty */ .Im)(data[attr]))
167
- this[attr] = data[attr];
168
- });
169
-
170
- this.ext = this.file.toLowerCase().split('.').pop();
171
- this.type = this.getFileType(this.ext);
172
-
173
- // Check if it's an animated GIF
174
- if (this.ext === 'gif' && this.animated === 'undefined')
175
- this.checkAnimatedGif();
176
-
177
- if (this.type === 'font') {
178
- this.fontName = this.name === this.file && this.name.lastIndexOf('.') > 0 ?
179
- this.name.substring(0, this.name.lastIndexOf('.')) :
180
- this.name;
181
- }
182
- return this;
183
- }
184
-
185
- /**
186
- * Checks if the image associated with this MediaBagElement is an animated GIF
187
- *
188
- * Based on: {@link https://gist.github.com/marckubischta/261ad8427a214022890b}
189
- * Thanks to `@lakenen` and `@marckubischta`
190
- */
191
- checkAnimatedGif() {
192
- const request = new XMLHttpRequest();
193
- // Set `responseType` moved after calling `open`
194
- // see: https://stackoverflow.com/questions/20760635/why-does-setting-xmlhttprequest-responsetype-before-calling-open-throw
195
- // request.responseType = 'arraybuffer'
196
- request.addEventListener('load', () => {
197
- const
198
- arr = new Uint8Array(request.response),
199
- length = arr.length;
200
-
201
- // make sure it's a gif (GIF8)
202
- if (arr[0] !== 0x47 || arr[1] !== 0x49 ||
203
- arr[2] !== 0x46 || arr[3] !== 0x38) {
204
- this.animated = false;
205
- return;
206
- }
207
-
208
- // Ported from PHP [http://www.php.net/manual/en/function.imagecreatefromgif.php#104473]
209
- // an animated gif contains multiple "frames", with each frame having a
210
- // header made up of:
211
- // * a static 3-byte sequence (\x00\x21\xF9
212
- // * one byte indicating the length of the header (usually \x04)
213
- // * variable length header (usually 4 bytes)
214
- // * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)
215
- // We read through the file as long as we haven't reached the end of the file
216
- // and we haven't yet found at least 2 frame headers
217
- for (let i = 0, len = length - 3, frames = 0; i < len && frames < 2; ++i) {
218
- if (arr[i] === 0x00 && arr[i + 1] === 0x21 && arr[i + 2] === 0xF9) {
219
- const
220
- blocklength = arr[i + 3],
221
- afterblock = i + 4 + blocklength;
222
- if (afterblock + 1 < length &&
223
- arr[afterblock] === 0x00 &&
224
- (arr[afterblock + 1] === 0x2C || arr[afterblock + 1] === 0x21)) {
225
- if (++frames > 1) {
226
- this.animated = true;
227
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .log */ .Rm)('debug', `Animated GIF detected: ${this.file}`);
228
- break;
229
- }
230
- }
231
- }
232
- }
233
- });
234
-
235
- this.getFullPathPromise()
236
- .then(fullPath => {
237
- request.open('GET', fullPath, true);
238
- request.responseType = 'arraybuffer';
239
- request.send();
240
- });
241
- }
242
-
243
- /**
244
- * Checks if the MediaBagElement has been initiated
245
- * @returns {boolean}
246
- */
247
- isEmpty() {
248
- return this.data === null;
249
- }
250
-
251
- /**
252
- * Determines the type of a file from its extension
253
- * @param {string} ext - The file name extension
254
- * @returns {string}
255
- */
256
- getFileType(ext) {
257
- let result = null;
258
- for (let type in _Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .settings */ .W0.FILE_TYPES) {
259
- if (_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .settings */ .W0.FILE_TYPES[type].indexOf(ext) >= 0) {
260
- result = type;
261
- break;
262
- }
263
- }
264
- return result;
265
- }
266
-
267
- /**
268
- * Instantiates the media content
269
- * @param {function} callback - Callback method called when the referred resource is ready
270
- * @param {module:JClicPlayer.JClicPlayer} ps=null - An optional `PlayStation` (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used to dynamically load fonts
271
- * @param {boolean} force=false - Used only in media of type 'audio'. When `true`, a static {@link MediaBagElement._audioPlayers audioPlayer element} will be loaded with this media source
272
- * @param {number} level=1 - Priority level of the media content to be built. Used only n audio elements.
273
- */
274
- build(callback, ps = null, force = false, level = 1) {
275
- // Mock data when running in NodeJS
276
- if (_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .settings */ .W0.NODEJS) {
277
- this.data = [];
278
- this.ready = true;
279
- }
280
-
281
- if (callback) {
282
- if (!this._whenReady)
283
- this._whenReady = [];
284
- this._whenReady.push(callback);
285
- }
286
-
287
- if (!this.data)
288
- this.getFullPathPromise()
289
- .then(fullPath => {
290
- switch (this.type) {
291
- case 'font':
292
- const
293
- format = this.ext === 'ttf' ? 'truetype' : this.ext === 'otf' ? 'embedded-opentype' : this.ext,
294
- css = `@font-face{font-family:"${this.fontName}";src:url(${fullPath}) format("${format}");}`;
295
-
296
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .appendStyleAtHead */ .dw)(css, ps);
297
- this.data = new _AWT_js__WEBPACK_IMPORTED_MODULE_3__/* .Font */ .KQ(this.name);
298
- this.ready = true;
299
- break;
300
-
301
- case 'image':
302
- this.data = new Image();
303
- this.data.addEventListener('load', () => { this._onReady.call(this); }, { once: true });
304
- this.data.src = fullPath;
305
- break;
306
-
307
- case 'video':
308
- this.data = document.createElement(this.type);
309
- this.data.addEventListener('canplay', () => { this._onReady.call(this); }, { once: true });
310
- this.data.src = fullPath;
311
- this.data.load();
312
- this.data.pause();
313
- break;
314
-
315
- case 'audio':
316
- // HTML Audio objects will be created on demand, when the param 'force' is set to true
317
- if (force) {
318
- // Clean up state in current audio element, if any
319
- const currentAudioElement = MediaBagElement._currentAudioElements[level];
320
- if (currentAudioElement && currentAudioElement !== this) {
321
- currentAudioElement.data = null;
322
- currentAudioElement.ready = false;
323
- }
324
- // Register as a current audio element
325
- MediaBagElement._currentAudioElements[level] = this;
326
- // Configure the audio player
327
- const audioPlayer = MediaBagElement.getAudioPlayer(level);
328
- if (audioPlayer.src !== fullPath) {
329
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .log */ .Rm)('trace', `Loading static player #${level} with new audio: ${fullPath}`);
330
- this.data = audioPlayer;
331
- this.ready = false;
332
- audioPlayer.addEventListener('canplay', () => { this._onReady.call(this); }, { once: true });
333
- audioPlayer.src = fullPath;
334
- audioPlayer.load();
335
- audioPlayer.pause();
336
- }
337
- else
338
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .log */ .Rm)('trace', `Reusing existing audio in player #${level}: ${fullPath}`);
339
- }
340
- else
341
- this.ready = true;
342
- break;
343
-
344
- case 'anim':
345
- // TODO: Use [Ruffle](https://ruffle.rs/) to play Flash movies
346
- this.data = jquery__WEBPACK_IMPORTED_MODULE_0___default()(`<object type"application/x-shockwave-flash" width="300" height="200" data="${fullPath}"/>`).get(-1);
347
- // Unable to check the loading progress in elements of type `object`. so we mark it always as `ready`:
348
- this.ready = true;
349
- break;
350
-
351
- case 'xml':
352
- jquery__WEBPACK_IMPORTED_MODULE_0___default().get(fullPath, null, null, 'xml').done(xmlData => {
353
- const children = xmlData ? xmlData.children || xmlData.childNodes : null;
354
- this.data = children && children.length > 0 ? (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .parseXmlNode */ .Fy)(children[0]) : null;
355
- this._onReady();
356
- }).fail(err => {
357
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .log */ .Rm)('error', `Error loading ${this.name}: ${err}`);
358
- this._onReady();
359
- });
360
- break;
361
-
362
- case 'midi':
363
- const request = new XMLHttpRequest();
364
- request.onreadystatechange = () => {
365
- if (request.readyState === 4) {
366
- if (request.status === 200)
367
- this.data = new _media_MidiAudioPlayer_js__WEBPACK_IMPORTED_MODULE_1__["default"](request.response, ps && ps.options);
368
- else
369
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .log */ .Rm)('error', `Error loading ${this.name}: ${request.statusText}`);
370
- this._onReady();
371
- }
372
- };
373
- request.open('GET', fullPath, true);
374
- request.responseType = 'arraybuffer';
375
- request.send();
376
- break;
377
-
378
- default:
379
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .log */ .Rm)('trace', `Media currently not supported: ${this.name}`);
380
- this.ready = true;
381
- }
382
-
383
- if (this.ready)
384
- this._onReady();
385
- });
386
- else if (this.ready)
387
- this._onReady();
388
-
389
- return this;
390
- }
391
-
392
- /**
393
- * Checks if this media element is ready to start
394
- * @returns {boolean} - `true` if ready, `false` otherwise
395
- */
396
- checkReady() {
397
- if (this.data && !this.ready) {
398
- switch (this.type) {
399
- case 'image':
400
- this.ready = this.data.complete === true;
401
- break;
402
- case 'audio':
403
- case 'video':
404
- case 'anim':
405
- this.ready = this.data.readyState >= 1;
406
- break;
407
- default:
408
- this.ready = true;
409
- }
410
- }
411
- return this.ready;
412
- }
413
-
414
- /**
415
- * Checks if this resource has timed out.
416
- * @returns {boolean} - `true` if the resource has exhausted the allowed time to load, `false` otherwise
417
- */
418
- checkTimeout() {
419
- const result = Date.now() > this.timeout;
420
- if (result)
421
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .log */ .Rm)('warn', `Timeout while loading: ${this.name}`);
422
- return result;
423
- }
424
-
425
- /**
426
- * Notify listeners that the resource is ready
427
- */
428
- _onReady() {
429
- this.ready = true;
430
- if (this._whenReady) {
431
- this._whenReady.forEach(fn => fn.call(this, this));
432
- this._whenReady = null;
433
- }
434
- }
435
-
436
- /**
437
- * Gets the full path of the file associated to this element.
438
- * WARNING: This function should be called only after a successful call to `getFullPathPromise`
439
- * @returns {string}
440
- */
441
- getFullPath() {
442
- return this._fullPath;
443
- }
444
-
445
- /**
446
- * Gets a promise with the full path of the file associated to this element.
447
- * @returns {external:Promise}
448
- */
449
- getFullPathPromise() {
450
- return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .getPathPromise */ .xw)(this.basePath, this.file, this.zip)
451
- .then(fullPath => {
452
- // Process full URL only when running in a browser
453
- this._fullPath = _Utils_js__WEBPACK_IMPORTED_MODULE_2__/* .settings */ .W0.NODEJS
454
- ? fullPath
455
- : (new URL(fullPath, document.location.href)).toString();
456
- return this._fullPath;
457
- });
458
- }
459
- }
460
-
461
- Object.assign(MediaBagElement.prototype, {
462
- /**
463
- * The name of this element. Usually is the same as `file`
464
- * @name module:bags/MediaBagElement.MediaBagElement#name
465
- * @type {string} */
466
- name: '',
467
- /**
468
- * The name of the file where this element is stored
469
- * @name module:bags/MediaBagElement.MediaBagElement#file
470
- * @type {string} */
471
- file: '',
472
- /**
473
- * The font family name, used only in elements of type 'font'
474
- * @name module:bags/MediaBagElement.MediaBagElement#fontName
475
- * @type {string} */
476
- fontName: '',
477
- /**
478
- * The path to be used as base to access this media element
479
- * @name module:bags/MediaBagElement.MediaBagElement#basePath
480
- * @type {string} */
481
- basePath: '',
482
- /**
483
- * An optional JSZip object that can act as a container of this media
484
- * @name module:bags/MediaBagElement.MediaBagElement#zip
485
- * @type {external:JSZip} */
486
- zip: null,
487
- /**
488
- * When loaded, this field will store the realized media object
489
- * @name module:bags/MediaBagElement.MediaBagElement#data
490
- * @type {object} */
491
- data: null,
492
- /**
493
- * Flag indicating that `data` is ready to be used
494
- * @name module:bags/MediaBagElement.MediaBagElement#ready
495
- * @type {boolean} */
496
- ready: false,
497
- /**
498
- * Array of callback methods to be called when the resource becomes ready
499
- * @name module:bags/MediaBagElement.MediaBagElement#_whenReady
500
- * @private
501
- * @type {function[]} */
502
- _whenReady: null,
503
- /**
504
- * Normalized extension of `file`, useful to guess the media type
505
- * @name module:bags/MediaBagElement.MediaBagElement#ext
506
- * @type {string} */
507
- ext: '',
508
- /**
509
- * The resource type ('audio', 'image', 'midi', 'video', 'font')
510
- * @name module:bags/MediaBagElement.MediaBagElement#type
511
- * @type {string} */
512
- type: null,
513
- /**
514
- * Time set to load the resource before leaving
515
- * @name module:bags/MediaBagElement.MediaBagElement#timeout
516
- * @type {number} */
517
- timeout: 0,
518
- //
519
- /**
520
- * Flag used for animated GIFs
521
- * @name module:bags/MediaBagElement.MediaBagElement#animated
522
- * @type {boolean} */
523
- animated: false,
524
- /**
525
- * Full path obtained after a successful call to getFullPathPromise
526
- * @name module:bags/MediaBagElement.MediaBagElement#_fullPath
527
- * @private
528
- * @type {string}
529
- */
530
- _fullPath: null,
531
- });
532
-
533
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MediaBagElement);
534
-
535
-
536
- /***/ }),
537
-
538
- /***/ 3391:
539
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
540
-
541
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
542
- /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
543
- /* harmony export */ });
544
- /* unused harmony export MidiAudioPlayer */
545
- /* harmony import */ var _francesc_basic_midi_player_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5428);
546
- /* harmony import */ var _francesc_basic_midi_player_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_francesc_basic_midi_player_js__WEBPACK_IMPORTED_MODULE_0__);
547
- /* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1253);
548
- /**
549
- * File : media/MidiAudioPlayer.js
550
- * Created : 11/10/2018
551
- * By : Francesc Busquets <francesc@gmail.com>
552
- *
553
- * JClic.js
554
- * An HTML5 player of JClic activities
555
- * https://projectestac.github.io/jclic.js
556
- *
557
- * @source https://github.com/projectestac/jclic.js
558
- *
559
- * @license EUPL-1.2
560
- * @licstart
561
- * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
562
- *
563
- * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
564
- * the European Commission- subsequent versions of the EUPL (the "Licence");
565
- * You may not use this work except in compliance with the Licence.
566
- *
567
- * You may obtain a copy of the Licence at:
568
- * https://joinup.ec.europa.eu/software/page/eupl
569
- *
570
- * Unless required by applicable law or agreed to in writing, software
571
- * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
572
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
573
- * Licence for the specific language governing permissions and limitations
574
- * under the Licence.
575
- * @licend
576
- * @module
577
- */
578
-
579
- /* global window */
580
-
581
-
582
-
583
-
584
- // TODO: Use multiple instruments, at least one for each track
585
- // TODO: Use multiple midi channels (currently flattened to a single channel)
586
- // TODO: Use of channel 10 for percussion instruments
587
- // TODO: ... build a real MIDI player!!
588
-
589
- /**
590
- * A simple MIDI player based on MidiPlayerJS
591
- * https://github.com/grimmdude/MidiPlayerJS
592
- * See also: http://www.midijs.net (https://github.com/babelsberg/babelsberg-js/tree/master/midijs)
593
- */
594
- class MidiAudioPlayer {
595
- /**
596
- * MidiAudioPlayer constructor
597
- * @param {external:ArrayBuffer} data - The MIDI file content, in ArrayBuffer format
598
- * @param {object} [options={}] - Optional params related to the type of soundfont used. Valid options inside this object are:<br>
599
- * - `MIDISoundFontObject`: An object containing the full soundfont data. When this param is provided, no other one will be used.
600
- * - `MIDISoundFontBase`: The URL used as base for the current collection of MIDI soundfonts. Defaults to `https://clic.xtec.cat/dist/jclic.js/soundfonts/MusyngKite`
601
- * - `MIDISoundFontName`: The MIDI instrument name. Defaults to `acoustic_grand_piano`. See [MIDI.js Soundfonts](https://github.com/gleitz/midi-js-soundfonts) for full lists of MIDI instrument names.
602
- * - `MIDISoundFontExtension`: An extension to be added to `MIDISoundFontName` in order to build the full file name of the soundfont JS file. Defaults to `-mp3.js`
603
- */
604
- constructor(data, options = {}) {
605
- const AudioContext = window && (window.AudioContext || window.webkitAudioContext);
606
- if (AudioContext) {
607
- // Build instrument on first call to constructor
608
- MidiAudioPlayer.prepareInstrument(options, new AudioContext());
609
- this.data = data;
610
- this.player = new (_francesc_basic_midi_player_js__WEBPACK_IMPORTED_MODULE_0___default().Player)(ev => this.playEvent(ev));
611
- if (this.player)
612
- this.player.loadArrayBuffer(data);
613
- }
614
- }
615
-
616
- /**
617
- * Initializes the soundfont instrument, loading data from GitHub
618
- * NOTE: This will not work when off-line!
619
- * TODO: Provided a basic, simple, static soundfont
620
- * @param {object} options - Optional param with options related to the MIDI soundfont. See details in `constructor` description.
621
- * @param {external:AudioContext} audioContext - The AudioContext object (see: https://developer.mozilla.org/en-US/docs/Web/API/AudioContext)
622
- */
623
- static prepareInstrument(options = {}, audioContext) {
624
- if (MidiAudioPlayer.loadingInstrument === false) {
625
- MidiAudioPlayer.loadingInstrument = true;
626
- MidiAudioPlayer.audioContext = audioContext;
627
- _francesc_basic_midi_player_js__WEBPACK_IMPORTED_MODULE_0___default().Soundfont.instrument(
628
- MidiAudioPlayer.audioContext,
629
- options.MIDISoundFontObject || MidiAudioPlayer.MIDISoundFontObject ||
630
- `${options.MIDISoundFontBase || MidiAudioPlayer.MIDISoundFontBase}/${options.MIDISoundFontName || MidiAudioPlayer.MIDISoundFontName}${options.MIDISoundFontExtension || MidiAudioPlayer.MIDISoundFontExtension}`)
631
- .then(instrument => {
632
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .log */ .Rm)('info', 'MIDI soundfont instrument loaded');
633
- MidiAudioPlayer.instrument = instrument;
634
- })
635
- .catch(err => {
636
- (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__/* .log */ .Rm)('error', `Error loading soundfont base instrument: ${err}`);
637
- });
638
- }
639
- }
640
-
641
- /**
642
- * Pauses the player
643
- */
644
- pause() {
645
- if (this.player) {
646
- this.player.pause();
647
- this.startedNotes = [];
648
- }
649
- }
650
-
651
- /**
652
- * Starts or resumes playing
653
- */
654
- play() {
655
- if (this.player) {
656
- this.startedNotes = [];
657
- this.player.play();
658
- }
659
- }
660
-
661
- /**
662
- * Gets the ' paused' state of the current player
663
- * @returns boolean
664
- */
665
- get paused() {
666
- return this.player && !this.player.isPlaying();
667
- }
668
-
669
- /**
670
- * Checks if the current player has ended or is already playing
671
- * @returns boolean
672
- */
673
- get ended() {
674
- return this.player && this.player.getSongTimeRemaining() <= 0;
675
- }
676
-
677
- /**
678
- * Gets the current time
679
- * @returns number
680
- */
681
- get currentTime() {
682
- return this.player && (this.player.getSongTime() * 1000) || 0;
683
- }
684
-
685
- /**
686
- * Sets the current time of this player (in milliseconds)
687
- * @param {number} time - The time position where the player pointer must be placed
688
- */
689
- set currentTime(time) {
690
- if (this.player)
691
- this.player.skipToSeconds(time / 1000);
692
- }
693
-
694
- /**
695
- * Plays a MIDI event
696
- * @param {object} ev - The event data. See http://grimmdude.com/MidiPlayerJS/docs/index.html for details
697
- */
698
- playEvent(ev) {
699
- if (this.player && MidiAudioPlayer.instrument) {
700
- // Check for specific interval
701
- if (this.playTo > 0 && this.currentTime >= this.playTo)
702
- this.pause();
703
- // Set main volume
704
- else if (ev.name === 'Controller Change' && ev.number === 7)
705
- this.mainVolume = ev.value / 127;
706
- // Process 'Note on' messages. Max gain set to 2.0 for better results with the used soundfont
707
- else if (ev.name === 'Note on' && ev.velocity > 0)
708
- this.startedNotes[ev.noteNumber] = MidiAudioPlayer.instrument.play(ev.noteName, MidiAudioPlayer.audioContext.currentTime, { gain: 2 * (this.mainVolume * ev.velocity / 100) });
709
- // Process 'Note off' messages
710
- else if (ev.name === 'Note off' && ev.noteNumber && this.startedNotes[ev.noteNumber]) {
711
- this.startedNotes[ev.noteNumber].stop();
712
- delete (this.startedNotes[ev.noteNumber]);
713
- }
714
- }
715
- }
716
- }
717
-
718
- Object.assign(MidiAudioPlayer.prototype, {
719
- /**
720
- * The MIDI file data used by this MIDI player
721
- * @name module:media/MidiAudioPlayer.MidiAudioPlayer#data
722
- * @type {external:ArrayBuffer} */
723
- data: null,
724
- /**
725
- * The grimmdude's MidiPlayer used by this player
726
- * @name module:media/MidiAudioPlayer.MidiAudioPlayer#player
727
- * @type {external:MidiPlayerJS} */
728
- player: null,
729
- /**
730
- * When >0, time position at which the music must end
731
- * @name module:media/MidiAudioPlayer.MidiAudioPlayer#playTo
732
- * @type {number} */
733
- playTo: 0,
734
- /**
735
- * Main volume of this track (set with a MIDI message of type `Controller Change` #7)
736
- * @name module:media/MidiAudioPlayer.MidiAudioPlayer#mainVolume
737
- * @type {number} */
738
- mainVolume: 1.0,
739
- /**
740
- * This array is used when processing 'Note off' events to stop notes that are currently playing.
741
- * It contains a collection of 'instrument.play' instances, one for each active note
742
- * @name module:media/MidiAudioPlayer.MidiAudioPlayer#startedNotes
743
- * @type {function[]} */
744
- startedNotes: [],
745
- });
746
-
747
- /**
748
- * The {@link external:AudioContext} used by this MIDI player.
749
- * @type {external:AudioContext}
750
- */
751
- MidiAudioPlayer.audioContext = null;
752
-
753
- /**
754
- * The "Instrument" object used by this MIDI player.
755
- * See: https://github.com/danigb/soundfont-player
756
- * @type {external:Instrument}
757
- */
758
- MidiAudioPlayer.instrument = null;
759
-
760
- /**
761
- * A flag used to avoid re-entrant calls to {@link module:media/MidiAudioPlayer.MidiAudioPlayer#prepareInstrument prepareInstrument}
762
- * @type {boolean}
763
- */
764
- MidiAudioPlayer.loadingInstrument = false;
765
-
766
- /**
767
- * An object containing the full soundfont data used by {@link module:media/MidiAudioPlayer.MidiAudioPlayer#instrument instrument}
768
- * When this member is set, no other settings related to the sounfFont will be used.
769
- * This value can be overwritten by the global parameter `MIDISoundFontObject`
770
- * @type {object}
771
- */
772
- MidiAudioPlayer.MIDISoundFontObject = null;
773
-
774
- /**
775
- * The URL used as base for the current collection of MIDI soundfonts.
776
- * This value can be overwritten by the global parameter `MIDISoundFontBase`
777
- * @type {string}
778
- */
779
- MidiAudioPlayer.MIDISoundFontBase = 'https://clic.xtec.cat/dist/jclic.js/soundfonts/MusyngKite';
780
- // Alternative sites are:
781
- // 'https://clic.xtec.cat/dist/jclic.js/soundfonts/FluidR3_GM'
782
- // 'https://raw.githubusercontent.com/gleitz/midi-js-soundfonts/gh-pages/FluidR3_GM'
783
- // 'https://raw.githubusercontent.com/gleitz/midi-js-soundfonts/gh-pages/MusyngKite'
784
-
785
- /**
786
- * The MIDI instrument name.
787
- * This value can be overwritten by the global parameter `MIDISoundFontName`
788
- * See [MIDI.js Soundfonts](https://github.com/gleitz/midi-js-soundfonts) for full lists of MIDI instrument names.
789
- * @type {string}
790
- */
791
- MidiAudioPlayer.MIDISoundFontName = 'acoustic_grand_piano';
792
-
793
- /**
794
- * An extension to be added to `MIDISoundFontName` in order to build the full file name of the soundfont JS file.
795
- * Current valid options are `-mp3.js` and `-ogg.js`
796
- * This value can be overwritten by the global parameter `MIDISoundFontExtension`
797
- * @type {string}
798
- */
799
- MidiAudioPlayer.MIDISoundFontExtension = '-mp3.js';
800
-
801
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MidiAudioPlayer);
802
-
803
-
804
- /***/ })
805
-
806
- };
807
- ;
808
- //# sourceMappingURL=1196.jclic-node.js.map