jclic 2.1.21 → 2.1.22

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 (173) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/jclic-node.js +1 -1
  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 +1 -1
  7. package/src/GlobalData.js +1 -1
  8. package/dist/1078.jclic-node.js +0 -282
  9. package/dist/1078.jclic-node.js.map +0 -1
  10. package/dist/1196.jclic-node.js +0 -808
  11. package/dist/1196.jclic-node.js.map +0 -1
  12. package/dist/1253.jclic-node.js +0 -1432
  13. package/dist/1253.jclic-node.js.map +0 -1
  14. package/dist/13.jclic-node.js +0 -103
  15. package/dist/13.jclic-node.js.map +0 -1
  16. package/dist/1567.jclic-node.js +0 -2313
  17. package/dist/1567.jclic-node.js.map +0 -1
  18. package/dist/1588.jclic-node.js +0 -602
  19. package/dist/1588.jclic-node.js.map +0 -1
  20. package/dist/1725.jclic-node.js +0 -836
  21. package/dist/1725.jclic-node.js.map +0 -1
  22. package/dist/1731.jclic-node.js +0 -438
  23. package/dist/1731.jclic-node.js.map +0 -1
  24. package/dist/1842.jclic-node.js +0 -651
  25. package/dist/1842.jclic-node.js.map +0 -1
  26. package/dist/2160.jclic-node.js +0 -1016
  27. package/dist/2160.jclic-node.js.map +0 -1
  28. package/dist/222.jclic-node.js +0 -129
  29. package/dist/222.jclic-node.js.map +0 -1
  30. package/dist/2316.jclic-node.js +0 -949
  31. package/dist/2316.jclic-node.js.map +0 -1
  32. package/dist/2355.jclic-node.js +0 -371
  33. package/dist/2355.jclic-node.js.map +0 -1
  34. package/dist/2366.jclic-node.js +0 -431
  35. package/dist/2366.jclic-node.js.map +0 -1
  36. package/dist/2379.jclic-node.js +0 -202
  37. package/dist/2379.jclic-node.js.map +0 -1
  38. package/dist/2437.jclic-node.js +0 -450
  39. package/dist/2437.jclic-node.js.map +0 -1
  40. package/dist/2531.jclic-node.js +0 -869
  41. package/dist/2531.jclic-node.js.map +0 -1
  42. package/dist/2608.jclic-node.js +0 -160
  43. package/dist/2608.jclic-node.js.map +0 -1
  44. package/dist/2715.jclic-node.js +0 -554
  45. package/dist/2715.jclic-node.js.map +0 -1
  46. package/dist/277.jclic-node.js +0 -22
  47. package/dist/277.jclic-node.js.map +0 -1
  48. package/dist/2921.jclic-node.js +0 -660
  49. package/dist/2921.jclic-node.js.map +0 -1
  50. package/dist/2952.jclic-node.js +0 -101
  51. package/dist/2952.jclic-node.js.map +0 -1
  52. package/dist/3018.jclic-node.js +0 -421
  53. package/dist/3018.jclic-node.js.map +0 -1
  54. package/dist/3019.jclic-node.js +0 -682
  55. package/dist/3019.jclic-node.js.map +0 -1
  56. package/dist/3231.jclic-node.js +0 -274
  57. package/dist/3231.jclic-node.js.map +0 -1
  58. package/dist/331.jclic-node.js +0 -115
  59. package/dist/331.jclic-node.js.map +0 -1
  60. package/dist/3391.jclic-node.js +0 -276
  61. package/dist/3391.jclic-node.js.map +0 -1
  62. package/dist/3502.jclic-node.js +0 -671
  63. package/dist/3502.jclic-node.js.map +0 -1
  64. package/dist/3653.jclic-node.js +0 -982
  65. package/dist/3653.jclic-node.js.map +0 -1
  66. package/dist/371.jclic.min.js +0 -2
  67. package/dist/371.jclic.min.js.map +0 -1
  68. package/dist/3856.jclic-node.js +0 -575
  69. package/dist/3856.jclic-node.js.map +0 -1
  70. package/dist/4112.jclic-node.js +0 -659
  71. package/dist/4112.jclic-node.js.map +0 -1
  72. package/dist/4123.jclic-node.js +0 -910
  73. package/dist/4123.jclic-node.js.map +0 -1
  74. package/dist/427.jclic-node.js +0 -894
  75. package/dist/427.jclic-node.js.map +0 -1
  76. package/dist/4483.jclic-node.js +0 -327
  77. package/dist/4483.jclic-node.js.map +0 -1
  78. package/dist/4548.jclic-node.js +0 -1078
  79. package/dist/4548.jclic-node.js.map +0 -1
  80. package/dist/466.jclic-node.js +0 -99
  81. package/dist/466.jclic-node.js.map +0 -1
  82. package/dist/485.jclic-node.js +0 -783
  83. package/dist/485.jclic-node.js.map +0 -1
  84. package/dist/4921.jclic-node.js +0 -500
  85. package/dist/4921.jclic-node.js.map +0 -1
  86. package/dist/5091.jclic-node.js +0 -239
  87. package/dist/5091.jclic-node.js.map +0 -1
  88. package/dist/520.jclic-node.js +0 -550
  89. package/dist/520.jclic-node.js.map +0 -1
  90. package/dist/5312.jclic-node.js +0 -1126
  91. package/dist/5312.jclic-node.js.map +0 -1
  92. package/dist/5338.jclic-node.js +0 -212
  93. package/dist/5338.jclic-node.js.map +0 -1
  94. package/dist/5344.jclic-node.js +0 -229
  95. package/dist/5344.jclic-node.js.map +0 -1
  96. package/dist/5550.jclic-node.js +0 -238
  97. package/dist/5550.jclic-node.js.map +0 -1
  98. package/dist/5626.jclic-node.js +0 -614
  99. package/dist/5626.jclic-node.js.map +0 -1
  100. package/dist/5977.jclic-node.js +0 -1081
  101. package/dist/5977.jclic-node.js.map +0 -1
  102. package/dist/6148.jclic-node.js +0 -345
  103. package/dist/6148.jclic-node.js.map +0 -1
  104. package/dist/6176.jclic-node.js +0 -481
  105. package/dist/6176.jclic-node.js.map +0 -1
  106. package/dist/6221.jclic-node.js +0 -1072
  107. package/dist/6221.jclic-node.js.map +0 -1
  108. package/dist/6238.jclic-node.js +0 -718
  109. package/dist/6238.jclic-node.js.map +0 -1
  110. package/dist/6454.jclic-node.js +0 -1413
  111. package/dist/6454.jclic-node.js.map +0 -1
  112. package/dist/6565.jclic-node.js +0 -294
  113. package/dist/6565.jclic-node.js.map +0 -1
  114. package/dist/6579.jclic-node.js +0 -719
  115. package/dist/6579.jclic-node.js.map +0 -1
  116. package/dist/6715.jclic-node.js +0 -148
  117. package/dist/6715.jclic-node.js.map +0 -1
  118. package/dist/6777.jclic-node.js +0 -171
  119. package/dist/6777.jclic-node.js.map +0 -1
  120. package/dist/6782.jclic-node.js +0 -1611
  121. package/dist/6782.jclic-node.js.map +0 -1
  122. package/dist/6847.jclic-node.js +0 -601
  123. package/dist/6847.jclic-node.js.map +0 -1
  124. package/dist/6856.jclic-node.js +0 -252
  125. package/dist/6856.jclic-node.js.map +0 -1
  126. package/dist/696.jclic-node.js +0 -1821
  127. package/dist/696.jclic-node.js.map +0 -1
  128. package/dist/698.jclic-node.js +0 -583
  129. package/dist/698.jclic-node.js.map +0 -1
  130. package/dist/704.jclic-node.js +0 -80
  131. package/dist/704.jclic-node.js.map +0 -1
  132. package/dist/7046.jclic-node.js +0 -735
  133. package/dist/7046.jclic-node.js.map +0 -1
  134. package/dist/7220.jclic-node.js +0 -156
  135. package/dist/7220.jclic-node.js.map +0 -1
  136. package/dist/7257.jclic-node.js +0 -931
  137. package/dist/7257.jclic-node.js.map +0 -1
  138. package/dist/743.jclic-node.js +0 -583
  139. package/dist/743.jclic-node.js.map +0 -1
  140. package/dist/757.jclic-node.js +0 -1072
  141. package/dist/757.jclic-node.js.map +0 -1
  142. package/dist/7781.jclic-node.js +0 -202
  143. package/dist/7781.jclic-node.js.map +0 -1
  144. package/dist/7912.jclic-node.js +0 -2103
  145. package/dist/7912.jclic-node.js.map +0 -1
  146. package/dist/827.jclic-node.js +0 -708
  147. package/dist/827.jclic-node.js.map +0 -1
  148. package/dist/8276.jclic-node.js +0 -409
  149. package/dist/8276.jclic-node.js.map +0 -1
  150. package/dist/8322.jclic-node.js +0 -498
  151. package/dist/8322.jclic-node.js.map +0 -1
  152. package/dist/8641.jclic-node.js +0 -360
  153. package/dist/8641.jclic-node.js.map +0 -1
  154. package/dist/8837.jclic-node.js +0 -651
  155. package/dist/8837.jclic-node.js.map +0 -1
  156. package/dist/8895.jclic-node.js +0 -151
  157. package/dist/8895.jclic-node.js.map +0 -1
  158. package/dist/9072.jclic-node.js +0 -1285
  159. package/dist/9072.jclic-node.js.map +0 -1
  160. package/dist/9078.jclic-node.js +0 -935
  161. package/dist/9078.jclic-node.js.map +0 -1
  162. package/dist/9103.jclic-node.js +0 -718
  163. package/dist/9103.jclic-node.js.map +0 -1
  164. package/dist/9359.jclic-node.js +0 -145
  165. package/dist/9359.jclic-node.js.map +0 -1
  166. package/dist/9409.jclic-node.js +0 -921
  167. package/dist/9409.jclic-node.js.map +0 -1
  168. package/dist/9513.jclic-node.js +0 -720
  169. package/dist/9513.jclic-node.js.map +0 -1
  170. package/dist/9704.jclic-node.js +0 -81
  171. package/dist/9704.jclic-node.js.map +0 -1
  172. package/dist/9950.jclic-node.js +0 -827
  173. package/dist/9950.jclic-node.js.map +0 -1
