@osimatic/helpers-js 1.4.25 → 1.4.26

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 (110) hide show
  1. package/.claude/settings.local.json +1 -1
  2. package/duration.js +174 -125
  3. package/file.js +19 -4
  4. package/google_charts.js +2 -1
  5. package/location.js +5 -1
  6. package/media.js +6 -6
  7. package/multi_files_input.js +3 -1
  8. package/package.json +2 -1
  9. package/paging.js +2 -2
  10. package/tests/__mocks__/socket.io-client.js +13 -0
  11. package/tests/count_down.test.js +580 -0
  12. package/tests/details_sub_array.test.js +367 -0
  13. package/tests/file.test.js +210 -0
  14. package/tests/flash_message.test.js +297 -0
  15. package/tests/form_date.test.js +1142 -0
  16. package/tests/form_helper.test.js +780 -130
  17. package/tests/google_charts.test.js +768 -0
  18. package/tests/google_maps.test.js +655 -0
  19. package/tests/google_recaptcha.test.js +441 -0
  20. package/tests/import_from_csv.test.js +797 -0
  21. package/tests/list_box.test.js +255 -0
  22. package/tests/location.test.js +86 -0
  23. package/tests/media.test.js +15 -0
  24. package/tests/multi_files_input.test.js +1015 -0
  25. package/tests/multiple_action_in_table.test.js +477 -0
  26. package/tests/paging.test.js +646 -0
  27. package/tests/select_all.test.js +360 -0
  28. package/tests/sortable_list.test.js +602 -0
  29. package/tests/string.test.js +16 -0
  30. package/tests/web_rtc.test.js +458 -0
  31. package/tests/web_socket.test.js +538 -0
  32. package/tmpclaude-00a6-cwd +0 -1
  33. package/tmpclaude-0526-cwd +0 -1
  34. package/tmpclaude-0973-cwd +0 -1
  35. package/tmpclaude-0b61-cwd +0 -1
  36. package/tmpclaude-0fa4-cwd +0 -1
  37. package/tmpclaude-104f-cwd +0 -1
  38. package/tmpclaude-1468-cwd +0 -1
  39. package/tmpclaude-146f-cwd +0 -1
  40. package/tmpclaude-223d-cwd +0 -1
  41. package/tmpclaude-2330-cwd +0 -1
  42. package/tmpclaude-282a-cwd +0 -1
  43. package/tmpclaude-2846-cwd +0 -1
  44. package/tmpclaude-28a6-cwd +0 -1
  45. package/tmpclaude-2b5a-cwd +0 -1
  46. package/tmpclaude-2def-cwd +0 -1
  47. package/tmpclaude-324b-cwd +0 -1
  48. package/tmpclaude-35d3-cwd +0 -1
  49. package/tmpclaude-3906-cwd +0 -1
  50. package/tmpclaude-3b32-cwd +0 -1
  51. package/tmpclaude-3da9-cwd +0 -1
  52. package/tmpclaude-3dc3-cwd +0 -1
  53. package/tmpclaude-3e3b-cwd +0 -1
  54. package/tmpclaude-43b6-cwd +0 -1
  55. package/tmpclaude-4495-cwd +0 -1
  56. package/tmpclaude-462f-cwd +0 -1
  57. package/tmpclaude-4aa8-cwd +0 -1
  58. package/tmpclaude-4b29-cwd +0 -1
  59. package/tmpclaude-4db5-cwd +0 -1
  60. package/tmpclaude-4e01-cwd +0 -1
  61. package/tmpclaude-5101-cwd +0 -1
  62. package/tmpclaude-524f-cwd +0 -1
  63. package/tmpclaude-5636-cwd +0 -1
  64. package/tmpclaude-5cdd-cwd +0 -1
  65. package/tmpclaude-5f1f-cwd +0 -1
  66. package/tmpclaude-6078-cwd +0 -1
  67. package/tmpclaude-622e-cwd +0 -1
  68. package/tmpclaude-6802-cwd +0 -1
  69. package/tmpclaude-6e36-cwd +0 -1
  70. package/tmpclaude-7793-cwd +0 -1
  71. package/tmpclaude-7f96-cwd +0 -1
  72. package/tmpclaude-8566-cwd +0 -1
  73. package/tmpclaude-8874-cwd +0 -1
  74. package/tmpclaude-8915-cwd +0 -1
  75. package/tmpclaude-8c8b-cwd +0 -1
  76. package/tmpclaude-94df-cwd +0 -1
  77. package/tmpclaude-9859-cwd +0 -1
  78. package/tmpclaude-9ac5-cwd +0 -1
  79. package/tmpclaude-9f18-cwd +0 -1
  80. package/tmpclaude-a202-cwd +0 -1
  81. package/tmpclaude-a741-cwd +0 -1
  82. package/tmpclaude-ab5f-cwd +0 -1
  83. package/tmpclaude-b008-cwd +0 -1
  84. package/tmpclaude-b0a1-cwd +0 -1
  85. package/tmpclaude-b63d-cwd +0 -1
  86. package/tmpclaude-b681-cwd +0 -1
  87. package/tmpclaude-b72d-cwd +0 -1
  88. package/tmpclaude-b92f-cwd +0 -1
  89. package/tmpclaude-bc49-cwd +0 -1
  90. package/tmpclaude-bc50-cwd +0 -1
  91. package/tmpclaude-bccf-cwd +0 -1
  92. package/tmpclaude-be55-cwd +0 -1
  93. package/tmpclaude-c228-cwd +0 -1
  94. package/tmpclaude-c717-cwd +0 -1
  95. package/tmpclaude-c7ce-cwd +0 -1
  96. package/tmpclaude-cf3e-cwd +0 -1
  97. package/tmpclaude-d142-cwd +0 -1
  98. package/tmpclaude-d5bc-cwd +0 -1
  99. package/tmpclaude-d6ae-cwd +0 -1
  100. package/tmpclaude-d77a-cwd +0 -1
  101. package/tmpclaude-d8da-cwd +0 -1
  102. package/tmpclaude-dbdb-cwd +0 -1
  103. package/tmpclaude-de61-cwd +0 -1
  104. package/tmpclaude-de81-cwd +0 -1
  105. package/tmpclaude-df9d-cwd +0 -1
  106. package/tmpclaude-e786-cwd +0 -1
  107. package/tmpclaude-f01d-cwd +0 -1
  108. package/tmpclaude-f2a9-cwd +0 -1
  109. package/tmpclaude-fc36-cwd +0 -1
  110. package/tmpclaude-ffef-cwd +0 -1
