underpost 2.7.1 → 2.7.3

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 (214) hide show
  1. package/.dockerignore +13 -13
  2. package/.env.development +7 -7
  3. package/.env.production +7 -7
  4. package/.env.test +7 -7
  5. package/.github/workflows/publish.yml +26 -0
  6. package/.github/workflows/test.yml +80 -0
  7. package/.nycrc +9 -9
  8. package/.prettierignore +12 -12
  9. package/.prettierrc +9 -9
  10. package/.vscode/extensions.json +72 -72
  11. package/.vscode/settings.json +100 -99
  12. package/Dockerfile +89 -89
  13. package/LICENSE +21 -21
  14. package/README.md +96 -96
  15. package/bin/db.js +172 -119
  16. package/bin/deploy.js +607 -661
  17. package/bin/file.js +93 -92
  18. package/bin/index.js +76 -53
  19. package/bin/ssl.js +55 -64
  20. package/bin/util.js +182 -182
  21. package/bin/vs.js +35 -35
  22. package/conf.js +251 -249
  23. package/docker-compose.yml +67 -67
  24. package/jsconfig.json +7 -7
  25. package/jsdoc.json +32 -32
  26. package/nodemon.json +6 -6
  27. package/package.json +137 -132
  28. package/prometheus.yml +36 -36
  29. package/setup.sh +24 -24
  30. package/src/api/core/core.controller.js +69 -69
  31. package/src/api/core/core.model.js +11 -11
  32. package/src/api/core/core.router.js +23 -23
  33. package/src/api/core/core.service.js +29 -29
  34. package/src/api/crypto/crypto.controller.js +51 -51
  35. package/src/api/crypto/crypto.model.js +23 -23
  36. package/src/api/crypto/crypto.router.js +20 -20
  37. package/src/api/crypto/crypto.service.js +64 -64
  38. package/src/api/default/default.controller.js +69 -69
  39. package/src/api/default/default.model.js +20 -20
  40. package/src/api/default/default.router.js +23 -23
  41. package/src/api/default/default.service.js +31 -31
  42. package/src/api/file/file.controller.js +53 -51
  43. package/src/api/file/file.model.js +19 -19
  44. package/src/api/file/file.router.js +21 -20
  45. package/src/api/file/file.service.js +76 -70
  46. package/src/api/instance/instance.controller.js +69 -69
  47. package/src/api/instance/instance.model.js +36 -36
  48. package/src/api/instance/instance.router.js +33 -33
  49. package/src/api/instance/instance.service.js +48 -48
  50. package/src/api/test/test.controller.js +59 -59
  51. package/src/api/test/test.model.js +14 -14
  52. package/src/api/test/test.router.js +21 -21
  53. package/src/api/test/test.service.js +35 -35
  54. package/src/api/user/user.build.js +16 -0
  55. package/src/api/user/user.controller.js +70 -70
  56. package/src/api/user/user.model.js +65 -65
  57. package/src/api/user/user.router.js +345 -345
  58. package/src/api/user/user.service.js +479 -479
  59. package/src/api.js +23 -23
  60. package/src/client/Default.index.js +40 -40
  61. package/src/client/components/core/Account.js +290 -290
  62. package/src/client/components/core/AgGrid.js +160 -160
  63. package/src/client/components/core/Auth.js +19 -19
  64. package/src/client/components/core/Badge.js +32 -32
  65. package/src/client/components/core/{BlockChain.js → Blockchain.js} +41 -41
  66. package/src/client/components/core/Blog.js +9 -9
  67. package/src/client/components/core/BtnIcon.js +101 -94
  68. package/src/client/components/core/CalendarCore.js +458 -319
  69. package/src/client/components/core/Chat.js +64 -64
  70. package/src/client/components/core/ColorPalette.js +5267 -5267
  71. package/src/client/components/core/CommonJs.js +735 -732
  72. package/src/client/components/core/Content.js +193 -49
  73. package/src/client/components/core/Css.js +1064 -1027
  74. package/src/client/components/core/CssCore.js +817 -796
  75. package/src/client/components/core/D3Chart.js +44 -44
  76. package/src/client/components/core/Docs.js +229 -229
  77. package/src/client/components/core/DropDown.js +164 -164
  78. package/src/client/components/core/EventsUI.js +46 -54
  79. package/src/client/components/core/FileExplorer.js +699 -624
  80. package/src/client/components/core/FullScreen.js +45 -45
  81. package/src/client/components/core/Input.js +346 -259
  82. package/src/client/components/core/JoyStick.js +77 -77
  83. package/src/client/components/core/Keyboard.js +73 -73
  84. package/src/client/components/core/LoadingAnimation.js +179 -157
  85. package/src/client/components/core/LogIn.js +187 -181
  86. package/src/client/components/core/LogOut.js +58 -52
  87. package/src/client/components/core/Logger.js +26 -26
  88. package/src/client/components/core/Modal.js +1612 -1596
  89. package/src/client/components/core/NotificationManager.js +84 -84
  90. package/src/client/components/core/Panel.js +613 -413
  91. package/src/client/components/core/PanelForm.js +468 -0
  92. package/src/client/components/core/Polyhedron.js +162 -162
  93. package/src/client/components/core/Recover.js +204 -204
  94. package/src/client/components/core/Responsive.js +53 -53
  95. package/src/client/components/core/RichText.js +51 -27
  96. package/src/client/components/core/Router.js +76 -77
  97. package/src/client/components/core/Scroll.js +34 -0
  98. package/src/client/components/core/SignUp.js +125 -125
  99. package/src/client/components/core/SocketIo.js +72 -72
  100. package/src/client/components/core/Stream.js +113 -113
  101. package/src/client/components/core/ToggleSwitch.js +87 -87
  102. package/src/client/components/core/ToolTip.js +26 -26
  103. package/src/client/components/core/Translate.js +437 -408
  104. package/src/client/components/core/Validator.js +100 -100
  105. package/src/client/components/core/VanillaJs.js +460 -457
  106. package/src/client/components/core/Wallet.js +106 -106
  107. package/src/client/components/core/Webhook.js +25 -25
  108. package/src/client/components/core/Worker.js +272 -272
  109. package/src/client/components/default/CommonDefault.js +29 -29
  110. package/src/client/components/default/CssDefault.js +13 -13
  111. package/src/client/components/default/ElementsDefault.js +38 -38
  112. package/src/client/components/default/LogInDefault.js +41 -41
  113. package/src/client/components/default/LogOutDefault.js +28 -28
  114. package/src/client/components/default/MenuDefault.js +389 -389
  115. package/src/client/components/default/RoutesDefault.js +48 -48
  116. package/src/client/components/default/SettingsDefault.js +16 -16
  117. package/src/client/components/default/SignUpDefault.js +9 -9
  118. package/src/client/components/default/SocketIoDefault.js +54 -54
  119. package/src/client/components/default/TranslateDefault.js +7 -7
  120. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  121. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  122. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  123. package/src/client/public/default/browserconfig.xml +11 -11
  124. package/src/client/public/default/manifest.webmanifest +68 -68
  125. package/src/client/public/default/plantuml/client-conf.svg +1 -0
  126. package/src/client/public/default/plantuml/client-schema.svg +1 -0
  127. package/src/client/public/default/plantuml/cron-conf.svg +1 -0
  128. package/src/client/public/default/plantuml/cron-schema.svg +1 -0
  129. package/src/client/public/default/plantuml/server-conf.svg +1 -0
  130. package/src/client/public/default/plantuml/server-schema.svg +1 -0
  131. package/src/client/public/default/plantuml/ssr-conf.svg +1 -0
  132. package/src/client/public/default/plantuml/ssr-schema.svg +1 -0
  133. package/src/client/public/default/sitemap +147 -147
  134. package/src/client/public/default/yandex-browser-manifest.json +8 -8
  135. package/src/client/public/doc/sitemap +147 -147
  136. package/src/client/public/test/sitemap +147 -147
  137. package/src/client/services/core/core.service.js +170 -152
  138. package/src/client/services/crypto/crypto.service.js +70 -70
  139. package/src/client/services/default/default.management.js +345 -345
  140. package/src/client/services/default/default.service.js +89 -89
  141. package/src/client/services/file/file.service.js +70 -70
  142. package/src/client/services/instance/instance.management.js +74 -74
  143. package/src/client/services/instance/instance.service.js +89 -89
  144. package/src/client/services/test/test.service.js +70 -70
  145. package/src/client/services/user/user.management.js +50 -50
  146. package/src/client/services/user/user.service.js +89 -89
  147. package/src/client/ssr/Render.js +16 -16
  148. package/src/client/ssr/body-components/CacheControl.js +114 -113
  149. package/src/client/ssr/body-components/DefaultSplashScreen.js +79 -79
  150. package/src/client/ssr/email-components/DefaultRecoverEmail.js +21 -21
  151. package/src/client/ssr/email-components/DefaultVerifyEmail.js +17 -17
  152. package/src/client/ssr/head-components/Css.js +241 -241
  153. package/src/client/ssr/head-components/DefaultScripts.js +3 -3
  154. package/src/client/ssr/head-components/Microdata.js +11 -11
  155. package/src/client/ssr/head-components/Production.js +1 -1
  156. package/src/client/ssr/head-components/PwaDefault.js +59 -59
  157. package/src/client/ssr/head-components/Seo.js +14 -14
  158. package/src/client/sw/default.sw.js +201 -201
  159. package/src/client/sw/template.sw.js +84 -84
  160. package/src/client.build.js +22 -22
  161. package/src/client.dev.js +21 -21
  162. package/src/cron.js +25 -25
  163. package/src/db/DataBaseProvider.js +34 -34
  164. package/src/db/mariadb/MariaDB.js +33 -33
  165. package/src/db/mongo/MongooseDB.js +137 -46
  166. package/src/dns.js +22 -22
  167. package/src/index.js +42 -29
  168. package/src/mailer/EmailRender.js +69 -69
  169. package/src/mailer/MailerProvider.js +96 -96
  170. package/src/proxy.js +22 -22
  171. package/src/runtime/lampp/Lampp.js +115 -44
  172. package/src/runtime/nginx/Nginx.js +3 -3
  173. package/src/runtime/xampp/Xampp.js +49 -49
  174. package/src/server/auth.js +235 -204
  175. package/src/server/backup.js +101 -94
  176. package/src/server/client-build-live.js +72 -72
  177. package/src/server/client-build.js +699 -699
  178. package/src/server/client-dev-server.js +60 -58
  179. package/src/server/client-formatted.js +48 -48
  180. package/src/server/client-icons.js +149 -150
  181. package/src/server/conf.js +860 -611
  182. package/src/server/dns.js +98 -98
  183. package/src/server/downloader.js +42 -42
  184. package/src/server/logger.js +190 -180
  185. package/src/server/network.js +122 -122
  186. package/src/server/peer.js +33 -33
  187. package/src/server/process.js +66 -66
  188. package/src/server/prompt-optimizer.js +28 -28
  189. package/src/server/proxy.js +118 -118
  190. package/src/server/runtime.js +444 -393
  191. package/src/server/ssl.js +120 -107
  192. package/src/server.js +25 -25
  193. package/src/ws/IoInterface.js +45 -45
  194. package/src/ws/IoServer.js +39 -39
  195. package/src/ws/core/channels/core.ws.chat.js +23 -23
  196. package/src/ws/core/channels/core.ws.mailer.js +35 -35
  197. package/src/ws/core/channels/core.ws.stream.js +31 -31
  198. package/src/ws/core/core.ws.connection.js +28 -28
  199. package/src/ws/core/core.ws.emit.js +14 -14
  200. package/src/ws/core/core.ws.server.js +24 -24
  201. package/src/ws/core/management/core.ws.chat.js +8 -8
  202. package/src/ws/core/management/core.ws.mailer.js +16 -16
  203. package/src/ws/core/management/core.ws.stream.js +8 -8
  204. package/src/ws/default/channels/default.ws.main.js +16 -16
  205. package/src/ws/default/default.ws.connection.js +22 -22
  206. package/src/ws/default/default.ws.emit.js +14 -14
  207. package/src/ws/default/default.ws.server.js +20 -20
  208. package/src/ws/default/management/default.ws.main.js +8 -8
  209. package/startup.js +11 -11
  210. package/supervisord-openssh-server.conf +4 -4
  211. package/test/api.test.js +60 -60
  212. package/bin/dns.js +0 -1
  213. package/bin/install.js +0 -357
  214. package/bin/shortcut.js +0 -44