@@ -1,1432 +0,0 @@
1
- "use strict";
2
- exports.id = 1253;
3
- exports.ids = [1253];
4
- exports.modules = {
5
-
6
- /***/ 1253:
7
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8
-
9
- /* harmony export */ __webpack_require__.d(__webpack_exports__, {
10
- /* harmony export */ Aj: () => (/* binding */ getRelativePath),
11
- /* harmony export */ DC: () => (/* binding */ reduceTextsToStrings),
12
- /* harmony export */ DT: () => (/* binding */ getBasePath),
13
- /* harmony export */ DV: () => (/* binding */ parseOldDate),
14
- /* harmony export */ EB: () => (/* binding */ getHMStime),
15
- /* harmony export */ Fy: () => (/* binding */ parseXmlNode),
16
- /* harmony export */ GB: () => (/* binding */ roundTo),
17
- /* harmony export */ GM: () => (/* binding */ attrForEach),
18
- /* harmony export */ GV: () => (/* binding */ $HTML),
19
- /* harmony export */ HC: () => (/* binding */ getXmlText),
20
- /* harmony export */ HR: () => (/* binding */ getImgClipUrl),
21
- /* harmony export */ H_: () => (/* binding */ getXmlNodeText),
22
- /* harmony export */ Hb: () => (/* binding */ getCaretCharacterOffsetWithin),
23
- /* harmony export */ He: () => (/* binding */ setLogLevel),
24
- /* harmony export */ I4: () => (/* binding */ checkColor),
25
- /* harmony export */ Im: () => (/* binding */ isEmpty),
26
- /* harmony export */ Mk: () => (/* binding */ stringToWords),
27
- /* harmony export */ NQ: () => (/* binding */ getRootHead),
28
- /* harmony export */ Os: () => (/* binding */ getPercent),
29
- /* harmony export */ PD: () => (/* binding */ getTriState),
30
- /* harmony export */ Pj: () => (/* binding */ isNullOrUndef),
31
- /* harmony export */ Rm: () => (/* binding */ log),
32
- /* harmony export */ SV: () => (/* binding */ toCssSize),
33
- /* harmony export */ TQ: () => (/* binding */ findParentsWithChild),
34
- /* harmony export */ Ts: () => (/* binding */ init),
35
- /* harmony export */ UM: () => (/* binding */ compareMultipleOptions),
36
- /* harmony export */ W0: () => (/* binding */ settings),
37
- /* harmony export */ WZ: () => (/* binding */ getNumber),
38
- /* harmony export */ Yn: () => (/* binding */ getPath),
39
- /* harmony export */ bG: () => (/* binding */ cleanOldLanguageTag),
40
- /* harmony export */ c0: () => (/* binding */ colorHasTransparency),
41
- /* harmony export */ c4: () => (/* binding */ nSlash),
42
- /* harmony export */ d5: () => (/* binding */ endsWith),
43
- /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
44
- /* harmony export */ dw: () => (/* binding */ appendStyleAtHead),
45
- /* harmony export */ eG: () => (/* binding */ setSelectionRange),
46
- /* harmony export */ eH: () => (/* binding */ getVal),
47
- /* harmony export */ fx: () => (/* binding */ fx),
48
- /* harmony export */ g8: () => (/* binding */ svgToURI),
49
- /* harmony export */ h2: () => (/* binding */ cloneObject),
50
- /* harmony export */ iu: () => (/* binding */ getAttr),
51
- /* harmony export */ k$: () => (/* binding */ isSeparator),
52
- /* harmony export */ l2: () => (/* binding */ isEquivalent),
53
- /* harmony export */ ob: () => (/* binding */ setAttr),
54
- /* harmony export */ pW: () => (/* binding */ getBoolean),
55
- /* harmony export */ qG: () => (/* binding */ getMsg),
56
- /* harmony export */ qN: () => (/* binding */ DEFAULT),
57
- /* harmony export */ r4: () => (/* binding */ getSvg),
58
- /* harmony export */ vD: () => (/* binding */ fillString),
59
- /* harmony export */ w1: () => (/* binding */ startsWith),
60
- /* harmony export */ wF: () => (/* binding */ mReplace),
61
- /* harmony export */ xw: () => (/* binding */ getPathPromise)
62
- /* harmony export */ });
63
- /* unused harmony exports pkg, LOG_LEVELS, LOG_PRINT_LABELS, LOG_OPTIONS, normalizeLocale, checkPreferredLanguage, zp, getDateTime, FALSE, TRUE, cssToString, normalizeObject, getValue, buildObj, isWordDelimiter, isURL, getTextNodesIn, Utils */
64
- /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7750);
65
- /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
66
- /* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8194);
67
- /* harmony import */ var jszip__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(jszip__WEBPACK_IMPORTED_MODULE_1__);
68
- /* harmony import */ var jszip_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6402);
69
- /* harmony import */ var jszip_utils__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(jszip_utils__WEBPACK_IMPORTED_MODULE_2__);
70
- /* harmony import */ var _GlobalData_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(277);
71
- /**
72
- * File : Utils.js
73
- * Created : 01/04/2015
74
- * By : Francesc Busquets <francesc@gmail.com>
75
- *
76
- * JClic.js
77
- * An HTML5 player of JClic activities
78
- * https://projectestac.github.io/jclic.js
79
- *
80
- * @source https://github.com/projectestac/jclic.js
81
- *
82
- * @license EUPL-1.2
83
- * @licstart
84
- * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
85
- *
86
- * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
87
- * the European Commission- subsequent versions of the EUPL (the "Licence");
88
- * You may not use this work except in compliance with the Licence.
89
- *
90
- * You may obtain a copy of the Licence at:
91
- * https://joinup.ec.europa.eu/software/page/eupl
92
- *
93
- * Unless required by applicable law or agreed to in writing, software
94
- * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
95
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
96
- * Licence for the specific language governing permissions and limitations
97
- * under the Licence.
98
- * @licend
99
- * @module
100
- */
101
-
102
- /* global Promise, window, document, console, HTMLElement */
103
-
104
-
105
-
106
-
107
-
108
-
109
- /**
110
- * Exports third-party NPM packages used by JClic, so they become available to other scripts through
111
- * the global variable `JClicObject` (defined in {@link module:JClic.JClic})
112
- * @type: {object}
113
- */
114
- const pkg = {
115
- $: (jquery__WEBPACK_IMPORTED_MODULE_0___default()),
116
- JSZip: (jszip__WEBPACK_IMPORTED_MODULE_1___default()),
117
- JSZipUtils: (jszip_utils__WEBPACK_IMPORTED_MODULE_2___default()),
118
- };
119
-
120
- /**
121
- * List of valid verbosity levels
122
- * @const {string[]}
123
- */
124
- const LOG_LEVELS = ['none', 'error', 'warn', 'info', 'debug', 'trace', 'all'];
125
-
126
- /**
127
- * Labels printed on logs for each message type
128
- * @const {string[]}
129
- */
130
- const LOG_PRINT_LABELS = [' ', 'ERROR', 'WARN ', 'INFO ', 'DEBUG', 'TRACE', 'ALL '];
131
-
132
- /**
133
- * Options of the logging system
134
- * @type {object} */
135
- const LOG_OPTIONS = {
136
- level: 2, // warn
137
- prefix: 'JClic',
138
- timestamp: true,
139
- popupOnErrors: false,
140
- chainTo: null,
141
- pipeTo: null,
142
- };
143
-
144
- /**
145
- * Current dictionary of string translations
146
- */
147
- let _messages = {};
148
-
149
- /**
150
- * Initializes the global settings
151
- * @param {object} options - An object with global settings
152
- * @param {boolean} [setLog=true] - When `true`, the log level will be set
153
- * @param {boolean} [setLang=true] - When `true`, the current language will be set
154
- * @returns {object} The normalized `options` object
155
- */
156
- function init(options, setLog = true, setLang = true) {
157
- options = normalizeObject(options);
158
- if (setLog) {
159
- if (typeof options.logLevel !== 'undefined')
160
- setLogLevel(options.logLevel);
161
- if (typeof options.chainLogTo === 'function')
162
- LOG_OPTIONS.chainTo = options.chainLogTo;
163
- if (typeof options.pipeLogTo === 'function')
164
- LOG_OPTIONS.pipeTo = options.pipeLogTo;
165
- }
166
-
167
- if (setLang) {
168
- const lngRequested = options.lang;
169
- const lng = checkPreferredLanguage(_GlobalData_js__WEBPACK_IMPORTED_MODULE_3__["default"].languages, 'en', lngRequested);
170
- log('debug', `Language ${lngRequested ? `requested: "${lngRequested}" ` : ''} used: "${lng}"`);
171
- _messages = lng === 'en' ? {} : _GlobalData_js__WEBPACK_IMPORTED_MODULE_3__["default"].messages[lng];
172
- }
173
-
174
- return options;
175
- };
176
-
177
- /**
178
- * Function that will return the translation of the provided key
179
- * into the current language.
180
- * @param {string} key - ID of the expression to be translated
181
- * @returns {string} - The translated text
182
- */
183
- function getMsg(key) {
184
- return _messages[key] || key;
185
- }
186
-
187
- /**
188
- * Converts expressions of type 'pt-br', 'FR', 'ca_es@valencia'... to the format expected by the i18n system:
189
- * lc[_CC][@variant] where 'lc' is a two or three lowercase letter language code, CC is an optional two uppercase
190
- * letter country code, followed by an optional 'variant' consisting in letters and/or digits.
191
- * @param {string} locale - The locale expression to be normalized
192
- * @returns string - The normalized locale
193
- */
194
- function normalizeLocale(locale = '') {
195
- const [, language = null, country = null, variant = null] = /^([a-zA-Z]{2,3})[_-]?([a-zA-Z]{2})?@?([a-zA-Z0-9]*)?$/.exec(locale.trim()) || [];
196
- return language
197
- ? `${language.toLowerCase()}${country ? `_${country.toUpperCase()}` : ''}${variant ? `@${variant.toLowerCase()}` : ''}`
198
- : '';
199
- };
200
-
201
- /**
202
- * Checks if the language preferred by the user (based on browser and/or specific settings)
203
- * is in a list of available languages.
204
- * @param {string[]} availableLangs - Array of available languages. It should contain at least one item.
205
- * @param {string} [defaultLang=en] - Language to be used by default when not found the selected one
206
- * @param {string} [requestedLang=''] - Request this specific language
207
- * @returns {string} - The most suitable language for this request
208
- */
209
- function checkPreferredLanguage(availableLangs, defaultLang = 'en', requestedLang = '') {
210
- let result = -1;
211
-
212
- // Create an array to store possible values
213
- let tries = [];
214
-
215
- // If "setLang" is specified, check it
216
- if (requestedLang) {
217
- // Normalize requested locale
218
- const lang = normalizeLocale(requestedLang);
219
- if (lang)
220
- tries.push(lang);
221
- }
222
-
223
- // Add user's preferred languages, if any
224
- if (window.navigator.languages)
225
- tries = tries.concat(window.navigator.languages);
226
-
227
- // Add the navigator main language, if defined
228
- if (window.navigator.language)
229
- tries.push(window.navigator.language);
230
-
231
- // Add English as final option
232
- tries.push(defaultLang);
233
-
234
- for (let i = 0; i < tries.length; i++) {
235
- let match = -1;
236
- for (let n in availableLangs) {
237
- if (tries[i].indexOf(availableLangs[n]) === 0) {
238
- match = n;
239
- if (tries[i] === availableLangs[n]) {
240
- result = n;
241
- break;
242
- }
243
- }
244
- }
245
- if (result >= 0 || (result = match) >= 0)
246
- break;
247
- }
248
- return availableLangs[result >= 0 ? result : 0];
249
- };
250
-
251
- /**
252
- * Establishes the current verbosity level of the logging system
253
- * @param {string} level - One of the valid strings in {@link module:Utils.LOG_LEVELS}
254
- */
255
- function setLogLevel(level) {
256
- const log = LOG_LEVELS.indexOf(level);
257
- if (log >= 0)
258
- LOG_OPTIONS.level = log;
259
- };
260
-
261
- /**
262
- * Reports a new message to the logging system
263
- * @param {string} type - The type of message. Mus be `error`, `warn`, `info`, `debug` or `trace`.
264
- * @param {string} msg - The main message to be logged. Additional parameters can be added, like
265
- * in `console.log` (see: {@link https://developer.mozilla.org/en-US/docs/Web/API/Console/log})
266
- */
267
- function log(type, msg) {
268
- const level = LOG_LEVELS.indexOf(type);
269
- const args = Array.prototype.slice.call(arguments);
270
-
271
- // Check if message should currently be logged
272
- if (level < 0 || level <= LOG_OPTIONS.level) {
273
- if (LOG_OPTIONS.pipeTo)
274
- LOG_OPTIONS.pipeTo.apply(null, args);
275
- else {
276
- const mainMsg = `${LOG_OPTIONS.prefix || ''} ${LOG_PRINT_LABELS[level]} ${LOG_OPTIONS.timestamp ? getDateTime() : ''} ${msg}`;
277
- console[level === 1 ? 'error' : level === 2 ? 'warn' : 'log'].apply(console, [mainMsg].concat(args.slice(2)));
278
- // Call chained logger, if anny
279
- if (LOG_OPTIONS.chainTo)
280
- LOG_OPTIONS.chainTo.apply(null, args);
281
- }
282
- }
283
- };
284
-
285
- /**
286
- * Gets a boolean value from a textual expression
287
- * @param {string} val - The value to be parsed (`true` for true, null or otherwise for `false`)
288
- * @param {boolean} [defaultValue=false] - The default value to return when `val` is false
289
- * @returns {number}
290
- */
291
- function getBoolean(val, defaultValue = false) {
292
- return val === 'true' ? true : val === 'false' ? false : defaultValue;
293
- };
294
-
295
- /**
296
- * Gets a value from an given expression that can be `null`, `undefined` or empty string ('')
297
- * @param {any} val - The expression to parse
298
- * @param {any} [defaultValue=null] - The value to return when `val` is `null`, `''` or `undefined`
299
- * @returns {any}
300
- */
301
- function getVal(val, defaultValue = null) {
302
- return (val === '' || val === null || typeof val === 'undefined') ? defaultValue : val;
303
- };
304
-
305
- /**
306
- * Gets a number from a string or another number
307
- * @param {any} val - The expression to parse
308
- * @param {number} [defaultValue=0] - The default value
309
- * @returns {number}
310
- */
311
- function getNumber(val, defaultValue) {
312
- return Number(getVal(val, defaultValue));
313
- };
314
-
315
- /**
316
- * Gets the plain percent expression (without decimals) of the given value
317
- * @param {number} val - The value to be expressed as a percentile
318
- * @returns {string}
319
- */
320
- function getPercent(val) {
321
- return `${Math.round(val * 100)}%`;
322
- }
323
-
324
- /**
325
- * Returns the two-digits text expression representing the given number (lesser than 100) zero-padded at left
326
- * Useful for representing hours, minutes and seconds
327
- * @param {number} val - The number to be processed
328
- * @returns {string}
329
- */
330
- function zp(val) {
331
- return `0${val}`.slice(-2);
332
- };
333
-
334
- /**
335
- * Returns a given time in [00h 00'00"] format
336
- * @param {number} millis - Amount of milliseconds to be processed
337
- * @returns {string}
338
- */
339
- function getHMStime(millis) {
340
- const d = new Date(millis);
341
- const h = d.getUTCHours(), m = d.getUTCMinutes(), s = d.getUTCSeconds();
342
- return `${h ? h + 'h ' : ''}${h || m ? zp(m) + '\'' : ''}${zp(s)}"`;
343
- };
344
-
345
- /**
346
- * Returns a formatted string with the provided date and time
347
- * @param {external:Date} date - The date to be formatted. When `null` or `undefined`, the current date will be used.
348
- * @returns {string}
349
- */
350
- function getDateTime(date = new Date()) {
351
- return `${date.getFullYear()}/${zp(date.getMonth() + 1)}/${zp(date.getDate())} ${zp(date.getHours())}:${zp(date.getMinutes())}:${zp(date.getSeconds())}`;
352
- };
353
-
354
- /**
355
- * Parse 'date' fields generated by "JClic Author" in format d/m/y, with
356
- * variable number of digits.
357
- * @param {string} text - The old 'date' field
358
- * @returns {external:Date} - Always return a Date object (now, if text was invalid)
359
- */
360
- function parseOldDate(text) {
361
- let result = null;
362
- if (text) {
363
- const elements = text.trim().split('/');
364
- if (elements.length === 3) {
365
- let m = parseInt(elements[0]) || 0;
366
- let d = parseInt(elements[1]) || 0;
367
- let y = parseInt(elements[2]) || 0;
368
- if (m > 12 && d <= 12) {
369
- const t = m;
370
- m = d;
371
- d = t;
372
- }
373
- if (y < 1980)
374
- y += (y < 90 ? 2000 : 1900);
375
- if (d && m && y) {
376
- result = new Date(Date.parse(`${m}/${d}/${y}`));
377
- }
378
- }
379
- }
380
- return result || new Date();
381
- };
382
-
383
- /**
384
- * Extracts just the ISO-639 language code from complex
385
- * expressions like "English (en)", buid by JClic Author.
386
- * @param {string} text - The expression to parse
387
- * @returns {string} - The ISO-639 language code, or '--' if none found
388
- */
389
- function cleanOldLanguageTag(text) {
390
- if (!text)
391
- text = '--';
392
- // Allow only ISO-639-1 and ISO-639-2 language codes
393
- else if (!text.match(/^[a-z][a-z][a-z]?$/)) {
394
- const matches = text.match(/\(([a-z][a-z][a-z]?)\)/);
395
- if (matches && matches.length === 2)
396
- text = matches[1];
397
- else
398
- text = '--';
399
- }
400
- return text;
401
- };
402
-
403
- /** @const {number} */
404
- const FALSE = 0;
405
-
406
- /** @const {number} */
407
- const TRUE = 1;
408
-
409
- /** @const {number} */
410
- const DEFAULT = 2;
411
-
412
- /**
413
- * Gets a numeric value (0, 1 or 2) from a set of possible values: `false`, `true` and `default`.
414
- * @param {string} val - The text to be parsed
415
- * @param {any} def - An optional default value
416
- * @returns {number}
417
- */
418
- function getTriState(val, def = DEFAULT) {
419
- return val === 'true' ? TRUE : val === 'false' ? FALSE : def;
420
- };
421
-
422
- /**
423
- * Returns a string with the given `tag` repeated n times
424
- * @param {string} tag - The tag to be repeated
425
- * @param {number} repeats - The number of times to repeat the tag
426
- * @returns {string}
427
- */
428
- function fillString(tag, repeats = 0) {
429
- return Array(repeats).fill(tag).join('');
430
- };
431
-
432
- /**
433
- * Checks if the provided value is 'null' or 'undefined'.
434
- * @param {any} val - The value to be parsed
435
- * @returns {boolean}
436
- */
437
- function isNullOrUndef(val) {
438
- return typeof val === 'undefined' || val === null;
439
- };
440
-
441
- /**
442
- * Checks if two expressions are equivalent.
443
- * Returns `true` when both parameters are `null` or `undefined`, and also when both have
444
- * equivalent values.
445
- * @param {any} a
446
- * @param {any} b
447
- * @returns {boolean}
448
- */
449
- function isEquivalent(a, b) {
450
- return (typeof a === 'undefined' || a === null) && (typeof b === 'undefined' || b === null) || a === b;
451
- };
452
-
453
- /**
454
- * Reads paragraphs, identified by `<p></p>` elements, inside XML data
455
- * @param {object} xml - The DOM-XML element to be parsed
456
- * @returns {string}
457
- */
458
- function getXmlText(xml) {
459
- let text = '';
460
- jquery__WEBPACK_IMPORTED_MODULE_0___default()(xml).children('p').each((_n, child) => { text += `<p>${child.textContent}</p>`; });
461
- return text;
462
- };
463
-
464
- /**
465
- * Parse the provided XML element node, returning a complex object
466
- * @param {object} xml - The root XML element to parse
467
- * @param {boolean} [withText=false] - When `true`, any text found inside the XML element is also included in the resulting object.
468
- * @returns {object}
469
- */
470
- function parseXmlNode(xml, withText = false) {
471
- // Initialize the resulting object
472
- const result = {};
473
- // Direct copy of root element attributes as object properties
474
- if (xml.attributes)
475
- attrForEach(xml.attributes, (name, value) => result[name] = /^-?\d*$/.test(value) ? Number(value) : value);
476
-
477
- const keys = [];
478
- const children = Array.from(xml.children || xml.childNodes || []);
479
-
480
- // If all children is of type 'p', just compile it in a single string
481
- const paragraphs = children.filter(child => child.nodeName === 'p');
482
- if (paragraphs.length > 0 && paragraphs.length === children.filter(ch => ch.nodeName !== '#text').length) {
483
- const text = paragraphs.map(ch => ch.textContent).join('\n');
484
- if (xml.attributes) {
485
- result.text = text;
486
- return result;
487
- }
488
- return text;
489
- }
490
-
491
- // Process children elements
492
- children.forEach(child => {
493
- // Avoid extra text content collected by [xmldom](https://www.npmjs.com/package/xmldom)
494
- if (child.nodeName === '#text' && !withText)
495
- return;
496
-
497
- // Recursive processing of children
498
- const ch = parseXmlNode(child, withText);
499
- // Store the result into a temporary object named as the child node name,
500
- if (!result[child.nodeName]) {
501
- // Create object and save key for later processing
502
- result[child.nodeName] = {};
503
- keys.push(child.nodeName);
504
- }
505
- // Use 'id' (or an incremental number if 'id' is not set) as a key
506
- if (ch.id)
507
- result[child.nodeName][ch.id] = ch;
508
- else {
509
- const n = Object.keys(result[child.nodeName]).length;
510
- result[child.nodeName][n] = ch;
511
- }
512
- });
513
- // Check temporary objects, converting it to an array, a single object or a complex object
514
- keys.forEach(k => {
515
- // Retrieve temporary object from `keys`
516
- const kx = Object.keys(result[k]);
517
- // If all keys are numbers, convert object into an array (or leave it as a single object)
518
- if (!kx.find(kk => isNaN(kk))) {
519
- if (kx.length === 1)
520
- // Array with a single element. Leave it as a simple object:
521
- result[k] = result[k][0];
522
- else {
523
- // Object with numeric keys. Convert it to array:
524
- const arr = [];
525
- kx.forEach(kk => arr.push(result[k][kk]));
526
- result[k] = arr;
527
- }
528
- }
529
- });
530
- // Save text content, if any:
531
- if (children.length === 0 && xml.textContent)
532
- result.textContent = xml.textContent;
533
- return result;
534
- };
535
-
536
- /**
537
- * Parse the given XML node, known as containing only text elements,
538
- * and return its content as a string (when possible)
539
- * @param {object} xml - The XML element to parse
540
- * @returns {string|object}
541
- */
542
- function getXmlNodeText(node) {
543
- const result = parseXmlNode(node);
544
- return typeof result === 'string' ?
545
- result :
546
- result.hasOwnProperty('text') ?
547
- result.text :
548
- result.hasOwnProperty('textContent') ?
549
- result.textContent :
550
- result;
551
- };
552
-
553
- /**
554
- * Recursively explore the given object, converting to a string
555
- * all attributes with a single attribute named 'text'.
556
- * Example:
557
- * {a:1, b:{text:"hello"}, c:{d:2, text:"world"}} => {a:1, b:"hello", c:{d:2, text:"world"}}
558
- * @param {object} obj - The object to explore
559
- * @returns {object} - The same object, with text attributes reduced to strings
560
- */
561
- function reduceTextsToStrings(obj) {
562
- if (obj) {
563
- const keys = Object.keys(obj);
564
- keys.forEach(k => {
565
- const attr = obj[k];
566
- if (typeof attr === 'object') {
567
- const ko = Object.keys(attr);
568
- if (ko.length === 1 && ko[0] === 'text')
569
- obj[k] = attr.text;
570
- else
571
- obj[k] = reduceTextsToStrings(attr);
572
- }
573
- });
574
- }
575
- return obj;
576
- };
577
-
578
- /**
579
- * Creates a string suitable to be used in the 'style' attribute of HTML tags, filled with the
580
- * CSS attributes contained in the provided object.
581
- * @param {object} cssObj
582
- * @returns {string}
583
- */
584
- function cssToString(cssObj) {
585
- return Object.keys(cssObj).reduce((s, key) => `${s}${key}:${cssObj[key]};`, '');
586
- };
587
-
588
- /**
589
- * Converts java-like color codes (like '0xRRGGBB') to valid CSS values like '#RRGGBB' or 'rgba(r,g,b,a)'
590
- * @param {string} [color] - A color, as codified in Java
591
- * @param {string} [defaultColor] - The default color to be used
592
- * @returns {string}
593
- */
594
- function checkColor(color, defaultColor = settings.BoxBase.BACK_COLOR) {
595
- if (typeof color === 'undefined' || color === null)
596
- color = defaultColor;
597
- color = color.replace('0x', '#');
598
- // Check for Alpha value
599
- if (color.charAt(0) === '#' && color.length > 7) {
600
- const alpha = fx(parseInt(color.substring(1, 3), 16) / 255.0, 2);
601
- color = `rgba(${parseInt(color.substring(3, 5), 16)},${parseInt(color.substring(5, 7), 16)},${parseInt(color.substring(7, 9), 16)},${alpha})`;
602
- }
603
- return color;
604
- };
605
-
606
- /**
607
- * Checks if the provided color has an alpha value less than 1
608
- * @param {string} color - The color to be analyzed
609
- * @returns {boolean}
610
- */
611
- function colorHasTransparency(color) {
612
- if (startsWith(color, 'rgba(')) {
613
- var alpha = parseInt(color.substring(color.lastIndexOf(',')));
614
- return typeof alpha === 'number' && alpha < 1.0;
615
- }
616
- return false;
617
- };
618
-
619
- /**
620
- * Clones the provided object
621
- * See: https://stackoverflow.com/questions/41474986/how-to-clone-a-javascript-es6-class-instance
622
- * @param {object} obj
623
- * @returns {object}
624
- */
625
- //cloneObject: obj => Object.assign(Object.create(Object.getPrototypeOf(obj)), obj),
626
- function cloneObject(obj) {
627
- return jquery__WEBPACK_IMPORTED_MODULE_0___default().extend(true, Object.create(Object.getPrototypeOf(obj)), obj);
628
- };
629
-
630
- /**
631
- * Converts string values to number or boolean when needed
632
- * @param {object} obj - The object to be processed
633
- * @returns {object} - A new object with normalized content
634
- */
635
- function normalizeObject(obj) {
636
- const result = {};
637
- if (obj)
638
- jquery__WEBPACK_IMPORTED_MODULE_0___default().each(obj, (key, value) => {
639
- let s;
640
- if (typeof value === 'string' && (s = value.trim().toLowerCase()) !== '')
641
- value = s === 'true' ? true : s === 'false' ? false : isNaN(s) ? value : Number(s);
642
- result[key] = value;
643
- });
644
- return result;
645
- };
646
-
647
- /**
648
- * Returns an partial clone of an object, containing only the own attributes specified in an array of possible keys.
649
- * When the value of an attribute is of type 'Object' and this object has a method named `getAttributes`, the result of calling
650
- * this method is returned instead of the crude object.
651
- * @param {object} obj - The object to be processed
652
- * @param {string[]} [keys] - An optional array of keys to be included in the resulting object.
653
- * When null or not set, all keys of `obj` are included. Keys can include a default value separed by '|'.
654
- * Attributes with default value will be excluded from the resulting object.
655
- * @returns {object}
656
- */
657
- function getAttr(obj, keys = null) {
658
- let result = {};
659
- keys = keys || Object.keys(obj);
660
- keys.forEach(key => {
661
- const [k, d] = key.split('|');
662
- if (obj.hasOwnProperty(k) && typeof obj[k] !== 'undefined' && obj[k] !== null && obj[k].toString() !== d) {
663
- const v = getValue(obj[k]);
664
- if (!isEmpty(v))
665
- result[k] = v;
666
- }
667
- });
668
-
669
- // Convert to string objects with only a "text" attribute
670
- keys = Object.keys(result);
671
- if (keys.length === 1 && keys[0] === 'text')
672
- result = result.text;
673
-
674
- return result;
675
- };
676
-
677
- /**
678
- * Gets the minimal representation of the given value (object, array, string, number...)
679
- * @param {any} value - The value to be processed
680
- * @returns {any}
681
- */
682
- function getValue(value) {
683
- return value.getAttributes ?
684
- value.getAttributes() :
685
- value instanceof Array ?
686
- value.map(e => getValue(e)) :
687
- value instanceof Date ?
688
- value.toISOString() :
689
- value instanceof Object ?
690
- getAttr(value) :
691
- value;
692
- };
693
-
694
- /**
695
- * Checks if the given value is an empty object, null or a zero-length string
696
- * @param {any} v - The value to be checked
697
- * @returns {boolean} - `true` if `v` is `{}`, `null` or `""`
698
- */
699
- function isEmpty(v) {
700
- let result = (typeof v === 'undefined' || v === null);
701
- if (!result) {
702
- switch (typeof v) {
703
- case 'object':
704
- result = Object.keys(v).length === 0;
705
- break;
706
-
707
- case 'string':
708
- result = v.length === 0;
709
- break;
710
- }
711
- }
712
- return result;
713
- };
714
-
715
- /**
716
- * Fills an object with specific attributes from another data object
717
- * @param {object} obj - The target object
718
- * @param {object} data - The data object
719
- * @param {string[]} attr - The list of attributes to be copied from `data` to `obj`
720
- * Elements of this list can be:
721
- * a) Just a string. In this case, the native object will be used as a value
722
- * b) An object with the following members:
723
- * - `key`{string} - The attribute name
724
- * - `fn` {function} - The function to be invoked to build the object
725
- * - `params` {string[]} - Optional params to be passed to the `setAttributes` method of the created object
726
- * - `group` {string} - Used when `data` is an object or an array (possible values are `object` and `array`), and multiple results
727
- * should be aggregated in a resulting object or array with the same keys (or ordering) as data.
728
- * - `init` {string} - Optional parameter indicating if `fn` should be passed with an additional param. This param can be:
729
- * - `key` - The member's key
730
- *
731
- * @returns {object} - Always returns `obj`
732
- */
733
- function setAttr(obj, data, attr) {
734
- attr.forEach(a => {
735
- if (a.key) {
736
- const { key, fn, group, init, params } = a;
737
- // A new object should be built
738
- if (!isEmpty(data[key])) {
739
- const dataset = data[key];
740
- if (group === 'object')
741
- obj[key] = Object.keys(dataset).reduce((o, k) => {
742
- o[k] = buildObj(fn, dataset[k], init === 'key' ? k : init, params);
743
- return o;
744
- }, {});
745
- else if (group === 'array')
746
- obj[key] = dataset.map((element, n) => buildObj(fn, element, init === 'key' ? n : init, params));
747
- else
748
- obj[key] = buildObj(fn, dataset, init, params);
749
- }
750
- } else if (!isEmpty(data[a]))
751
- obj[a] = data[a];
752
- });
753
- return obj;
754
- };
755
-
756
- /**
757
- * Builds a new object based on the provided constructor, data and initialization value
758
- * Objects used with this function should implement `setAttributes`, or an static method named `factory`
759
- * @param {function} objType - A class or function to be invoked to build the object.
760
- * @param {object} [data] - An optional object filled with the attributes to be assigned to the newly created object.
761
- * @param {any} [init] - An optional value to be passed to the function when invoked with `new`
762
- * @param {object[]} [params=[]] - Optional array of params to be passed when calling `setAttributes` on the final object
763
- * @returns {object} - The resulting object
764
- */
765
- function buildObj(objType, data, init, params = []) {
766
- return objType.factory ? objType.factory(data, init, params) : new objType(init).setAttributes(data, ...params);
767
- };
768
-
769
- /**
770
- * Check if the given char is a separator
771
- * @param {string} ch - A string with a single character
772
- * @returns {boolean}
773
- */
774
- function isSeparator(ch) {
775
- return settings.SEPARATORS.includes(ch);
776
- };
777
-
778
- /**
779
- * Check if the given char is a word delimiter
780
- * @param {string} ch - A string with a single character
781
- * @returns {boolean}
782
- */
783
- function isWordDelimiter(ch) {
784
- return settings.WORD_DELIMITERS.includes(ch);
785
- }
786
-
787
- /**
788
- * Converts a string in an array of objects with 'text' and 'sep' attributes, where 'text' are single words and 'sep'
789
- * are the word separators following each word in the sentence.
790
- * @example
791
- * stringToWords("Hello, World! That's all") returns:
792
- * [
793
- * {text: "Hello", sep: ", "},
794
- * {text: "World", sep: "! "},
795
- * {text: "That", sep: "'"},
796
- * {text: "s", sep: " "},
797
- * {text: "all", sep: ""},
798
- * ]
799
- * @param {*} str - The text to be tokenized
800
- * @returns {object[]}
801
- */
802
- function stringToWords(str) {
803
- const result = [];
804
- let token = { text: '', sep: '' };
805
- let inWord = true;
806
- for (let i = 0; i < str.length; i++) {
807
- const ch = str.charAt(i);
808
- const delim = isWordDelimiter(ch);
809
- if (inWord) {
810
- if (!delim)
811
- token.text += ch;
812
- else {
813
- inWord = false;
814
- token.sep = ch;
815
- }
816
- } else {
817
- if (delim)
818
- token.sep += ch;
819
- else {
820
- result.push(token);
821
- token = { text: ch, sep: '' };
822
- inWord = true;
823
- }
824
- }
825
- }
826
- result.push(token);
827
- return result;
828
- }
829
-
830
- /**
831
- * Rounds `v` to the nearest multiple of `n`
832
- * @param {number} v
833
- * @param {number} n - Cannot be zero!
834
- * @returns {number}
835
- */
836
- function roundTo(v, n) {
837
- return Math.round(v / n) * n;
838
- };
839
-
840
- /**
841
- * Set the maximum number of decimals for a number
842
- * @param {any} v - The value to be converted to a fixed number of decimals. Can be anything.
843
- * @param {number} n=4 - the maximum number of decimals
844
- * @returns {any} - When `v` is a number, a number with fixed decimals is returned. Otherwise, returns `v`
845
- */
846
- function fx(v, n = 4) {
847
- return v.toFixed ? Number(v.toFixed(n)) : v;
848
- };
849
-
850
- /**
851
- * Compares the provided answer against multiple valid options. These valid options are
852
- * concatenated in a string, separated by pipe chars (`|`). The comparing can be case sensitive.
853
- * @param {string} answer - The text to check against to
854
- * @param {string} check - String containing one or multiple options, separated by `|`
855
- * @param {boolean} [checkCase=false] - When true, the comparing will be case-sensitive
856
- * @param {boolean} [numeric=false] - When true, we are comparing numeric expressions
857
- * @returns {boolean}
858
- */
859
- function compareMultipleOptions(answer, check, checkCase = false, numeric = false) {
860
- if (answer === null || answer.length === 0 || check === null || check.length === 0)
861
- return false;
862
- if (!checkCase && !numeric)
863
- answer = answer.toUpperCase();
864
- answer = answer.trim();
865
-
866
- // Check for numeric digits in answer!
867
- numeric = numeric && /\d/.test(answer);
868
-
869
- for (let token of check.split('|')) {
870
- if (numeric) {
871
- if (Number.parseFloat(answer.replace(/,/, '.')) === Number.parseFloat(token.replace(/,/, '.')))
872
- return true;
873
- }
874
- else if (answer === (checkCase ? token : token.toUpperCase()).trim())
875
- return true;
876
- }
877
- return false;
878
- };
879
-
880
- /**
881
- * Checks if the given string ends with the specified expression
882
- * @param {string} text - The string where to find the expression
883
- * @param {string} expr - The expression to search for.
884
- * @param {boolean} [trim] - When `true`, the `text` string will be trimmed before check
885
- * @returns {boolean}
886
- */
887
- function endsWith(text = '', expr, trim) {
888
- return typeof text === 'string' && (trim ? text.trim() : text).endsWith(expr);
889
- };
890
-
891
- /**
892
- * Checks if the given string starts with the specified expression
893
- * @param {string} text - The string where to find the expression
894
- * @param {string} expr - The expression to search for.
895
- * @param {boolean} [trim] - When `true`, the `text` string will be trimmed before check
896
- * @returns {boolean}
897
- */
898
- function startsWith(text = '', expr, trim) {
899
- return typeof text === 'string' && (trim ? text.trim() : text).indexOf(expr) === 0;
900
- };
901
-
902
- /**
903
- * Replaces all occurrences of the backslash character (`\`) by a regular slash (`/`)
904
- * This is useful to normalize bad path names present in some old JClic projects
905
- * @param {string} str - The string to be normalized
906
- * @returns {string}
907
- */
908
- function nSlash(str) {
909
- return str ? str.replace(/\\/g, '/') : str;
910
- };
911
-
912
- /**
913
- * Checks if the given expression is an absolute URL
914
- * @param {string} exp - The expression to be checked
915
- * @returns {boolean}
916
- */
917
- function isURL(exp) {
918
- return /^(filesystem:)?(https?|file|data|ftps?):/i.test(exp);
919
- };
920
-
921
- /**
922
- * Gets the base path of the given file path (absolute or full URL). This base path always ends
923
- * with `/`, meaning it can be concatenated with relative paths without adding a separator.
924
- * @param {string} path - The full path to be parsed
925
- * @returns {string}
926
- */
927
- function getBasePath(path) {
928
- const p = path.lastIndexOf('/');
929
- return p >= 0 ? path.substring(0, p + 1) : '';
930
- };
931
-
932
- /**
933
- * Gets the full path of `file` relative to `basePath`
934
- * @param {string} file - The file name
935
- * @param {string} [path] - The base path
936
- * @returns {string}
937
- */
938
- function getRelativePath(file, path) {
939
- return (!path || path === '' || file.indexOf(path) !== 0) ? file : file.substring(path.length);
940
- };
941
-
942
- /**
943
- * Gets the complete path of a relative or absolute URL, using the provided `basePath`
944
- * @param {string} basePath - The base URL
945
- * @param {string} path - The filename
946
- * @returns {string}
947
- */
948
- function getPath(basePath, path) {
949
- return isURL(path) ? path : basePath + path;
950
- };
951
-
952
- /**
953
- * Gets a promise with the complete path of a relative or absolute URL, using the provided `basePath`
954
- * @param {string} basePath - The base URL
955
- * @param {string} path - The filename
956
- * @param {external:JSZip} [zip] - An optional {@link external:JSZip} object where to look
957
- * for the file
958
- * @returns {external:Promise}
959
- */
960
- function getPathPromise(basePath, path, zip) {
961
- if (zip) {
962
- const fName = getRelativePath(basePath + path, zip.zipBasePath);
963
- if (zip.files[fName]) {
964
- return new Promise((resolve, reject) => {
965
- zip.file(fName).async('base64').then(data => {
966
- const ext = path.toLowerCase().split('.').pop();
967
- const mime = settings.MIME_TYPES[ext] || 'application/octet-stream';
968
- resolve(`data:${mime};base64,${data}`);
969
- }).catch(reject);
970
- });
971
- }
972
- }
973
- return Promise.resolve(getPath(basePath, path));
974
- };
975
-
976
- /**
977
- * Utility object that provides several methods to build simple and complex DOM objects
978
- * @type {object}
979
- */
980
- const $HTML = {
981
- doubleCell: (a, b) => jquery__WEBPACK_IMPORTED_MODULE_0___default()('<tr/>').append(jquery__WEBPACK_IMPORTED_MODULE_0___default()('<td/>').html(a)).append(jquery__WEBPACK_IMPORTED_MODULE_0___default()('<td/>').html(b)),
982
- p: txt => jquery__WEBPACK_IMPORTED_MODULE_0___default()('<p/>').html(txt),
983
- td: (txt, className) => jquery__WEBPACK_IMPORTED_MODULE_0___default()('<td/>', className ? { class: className } : null).html(txt),
984
- th: (txt, className) => jquery__WEBPACK_IMPORTED_MODULE_0___default()('<th/>', className ? { class: className } : null).html(txt),
985
- };
986
-
987
- /**
988
- * Replaces `width`, `height` and `fill` attributes of a simple SVG image
989
- * with the provided values
990
- * @param {string} svg - The SVG image as XML string
991
- * @param {string} [width] - Optional setting for "width" property
992
- * @param {string} [height] - Optional setting for "height" property
993
- * @param {string} [fill] - Optional setting for "fill" property
994
- * @returns {string} - The resulting svg code
995
- */
996
- function getSvg(svg, width, height, fill) {
997
- if (width)
998
- svg = svg.replace(/width=\"\d*\"/, `width="${width}"`);
999
- if (height)
1000
- svg = svg.replace(/height=\"\d*\"/, `height="${height}"`);
1001
- if (fill)
1002
- svg = svg.replace(/fill=\"[#A-Za-z0-9]*\"/, `fill="${fill}"`);
1003
- return svg;
1004
- };
1005
-
1006
- /**
1007
- * Encodes a svg expression into a {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs|data URI}
1008
- * suitable for the `src` property of `img` elements, optionally changing its original size and fill values.
1009
- * @param {string} svg - The SVG image as XML string
1010
- * @param {string} [width] - Optional setting for "width" property
1011
- * @param {string} [height] - Optional setting for "height" property
1012
- * @param {string} [fill] - Optional setting for "fill" property
1013
- * @returns {string} - The resulting Data URI
1014
- */
1015
- function svgToURI(svg, width, height, fill) {
1016
- return 'data:image/svg+xml;base64,' + window.btoa(getSvg(svg, width, height, fill));
1017
- };
1018
-
1019
- /**
1020
- * Converts the given expression into a valid value for CSS size values
1021
- * @param {string|number} exp - The expression to be evaluated. Can be a numeric value, `null` or `undefined`.
1022
- * Positive values are in "px" units, negative ones are "%"
1023
- * @param {object} css - An optional Object where the resulting expression (if any) will be saved
1024
- * @param {string} key - The key under which the result will be stored in `css`
1025
- * @param {string} def - Default value to be used when `exp` is `null` or `undefined`
1026
- * @returns {string} - A valid CSS value, or `null` if it can't be found. Default units are `px`
1027
- */
1028
- function toCssSize(exp, css, key, def) {
1029
- const result = typeof exp === 'undefined' || exp === null ? null : isNaN(exp) ? exp : exp < 0 ? `${Math.abs(exp)}%` : `${exp}px`;
1030
- if (css && key && (result || def))
1031
- css[key] = result !== null ? result : def;
1032
- return result;
1033
- };
1034
-
1035
- /**
1036
- * Gets a clip of the give image data, in a URL base64 encoded format
1037
- * @param {object} img - The binary data of the realized image, usually obtained from a {@link module:bads/MediaBagElement.MediaBagElement}
1038
- * @param {module:AWT.Rectangle} rect - A rectangle containing the requested clip
1039
- * @returns {string} - The URL with the image clip, as a PNG file encoded in base64
1040
- */
1041
- function getImgClipUrl(img, rect) {
1042
- const canvas = document.createElement('canvas');
1043
- canvas.width = rect.dim.width;
1044
- canvas.height = rect.dim.height;
1045
- const ctx = canvas.getContext('2d');
1046
- let result = '';
1047
- try {
1048
- ctx.drawImage(img, rect.pos.x, rect.pos.y, rect.dim.width, rect.dim.height, 0, 0, rect.dim.width, rect.dim.height);
1049
- result = canvas.toDataURL();
1050
- } catch (err) {
1051
- // catch 'tainted canvases may not be exported' and other errors
1052
- log('error', err);
1053
- }
1054
- return result;
1055
- };
1056
-
1057
- /**
1058
- * Finds the nearest `head` or root node of a given HTMLElement, useful to place `<style/>` elements when
1059
- * the main component of JClic is behind a shadow-root.
1060
- * This method will be replaced by a call to [Node.getRootNode()](https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode)
1061
- * when fully supported by all major browsers.
1062
- * @param {external:HTMLElement} [el] - The element from which to start the search
1063
- * @returns {external:HTMLElement}
1064
- */
1065
- function getRootHead(el) {
1066
- if (el) {
1067
- // Skip HTMLElements
1068
- while (el.parentElement)
1069
- el = el.parentElement;
1070
- // Get the parent node of the last HTMLElement
1071
- if (el instanceof HTMLElement)
1072
- el = el.parentNode || el;
1073
- // If the root node has a `head`, take it
1074
- el = el['head'] || el;
1075
- }
1076
- return el || document.head;
1077
- };
1078
-
1079
- /**
1080
- * Appends a stylesheet element to the `head` or root node nearest to the given `HTMLElement`.
1081
- * @param {string} css - The content of the stylesheet
1082
- * @param {module:JClicPlayer.JClicPlayer} [ps] - An optional `PlayStation` (currently a {@link module:JClicPlayer.JClicPlayer JClicPlayer}) used as a base to find the root node
1083
- * @returns {external:HTMLStyleElement} - The appended style element
1084
- */
1085
- function appendStyleAtHead(css, ps) {
1086
- const root = getRootHead(ps && ps.$topDiv ? ps.$topDiv[0] : null);
1087
- const style = document.createElement('style');
1088
- style.type = 'text/css';
1089
- style.appendChild(document.createTextNode(css));
1090
- return root.appendChild(style);
1091
- };
1092
-
1093
- /**
1094
- * Traverses all the attributes defined in an Element, calling a function with its name and value as a parameters
1095
- * @param {external:NamedNodeMap} attributes - The [Element.attributes](https://developer.mozilla.org/en-US/docs/Web/API/Element/attributes)
1096
- * object to be traversed
1097
- * @param {function} callback - The function to be called for each [Attr](https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap)
1098
- * object. It should take two parametres: `name` and `value`
1099
- */
1100
- function attrForEach(attributes, callback) {
1101
- for (let i = 0; i < attributes.length; i++)
1102
- callback(attributes[i].name, attributes[i].value);
1103
- };
1104
-
1105
- /**
1106
- * Recursive traversal of all nodes of the given object looking for children having the `childName` attribute
1107
- * WARNING: Don't call this method on objects with circular dependencies!
1108
- * @param {object} obj - The object to be analized
1109
- * @param {string} childName - Name of the attribute to search for
1110
- * @returns {object[]} - Array of children having the searched attribute
1111
- */
1112
- function findParentsWithChild(obj, childName, _result = []) {
1113
- if (obj[childName])
1114
- _result.push(obj);
1115
- else
1116
- Object.values(obj).forEach(val => {
1117
- if (typeof val === 'object')
1118
- findParentsWithChild(val, childName, _result);
1119
- });
1120
- return _result;
1121
- };
1122
-
1123
- //
1124
- // Functions useful to deal with caret position in `contentEditable` DOM elements
1125
- //
1126
- /**
1127
- * Gets the caret position within the given element. Thanks to
1128
- * {@link http://stackoverflow.com/users/96100/tim-down|Tim Down} answers in:
1129
- * {@link http://stackoverflow.com/questions/4811822/get-a-ranges-start-and-end-offsets-relative-to-its-parent-container}
1130
- * and {@link http://stackoverflow.com/questions/6240139/highlight-text-range-using-javascript/6242538}
1131
- * @param {object} element - A DOM element
1132
- * @returns {number}
1133
- */
1134
- function getCaretCharacterOffsetWithin(element) {
1135
- let caretOffset = 0;
1136
- const doc = element.ownerDocument || element.document;
1137
- const win = doc.defaultView || doc.parentWindow;
1138
- let sel;
1139
- if (typeof win.getSelection !== "undefined") {
1140
- sel = win.getSelection();
1141
- if (sel.rangeCount > 0) {
1142
- const range = win.getSelection().getRangeAt(0);
1143
- const preCaretRange = range.cloneRange();
1144
- preCaretRange.selectNodeContents(element);
1145
- preCaretRange.setEnd(range.endContainer, range.endOffset);
1146
- caretOffset = preCaretRange.toString().length;
1147
- }
1148
- } else if ((sel = doc.selection) && sel.type !== "Control") {
1149
- const textRange = sel.createRange();
1150
- const preCaretTextRange = doc.body.createTextRange();
1151
- preCaretTextRange.moveToElementText(element);
1152
- preCaretTextRange.setEndPoint("EndToEnd", textRange);
1153
- caretOffset = preCaretTextRange.text.length;
1154
- }
1155
- return caretOffset;
1156
- };
1157
-
1158
- /**
1159
- * Utility function called by {@link module:Utils.getCaretCharacterOffsetWithin}
1160
- * @param {object} node - A text node
1161
- * @returns {object[]}
1162
- */
1163
- function getTextNodesIn(node) {
1164
- const textNodes = [];
1165
- if (node.nodeType === 3) {
1166
- textNodes.push(node);
1167
- } else {
1168
- const children = node.childNodes;
1169
- for (let i = 0, len = children.length; i < len; ++i) {
1170
- textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
1171
- }
1172
- }
1173
- return textNodes;
1174
- };
1175
-
1176
- /**
1177
- * Sets the selection range (or the cursor position, when `start` and `end` are the same) to a
1178
- * specific position inside a DOM element.
1179
- * @param {object} el - The DOM element where to set the cursor
1180
- * @param {number} start - The start position of the selection (or cursor position)
1181
- * @param {number} end - The end position of the selection. When null or identical to `start`,
1182
- * indicates a cursor position.
1183
- */
1184
- function setSelectionRange(el, start, end) {
1185
- if (isNullOrUndef(end))
1186
- end = start;
1187
- if (document.createRange && window.getSelection) {
1188
- const range = document.createRange();
1189
- range.selectNodeContents(el);
1190
- const textNodes = getTextNodesIn(el);
1191
- let foundStart = false;
1192
- let charCount = 0, endCharCount, textNode;
1193
-
1194
- for (let i = 0; i < textNodes.length; i++) {
1195
- textNode = textNodes[i];
1196
- endCharCount = charCount + textNode.length;
1197
- if (!foundStart && start >= charCount &&
1198
- (start < endCharCount ||
1199
- start === endCharCount && i + 1 <= textNodes.length)) {
1200
- range.setStart(textNode, start - charCount);
1201
- foundStart = true;
1202
- }
1203
- if (foundStart && end <= endCharCount) {
1204
- range.setEnd(textNode, end - charCount);
1205
- break;
1206
- }
1207
- charCount = endCharCount;
1208
- }
1209
- const sel = window.getSelection();
1210
- sel.removeAllRanges();
1211
- sel.addRange(range);
1212
- } else if (document.selection && document.body.createTextRange) {
1213
- const textRange = document.body.createTextRange();
1214
- textRange.moveToElementText(el);
1215
- textRange.collapse(true);
1216
- textRange.moveEnd('character', end);
1217
- textRange.moveStart('character', start);
1218
- textRange.select();
1219
- }
1220
- };
1221
-
1222
- /**
1223
- * Performs multiple replacements on the provided string
1224
- * See: https://stackoverflow.com/questions/2501435/replacing-multiple-patterns-in-a-block-of-data
1225
- * @param {Object[]} replacements - Array of pairs formed by an "expression" (regexp or string) and a "value" (string) to replace the fragments found
1226
- * @param {String} str - The string to be checked for replacements
1227
- * @returns {String} - The original string with the fragments found already replaced
1228
- */
1229
- function mReplace(replacements, str) {
1230
- return replacements.reduce((result, [exp, replacement]) => result.replace(exp, replacement), str);
1231
- };
1232
-
1233
- /**
1234
- * Global constants
1235
- * @const
1236
- */
1237
- const settings = {
1238
- // JClic.js Version
1239
- VERSION: _GlobalData_js__WEBPACK_IMPORTED_MODULE_3__["default"].version,
1240
- // Check if we are running on NodeJS with JSDOM
1241
- NODEJS: typeof window === 'undefined' || window?.navigator?.userAgent?.includes('jsdom'),
1242
- // layout constants
1243
- AB: 0, BA: 1, AUB: 2, BUA: 3,
1244
- LAYOUT_NAMES: ['AB', 'BA', 'AUB', 'BUA'],
1245
- DEFAULT_WIDTH: 400,
1246
- DEFAULT_HEIGHT: 300,
1247
- MINIMUM_WIDTH: 40,
1248
- MINIMUM_HEIGHT: 40,
1249
- DEFAULT_NAME: '---',
1250
- DEFAULT_MARGIN: 8,
1251
- DEFAULT_SHUFFLES: 31,
1252
- DEFAULT_GRID_ELEMENT_SIZE: 20,
1253
- MIN_CELL_SIZE: 10,
1254
- //DEFAULT_BG_COLOR: '#D3D3D3', // LightGray
1255
- DEFAULT_BG_COLOR: '#C0C0C0', // LightGray
1256
- ACTIONS: {
1257
- ACTION_MATCH: 'MATCH', ACTION_PLACE: 'PLACE',
1258
- ACTION_WRITE: 'WRITE', ACTION_SELECT: 'SELECT', ACTION_HELP: 'HELP'
1259
- },
1260
- PREVIOUS: 0, MAIN: 1, END: 2, END_ERROR: 3, NUM_MSG: 4,
1261
- MSG_TYPE: ['previous', 'initial', 'final', 'finalError'],
1262
- RANDOM_CHARS: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
1263
- NUM_COUNTERS: 3,
1264
- MAX_RECORD_LENGTH: 180,
1265
- // BoxBase defaults
1266
- BoxBase: {
1267
- REDUCE_FONT_STEP: 1.0,
1268
- MIN_FONT_SIZE: 8,
1269
- STROKE: 1,
1270
- AC_MARGIN: 6,
1271
- //BACK_COLOR: 'lightgray',
1272
- BACK_COLOR: '#C0C0C0',
1273
- TEXT_COLOR: 'black',
1274
- SHADOW_COLOR: 'gray',
1275
- INACTIVE_COLOR: 'gray',
1276
- ALTERNATIVE_COLOR: 'gray',
1277
- BORDER_COLOR: 'black',
1278
- BORDER_STROKE_WIDTH: 0.75,
1279
- MARKER_STROKE_WIDTH: 2.75
1280
- },
1281
- FILE_TYPES: {
1282
- image: 'gif,jpg,png,jpeg,bmp,ico,svg',
1283
- audio: 'wav,mp3,ogg,oga,au,aiff,flac',
1284
- video: 'avi,mov,mpeg,mp4,ogv,m4v,webm',
1285
- font: 'ttf,otf,eot,woff,woff2',
1286
- midi: 'mid,midi',
1287
- anim: 'swf',
1288
- // Used in custom skins
1289
- xml: 'xml'
1290
- },
1291
- MIME_TYPES: {
1292
- xml: 'text/xml',
1293
- gif: 'image/gif',
1294
- jpg: 'image/jpeg',
1295
- jpeg: 'image/jpeg',
1296
- png: 'image/png',
1297
- bmp: 'image/bmp',
1298
- svg: 'image/svg+xml',
1299
- ico: 'image/x-icon',
1300
- wav: 'audio/wav',
1301
- mp3: 'audio/mpeg',
1302
- mp4: 'video/mp4',
1303
- m4v: 'video/mp4',
1304
- ogg: 'audio/ogg',
1305
- oga: 'audio/ogg',
1306
- ogv: 'video/ogg',
1307
- webm: 'video/webm',
1308
- au: 'audio/basic',
1309
- aiff: 'audio/x-aiff',
1310
- flac: 'audio/flac',
1311
- avi: 'video/avi',
1312
- mov: 'video/quicktime',
1313
- mpeg: 'video/mpeg',
1314
- ttf: 'application/font-sfnt',
1315
- otf: 'application/font-sfnt',
1316
- eot: ' application/vnd.ms-fontobject',
1317
- woff: 'application/font-woff',
1318
- woff2: 'application/font-woff2',
1319
- swf: 'application/x-shockwave-flash',
1320
- mid: 'audio/midi',
1321
- midi: 'audio/midi'
1322
- },
1323
- // Global settings susceptible to be modified
1324
- COMPRESS_IMAGES: true,
1325
- // Keyboard key codes
1326
- VK: {
1327
- LEFT: 37,
1328
- UP: 38,
1329
- RIGHT: 39,
1330
- DOWN: 40
1331
- },
1332
- // Flag to indicate that we are running on a touch device
1333
- TOUCH_DEVICE: false,
1334
- // Amount of time (in milliseconds) to wait before a media resource is loaded
1335
- LOAD_TIMEOUT: 10000,
1336
- // Number of points to be calculated as polygon vertexs when simplifying bezier curves
1337
- BEZIER_POINTS: 4,
1338
- // Check if canvas accessibility features are enabled
1339
- // See: http://codepen.io/francesc/pen/amwvRp
1340
- // UPDATED May 2020: Detection removed since Canvas HitRegions have been deprecated
1341
- // See: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility
1342
- //
1343
- // CANVAS_HITREGIONS: typeof CanvasRenderingContext2D !== 'undefined' && typeof CanvasRenderingContext2D.prototype.addHitRegion === 'function',
1344
- // CANVAS_HITREGIONS_FOCUS: typeof CanvasRenderingContext2D !== 'undefined' && typeof CanvasRenderingContext2D.prototype.drawFocusIfNeeded === 'function',
1345
- //
1346
- CANVAS_DRAW_FOCUS: typeof window !== 'undefined' && typeof window?.CanvasRenderingContext2D?.prototype?.drawFocusIfNeeded === 'function',
1347
- // See: https://emptycharacter.com/
1348
- // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
1349
- WHITESPACES: ' \f\n\r\t\v\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202f\u205f\u3000\ufeff',
1350
- };
1351
- settings.SEPARATORS = `${settings.WHITESPACES}.,;-|`;
1352
- settings.WORD_DELIMITERS = `${settings.SEPARATORS}…_<>"“”«»'\xB4\x60\u2018\u2019\u2022~+\u2013\u2014\u2015=%¿?¡!:/\\()[]{}$£€`;
1353
-
1354
- /**
1355
- * Miscellaneous utility functions and constants
1356
- */
1357
- const Utils = {
1358
- pkg,
1359
- settings,
1360
- getMsg,
1361
- LOG_LEVELS,
1362
- LOG_PRINT_LABELS,
1363
- LOG_OPTIONS,
1364
- init,
1365
- setLogLevel,
1366
- log,
1367
- getBoolean,
1368
- getVal,
1369
- getNumber,
1370
- getPercent,
1371
- zp,
1372
- getHMStime,
1373
- getDateTime,
1374
- parseOldDate,
1375
- cleanOldLanguageTag,
1376
- FALSE,
1377
- TRUE,
1378
- DEFAULT,
1379
- getTriState,
1380
- fillString,
1381
- isNullOrUndef,
1382
- isEquivalent,
1383
- getXmlText,
1384
- parseXmlNode,
1385
- getXmlNodeText,
1386
- reduceTextsToStrings,
1387
- cssToString,
1388
- checkColor,
1389
- colorHasTransparency,
1390
- cloneObject,
1391
- normalizeObject,
1392
- getAttr,
1393
- getValue,
1394
- isEmpty,
1395
- setAttr,
1396
- buildObj,
1397
- isSeparator,
1398
- isWordDelimiter,
1399
- stringToWords,
1400
- roundTo,
1401
- fx,
1402
- compareMultipleOptions,
1403
- endsWith,
1404
- startsWith,
1405
- nSlash,
1406
- isURL,
1407
- getBasePath,
1408
- getRelativePath,
1409
- getPath,
1410
- getPathPromise,
1411
- $HTML,
1412
- getSvg,
1413
- svgToURI,
1414
- toCssSize,
1415
- getImgClipUrl,
1416
- getRootHead,
1417
- appendStyleAtHead,
1418
- attrForEach,
1419
- findParentsWithChild,
1420
- getCaretCharacterOffsetWithin,
1421
- getTextNodesIn,
1422
- setSelectionRange
1423
- };
1424
-
1425
- /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Utils);
1426
-
1427
-
1428
- /***/ })
1429
-
1430
- };
1431
- ;
1432
- //# sourceMappingURL=1253.jclic-node.js.map