@@ -7,7 +7,7 @@
7
7
  "Bash(npm login)",
8
8
  "Bash(npm publish:*)",
9
9
  "Bash(npm logout:*)",
10
- "Bash(node -e:*)",
10
+ "Bash(node -e:*)"
11
11
  ]
12
12
  }
13
13
  }
package/duration.js CHANGED
@@ -1,196 +1,245 @@
1
1
 
2
2
  class Duration {
3
3
 
4
- // ---------- Nb jours ----------
4
+ // -------------------------------------------------------------------------
5
+ // Days formatting
6
+ // -------------------------------------------------------------------------
5
7
 
6
- static formatNbDays(nbDays, locale='fr-FR') {
8
+ static formatDays(days, locale = 'fr-FR') {
7
9
  return new Intl.NumberFormat(locale, {
8
10
  minimumFractionDigits: 2,
9
11
  maximumFractionDigits: 2
10
- }).format(nbDays);
12
+ }).format(days);
11
13
  }
12
- static formatNbDaysIfPositive(nbDays) {
13
- return nbDays < 0 ? '-' : this.formatNbDays(nbDays);
14
+
15
+ static formatDaysIfPositive(days) {
16
+ return days < 0 ? '-' : this.formatDays(days);
14
17
  }
15
- static formatNbDaysWithColor(nbDays) {
16
- return '<span class="text-'+(nbDays<0?'danger':'success')+'">'+this.formatNbDays(nbDays)+'</span>';
18
+
19
+ static formatDaysWithColor(days) {
20
+ return '<span class="text-' + (days < 0 ? 'danger' : 'success') + '">' + this.formatDays(days) + '</span>';
17
21
  }
18
22
 
19
- // ---------- Durée en seconde ----------
23
+ // -------------------------------------------------------------------------
24
+ // Seconds — conversion
25
+ // -------------------------------------------------------------------------
20
26
 
21
- static convertInputTimeValueToDuration(inputTimeValue) {
22
- if (null === inputTimeValue || -1 === inputTimeValue.indexOf(':')) {
27
+ static parseTimeInputToSeconds(timeInput) {
28
+ if (null === timeInput || -1 === timeInput.indexOf(':')) {
23
29
  return 0;
24
30
  }
25
- let arrayTime = inputTimeValue.split(':');
26
- const nbHours = typeof arrayTime[0] != 'undefined' ? parseInt(arrayTime[0]) || 0 : 0;
31
+ let arrayTime = timeInput.split(':');
32
+ const nbHours = typeof arrayTime[0] != 'undefined' ? parseInt(arrayTime[0]) || 0 : 0;
27
33
  const nbMinutes = typeof arrayTime[1] != 'undefined' ? parseInt(arrayTime[1]) || 0 : 0;
28
34
  const nbSeconds = typeof arrayTime[2] != 'undefined' ? parseInt(arrayTime[2]) || 0 : 0;
29
35
  return nbHours * 3600 + nbMinutes * 60 + nbSeconds;
30
36
  }
31
37
 
32
- static convertToDurationAsInputTimeValue(durationInSeconds) {
33
- return Duration.convertToDurationInHourChronoDisplay(Math.abs(durationInSeconds), 'input_time');
38
+ // -------------------------------------------------------------------------
39
+ // Seconds — formatting
40
+ // -------------------------------------------------------------------------
41
+
42
+ static formatSecondsAsTimeInput(seconds) {
43
+ return Duration.formatSecondsAsChrono(Math.abs(seconds), 'input_time');
34
44
  }
35
45
 
36
- static convertToDurationInHourChronoDisplay(durationInSeconds, displayMode='chrono') {
37
- durationInSeconds = Math.round(durationInSeconds);
46
+ static formatSecondsAsChrono(seconds, displayMode = 'chrono', withSeconds = true) {
47
+ seconds = Math.round(seconds);
48
+ const absoluteSeconds = Math.abs(seconds);
49
+
50
+ let secs = absoluteSeconds % 60;
51
+ let remainder = (absoluteSeconds % 3600) - secs;
52
+ let minutes = remainder / 60;
53
+ remainder = absoluteSeconds - (absoluteSeconds % 3600);
54
+ let hours = remainder / 3600;
38
55
 
39
- let durationInSecondsOriginal = durationInSeconds;
40
- durationInSeconds = Math.abs(durationInSeconds);
41
- let seconds = ( durationInSeconds % 60 );
42
- let remander = ( durationInSeconds % 3600 ) - seconds;
43
- let minutes = ( remander / 60 );
44
- remander = ( durationInSeconds ) - ( durationInSeconds % 3600 );
45
- let hours = ( remander / 3600 );
46
- if(hours.toString().length < 2) hours = '0'+hours;
47
- if(hours.toString().charAt(0) === "-") hours[0] = '0';
48
- if(minutes.toString().length < 2) minutes = '0'+minutes;
49
- if(minutes.toString().charAt(0) === "-") minutes[0] = '0';
50
- if(seconds.toString().length < 2) seconds = '0'+seconds;
51
- return (durationInSecondsOriginal < 0 ? '- ' : '')+hours+':'+minutes+(displayMode==='input_time'?':':'.')+seconds;
56
+ hours = hours.toString().length < 2 ? '0' + hours : hours;
57
+ minutes = minutes.toString().length < 2 ? '0' + minutes : minutes;
58
+
59
+ let result = (seconds < 0 ? '- ' : '') + hours + ':' + minutes;
60
+ if (withSeconds) {
61
+ secs = secs.toString().length < 2 ? '0' + secs : secs;
62
+ result += (displayMode === 'input_time' ? ':' : '.') + secs;
63
+ }
64
+ return result;
52
65
  }
53
66
 
54
- static convertToDurationInHourStringDisplay(durationInSeconds, withSeconds=true, withMinutes=true, withMinuteLabel=true, fullLabel=false, hideHourIfZeroHour=false) {
55
- durationInSeconds = Math.round(durationInSeconds);
67
+ static formatSecondsAsString(seconds, withSeconds = true, withMinutes = true, withMinuteLabel = true, fullLabel = false, hideHourIfZero = false) {
68
+ seconds = Math.round(seconds);
56
69
 
57
- // Heures
58
- let strHeure = '';
59
- let nbHeures = this.getNbHoursOfDurationInSeconds(durationInSeconds);
60
- if (!hideHourIfZeroHour || nbHeures > 0) {
61
- strHeure += nbHeures;
70
+ // Hours
71
+ let strHours = '';
72
+ let nbHours = this.totalHours(seconds);
73
+ if (!hideHourIfZero || nbHours > 0) {
74
+ strHours += nbHours;
62
75
  if (fullLabel) {
63
- strHeure += ' heure'+(nbHeures>1?'s':'');
64
- }
65
- else {
66
- strHeure += 'h';
76
+ strHours += ' heure' + (nbHours > 1 ? 's' : '');
77
+ } else {
78
+ strHours += 'h';
67
79
  }
68
80
  }
69
-
81
+
70
82
  // Minutes
71
- let strMinute = '';
83
+ let strMinutes = '';
72
84
  if (withMinutes) {
73
- let nbMinutes = this.getNbMinutesRemainingOfDurationInSeconds(durationInSeconds);
74
- strMinute += ' ';
85
+ let nbMinutes = this.remainingMinutes(seconds);
86
+ strMinutes += ' ';
75
87
  if (fullLabel) {
76
- strMinute += nbMinutes.toString()+(withMinuteLabel ? ' minute'+(nbMinutes>1?'s':'') : '');
77
- }
78
- else {
79
- strMinute += nbMinutes.toString().padStart(2, '0')+(withMinuteLabel ? 'min' : '');
88
+ strMinutes += nbMinutes.toString() + (withMinuteLabel ? ' minute' + (nbMinutes > 1 ? 's' : '') : '');
89
+ } else {
90
+ strMinutes += nbMinutes.toString().padStart(2, '0') + (withMinuteLabel ? 'min' : '');
80
91
  }
81
92
  }
82
93
 
83
- // Secondes
84
- let strSeconde = '';
94
+ // Seconds
95
+ let strSeconds = '';
85
96
  if (withSeconds) {
86
- let nbSecondes = this.getNbSecondsRemainingOfDurationInSeconds(durationInSeconds);
87
- strSeconde += ' ';
97
+ let nbSeconds = this.remainingSeconds(seconds);
98
+ strSeconds += ' ';
88
99
  if (fullLabel) {
89
- strSeconde += nbSecondes.toString()+' seconde'+(nbSecondes>1?'s':'');
90
- }
91
- else {
92
- strSeconde += nbSecondes.toString().padStart(2, '0')+'s';
100
+ strSeconds += nbSeconds.toString() + ' seconde' + (nbSeconds > 1 ? 's' : '');
101
+ } else {
102
+ strSeconds += nbSeconds.toString().padStart(2, '0') + 's';
93
103
  }
94
104
  }
95
-
96
- return (strHeure+strMinute+strSeconde).trim();
105
+
106
+ return (strHours + strMinutes + strSeconds).trim();
97
107
  }
98
108
 
99
- static roundNbSeconds(durationInSeconds, roundPrecision, roundMode='close') {
100
- let hours = Math.floor(durationInSeconds / 3600);
101
- let minutes = Math.floor((durationInSeconds % 3600) / 60);
102
- let seconds = durationInSeconds % 60;
109
+ // -------------------------------------------------------------------------
110
+ // Seconds rounding
111
+ // -------------------------------------------------------------------------
103
112
 
104
- let hoursRounded = hours;
105
- let minutesRounded = minutes;
106
- let secondsRounded = seconds;
113
+ static roundSeconds(seconds, precision, roundMode = 'close') {
114
+ let hours = Math.floor(seconds / 3600);
115
+ let minutes = Math.floor((seconds % 3600) / 60);
116
+ let secs = seconds % 60;
107
117
 
108
- if (roundPrecision > 0) {
109
- let minutesRemaining = minutes % roundPrecision;
110
- let minutesRemainingAndSecondsAsCentieme = minutesRemaining + seconds/60;
111
- if (minutesRemainingAndSecondsAsCentieme === 0) {
112
- // pas d'arrondissement
113
- }
114
- else {
115
- let halfRoundPrecision = roundPrecision / 2;
116
- hoursRounded = hours;
118
+ let hoursRounded = hours;
119
+ let minutesRounded = minutes;
120
+ let secondsRounded = secs;
121
+
122
+ if (precision > 0) {
123
+ let minutesRemaining = minutes % precision;
124
+ let minutesRemainingAndSecondsAsFraction = minutesRemaining + secs / 60;
125
+ if (minutesRemainingAndSecondsAsFraction === 0) {
126
+ // already aligned, no rounding needed
127
+ } else {
128
+ let halfPrecision = precision / 2;
129
+ hoursRounded = hours;
117
130
  secondsRounded = 0;
118
- if (roundMode === 'up' || (roundMode === 'close' && minutesRemainingAndSecondsAsCentieme > halfRoundPrecision)) {
119
- // Arrondissement au dessus
120
- if (minutes > (60-roundPrecision)) {
131
+ if (roundMode === 'up' || (roundMode === 'close' && minutesRemainingAndSecondsAsFraction > halfPrecision)) {
132
+ // Round up
133
+ if (minutes > (60 - precision)) {
121
134
  minutesRounded = 0;
122
135
  hoursRounded++;
136
+ } else {
137
+ minutesRounded = (minutes - minutesRemaining) + precision;
123
138
  }
124
- else {
125
- minutesRounded = (minutes-minutesRemaining)+roundPrecision;
126
- }
127
- }
128
- else {
129
- // Arrondissement au dessous
130
- minutesRounded = (minutes-minutesRemaining);
139
+ } else {
140
+ // Round down
141
+ minutesRounded = minutes - minutesRemaining;
131
142
  }
132
143
  }
133
144
  }
134
- // console.log(element.data('duration_default'), durationInSeconds, hours, minutes, seconds, '->', secondsTotalRounded, hoursRounded, minutesRounded, secondsRounded);
145
+
135
146
  return hoursRounded * 3600 + minutesRounded * 60 + secondsRounded;
136
147
  }
137
148
 
138
- static getNbDaysOfDurationInSeconds(durationInSeconds) {
139
- return Math.floor(durationInSeconds / 86400);
140
- }
141
- static getNbHoursOfDurationInSeconds(durationInSeconds) {
142
- return Math.floor(durationInSeconds / 3600);
143
- }
144
- static getNbMinutesOfDurationInSeconds(durationInSeconds) {
145
- return Math.floor(durationInSeconds / 60);
149
+ // -------------------------------------------------------------------------
150
+ // Seconds total extraction
151
+ // -------------------------------------------------------------------------
152
+
153
+ static totalDays(seconds) {
154
+ return Math.floor(seconds / 86400);
146
155
  }
147
156
 
148
- /*static getNbMinutesRemaining(durationInSeconds) {
149
- var remander = ( durationInSeconds % 3600 ) - ( durationInSeconds % 60 );
150
- return ( remander / 60 );
157
+ static totalHours(seconds) {
158
+ return Math.floor(seconds / 3600);
151
159
  }
152
- static getNbHoursOfDurationInSeconds(durationInSeconds) {
153
- // return (this.getNbDaysOfDurationInSeconds(durationInSeconds)*24)+this.getNbHoursRemainingOfDurationInSeconds(durationInSeconds);
154
- return (durationInSeconds - (durationInSeconds % 3600)) / 3600;
160
+
161
+ static totalMinutes(seconds) {
162
+ return Math.floor(seconds / 60);
155
163
  }
156
- static getNbMinutesOfDurationInSeconds(durationInSeconds) {
157
- // return (this.getNbDaysOfDurationInSeconds(durationInSeconds)*24*60)+(this.getNbHoursRemainingOfDurationInSeconds(durationInSeconds)*60)+this.getNbMinutesRemainingOfDurationInSeconds(durationInSeconds);
158
- return (durationInSeconds - (durationInSeconds % 60)) / 60;
159
- }*/
160
164
 
161
- static getNbHoursRemainingOfDurationInSeconds(durationInSeconds) {
162
- return this.getNbHoursOfDurationInSeconds(durationInSeconds % 86400);
165
+ // -------------------------------------------------------------------------
166
+ // Seconds remaining extraction
167
+ // -------------------------------------------------------------------------
168
+
169
+ static remainingHours(seconds) {
170
+ return this.totalHours(seconds % 86400);
163
171
  }
164
- static getNbMinutesRemainingOfDurationInSeconds(durationInSeconds) {
165
- return this.getNbMinutesOfDurationInSeconds(durationInSeconds % 3600);
172
+
173
+ static remainingMinutes(seconds) {
174
+ return this.totalMinutes(seconds % 3600);
166
175
  }
167
- static getNbSecondsRemainingOfDurationInSeconds(durationInSeconds) {
168
- return durationInSeconds % 60;
176
+
177
+ static remainingSeconds(seconds) {
178
+ return seconds % 60;
169
179
  }
170
180
 
171
- // ---------- Durée en centième d'heure ----------
181
+ // -------------------------------------------------------------------------
182
+ // Decimal hours (hundredth of an hour)
183
+ // -------------------------------------------------------------------------
172
184
 
173
- static convertToDurationAsHundredthOfAnHour(durationInSeconds) {
174
- let hour = Math.floor(durationInSeconds / 3600);
175
- let minutes = durationInSeconds % 3600;
176
- minutes = Math.floor(minutes / 60);
177
- // minutes = minutes - (minutes % 60);
178
- let minCentieme = Math.round( (minutes / 60 ) * 100 );
179
- return hour+(minCentieme/100);
180
- //return parseFloat(hour+'.'+minCentieme);
185
+ static toDecimalHours(seconds) {
186
+ let hour = Math.floor(seconds / 3600);
187
+ let minutes = Math.floor((seconds % 3600) / 60);
188
+ let centieme = Math.round((minutes / 60) * 100);
189
+ return hour + (centieme / 100);
181
190
  }
182
191
 
183
- static getNbHoursOfHundredthOfAnHour(durationAsHundredthOfAnHour) {
184
- return Math.trunc(durationAsHundredthOfAnHour);
192
+ static getHoursFromDecimal(decimalHours) {
193
+ return Math.trunc(decimalHours);
185
194
  }
186
195
 
187
- static getNbMinutesOfHundredthOfAnHour(durationAsHundredthOfAnHour) {
188
- // Extraire la partie décimale et convertir en minutes
189
- // Ex: 1.5h -> 0.5 * 60 = 30 minutes
190
- const decimalPart = durationAsHundredthOfAnHour - Math.floor(durationAsHundredthOfAnHour);
191
- return Math.floor(decimalPart * 60);
196
+ static getMinutesFromDecimal(decimalHours) {
197
+ const decimal = decimalHours - Math.floor(decimalHours);
198
+ return Math.floor(decimal * 60);
192
199
  }
193
200
 
201
+ // -------------------------------------------------------------------------
202
+ // Deprecated aliases — kept for backwards compatibility
203
+ // -------------------------------------------------------------------------
204
+
205
+ /** @deprecated Use {@link formatDays} instead */
206
+ static formatNbDays(nbDays, locale = 'fr-FR') { return this.formatDays(nbDays, locale); }
207
+ /** @deprecated Use {@link formatDaysIfPositive} instead */
208
+ static formatNbDaysIfPositive(nbDays) { return this.formatDaysIfPositive(nbDays); }
209
+ /** @deprecated Use {@link formatDaysWithColor} instead */
210
+ static formatNbDaysWithColor(nbDays) { return this.formatDaysWithColor(nbDays); }
211
+
212
+ /** @deprecated Use {@link parseTimeInputToSeconds} instead */
213
+ static convertInputTimeValueToDuration(inputTimeValue) { return this.parseTimeInputToSeconds(inputTimeValue); }
214
+ /** @deprecated Use {@link formatSecondsAsTimeInput} instead */
215
+ static convertToDurationAsInputTimeValue(durationInSeconds) { return this.formatSecondsAsTimeInput(durationInSeconds); }
216
+ /** @deprecated Use {@link formatSecondsAsChrono} instead */
217
+ static convertToDurationInHourChronoDisplay(durationInSeconds, displayMode = 'chrono') { return this.formatSecondsAsChrono(durationInSeconds, displayMode); }
218
+ /** @deprecated Use {@link formatSecondsAsString} instead */
219
+ static convertToDurationInHourStringDisplay(durationInSeconds, withSeconds = true, withMinutes = true, withMinuteLabel = true, fullLabel = false, hideHourIfZeroHour = false) { return this.formatSecondsAsString(durationInSeconds, withSeconds, withMinutes, withMinuteLabel, fullLabel, hideHourIfZeroHour); }
220
+ /** @deprecated Use {@link roundSeconds} instead */
221
+ static roundNbSeconds(durationInSeconds, roundPrecision, roundMode = 'close') { return this.roundSeconds(durationInSeconds, roundPrecision, roundMode); }
222
+
223
+ /** @deprecated Use {@link totalDays} instead */
224
+ static getNbDaysOfDurationInSeconds(durationInSeconds) { return this.totalDays(durationInSeconds); }
225
+ /** @deprecated Use {@link totalHours} instead */
226
+ static getNbHoursOfDurationInSeconds(durationInSeconds) { return this.totalHours(durationInSeconds); }
227
+ /** @deprecated Use {@link totalMinutes} instead */
228
+ static getNbMinutesOfDurationInSeconds(durationInSeconds) { return this.totalMinutes(durationInSeconds); }
229
+
230
+ /** @deprecated Use {@link remainingHours} instead */
231
+ static getNbHoursRemainingOfDurationInSeconds(durationInSeconds) { return this.remainingHours(durationInSeconds); }
232
+ /** @deprecated Use {@link remainingMinutes} instead */
233
+ static getNbMinutesRemainingOfDurationInSeconds(durationInSeconds) { return this.remainingMinutes(durationInSeconds); }
234
+ /** @deprecated Use {@link remainingSeconds} instead */
235
+ static getNbSecondsRemainingOfDurationInSeconds(durationInSeconds) { return this.remainingSeconds(durationInSeconds); }
236
+
237
+ /** @deprecated Use {@link toDecimalHours} instead */
238
+ static convertToDurationAsHundredthOfAnHour(durationInSeconds) { return this.toDecimalHours(durationInSeconds); }
239
+ /** @deprecated Use {@link getHoursFromDecimal} instead */
240
+ static getNbHoursOfHundredthOfAnHour(durationAsHundredthOfAnHour) { return this.getHoursFromDecimal(durationAsHundredthOfAnHour); }
241
+ /** @deprecated Use {@link getMinutesFromDecimal} instead */
242
+ static getNbMinutesOfHundredthOfAnHour(durationAsHundredthOfAnHour) { return this.getMinutesFromDecimal(durationAsHundredthOfAnHour); }
194
243
 
195
244
  }
196
245
 
package/file.js CHANGED
@@ -124,10 +124,25 @@ class Img {
124
124
  }
125
125
 
126
126
  static setBlobToImg(img, blob) {
127
- // img.attr('src', btoa(unescape(encodeURIComponent(data))));
128
- // img.attr('src', 'data:image/png;base64, '+btoa(unescape(encodeURIComponent(data))));
129
- let urlCreator = window.URL || window.webkitURL;
130
- img.attr('src', urlCreator.createObjectURL(blob));
127
+ // Validation de l'élément img
128
+ if (!img || !img.length) {
129
+ console.error('Invalid img element provided to setBlobToImg');
130
+ return;
131
+ }
132
+
133
+ // Validation du blob
134
+ if (!blob || !(blob instanceof Blob) || blob.size === 0) {
135
+ console.error('Invalid blob provided to setBlobToImg', blob);
136
+ return;
137
+ }
138
+
139
+ try {
140
+ let urlCreator = window.URL || window.webkitURL;
141
+ let objectURL = urlCreator.createObjectURL(blob);
142
+ img.attr('src', objectURL);
143
+ } catch (error) {
144
+ console.error('Error creating object URL from blob:', error);
145
+ }
131
146
  }
132
147
 
133
148
  static async getBase64FromUrl(url) {
package/google_charts.js CHANGED
@@ -77,6 +77,7 @@ class GoogleCharts {
77
77
  }
78
78
 
79
79
  let data = null;
80
+ let nbCells = 0;
80
81
  if (typeGraph === 'pie_chart') {
81
82
  //data = google.visualization.arrayToDataTable(tabDataAbsParam);
82
83
 
@@ -101,7 +102,7 @@ class GoogleCharts {
101
102
  });
102
103
 
103
104
  // Remplissage des données
104
- let nbCells = 0;
105
+ nbCells = 0;
105
106
  let numRow = 0;
106
107
  $.each(tabDataAbsParam, function(idx, dataAbs) {
107
108
  // dataOrd = tabDataOrd[idx];
package/location.js CHANGED
@@ -629,7 +629,11 @@ class GeographicCoordinates {
629
629
  }
630
630
 
631
631
  static formatPoint(geoJsonPoint, fractionDigit=6) {
632
- const [lat, long] = GeographicCoordinates.parseFromGeoJson(geoJsonPoint);
632
+ const coords = GeographicCoordinates.parseFromGeoJson(geoJsonPoint);
633
+ if (coords == null) {
634
+ return '';
635
+ }
636
+ const [lat, long] = coords;
633
637
  if (typeof long == 'undefined' || typeof lat == 'undefined') {
634
638
  return '';
635
639
  }
package/media.js CHANGED
@@ -152,12 +152,12 @@ class UserMedia {
152
152
  return;
153
153
  }*/
154
154
 
155
- return new Promise((resolve, reject) => {
155
+ return new Promise((resolve, reject) => {
156
156
  const bowser = require('bowser');
157
157
  const browser = bowser.getParser(window.navigator.userAgent);
158
158
  const browserName = browser.getBrowserName();
159
159
 
160
- navigator.mediaDevices.getUserMedia(constraints !== 'undefined' ? constraints : { audio: true, video: true })
160
+ navigator.mediaDevices.getUserMedia(typeof constraints !== 'undefined' ? constraints : { audio: true, video: true })
161
161
  .then((stream) => resolve(stream))
162
162
  .catch((error) => {
163
163
  const errName = error.name;
@@ -203,15 +203,15 @@ class UserMedia {
203
203
  }
204
204
 
205
205
  static requestAudioPermissions(audioConstraints) {
206
- return this.requestMediaPermissions({ audio: (audioConstraints !== 'undefined' ? audioConstraints : true), video: false });
206
+ return this.requestMediaPermissions({ audio: (typeof audioConstraints !== 'undefined' ? audioConstraints : true), video: false });
207
207
  }
208
-
208
+
209
209
  static requestVideoPermissions(audioConstraints, videoConstraints) {
210
- return this.requestMediaPermissions({ audio: (audioConstraints !== 'undefined' ? audioConstraints : true), video: (videoConstraints !== 'undefined' ? videoConstraints : true )});
210
+ return this.requestMediaPermissions({ audio: (typeof audioConstraints !== 'undefined' ? audioConstraints : true), video: (typeof videoConstraints !== 'undefined' ? videoConstraints : true )});
211
211
  }
212
212
 
213
213
  static requestMutedVideoPermissions(videoConstraints) {
214
- return this.requestMediaPermissions({ audio: false, video: (videoConstraints !== 'undefined' ? videoConstraints : true )});
214
+ return this.requestMediaPermissions({ audio: false, video: (typeof videoConstraints !== 'undefined' ? videoConstraints : true )});
215
215
  }
216
216
  }
217
217
 
@@ -1,3 +1,5 @@
1
+ const { Str } = require('./string');
2
+
1
3
  class MultiFilesInput {
2
4
  static init(fileInput, setFilesList, nbMaxFiles, maxFileSize) {
3
5
  let filesList = [];
@@ -72,7 +74,7 @@ class MultiFilesInput {
72
74
  const wrap = $(`
73
75
  <div class="border rounded p-2 d-inline-flex align-items-center" data-file-id="${id}" style="background:white;">
74
76
  <div class="me-2 preview-thumb" style="width:64px; height:48px; display:flex; align-items:center; justify-content:center; overflow:hidden;"></div>
75
- <div class="small text-truncate" style="max-width:160px;">${file.name}</div>
77
+ <div class="small text-truncate" style="max-width:160px;">${(file.name || '').escapeHtml()}</div>
76
78
  <button type="button" class="btn-close btn-close-small ms-2" aria-label="Supprimer" style="margin-left:8px;"></button>
77
79
  </div>
78
80
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osimatic/helpers-js",
3
- "version": "1.4.25",
3
+ "version": "1.4.26",
4
4
  "main": "main.js",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "devDependencies": {
19
19
  "jest": "^30.2.0",
20
+ "jest-environment-jsdom": "^30.2.0",
20
21
  "whatwg-fetch": "^3.6.20"
21
22
  },
22
23
  "jest": {
package/paging.js CHANGED
@@ -32,7 +32,7 @@ class Pagination {
32
32
 
33
33
  maxItems = parseInt(select.val());
34
34
 
35
- select.change(update);
35
+ select.change(() => Pagination.paginate(div, items, nbItemsPerPage, select, doublePagination));
36
36
  }
37
37
 
38
38
  const ulPagination = $('ul.pagination');
@@ -151,7 +151,7 @@ class Navigation {
151
151
  window.history.replaceState('', document.title, url);
152
152
  }
153
153
  else {
154
- window.history.pushState("", "", newUrl);
154
+ window.history.pushState("", "", url);
155
155
  }
156
156
  }
157
157
  }
@@ -0,0 +1,13 @@
1
+ // Mock for socket.io-client
2
+ const mockSocket = {
3
+ on: jest.fn(),
4
+ emit: jest.fn(),
5
+ connected: false
6
+ };
7
+
8
+ const io = jest.fn(() => mockSocket);
9
+
10
+ module.exports = {
11
+ io,
12
+ __mockSocket: mockSocket
13
+ };