@@ -1,732 +1,735 @@
1
- /**
2
- * Common JavaScript functions
3
- * @module src/client/components/core/CommonJs.js
4
- * @namespace CommonJS
5
- */
6
-
7
- /**
8
- * The function `s4` generates a random hexadecimal string with a length of 4 characters.
9
- * @memberof CommonJS
10
- */
11
- const s4 = () => (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
12
-
13
- /**
14
- * The `range` function generates an array of numbers within a specified range, handling both ascending
15
- * and descending ranges.
16
- * @param start - The `start` parameter in the `range` function represents the starting value of the
17
- * range you want to generate.
18
- * @param end - The `end` parameter in the `range` function represents the ending value of the range
19
- * that you want to generate.
20
- * @returns The `range` function returns an array containing a range of numbers starting from the
21
- * `start` value up to the `end` value (inclusive). If `end` is less than `start`, it will recursively
22
- * call the `range` function with the arguments swapped and then reverse the resulting array.
23
- * @memberof CommonJS
24
- */
25
- const range = (start, end) => {
26
- return end < start
27
- ? range(end, start).reverse()
28
- : Array.apply(0, Array(end - start + 1)).map((element, index) => index + start);
29
- };
30
-
31
- /**
32
- * The `getId` function generates a unique identifier based on an array of objects or keys.
33
- * @param arr - The `arr` parameter in the `getId` function is an array of objects or an object. If it
34
- * is an object, the function converts it into an array of objects where each object has a key
35
- * specified by the `keyId` parameter.
36
- * @param suffix - The `suffix` parameter in the `getId` function is a string that can be added to
37
- * the generated ID. It is optional and by default is an empty string. You can provide a suffix to be
38
- * appended to the generated ID if needed.
39
- * @param keyId - The `keyId` parameter in the `getId` function is used to specify the key in the
40
- * array elements that contains the unique identifier (ID) for each element. By default, the function
41
- * assumes that the ID is stored in a property named `'id'`, but you can customize this by providing
42
- * @returns The `getId` function returns a unique identifier `_id` based on the input array `arr`,
43
- * optional `suffix`, and `keyId`.
44
- * @memberof CommonJS
45
- */
46
- const getId = (arr, suffix = '', keyId = 'id') => {
47
- if (!Array.isArray(arr) && typeof arr === 'object')
48
- arr = Object.keys(arr).map((id) => {
49
- const idElement = {};
50
- idElement[keyId] = id;
51
- return idElement;
52
- });
53
- let _id;
54
- while (arr.find((element) => element[keyId] === _id) || !_id)
55
- _id = suffix + (s4() + s4() + s4() + s4() + s4()).slice(1);
56
- return _id;
57
- };
58
-
59
- /**
60
- * The function `random` generates a random integer within a specified range.
61
- * @param min - The `min` parameter represents the minimum value of the range from which you want to
62
- * generate a random number.
63
- * @param max - The `max` parameter in the `random` function represents the maximum value that you want
64
- * to generate a random number up to.
65
- * @memberof CommonJS
66
- */
67
- const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
68
-
69
- const randomHexColor = () => '#' + ((Math.random() * 0xffffff) << 0).toString(16).padStart(6, '0');
70
-
71
- const getRawCsvFromArray = (array) =>
72
- array[0]
73
- ? Object.keys(array[0]).join(';') +
74
- '\r\n' +
75
- array
76
- .map((x) => {
77
- return (
78
- Object.keys(x)
79
- .map((attr) => x[attr])
80
- .join(';') + '\r\n'
81
- );
82
- })
83
- .join('')
84
- : '';
85
-
86
- const newInstance = (obj) => {
87
- // structuredClone() 2022 ES6 feature
88
- try {
89
- return JSON.parse(JSON.stringify(obj));
90
- } catch (error) {
91
- return { error: error.message };
92
- }
93
- };
94
-
95
- const cap = (str) =>
96
- str
97
- .toLowerCase()
98
- .split(' ')
99
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
100
- .join(' ');
101
-
102
- const capFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);
103
-
104
- const uniqueArray = (arr) => arr.filter((item, pos) => arr.indexOf(item) == pos);
105
-
106
- const orderArrayFromAttrInt = (arr, attr, type) =>
107
- // type -> true asc
108
- // type -> false desc
109
- type === 'asc' ? arr.sort((a, b) => a[attr] - b[attr]) : arr.sort((a, b) => b[attr] - a[attr]);
110
-
111
- const getRandomPoint = (suffix, pointsArray) => {
112
- const point = pointsArray[random(0, pointsArray.length - 1)];
113
- const returnPoint = {};
114
- returnPoint['x' + suffix] = point[0];
115
- returnPoint['y' + suffix] = point[1];
116
- return returnPoint;
117
- };
118
-
119
- const getYouTubeID = (url) => {
120
- const p =
121
- /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
122
- if (url.match(p)) return url.match(p)[1];
123
- return false;
124
- };
125
-
126
- const timer = (ms) => new Promise((res) => setTimeout(res, ms));
127
-
128
- const reOrderIntArray = (array) => {
129
- /* shuffle */
130
- let currentIndex = array.length,
131
- randomIndex;
132
-
133
- // While there remain elements to shuffle.
134
- while (currentIndex != 0) {
135
- // Pick a remaining element.
136
- randomIndex = Math.floor(Math.random() * currentIndex);
137
- currentIndex--;
138
-
139
- // And swap it with the current element.
140
- [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
141
- }
142
-
143
- return array;
144
- };
145
-
146
- const orderAbc = (arr, attr) =>
147
- arr.sort((a, b) => {
148
- if (attr) {
149
- if (a[attr] < b[attr]) {
150
- return -1;
151
- }
152
- if (a[attr] > b[attr]) {
153
- return 1;
154
- }
155
- } else {
156
- if (a < b) {
157
- return -1;
158
- }
159
- if (a > b) {
160
- return 1;
161
- }
162
- }
163
- return 0;
164
- });
165
-
166
- const JSONmatrix = (matrix) => {
167
- if (Array.isArray(matrix))
168
- return `[\r\n${matrix
169
- .map((x, i) => ` ` + JSON.stringify(x) + (i === matrix.length - 1 ? '' : ',') + '\r\n')
170
- .join('')}]`;
171
- else
172
- return `[\r\n${Object.keys(matrix)
173
- .map((x, i) => ` ` + JSON.stringify(Object.values(matrix[x])) + (i === matrix.length - 1 ? '' : ',') + '\r\n')
174
- .join('')}]`;
175
- };
176
-
177
- const getDistance = (x1, y1, x2, y2) => {
178
- const disX = Math.abs(x2 - x1);
179
- const disY = Math.abs(y2 - y1);
180
- return Math.sqrt(disX * disX + disY * disY);
181
- };
182
-
183
- const setPad = (num, padValue, targetLength, endPad, separator) => {
184
- separator = separator ? separator : '.';
185
- let str = String(num).split(separator);
186
- let removeSeparator = false;
187
- if (!str[1]) {
188
- str[1] = '';
189
- if (!endPad) removeSeparator = true;
190
- }
191
- while (endPad ? str[1].length < targetLength : str[0].length < targetLength)
192
- endPad ? (str[1] = str[1] + padValue) : (str[0] = padValue + str[0]);
193
- return removeSeparator ? str.join(separator).replace(separator, '') : str.join(separator);
194
- };
195
-
196
- /**
197
- * Decimal setting of a number.
198
- *
199
- * @param {String} type The type of setting.
200
- * @param {Number} value The number.
201
- * @param {Integer} exp The exponent (the log 10 of the base fit).
202
- * @returns {Number} The adjusted value.
203
- * @memberof CommonJS
204
- */
205
- const decimalAdjust = (type, value, exp) => {
206
- if (typeof exp === 'undefined' || +exp === 0) {
207
- return Math[type](value);
208
- }
209
- value = +value;
210
- exp = +exp;
211
-
212
- if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
213
- return NaN;
214
- }
215
- // Shift
216
- value = value.toString().split('e');
217
- value = Math[type](+(value[0] + 'e' + (value[1] ? +value[1] - exp : -exp)));
218
- // Shift back
219
- value = value.toString().split('e');
220
- return +(value[0] + 'e' + (value[1] ? +value[1] + exp : exp));
221
-
222
- // https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/round
223
- };
224
-
225
- const floatRound = (v, d) => parseFloat(parseFloat(v).toFixed(d));
226
-
227
- // Decimal round
228
-
229
- const round10 = (value, exp) => {
230
- return decimalAdjust('round', value, exp);
231
- };
232
-
233
- // Decimal floor
234
-
235
- const floor10 = (value, exp) => {
236
- return decimalAdjust('floor', value, exp);
237
- };
238
-
239
- // Decimal ceil
240
-
241
- const ceil10 = (value, exp) => {
242
- return decimalAdjust('ceil', value, exp);
243
- };
244
-
245
- // // Round
246
- // round10(55.55, -1); // 55.6
247
- // round10(55.549, -1); // 55.5
248
- // round10(55, 1); // 60
249
- // round10(54.9, 1); // 50
250
- // round10(-55.55, -1); // -55.5
251
- // round10(-55.551, -1); // -55.6
252
- // round10(-55, 1); // -50
253
- // round10(-55.1, 1); // -60
254
- // round10(1.005, -2); // 1.01 -- compare this with round(1.005*100)/100 above
255
- // // Floor
256
- // floor10(55.59, -1); // 55.5
257
- // floor10(59, 1); // 50
258
- // floor10(-55.51, -1); // -55.6
259
- // floor10(-51, 1); // -60
260
- // // Ceil
261
- // ceil10(55.51, -1); // 55.6
262
- // ceil10(51, 1); // 60
263
- // ceil10(-55.59, -1); // -55.5
264
- // ceil10(-59, 1); // -50
265
-
266
- function objectEquals(x, y) {
267
- // TODO:
268
- // https://www.npmjs.com/package/deep-equal
269
- // https://www.npmjs.com/package/fast-deep-equal
270
- const ok = Object.keys,
271
- tx = typeof x,
272
- ty = typeof y;
273
- return x && y && tx === 'object' && tx === ty
274
- ? ok(x).length === ok(y).length && ok(x).every((key) => objectEquals(x[key], y[key]))
275
- : x === y;
276
- }
277
-
278
- function insertTransitionCoordinates(coordinates, transitionFactor) {
279
- // Create a new array to store the resulting coordinates
280
- const coordinatesWithTransition = [];
281
-
282
- // Iterate over the coordinates array
283
- for (let i = 0; i < coordinates.length - 1; i++) {
284
- const [x1, y1] = coordinates[i];
285
- const [x2, y2] = coordinates[i + 1];
286
-
287
- // Add the initial integer coordinate to the new array
288
- coordinatesWithTransition.push([x1, y1]);
289
-
290
- // Calculate the increments for each coordinate
291
- const incrementX = (x2 - x1) / transitionFactor;
292
- const incrementY = (y2 - y1) / transitionFactor;
293
-
294
- // Add the intermediate coordinates
295
- for (let j = 1; j <= transitionFactor - 1; j++) {
296
- const xIntermediate = x1 + incrementX * j;
297
- const yIntermediate = y1 + incrementY * j;
298
- coordinatesWithTransition.push([xIntermediate, yIntermediate]);
299
- }
300
- }
301
-
302
- // Add the last integer coordinate to the new array
303
- coordinatesWithTransition.push(coordinates[coordinates.length - 1]);
304
-
305
- // Now, coordinatesWithTransition contains the coordinates with transition
306
- return coordinatesWithTransition;
307
- }
308
-
309
- const getIsoDate = (date) => date.toISOString().slice(0, -5).replace('T', ' ');
310
-
311
- const clearTerminalStringColor = (str) => str.replace(/\x1b\[[0-9;]*m/g, '');
312
-
313
- function getValueFromJoinString(obj, path, join = '.') {
314
- // Split the path string into an array of attribute names
315
- const attributes = path.split(join);
316
-
317
- // Iterate through the attributes to access the desired value
318
- let value = obj;
319
- for (let i = 0; i < attributes.length; i++) {
320
- value = value[attributes[i]];
321
-
322
- // Check if the value is null or undefined at each step
323
- if (value === null || value === undefined) {
324
- // If the value is null or undefined, stop the iteration
325
- break;
326
- }
327
- }
328
-
329
- return value;
330
- }
331
-
332
- function getDirection(options = { x1: 1, y1: 1, x2: 1, y2: 1, radians: 1 }) {
333
- const { x1, y1, x2, y2, radians } = options;
334
- // Calculate the angle in radians
335
- const angle = radians !== undefined ? radians : Math.atan2(y2 - y1, x2 - x1);
336
-
337
- // Convert the angle to degrees
338
- let degrees = angle * (180 / Math.PI);
339
-
340
- // Adjust the angle to be positive
341
- if (degrees < 0) {
342
- degrees += 360;
343
- }
344
-
345
- // 45 / 2 = 22.5
346
- // formula -> 22.5 + (45*n)
347
-
348
- // Map the angle to one of the eight directions
349
- let direction;
350
- if (degrees >= 337.5 || degrees < 22.5) {
351
- // direction = 'right';
352
- // direction = 'East';
353
- direction = 'e';
354
- } else if (degrees >= 22.5 && degrees < 67.5) {
355
- // direction = 'up-right';
356
- // direction = 'South East';
357
- direction = 'se';
358
- } else if (degrees >= 67.5 && degrees < 112.5) {
359
- // direction = 'up';
360
- // direction = 'South';
361
- direction = 's';
362
- } else if (degrees >= 112.5 && degrees < 157.5) {
363
- // direction = 'up-left';
364
- // direction = 'South West';
365
- direction = 'sw';
366
- } else if (degrees >= 157.5 && degrees < 202.5) {
367
- // direction = 'left';
368
- // direction = 'West';
369
- direction = 'w';
370
- } else if (degrees >= 202.5 && degrees < 247.5) {
371
- // direction = 'down-left';
372
- // direction = 'North West';
373
- direction = 'nw';
374
- } else if (degrees >= 247.5 && degrees < 292.5) {
375
- // direction = 'down';
376
- // direction = 'North';
377
- direction = 'n';
378
- } else if (degrees >= 292.5 && degrees < 337.5) {
379
- // direction = 'down-right';
380
- // direction = 'North East';
381
- direction = 'ne';
382
- }
383
-
384
- return direction;
385
- }
386
-
387
- // Function to amplify a matrix in horizontal and vertical directions
388
- const amplifyMatrix = (matrix, factor) => {
389
- // Get the original dimensions of the matrix
390
- const rows = matrix.length;
391
- const cols = matrix[0].length;
392
-
393
- // Create a new amplified matrix filled with zeros
394
- const amplifiedMatrix = Array.from({ length: rows * factor }, () => Array(cols * factor).fill(0));
395
-
396
- // Iterate over the original matrix
397
- for (let i = 0; i < rows; i++) {
398
- for (let j = 0; j < cols; j++) {
399
- // Get the current value in the original matrix
400
- const originalValue = matrix[i][j];
401
-
402
- // Amplify in horizontal and vertical directions
403
- for (let x = 0; x < factor; x++) {
404
- for (let y = 0; y < factor; y++) {
405
- // Assign the amplified value to the new matrix
406
- amplifiedMatrix[i * factor + x][j * factor + y] = originalValue;
407
- }
408
- }
409
- }
410
- }
411
-
412
- return amplifiedMatrix;
413
- };
414
-
415
- // Function to reduce a matrix by a factor in horizontal and vertical directions
416
- const reduceMatrix = (matrix, factor) => {
417
- // Get the original dimensions of the matrix
418
- const rows = matrix.length;
419
- const cols = matrix[0].length;
420
-
421
- // Calculate the dimensions of the reduced matrix
422
- const reducedRows = Math.ceil(rows / factor);
423
- const reducedCols = Math.ceil(cols / factor);
424
-
425
- // Create a new reduced matrix filled with zeros
426
- const reducedMatrix = Array.from({ length: reducedRows }, () => Array(reducedCols).fill(0));
427
-
428
- // Iterate over the original matrix
429
- for (let i = 0; i < reducedRows; i++) {
430
- for (let j = 0; j < reducedCols; j++) {
431
- // Calculate the sum of values in the corresponding block of the original matrix
432
- let sum = 0;
433
-
434
- for (let x = 0; x < factor; x++) {
435
- for (let y = 0; y < factor; y++) {
436
- // Safely access the original matrix considering the boundaries
437
- const rowIndex = i * factor + x;
438
- const colIndex = j * factor + y;
439
-
440
- if (rowIndex < rows && colIndex < cols) {
441
- sum += matrix[rowIndex][colIndex];
442
- }
443
- }
444
- }
445
-
446
- // Calculate the average value for the reduced matrix
447
- reducedMatrix[i][j] = sum / Math.min(factor * factor, rows * cols);
448
- }
449
- }
450
-
451
- return reducedMatrix;
452
- };
453
-
454
- const mergeMatrices = (input) => {
455
- const rows = Object.keys(input).reduce((acc, key) => {
456
- const rowData = Object.keys(input[key]).reduce((rowAcc, subKey) => {
457
- const subArray = input[key][subKey];
458
- const rowIndex = parseInt(key, 10) * subArray.length;
459
- subArray.forEach((subRow, subRowIndex) => {
460
- const fullRowIndex = rowIndex + subRowIndex;
461
- if (!rowAcc[fullRowIndex]) {
462
- rowAcc[fullRowIndex] = [];
463
- }
464
- rowAcc[fullRowIndex] = rowAcc[fullRowIndex].concat(subRow);
465
- });
466
- return rowAcc;
467
- }, []);
468
- acc = acc.concat(rowData);
469
- return acc;
470
- }, []);
471
-
472
- // Remove empty rows
473
- const nonEmptyRows = rows.filter((row) => row.some((cell) => cell !== undefined));
474
-
475
- // Remove empty columns
476
- const transpose = nonEmptyRows[0].map((col, i) => nonEmptyRows.map((row) => row[i]));
477
- const nonEmptyColumns = transpose.filter((col) => col.some((cell) => cell !== undefined));
478
-
479
- // Transpose back to rows
480
- const result = nonEmptyColumns[0].map((row, i) => nonEmptyColumns.map((col) => col[i]));
481
-
482
- return result;
483
- };
484
-
485
- const titleFormatted = (str) => cap(str.trim().replaceAll('/', '').replaceAll('-', ' '));
486
-
487
- const getSubpaths = (path) =>
488
- path
489
- .split('/')
490
- .filter(Boolean)
491
- .map((_, i, segments) => `/${segments.slice(0, i + 1).join('/')}`);
492
-
493
- function formatBytes(bytes, decimals = 2) {
494
- if (!+bytes) return '0 Bytes';
495
-
496
- const k = 1024;
497
- const dm = decimals < 0 ? 0 : decimals;
498
- const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
499
-
500
- const i = Math.floor(Math.log(bytes) / Math.log(k));
501
-
502
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
503
- }
504
-
505
- function getDirname(path) {
506
- // Split the path based on the path separator
507
- const parts = path.split(/[/|\\]/);
508
-
509
- // Remove the last element (filename)
510
- parts.pop();
511
-
512
- // If the path ends with a separator, remove the empty element
513
- if (parts[parts.length - 1] === '') {
514
- parts.pop();
515
- }
516
-
517
- // Join the remaining parts to get the directory path
518
- return parts.join('/'); // Adjust separator if needed for Windows ('\')
519
- }
520
-
521
- const isDayValid = (day) => {
522
- const date = new Date();
523
- date.setDate(day);
524
- return date.getDate() === day;
525
- };
526
-
527
- const isMonthValid = (month) => {
528
- const date = new Date();
529
- date.setMonth(month - 1);
530
- return date.getMonth() === month - 1;
531
- };
532
-
533
- const isValidDate = (day, month, year) => {
534
- if (!isDayValid(day) || !isMonthValid(month)) {
535
- return false;
536
- }
537
-
538
- const date = new Date(year, month - 1, day);
539
- return !isNaN(date.getTime());
540
- };
541
-
542
- const isValidFormat = (value, format) => {
543
- try {
544
- switch (format) {
545
- case 'ALPHANUMERIC':
546
- return /^[a-z0-9]+$/i.test(value);
547
- case 'DDMMYYYY': {
548
- const day = parseInt(value.substring(0, 2));
549
- const month = parseInt(value.substring(2, 4));
550
- const year = parseInt(value.substring(4));
551
- return isValidDate(day, month, year);
552
- }
553
- case 'YYYYDDMM': {
554
- const day = parseInt(value.substring(4, 6));
555
- const month = parseInt(value.substring(6, 8));
556
- const year = parseInt(value.substring(0, 4));
557
- return isValidDate(day, month, year);
558
- }
559
- case 'DD-MM-YYYY': {
560
- value = value.split('-');
561
- const day = parseInt(value[0]);
562
- const month = parseInt(value[1]);
563
- const year = parseInt(value[2]);
564
- return isValidDate(day, month, year);
565
- }
566
-
567
- default:
568
- return false;
569
- }
570
- } catch (error) {
571
- console.error(error);
572
- return false;
573
- }
574
- };
575
-
576
- /**
577
- * Returns the time difference between UTC time and local time, in minutes.
578
- * @memberof CommonJS
579
- */
580
- const getTimezoneOffset = () => new Date().getTimezoneOffset();
581
-
582
- // https://unicode-explorer.com/c/<unicode>
583
- // example: https://unicode-explorer.com/c/0000
584
- function cleanString(string) {
585
- // Define the problematic escape sequences unicode characters to remove with descriptions
586
- const problematicCharacters = [
587
- // '\u0000', // Null character (Represents absence of a character) not work
588
- '\u0008', // Backspace character
589
- '\u0002', // Start of Text (STX) character
590
- '\u0009', // Horizontal Tab character
591
- '\u000B', // Vertical Tab character
592
- '\u000C', // Form Feed character
593
- '\u000D', // Carriage Return character
594
- '\u001D', // Group Separator (GS) character
595
- '\u001F', // Substitution character
596
- // '\u0020', // Space character
597
- '\u200B', // Zero Width Space character
598
- '\u200C', // Zero Width Non-Joiner character
599
- '\u200D', // Zero Width Joiner character
600
- '\u200F', // Right-to-Left Mark character
601
- '\u2028', // Left-to-Right Mark character
602
- '\u2060', // Word Spacing character
603
- '\u2061', // Word Joiner character
604
- '\u2062', // Invisible Text Character character
605
- '\u2063', // Inhibit Explicit Word Joining character
606
- '\u2064', // Invisible Text Processing character
607
- ];
608
-
609
- // Replace each problematic character with an empty string
610
- return problematicCharacters.reduce((cleanString, character) => {
611
- const charRegex = new RegExp(character, 'g'); // Regular expression for character
612
- return cleanString.replace(charRegex, ''); // Replace with empty string
613
- }, string);
614
- }
615
-
616
- function splitEveryXChar(originalString, everyXChar = 30, nextCharSplit) {
617
- let modifiedString = '';
618
- const arrayString = [];
619
- let i = -1;
620
- let charSplit = false;
621
- for (let char of originalString) {
622
- i++;
623
- modifiedString += char;
624
- if (i !== 0 && i % everyXChar === 0) charSplit = true;
625
- if (modifiedString.length >= everyXChar && charSplit && (!nextCharSplit || nextCharSplit.includes(char))) {
626
- arrayString.push(newInstance(modifiedString));
627
- modifiedString = '';
628
- charSplit = false;
629
- }
630
- }
631
- if (modifiedString) arrayString.push(modifiedString);
632
- return arrayString;
633
- }
634
-
635
- const getMostFrequentValue = (arr) =>
636
- arr.sort((a, b) => arr.filter((v) => v === a).length - arr.filter((v) => v === b).length).pop();
637
-
638
- const getFillMatrix = (maxX, maxY, value = 0) =>
639
- new Array(maxY).fill().map(() => new Array(maxX).fill().map(() => value));
640
-
641
- function validatePassword(password) {
642
- let errors = [];
643
- if (!/[a-z]/.test(password))
644
- errors.push({ en: 'must contain at least one lowercase letter', es: 'debe contener al menos una letra minúscula' });
645
- if (!/[A-Z]/.test(password))
646
- errors.push({ en: 'must contain at least one uppercase letter', es: 'debe contener al menos una letra mayúscula' });
647
- if (!/\d/.test(password))
648
- errors.push({ en: 'must contain at least one number', es: 'debe contener al menos un número' });
649
- if (!/[@#$-%^&*()_+{}\[\]:;<>,.!?\/\\|`~]/.test(password))
650
- errors.push({
651
- en: 'must contain at least one special character',
652
- es: 'debe contener al menos un carácter especial',
653
- });
654
- if (password.length < 8)
655
- errors.push({ en: 'must be at least 8 characters long', es: 'debe tener al menos 8 caracteres de largo' });
656
-
657
- return errors;
658
- }
659
-
660
- function componentFromStr(numStr, percent) {
661
- const num = Math.max(0, parseInt(numStr, 10));
662
- return percent ? Math.floor((255 * Math.min(100, num)) / 100) : Math.min(255, num);
663
- }
664
-
665
- function rgbToHex(rgb) {
666
- const rgbRegex = /^rgb\(\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*\)$/;
667
- let result,
668
- r,
669
- g,
670
- b,
671
- hex = '';
672
- if ((result = rgbRegex.exec(rgb))) {
673
- r = componentFromStr(result[1], result[2]);
674
- g = componentFromStr(result[3], result[4]);
675
- b = componentFromStr(result[5], result[6]);
676
-
677
- hex = '' + (0x1000000 + (r << 16) + (g << 8) + b).toString(16).slice(1);
678
- }
679
- return hex;
680
- }
681
-
682
- export {
683
- s4,
684
- range,
685
- random,
686
- newInstance,
687
- cap,
688
- uniqueArray,
689
- orderArrayFromAttrInt,
690
- getYouTubeID,
691
- timer,
692
- getRawCsvFromArray,
693
- reOrderIntArray,
694
- capFirst,
695
- orderAbc,
696
- getDistance,
697
- decimalAdjust,
698
- round10,
699
- floor10,
700
- ceil10,
701
- JSONmatrix,
702
- getRandomPoint,
703
- objectEquals,
704
- floatRound,
705
- getId,
706
- insertTransitionCoordinates,
707
- randomHexColor,
708
- clearTerminalStringColor,
709
- getIsoDate,
710
- getValueFromJoinString,
711
- getDirection,
712
- amplifyMatrix,
713
- reduceMatrix,
714
- mergeMatrices,
715
- titleFormatted,
716
- setPad,
717
- getSubpaths,
718
- formatBytes,
719
- getDirname,
720
- isDayValid,
721
- isMonthValid,
722
- isValidDate,
723
- isValidFormat,
724
- getTimezoneOffset,
725
- cleanString,
726
- splitEveryXChar,
727
- getMostFrequentValue,
728
- getFillMatrix,
729
- validatePassword,
730
- componentFromStr,
731
- rgbToHex,
732
- };
1
+ /**
2
+ * Common JavaScript functions
3
+ * @module src/client/components/core/CommonJs.js
4
+ * @namespace CommonJS
5
+ */
6
+
7
+ /**
8
+ * The function `s4` generates a random hexadecimal string with a length of 4 characters.
9
+ * @memberof CommonJS
10
+ */
11
+ const s4 = () => (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
12
+
13
+ /**
14
+ * The `range` function generates an array of numbers within a specified range, handling both ascending
15
+ * and descending ranges.
16
+ * @param start - The `start` parameter in the `range` function represents the starting value of the
17
+ * range you want to generate.
18
+ * @param end - The `end` parameter in the `range` function represents the ending value of the range
19
+ * that you want to generate.
20
+ * @returns The `range` function returns an array containing a range of numbers starting from the
21
+ * `start` value up to the `end` value (inclusive). If `end` is less than `start`, it will recursively
22
+ * call the `range` function with the arguments swapped and then reverse the resulting array.
23
+ * @memberof CommonJS
24
+ */
25
+ const range = (start, end) => {
26
+ return end < start
27
+ ? range(end, start).reverse()
28
+ : Array.apply(0, Array(end - start + 1)).map((element, index) => index + start);
29
+ };
30
+
31
+ /**
32
+ * The `getId` function generates a unique identifier based on an array of objects or keys.
33
+ * @param arr - The `arr` parameter in the `getId` function is an array of objects or an object. If it
34
+ * is an object, the function converts it into an array of objects where each object has a key
35
+ * specified by the `keyId` parameter.
36
+ * @param suffix - The `suffix` parameter in the `getId` function is a string that can be added to
37
+ * the generated ID. It is optional and by default is an empty string. You can provide a suffix to be
38
+ * appended to the generated ID if needed.
39
+ * @param keyId - The `keyId` parameter in the `getId` function is used to specify the key in the
40
+ * array elements that contains the unique identifier (ID) for each element. By default, the function
41
+ * assumes that the ID is stored in a property named `'id'`, but you can customize this by providing
42
+ * @returns The `getId` function returns a unique identifier `_id` based on the input array `arr`,
43
+ * optional `suffix`, and `keyId`.
44
+ * @memberof CommonJS
45
+ */
46
+ const getId = (arr, suffix = '', keyId = 'id') => {
47
+ if (!Array.isArray(arr) && typeof arr === 'object')
48
+ arr = Object.keys(arr).map((id) => {
49
+ const idElement = {};
50
+ idElement[keyId] = id;
51
+ return idElement;
52
+ });
53
+ let _id;
54
+ while (arr.find((element) => element[keyId] === _id) || !_id)
55
+ _id = suffix + (s4() + s4() + s4() + s4() + s4()).slice(1);
56
+ return _id;
57
+ };
58
+
59
+ /**
60
+ * The function `random` generates a random integer within a specified range.
61
+ * @param min - The `min` parameter represents the minimum value of the range from which you want to
62
+ * generate a random number.
63
+ * @param max - The `max` parameter in the `random` function represents the maximum value that you want
64
+ * to generate a random number up to.
65
+ * @memberof CommonJS
66
+ */
67
+ const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min); // The maximum is inclusive and the minimum is inclusive
68
+
69
+ const randomHexColor = () => '#' + ((Math.random() * 0xffffff) << 0).toString(16).padStart(6, '0');
70
+
71
+ const getRawCsvFromArray = (array) =>
72
+ array[0]
73
+ ? Object.keys(array[0]).join(';') +
74
+ '\r\n' +
75
+ array
76
+ .map((x) => {
77
+ return (
78
+ Object.keys(x)
79
+ .map((attr) => x[attr])
80
+ .join(';') + '\r\n'
81
+ );
82
+ })
83
+ .join('')
84
+ : '';
85
+
86
+ const newInstance = (obj) => {
87
+ // structuredClone() 2022 ES6 feature
88
+ try {
89
+ return JSON.parse(JSON.stringify(obj));
90
+ } catch (error) {
91
+ return { error: error.message };
92
+ }
93
+ };
94
+
95
+ const cap = (str) =>
96
+ str
97
+ .toLowerCase()
98
+ .split(' ')
99
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
100
+ .join(' ');
101
+
102
+ const capFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);
103
+
104
+ const uniqueArray = (arr) => arr.filter((item, pos) => arr.indexOf(item) == pos);
105
+
106
+ const orderArrayFromAttrInt = (arr, attr, type) =>
107
+ // type -> true asc
108
+ // type -> false desc
109
+ type === 'asc' ? arr.sort((a, b) => a[attr] - b[attr]) : arr.sort((a, b) => b[attr] - a[attr]);
110
+
111
+ const getRandomPoint = (suffix, pointsArray) => {
112
+ const point = pointsArray[random(0, pointsArray.length - 1)];
113
+ const returnPoint = {};
114
+ returnPoint['x' + suffix] = point[0];
115
+ returnPoint['y' + suffix] = point[1];
116
+ return returnPoint;
117
+ };
118
+
119
+ const getYouTubeID = (url) => {
120
+ const p =
121
+ /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
122
+ if (url.match(p)) return url.match(p)[1];
123
+ return false;
124
+ };
125
+
126
+ const timer = (ms) => new Promise((res) => setTimeout(res, ms));
127
+
128
+ const reOrderIntArray = (array) => {
129
+ /* shuffle */
130
+ let currentIndex = array.length,
131
+ randomIndex;
132
+
133
+ // While there remain elements to shuffle.
134
+ while (currentIndex != 0) {
135
+ // Pick a remaining element.
136
+ randomIndex = Math.floor(Math.random() * currentIndex);
137
+ currentIndex--;
138
+
139
+ // And swap it with the current element.
140
+ [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]];
141
+ }
142
+
143
+ return array;
144
+ };
145
+
146
+ const orderAbc = (arr, attr) =>
147
+ arr.sort((a, b) => {
148
+ if (attr) {
149
+ if (a[attr] < b[attr]) {
150
+ return -1;
151
+ }
152
+ if (a[attr] > b[attr]) {
153
+ return 1;
154
+ }
155
+ } else {
156
+ if (a < b) {
157
+ return -1;
158
+ }
159
+ if (a > b) {
160
+ return 1;
161
+ }
162
+ }
163
+ return 0;
164
+ });
165
+
166
+ const JSONmatrix = (matrix) => {
167
+ if (Array.isArray(matrix))
168
+ return `[\r\n${matrix
169
+ .map((x, i) => ` ` + JSON.stringify(x) + (i === matrix.length - 1 ? '' : ',') + '\r\n')
170
+ .join('')}]`;
171
+ else
172
+ return `[\r\n${Object.keys(matrix)
173
+ .map((x, i) => ` ` + JSON.stringify(Object.values(matrix[x])) + (i === matrix.length - 1 ? '' : ',') + '\r\n')
174
+ .join('')}]`;
175
+ };
176
+
177
+ const getDistance = (x1, y1, x2, y2) => {
178
+ const disX = Math.abs(x2 - x1);
179
+ const disY = Math.abs(y2 - y1);
180
+ return Math.sqrt(disX * disX + disY * disY);
181
+ };
182
+
183
+ const setPad = (num, padValue, targetLength, endPad, separator) => {
184
+ separator = separator ? separator : '.';
185
+ let str = String(num).split(separator);
186
+ let removeSeparator = false;
187
+ if (!str[1]) {
188
+ str[1] = '';
189
+ if (!endPad) removeSeparator = true;
190
+ }
191
+ while (endPad ? str[1].length < targetLength : str[0].length < targetLength)
192
+ endPad ? (str[1] = str[1] + padValue) : (str[0] = padValue + str[0]);
193
+ return removeSeparator ? str.join(separator).replace(separator, '') : str.join(separator);
194
+ };
195
+
196
+ /**
197
+ * Decimal setting of a number.
198
+ *
199
+ * @param {String} type The type of setting.
200
+ * @param {Number} value The number.
201
+ * @param {Integer} exp The exponent (the log 10 of the base fit).
202
+ * @returns {Number} The adjusted value.
203
+ * @memberof CommonJS
204
+ */
205
+ const decimalAdjust = (type, value, exp) => {
206
+ if (typeof exp === 'undefined' || +exp === 0) {
207
+ return Math[type](value);
208
+ }
209
+ value = +value;
210
+ exp = +exp;
211
+
212
+ if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
213
+ return NaN;
214
+ }
215
+ // Shift
216
+ value = value.toString().split('e');
217
+ value = Math[type](+(value[0] + 'e' + (value[1] ? +value[1] - exp : -exp)));
218
+ // Shift back
219
+ value = value.toString().split('e');
220
+ return +(value[0] + 'e' + (value[1] ? +value[1] + exp : exp));
221
+
222
+ // https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/round
223
+ };
224
+
225
+ const floatRound = (v, d) => parseFloat(parseFloat(v).toFixed(d));
226
+
227
+ // Decimal round
228
+
229
+ const round10 = (value, exp) => {
230
+ return decimalAdjust('round', value, exp);
231
+ };
232
+
233
+ // Decimal floor
234
+
235
+ const floor10 = (value, exp) => {
236
+ return decimalAdjust('floor', value, exp);
237
+ };
238
+
239
+ // Decimal ceil
240
+
241
+ const ceil10 = (value, exp) => {
242
+ return decimalAdjust('ceil', value, exp);
243
+ };
244
+
245
+ // // Round
246
+ // round10(55.55, -1); // 55.6
247
+ // round10(55.549, -1); // 55.5
248
+ // round10(55, 1); // 60
249
+ // round10(54.9, 1); // 50
250
+ // round10(-55.55, -1); // -55.5
251
+ // round10(-55.551, -1); // -55.6
252
+ // round10(-55, 1); // -50
253
+ // round10(-55.1, 1); // -60
254
+ // round10(1.005, -2); // 1.01 -- compare this with round(1.005*100)/100 above
255
+ // // Floor
256
+ // floor10(55.59, -1); // 55.5
257
+ // floor10(59, 1); // 50
258
+ // floor10(-55.51, -1); // -55.6
259
+ // floor10(-51, 1); // -60
260
+ // // Ceil
261
+ // ceil10(55.51, -1); // 55.6
262
+ // ceil10(51, 1); // 60
263
+ // ceil10(-55.59, -1); // -55.5
264
+ // ceil10(-59, 1); // -50
265
+
266
+ function objectEquals(x, y) {
267
+ // TODO:
268
+ // https://www.npmjs.com/package/deep-equal
269
+ // https://www.npmjs.com/package/fast-deep-equal
270
+ const ok = Object.keys,
271
+ tx = typeof x,
272
+ ty = typeof y;
273
+ return x && y && tx === 'object' && tx === ty
274
+ ? ok(x).length === ok(y).length && ok(x).every((key) => objectEquals(x[key], y[key]))
275
+ : x === y;
276
+ }
277
+
278
+ function insertTransitionCoordinates(coordinates, transitionFactor) {
279
+ // Create a new array to store the resulting coordinates
280
+ const coordinatesWithTransition = [];
281
+
282
+ // Iterate over the coordinates array
283
+ for (let i = 0; i < coordinates.length - 1; i++) {
284
+ const [x1, y1] = coordinates[i];
285
+ const [x2, y2] = coordinates[i + 1];
286
+
287
+ // Add the initial integer coordinate to the new array
288
+ coordinatesWithTransition.push([x1, y1]);
289
+
290
+ // Calculate the increments for each coordinate
291
+ const incrementX = (x2 - x1) / transitionFactor;
292
+ const incrementY = (y2 - y1) / transitionFactor;
293
+
294
+ // Add the intermediate coordinates
295
+ for (let j = 1; j <= transitionFactor - 1; j++) {
296
+ const xIntermediate = x1 + incrementX * j;
297
+ const yIntermediate = y1 + incrementY * j;
298
+ coordinatesWithTransition.push([xIntermediate, yIntermediate]);
299
+ }
300
+ }
301
+
302
+ // Add the last integer coordinate to the new array
303
+ coordinatesWithTransition.push(coordinates[coordinates.length - 1]);
304
+
305
+ // Now, coordinatesWithTransition contains the coordinates with transition
306
+ return coordinatesWithTransition;
307
+ }
308
+
309
+ const getIsoDate = (date) => date.toISOString().slice(0, -5).replace('T', ' ');
310
+
311
+ const clearTerminalStringColor = (str) => str.replace(/\x1b\[[0-9;]*m/g, '');
312
+
313
+ function getValueFromJoinString(obj, path, join = '.') {
314
+ // Split the path string into an array of attribute names
315
+ const attributes = path.split(join);
316
+
317
+ // Iterate through the attributes to access the desired value
318
+ let value = obj;
319
+ for (let i = 0; i < attributes.length; i++) {
320
+ value = value[attributes[i]];
321
+
322
+ // Check if the value is null or undefined at each step
323
+ if (value === null || value === undefined) {
324
+ // If the value is null or undefined, stop the iteration
325
+ break;
326
+ }
327
+ }
328
+
329
+ return value;
330
+ }
331
+
332
+ function getDirection(options = { x1: 1, y1: 1, x2: 1, y2: 1, radians: 1 }) {
333
+ const { x1, y1, x2, y2, radians } = options;
334
+ // Calculate the angle in radians
335
+ const angle = radians !== undefined ? radians : Math.atan2(y2 - y1, x2 - x1);
336
+
337
+ // Convert the angle to degrees
338
+ let degrees = angle * (180 / Math.PI);
339
+
340
+ // Adjust the angle to be positive
341
+ if (degrees < 0) {
342
+ degrees += 360;
343
+ }
344
+
345
+ // 45 / 2 = 22.5
346
+ // formula -> 22.5 + (45*n)
347
+
348
+ // Map the angle to one of the eight directions
349
+ let direction;
350
+ if (degrees >= 337.5 || degrees < 22.5) {
351
+ // direction = 'right';
352
+ // direction = 'East';
353
+ direction = 'e';
354
+ } else if (degrees >= 22.5 && degrees < 67.5) {
355
+ // direction = 'up-right';
356
+ // direction = 'South East';
357
+ direction = 'se';
358
+ } else if (degrees >= 67.5 && degrees < 112.5) {
359
+ // direction = 'up';
360
+ // direction = 'South';
361
+ direction = 's';
362
+ } else if (degrees >= 112.5 && degrees < 157.5) {
363
+ // direction = 'up-left';
364
+ // direction = 'South West';
365
+ direction = 'sw';
366
+ } else if (degrees >= 157.5 && degrees < 202.5) {
367
+ // direction = 'left';
368
+ // direction = 'West';
369
+ direction = 'w';
370
+ } else if (degrees >= 202.5 && degrees < 247.5) {
371
+ // direction = 'down-left';
372
+ // direction = 'North West';
373
+ direction = 'nw';
374
+ } else if (degrees >= 247.5 && degrees < 292.5) {
375
+ // direction = 'down';
376
+ // direction = 'North';
377
+ direction = 'n';
378
+ } else if (degrees >= 292.5 && degrees < 337.5) {
379
+ // direction = 'down-right';
380
+ // direction = 'North East';
381
+ direction = 'ne';
382
+ }
383
+
384
+ return direction;
385
+ }
386
+
387
+ // Function to amplify a matrix in horizontal and vertical directions
388
+ const amplifyMatrix = (matrix, factor) => {
389
+ // Get the original dimensions of the matrix
390
+ const rows = matrix.length;
391
+ const cols = matrix[0].length;
392
+
393
+ // Create a new amplified matrix filled with zeros
394
+ const amplifiedMatrix = Array.from({ length: rows * factor }, () => Array(cols * factor).fill(0));
395
+
396
+ // Iterate over the original matrix
397
+ for (let i = 0; i < rows; i++) {
398
+ for (let j = 0; j < cols; j++) {
399
+ // Get the current value in the original matrix
400
+ const originalValue = matrix[i][j];
401
+
402
+ // Amplify in horizontal and vertical directions
403
+ for (let x = 0; x < factor; x++) {
404
+ for (let y = 0; y < factor; y++) {
405
+ // Assign the amplified value to the new matrix
406
+ amplifiedMatrix[i * factor + x][j * factor + y] = originalValue;
407
+ }
408
+ }
409
+ }
410
+ }
411
+
412
+ return amplifiedMatrix;
413
+ };
414
+
415
+ // Function to reduce a matrix by a factor in horizontal and vertical directions
416
+ const reduceMatrix = (matrix, factor) => {
417
+ // Get the original dimensions of the matrix
418
+ const rows = matrix.length;
419
+ const cols = matrix[0].length;
420
+
421
+ // Calculate the dimensions of the reduced matrix
422
+ const reducedRows = Math.ceil(rows / factor);
423
+ const reducedCols = Math.ceil(cols / factor);
424
+
425
+ // Create a new reduced matrix filled with zeros
426
+ const reducedMatrix = Array.from({ length: reducedRows }, () => Array(reducedCols).fill(0));
427
+
428
+ // Iterate over the original matrix
429
+ for (let i = 0; i < reducedRows; i++) {
430
+ for (let j = 0; j < reducedCols; j++) {
431
+ // Calculate the sum of values in the corresponding block of the original matrix
432
+ let sum = 0;
433
+
434
+ for (let x = 0; x < factor; x++) {
435
+ for (let y = 0; y < factor; y++) {
436
+ // Safely access the original matrix considering the boundaries
437
+ const rowIndex = i * factor + x;
438
+ const colIndex = j * factor + y;
439
+
440
+ if (rowIndex < rows && colIndex < cols) {
441
+ sum += matrix[rowIndex][colIndex];
442
+ }
443
+ }
444
+ }
445
+
446
+ // Calculate the average value for the reduced matrix
447
+ reducedMatrix[i][j] = sum / Math.min(factor * factor, rows * cols);
448
+ }
449
+ }
450
+
451
+ return reducedMatrix;
452
+ };
453
+
454
+ const mergeMatrices = (input) => {
455
+ const rows = Object.keys(input).reduce((acc, key) => {
456
+ const rowData = Object.keys(input[key]).reduce((rowAcc, subKey) => {
457
+ const subArray = input[key][subKey];
458
+ const rowIndex = parseInt(key, 10) * subArray.length;
459
+ subArray.forEach((subRow, subRowIndex) => {
460
+ const fullRowIndex = rowIndex + subRowIndex;
461
+ if (!rowAcc[fullRowIndex]) {
462
+ rowAcc[fullRowIndex] = [];
463
+ }
464
+ rowAcc[fullRowIndex] = rowAcc[fullRowIndex].concat(subRow);
465
+ });
466
+ return rowAcc;
467
+ }, []);
468
+ acc = acc.concat(rowData);
469
+ return acc;
470
+ }, []);
471
+
472
+ // Remove empty rows
473
+ const nonEmptyRows = rows.filter((row) => row.some((cell) => cell !== undefined));
474
+
475
+ // Remove empty columns
476
+ const transpose = nonEmptyRows[0].map((col, i) => nonEmptyRows.map((row) => row[i]));
477
+ const nonEmptyColumns = transpose.filter((col) => col.some((cell) => cell !== undefined));
478
+
479
+ // Transpose back to rows
480
+ const result = nonEmptyColumns[0].map((row, i) => nonEmptyColumns.map((col) => col[i]));
481
+
482
+ return result;
483
+ };
484
+
485
+ const titleFormatted = (str) => cap(str.trim().replaceAll('/', '').replaceAll('-', ' '));
486
+
487
+ const getSubpaths = (path) =>
488
+ path
489
+ .split('/')
490
+ .filter(Boolean)
491
+ .map((_, i, segments) => `/${segments.slice(0, i + 1).join('/')}`);
492
+
493
+ function formatBytes(bytes, decimals = 2) {
494
+ if (!+bytes) return '0 Bytes';
495
+
496
+ const k = 1024;
497
+ const dm = decimals < 0 ? 0 : decimals;
498
+ const sizes = ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
499
+
500
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
501
+
502
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
503
+ }
504
+
505
+ function getDirname(path) {
506
+ // Split the path based on the path separator
507
+ const parts = path.split(/[/|\\]/);
508
+
509
+ // Remove the last element (filename)
510
+ parts.pop();
511
+
512
+ // If the path ends with a separator, remove the empty element
513
+ if (parts[parts.length - 1] === '') {
514
+ parts.pop();
515
+ }
516
+
517
+ // Join the remaining parts to get the directory path
518
+ return parts.join('/'); // Adjust separator if needed for Windows ('\')
519
+ }
520
+
521
+ const isDayValid = (day) => {
522
+ const date = new Date();
523
+ date.setDate(day);
524
+ return date.getDate() === day;
525
+ };
526
+
527
+ const isMonthValid = (month) => {
528
+ const date = new Date();
529
+ date.setMonth(month - 1);
530
+ return date.getMonth() === month - 1;
531
+ };
532
+
533
+ const isValidDate = (day, month, year) => {
534
+ if (!isDayValid(day) || !isMonthValid(month)) {
535
+ return false;
536
+ }
537
+
538
+ const date = new Date(year, month - 1, day);
539
+ return !isNaN(date.getTime());
540
+ };
541
+
542
+ const isValidFormat = (value, format) => {
543
+ try {
544
+ switch (format) {
545
+ case 'ALPHANUMERIC':
546
+ return /^[a-z0-9]+$/i.test(value);
547
+ case 'DDMMYYYY': {
548
+ const day = parseInt(value.substring(0, 2));
549
+ const month = parseInt(value.substring(2, 4));
550
+ const year = parseInt(value.substring(4));
551
+ return isValidDate(day, month, year);
552
+ }
553
+ case 'YYYYDDMM': {
554
+ const day = parseInt(value.substring(4, 6));
555
+ const month = parseInt(value.substring(6, 8));
556
+ const year = parseInt(value.substring(0, 4));
557
+ return isValidDate(day, month, year);
558
+ }
559
+ case 'DD-MM-YYYY': {
560
+ value = value.split('-');
561
+ const day = parseInt(value[0]);
562
+ const month = parseInt(value[1]);
563
+ const year = parseInt(value[2]);
564
+ return isValidDate(day, month, year);
565
+ }
566
+
567
+ default:
568
+ return false;
569
+ }
570
+ } catch (error) {
571
+ console.error(error);
572
+ return false;
573
+ }
574
+ };
575
+
576
+ /**
577
+ * Returns the time difference between UTC time and local time, in minutes.
578
+ * @memberof CommonJS
579
+ */
580
+ const getTimezoneOffset = () => new Date().getTimezoneOffset();
581
+
582
+ // https://unicode-explorer.com/c/<unicode>
583
+ // example: https://unicode-explorer.com/c/0000
584
+ function cleanString(string) {
585
+ // Define the problematic escape sequences unicode characters to remove with descriptions
586
+ const problematicCharacters = [
587
+ // '\u0000', // Null character (Represents absence of a character) not work
588
+ '\u0008', // Backspace character
589
+ '\u0002', // Start of Text (STX) character
590
+ '\u0009', // Horizontal Tab character
591
+ '\u000B', // Vertical Tab character
592
+ '\u000C', // Form Feed character
593
+ '\u000D', // Carriage Return character
594
+ '\u001D', // Group Separator (GS) character
595
+ '\u001F', // Substitution character
596
+ // '\u0020', // Space character
597
+ '\u200B', // Zero Width Space character
598
+ '\u200C', // Zero Width Non-Joiner character
599
+ '\u200D', // Zero Width Joiner character
600
+ '\u200F', // Right-to-Left Mark character
601
+ '\u2028', // Left-to-Right Mark character
602
+ '\u2060', // Word Spacing character
603
+ '\u2061', // Word Joiner character
604
+ '\u2062', // Invisible Text Character character
605
+ '\u2063', // Inhibit Explicit Word Joining character
606
+ '\u2064', // Invisible Text Processing character
607
+ ];
608
+
609
+ // Replace each problematic character with an empty string
610
+ return problematicCharacters.reduce((cleanString, character) => {
611
+ const charRegex = new RegExp(character, 'g'); // Regular expression for character
612
+ return cleanString.replace(charRegex, ''); // Replace with empty string
613
+ }, string);
614
+ }
615
+
616
+ function splitEveryXChar(originalString, everyXChar = 30, nextCharSplit) {
617
+ let modifiedString = '';
618
+ const arrayString = [];
619
+ let i = -1;
620
+ let charSplit = false;
621
+ for (let char of originalString) {
622
+ i++;
623
+ modifiedString += char;
624
+ if (i !== 0 && i % everyXChar === 0) charSplit = true;
625
+ if (modifiedString.length >= everyXChar && charSplit && (!nextCharSplit || nextCharSplit.includes(char))) {
626
+ arrayString.push(newInstance(modifiedString));
627
+ modifiedString = '';
628
+ charSplit = false;
629
+ }
630
+ }
631
+ if (modifiedString) arrayString.push(modifiedString);
632
+ return arrayString;
633
+ }
634
+
635
+ const getMostFrequentValue = (arr) =>
636
+ arr.sort((a, b) => arr.filter((v) => v === a).length - arr.filter((v) => v === b).length).pop();
637
+
638
+ const getFillMatrix = (maxX, maxY, value = 0) =>
639
+ new Array(maxY).fill().map(() => new Array(maxX).fill().map(() => value));
640
+
641
+ function validatePassword(password) {
642
+ let errors = [];
643
+ if (!/[a-z]/.test(password))
644
+ errors.push({ en: 'must contain at least one lowercase letter', es: 'debe contener al menos una letra minúscula' });
645
+ if (!/[A-Z]/.test(password))
646
+ errors.push({ en: 'must contain at least one uppercase letter', es: 'debe contener al menos una letra mayúscula' });
647
+ if (!/\d/.test(password))
648
+ errors.push({ en: 'must contain at least one number', es: 'debe contener al menos un número' });
649
+ if (!/[@#$-%^&*()_+{}\[\]:;<>,.!?\/\\|`~]/.test(password))
650
+ errors.push({
651
+ en: 'must contain at least one special character',
652
+ es: 'debe contener al menos un carácter especial',
653
+ });
654
+ if (password.length < 8)
655
+ errors.push({ en: 'must be at least 8 characters long', es: 'debe tener al menos 8 caracteres de largo' });
656
+
657
+ return errors;
658
+ }
659
+
660
+ function componentFromStr(numStr, percent) {
661
+ const num = Math.max(0, parseInt(numStr, 10));
662
+ return percent ? Math.floor((255 * Math.min(100, num)) / 100) : Math.min(255, num);
663
+ }
664
+
665
+ function rgbToHex(rgb) {
666
+ const rgbRegex = /^rgb\(\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*,\s*(-?\d+)(%?)\s*\)$/;
667
+ let result,
668
+ r,
669
+ g,
670
+ b,
671
+ hex = '';
672
+ if ((result = rgbRegex.exec(rgb))) {
673
+ r = componentFromStr(result[1], result[2]);
674
+ g = componentFromStr(result[3], result[4]);
675
+ b = componentFromStr(result[5], result[6]);
676
+
677
+ hex = '' + (0x1000000 + (r << 16) + (g << 8) + b).toString(16).slice(1);
678
+ }
679
+ return hex;
680
+ }
681
+
682
+ const getCapVariableName = (value = 'default') => cap(value.replaceAll('-', ' ')).replaceAll(' ', '');
683
+
684
+ export {
685
+ s4,
686
+ range,
687
+ random,
688
+ newInstance,
689
+ cap,
690
+ uniqueArray,
691
+ orderArrayFromAttrInt,
692
+ getYouTubeID,
693
+ timer,
694
+ getRawCsvFromArray,
695
+ reOrderIntArray,
696
+ capFirst,
697
+ orderAbc,
698
+ getDistance,
699
+ decimalAdjust,
700
+ round10,
701
+ floor10,
702
+ ceil10,
703
+ JSONmatrix,
704
+ getRandomPoint,
705
+ objectEquals,
706
+ floatRound,
707
+ getId,
708
+ insertTransitionCoordinates,
709
+ randomHexColor,
710
+ clearTerminalStringColor,
711
+ getIsoDate,
712
+ getValueFromJoinString,
713
+ getDirection,
714
+ amplifyMatrix,
715
+ reduceMatrix,
716
+ mergeMatrices,
717
+ titleFormatted,
718
+ setPad,
719
+ getSubpaths,
720
+ formatBytes,
721
+ getDirname,
722
+ isDayValid,
723
+ isMonthValid,
724
+ isValidDate,
725
+ isValidFormat,
726
+ getTimezoneOffset,
727
+ cleanString,
728
+ splitEveryXChar,
729
+ getMostFrequentValue,
730
+ getFillMatrix,
731
+ validatePassword,
732
+ componentFromStr,
733
+ rgbToHex,
734
+ getCapVariableName,
735
+ };