@opengeoweb/time-slider 19.1.0 → 19.2.0

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 (47) hide show
  1. package/dist/README.md +11 -0
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.esm.js +3662 -0
  4. package/dist/src/index.d.ts +5 -0
  5. package/dist/src/lib/Providers/Providers.d.ts +8 -0
  6. package/dist/src/lib/Providers/index.d.ts +1 -0
  7. package/dist/src/lib/components/TimeSlider/TimeSlider.d.ts +16 -0
  8. package/dist/src/lib/components/TimeSlider/changeTimeFunctions.d.ts +14 -0
  9. package/dist/src/lib/components/TimeSlider/index.d.ts +4 -0
  10. package/dist/src/lib/components/TimeSlider/timeSliderEffects.d.ts +2 -0
  11. package/dist/src/lib/components/TimeSlider/timeSliderUtils.d.ts +129 -0
  12. package/dist/src/lib/components/TimeSliderButtons/AnimationLengthButton/AnimationLengthButton.d.ts +12 -0
  13. package/dist/src/lib/components/TimeSliderButtons/AutoUpdateButton/AutoUpdateButton.d.ts +8 -0
  14. package/dist/src/lib/components/TimeSliderButtons/BackwardForwardStepButton/BackwardForwardStepButton.d.ts +7 -0
  15. package/dist/src/lib/components/TimeSliderButtons/ControlButtons/ControlButtons.d.ts +8 -0
  16. package/dist/src/lib/components/TimeSliderButtons/HideSliderButton/HideSliderButton.d.ts +6 -0
  17. package/dist/src/lib/components/TimeSliderButtons/NowButton/NowButton.d.ts +7 -0
  18. package/dist/src/lib/components/TimeSliderButtons/OptionsMenuButton/OptionsMenu.d.ts +8 -0
  19. package/dist/src/lib/components/TimeSliderButtons/OptionsMenuButton/OptionsMenuButton.d.ts +12 -0
  20. package/dist/src/lib/components/TimeSliderButtons/OptionsMenuButton/index.d.ts +2 -0
  21. package/dist/src/lib/components/TimeSliderButtons/OptionsMenuButton/optionsMenuShortcut.d.ts +9 -0
  22. package/dist/src/lib/components/TimeSliderButtons/PlayButton/PlayButton.d.ts +7 -0
  23. package/dist/src/lib/components/TimeSliderButtons/SpeedButton/SpeedButton.d.ts +6 -0
  24. package/dist/src/lib/components/TimeSliderButtons/TimeSliderButtons.d.ts +10 -0
  25. package/dist/src/lib/components/TimeSliderButtons/TimeSliderMenu/TimeSliderMenu.d.ts +24 -0
  26. package/dist/src/lib/components/TimeSliderButtons/TimeSpanButton/TimeSpanButton.d.ts +17 -0
  27. package/dist/src/lib/components/TimeSliderButtons/TimeSpanButton/TimeSpanButtonCustomSelect.d.ts +7 -0
  28. package/dist/src/lib/components/TimeSliderButtons/TimeStepButton/TimeStepButton.d.ts +11 -0
  29. package/dist/src/lib/components/TimeSliderButtons/index.d.ts +13 -0
  30. package/dist/src/lib/components/TimeSliderCurrentTimeBox/CalendarButton/CalendarButton.d.ts +10 -0
  31. package/dist/src/lib/components/TimeSliderCurrentTimeBox/MarkerTimeSelector/MarkerTimeSelector.d.ts +24 -0
  32. package/dist/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBox.d.ts +20 -0
  33. package/dist/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBoxMouseEvents.d.ts +2 -0
  34. package/dist/src/lib/components/TimeSliderCurrentTimeBox/TimeSliderCurrentTimeBoxRenderFunctions.d.ts +3 -0
  35. package/dist/src/lib/components/TimeSliderCurrentTimeBox/index.d.ts +1 -0
  36. package/dist/src/lib/components/TimeSliderLegend/TimeSliderLegend.d.ts +35 -0
  37. package/dist/src/lib/components/TimeSliderLegend/drawFunctions/drawBackground.d.ts +4 -0
  38. package/dist/src/lib/components/TimeSliderLegend/drawFunctions/drawCurrentTime.d.ts +2 -0
  39. package/dist/src/lib/components/TimeSliderLegend/drawFunctions/drawNeedle.d.ts +2 -0
  40. package/dist/src/lib/components/TimeSliderLegend/drawFunctions/drawTimeScale.d.ts +7 -0
  41. package/dist/src/lib/components/TimeSliderLegend/drawFunctions/drawTimeSliderLegend.d.ts +2 -0
  42. package/dist/src/lib/components/TimeSliderLegend/drawFunctions/index.d.ts +1 -0
  43. package/dist/src/lib/components/TimeSliderLegend/index.d.ts +1 -0
  44. package/dist/src/lib/components/TimeSliderLegend/timeSliderLegendUtils.d.ts +37 -0
  45. package/dist/src/lib/index.d.ts +5 -0
  46. package/dist/src/lib/utils/i18n.d.ts +6 -0
  47. package/package.json +2 -1
@@ -0,0 +1,3662 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { Grid, useTheme, Box, Typography, Menu, MenuItem, CardHeader, FormControl, TextField, Select, Popper, Paper, Stack, InputAdornment, ClickAwayListener } from '@mui/material';
3
+ import React, { useState, useRef, useEffect, useCallback, useContext, useMemo, createElement } from 'react';
4
+ import { dateUtils, safelyInitI18nForTestsAndStories, CustomIconButton, CustomTooltip, CanvasComponent, renderCounter, CustomToggleButton } from '@opengeoweb/shared';
5
+ import { debounce, throttle } from 'lodash';
6
+ import { ChevronDown, ChevronUp, dragHandlePath, Edit, Animation, AutoUpdateActive, AutoUpdateInActive, StepForward, StepBackward, Now, Pause, Play, Speed, Clock, FastForward, Options, CalendarToday, ThemeWrapper, lightTheme, darkTheme } from '@opengeoweb/theme';
7
+ import i18n from 'i18next';
8
+ import { useTranslation, I18nextProvider } from 'react-i18next';
9
+ import { Box as Box$1 } from '@mui/system';
10
+ import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
11
+ import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
12
+ import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
13
+ import { PickerDay } from '@mui/x-date-pickers/PickerDay';
14
+
15
+ var en = {
16
+ "timeslider-auto": "Auto",
17
+ "timeslider-length": "length",
18
+ "timeslider-animation": "Animation",
19
+ "timeslider-auto-update-on": "Auto update on",
20
+ "timeslider-auto-update-off": "Auto update off",
21
+ "timeslider-backward": "Backward",
22
+ "timeslider-forward": "Forward",
23
+ "timeslider-hide": "Hide timeslider",
24
+ "timeslider-show": "Show timeslider",
25
+ "timeslider-now": "Now",
26
+ "timeslider-animation-options": "Animation options",
27
+ "timeslider-play": "Play",
28
+ "timeslider-pause": "Pause",
29
+ "timeslider-speed": "Speed",
30
+ "timeslider-min": "min",
31
+ "timeslider-hour": "h",
32
+ "timeslider-day": "d",
33
+ "timeslider-week": "week",
34
+ "timeslider-weeks": "weeks",
35
+ "timeslider-month": "month",
36
+ "timeslider-months": "months",
37
+ "timeslider-year": "year",
38
+ "timeslider-years": "years",
39
+ "timeslider-time-step": "Time step",
40
+ "timeslider-time-span": "Time span",
41
+ "timeslider-january": "Jan",
42
+ "timeslider-february": "Feb",
43
+ "timeslider-march": "Mar",
44
+ "timeslider-april": "Apr",
45
+ "timeslider-may": "May",
46
+ "timeslider-june": "Jun",
47
+ "timeslider-july": "Jul",
48
+ "timeslider-august": "Aug",
49
+ "timeslider-september": "Sep",
50
+ "timeslider-october": "Oct",
51
+ "timeslider-november": "Nov",
52
+ "timeslider-december": "Dec",
53
+ "timeslider-sunday": "Sun",
54
+ "timeslider-monday": "Mon",
55
+ "timeslider-tuesday": "Tue",
56
+ "timeslider-wednesday": "Wed",
57
+ "timeslider-thursday": "Thu",
58
+ "timeslider-friday": "Fri",
59
+ "timeslider-saturday": "Sat",
60
+ "timeslider-edit": "Edit",
61
+ "timeslider-span": "Span",
62
+ "timeslider-marker": "Marker",
63
+ "timeslider-marker-placement": "Marker placement",
64
+ "timeslider-marker-label": "Select date and time"
65
+ };
66
+ var fi = {
67
+ "timeslider-auto": "Auto",
68
+ "timeslider-length": "pituus",
69
+ "timeslider-animation": "Animaatio",
70
+ "timeslider-auto-update-on": "Auto update päällä",
71
+ "timeslider-auto-update-off": "Auto update pois päältä",
72
+ "timeslider-backward": "Taaksepäin",
73
+ "timeslider-forward": "Eteenpäin",
74
+ "timeslider-hide": "Piilota Timeslider",
75
+ "timeslider-show": "Näytä Timeslider",
76
+ "timeslider-now": "Nyt",
77
+ "timeslider-animation-options": "Animoinnin asetukset",
78
+ "timeslider-play": "Toista",
79
+ "timeslider-pause": "Tauko",
80
+ "timeslider-speed": "Nopeus",
81
+ "timeslider-min": "min",
82
+ "timeslider-hour": "t",
83
+ "timeslider-week": "viikko",
84
+ "timeslider-weeks": "viikkoa",
85
+ "timeslider-month": "kuukausi",
86
+ "timeslider-months": "kuukautta",
87
+ "timeslider-year": "vuosi",
88
+ "timeslider-years": "vuotta",
89
+ "timeslider-time-step": "Aika-askel",
90
+ "timeslider-time-span": "Aikaväli",
91
+ "timeslider-january": "Tammmi",
92
+ "timeslider-february": "Helmi",
93
+ "timeslider-march": "Maalis",
94
+ "timeslider-april": "Huhti",
95
+ "timeslider-may": "Touko",
96
+ "timeslider-june": "Kesä",
97
+ "timeslider-july": "Heinä",
98
+ "timeslider-august": "Elo",
99
+ "timeslider-september": "Syys",
100
+ "timeslider-october": "Loka",
101
+ "timeslider-november": "Marras",
102
+ "timeslider-december": "Joulu",
103
+ "timeslider-sunday": "Su",
104
+ "timeslider-monday": "Ma",
105
+ "timeslider-tuesday": "Ti",
106
+ "timeslider-wednesday": "Ke",
107
+ "timeslider-thursday": "To",
108
+ "timeslider-friday": "Pe",
109
+ "timeslider-saturday": "La",
110
+ "timeslider-edit": "missing-translation",
111
+ "timeslider-span": "missing-translation",
112
+ "timeslider-marker": "Aikamerkki",
113
+ "timeslider-marker-placement": "Aikamerkin siirto",
114
+ "timeslider-marker-label": "Valitse päivämäärä ja kellonaika"
115
+ };
116
+ var no = {
117
+ "timeslider-auto": "Auto",
118
+ "timeslider-length": "lengde",
119
+ "timeslider-animation": "Animasjon",
120
+ "timeslider-auto-update-on": "Autooppdatering på",
121
+ "timeslider-auto-update-off": "Autooppdatering av",
122
+ "timeslider-backward": "Bakover",
123
+ "timeslider-forward": "Forover",
124
+ "timeslider-hide": "Skjul",
125
+ "timeslider-show": "Vis",
126
+ "timeslider-now": "Nå",
127
+ "timeslider-animation-options": "Animasjonsinnstillinger",
128
+ "timeslider-play": "Spill",
129
+ "timeslider-pause": "Pause",
130
+ "timeslider-speed": "Hurtighet",
131
+ "timeslider-min": "min",
132
+ "timeslider-hour": "t",
133
+ "timeslider-week": "uke",
134
+ "timeslider-weeks": "uker",
135
+ "timeslider-month": "måned",
136
+ "timeslider-months": "måneder",
137
+ "timeslider-year": "år",
138
+ "timeslider-years": "år",
139
+ "timeslider-time-step": "Tidsintervall",
140
+ "timeslider-time-span": "Tidsperiode",
141
+ "timeslider-january": "Jan",
142
+ "timeslider-february": "Feb",
143
+ "timeslider-march": "Mar",
144
+ "timeslider-april": "Apr",
145
+ "timeslider-may": "Mai",
146
+ "timeslider-june": "Jun",
147
+ "timeslider-july": "Jul",
148
+ "timeslider-august": "Aug",
149
+ "timeslider-september": "Sep",
150
+ "timeslider-october": "Okt",
151
+ "timeslider-november": "Nov",
152
+ "timeslider-december": "Des",
153
+ "timeslider-sunday": "Søn",
154
+ "timeslider-monday": "Man",
155
+ "timeslider-tuesday": "Tir",
156
+ "timeslider-wednesday": "Ons",
157
+ "timeslider-thursday": "Tor",
158
+ "timeslider-friday": "Fre",
159
+ "timeslider-saturday": "Lør",
160
+ "timeslider-edit": "Editer",
161
+ "timeslider-span": "Periode",
162
+ "timeslider-marker": "missing translation",
163
+ "timeslider-marker-placement": "missing translation",
164
+ "timeslider-marker-label": "missing translation"
165
+ };
166
+ var nl = {
167
+ "timeslider-auto": "Auto",
168
+ "timeslider-length": "lengte",
169
+ "timeslider-animation": "Animatie",
170
+ "timeslider-auto-update-on": "Auto update aan",
171
+ "timeslider-auto-update-off": "Auto update uit",
172
+ "timeslider-backward": "Achteruit",
173
+ "timeslider-forward": "Vooruit",
174
+ "timeslider-hide": "Timeslider verbergen",
175
+ "timeslider-show": "Timeslider tonen",
176
+ "timeslider-now": "Nu",
177
+ "timeslider-animation-options": "Animatie opties",
178
+ "timeslider-play": "Afspelen",
179
+ "timeslider-pause": "Pauze",
180
+ "timeslider-speed": "Snelheid",
181
+ "timeslider-min": "min",
182
+ "timeslider-hour": "u",
183
+ "timeslider-week": "week",
184
+ "timeslider-weeks": "weken",
185
+ "timeslider-month": "maand",
186
+ "timeslider-months": "maanden",
187
+ "timeslider-year": "jaar",
188
+ "timeslider-years": "jaren",
189
+ "timeslider-time-step": "Tijdsinterval",
190
+ "timeslider-time-span": "Tijdsperiode",
191
+ "timeslider-january": "Jan",
192
+ "timeslider-february": "Feb",
193
+ "timeslider-march": "Maa",
194
+ "timeslider-april": "Apr",
195
+ "timeslider-may": "Mei",
196
+ "timeslider-june": "Jun",
197
+ "timeslider-july": "Jul",
198
+ "timeslider-august": "Aug",
199
+ "timeslider-september": "Sep",
200
+ "timeslider-october": "Okt",
201
+ "timeslider-november": "Nov",
202
+ "timeslider-december": "Dec",
203
+ "timeslider-sunday": "Zon",
204
+ "timeslider-monday": "Maa",
205
+ "timeslider-tuesday": "Din",
206
+ "timeslider-wednesday": "Woe",
207
+ "timeslider-thursday": "Don",
208
+ "timeslider-friday": "Vri",
209
+ "timeslider-saturday": "Zat",
210
+ "timeslider-edit": "Bewerken",
211
+ "timeslider-span": "Tijdsperiode",
212
+ "timeslider-marker": "Kies tijdstip",
213
+ "timeslider-marker-placement": "Tijd kiezen",
214
+ "timeslider-marker-label": "Selecteer datum en tijd"
215
+ };
216
+ var timesliderTranslations = {
217
+ en: en,
218
+ fi: fi,
219
+ no: no,
220
+ nl: nl
221
+ };
222
+
223
+ function _arrayLikeToArray(r, a) {
224
+ (null == a || a > r.length) && (a = r.length);
225
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
226
+ return n;
227
+ }
228
+ function _createForOfIteratorHelperLoose(r, e) {
229
+ var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
230
+ if (t) return (t = t.call(r)).next.bind(t);
231
+ if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e) {
232
+ t && (r = t);
233
+ var o = 0;
234
+ return function () {
235
+ return o >= r.length ? {
236
+ done: true
237
+ } : {
238
+ done: false,
239
+ value: r[o++]
240
+ };
241
+ };
242
+ }
243
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
244
+ }
245
+ function _objectWithoutPropertiesLoose(r, e) {
246
+ if (null == r) return {};
247
+ var t = {};
248
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
249
+ if (-1 !== e.indexOf(n)) continue;
250
+ t[n] = r[n];
251
+ }
252
+ return t;
253
+ }
254
+ function _unsupportedIterableToArray(r, a) {
255
+ if (r) {
256
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
257
+ var t = {}.toString.call(r).slice(8, -1);
258
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
259
+ }
260
+ }
261
+
262
+ var Scale;
263
+ (function (Scale) {
264
+ Scale[Scale["Minutes5"] = 0] = "Minutes5";
265
+ Scale[Scale["Hour"] = 1] = "Hour";
266
+ Scale[Scale["Hours3"] = 2] = "Hours3";
267
+ Scale[Scale["Hours6"] = 3] = "Hours6";
268
+ Scale[Scale["Day"] = 4] = "Day";
269
+ Scale[Scale["Week"] = 5] = "Week";
270
+ Scale[Scale["Weeks2"] = 6] = "Weeks2";
271
+ Scale[Scale["Month"] = 7] = "Month";
272
+ Scale[Scale["Months3"] = 8] = "Months3";
273
+ Scale[Scale["Year"] = 9] = "Year";
274
+ })(Scale || (Scale = {}));
275
+ var AnimationLength;
276
+ (function (AnimationLength) {
277
+ AnimationLength[AnimationLength["Minutes15"] = 15] = "Minutes15";
278
+ AnimationLength[AnimationLength["Minutes30"] = 30] = "Minutes30";
279
+ AnimationLength[AnimationLength["Hours1"] = 60] = "Hours1";
280
+ AnimationLength[AnimationLength["Hours2"] = 120] = "Hours2";
281
+ AnimationLength[AnimationLength["Hours3"] = 180] = "Hours3";
282
+ AnimationLength[AnimationLength["Hours6"] = 360] = "Hours6";
283
+ AnimationLength[AnimationLength["Hours12"] = 720] = "Hours12";
284
+ AnimationLength[AnimationLength["Hours24"] = 1440] = "Hours24";
285
+ })(AnimationLength || (AnimationLength = {}));
286
+ /**
287
+ * In this Map collection all fundamental scales
288
+ * (Scale.Minutes5 ... Scale.Year) are mapped with their corresponding
289
+ * secondsPerPx numbers.
290
+ * @returns a Map including information explained above
291
+ */
292
+ var secondsPerPxToScale = new Map([[2.5, Scale.Minutes5], [30, Scale.Hour], [3 * 30, Scale.Hours3], [6 * 30, Scale.Hours6], [24 * 30, Scale.Day], [7 * 24 * 30, Scale.Week], [14 * 24 * 30, Scale.Weeks2], [30 * 24 * 30, Scale.Month], [90 * 24 * 30, Scale.Months3], [365 * 24 * 30, Scale.Year]]);
293
+ var spanToScale = new Map([[5 * 60, Scale.Minutes5], [60 * 60, Scale.Hour], [3 * 60 * 60, Scale.Hours3], [6 * 60 * 60, Scale.Hours6], [24 * 60 * 60, Scale.Day], [7 * 24 * 60 * 60, Scale.Week], [14 * 24 * 60 * 60, Scale.Weeks2], [30 * 24 * 60 * 60, Scale.Month], [90 * 24 * 60 * 60, Scale.Months3], [365 * 24 * 60 * 60, Scale.Year]]);
294
+ /**
295
+ * Creates a reverse mapping of scales to their corresponding secondsPerPx
296
+ * values to make it easier in some parts GeoWeb to fetch a secondsPerpx for
297
+ * a certain fundamental scale (Scale.Minutes5 ... Scale.year)
298
+ * @returns an Object, where names are fundamental scale values (0 - 7) and
299
+ * values are their corresponding secondsPerPx numbers.
300
+ */
301
+ var scaleToSecondsPerPx = Object.fromEntries(Array.from(secondsPerPxToScale.entries()).map(function (_ref) {
302
+ var key = _ref[0],
303
+ value = _ref[1];
304
+ return [value, key];
305
+ }));
306
+ var scalingCoefficient = function scalingCoefficient(end, start, width) {
307
+ return width / (end - start);
308
+ };
309
+ var timestampToPixelEdges = function timestampToPixelEdges(timestamp, start, end, width) {
310
+ return (timestamp - start) * scalingCoefficient(end, start, width);
311
+ };
312
+ var timestampToPixel = function timestampToPixel(timestamp, centerTime, widthPx, secondsPerPx) {
313
+ return widthPx / 2 - (centerTime - timestamp) / secondsPerPx;
314
+ };
315
+ var pixelToTimestamp = function pixelToTimestamp(timePx, centerTime, widthPx, secondsPerPx) {
316
+ return centerTime - (widthPx / 2 - timePx) * secondsPerPx;
317
+ };
318
+ /**
319
+ * This function creates and returns an array where there is secondsPerPx
320
+ * number of the data set added for a data scale (secondsPerPx)
321
+ * to secondsPerPxToScale.
322
+ * @param secondsPerPx
323
+ * @returns an array containing secondsPerPx numbers.
324
+ * The secondsPerPx number for a data scale is included
325
+ * contrary to secondsPerPxToScale.
326
+ */
327
+ var secondsPerPxValues = function secondsPerPxValues(secondsPerPx) {
328
+ var sortedSecondsPerPx = [].concat(secondsPerPxToScale).map(function (value) {
329
+ return Number(value[0]);
330
+ });
331
+ var full = [].concat(sortedSecondsPerPx, [secondsPerPx]);
332
+ return full;
333
+ };
334
+ var secondsPerPxFromCanvasWidth = function secondsPerPxFromCanvasWidth(canvasWidth, spanInSeconds) {
335
+ if (canvasWidth <= 0 || spanInSeconds <= 0) {
336
+ return undefined;
337
+ }
338
+ return spanInSeconds / canvasWidth;
339
+ };
340
+ var getNewCenterOfFixedPointZoom = function getNewCenterOfFixedPointZoom(fixedTimePoint, oldSecondsPerPx, newSecondsPerPx, oldCenterTime) {
341
+ var centerToFixedPointPx = (fixedTimePoint - oldCenterTime) / oldSecondsPerPx;
342
+ return fixedTimePoint - centerToFixedPointPx * newSecondsPerPx;
343
+ };
344
+ /**
345
+ * Move the time slider such that a given time point (timePoint)
346
+ * is at a given pixel width (timePointPx).
347
+ * @returns a new center time for the resulting position
348
+ */
349
+ var moveRelativeToTimePoint = function moveRelativeToTimePoint(timePoint, timePointPx, secondsPerPx, canvasWidth) {
350
+ return timePoint - secondsPerPx * (timePointPx - canvasWidth / 2);
351
+ };
352
+ /** This reusable custom hook tells whether given pointer event targets current canvas node.
353
+ * Example:
354
+ *
355
+ * const [isAllowedCanvasNodePointed, nodeRef] = useCanvasTarget('mousedown', false);
356
+ * ...
357
+ * return isAllowedCanvasNodePointed ? (<CanvasComponent ref={nodeRef}>Component with ref</CanvasComponent>) : (<CanvasComponent>Component with NO ref</CanvasComponent>);
358
+ * ...
359
+ */
360
+ var useCanvasTarget = function useCanvasTarget(eventType) {
361
+ var nodeRef = React.useRef(null);
362
+ var _React$useState = React.useState(false),
363
+ isTargetNode = _React$useState[0],
364
+ setIsTargetNode = _React$useState[1];
365
+ // Check if pointer event targets current node element
366
+ var pointerEventListener = React.useCallback(function (event) {
367
+ setIsTargetNode(nodeRef.current.canvas ? nodeRef.current.canvas.isEqualNode(event.target) : false);
368
+ }, [nodeRef]);
369
+ React.useEffect(function () {
370
+ document.addEventListener(eventType, pointerEventListener);
371
+ return function () {
372
+ return document.removeEventListener(eventType, pointerEventListener);
373
+ };
374
+ }, [eventType, pointerEventListener]); // Only add/remove event listener when listener really changes, that is, NOT necessarily between every re-render.
375
+ return [isTargetNode, nodeRef];
376
+ };
377
+ var timeBoxGeom = {
378
+ smallWidth: 126,
379
+ largeWidth: 167,
380
+ height: 24,
381
+ cornerRadius: 5,
382
+ lineWidth: 1,
383
+ iconWidth: 25,
384
+ calendarWidth: 20
385
+ };
386
+ var AUTO_MOVE_AREA_PADDING = 1;
387
+ var getAutoMoveAreaWidth = function getAutoMoveAreaWidth(scale) {
388
+ return (scale === Scale.Year ? timeBoxGeom.largeWidth + timeBoxGeom.iconWidth : timeBoxGeom.smallWidth + timeBoxGeom.iconWidth) / 2 + AUTO_MOVE_AREA_PADDING;
389
+ };
390
+ var TimeInMinutes;
391
+ (function (TimeInMinutes) {
392
+ TimeInMinutes[TimeInMinutes["YEAR"] = 525600] = "YEAR";
393
+ TimeInMinutes[TimeInMinutes["MONTH"] = 43200] = "MONTH";
394
+ TimeInMinutes[TimeInMinutes["WEEK"] = 10080] = "WEEK";
395
+ TimeInMinutes[TimeInMinutes["DAY"] = 1440] = "DAY";
396
+ TimeInMinutes[TimeInMinutes["HOUR"] = 60] = "HOUR";
397
+ TimeInMinutes[TimeInMinutes["MINUTE"] = 1] = "MINUTE";
398
+ })(TimeInMinutes || (TimeInMinutes = {}));
399
+ /**
400
+ *
401
+ * @param minutes
402
+ * @returns the two highest values in the format yr(s) mo(s) d h m
403
+ */
404
+ var minutesToDescribedDuration = function minutesToDescribedDuration(minutes) {
405
+ var units = [{
406
+ label: 'yr',
407
+ value: TimeInMinutes.YEAR,
408
+ plural: 's'
409
+ }, {
410
+ label: 'mo',
411
+ value: TimeInMinutes.MONTH,
412
+ plural: 's'
413
+ }, {
414
+ label: 'd',
415
+ value: TimeInMinutes.DAY
416
+ }, {
417
+ label: 'h',
418
+ value: TimeInMinutes.HOUR
419
+ }, {
420
+ label: 'm',
421
+ value: TimeInMinutes.MINUTE
422
+ }];
423
+ var durations = units.reduce(function (units, duration) {
424
+ var min = units.min,
425
+ time = units.time,
426
+ count = units.count;
427
+ var label = duration.label,
428
+ value = duration.value,
429
+ _duration$plural = duration.plural,
430
+ plural = _duration$plural === void 0 ? '' : _duration$plural;
431
+ var unit = Math.floor(min / value);
432
+ if (unit > 0 && count < 2) {
433
+ return {
434
+ time: "" + time + unit + label + (unit > 1 ? plural : '') + " ",
435
+ min: min - unit * value,
436
+ count: count + 1
437
+ };
438
+ }
439
+ return {
440
+ min: min,
441
+ time: time,
442
+ count: count
443
+ };
444
+ }, {
445
+ min: minutes,
446
+ time: '',
447
+ count: 0
448
+ });
449
+ return durations.time.trim();
450
+ };
451
+ /**
452
+ * Returns the largest timeunit value divisible by minuts
453
+ * @param minutes
454
+ * @returns
455
+ */
456
+ function getLargestTimeUnit(minutes) {
457
+ var values = Object.values(TimeInMinutes).filter(function (value) {
458
+ return typeof value === 'number';
459
+ });
460
+ for (var _iterator = _createForOfIteratorHelperLoose(values), _step; !(_step = _iterator()).done;) {
461
+ var value = _step.value;
462
+ if (minutes >= value) {
463
+ return value;
464
+ }
465
+ }
466
+ return TimeInMinutes.MINUTE;
467
+ }
468
+ // For a data scale an appropriate fundamental scale is chosen
469
+ // depending on secondsPerPx of data. When a time range of
470
+ // data is for example many months. the fundamental scale Scale.Year
471
+ // is chosen here and the legend of the time slider is drawn in the
472
+ // same as if otiginally a year scale would have been chose.
473
+ //
474
+ // If a time range of data is a few weeks, Scale.Month is chosen. So, all
475
+ // the time range of data can be shown in the window.
476
+ var getFundamentalScale = function getFundamentalScale(secondsPerPx) {
477
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Month]) {
478
+ return Scale.Year;
479
+ }
480
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Week]) {
481
+ return Scale.Month;
482
+ }
483
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Day]) {
484
+ return Scale.Week;
485
+ }
486
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Hours6]) {
487
+ return Scale.Day;
488
+ }
489
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Hours3]) {
490
+ return Scale.Hours6;
491
+ }
492
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Hour]) {
493
+ return Scale.Hours3;
494
+ }
495
+ if (secondsPerPx >= scaleToSecondsPerPx[Scale.Minutes5]) {
496
+ return Scale.Hour;
497
+ }
498
+ return Scale.Minutes5;
499
+ };
500
+ var getScaleFromSpan = function getScaleFromSpan(span) {
501
+ var sortedScales = [].concat(spanToScale.entries()).sort(function (_ref2, _ref3) {
502
+ var sa = _ref2[0];
503
+ var sb = _ref3[0];
504
+ return sb - sa;
505
+ });
506
+ for (var _iterator2 = _createForOfIteratorHelperLoose(sortedScales), _step2; !(_step2 = _iterator2()).done;) {
507
+ var _step2$value = _step2.value,
508
+ scaleSpan = _step2$value[0],
509
+ scale = _step2$value[1];
510
+ if (span >= scaleSpan) {
511
+ return scale;
512
+ }
513
+ }
514
+ return sortedScales[0][1];
515
+ };
516
+ var calculateMouseTimeAndCheckBounds = function calculateMouseTimeAndCheckBounds(x, startAnimationPosition, endAnimationPosition, DRAG_AREA_WIDTH, pixelsBetweenViewportAndTimesliderOnLeft, centerTime, canvasWidth, secondsPerPx, tooltipPosition) {
517
+ var mousePosition = startAnimationPosition + x;
518
+ var startAnimationMaxPosition = endAnimationPosition - DRAG_AREA_WIDTH * 2;
519
+ var isDraggingWithinBounds = mousePosition >= startAnimationMaxPosition || mousePosition <= 0;
520
+ if (isDraggingWithinBounds) {
521
+ return undefined;
522
+ }
523
+ // eslint-disable-next-line no-param-reassign
524
+ tooltipPosition.current = pixelsBetweenViewportAndTimesliderOnLeft && mousePosition + pixelsBetweenViewportAndTimesliderOnLeft;
525
+ return pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx);
526
+ };
527
+ // default values
528
+ var defaultAnimationDelayAtStart = 250;
529
+ var defaultDelay = 1000; // [ms]
530
+ var defaultTimeStep = 60;
531
+ var defaultSecondsPerPx = 80;
532
+ var defaultTimeSpan = 24 * 3600;
533
+ var speedFactors = [0.1, 0.2, 0.5, 1, 2, 4, 8, 16]; // Declares available animation speed multipliers for default delay
534
+ var roundWithTimeStep = function roundWithTimeStep(unixTime, timeStep, type) {
535
+ var adjustedTimeStep = timeStep * 60;
536
+ if (!type || type === 'round') {
537
+ return Math.round(unixTime / adjustedTimeStep) * adjustedTimeStep;
538
+ }
539
+ if (type === 'floor') {
540
+ return Math.floor(unixTime / adjustedTimeStep) * adjustedTimeStep;
541
+ }
542
+ if (type === 'ceil') {
543
+ return Math.ceil(unixTime / adjustedTimeStep) * adjustedTimeStep;
544
+ }
545
+ return undefined;
546
+ };
547
+ /**
548
+ * Returns speed delay for given speedFactor. For options, see defined above in "speedFactors"
549
+ */
550
+ var getSpeedDelay = function getSpeedDelay(speedFactor) {
551
+ return defaultDelay / speedFactor;
552
+ };
553
+ var timeSliderLegendDefaultProps = {
554
+ timeSliderWidth: 100,
555
+ centerTime: dateUtils.unix(dateUtils.set(dateUtils.utc(), {
556
+ hours: 12,
557
+ minutes: 0,
558
+ seconds: 0,
559
+ milliseconds: 0
560
+ })),
561
+ secondsPerPx: defaultSecondsPerPx,
562
+ selectedTime: dateUtils.unix(dateUtils.set(dateUtils.utc(), {
563
+ hours: 12,
564
+ minutes: 0,
565
+ seconds: 0,
566
+ milliseconds: 0
567
+ }))
568
+ };
569
+
570
+ var timeSliderUtils = /*#__PURE__*/Object.freeze({
571
+ __proto__: null,
572
+ AUTO_MOVE_AREA_PADDING: AUTO_MOVE_AREA_PADDING,
573
+ get AnimationLength () { return AnimationLength; },
574
+ get Scale () { return Scale; },
575
+ get TimeInMinutes () { return TimeInMinutes; },
576
+ calculateMouseTimeAndCheckBounds: calculateMouseTimeAndCheckBounds,
577
+ defaultAnimationDelayAtStart: defaultAnimationDelayAtStart,
578
+ defaultDelay: defaultDelay,
579
+ defaultSecondsPerPx: defaultSecondsPerPx,
580
+ defaultTimeSpan: defaultTimeSpan,
581
+ defaultTimeStep: defaultTimeStep,
582
+ getAutoMoveAreaWidth: getAutoMoveAreaWidth,
583
+ getFundamentalScale: getFundamentalScale,
584
+ getLargestTimeUnit: getLargestTimeUnit,
585
+ getNewCenterOfFixedPointZoom: getNewCenterOfFixedPointZoom,
586
+ getScaleFromSpan: getScaleFromSpan,
587
+ getSpeedDelay: getSpeedDelay,
588
+ minutesToDescribedDuration: minutesToDescribedDuration,
589
+ moveRelativeToTimePoint: moveRelativeToTimePoint,
590
+ pixelToTimestamp: pixelToTimestamp,
591
+ roundWithTimeStep: roundWithTimeStep,
592
+ scaleToSecondsPerPx: scaleToSecondsPerPx,
593
+ scalingCoefficient: scalingCoefficient,
594
+ secondsPerPxFromCanvasWidth: secondsPerPxFromCanvasWidth,
595
+ secondsPerPxToScale: secondsPerPxToScale,
596
+ secondsPerPxValues: secondsPerPxValues,
597
+ spanToScale: spanToScale,
598
+ speedFactors: speedFactors,
599
+ timeBoxGeom: timeBoxGeom,
600
+ timeSliderLegendDefaultProps: timeSliderLegendDefaultProps,
601
+ timestampToPixel: timestampToPixel,
602
+ timestampToPixelEdges: timestampToPixelEdges,
603
+ useCanvasTarget: useCanvasTarget
604
+ });
605
+
606
+ /* *
607
+ * Licensed under the Apache License, Version 2.0 (the "License");
608
+ * you may not use this file except in compliance with the License.
609
+ * You may obtain a copy of the License at
610
+ *
611
+ * http://www.apache.org/licenses/LICENSE-2.0
612
+ *
613
+ * Unless required by applicable law or agreed to in writing, software
614
+ * distributed under the License is distributed on an "AS IS" BASIS,
615
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
616
+ * See the License for the specific language governing permissions and
617
+ * limitations under the License.
618
+ *
619
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
620
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
621
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
622
+ * */
623
+ var onsetNewDateDebounced = debounce(function (dateToSet, onSetNewDate) {
624
+ onSetNewDate(dateToSet);
625
+ }, 4, {
626
+ maxWait: 40
627
+ });
628
+ var setPreviousTimeStep = function setPreviousTimeStep(timeStep, currentTime, dataStartTime, onSetNewDate) {
629
+ // timeStep is in minutes, convert to seconds
630
+ var timeStepInSeconds = timeStep * 60;
631
+ var nextTime = currentTime - timeStepInSeconds;
632
+ // Don't round - just step by the timestep amount from current position
633
+ var newTime = Math.max(nextTime, dataStartTime || nextTime);
634
+ var selectedTimeString = dateUtils.fromUnix(newTime).toISOString();
635
+ onSetNewDate(selectedTimeString);
636
+ };
637
+ var setNextTimeStep = function setNextTimeStep(timeStep, currentTime, dataEndTime, onSetNewDate) {
638
+ // timeStep is in minutes, convert to seconds
639
+ var timeStepInSeconds = timeStep * 60;
640
+ var nextTime = currentTime + timeStepInSeconds;
641
+ // Don't round - just step by the timestep amount from current position
642
+ var newTime = Math.min(nextTime, dataEndTime || nextTime);
643
+ var selectedTimeString = dateUtils.fromUnix(newTime).toISOString();
644
+ onSetNewDate(selectedTimeString);
645
+ };
646
+ /**
647
+ * updates unfiltered selected time and moves selected time a given distance
648
+ * in pixels. Unfiltered selected time can be outside data data limits, but
649
+ * selected time cannot.
650
+ */
651
+ var moveSelectedTimePx = function moveSelectedTimePx(pixelsMoved, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime) {
652
+ var unfilteredSelectedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
653
+ var clickedUnfilteredSelectedTimePx = unfilteredSelectedTimePx + pixelsMoved;
654
+ var newUnfilteredSelectedTime = pixelToTimestamp(clickedUnfilteredSelectedTimePx, centerTime, canvasWidth, secondsPerPx);
655
+ setUnfilteredSelectedTime(newUnfilteredSelectedTime);
656
+ };
657
+ function getFilteredTime(unfilteredTime, timeStep, dataStartTime, dataEndTime) {
658
+ if (!timeStep || !dataStartTime || !dataEndTime) {
659
+ return unfilteredTime;
660
+ }
661
+ var roundedTime = roundWithTimeStep(unfilteredTime, timeStep);
662
+ var maxTime = Math.max(roundedTime, dataStartTime);
663
+ return Math.min(maxTime, dataEndTime);
664
+ }
665
+ /** Reusable business logic for how to handle events that set time to now (closest).
666
+ * Used in NowButton and TimeSliderLegend.
667
+ */
668
+ var handleSetNowEvent = function handleSetNowEvent(timeStep, dataStartTime, dataEndTime, currentTime, onSetNewDate, onSetCenterTime) {
669
+ if (dataStartTime < dataEndTime) {
670
+ if (dataEndTime < currentTime) {
671
+ onSetNewDate(dateUtils.fromUnix(dataEndTime).toISOString());
672
+ onSetCenterTime(dataEndTime);
673
+ } else if (dataStartTime > currentTime) {
674
+ onSetNewDate(dateUtils.fromUnix(dataStartTime).toISOString());
675
+ onSetCenterTime(dataStartTime);
676
+ } else {
677
+ var closestToCurrent = roundWithTimeStep(currentTime, timeStep);
678
+ onSetNewDate(dateUtils.fromUnix(closestToCurrent).toISOString());
679
+ onSetCenterTime(closestToCurrent);
680
+ }
681
+ }
682
+ };
683
+
684
+ /* *
685
+ * Licensed under the Apache License, Version 2.0 (the "License");
686
+ * you may not use this file except in compliance with the License.
687
+ * You may obtain a copy of the License at
688
+ *
689
+ * http://www.apache.org/licenses/LICENSE-2.0
690
+ *
691
+ * Unless required by applicable law or agreed to in writing, software
692
+ * distributed under the License is distributed on an "AS IS" BASIS,
693
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
694
+ * See the License for the specific language governing permissions and
695
+ * limitations under the License.
696
+ *
697
+ * Copyright 2024 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
698
+ * Copyright 2024 - Finnish Meteorological Institute (FMI)
699
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
700
+ * */
701
+ var useToggleTimesliderVisibility = function useToggleTimesliderVisibility(mapIsActive, isVisible, onToggleTimeSlider) {
702
+ React.useEffect(function () {
703
+ var handleKeyDown = function handleKeyDown(event) {
704
+ var target = event.target;
705
+ if (target.tagName !== 'INPUT' && target.tagName !== 'TEXTAREA' && (event.key === 't' || event.key === 'T') && mapIsActive) {
706
+ onToggleTimeSlider(!isVisible);
707
+ }
708
+ };
709
+ document.addEventListener('keydown', handleKeyDown);
710
+ return function () {
711
+ document.removeEventListener('keydown', handleKeyDown);
712
+ };
713
+ }, [mapIsActive, isVisible, onToggleTimeSlider]);
714
+ };
715
+ var useMoveTimeWithKeyboard = function useMoveTimeWithKeyboard(mapIsActive, timeStep, dataStartTime, dataEndTime, onSetNewDate, onSetCenterTime, selectedTime) {
716
+ React.useEffect(function () {
717
+ var handleKeyDown = function handleKeyDown(event) {
718
+ if (event.key === 'Home' && mapIsActive) {
719
+ handleSetNowEvent(timeStep, dataStartTime, dataEndTime, dateUtils.unix(dateUtils.utc()), onSetNewDate, onSetCenterTime);
720
+ }
721
+ var isMac = window.navigator.userAgent.includes(' Mac ');
722
+ var isCorrectModifier = isMac && event.ctrlKey && event.shiftKey || !isMac && event.ctrlKey;
723
+ if (isCorrectModifier && dataStartTime && dataEndTime && mapIsActive) {
724
+ switch (event.code) {
725
+ case 'ArrowLeft':
726
+ setPreviousTimeStep(timeStep, selectedTime, dataStartTime, onSetNewDate);
727
+ break;
728
+ case 'ArrowRight':
729
+ setNextTimeStep(timeStep, selectedTime, dataEndTime, onSetNewDate);
730
+ break;
731
+ }
732
+ }
733
+ };
734
+ document.addEventListener('keydown', handleKeyDown);
735
+ return function () {
736
+ document.removeEventListener('keydown', handleKeyDown);
737
+ };
738
+ }, [dataEndTime, dataStartTime, mapIsActive, onSetCenterTime, onSetNewDate, selectedTime, timeStep]);
739
+ };
740
+
741
+ /* *
742
+ * Licensed under the Apache License, Version 2.0 (the "License");
743
+ * you may not use this file except in compliance with the License.
744
+ * You may obtain a copy of the License at
745
+ *
746
+ * http://www.apache.org/licenses/LICENSE-2.0
747
+ *
748
+ * Unless required by applicable law or agreed to in writing, software
749
+ * distributed under the License is distributed on an "AS IS" BASIS,
750
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
751
+ * See the License for the specific language governing permissions and
752
+ * limitations under the License.
753
+ *
754
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
755
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
756
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
757
+ * */
758
+ var TIME_SLIDER_NAMESPACE = 'timeslider';
759
+ var initTimesliderI18n = function initTimesliderI18n() {
760
+ safelyInitI18nForTestsAndStories(i18n, TIME_SLIDER_NAMESPACE, [{
761
+ ns: TIME_SLIDER_NAMESPACE,
762
+ translations: timesliderTranslations
763
+ }]);
764
+ };
765
+ var useTimesliderTranslation = function useTimesliderTranslation() {
766
+ return useTranslation(TIME_SLIDER_NAMESPACE);
767
+ };
768
+
769
+ var HideSliderButtonComponent = function HideSliderButtonComponent(_ref) {
770
+ var isVisible = _ref.isVisible,
771
+ toggleTimeSliderIsVisible = _ref.toggleTimeSliderIsVisible;
772
+ var _useTimesliderTransla = useTimesliderTranslation(),
773
+ t = _useTimesliderTransla.t;
774
+ return jsx(CustomIconButton, {
775
+ "data-testid": "hideTimeSliderButton",
776
+ onClick: function onClick() {
777
+ toggleTimeSliderIsVisible(!isVisible);
778
+ },
779
+ tooltipTitle: isVisible ? t('timeslider-hide') : t('timeslider-show'),
780
+ variant: "tool",
781
+ children: isVisible ? jsx(ChevronDown, {}) : jsx(ChevronUp, {})
782
+ });
783
+ };
784
+ var HideSliderButton = /*#__PURE__*/React.memo(HideSliderButtonComponent);
785
+
786
+ /* *
787
+ * Licensed under the Apache License, Version 2.0 (the "License");
788
+ * you may not use this file except in compliance with the License.
789
+ * You may obtain a copy of the License at
790
+ *
791
+ * http://www.apache.org/licenses/LICENSE-2.0
792
+ *
793
+ * Unless required by applicable law or agreed to in writing, software
794
+ * distributed under the License is distributed on an "AS IS" BASIS,
795
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
796
+ * See the License for the specific language governing permissions and
797
+ * limitations under the License.
798
+ *
799
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
800
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
801
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
802
+ * */
803
+ /**
804
+ * @param x The pin location
805
+ * @param selectedTimePx The selected px
806
+ * @param width The default width of a hoverable icon (usually 24px)
807
+ * @returns
808
+ */
809
+ var isSelectedTimeIconArea = function isSelectedTimeIconArea(x, selectedTimePx, width) {
810
+ return x >= selectedTimePx && x <= selectedTimePx + width / 2;
811
+ };
812
+ /**
813
+ * @param x The pin location
814
+ * @param selectedTimePx The selected px
815
+ * @param width The default width of a hoverable icon (usually 24px)
816
+ * @returns
817
+ */
818
+ var isRightAnimationIconArea = function isRightAnimationIconArea(x, rightMarkerPx, width) {
819
+ return x >= rightMarkerPx - width && x <= rightMarkerPx;
820
+ };
821
+ var isInsideAnimationArea = function isInsideAnimationArea(x, leftMarkerPx, rightMarkerPx) {
822
+ var isInsideOnLeftSide = x >= leftMarkerPx;
823
+ var isInsideOnRightSide = x <= rightMarkerPx;
824
+ return isInsideOnLeftSide && isInsideOnRightSide;
825
+ };
826
+ /**
827
+ * @param x The pin location
828
+ * @param selectedTimePx The selected px
829
+ * @param width The default width of a hoverable icon (usually 24px)
830
+ * @returns
831
+ */
832
+ var isLeftAnimationIconArea = function isLeftAnimationIconArea(x, leftMarkerPx, width) {
833
+ return x >= leftMarkerPx && x <= leftMarkerPx + width;
834
+ };
835
+ function convertStringTimeToUnix(time) {
836
+ return time ? dateUtils.unix(new Date(time)) : undefined;
837
+ }
838
+ var timeValues = [3600, 10800, 21600, 43200, 86400, 172800, 604800, 1209600, 2592000, 7776000, 31536000];
839
+ var TIME_SLIDER_LEGEND_HEIGHT = 24;
840
+ var DRAG_AREA_WIDTH = 24;
841
+ var isDraggingStartWithinBounds = function isDraggingStartWithinBounds(endPos, mousePosition) {
842
+ var startAnimationMaxPosition = endPos - DRAG_AREA_WIDTH * 2;
843
+ return mousePosition >= startAnimationMaxPosition || mousePosition <= 0;
844
+ };
845
+ var isDraggingEndWithinBounds = function isDraggingEndWithinBounds(startPos, mousePosition, canvasWidth) {
846
+ var endAnimationMinimumPosition = startPos + DRAG_AREA_WIDTH * 2;
847
+ return endAnimationMinimumPosition >= mousePosition || mousePosition >= canvasWidth;
848
+ };
849
+ var getTimeSliderLegendId = function getTimeSliderLegendId(mapId) {
850
+ return "timeSliderLegend_" + mapId;
851
+ };
852
+ var getTimeSliderLegendElement = function getTimeSliderLegendElement(mapId) {
853
+ return document.querySelector(".timeSliderLegend_" + mapId);
854
+ };
855
+ var getPixelsBetweenViewportAndTimesliderOnLeft = function getPixelsBetweenViewportAndTimesliderOnLeft(mapId) {
856
+ var timeSliderLegendElement = document.querySelector(".timeSliderLegend_" + mapId);
857
+ return timeSliderLegendElement == null ? void 0 : timeSliderLegendElement.getBoundingClientRect()['left'];
858
+ };
859
+ function getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end) {
860
+ var selectedTimePosition = timestampToPixel(unfilteredSelectedTime, centerTime, width, secondsPerPx);
861
+ var endAnimationPosition = timestampToPixel(end, centerTime, width, secondsPerPx);
862
+ var startAnimationPosition = timestampToPixel(start, centerTime, width, secondsPerPx);
863
+ return {
864
+ startAnimationPosition: startAnimationPosition,
865
+ endAnimationPosition: endAnimationPosition,
866
+ selectedTimePosition: selectedTimePosition
867
+ };
868
+ }
869
+
870
+ var TimeSlider = function TimeSlider(_ref) {
871
+ var buttons = _ref.buttons,
872
+ timeBox = _ref.timeBox,
873
+ legend = _ref.legend,
874
+ _ref$mapIsActive = _ref.mapIsActive,
875
+ mapIsActive = _ref$mapIsActive === void 0 ? true : _ref$mapIsActive,
876
+ _ref$isVisible = _ref.isVisible,
877
+ isVisible = _ref$isVisible === void 0 ? true : _ref$isVisible,
878
+ timeStep = _ref.timeStep,
879
+ dataStartTime = _ref.dataStartTime,
880
+ dataEndTime = _ref.dataEndTime,
881
+ selectedTime = _ref.selectedTime,
882
+ onSetNewDate = _ref.onSetNewDate,
883
+ onSetCenterTime = _ref.onSetCenterTime,
884
+ _ref$onToggleTimeSlid = _ref.onToggleTimeSlider,
885
+ onToggleTimeSlider = _ref$onToggleTimeSlid === void 0 ? function () {} : _ref$onToggleTimeSlid;
886
+ // set up visibility toggle
887
+ useToggleTimesliderVisibility(mapIsActive, isVisible, onToggleTimeSlider);
888
+ // set up movement with keyboard shortcuts
889
+ useMoveTimeWithKeyboard(mapIsActive, timeStep, dataStartTime, dataEndTime, onSetNewDate, onSetCenterTime, selectedTime);
890
+ // timeBox, buttons and legend are created in TimeSliderConnect.tsx
891
+ // these components will always be created as TimeSlider never runs in isolation from the store
892
+ return isVisible ? jsxs(Grid, {
893
+ container: true,
894
+ "data-testid": "timeSlider",
895
+ sx: {
896
+ display: 'grid',
897
+ gridTemplateColumns: '175px 1fr 40px',
898
+ gridTemplateRows: TIME_SLIDER_LEGEND_HEIGHT,
899
+ gridTemplateAreas: "\". timebox .\"\n \"buttons timelegend toggle\"",
900
+ alignItems: 'center',
901
+ justifyContent: 'center',
902
+ visibility: isVisible ? 'visible' : 'hidden',
903
+ // Apply these styles only one mobile devices on landscape orientation
904
+ '@media screen and (max-width: 1024px) and (orientation: landscape)': {
905
+ paddingLeft: '5%',
906
+ paddingRight: '5%'
907
+ }
908
+ },
909
+ children: [jsx(Grid, {
910
+ sx: {
911
+ gridArea: 'timebox',
912
+ zIndex: 99,
913
+ position: 'relative',
914
+ overflow: 'hidden'
915
+ },
916
+ children: timeBox
917
+ }), jsx(Grid, {
918
+ sx: {
919
+ gridArea: 'buttons'
920
+ },
921
+ children: buttons
922
+ }), jsx(Grid, {
923
+ sx: {
924
+ gridArea: 'timelegend'
925
+ },
926
+ children: legend
927
+ }), jsx(Grid, {
928
+ sx: {
929
+ gridArea: 'toggle',
930
+ paddingLeft: 1,
931
+ lineHeight: 0
932
+ },
933
+ children: jsx(HideSliderButton, {
934
+ isVisible: isVisible,
935
+ toggleTimeSliderIsVisible: onToggleTimeSlider
936
+ })
937
+ })]
938
+ }) : jsx(Grid, {
939
+ container: true,
940
+ sx: {
941
+ paddingRight: 1,
942
+ alignItems: 'center',
943
+ justifyContent: 'flex-end'
944
+ },
945
+ children: jsx(HideSliderButton, {
946
+ isVisible: isVisible,
947
+ toggleTimeSliderIsVisible: onToggleTimeSlider
948
+ })
949
+ });
950
+ };
951
+
952
+ var _scaleToUnitSeconds, _scaleToRoundableUnit;
953
+ var scaleToUnitSeconds = (_scaleToUnitSeconds = {}, _scaleToUnitSeconds[Scale.Minutes5] = 5 * 60, _scaleToUnitSeconds[Scale.Hour] = 60 * 60, _scaleToUnitSeconds[Scale.Hours3] = 3 * 60 * 60, _scaleToUnitSeconds[Scale.Hours6] = 6 * 60 * 60, _scaleToUnitSeconds[Scale.Day] = 24 * 60 * 60, _scaleToUnitSeconds[Scale.Week] = 7 * 24 * 60 * 60, _scaleToUnitSeconds[Scale.Weeks2] = 14 * 24 * 60 * 60, _scaleToUnitSeconds);
954
+ var TICK_MARK_HEIGHT_PRIMARY = 40;
955
+ var TICK_MARK_HEIGHT_SECONDARY = 10;
956
+ var TICK_MARK_HEIGHT_TERTIARY = 5;
957
+ var getStepPxLineHeight = function getStepPxLineHeight(scale, timestep) {
958
+ var scaleUnitSeconds = scaleToUnitSeconds[scale];
959
+ var rem = timestep % scaleUnitSeconds;
960
+ switch (scale) {
961
+ case Scale.Hour:
962
+ {
963
+ if (rem === 0) {
964
+ return TICK_MARK_HEIGHT_PRIMARY;
965
+ }
966
+ // 15 min subdivisions
967
+ if (rem % (15 * 60) === 0) {
968
+ return TICK_MARK_HEIGHT_SECONDARY;
969
+ }
970
+ return TICK_MARK_HEIGHT_TERTIARY;
971
+ }
972
+ case Scale.Hours3:
973
+ {
974
+ if (rem === 0) {
975
+ return TICK_MARK_HEIGHT_PRIMARY;
976
+ }
977
+ return TICK_MARK_HEIGHT_TERTIARY;
978
+ }
979
+ case Scale.Hours6:
980
+ {
981
+ if (rem === 0) {
982
+ return TICK_MARK_HEIGHT_PRIMARY;
983
+ }
984
+ // 3 hour subdivisions
985
+ if (rem % (3 * 60 * 60) === 0) {
986
+ return TICK_MARK_HEIGHT_SECONDARY;
987
+ }
988
+ return TICK_MARK_HEIGHT_TERTIARY;
989
+ }
990
+ case Scale.Day:
991
+ {
992
+ if (rem === 0) {
993
+ return TICK_MARK_HEIGHT_PRIMARY;
994
+ }
995
+ // 6 hour subdivisions
996
+ if (rem % (6 * 60 * 60) === 0) {
997
+ return TICK_MARK_HEIGHT_SECONDARY;
998
+ }
999
+ return TICK_MARK_HEIGHT_TERTIARY;
1000
+ }
1001
+ case Scale.Week:
1002
+ case Scale.Weeks2:
1003
+ {
1004
+ var weekday = dateUtils.getDay(dateUtils.fromUnix(timestep));
1005
+ // dateUtils days range from 0 (Sunday) to 6 (Saturday)
1006
+ if (weekday === 1) {
1007
+ return TICK_MARK_HEIGHT_PRIMARY;
1008
+ }
1009
+ return TICK_MARK_HEIGHT_TERTIARY;
1010
+ }
1011
+ case Scale.Year:
1012
+ {
1013
+ var month = dateUtils.getMonth(dateUtils.fromUnix(timestep));
1014
+ // months are zero indexed
1015
+ if (month === 0) {
1016
+ return TICK_MARK_HEIGHT_PRIMARY;
1017
+ }
1018
+ if (month % 3 === 0) {
1019
+ return TICK_MARK_HEIGHT_SECONDARY;
1020
+ }
1021
+ return TICK_MARK_HEIGHT_TERTIARY;
1022
+ }
1023
+ case Scale.Minutes5:
1024
+ {
1025
+ // add primary line on day change
1026
+ if (timestep % (60 * 60 * 24) === 0) {
1027
+ return TICK_MARK_HEIGHT_PRIMARY;
1028
+ }
1029
+ return TICK_MARK_HEIGHT_TERTIARY;
1030
+ }
1031
+ default:
1032
+ // Scale.Month
1033
+ return TICK_MARK_HEIGHT_TERTIARY;
1034
+ }
1035
+ };
1036
+ var drawStepPxLine = function drawStepPxLine(ctx, theme, stepPx, height, fundamentalScale, timestep) {
1037
+ var ctx2 = ctx;
1038
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1039
+ ctx2.lineWidth = 1;
1040
+ var stepPxLineHeight = getStepPxLineHeight(fundamentalScale, timestep);
1041
+ ctx2.beginPath();
1042
+ ctx2.moveTo(stepPx, height - stepPxLineHeight);
1043
+ ctx2.lineTo(stepPx, height);
1044
+ ctx2.stroke();
1045
+ };
1046
+ var drawTimeText = function drawTimeText(ctx, theme, stepPx, height, timeText, scale) {
1047
+ var ctx2 = ctx;
1048
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider.timelineText,
1049
+ fontSize = _theme$palette$geoweb.fontSize,
1050
+ fontFamily = _theme$palette$geoweb.fontFamily,
1051
+ color = _theme$palette$geoweb.color;
1052
+ ctx2.fillStyle = color;
1053
+ // time text has smaller font than other timeline text
1054
+ ctx2.font = fontSize + "px " + fontFamily;
1055
+ ctx2.textAlign = 'left';
1056
+ if (scale === Scale.Year || scale === Scale.Months3 || scale === Scale.Month || scale === Scale.Weeks2 || scale === Scale.Week || scale === Scale.Day) {
1057
+ ctx2.fillText(timeText, stepPx, height - 12);
1058
+ } else {
1059
+ ctx2.fillText(timeText, stepPx - 15, height - 12);
1060
+ }
1061
+ };
1062
+ var drawYearScaleText = function drawYearScaleText(ctx, theme, newDate, stepPx, height) {
1063
+ var ctx2 = ctx;
1064
+ var _theme$palette$geoweb2 = theme.palette.geowebColors.timeSlider.timelineText,
1065
+ fontSize = _theme$palette$geoweb2.fontSize,
1066
+ fontFamily = _theme$palette$geoweb2.fontFamily,
1067
+ color = _theme$palette$geoweb2.color;
1068
+ ctx2.fillStyle = color;
1069
+ ctx2.font = fontSize + "px " + fontFamily;
1070
+ ctx2.textAlign = 'left';
1071
+ ctx2.fillText(newDate, stepPx + 2, height - 10);
1072
+ };
1073
+ var drawLeftSideDateText = function drawLeftSideDateText(ctx, theme, newDate, height) {
1074
+ var ctx2 = ctx;
1075
+ var _theme$palette$geoweb3 = theme.palette.geowebColors.timeSlider.timelineText,
1076
+ fontSize = _theme$palette$geoweb3.fontSize,
1077
+ fontFamily = _theme$palette$geoweb3.fontFamily,
1078
+ color = _theme$palette$geoweb3.color;
1079
+ ctx2.fillStyle = color;
1080
+ ctx2.font = fontSize + "px " + fontFamily;
1081
+ ctx2.textAlign = 'left';
1082
+ ctx2.fillText(newDate, 2, height - 30);
1083
+ };
1084
+ var getTimeFormat = function getTimeFormat(scale) {
1085
+ switch (scale) {
1086
+ case Scale.Year:
1087
+ return 'y';
1088
+ case Scale.Month:
1089
+ case Scale.Months3:
1090
+ return 'MMM';
1091
+ case Scale.Week:
1092
+ case Scale.Weeks2:
1093
+ return 'dd MMM';
1094
+ case Scale.Day:
1095
+ return 'EEE dd';
1096
+ default:
1097
+ return dateUtils.DATE_FORMAT_HOURS;
1098
+ }
1099
+ };
1100
+ var drawDateChangeLine = function drawDateChangeLine(ctx, theme, stepPx, height) {
1101
+ var ctx2 = ctx;
1102
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1103
+ ctx2.lineWidth = 1;
1104
+ ctx2.beginPath();
1105
+ ctx2.moveTo(stepPx, height - 40);
1106
+ ctx2.lineTo(stepPx, height);
1107
+ ctx2.stroke();
1108
+ };
1109
+ var drawDashedMonthChangeLine = function drawDashedMonthChangeLine(ctx, theme, stepPx, height) {
1110
+ var ctx2 = ctx;
1111
+ ctx2.strokeStyle = theme.palette.geowebColors.timeSlider.timelineMonthChangeDash.rgba;
1112
+ ctx2.lineWidth = 3;
1113
+ ctx2.setLineDash([5, 5]);
1114
+ ctx2.beginPath();
1115
+ ctx2.moveTo(stepPx, 0);
1116
+ ctx2.lineTo(stepPx, height);
1117
+ ctx2.stroke();
1118
+ ctx2.setLineDash([]);
1119
+ };
1120
+ var roundByUnitOfTime = function roundByUnitOfTime(timeUnix, unit, roundUp) {
1121
+ if (roundUp === void 0) {
1122
+ roundUp = false;
1123
+ }
1124
+ if (unit === 'hour') {
1125
+ var _timeStartOfPassedUnit = dateUtils.startOfHourUTC(dateUtils.fromUnix(timeUnix));
1126
+ if (roundUp) {
1127
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit, {
1128
+ hours: 1
1129
+ }));
1130
+ }
1131
+ return dateUtils.unix(_timeStartOfPassedUnit);
1132
+ }
1133
+ if (unit === 'day') {
1134
+ var _timeStartOfPassedUnit2 = dateUtils.startOfDayUTC(dateUtils.fromUnix(timeUnix));
1135
+ if (roundUp) {
1136
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit2, {
1137
+ days: 1
1138
+ }));
1139
+ }
1140
+ return dateUtils.unix(_timeStartOfPassedUnit2);
1141
+ }
1142
+ if (unit === 'week') {
1143
+ var _timeStartOfPassedUnit3 = dateUtils.startOfWeekUTC(dateUtils.fromUnix(timeUnix));
1144
+ if (roundUp) {
1145
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit3, {
1146
+ weeks: 1
1147
+ }));
1148
+ }
1149
+ return dateUtils.unix(_timeStartOfPassedUnit3);
1150
+ }
1151
+ if (unit === 'month') {
1152
+ var _timeStartOfPassedUnit4 = dateUtils.startOfMonthUTC(dateUtils.fromUnix(timeUnix));
1153
+ if (roundUp) {
1154
+ return dateUtils.unix(dateUtils.add(_timeStartOfPassedUnit4, {
1155
+ months: 1
1156
+ }));
1157
+ }
1158
+ return dateUtils.unix(_timeStartOfPassedUnit4);
1159
+ }
1160
+ // Default unit === 'year'
1161
+ var timeStartOfPassedUnit = dateUtils.startOfYearUTC(dateUtils.fromUnix(timeUnix));
1162
+ if (roundUp) {
1163
+ return dateUtils.unix(dateUtils.add(timeStartOfPassedUnit, {
1164
+ years: 1
1165
+ }));
1166
+ }
1167
+ return dateUtils.unix(timeStartOfPassedUnit);
1168
+ };
1169
+ var roundToNearestMultiple = function roundToNearestMultiple(timeUnix, scale, roundUp) {
1170
+ if (roundUp === void 0) {
1171
+ roundUp = false;
1172
+ }
1173
+ var stepSeconds = scaleToUnitSeconds[scale];
1174
+ var roundFn = roundUp ? Math.ceil : Math.floor;
1175
+ return roundFn(timeUnix / stepSeconds) * stepSeconds;
1176
+ };
1177
+ /**
1178
+ * In this script starting and ending times of the time slider are rounded.
1179
+ * Here it is defined what is a time unit to a start of which a rounding is
1180
+ * done for each scale.
1181
+ * @returns an object where there are rounding units of each scale
1182
+ */
1183
+ var scaleToRoundableUnit = (_scaleToRoundableUnit = {}, _scaleToRoundableUnit[Scale.Hour] = 'hour', _scaleToRoundableUnit[Scale.Day] = 'day', _scaleToRoundableUnit[Scale.Week] = 'week', _scaleToRoundableUnit[Scale.Weeks2] = 'week', _scaleToRoundableUnit[Scale.Month] = 'week', _scaleToRoundableUnit[Scale.Months3] = 'week', _scaleToRoundableUnit[Scale.Year] = 'year', _scaleToRoundableUnit);
1184
+ var getRoundedStartAndEnd = function getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale) {
1185
+ if (scale === Scale.Minutes5 || scale === Scale.Hours3 || scale === Scale.Hours6) {
1186
+ return [roundToNearestMultiple(visibleTimeStart, scale, false), roundToNearestMultiple(visibleTimeEnd, scale, true)];
1187
+ }
1188
+ var unit = scaleToRoundableUnit[scale];
1189
+ return [roundByUnitOfTime(visibleTimeStart, unit, false), roundByUnitOfTime(visibleTimeEnd, unit, true)];
1190
+ };
1191
+ var getCustomRoundedStartAndEndScale = function getCustomRoundedStartAndEndScale(scale) {
1192
+ switch (scale) {
1193
+ case Scale.Year:
1194
+ return 'month';
1195
+ case Scale.Month:
1196
+ case Scale.Months3:
1197
+ return 'week';
1198
+ case Scale.Week:
1199
+ case Scale.Weeks2:
1200
+ return 'day';
1201
+ default:
1202
+ return 'day';
1203
+ }
1204
+ };
1205
+ var getCustomRoundedStartAndEnd = function getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, unit) {
1206
+ var scale = getCustomRoundedStartAndEndScale(unit);
1207
+ return [roundByUnitOfTime(visibleTimeStart, scale, false), roundByUnitOfTime(visibleTimeEnd, scale, true)];
1208
+ };
1209
+ var incrementTimestep = function incrementTimestep(timeAtTimeStep, fundamentalScale) {
1210
+ switch (fundamentalScale) {
1211
+ case Scale.Minutes5:
1212
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1213
+ minutes: 1
1214
+ }));
1215
+ case Scale.Hour:
1216
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1217
+ minutes: 5
1218
+ }));
1219
+ case Scale.Hours3:
1220
+ case Scale.Hours6:
1221
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1222
+ hours: 1
1223
+ }));
1224
+ case Scale.Day:
1225
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1226
+ hours: 3
1227
+ }));
1228
+ case Scale.Week:
1229
+ case Scale.Weeks2:
1230
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1231
+ days: 1
1232
+ }));
1233
+ case Scale.Month:
1234
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1235
+ weeks: 1
1236
+ }));
1237
+ case Scale.Year:
1238
+ case Scale.Months3:
1239
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1240
+ months: 1
1241
+ }));
1242
+ default:
1243
+ return dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timeAtTimeStep), {
1244
+ months: 1
1245
+ }));
1246
+ }
1247
+ };
1248
+ var getTimesteps = function getTimesteps(roundedStart, roundedEnd, fundamentalScaleType) {
1249
+ var timesteps = [];
1250
+ var timestep = roundedStart;
1251
+ while (timestep <= roundedEnd) {
1252
+ timesteps.push(timestep);
1253
+ timestep = incrementTimestep(timestep, fundamentalScaleType);
1254
+ }
1255
+ return timesteps;
1256
+ };
1257
+ var getCustomTimesteps = function getCustomTimesteps(roundedStart, roundedEnd, increment) {
1258
+ var timesteps = [];
1259
+ var timestep = roundedStart;
1260
+ while (timestep <= roundedEnd) {
1261
+ var _dateUtils$add;
1262
+ timesteps.push(timestep);
1263
+ timestep = dateUtils.unix(dateUtils.add(dateUtils.fromUnix(timestep), (_dateUtils$add = {}, _dateUtils$add[increment] = 1, _dateUtils$add)));
1264
+ }
1265
+ return timesteps;
1266
+ };
1267
+ var getLeftSideDateText = function getLeftSideDateText(timestamp, fundamentalScale) {
1268
+ var time = dateUtils.fromUnix(timestamp);
1269
+ switch (fundamentalScale) {
1270
+ case Scale.Minutes5:
1271
+ case Scale.Hour:
1272
+ case Scale.Hours3:
1273
+ case Scale.Hours6:
1274
+ return dateUtils.dateToString(time, 'y MMM EEE dd');
1275
+ case Scale.Day:
1276
+ case Scale.Week:
1277
+ case Scale.Weeks2:
1278
+ return dateUtils.dateToString(time, 'y MMM');
1279
+ case Scale.Month:
1280
+ case Scale.Months3:
1281
+ return dateUtils.dateToString(time, 'y');
1282
+ case Scale.Year:
1283
+ return dateUtils.dateToString(time, 'y');
1284
+ default:
1285
+ return '';
1286
+ }
1287
+ };
1288
+ var drawTimeScale = function drawTimeScale(context, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx) {
1289
+ var fundamentalScale = getFundamentalScale(secondsPerPx);
1290
+ var _getRoundedStartAndEn = getRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, fundamentalScale),
1291
+ roundedStart = _getRoundedStartAndEn[0],
1292
+ roundedEnd = _getRoundedStartAndEn[1];
1293
+ // draw regular tickmarks
1294
+ var ctx = context;
1295
+ getTimesteps(roundedStart, roundedEnd, fundamentalScale).forEach(function (timestep) {
1296
+ var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
1297
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
1298
+ drawStepPxLine(ctx, theme, Math.floor(stepPx) + 0.5, height, fundamentalScale, timestep);
1299
+ // Draw the time step time as text
1300
+ var timeFormat = getTimeFormat(fundamentalScale);
1301
+ var timeText = dateUtils.dateToString(dateUtils.fromUnix(timestep), timeFormat);
1302
+ if ([Scale.Minutes5, Scale.Hour, Scale.Hours3, Scale.Hours6, Scale.Day].includes(fundamentalScale) &&
1303
+ // eslint-disable-next-line @typescript-eslint/no-confusing-non-null-assertion
1304
+ timestep % scaleToUnitSeconds[fundamentalScale] === 0 || fundamentalScale === Scale.Week && dateUtils.getDay(dateUtils.fromUnix(timestep)) === 1) {
1305
+ drawTimeText(ctx, theme, stepPx, height, timeText, fundamentalScale);
1306
+ }
1307
+ if (fundamentalScale === Scale.Year && dateUtils.getMonth(dateUtils.fromUnix(timestep)) === 0) {
1308
+ drawYearScaleText(ctx, theme, timeText, stepPx, height);
1309
+ }
1310
+ });
1311
+ // draw month overlay lines
1312
+ if (fundamentalScale === Scale.Week || fundamentalScale === Scale.Weeks2 || fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
1313
+ var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, Scale.Year),
1314
+ _roundedStart = _getCustomRoundedStar[0],
1315
+ _roundedEnd = _getCustomRoundedStar[1];
1316
+ var monthTimesteps = getCustomTimesteps(_roundedStart, _roundedEnd, 'months');
1317
+ monthTimesteps.forEach(function (timestep) {
1318
+ var stepPx = timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
1319
+ if (fundamentalScale === Scale.Month || fundamentalScale === Scale.Months3) {
1320
+ var month = dateUtils.dateToString(dateUtils.fromUnix(timestep), 'MMM');
1321
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
1322
+ drawDateChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
1323
+ drawTimeText(ctx, theme, stepPx, height, month, fundamentalScale);
1324
+ return;
1325
+ }
1326
+ // adding 0.5 to make line not so blurred
1327
+ drawDashedMonthChangeLine(ctx, theme, Math.floor(stepPx) + 0.5, height);
1328
+ });
1329
+ }
1330
+ // draw date change texts
1331
+ if (fundamentalScale === Scale.Year) {
1332
+ return;
1333
+ }
1334
+ var dateText = getLeftSideDateText(visibleTimeStart, fundamentalScale);
1335
+ drawLeftSideDateText(ctx, theme, dateText, height);
1336
+ };
1337
+
1338
+ /* *
1339
+ * Licensed under the Apache License, Version 2.0 (the "License");
1340
+ * you may not use this file except in compliance with the License.
1341
+ * You may obtain a copy of the License at
1342
+ *
1343
+ * http://www.apache.org/licenses/LICENSE-2.0
1344
+ *
1345
+ * Unless required by applicable law or agreed to in writing, software
1346
+ * distributed under the License is distributed on an "AS IS" BASIS,
1347
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1348
+ * See the License for the specific language governing permissions and
1349
+ * limitations under the License.
1350
+ *
1351
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1352
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1353
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1354
+ * */
1355
+ var drawBackground = function drawBackground(context, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx) {
1356
+ var ctx = context;
1357
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
1358
+ timelineNightTime = _theme$palette$geoweb.timelineNightTime,
1359
+ ledgendObservedBackground = _theme$palette$geoweb.ledgendObservedBackground,
1360
+ legendForecastBackground = _theme$palette$geoweb.legendForecastBackground,
1361
+ legendNoDataBackground = _theme$palette$geoweb.legendNoDataBackground;
1362
+ // top spacing
1363
+ var y = 0;
1364
+ var scaleToUse = timeSliderSpan ? getScaleFromSpan(timeSliderSpan) : getFundamentalScale(secondsPerPx);
1365
+ drawDefaultBackground();
1366
+ drawObservedData();
1367
+ drawForecastData();
1368
+ drawNightOrAlternateTime();
1369
+ drawAnimationArea();
1370
+ drawDraggableIcons();
1371
+ function drawDefaultBackground() {
1372
+ ctx.fillStyle = legendNoDataBackground.rgba;
1373
+ ctx.fillRect(0, y, canvasWidth, height);
1374
+ }
1375
+ function drawObservedData() {
1376
+ if (dataStartPx < currentTimePx) {
1377
+ ctx.fillStyle = ledgendObservedBackground.fill;
1378
+ ctx.fillRect(Math.max(dataStartPx, y), y, Math.min(currentTimePx, dataEndPx) - Math.max(dataStartPx, y), height);
1379
+ }
1380
+ }
1381
+ function drawForecastData() {
1382
+ if (dataEndPx > currentTimePx) {
1383
+ ctx.fillStyle = legendForecastBackground.fill;
1384
+ ctx.fillRect(Math.max(currentTimePx, dataStartPx), y, Math.min(canvasWidth, dataEndPx) - Math.max(currentTimePx, dataStartPx), height);
1385
+ }
1386
+ }
1387
+ function drawAnimationArea() {
1388
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineSelectionBackground.rgba;
1389
+ ctx.strokeStyle = theme.palette.geowebColors.timeSlider.timelineSelectionOutline.rgba;
1390
+ ctx.lineWidth = 3;
1391
+ ctx.rect(animationStartPx, y, Math.max(animationEndPx - animationStartPx, y), height);
1392
+ ctx.fill();
1393
+ ctx.stroke();
1394
+ }
1395
+ function drawDraggableIcons() {
1396
+ ctx.save();
1397
+ var path = new Path2D(dragHandlePath);
1398
+ ctx.translate(animationStartPx, y);
1399
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1400
+ ctx.fill(path);
1401
+ ctx.restore();
1402
+ ctx.save();
1403
+ ctx.translate(animationEndPx - 24, y);
1404
+ ctx.fillStyle = theme.palette.geowebColors.timeSlider.timelineTimeScale.fill;
1405
+ ctx.fill(path);
1406
+ ctx.restore();
1407
+ }
1408
+ function drawNightOrAlternateTime() {
1409
+ var colorChangeTimesteps = getColorChangeTimesteps(scaleToUse, visibleTimeStart, visibleTimeEnd);
1410
+ colorChangeTimesteps.forEach(function (timestep, i, arr) {
1411
+ if (i === 0) {
1412
+ return;
1413
+ }
1414
+ var _map = [arr[i - 1], timestep].map(function (timestep) {
1415
+ return timestampToPixelEdges(timestep, visibleTimeStart, visibleTimeEnd, canvasWidth);
1416
+ }),
1417
+ prevPx = _map[0],
1418
+ currPx = _map[1];
1419
+ if (!isColorIntervalEven(scaleToUse, timestep)) {
1420
+ ctx.fillStyle = timelineNightTime.rgba;
1421
+ var TOP_OFFSET = 0;
1422
+ ctx.fillRect(prevPx, TOP_OFFSET, currPx - prevPx, height);
1423
+ }
1424
+ });
1425
+ }
1426
+ };
1427
+ var getColorChangeTimestepUnit = function getColorChangeTimestepUnit(scale) {
1428
+ switch (scale) {
1429
+ case Scale.Year:
1430
+ return 'months';
1431
+ case Scale.Month:
1432
+ case Scale.Months3:
1433
+ return 'weeks';
1434
+ case Scale.Weeks2:
1435
+ case Scale.Week:
1436
+ return 'days';
1437
+ default:
1438
+ return 'days';
1439
+ }
1440
+ };
1441
+ var isColorIntervalEven = function isColorIntervalEven(scale, timestep) {
1442
+ var time = dateUtils.fromUnix(timestep);
1443
+ switch (scale) {
1444
+ case Scale.Year:
1445
+ return dateUtils.getMonth(time) % 2 === 0;
1446
+ case Scale.Month:
1447
+ case Scale.Months3:
1448
+ return dateUtils.getWeek(time) % 2 === 0;
1449
+ case Scale.Week:
1450
+ case Scale.Weeks2:
1451
+ return dateUtils.getDayOfYear(time) % 2 === 0;
1452
+ default:
1453
+ {
1454
+ return dateUtils.getDayOfYear(time) % 2 === 0;
1455
+ }
1456
+ }
1457
+ };
1458
+ function getColorChangeTimesteps(scale, visibleTimeStart, visibleTimeEnd) {
1459
+ var _getCustomRoundedStar = getCustomRoundedStartAndEnd(visibleTimeStart, visibleTimeEnd, scale),
1460
+ colorChangeStart = _getCustomRoundedStar[0],
1461
+ colorChangeEnd = _getCustomRoundedStar[1];
1462
+ var colorChangeUnit = getColorChangeTimestepUnit(scale);
1463
+ var colorChangeTimesteps = getCustomTimesteps(colorChangeStart, colorChangeEnd, colorChangeUnit);
1464
+ return colorChangeTimesteps;
1465
+ }
1466
+
1467
+ /* *
1468
+ * Licensed under the Apache License, Version 2.0 (the "License");
1469
+ * you may not use this file except in compliance with the License.
1470
+ * You may obtain a copy of the License at
1471
+ *
1472
+ * http://www.apache.org/licenses/LICENSE-2.0
1473
+ *
1474
+ * Unless required by applicable law or agreed to in writing, software
1475
+ * distributed under the License is distributed on an "AS IS" BASIS,
1476
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1477
+ * See the License for the specific language governing permissions and
1478
+ * limitations under the License.
1479
+ *
1480
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1481
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1482
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1483
+ * */
1484
+ var drawCurrentTime = function drawCurrentTime(context, theme, width, height, startTime, endTime, currentTime) {
1485
+ var ctx = context;
1486
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
1487
+ playerNeedleTime = _theme$palette$geoweb.playerNeedleTime,
1488
+ playerNeedleTimeTop = _theme$palette$geoweb.playerNeedleTimeTop;
1489
+ var current = currentTime;
1490
+ var currentPx = current ? timestampToPixelEdges(current, startTime, endTime, width) : 0;
1491
+ // Draw a high vertical line (needle) indicating the current or selected time
1492
+ ctx.beginPath();
1493
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
1494
+ ctx.moveTo(Math.floor(currentPx) + 0.5, height - 24);
1495
+ ctx.lineTo(Math.floor(currentPx) + 0.5, height);
1496
+ ctx.lineWidth = 5;
1497
+ ctx.strokeStyle = playerNeedleTime.rgba;
1498
+ ctx.stroke();
1499
+ ctx.lineWidth = 1;
1500
+ ctx.strokeStyle = playerNeedleTimeTop.rgba;
1501
+ ctx.stroke();
1502
+ };
1503
+
1504
+ /* *
1505
+ * Licensed under the Apache License, Version 2.0 (the "License");
1506
+ * you may not use this file except in compliance with the License.
1507
+ * You may obtain a copy of the License at
1508
+ *
1509
+ * http://www.apache.org/licenses/LICENSE-2.0
1510
+ *
1511
+ * Unless required by applicable law or agreed to in writing, software
1512
+ * distributed under the License is distributed on an "AS IS" BASIS,
1513
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1514
+ * See the License for the specific language governing permissions and
1515
+ * limitations under the License.
1516
+ *
1517
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1518
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1519
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1520
+ * */
1521
+ var drawNeedle = function drawNeedle(context, theme, width, height, startTime, endTime, selectedTime) {
1522
+ if (!selectedTime) {
1523
+ return;
1524
+ }
1525
+ var ctx = context;
1526
+ var _theme$palette$geoweb = theme.palette.geowebColors.timeSlider,
1527
+ playerNeedlePlayer = _theme$palette$geoweb.playerNeedlePlayer,
1528
+ playerNeedlePlayerTop = _theme$palette$geoweb.playerNeedlePlayerTop,
1529
+ playerTimeMarkers = _theme$palette$geoweb.playerTimeMarkers;
1530
+ var selectedPx = timestampToPixelEdges(selectedTime, startTime, endTime, width);
1531
+ // Draw a high vertical line (needle) indicating the current or selected time
1532
+ ctx.beginPath();
1533
+ // Move 1 pixel line by 0.5 pixels to prevent it from being shown as blurry: https://usefulangle.com/post/17/html5-canvas-drawing-1px-crisp-straight-lines
1534
+ ctx.moveTo(Math.floor(selectedPx) + 0.5, height - 50);
1535
+ ctx.lineTo(Math.floor(selectedPx) + 0.5, height);
1536
+ ctx.lineWidth = 5;
1537
+ ctx.strokeStyle = playerNeedlePlayer.rgba;
1538
+ ctx.stroke();
1539
+ ctx.lineWidth = 1;
1540
+ ctx.strokeStyle = playerNeedlePlayerTop.rgba;
1541
+ ctx.stroke();
1542
+ // Triange connecting timebox.
1543
+ ctx.beginPath();
1544
+ ctx.moveTo(Math.floor(selectedPx) + 5, 0);
1545
+ ctx.lineTo(Math.floor(selectedPx) + 0.5, 5);
1546
+ ctx.lineTo(Math.floor(selectedPx) - 5, 0);
1547
+ ctx.closePath();
1548
+ ctx.fillStyle = playerTimeMarkers.fill;
1549
+ ctx.fill();
1550
+ };
1551
+
1552
+ /* *
1553
+ * Licensed under the Apache License, Version 2.0 (the "License");
1554
+ * you may not use this file except in compliance with the License.
1555
+ * You may obtain a copy of the License at
1556
+ *
1557
+ * http://www.apache.org/licenses/LICENSE-2.0
1558
+ *
1559
+ * Unless required by applicable law or agreed to in writing, software
1560
+ * distributed under the License is distributed on an "AS IS" BASIS,
1561
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1562
+ * See the License for the specific language governing permissions and
1563
+ * limitations under the License.
1564
+ *
1565
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
1566
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
1567
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
1568
+ * */
1569
+ var drawTimeSliderLegend = function drawTimeSliderLegend(context, theme, canvasWidth, height, centerTime, secondsPerPx, timeSliderSpan, selectedTimeUnix, currentTimeUnix, animationStartTime, animationEndTime, dataStartTime, dataEndTime) {
1570
+ var ctx = context;
1571
+ var _map = [0, canvasWidth].map(function (px) {
1572
+ return pixelToTimestamp(px, centerTime, canvasWidth, secondsPerPx);
1573
+ }),
1574
+ visibleTimeStart = _map[0],
1575
+ visibleTimeEnd = _map[1];
1576
+ var _map2 = [animationStartTime, animationEndTime, dataStartTime, dataEndTime, currentTimeUnix].map(function (time) {
1577
+ return timestampToPixel(time, centerTime, canvasWidth, secondsPerPx);
1578
+ }),
1579
+ animationStartPx = _map2[0],
1580
+ animationEndPx = _map2[1],
1581
+ dataStartPx = _map2[2],
1582
+ dataEndPx = _map2[3],
1583
+ currentTimePx = _map2[4];
1584
+ ctx.clearRect(0, 0, canvasWidth, height);
1585
+ drawBackground(ctx, theme, visibleTimeStart, visibleTimeEnd, animationStartPx, animationEndPx, canvasWidth, height, secondsPerPx, timeSliderSpan, dataStartPx, dataEndPx, currentTimePx);
1586
+ drawTimeScale(ctx, theme, visibleTimeStart, visibleTimeEnd, canvasWidth, height, secondsPerPx);
1587
+ drawCurrentTime(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, currentTimeUnix);
1588
+ drawNeedle(ctx, theme, canvasWidth, height, visibleTimeStart, visibleTimeEnd, selectedTimeUnix);
1589
+ };
1590
+
1591
+ // Explanation of props can be found here:
1592
+ // https://drive.google.com/file/d/1jqqNcciCH0UJiZ04HO-1vknmPPpT8fK5/view?usp=sharing
1593
+ var TimeSliderLegend = function TimeSliderLegend(_ref) {
1594
+ var _node$current, _getTimeSliderLegendE;
1595
+ var mapId = _ref.mapId,
1596
+ isTimeScrollingEnabled = _ref.isTimeScrollingEnabled,
1597
+ mapWindowRef = _ref.mapWindowRef,
1598
+ centerTime = _ref.centerTime,
1599
+ canvasWidth = _ref.timeSliderWidth,
1600
+ _ref$secondsPerPx = _ref.secondsPerPx,
1601
+ secondsPerPx = _ref$secondsPerPx === void 0 ? defaultSecondsPerPx : _ref$secondsPerPx,
1602
+ currentTime = _ref.currentTime,
1603
+ dataStartTime = _ref.dataStartTime,
1604
+ dataEndTime = _ref.dataEndTime,
1605
+ reduxAnimationStartTime = _ref.reduxAnimationStartTime,
1606
+ reduxAnimationEndTime = _ref.reduxAnimationEndTime,
1607
+ timeStep = _ref.timeStep,
1608
+ unfilteredSelectedTime = _ref.unfilteredSelectedTime,
1609
+ isDraggingStartAnimation = _ref.isDraggingStartAnimation,
1610
+ isDraggingEndAnimation = _ref.isDraggingEndAnimation,
1611
+ isTimeSliderHoverOn = _ref.isTimeSliderHoverOn,
1612
+ timeSliderSpan = _ref.timeSliderSpan,
1613
+ _ref$setUnfilteredSel = _ref.setUnfilteredSelectedTime,
1614
+ setUnfilteredSelectedTime = _ref$setUnfilteredSel === void 0 ? function () {} : _ref$setUnfilteredSel,
1615
+ _ref$onSetCenterTime = _ref.onSetCenterTime,
1616
+ onSetCenterTime = _ref$onSetCenterTime === void 0 ? function () {} : _ref$onSetCenterTime,
1617
+ _ref$onSetAnimationSt = _ref.onSetAnimationStartTime,
1618
+ onSetAnimationStartTime = _ref$onSetAnimationSt === void 0 ? function () {} : _ref$onSetAnimationSt,
1619
+ _ref$onSetAnimationEn = _ref.onSetAnimationEndTime,
1620
+ onSetAnimationEndTime = _ref$onSetAnimationEn === void 0 ? function () {} : _ref$onSetAnimationEn,
1621
+ _ref$updateCanvasWidt = _ref.updateCanvasWidth,
1622
+ updateCanvasWidth = _ref$updateCanvasWidt === void 0 ? function () {} : _ref$updateCanvasWidt,
1623
+ setIsDraggingStartAnimation = _ref.setIsDraggingStartAnimation,
1624
+ setIsDraggingEndAnimation = _ref.setIsDraggingEndAnimation,
1625
+ onStartTimeChange = _ref.onStartTimeChange,
1626
+ onEndTimeChange = _ref.onEndTimeChange,
1627
+ onSetTimeSliderSpan = _ref.onSetTimeSliderSpan,
1628
+ _ref$adjustSelectedTi = _ref.adjustSelectedTimeOnWheel,
1629
+ adjustSelectedTimeOnWheel = _ref$adjustSelectedTi === void 0 ? function () {} : _ref$adjustSelectedTi;
1630
+ var _useCanvasTarget = useCanvasTarget('mousedown'),
1631
+ node = _useCanvasTarget[1];
1632
+ var theme = useTheme();
1633
+ var _useState = useState(false),
1634
+ isDraggingSelectedTime = _useState[0],
1635
+ setIsDraggingSelectedTime = _useState[1];
1636
+ var _useState2 = useState(false),
1637
+ isDraggingLegend = _useState2[0],
1638
+ setIsDraggingLegend = _useState2[1];
1639
+ var xOffset = ((_node$current = node.current) == null || (_node$current = _node$current.canvas) == null ? void 0 : _node$current.getBoundingClientRect().x) || 0;
1640
+ var _useState3 = useState(false),
1641
+ isDraggingAnimationArea = _useState3[0],
1642
+ setIsDraggingAnimationArea = _useState3[1];
1643
+ var _useState4 = useState(false),
1644
+ isMouseOverCanvas = _useState4[0],
1645
+ setIsMouseOverCanvas = _useState4[1];
1646
+ var _useState5 = useState('auto'),
1647
+ cursorStyle = _useState5[0],
1648
+ setCursorStyle = _useState5[1];
1649
+ var _useState6 = useState(undefined),
1650
+ showTooltip = _useState6[0],
1651
+ setShowTooltip = _useState6[1];
1652
+ var _useState7 = useState(),
1653
+ lastHandledRoundedTime = _useState7[0],
1654
+ setLastHandledRoundedTime = _useState7[1];
1655
+ // remove active drag. can happen outside canvas.
1656
+ var _useState8 = useState(),
1657
+ localAnimationStartTime = _useState8[0],
1658
+ setLocalAnimationStartTime = _useState8[1];
1659
+ var _useState9 = useState(),
1660
+ localAnimationEndTime = _useState9[0],
1661
+ setLocalAnimationEndTime = _useState9[1];
1662
+ var _useState0 = useState(),
1663
+ pointerTime = _useState0[0],
1664
+ setPointerTime = _useState0[1];
1665
+ var _useState1 = useState(false),
1666
+ showPointerTimeTooltip = _useState1[0],
1667
+ setShowPointerTimeTooltip = _useState1[1];
1668
+ var debouncedSetShowPointerTimeTooltip = useRef(debounce(setShowPointerTimeTooltip, 500)).current;
1669
+ var timeBetweenMouseAndStartAndEnd = useRef(undefined);
1670
+ var pixelsMovedSinceStartDragging = useRef(0);
1671
+ var isAnimationTimeModifiedSetRef = useRef(false);
1672
+ var tooltipPosition = useRef(undefined);
1673
+ var startDraggingPosition = useRef(0);
1674
+ var popperRef = useRef(null);
1675
+ var isClickOrDrag = useRef(undefined);
1676
+ // Display unfilteredSelectedTime (already snapped to available timestep)
1677
+ var displayTime = unfilteredSelectedTime;
1678
+ var start = localAnimationStartTime;
1679
+ var end = localAnimationEndTime;
1680
+ var pixelsBetweenViewportAndTimesliderOnTop = (_getTimeSliderLegendE = getTimeSliderLegendElement(mapId)) == null ? void 0 : _getTimeSliderLegendE.getBoundingClientRect()['top'];
1681
+ var setTooltipPosition = function setTooltipPosition() {
1682
+ var tooltipX = tooltipPosition.current;
1683
+ var tooltipY = pixelsBetweenViewportAndTimesliderOnTop && pixelsBetweenViewportAndTimesliderOnTop - TIME_SLIDER_LEGEND_HEIGHT * 2.5;
1684
+ return new DOMRect(tooltipX, tooltipY, 0, 0);
1685
+ };
1686
+ var getTooltipTime = function getTooltipTime() {
1687
+ switch (showTooltip) {
1688
+ case 'animationStart':
1689
+ return localAnimationStartTime;
1690
+ case 'animationEnd':
1691
+ return localAnimationEndTime;
1692
+ case 'mousePointer':
1693
+ return pointerTime;
1694
+ default:
1695
+ return undefined;
1696
+ }
1697
+ };
1698
+ var getTooltipText = function getTooltipText() {
1699
+ var time = getTooltipTime();
1700
+ if (!time) {
1701
+ return undefined;
1702
+ }
1703
+ var roundedTooltipTime = showTooltip === 'mousePointer' ? time : roundWithTimeStep$1(time);
1704
+ var tooltipText = dateUtils.dateToString(dateUtils.fromUnix(roundedTooltipTime), dateUtils.DATE_FORMAT_HOURS);
1705
+ return tooltipText;
1706
+ };
1707
+ var roundWithTimeStep$1 = function roundWithTimeStep$1(time) {
1708
+ return roundWithTimeStep(time, timeStep);
1709
+ };
1710
+ var currentIndex = timeValues.indexOf(timeSliderSpan);
1711
+ var updateTimeSpan = function updateTimeSpan(deltaY) {
1712
+ if (onSetTimeSliderSpan) {
1713
+ // Don't do anything if we are already at the edges of the timespan options
1714
+ if (deltaY < 0 && currentIndex === 0 || deltaY > 0 && currentIndex === timeValues.length - 1) {
1715
+ return;
1716
+ }
1717
+ var newTimeSpan = deltaY < 0 ? timeValues[currentIndex - 1] : timeValues[currentIndex + 1];
1718
+ onSetTimeSliderSpan(newTimeSpan, centerTime);
1719
+ }
1720
+ };
1721
+ var throttledUpdateTimeSpan = throttle(updateTimeSpan, 200);
1722
+ var debouncedAndThrottledUpdateTimeSpan = debounce(throttledUpdateTimeSpan, 20);
1723
+ var handleAnimationDragging = React.useCallback(function (x, clientX) {
1724
+ if (!localAnimationStartTime || !localAnimationEndTime) {
1725
+ return;
1726
+ }
1727
+ var mousePosition = clientX - xOffset;
1728
+ var startPos = timestampToPixel(localAnimationStartTime, centerTime, canvasWidth, secondsPerPx);
1729
+ var endPos = timestampToPixel(localAnimationEndTime, centerTime, canvasWidth, secondsPerPx);
1730
+ var mouseTimeUnix = pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx);
1731
+ var startTime = roundWithTimeStep(mouseTimeUnix, timeStep);
1732
+ var endTime = roundWithTimeStep(mouseTimeUnix, timeStep);
1733
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
1734
+ if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
1735
+ if (!isAnimationTimeModifiedSetRef.current) {
1736
+ isAnimationTimeModifiedSetRef.current = true;
1737
+ }
1738
+ }
1739
+ if (isDraggingStartAnimation) {
1740
+ if (isDraggingStartWithinBounds(endPos, mousePosition)) {
1741
+ return;
1742
+ }
1743
+ setLocalAnimationStartTime(roundWithTimeStep(mouseTimeUnix, timeStep));
1744
+ if (lastHandledRoundedTime !== startTime) {
1745
+ setLastHandledRoundedTime(startTime);
1746
+ setShowTooltip('animationStart');
1747
+ onStartTimeChange == null || onStartTimeChange(startTime);
1748
+ }
1749
+ } else if (isDraggingEndAnimation && pixelsBetweenOnLeft) {
1750
+ if (isDraggingEndWithinBounds(startPos, mousePosition, canvasWidth)) {
1751
+ return;
1752
+ }
1753
+ setLocalAnimationEndTime(roundWithTimeStep(mouseTimeUnix, timeStep));
1754
+ if (lastHandledRoundedTime !== endTime) {
1755
+ setLastHandledRoundedTime(endTime);
1756
+ setShowTooltip('animationEnd');
1757
+ onEndTimeChange == null || onEndTimeChange(endTime);
1758
+ }
1759
+ }
1760
+ if (isDraggingAnimationArea) {
1761
+ if (timeBetweenMouseAndStartAndEnd.current === undefined) {
1762
+ // to move the whole animation area we need to calculate the distance
1763
+ // between the mouse position and the start and end position
1764
+ var _timeFromMouseToStart = mouseTimeUnix - start;
1765
+ var _timeFromMouseToEnd = end - mouseTimeUnix;
1766
+ timeBetweenMouseAndStartAndEnd.current = {
1767
+ timeFromMouseToEnd: _timeFromMouseToEnd,
1768
+ timeFromMouseToStart: _timeFromMouseToStart
1769
+ };
1770
+ return;
1771
+ }
1772
+ pixelsMovedSinceStartDragging.current += x;
1773
+ var _timeBetweenMouseAndS = timeBetweenMouseAndStartAndEnd.current,
1774
+ timeFromMouseToEnd = _timeBetweenMouseAndS.timeFromMouseToEnd,
1775
+ timeFromMouseToStart = _timeBetweenMouseAndS.timeFromMouseToStart;
1776
+ var newStartTime = mouseTimeUnix - timeFromMouseToStart;
1777
+ var newEndTime = mouseTimeUnix + timeFromMouseToEnd;
1778
+ var roundedNewStartTime = roundWithTimeStep(newStartTime, timeStep);
1779
+ var roundedNewEndTime = roundWithTimeStep(newEndTime, timeStep);
1780
+ setLocalAnimationStartTime(roundedNewStartTime);
1781
+ setLocalAnimationEndTime(roundedNewEndTime);
1782
+ }
1783
+ }, [canvasWidth, centerTime, end, isDraggingAnimationArea, isDraggingEndAnimation, isDraggingStartAnimation, lastHandledRoundedTime, localAnimationEndTime, localAnimationStartTime, mapId, onEndTimeChange, onStartTimeChange, secondsPerPx, start, timeStep, xOffset]);
1784
+ useEffect(function () {
1785
+ var handleMouseUp = function handleMouseUp() {
1786
+ pixelsMovedSinceStartDragging.current = 0;
1787
+ timeBetweenMouseAndStartAndEnd.current = undefined;
1788
+ };
1789
+ document.addEventListener('mouseup', handleMouseUp);
1790
+ return function () {
1791
+ document.removeEventListener('mouseup', handleMouseUp);
1792
+ };
1793
+ }, []);
1794
+ useEffect(function () {
1795
+ var startTimestamp = convertStringTimeToUnix(reduxAnimationStartTime);
1796
+ var endTimestamp = convertStringTimeToUnix(reduxAnimationEndTime);
1797
+ setLocalAnimationStartTime(startTimestamp);
1798
+ setLocalAnimationEndTime(endTimestamp);
1799
+ }, [reduxAnimationStartTime, reduxAnimationEndTime, setLocalAnimationStartTime, setLocalAnimationEndTime]);
1800
+ useEffect(function () {
1801
+ var stoppedDragging = !isDraggingStartAnimation && !isDraggingEndAnimation && !isDraggingAnimationArea;
1802
+ if (stoppedDragging && isAnimationTimeModifiedSetRef.current) {
1803
+ if (start && start !== localAnimationStartTime) {
1804
+ onSetAnimationStartTime(dateUtils.fromUnix(start).toISOString());
1805
+ }
1806
+ if (end && end !== localAnimationEndTime) {
1807
+ onSetAnimationEndTime(dateUtils.fromUnix(end).toISOString());
1808
+ }
1809
+ isAnimationTimeModifiedSetRef.current = false;
1810
+ }
1811
+ }, [isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isAnimationTimeModifiedSetRef, localAnimationStartTime, localAnimationEndTime, onSetAnimationStartTime, onSetAnimationEndTime, start, end]);
1812
+ useEffect(function () {
1813
+ var handleMouseUp = function handleMouseUp() {
1814
+ if (isDraggingAnimationArea) {
1815
+ onStartTimeChange == null || onStartTimeChange(localAnimationStartTime);
1816
+ onEndTimeChange == null || onEndTimeChange(localAnimationEndTime);
1817
+ }
1818
+ setCursorStyle('auto');
1819
+ setIsDraggingSelectedTime(false);
1820
+ setIsDraggingStartAnimation == null || setIsDraggingStartAnimation(false);
1821
+ setIsDraggingEndAnimation == null || setIsDraggingEndAnimation(false);
1822
+ setIsDraggingLegend(false);
1823
+ setShowTooltip(undefined);
1824
+ setIsDraggingAnimationArea(false);
1825
+ startDraggingPosition.current = 0;
1826
+ if (isAnimationTimeModifiedSetRef.current) {
1827
+ isAnimationTimeModifiedSetRef.current = false;
1828
+ }
1829
+ };
1830
+ document.addEventListener('mouseup', handleMouseUp);
1831
+ return function () {
1832
+ document.removeEventListener('mouseup', handleMouseUp);
1833
+ };
1834
+ }, [setIsDraggingStartAnimation, setIsDraggingEndAnimation, localAnimationStartTime, localAnimationEndTime, onStartTimeChange, onEndTimeChange, isDraggingAnimationArea]);
1835
+ useEffect(function () {
1836
+ var handleMouseActions = function handleMouseActions(event) {
1837
+ if (event.movementX === 0) {
1838
+ return;
1839
+ }
1840
+ if (isDraggingLegend) {
1841
+ var dragDistanceTime = event.movementX * secondsPerPx;
1842
+ var newCenterTime = centerTime - dragDistanceTime;
1843
+ onSetCenterTime(newCenterTime);
1844
+ } else if (isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
1845
+ handleAnimationDragging(event.movementX, event.clientX);
1846
+ } else if (isDraggingSelectedTime) {
1847
+ moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
1848
+ }
1849
+ if (isMouseOverCanvas && isTimeSliderHoverOn) {
1850
+ moveSelectedTimePx(event.movementX, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
1851
+ }
1852
+ };
1853
+ var handleMouseMove = function handleMouseMove(event) {
1854
+ handleMouseActions(event);
1855
+ };
1856
+ document.addEventListener('mousemove', handleMouseMove);
1857
+ return function () {
1858
+ document.removeEventListener('mousemove', handleMouseMove);
1859
+ };
1860
+ }, [isDraggingLegend, isDraggingStartAnimation, isDraggingEndAnimation, isDraggingAnimationArea, isDraggingSelectedTime, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime, onSetCenterTime, isTimeSliderHoverOn, isMouseOverCanvas, handleAnimationDragging]);
1861
+ useEffect(function () {
1862
+ if (!showTooltip && pointerTime) {
1863
+ if (showPointerTimeTooltip) {
1864
+ setShowTooltip('mousePointer');
1865
+ } else {
1866
+ debouncedSetShowPointerTimeTooltip(true);
1867
+ }
1868
+ } else if (showTooltip === 'mousePointer' && !pointerTime) {
1869
+ setShowTooltip(undefined);
1870
+ debouncedSetShowPointerTimeTooltip(false);
1871
+ debouncedSetShowPointerTimeTooltip.flush();
1872
+ } else if (showTooltip !== 'mousePointer') {
1873
+ debouncedSetShowPointerTimeTooltip(false);
1874
+ debouncedSetShowPointerTimeTooltip.flush();
1875
+ }
1876
+ }, [debouncedSetShowPointerTimeTooltip, pointerTime, showPointerTimeTooltip, showTooltip]);
1877
+ var onMouseDown = function onMouseDown(x, y, width) {
1878
+ isClickOrDrag.current = 'click';
1879
+ startDraggingPosition.current = x;
1880
+ var _getPositions = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
1881
+ startAnimationPosition = _getPositions.startAnimationPosition,
1882
+ endAnimationPosition = _getPositions.endAnimationPosition,
1883
+ selectedTimePosition = _getPositions.selectedTimePosition;
1884
+ // start dragging selected time.
1885
+ if (isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH)) {
1886
+ setCursorStyle('grabbing');
1887
+ setIsDraggingSelectedTime(true);
1888
+ return;
1889
+ }
1890
+ if (reduxAnimationStartTime && reduxAnimationEndTime) {
1891
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
1892
+ tooltipPosition.current = pixelsBetweenOnLeft ? x + pixelsBetweenOnLeft : x;
1893
+ // start dragging either marker
1894
+ if (isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH)) {
1895
+ setCursorStyle('grabbing');
1896
+ setIsDraggingStartAnimation == null || setIsDraggingStartAnimation(true);
1897
+ setShowTooltip('animationStart');
1898
+ return;
1899
+ }
1900
+ if (isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH)) {
1901
+ setCursorStyle('grabbing');
1902
+ setIsDraggingEndAnimation == null || setIsDraggingEndAnimation(true);
1903
+ setShowTooltip('animationEnd');
1904
+ return;
1905
+ }
1906
+ if (isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition)) {
1907
+ setCursorStyle('grabbing');
1908
+ setIsDraggingAnimationArea(true);
1909
+ return;
1910
+ }
1911
+ }
1912
+ // clicking the timeslider
1913
+ setIsDraggingLegend(true);
1914
+ };
1915
+ var onMouseUp = function onMouseUp(x) {
1916
+ if (isClickOrDrag.current === 'click') {
1917
+ var unfilteredSelectedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
1918
+ moveSelectedTimePx(x - unfilteredSelectedTimePx, canvasWidth, centerTime, dataStartTime, dataEndTime, secondsPerPx, timeStep, unfilteredSelectedTime, setUnfilteredSelectedTime);
1919
+ }
1920
+ isClickOrDrag.current = undefined;
1921
+ };
1922
+ var onMouseMove = function onMouseMove(x, y, event, width) {
1923
+ var mousePosition = x;
1924
+ setPointerTime(pixelToTimestamp(mousePosition, centerTime, canvasWidth, secondsPerPx));
1925
+ var pixelsBetweenOnLeft = getPixelsBetweenViewportAndTimesliderOnLeft(mapId);
1926
+ tooltipPosition.current = pixelsBetweenOnLeft && mousePosition + pixelsBetweenOnLeft;
1927
+ if (isClickOrDrag.current === 'click') {
1928
+ isClickOrDrag.current = 'drag';
1929
+ }
1930
+ if (isDraggingSelectedTime || isDraggingStartAnimation || isDraggingEndAnimation || isDraggingAnimationArea) {
1931
+ return;
1932
+ }
1933
+ var _getPositions2 = getPositions(width, unfilteredSelectedTime, centerTime, secondsPerPx, start, end),
1934
+ startAnimationPosition = _getPositions2.startAnimationPosition,
1935
+ endAnimationPosition = _getPositions2.endAnimationPosition,
1936
+ selectedTimePosition = _getPositions2.selectedTimePosition;
1937
+ // Adjust mouse cursor while hovering draggable areas
1938
+ var leftAnimationIconArea = isLeftAnimationIconArea(x, startAnimationPosition, DRAG_AREA_WIDTH);
1939
+ var rightAnimationIconArea = isRightAnimationIconArea(x, endAnimationPosition, DRAG_AREA_WIDTH);
1940
+ var selectedTimeArea = isSelectedTimeIconArea(x, selectedTimePosition, DRAG_AREA_WIDTH);
1941
+ var insideAnimationArea = isInsideAnimationArea(x, startAnimationPosition, endAnimationPosition);
1942
+ var hoveringLegendHandles = leftAnimationIconArea || rightAnimationIconArea || selectedTimeArea || isDraggingLegend;
1943
+ if (hoveringLegendHandles) {
1944
+ setCursorStyle('ew-resize');
1945
+ } else if (insideAnimationArea && !isDraggingAnimationArea) {
1946
+ setCursorStyle('grab');
1947
+ } else if (insideAnimationArea && isDraggingAnimationArea) {
1948
+ setCursorStyle('grabbing');
1949
+ } else {
1950
+ setCursorStyle('auto');
1951
+ }
1952
+ };
1953
+ var onWheel = React.useCallback(function (_ref2) {
1954
+ var event = _ref2.event,
1955
+ deltaY = _ref2.deltaY;
1956
+ event.preventDefault();
1957
+ if (event.ctrlKey || event.metaKey) {
1958
+ debouncedAndThrottledUpdateTimeSpan(deltaY);
1959
+ }
1960
+ }, [debouncedAndThrottledUpdateTimeSpan]);
1961
+ var onWheelOverCanvas = React.useCallback(function (props) {
1962
+ onWheel(props);
1963
+ adjustSelectedTimeOnWheel(props);
1964
+ }, [adjustSelectedTimeOnWheel, onWheel]);
1965
+ React.useEffect(function () {
1966
+ if (isTimeScrollingEnabled && mapWindowRef != null && mapWindowRef.current) {
1967
+ var handleWheel = function handleWheel(event) {
1968
+ event.preventDefault();
1969
+ onWheel({
1970
+ event: event,
1971
+ deltaY: event.deltaY
1972
+ });
1973
+ };
1974
+ var element = mapWindowRef.current;
1975
+ element.addEventListener('wheel', handleWheel);
1976
+ return function () {
1977
+ element.removeEventListener('wheel', handleWheel);
1978
+ };
1979
+ }
1980
+ return undefined;
1981
+ }, [isTimeScrollingEnabled, mapWindowRef, onWheel]);
1982
+ return jsxs(Box, {
1983
+ sx: {
1984
+ position: 'relative',
1985
+ height: TIME_SLIDER_LEGEND_HEIGHT + "px"
1986
+ },
1987
+ children: [jsx(CustomTooltip, {
1988
+ open: Boolean(showTooltip),
1989
+ slotProps: {
1990
+ popper: {
1991
+ popperRef: popperRef,
1992
+ anchorEl: {
1993
+ getBoundingClientRect: setTooltipPosition
1994
+ }
1995
+ }
1996
+ },
1997
+ title: getTooltipText(),
1998
+ children: jsx(Box, {
1999
+ className: getTimeSliderLegendId(mapId),
2000
+ "data-testid": "timeSliderLegend",
2001
+ onMouseLeave: function onMouseLeave() {
2002
+ setPointerTime(undefined);
2003
+ },
2004
+ sx: {
2005
+ height: TIME_SLIDER_LEGEND_HEIGHT + "px",
2006
+ borderRadius: '4.5px',
2007
+ overflow: 'hidden',
2008
+ cursor: cursorStyle
2009
+ },
2010
+ children: jsx(CanvasComponent, {
2011
+ onMouseDown: onMouseDown,
2012
+ onMouseMove: onMouseMove,
2013
+ onMouseUp: onMouseUp,
2014
+ onRenderCanvas: function onRenderCanvas(ctx, width, height) {
2015
+ updateCanvasWidth(canvasWidth, width);
2016
+ drawTimeSliderLegend(ctx, theme, width, height, centerTime, secondsPerPx, timeSliderSpan, displayTime, currentTime, start, end, dataStartTime, dataEndTime);
2017
+ },
2018
+ onWheel: onWheelOverCanvas,
2019
+ ref: node
2020
+ })
2021
+ })
2022
+ }), !!isTimeSliderHoverOn && jsx(Box, {
2023
+ "data-testid": "customCanvasMouseOverContainer",
2024
+ onMouseLeave: function onMouseLeave() {
2025
+ return setIsMouseOverCanvas(false);
2026
+ },
2027
+ onMouseOver: function onMouseOver() {
2028
+ return setIsMouseOverCanvas(true);
2029
+ },
2030
+ sx: {
2031
+ position: 'absolute',
2032
+ top: '-40px',
2033
+ left: 0,
2034
+ right: 0,
2035
+ bottom: 0,
2036
+ height: TIME_SLIDER_LEGEND_HEIGHT + " + 40px",
2037
+ zIndex: isMouseOverCanvas ? 100 : 0
2038
+ }
2039
+ })]
2040
+ });
2041
+ };
2042
+
2043
+ var THROTTLE_WAIT_TIME = 300; // [ms]
2044
+ var THROTTLE_OPTIONS = {
2045
+ trailing: false // Invoke function when called, but not more than once every <THROTTLE_WAIT_TIME>.
2046
+ };
2047
+ var TimeSliderMenu = function TimeSliderMenu(_ref) {
2048
+ var marks = _ref.marks,
2049
+ value = _ref.value,
2050
+ allOptionsDisabled = _ref.allOptionsDisabled,
2051
+ isAutoDisabled = _ref.isAutoDisabled,
2052
+ handleAutoClick = _ref.handleAutoClick,
2053
+ isAutoSelected = _ref.isAutoSelected,
2054
+ title = _ref.title,
2055
+ icon = _ref.icon,
2056
+ _ref$onChangeSliderVa = _ref.onChangeSliderValue,
2057
+ onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
2058
+ displayCurrentLength = _ref.displayCurrentLength,
2059
+ _ref$disbleUserSetDur = _ref.disbleUserSetDuration,
2060
+ disbleUserSetDuration = _ref$disbleUserSetDur === void 0 ? true : _ref$disbleUserSetDur,
2061
+ customLengthSelector = _ref.customLengthSelector,
2062
+ _ref$setOpen = _ref.setOpen,
2063
+ setOpen = _ref$setOpen === void 0 ? function () {} : _ref$setOpen,
2064
+ _ref$customFieldHeade = _ref.customFieldHeader,
2065
+ customFieldHeader = _ref$customFieldHeade === void 0 ? 'timeslider-length' : _ref$customFieldHeade,
2066
+ open = _ref.open;
2067
+ var currentMarkIndex = marks.findIndex(function (mark) {
2068
+ return mark.value === value;
2069
+ });
2070
+ var currentMark = marks[currentMarkIndex];
2071
+ var _React$useState = React.useState(null),
2072
+ anchorRef = _React$useState[0],
2073
+ setAnchorRef = _React$useState[1];
2074
+ var _useTimesliderTransla = useTimesliderTranslation(),
2075
+ t = _useTimesliderTransla.t;
2076
+ var _useState = useState(false),
2077
+ displayLengthInputField = _useState[0],
2078
+ setDisplayLengthInputField = _useState[1];
2079
+ React.useEffect(function () {
2080
+ if (!open && displayLengthInputField) {
2081
+ setDisplayLengthInputField(false);
2082
+ }
2083
+ }, [displayLengthInputField, open]);
2084
+ var buttonText = function buttonText(value, displayCurrentLength, currentMark) {
2085
+ if (displayCurrentLength) {
2086
+ return minutesToDescribedDuration(value);
2087
+ }
2088
+ if (currentMark) {
2089
+ var parts = t(currentMark.label).split(' ');
2090
+ if (parts.length > 1) {
2091
+ return parts[0] + parts.slice(1).join(' ');
2092
+ }
2093
+ return parts.join('');
2094
+ }
2095
+ return '';
2096
+ };
2097
+ // eslint-disable-next-line react-hooks/exhaustive-deps
2098
+ var throttledScroll = React.useCallback(throttle(function (newValue) {
2099
+ onChangeSliderValue(newValue);
2100
+ }, THROTTLE_WAIT_TIME, THROTTLE_OPTIONS), []);
2101
+ var onWheel = React.useCallback(function (event) {
2102
+ var direction = event.deltaY < 0 ? 1 : -1;
2103
+ var newValue = marks[Math.min(Math.max(currentMarkIndex - direction, 0), marks.length - 1)];
2104
+ throttledScroll(newValue.value);
2105
+ }, [currentMarkIndex, marks, throttledScroll]);
2106
+ return jsxs(Box, {
2107
+ onKeyDown: function onKeyDown(event) {
2108
+ event.stopPropagation();
2109
+ },
2110
+ children: [jsxs(CustomIconButton, {
2111
+ isSelected: true,
2112
+ onClick: function onClick() {
2113
+ setOpen(true);
2114
+ },
2115
+ onWheel: onWheel,
2116
+ ref: setAnchorRef,
2117
+ sx: {
2118
+ padding: '0px',
2119
+ paddingRight: '12px',
2120
+ width: '100%!important',
2121
+ minWidth: '64px',
2122
+ justifyContent: 'space-between'
2123
+ },
2124
+ tooltipTitle: title,
2125
+ variant: "tool",
2126
+ children: [icon, jsx(Typography, {
2127
+ sx: {
2128
+ fontSize: 12,
2129
+ fontWeight: 400,
2130
+ textTransform: 'none'
2131
+ },
2132
+ children: buttonText(value, displayCurrentLength, currentMark)
2133
+ })]
2134
+ }), !!anchorRef && jsxs(Menu, {
2135
+ anchorEl: anchorRef,
2136
+ anchorOrigin: {
2137
+ vertical: -15,
2138
+ horizontal: 'center'
2139
+ },
2140
+ onClose: function onClose() {
2141
+ return setOpen(false);
2142
+ },
2143
+ open: open,
2144
+ slotProps: {
2145
+ backdrop: {
2146
+ sx: {
2147
+ backgroundColor: 'transparent'
2148
+ }
2149
+ }
2150
+ },
2151
+ transformOrigin: {
2152
+ vertical: 'bottom',
2153
+ horizontal: 'center'
2154
+ },
2155
+ children: [jsx(MenuItem, {
2156
+ disabled: true,
2157
+ sx: {
2158
+ fontSize: '12px',
2159
+ opacity: 0.67,
2160
+ padding: '0px 12px',
2161
+ '&.MuiMenuItem-root': {
2162
+ minHeight: '30px!important',
2163
+ minWidth: 150
2164
+ }
2165
+ },
2166
+ children: title
2167
+ }), marks.map(function (mark) {
2168
+ var isSelected = (currentMark == null ? void 0 : currentMark.value) === mark.value && !isAutoSelected;
2169
+ return jsx(MenuItem, {
2170
+ disabled: allOptionsDisabled,
2171
+ onClick: function onClick() {
2172
+ if (!isSelected) {
2173
+ onChangeSliderValue(mark.value);
2174
+ }
2175
+ setOpen(false);
2176
+ },
2177
+ selected: !!isSelected && !displayLengthInputField,
2178
+ children: mark.label || mark.text
2179
+ }, mark.value);
2180
+ }), !!handleAutoClick && jsx(MenuItem, {
2181
+ disabled: allOptionsDisabled || isAutoDisabled,
2182
+ onClick: function onClick() {
2183
+ handleAutoClick();
2184
+ setOpen(false);
2185
+ },
2186
+ selected: isAutoSelected,
2187
+ children: t('timeslider-auto')
2188
+ }), !!displayCurrentLength && jsxs(MenuItem, {
2189
+ disabled: disbleUserSetDuration,
2190
+ onClick: function onClick() {
2191
+ return setDisplayLengthInputField(true);
2192
+ },
2193
+ sx: {
2194
+ maxWidth: '175px'
2195
+ },
2196
+ children: [!!displayLengthInputField && customLengthSelector, !displayLengthInputField && jsxs(Box, {
2197
+ sx: {
2198
+ flexDirection: 'column',
2199
+ display: 'flex',
2200
+ flexGrow: 1
2201
+ },
2202
+ children: [jsx(CardHeader, {
2203
+ slotProps: {
2204
+ title: {
2205
+ sx: {
2206
+ fontSize: 12
2207
+ }
2208
+ }
2209
+ },
2210
+ sx: {
2211
+ height: 2,
2212
+ padding: 0,
2213
+ color: 'geowebColors.greys.accessible'
2214
+ },
2215
+ title: t(customFieldHeader)
2216
+ }), jsxs(Box, {
2217
+ sx: {
2218
+ flexDirection: 'row',
2219
+ display: 'flex',
2220
+ justifyContent: 'space-between',
2221
+ flexGrow: 1,
2222
+ paddingTop: 0.5
2223
+ },
2224
+ children: [jsx(Typography, {
2225
+ sx: {
2226
+ fontSize: 14,
2227
+ textTransform: 'none',
2228
+ lineHeight: 2
2229
+ },
2230
+ children: minutesToDescribedDuration(value)
2231
+ }), jsx(CustomTooltip, {
2232
+ title: t('timeslider-edit'),
2233
+ children: jsx("span", {
2234
+ children: jsx(CustomIconButton, {
2235
+ "aria-label": "edit animation option",
2236
+ "data-testid": "editAnimationOption",
2237
+ children: jsx(Edit, {})
2238
+ })
2239
+ })
2240
+ })]
2241
+ })]
2242
+ })]
2243
+ })]
2244
+ })]
2245
+ });
2246
+ };
2247
+
2248
+ var marks$2 = [{
2249
+ value: AnimationLength.Minutes15,
2250
+ text: 'timeslider-min',
2251
+ count: 15
2252
+ }, {
2253
+ value: AnimationLength.Minutes30,
2254
+ text: 'timeslider-min',
2255
+ count: 30
2256
+ }, {
2257
+ value: AnimationLength.Hours1,
2258
+ text: 'timeslider-hour',
2259
+ count: 1
2260
+ }, {
2261
+ value: AnimationLength.Hours2,
2262
+ text: 'timeslider-hour',
2263
+ count: 2
2264
+ }, {
2265
+ value: AnimationLength.Hours3,
2266
+ text: 'timeslider-hour',
2267
+ count: 3
2268
+ }, {
2269
+ value: AnimationLength.Hours6,
2270
+ text: 'timeslider-hour',
2271
+ count: 6
2272
+ }, {
2273
+ value: AnimationLength.Hours12,
2274
+ text: 'timeslider-hour',
2275
+ count: 12
2276
+ }, {
2277
+ value: AnimationLength.Hours24,
2278
+ text: 'timeslider-hour',
2279
+ count: 24
2280
+ }].sort(function (ta, tb) {
2281
+ return tb.value - ta.value;
2282
+ });
2283
+ var AnimationLengthButton = function AnimationLengthButton(_ref) {
2284
+ var _ref$disabled = _ref.disabled,
2285
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
2286
+ _ref$animationLength = _ref.animationLength,
2287
+ animationLength = _ref$animationLength === void 0 ? AnimationLength.Hours1 : _ref$animationLength,
2288
+ _ref$isAuto = _ref.isAuto,
2289
+ isAuto = _ref$isAuto === void 0 ? false : _ref$isAuto,
2290
+ layerHasTimeStep = _ref.layerHasTimeStep,
2291
+ onChangeAnimationLength = _ref.onChangeAnimationLength,
2292
+ toggleAnimationLengthAuto = _ref.toggleAnimationLengthAuto;
2293
+ var _useTimesliderTransla = useTimesliderTranslation(),
2294
+ t = _useTimesliderTransla.t;
2295
+ var translatedMarks = marks$2.map(function (mark) {
2296
+ return Object.assign({}, mark, {
2297
+ label: mark.count + " " + t(mark.text)
2298
+ });
2299
+ });
2300
+ var onChangeSliderValue = function onChangeSliderValue(newSliderValue) {
2301
+ var newLength = newSliderValue ? Math.round(newSliderValue) : 0;
2302
+ onChangeAnimationLength == null || onChangeAnimationLength(newLength);
2303
+ };
2304
+ var _useState = useState(false),
2305
+ open = _useState[0],
2306
+ setOpen = _useState[1];
2307
+ return jsx(TimeSliderMenu, {
2308
+ allOptionsDisabled: disabled,
2309
+ displayCurrentLength: true,
2310
+ handleAutoClick: toggleAnimationLengthAuto,
2311
+ icon: jsx(Animation, {
2312
+ "data-testid": "animationLengthButton"
2313
+ }),
2314
+ isAutoDisabled: !layerHasTimeStep,
2315
+ isAutoSelected: isAuto,
2316
+ marks: translatedMarks,
2317
+ onChangeSliderValue: onChangeSliderValue,
2318
+ open: open,
2319
+ setOpen: setOpen,
2320
+ title: t('timeslider-animation'),
2321
+ value: animationLength
2322
+ });
2323
+ };
2324
+
2325
+ var AutoUpdateButton = function AutoUpdateButton(_ref) {
2326
+ var _ref$toggleAutoUpdate = _ref.toggleAutoUpdate,
2327
+ toggleAutoUpdate = _ref$toggleAutoUpdate === void 0 ? function () {} : _ref$toggleAutoUpdate,
2328
+ _ref$isAutoUpdating = _ref.isAutoUpdating,
2329
+ isAutoUpdating = _ref$isAutoUpdating === void 0 ? false : _ref$isAutoUpdating,
2330
+ _ref$disabled = _ref.disabled,
2331
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
2332
+ var _useTimesliderTransla = useTimesliderTranslation(),
2333
+ t = _useTimesliderTransla.t;
2334
+ return jsx(CustomIconButton, {
2335
+ "data-testid": "autoUpdateButton",
2336
+ disabled: disabled,
2337
+ isSelected: isAutoUpdating,
2338
+ onClick: function onClick() {
2339
+ return toggleAutoUpdate();
2340
+ },
2341
+ tooltipTitle: isAutoUpdating ? t('timeslider-auto-update-on') : t('timeslider-auto-update-off'),
2342
+ variant: "tool",
2343
+ children: isAutoUpdating ? jsx(AutoUpdateActive, {
2344
+ "data-testid": "auto-update-svg-on"
2345
+ }) : jsx(AutoUpdateInActive, {
2346
+ "data-testid": "auto-update-svg-off"
2347
+ })
2348
+ });
2349
+ };
2350
+
2351
+ var _BackwardForwardStepButton = function BackwardForwardStepButton(_ref) {
2352
+ var isForwardStep = _ref.isForwardStep,
2353
+ isDisabled = _ref.isDisabled,
2354
+ _ref$onClickBFButton = _ref.onClickBFButton,
2355
+ onClickBFButton = _ref$onClickBFButton === void 0 ? function () {} : _ref$onClickBFButton;
2356
+ // Added renderCounter for testing and performance purposes
2357
+ renderCounter.count(_BackwardForwardStepButton.name);
2358
+ var _useTimesliderTransla = useTimesliderTranslation(),
2359
+ t = _useTimesliderTransla.t;
2360
+ return jsx(CustomIconButton, {
2361
+ "aria-label": isForwardStep ? 'forward' : 'backward',
2362
+ "data-testid": isForwardStep ? 'stepForwardButton' : 'stepBackwardButton',
2363
+ disabled: isDisabled,
2364
+ onClick: onClickBFButton,
2365
+ tooltipTitle: isForwardStep ? t('timeslider-forward') : t('timeslider-backward'),
2366
+ variant: "tool",
2367
+ children: isForwardStep ? jsx(StepForward, {
2368
+ "data-testid": "step-forward-svg-path"
2369
+ }) : jsx(StepBackward, {
2370
+ "data-testid": "step-backward-svg-path"
2371
+ })
2372
+ });
2373
+ };
2374
+
2375
+ var NowButton = function NowButton(_ref) {
2376
+ var _ref$onSetNow = _ref.onSetNow,
2377
+ onSetNow = _ref$onSetNow === void 0 ? function () {} : _ref$onSetNow,
2378
+ _ref$disabled = _ref.disabled,
2379
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled;
2380
+ var _useTimesliderTransla = useTimesliderTranslation(),
2381
+ t = _useTimesliderTransla.t;
2382
+ return jsx(CustomIconButton, {
2383
+ "aria-label": "now",
2384
+ "data-testid": "nowButtonTooltip",
2385
+ disabled: disabled,
2386
+ onClick: function onClick() {
2387
+ return onSetNow();
2388
+ },
2389
+ tooltipTitle: t('timeslider-now'),
2390
+ variant: "tool",
2391
+ children: jsx(Now, {
2392
+ "data-testid": "now-svg"
2393
+ })
2394
+ });
2395
+ };
2396
+
2397
+ var PlayButton = function PlayButton(_ref) {
2398
+ var isAnimating = _ref.isAnimating,
2399
+ isDisabled = _ref.isDisabled,
2400
+ _ref$onTogglePlayButt = _ref.onTogglePlayButton,
2401
+ onTogglePlayButton = _ref$onTogglePlayButt === void 0 ? function () {} : _ref$onTogglePlayButt;
2402
+ var onTogglePlay = function onTogglePlay() {
2403
+ onTogglePlayButton();
2404
+ };
2405
+ var _useTimesliderTransla = useTimesliderTranslation(),
2406
+ t = _useTimesliderTransla.t;
2407
+ return jsx(CustomIconButton, {
2408
+ "data-testid": "playButton",
2409
+ disabled: isDisabled,
2410
+ isSelected: isAnimating,
2411
+ onClick: onTogglePlay,
2412
+ tooltipTitle: isAnimating ? t('timeslider-pause') : t('timeslider-play'),
2413
+ variant: "tool",
2414
+ children: isAnimating ? jsx(Pause, {
2415
+ "data-testid": "pause-svg-path"
2416
+ }) : jsx(Play, {
2417
+ "data-testid": "play-svg-path"
2418
+ })
2419
+ });
2420
+ };
2421
+
2422
+ var ControlButtons = function ControlButtons(_ref) {
2423
+ var backwardBtn = _ref.backwardBtn,
2424
+ forwardBtn = _ref.forwardBtn,
2425
+ playBtn = _ref.playBtn,
2426
+ nowBtn = _ref.nowBtn,
2427
+ autoUpdateBtn = _ref.autoUpdateBtn;
2428
+ return jsxs(Fragment, {
2429
+ children: [jsx(Grid, {
2430
+ children: backwardBtn || jsx(_BackwardForwardStepButton, {
2431
+ isForwardStep: false
2432
+ })
2433
+ }), jsx(Grid, {
2434
+ children: forwardBtn || jsx(_BackwardForwardStepButton, {
2435
+ isForwardStep: true
2436
+ })
2437
+ }), jsx(Grid, {
2438
+ children: playBtn || jsx(PlayButton, {})
2439
+ }), jsx(Grid, {
2440
+ children: nowBtn || jsx(NowButton, {})
2441
+ }), jsx(Grid, {
2442
+ children: autoUpdateBtn || jsx(AutoUpdateButton, {})
2443
+ })]
2444
+ });
2445
+ };
2446
+
2447
+ var SpeedButton = function SpeedButton(_ref) {
2448
+ var animationDelay = _ref.animationDelay,
2449
+ setMapAnimationDelay = _ref.setMapAnimationDelay;
2450
+ var sorted = [].concat(speedFactors).sort(function (sa, sb) {
2451
+ return sb - sa;
2452
+ });
2453
+ var marks = sorted.map(function (speedFactor) {
2454
+ return {
2455
+ value: getSpeedDelay(speedFactor),
2456
+ text: "x" + speedFactor,
2457
+ label: "x" + speedFactor
2458
+ };
2459
+ });
2460
+ var _useTimesliderTransla = useTimesliderTranslation(),
2461
+ t = _useTimesliderTransla.t;
2462
+ var _useState = useState(false),
2463
+ open = _useState[0],
2464
+ setOpen = _useState[1];
2465
+ return jsx(TimeSliderMenu, {
2466
+ icon: jsx(Speed, {}),
2467
+ marks: marks,
2468
+ onChangeSliderValue: function onChangeSliderValue(markValue) {
2469
+ setMapAnimationDelay(markValue);
2470
+ },
2471
+ open: open,
2472
+ setOpen: setOpen,
2473
+ title: t('timeslider-speed'),
2474
+ value: animationDelay
2475
+ });
2476
+ };
2477
+
2478
+ var TimeSpanButtonCustomSelect = function TimeSpanButtonCustomSelect(_ref) {
2479
+ var timeSliderSpan = _ref.timeSliderSpan,
2480
+ setOpen = _ref.setOpen,
2481
+ onChangeSliderValue = _ref.onChangeSliderValue;
2482
+ var _useTimesliderTransla = useTimesliderTranslation(),
2483
+ t = _useTimesliderTransla.t;
2484
+ var _React$useState = React.useState(timeSliderSpan / getLargestTimeUnit(timeSliderSpan)),
2485
+ selectedTimeValue = _React$useState[0],
2486
+ setSelectedTimeValue = _React$useState[1];
2487
+ var _React$useState2 = React.useState(getLargestTimeUnit(timeSliderSpan).toString()),
2488
+ selectedTimeResolution = _React$useState2[0],
2489
+ setSelectedTimeResolution = _React$useState2[1];
2490
+ var _React$useState3 = React.useState(true),
2491
+ isANumber = _React$useState3[0],
2492
+ setIsANumber = _React$useState3[1];
2493
+ return jsx(Box, {
2494
+ children: jsxs(FormControl, {
2495
+ onKeyDown: function onKeyDown(event) {
2496
+ event.stopPropagation();
2497
+ },
2498
+ size: "small",
2499
+ sx: {
2500
+ flexDirection: 'row',
2501
+ display: 'flex'
2502
+ },
2503
+ variant: "standard",
2504
+ children: [jsx(TextField, {
2505
+ autoFocus: true,
2506
+ color: isANumber ? 'primary' : 'warning',
2507
+ label: t('timeslider-span'),
2508
+ onBlur: function onBlur() {
2509
+ onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
2510
+ },
2511
+ onChange: function onChange(e) {
2512
+ if (!isNaN(+e.target.value)) {
2513
+ setIsANumber(true);
2514
+ setSelectedTimeValue(Number(e.target.value));
2515
+ } else {
2516
+ setIsANumber(false);
2517
+ }
2518
+ },
2519
+ onKeyDown: function onKeyDown(e) {
2520
+ if (e.key === 'Enter' || e.key === 'Escape') {
2521
+ onChangeSliderValue(selectedTimeValue * Number(selectedTimeResolution));
2522
+ setOpen(false);
2523
+ }
2524
+ },
2525
+ size: "small",
2526
+ slotProps: {
2527
+ htmlInput: {
2528
+ maxLength: 4,
2529
+ 'aria-label': 'custom-input'
2530
+ }
2531
+ },
2532
+ value: Math.round(selectedTimeValue * 100) / 100,
2533
+ variant: "standard"
2534
+ }), jsx(Box, {
2535
+ sx: {
2536
+ alignContent: 'end'
2537
+ },
2538
+ children: jsxs(Select, {
2539
+ "aria-label": "time-resolution-selector",
2540
+ defaultValue: "h",
2541
+ onChange: function onChange(e) {
2542
+ setSelectedTimeResolution(e.target.value);
2543
+ onChangeSliderValue(selectedTimeValue * Number(e.target.value));
2544
+ setOpen(false);
2545
+ },
2546
+ size: "small",
2547
+ tabIndex: -1,
2548
+ value: selectedTimeResolution,
2549
+ children: [jsx(MenuItem, {
2550
+ value: TimeInMinutes.YEAR,
2551
+ children: t('years')
2552
+ }), jsx(MenuItem, {
2553
+ value: TimeInMinutes.MONTH,
2554
+ children: t('months')
2555
+ }), jsx(MenuItem, {
2556
+ value: TimeInMinutes.WEEK,
2557
+ children: t('weeks')
2558
+ }), jsx(MenuItem, {
2559
+ value: TimeInMinutes.DAY,
2560
+ children: t('days')
2561
+ }), jsx(MenuItem, {
2562
+ value: TimeInMinutes.HOUR,
2563
+ children: t('hours')
2564
+ }), jsx(MenuItem, {
2565
+ value: TimeInMinutes.MINUTE,
2566
+ children: t('minutes')
2567
+ })]
2568
+ })
2569
+ })]
2570
+ })
2571
+ });
2572
+ };
2573
+
2574
+ var marks$1 = [{
2575
+ value: 60,
2576
+ text: 'timeslider-hour',
2577
+ count: 1
2578
+ }, {
2579
+ value: 3 * 60,
2580
+ text: 'timeslider-hour',
2581
+ count: 3
2582
+ }, {
2583
+ value: 6 * 60,
2584
+ text: 'timeslider-hour',
2585
+ count: 6
2586
+ }, {
2587
+ value: 12 * 60,
2588
+ text: 'timeslider-hour',
2589
+ count: 12
2590
+ }, {
2591
+ value: 24 * 60,
2592
+ text: 'timeslider-hour',
2593
+ count: 24
2594
+ }, {
2595
+ value: 2 * 24 * 60,
2596
+ text: 'timeslider-hour',
2597
+ count: 48
2598
+ }, {
2599
+ value: 7 * 24 * 60,
2600
+ text: 'timeslider-week',
2601
+ count: 1
2602
+ }, {
2603
+ value: 2 * 7 * 24 * 60,
2604
+ text: 'timeslider-weeks',
2605
+ count: 2
2606
+ }, {
2607
+ value: 30 * 24 * 60,
2608
+ text: 'timeslider-month',
2609
+ count: 1
2610
+ }, {
2611
+ value: 3 * 30 * 24 * 60,
2612
+ text: 'timeslider-months',
2613
+ count: 3
2614
+ }, {
2615
+ value: 365 * 24 * 60,
2616
+ text: 'timeslider-year',
2617
+ count: 1
2618
+ }].sort(function (ta, tb) {
2619
+ return tb.value - ta.value;
2620
+ });
2621
+ var TimeSpanButton = function TimeSpanButton(_ref) {
2622
+ var _ref$timeSliderSpan = _ref.timeSliderSpan,
2623
+ timeSliderSpan = _ref$timeSliderSpan === void 0 ? defaultTimeSpan : _ref$timeSliderSpan,
2624
+ _ref$disabled = _ref.disabled,
2625
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
2626
+ _ref$onChangeSliderVa = _ref.onChangeSliderValue,
2627
+ onChangeSliderValue = _ref$onChangeSliderVa === void 0 ? function () {} : _ref$onChangeSliderVa,
2628
+ onToggleTimeSpan = _ref.onToggleTimeSpan,
2629
+ isTimeSpanAuto = _ref.isTimeSpanAuto,
2630
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
2631
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
2632
+ _ref$layerHasTimeStep = _ref.layerHasTimeStep,
2633
+ layerHasTimeStep = _ref$layerHasTimeStep === void 0 ? false : _ref$layerHasTimeStep;
2634
+ var _useTimesliderTransla = useTimesliderTranslation(),
2635
+ t = _useTimesliderTransla.t;
2636
+ var translatedMarks = marks$1.map(function (mark) {
2637
+ return Object.assign({}, mark, {
2638
+ label: mark.count + " " + t(mark.text)
2639
+ });
2640
+ });
2641
+ var _useState = useState(isOpenByDefault),
2642
+ open = _useState[0],
2643
+ setOpen = _useState[1];
2644
+ return jsx(TimeSliderMenu, {
2645
+ allOptionsDisabled: disabled,
2646
+ customFieldHeader: t('timeslider-span'),
2647
+ customLengthSelector: jsx(TimeSpanButtonCustomSelect, {
2648
+ onChangeSliderValue: onChangeSliderValue,
2649
+ setOpen: setOpen,
2650
+ timeSliderSpan: timeSliderSpan
2651
+ }),
2652
+ disbleUserSetDuration: false,
2653
+ displayCurrentLength: true,
2654
+ handleAutoClick: onToggleTimeSpan,
2655
+ icon: jsx(Clock, {}),
2656
+ isAutoDisabled: !layerHasTimeStep,
2657
+ isAutoSelected: isTimeSpanAuto,
2658
+ marks: translatedMarks,
2659
+ onChangeSliderValue: onChangeSliderValue,
2660
+ open: open,
2661
+ setOpen: setOpen,
2662
+ title: t('timeslider-time-span'),
2663
+ value: timeSliderSpan
2664
+ });
2665
+ };
2666
+
2667
+ /* *
2668
+ * Licensed under the Apache License, Version 2.0 (the "License");
2669
+ * you may not use this file except in compliance with the License.
2670
+ * You may obtain a copy of the License at
2671
+ *
2672
+ * http://www.apache.org/licenses/LICENSE-2.0
2673
+ *
2674
+ * Unless required by applicable law or agreed to in writing, software
2675
+ * distributed under the License is distributed on an "AS IS" BASIS,
2676
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2677
+ * See the License for the specific language governing permissions and
2678
+ * limitations under the License.
2679
+ *
2680
+ * Copyright 2026 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
2681
+ * Copyright 2026 - Finnish Meteorological Institute (FMI)
2682
+ * Copyright 2026 - The Norwegian Meteorological Institute (MET Norway)
2683
+ * */
2684
+ var isMac = function isMac() {
2685
+ return window.navigator.userAgent.includes(' Mac ');
2686
+ };
2687
+ var hasShortcutModifier = function hasShortcutModifier(event) {
2688
+ return isMac() ? event.ctrlKey && event.shiftKey : event.ctrlKey;
2689
+ };
2690
+ var getTimeStepShortcutDirection = function getTimeStepShortcutDirection(event) {
2691
+ if (!hasShortcutModifier(event)) {
2692
+ return null;
2693
+ }
2694
+ if (event.key === 'ArrowUp') {
2695
+ return 'up';
2696
+ }
2697
+ if (event.key === 'ArrowDown') {
2698
+ return 'down';
2699
+ }
2700
+ return null;
2701
+ };
2702
+ var TimeStepShortcutContext = /*#__PURE__*/React.createContext(null);
2703
+ // Listens for the time-step keyboard shortcut on document (capture phase, so it
2704
+ // runs before any element-level handlers that may stopPropagation). Ignores
2705
+ // presses while focus is in a text input.
2706
+ var useTimeStepShortcutListener = function useTimeStepShortcutListener(enabled, onShortcut) {
2707
+ var onShortcutRef = React.useRef(onShortcut);
2708
+ React.useEffect(function () {
2709
+ onShortcutRef.current = onShortcut;
2710
+ });
2711
+ React.useEffect(function () {
2712
+ if (!enabled) {
2713
+ return undefined;
2714
+ }
2715
+ var handleKeyDown = function handleKeyDown(event) {
2716
+ var target = event.target;
2717
+ if ((target == null ? void 0 : target.tagName) === 'INPUT' || (target == null ? void 0 : target.tagName) === 'TEXTAREA' || target != null && target.isContentEditable) {
2718
+ return;
2719
+ }
2720
+ var direction = getTimeStepShortcutDirection(event);
2721
+ if (!direction) {
2722
+ return;
2723
+ }
2724
+ event.preventDefault();
2725
+ onShortcutRef.current(direction);
2726
+ };
2727
+ document.addEventListener('keydown', handleKeyDown, {
2728
+ capture: true
2729
+ });
2730
+ return function () {
2731
+ document.removeEventListener('keydown', handleKeyDown, {
2732
+ capture: true
2733
+ });
2734
+ };
2735
+ }, [enabled]);
2736
+ };
2737
+
2738
+ var marks = [{
2739
+ value: 1,
2740
+ text: 'timeslider-min',
2741
+ count: 1
2742
+ }, {
2743
+ value: 2,
2744
+ text: 'timeslider-min',
2745
+ count: 2
2746
+ }, {
2747
+ value: 2.5,
2748
+ text: 'timeslider-min',
2749
+ count: 2.5
2750
+ }, {
2751
+ value: 5,
2752
+ text: 'timeslider-min',
2753
+ count: 5
2754
+ }, {
2755
+ value: 10,
2756
+ text: 'timeslider-min',
2757
+ count: 10
2758
+ }, {
2759
+ value: 15,
2760
+ text: 'timeslider-min',
2761
+ count: 15
2762
+ }, {
2763
+ value: 30,
2764
+ text: 'timeslider-min',
2765
+ count: 30
2766
+ }, {
2767
+ value: 60,
2768
+ text: 'timeslider-hour',
2769
+ count: 1
2770
+ }, {
2771
+ value: 120,
2772
+ text: 'timeslider-hour',
2773
+ count: 2
2774
+ }, {
2775
+ value: 180,
2776
+ text: 'timeslider-hour',
2777
+ count: 3
2778
+ }, {
2779
+ value: 360,
2780
+ text: 'timeslider-hour',
2781
+ count: 6
2782
+ }, {
2783
+ value: 720,
2784
+ text: 'timeslider-hour',
2785
+ count: 12
2786
+ }, {
2787
+ value: 1440,
2788
+ text: 'timeslider-hour',
2789
+ count: 24
2790
+ }, {
2791
+ value: 2880,
2792
+ text: 'timeslider-hour',
2793
+ count: 48
2794
+ }, {
2795
+ value: 4320,
2796
+ text: 'timeslider-hour',
2797
+ count: 72
2798
+ }, {
2799
+ value: 10080,
2800
+ text: 'timeslider-week',
2801
+ count: 1
2802
+ }, {
2803
+ value: 20160,
2804
+ text: 'timeslider-weeks',
2805
+ count: 2
2806
+ }, {
2807
+ value: 43200,
2808
+ text: 'timeslider-month',
2809
+ count: 1
2810
+ }, {
2811
+ value: 87600,
2812
+ text: 'timeslider-months',
2813
+ count: 2
2814
+ }, {
2815
+ value: 262800,
2816
+ text: 'timeslider-months',
2817
+ count: 6
2818
+ }, {
2819
+ value: 525600,
2820
+ text: 'timeslider-year',
2821
+ count: 1
2822
+ }, {
2823
+ value: 5256000,
2824
+ text: 'timeslider-years',
2825
+ count: 10
2826
+ }].sort(function (ta, tb) {
2827
+ return tb.value - ta.value;
2828
+ });
2829
+ var _TimeStepButton = function TimeStepButton(_ref) {
2830
+ var _ref$timeStep = _ref.timeStep,
2831
+ timeStep = _ref$timeStep === void 0 ? marks[0].value : _ref$timeStep,
2832
+ _ref$disabled = _ref.disabled,
2833
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
2834
+ _ref$isTimestepAuto = _ref.isTimestepAuto,
2835
+ isTimestepAuto = _ref$isTimestepAuto === void 0 ? false : _ref$isTimestepAuto,
2836
+ onChangeTimeStep = _ref.onChangeTimeStep,
2837
+ _ref$onToggleTimestep = _ref.onToggleTimestepAuto,
2838
+ onToggleTimestepAuto = _ref$onToggleTimestep === void 0 ? function () {} : _ref$onToggleTimestep,
2839
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
2840
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
2841
+ timeStepFromLayer = _ref.timeStepFromLayer;
2842
+ var _useTimesliderTransla = useTimesliderTranslation(),
2843
+ t = _useTimesliderTransla.t;
2844
+ var translatedMarks = marks.map(function (mark) {
2845
+ return Object.assign({}, mark, {
2846
+ label: mark.count + " " + t(mark.text)
2847
+ });
2848
+ });
2849
+ var onMenuItemClick = useCallback(function (markValue) {
2850
+ if (isTimestepAuto) {
2851
+ onToggleTimestepAuto();
2852
+ }
2853
+ onChangeTimeStep(markValue);
2854
+ }, [isTimestepAuto, onToggleTimestepAuto, onChangeTimeStep]);
2855
+ var handleToggleTimeStep = function handleToggleTimeStep() {
2856
+ if (isTimestepAuto) {
2857
+ return;
2858
+ }
2859
+ onToggleTimestepAuto();
2860
+ timeStepFromLayer && onChangeTimeStep(timeStepFromLayer);
2861
+ };
2862
+ var layerHasTimeStep = Boolean(timeStepFromLayer);
2863
+ renderCounter.count(_TimeStepButton.name);
2864
+ var _useState = useState(isOpenByDefault),
2865
+ open = _useState[0],
2866
+ setOpen = _useState[1];
2867
+ var stepToAdjacentMark = useCallback(function (direction) {
2868
+ var _marks$nextIndex;
2869
+ var currentIndex = marks.findIndex(function (mark) {
2870
+ return mark.value === timeStep;
2871
+ });
2872
+ if (currentIndex === -1) {
2873
+ return;
2874
+ }
2875
+ var indexDelta = direction === 'up' ? -1 : 1;
2876
+ var nextIndex = Math.min(Math.max(currentIndex + indexDelta, 0), marks.length - 1);
2877
+ var nextValue = (_marks$nextIndex = marks[nextIndex]) == null ? void 0 : _marks$nextIndex.value;
2878
+ if (nextValue !== undefined && nextValue !== timeStep) {
2879
+ onMenuItemClick(nextValue);
2880
+ }
2881
+ }, [timeStep, onMenuItemClick]);
2882
+ var shortcutContext = useContext(TimeStepShortcutContext);
2883
+ useEffect(function () {
2884
+ if (!(shortcutContext != null && shortcutContext.pendingDirection)) {
2885
+ return;
2886
+ }
2887
+ setOpen(true);
2888
+ stepToAdjacentMark(shortcutContext.pendingDirection);
2889
+ shortcutContext.consume();
2890
+ }, [shortcutContext, stepToAdjacentMark]);
2891
+ return jsx(TimeSliderMenu, {
2892
+ allOptionsDisabled: disabled,
2893
+ displayCurrentLength: true,
2894
+ handleAutoClick: handleToggleTimeStep,
2895
+ icon: jsx(FastForward, {
2896
+ "data-testid": "timeStepButton"
2897
+ }),
2898
+ isAutoDisabled: !layerHasTimeStep,
2899
+ isAutoSelected: isTimestepAuto,
2900
+ marks: translatedMarks,
2901
+ onChangeSliderValue: onMenuItemClick,
2902
+ open: open,
2903
+ setOpen: setOpen,
2904
+ title: t('timeslider-time-step'),
2905
+ value: timeStep || translatedMarks[0].value
2906
+ });
2907
+ };
2908
+
2909
+ var OptionsMenu = function OptionsMenu(_ref) {
2910
+ var speedBtn = _ref.speedBtn,
2911
+ timeSpanBtn = _ref.timeSpanBtn,
2912
+ timeStepBtn = _ref.timeStepBtn,
2913
+ animationLengthBtn = _ref.animationLengthBtn;
2914
+ return jsxs(Fragment, {
2915
+ children: [jsx(Grid, {
2916
+ size: {
2917
+ xs: 'auto'
2918
+ },
2919
+ children: timeSpanBtn || jsx(TimeSpanButton, {
2920
+ disabled: false,
2921
+ isTimeSpanAuto: false,
2922
+ layerHasTimeStep: false,
2923
+ onChangeSliderValue: function onChangeSliderValue() {},
2924
+ onToggleTimeSpan: function onToggleTimeSpan() {},
2925
+ timeSliderSpan: 0
2926
+ })
2927
+ }), jsx(Grid, {
2928
+ size: {
2929
+ xs: 'auto'
2930
+ },
2931
+ children: animationLengthBtn || jsx(AnimationLengthButton, {
2932
+ onChangeAnimationLength: function onChangeAnimationLength() {},
2933
+ toggleAnimationLengthAuto: function toggleAnimationLengthAuto() {}
2934
+ })
2935
+ }), jsx(Grid, {
2936
+ size: {
2937
+ xs: 'auto'
2938
+ },
2939
+ children: timeStepBtn || jsx(_TimeStepButton, {
2940
+ isTimestepAuto: false,
2941
+ onChangeTimeStep: function onChangeTimeStep() {}
2942
+ })
2943
+ }), jsx(Grid, {
2944
+ size: {
2945
+ xs: 'auto'
2946
+ },
2947
+ children: speedBtn || jsx(SpeedButton, {
2948
+ animationDelay: defaultAnimationDelayAtStart,
2949
+ setMapAnimationDelay: function setMapAnimationDelay() {}
2950
+ })
2951
+ })]
2952
+ });
2953
+ };
2954
+
2955
+ var OptionsMenuButton = function OptionsMenuButton(_ref) {
2956
+ var speedBtn = _ref.speedBtn,
2957
+ timeStepBtn = _ref.timeStepBtn,
2958
+ timeSpanBtn = _ref.timeSpanBtn,
2959
+ animationLengthBtn = _ref.animationLengthBtn,
2960
+ _ref$isOpenByDefault = _ref.isOpenByDefault,
2961
+ isOpenByDefault = _ref$isOpenByDefault === void 0 ? false : _ref$isOpenByDefault,
2962
+ _ref$enableKeyboardSh = _ref.enableKeyboardShortcut,
2963
+ enableKeyboardShortcut = _ref$enableKeyboardSh === void 0 ? false : _ref$enableKeyboardSh;
2964
+ var _useState = useState(null),
2965
+ anchorEl = _useState[0],
2966
+ setAnchorEl = _useState[1];
2967
+ var _useState2 = useState(false),
2968
+ open = _useState2[0],
2969
+ setOpen = _useState2[1];
2970
+ var _useState3 = useState(null),
2971
+ pendingDirection = _useState3[0],
2972
+ setPendingDirection = _useState3[1];
2973
+ var _useTimesliderTransla = useTimesliderTranslation(),
2974
+ t = _useTimesliderTransla.t;
2975
+ useEffect(function () {
2976
+ if (anchorEl && isOpenByDefault) {
2977
+ setOpen(true);
2978
+ }
2979
+ }, [anchorEl, isOpenByDefault]);
2980
+ useTimeStepShortcutListener(enableKeyboardShortcut, function (direction) {
2981
+ setOpen(true);
2982
+ setPendingDirection(direction);
2983
+ });
2984
+ var shortcutContextValue = useMemo(function () {
2985
+ return {
2986
+ pendingDirection: pendingDirection,
2987
+ consume: function consume() {
2988
+ return setPendingDirection(null);
2989
+ }
2990
+ };
2991
+ }, [pendingDirection]);
2992
+ return jsxs("div", {
2993
+ children: [jsx(CustomIconButton, {
2994
+ "aria-label": "animation options",
2995
+ "data-testid": "optionsMenuButton",
2996
+ isSelected: open,
2997
+ onClick: function onClick() {
2998
+ setOpen(!open);
2999
+ },
3000
+ ref: function ref(_ref2) {
3001
+ setAnchorEl(_ref2);
3002
+ },
3003
+ tooltipProps: {
3004
+ title: t('timeslider-animation-options'),
3005
+ placement: 'bottom'
3006
+ },
3007
+ variant: "tool",
3008
+ children: jsx(Options, {})
3009
+ }), jsx(Popper, {
3010
+ anchorEl: anchorEl,
3011
+ "data-testid": "optionsMenuPopOver",
3012
+ open: open,
3013
+ placement: "top-start",
3014
+ sx: {
3015
+ zIndex: 10
3016
+ },
3017
+ children: jsx(Paper, {
3018
+ elevation: 3,
3019
+ sx: {
3020
+ position: 'relative',
3021
+ top: '-2rem'
3022
+ },
3023
+ children: jsx(Grid, {
3024
+ container: true,
3025
+ spacing: 1,
3026
+ sx: {
3027
+ padding: '10px'
3028
+ },
3029
+ children: jsx(TimeStepShortcutContext.Provider, {
3030
+ value: shortcutContextValue,
3031
+ children: jsx(OptionsMenu, {
3032
+ animationLengthBtn: animationLengthBtn,
3033
+ speedBtn: speedBtn,
3034
+ timeSpanBtn: timeSpanBtn,
3035
+ timeStepBtn: timeStepBtn
3036
+ })
3037
+ })
3038
+ })
3039
+ })
3040
+ })]
3041
+ });
3042
+ };
3043
+
3044
+ var TimeSliderButtons = function TimeSliderButtons(_ref) {
3045
+ var optionsMenuBtn = _ref.optionsMenuBtn,
3046
+ playBtn = _ref.playBtn,
3047
+ backwardBtn = _ref.backwardBtn,
3048
+ forwardBtn = _ref.forwardBtn,
3049
+ nowBtn = _ref.nowBtn,
3050
+ autoUpdateBtn = _ref.autoUpdateBtn;
3051
+ return jsx(Box, {
3052
+ "data-testid": "timeSliderButtons",
3053
+ sx: {
3054
+ height: 24
3055
+ },
3056
+ children: jsxs(Grid, {
3057
+ container: true,
3058
+ spacing: 0.5,
3059
+ sx: {
3060
+ alignItems: 'center',
3061
+ justifyContent: 'center'
3062
+ },
3063
+ children: [jsx(Grid, {
3064
+ children: optionsMenuBtn || jsx(OptionsMenuButton, {})
3065
+ }), jsx(ControlButtons, {
3066
+ autoUpdateBtn: autoUpdateBtn,
3067
+ backwardBtn: backwardBtn,
3068
+ forwardBtn: forwardBtn,
3069
+ nowBtn: nowBtn,
3070
+ playBtn: playBtn
3071
+ })]
3072
+ })
3073
+ });
3074
+ };
3075
+
3076
+ /* *
3077
+ * Licensed under the Apache License, Version 2.0 (the "License");
3078
+ * you may not use this file except in compliance with the License.
3079
+ * You may obtain a copy of the License at
3080
+ *
3081
+ * http://www.apache.org/licenses/LICENSE-2.0
3082
+ *
3083
+ * Unless required by applicable law or agreed to in writing, software
3084
+ * distributed under the License is distributed on an "AS IS" BASIS,
3085
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3086
+ * See the License for the specific language governing permissions and
3087
+ * limitations under the License.
3088
+ *
3089
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3090
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
3091
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
3092
+ * */
3093
+ var onMouseMove = function onMouseMove(x, width, selectedTime, centerTime, secondsPerPx, mouseDownInTimeBox, isTimeBoxArea, setCursorStyle) {
3094
+ if (!selectedTime || mouseDownInTimeBox) {
3095
+ return;
3096
+ }
3097
+ var selectedTimePx = timestampToPixel(selectedTime, centerTime, width, secondsPerPx);
3098
+ if (isTimeBoxArea(x, selectedTimePx)) {
3099
+ setCursorStyle('grab');
3100
+ } else {
3101
+ setCursorStyle('auto');
3102
+ }
3103
+ };
3104
+ var onMouseDown = function onMouseDown(x, width, selectedTime, centerTime, secondsPerPx, isTimeBoxArea, setCursorStyle, setMouseDownInTimeBox) {
3105
+ if (!selectedTime) {
3106
+ return;
3107
+ }
3108
+ var selectedTimePx = timestampToPixel(selectedTime, centerTime, width, secondsPerPx);
3109
+ if (isTimeBoxArea(x, selectedTimePx)) {
3110
+ setCursorStyle('grabbing');
3111
+ }
3112
+ setMouseDownInTimeBox(true);
3113
+ };
3114
+
3115
+ /* *
3116
+ * Licensed under the Apache License, Version 2.0 (the "License");
3117
+ * you may not use this file except in compliance with the License.
3118
+ * You may obtain a copy of the License at
3119
+ *
3120
+ * http://www.apache.org/licenses/LICENSE-2.0
3121
+ *
3122
+ * Unless required by applicable law or agreed to in writing, software
3123
+ * distributed under the License is distributed on an "AS IS" BASIS,
3124
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3125
+ * See the License for the specific language governing permissions and
3126
+ * limitations under the License.
3127
+ *
3128
+ * Copyright 2022 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
3129
+ * Copyright 2022 - Finnish Meteorological Institute (FMI)
3130
+ * Copyright 2024 - The Norwegian Meteorological Institute (MET Norway)
3131
+ * */
3132
+ var secondsInYear = 365 * 24 * 3600;
3133
+ var drawRoundedRectangle = function drawRoundedRectangle(ctx, x, y, width, height, cornerRadius, theme) {
3134
+ ctx.save();
3135
+ ctx.translate(x, y);
3136
+ var playerTimeMarkers = theme.palette.geowebColors.timeSlider.playerTimeMarkers;
3137
+ ctx.beginPath();
3138
+ ctx.strokeStyle = playerTimeMarkers.fill;
3139
+ ctx.fillStyle = playerTimeMarkers.fill;
3140
+ ctx.lineWidth = timeBoxGeom.lineWidth;
3141
+ var halfLineWidth = timeBoxGeom.lineWidth / 2;
3142
+ // Top left corner
3143
+ ctx.moveTo(halfLineWidth, height / 2);
3144
+ ctx.arcTo(halfLineWidth, halfLineWidth, width / 2, halfLineWidth, cornerRadius);
3145
+ // Top right corner
3146
+ ctx.arcTo(width - halfLineWidth, halfLineWidth, width - halfLineWidth, height / 2, cornerRadius);
3147
+ // Bottom right corner
3148
+ ctx.arcTo(width - halfLineWidth, height - halfLineWidth, width / 2, height - halfLineWidth, cornerRadius);
3149
+ // Bottom left corner
3150
+ ctx.arcTo(halfLineWidth, height - halfLineWidth, halfLineWidth, height / 2, cornerRadius);
3151
+ ctx.lineTo(halfLineWidth, height / 2);
3152
+ ctx.fill();
3153
+ ctx.stroke();
3154
+ ctx.restore();
3155
+ };
3156
+ var drawAutoUpdateIcon = function drawAutoUpdateIcon(ctx, x, y, theme, isAutoUpdating) {
3157
+ ctx.save();
3158
+ ctx.translate(x, y);
3159
+ var playerTimeText = theme.palette.geowebColors.timeSlider.playerTimeText;
3160
+ ctx.fillStyle = isAutoUpdating ? '#7BACFF' : '#B4B4B4';
3161
+ var path = new Path2D('M12.385 3.295l5 3-5 3V7.723l-.085.014c-3.08.548-5.418 3.24-5.418 6.479 0 3.634 2.945 6.58 6.577 6.58 2.914 0 5.385-1.896 6.248-4.523l2.815-1.626c-.225 4.814-4.197 8.648-9.063 8.648-5.012 0-9.074-4.065-9.074-9.08 0-4.65 3.495-8.484 8-9.015V3.295z');
3162
+ ctx.translate(7, -8);
3163
+ ctx.rotate(13.295);
3164
+ ctx.fill(path);
3165
+ ctx.restore();
3166
+ var text = 'Auto';
3167
+ ctx.save();
3168
+ ctx.translate(x, y);
3169
+ ctx.fillStyle = isAutoUpdating ? '#7BACFF' : '#B4B4B4'; // ON
3170
+ ctx.font = "7px " + playerTimeText.fontFamily;
3171
+ ctx.fillText(text, 5, 14);
3172
+ ctx.restore();
3173
+ };
3174
+ var drawTextAnnotation = function drawTextAnnotation(ctx, x, y, text, theme) {
3175
+ var playerTimeText = theme.palette.geowebColors.timeSlider.playerTimeText;
3176
+ ctx.save();
3177
+ ctx.translate(x, y);
3178
+ ctx.fillStyle = playerTimeText.color;
3179
+ ctx.font = playerTimeText.fontSize + "px " + playerTimeText.fontFamily;
3180
+ var textMetrics = ctx.measureText(text);
3181
+ var actualTextWidth = textMetrics.actualBoundingBoxRight - textMetrics.actualBoundingBoxLeft;
3182
+ var actualTextHeight = ctx.measureText('O').width;
3183
+ ctx.fillText(text, -actualTextWidth / 2, actualTextHeight / 2);
3184
+ ctx.restore();
3185
+ };
3186
+ var drawNewCurrentTimeBox = function drawNewCurrentTimeBox(ctx, selectedTime, selectedPx, span, theme, isAutoUpdating) {
3187
+ var smallWidth = timeBoxGeom.smallWidth,
3188
+ largeWidth = timeBoxGeom.largeWidth,
3189
+ height = timeBoxGeom.height,
3190
+ iconWidth = timeBoxGeom.iconWidth,
3191
+ calendarWidth = timeBoxGeom.calendarWidth;
3192
+ var boxWidth = span >= secondsInYear ? largeWidth : smallWidth;
3193
+ var needleX = selectedPx - boxWidth / 2;
3194
+ var needleY = timeBoxGeom.lineWidth;
3195
+ drawRoundedRectangle(ctx, needleX - iconWidth / 2 - calendarWidth / 2, needleY, boxWidth + iconWidth + calendarWidth, height, timeBoxGeom.cornerRadius, theme);
3196
+ var timeFormat = span >= secondsInYear ? "y " + dateUtils.DATE_FORMAT_NAME_OF_DAY_MONTH : dateUtils.DATE_FORMAT_NAME_OF_DAY_MONTH;
3197
+ var timeText = dateUtils.dateToString(dateUtils.fromUnix(selectedTime), timeFormat) || '';
3198
+ drawTextAnnotation(ctx, needleX + boxWidth / 2 - iconWidth / 2 + calendarWidth / 2, needleY + height / 2, timeText, theme);
3199
+ drawAutoUpdateIcon(ctx, needleX + boxWidth + calendarWidth - iconWidth / 2 - calendarWidth / 2, needleY, theme, isAutoUpdating);
3200
+ };
3201
+ var renderTimeSliderCurrentTimeBox = function renderTimeSliderCurrentTimeBox(ctx, theme, width, height, centerTime, selected, secondsPerPx, span, isAutoUpdating) {
3202
+ // map unix timestamps to pixel values
3203
+ var _map = [selected].map(function (t) {
3204
+ return timestampToPixel(t, centerTime, width, secondsPerPx);
3205
+ }),
3206
+ selectedPx = _map[0];
3207
+ ctx.clearRect(0, 0, width, height);
3208
+ drawNewCurrentTimeBox(ctx, selected, selectedPx, span, theme, isAutoUpdating);
3209
+ };
3210
+
3211
+ var _excluded = ["day", "today", "outsideCurrentMonth"];
3212
+ var getTimezoneOffsetS = function getTimezoneOffsetS(value) {
3213
+ return value.getTimezoneOffset() * 60;
3214
+ };
3215
+ var toLocalTime = function toLocalTime(dateTime) {
3216
+ return dateUtils.fromUnix(dateTime + getTimezoneOffsetS(dateUtils.fromUnix(dateTime)));
3217
+ };
3218
+ var toUTCTime = function toUTCTime(dateTime) {
3219
+ return dateUtils.unix(dateTime) - getTimezoneOffsetS(dateTime);
3220
+ };
3221
+ var OpenPicker = function OpenPicker() {
3222
+ return jsx(CalendarToday, {});
3223
+ };
3224
+ var enabledAndSelectedButtonStyle = {
3225
+ borderWidth: '6px',
3226
+ borderBottomStyle: 'solid',
3227
+ borderRadius: 0,
3228
+ borderColor: 'rgb(170, 210, 240)',
3229
+ backgroundColor: 'rgba(170, 210, 240, 0.3)'
3230
+ };
3231
+ var enabledButUnSelectedButtonStyle = Object.assign({}, enabledAndSelectedButtonStyle, {
3232
+ backgroundColor: 'transparent'
3233
+ });
3234
+ var disabledButtonStyle = Object.assign({}, enabledAndSelectedButtonStyle, {
3235
+ borderColor: 'transparent',
3236
+ backgroundColor: 'transparent'
3237
+ });
3238
+ var AvailableDayByTimeRange = function AvailableDayByTimeRange(props, isDisabledStyle) {
3239
+ var day = props.day,
3240
+ today = props.today,
3241
+ outsideCurrentMonth = props.outsideCurrentMonth,
3242
+ other = _objectWithoutPropertiesLoose(props, _excluded);
3243
+ var _React$useState = React.useState({}),
3244
+ calendarDayStyle = _React$useState[0],
3245
+ setCalendarDayStyle = _React$useState[1];
3246
+ React.useEffect(function () {
3247
+ if (outsideCurrentMonth || isDisabledStyle) {
3248
+ setCalendarDayStyle(disabledButtonStyle);
3249
+ } else if (today) {
3250
+ setCalendarDayStyle(enabledAndSelectedButtonStyle);
3251
+ } else {
3252
+ setCalendarDayStyle(enabledButUnSelectedButtonStyle);
3253
+ }
3254
+ }, [day, today, outsideCurrentMonth, isDisabledStyle]);
3255
+ return /*#__PURE__*/createElement(PickerDay, Object.assign({}, other, {
3256
+ day: day,
3257
+ disableHighlightToday: true,
3258
+ key: day.toString(),
3259
+ outsideCurrentMonth: outsideCurrentMonth,
3260
+ sx: Object.assign({}, calendarDayStyle)
3261
+ }));
3262
+ };
3263
+ var MarkerTimeSelector = function MarkerTimeSelector(_ref) {
3264
+ var value = _ref.value,
3265
+ _ref$format = _ref.format,
3266
+ format = _ref$format === void 0 ? dateUtils.DATE_FORMAT_DATEPICKER : _ref$format,
3267
+ dataStartTime = _ref.dataStartTime,
3268
+ dataEndTime = _ref.dataEndTime,
3269
+ _ref$onSelect = _ref.onSelect,
3270
+ onSelect = _ref$onSelect === void 0 ? function () {} : _ref$onSelect,
3271
+ _ref$onCancel = _ref.onCancel,
3272
+ onCancel = _ref$onCancel === void 0 ? function () {} : _ref$onCancel;
3273
+ var _useTimesliderTransla = useTimesliderTranslation(),
3274
+ t = _useTimesliderTransla.t;
3275
+ var _React$useState2 = React.useState(value ? toLocalTime(value) : null),
3276
+ localTimeValue = _React$useState2[0],
3277
+ setLocalTimeValue = _React$useState2[1];
3278
+ var _React$useState3 = React.useState(!dataStartTime || !dataEndTime || dataStartTime > dataEndTime),
3279
+ isUndefinedDateRange = _React$useState3[0],
3280
+ setIsUndefinedDateRange = _React$useState3[1];
3281
+ var isDateRangeDisabled = React.useCallback(function (date) {
3282
+ if (dataStartTime === undefined || dataEndTime === undefined || dataStartTime > dataEndTime) {
3283
+ return true;
3284
+ }
3285
+ var startOfFirstDay = dateUtils.fromUnix(dataStartTime);
3286
+ startOfFirstDay.setHours(0, 0, 0);
3287
+ var endOfLastDay = dateUtils.fromUnix(dataEndTime);
3288
+ var day = dateUtils.unix(date);
3289
+ return day < dateUtils.unix(startOfFirstDay) || day > dateUtils.unix(endOfLastDay);
3290
+ }, [dataStartTime, dataEndTime]);
3291
+ var _React$useState4 = React.useState(isDateRangeDisabled(localTimeValue)),
3292
+ isDisabledRange = _React$useState4[0],
3293
+ setIsDisabledRange = _React$useState4[1];
3294
+ var handleSelect = function handleSelect() {
3295
+ if (localTimeValue) {
3296
+ onSelect(toUTCTime(localTimeValue));
3297
+ }
3298
+ };
3299
+ var handleKeyDown = function handleKeyDown(event) {
3300
+ if (event.key === 'Enter') {
3301
+ handleSelect();
3302
+ } else if (event.key === 'Escape') {
3303
+ onCancel();
3304
+ }
3305
+ };
3306
+ var isDisabledDateWithSomeAvailableData = function isDisabledDateWithSomeAvailableData() {
3307
+ return isUndefinedDateRange ? false : isDisabledRange;
3308
+ };
3309
+ var handleDateChange = function handleDateChange(value) {
3310
+ if (value instanceof Date || value === null || isDisabledDateWithSomeAvailableData()) {
3311
+ setLocalTimeValue(value);
3312
+ }
3313
+ };
3314
+ var AvailableDay = function AvailableDay(props) {
3315
+ return AvailableDayByTimeRange(props, isDateRangeDisabled(props.day));
3316
+ };
3317
+ React.useEffect(function () {
3318
+ setIsUndefinedDateRange(!dataStartTime || !dataEndTime || dataStartTime > dataEndTime);
3319
+ setIsDisabledRange(isDateRangeDisabled(localTimeValue));
3320
+ }, [dataStartTime, dataEndTime, localTimeValue, isDateRangeDisabled]);
3321
+ return jsx(Paper, {
3322
+ sx: {
3323
+ borderRadius: '0px',
3324
+ width: '240px'
3325
+ },
3326
+ children: jsxs(Stack, {
3327
+ "data-testid": "markerTimeSelector",
3328
+ children: [jsx(Paper, {
3329
+ sx: {
3330
+ height: '24px',
3331
+ align: 'center',
3332
+ display: 'flex',
3333
+ justifyContent: 'center',
3334
+ alignItems: 'center',
3335
+ borderRadius: '0px'
3336
+ },
3337
+ children: jsx(Paper, {
3338
+ sx: {
3339
+ variant: 'subtitle',
3340
+ textAlign: 'center',
3341
+ display: 'flex',
3342
+ justifyContent: 'center',
3343
+ alignItems: 'center',
3344
+ font: {
3345
+ fontWeight: 'medium',
3346
+ fontFamily: 'Roboto',
3347
+ fontSize: '12px'
3348
+ },
3349
+ borderRadius: '0px',
3350
+ boxShadow: 'none'
3351
+ },
3352
+ children: t('timeslider-marker')
3353
+ })
3354
+ }), jsx(LocalizationProvider, {
3355
+ dateAdapter: AdapterDateFns,
3356
+ children: jsx(DateTimePicker, {
3357
+ ampm: false,
3358
+ autoFocus: true,
3359
+ closeOnSelect: false,
3360
+ desktopModeMediaQuery: "@media (min-width: 720px)",
3361
+ disableIgnoringDatePartForTimeValidation: true,
3362
+ format: format,
3363
+ label: t('timeslider-marker-label'),
3364
+ maxDateTime: isUndefinedDateRange ? undefined : toLocalTime(dataEndTime),
3365
+ minDateTime: isUndefinedDateRange ? undefined : toLocalTime(dataStartTime),
3366
+ onChange: handleDateChange,
3367
+ onClose: handleSelect,
3368
+ shouldDisableDate: isDisabledDateWithSomeAvailableData,
3369
+ slotProps: {
3370
+ textField: {
3371
+ variant: 'filled',
3372
+ endAdornment: jsx(InputAdornment, {
3373
+ position: "end",
3374
+ sx: {
3375
+ paddingTop: '16px'
3376
+ },
3377
+ children: "UTC"
3378
+ })
3379
+ },
3380
+ field: {
3381
+ onKeyDownCapture: handleKeyDown,
3382
+ openPickerButtonPosition: 'start'
3383
+ },
3384
+ openPickerButton: {
3385
+ size: 'small',
3386
+ sx: {
3387
+ padding: 0
3388
+ }
3389
+ }
3390
+ },
3391
+ slots: {
3392
+ openPickerIcon: OpenPicker,
3393
+ day: AvailableDay
3394
+ },
3395
+ sx: {
3396
+ marginTop: '8px',
3397
+ marginBottom: '8px',
3398
+ marginLeft: '8px',
3399
+ marginRight: '8px',
3400
+ borderRadius: '0px'
3401
+ },
3402
+ timeSteps: {
3403
+ minutes: 1
3404
+ },
3405
+ value: localTimeValue
3406
+ })
3407
+ })]
3408
+ })
3409
+ });
3410
+ };
3411
+
3412
+ var style = {
3413
+ '&.MuiToggleButton-root': {
3414
+ color: '#B4B4B4',
3415
+ '&:hover': {
3416
+ color: '#F8F9F9 !important',
3417
+ backgroundColor: 'rgba(255,255,225, 0.3)'
3418
+ },
3419
+ '&.Mui-selected': {
3420
+ color: '#7BACFF !important',
3421
+ '&:hover': {
3422
+ backgroundColor: 'rgba(255,255,225, 0.3)'
3423
+ }
3424
+ }
3425
+ },
3426
+ width: '26px',
3427
+ height: '24px!important'
3428
+ };
3429
+ var CalendarButton = function CalendarButton(_ref) {
3430
+ var calendarIconPx = _ref.calendarIconPx,
3431
+ dataStartTime = _ref.dataStartTime,
3432
+ dataEndTime = _ref.dataEndTime,
3433
+ selectedTime = _ref.selectedTime,
3434
+ _ref$onSelect = _ref.onSelect,
3435
+ _onSelect = _ref$onSelect === void 0 ? function () {} : _ref$onSelect;
3436
+ var _React$useState = React.useState(null),
3437
+ anchorEl = _React$useState[0],
3438
+ setAnchorEl = _React$useState[1];
3439
+ var _React$useState2 = React.useState(false),
3440
+ open = _React$useState2[0],
3441
+ setOpen = _React$useState2[1];
3442
+ var _useTimesliderTransla = useTimesliderTranslation(),
3443
+ t = _useTimesliderTransla.t;
3444
+ return jsx(ClickAwayListener, {
3445
+ mouseEvent: "onMouseDown",
3446
+ onClickAway: function onClickAway() {
3447
+ return setOpen(false);
3448
+ },
3449
+ children: jsxs("div", {
3450
+ style: {
3451
+ position: 'absolute',
3452
+ top: '-2px',
3453
+ left: calendarIconPx + "px"
3454
+ },
3455
+ children: [jsx(CustomTooltip, {
3456
+ slotProps: {
3457
+ transition: {
3458
+ exit: false
3459
+ }
3460
+ },
3461
+ title: !open && t('timeslider-marker-placement'),
3462
+ children: jsx(CustomToggleButton, {
3463
+ onClick: function onClick() {
3464
+ return setOpen(!open);
3465
+ },
3466
+ ref: function ref(_ref2) {
3467
+ setAnchorEl(_ref2);
3468
+ },
3469
+ selected: open,
3470
+ sx: style,
3471
+ variant: "flat",
3472
+ children: jsx(CalendarToday, {
3473
+ style: {
3474
+ marginRight: '0px'
3475
+ }
3476
+ })
3477
+ })
3478
+ }), jsx(Popper, {
3479
+ anchorEl: anchorEl,
3480
+ "data-testid": "dateTimePickerPopOver",
3481
+ open: open,
3482
+ placement: "top-start",
3483
+ sx: {
3484
+ zIndex: 10
3485
+ },
3486
+ children: jsx(MarkerTimeSelector, {
3487
+ dataEndTime: dataEndTime,
3488
+ dataStartTime: dataStartTime,
3489
+ onCancel: function onCancel() {
3490
+ return setOpen(false);
3491
+ },
3492
+ onSelect: function onSelect(newTime) {
3493
+ setOpen(false);
3494
+ _onSelect(newTime);
3495
+ },
3496
+ value: selectedTime
3497
+ })
3498
+ })]
3499
+ })
3500
+ });
3501
+ };
3502
+
3503
+ var getTimeBoxWidth = function getTimeBoxWidth(span) {
3504
+ var smallWidth = timeBoxGeom.smallWidth,
3505
+ largeWidth = timeBoxGeom.largeWidth,
3506
+ iconWidth = timeBoxGeom.iconWidth,
3507
+ calendarWidth = timeBoxGeom.calendarWidth;
3508
+ var mainWidth = span >= secondsInYear ? largeWidth : smallWidth;
3509
+ return mainWidth + iconWidth + calendarWidth;
3510
+ };
3511
+ var CALENDAR_ICON_LEFT_SPACING = 1;
3512
+ var DEFAULT_PX_TO_MOVE_TIMESLIDER_CENTER = 25; // When the timeslider centertime is reaching the end of the canvas, move the timeslider center a bit
3513
+ var TimeSliderCurrentTimeBox = function TimeSliderCurrentTimeBox(_ref) {
3514
+ var centerTime = _ref.centerTime,
3515
+ _ref$secondsPerPx = _ref.secondsPerPx,
3516
+ secondsPerPx = _ref$secondsPerPx === void 0 ? 50 : _ref$secondsPerPx,
3517
+ _ref$span = _ref.span,
3518
+ span = _ref$span === void 0 ? defaultTimeSpan : _ref$span;
3519
+ _ref.timeStep;
3520
+ var dataStartTime = _ref.dataStartTime,
3521
+ dataEndTime = _ref.dataEndTime,
3522
+ unfilteredSelectedTime = _ref.unfilteredSelectedTime,
3523
+ linkedMapAnimationInfo = _ref.linkedMapAnimationInfo,
3524
+ isAutoUpdating = _ref.isAutoUpdating,
3525
+ setUnfilteredSelectedTime = _ref.setUnfilteredSelectedTime,
3526
+ onCalendarSelect = _ref.onCalendarSelect,
3527
+ onSetCenterTime = _ref.onSetCenterTime;
3528
+ var timeBoxWidth = getTimeBoxWidth(span);
3529
+ var theme = useTheme();
3530
+ var _useCanvasTarget = useCanvasTarget('mousedown'),
3531
+ node = _useCanvasTarget[1];
3532
+ var _React$useState = React.useState('auto'),
3533
+ cursorStyle = _React$useState[0],
3534
+ setCursorStyle = _React$useState[1];
3535
+ var _React$useState2 = React.useState(false),
3536
+ mouseDownInTimeBox = _React$useState2[0],
3537
+ setMouseDownInTimeBox = _React$useState2[1];
3538
+ var _React$useState3 = React.useState(0),
3539
+ canvasWidth = _React$useState3[0],
3540
+ setCanvasWidth = _React$useState3[1];
3541
+ var isAnimating = linkedMapAnimationInfo == null ? void 0 : linkedMapAnimationInfo.isAnimating;
3542
+ // Move TimeBox back to view if it goes out of bounds
3543
+ useEffect(function () {
3544
+ if (!(onSetCenterTime && canvasWidth && !mouseDownInTimeBox)) {
3545
+ return;
3546
+ }
3547
+ var receivedTimePx = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
3548
+ var moveWidth = isAnimating ? DEFAULT_PX_TO_MOVE_TIMESLIDER_CENTER : getAutoMoveAreaWidth(getFundamentalScale(secondsPerPx));
3549
+ if (moveWidth > canvasWidth / 2 || canvasWidth < 100) {
3550
+ // don't move if the moveWidth is larger than half the canvaswidth or canvaswidth is very small
3551
+ return;
3552
+ }
3553
+ if (receivedTimePx < moveWidth) {
3554
+ onSetCenterTime(pixelToTimestamp(canvasWidth / 2 - (moveWidth - receivedTimePx), centerTime, canvasWidth, secondsPerPx));
3555
+ } else if (receivedTimePx > canvasWidth - moveWidth) {
3556
+ onSetCenterTime(pixelToTimestamp(canvasWidth / 2 + (receivedTimePx - (canvasWidth - moveWidth)), centerTime, canvasWidth, secondsPerPx));
3557
+ }
3558
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3559
+ }, [unfilteredSelectedTime, isAnimating]);
3560
+ var isTimeBoxArea = function isTimeBoxArea(x, selectedTimePx) {
3561
+ return x > selectedTimePx - timeBoxWidth / 2 && x < selectedTimePx + timeBoxWidth / 2;
3562
+ };
3563
+ var mouseDownX = useRef(0);
3564
+ var unfilteredSelectedTimePxAtMouseDown = useRef(0);
3565
+ React.useEffect(function () {
3566
+ var handleMouseUp = function handleMouseUp() {
3567
+ mouseDownInTimeBox ? setCursorStyle('grab') : setCursorStyle('auto');
3568
+ setMouseDownInTimeBox(false);
3569
+ };
3570
+ var handleMouseDown = function handleMouseDown(event) {
3571
+ mouseDownX.current = event.clientX;
3572
+ unfilteredSelectedTimePxAtMouseDown.current = timestampToPixel(unfilteredSelectedTime, centerTime, canvasWidth, secondsPerPx);
3573
+ };
3574
+ var handleMouseMove = function handleMouseMove(event) {
3575
+ if (mouseDownInTimeBox) {
3576
+ if (mouseDownX.current) {
3577
+ var pixelsMoved = event.clientX - mouseDownX.current;
3578
+ var clickedUnfilteredSelectedTimePx = unfilteredSelectedTimePxAtMouseDown.current + pixelsMoved;
3579
+ var newUnfilteredSelectedTime = pixelToTimestamp(clickedUnfilteredSelectedTimePx, centerTime, canvasWidth, secondsPerPx);
3580
+ setUnfilteredSelectedTime(newUnfilteredSelectedTime);
3581
+ }
3582
+ }
3583
+ };
3584
+ document.addEventListener('mouseup', handleMouseUp);
3585
+ document.addEventListener('mousemove', handleMouseMove);
3586
+ document.addEventListener('mousedown', handleMouseDown);
3587
+ return function () {
3588
+ document.removeEventListener('mousemove', handleMouseMove);
3589
+ document.removeEventListener('mousedown', handleMouseDown);
3590
+ document.removeEventListener('mouseup', handleMouseUp);
3591
+ };
3592
+ }, [canvasWidth, centerTime, mouseDownInTimeBox, secondsPerPx, setUnfilteredSelectedTime, unfilteredSelectedTime]);
3593
+ // Display unfilteredSelectedTime (already snapped to available timestep)
3594
+ var displayTime = unfilteredSelectedTime;
3595
+ var timePx = timestampToPixel(displayTime, centerTime, canvasWidth, secondsPerPx);
3596
+ var currentTimeBoxWidth = getTimeBoxWidth(span);
3597
+ var calendarIconPx = timePx - currentTimeBoxWidth / 2 + CALENDAR_ICON_LEFT_SPACING;
3598
+ return jsxs(Box$1, {
3599
+ className: "timeSliderTimeBox",
3600
+ "data-testid": "timeSliderTimeBox",
3601
+ sx: {
3602
+ height: '24px',
3603
+ cursor: cursorStyle
3604
+ },
3605
+ children: [jsx(CanvasComponent, {
3606
+ onMouseDown: function onMouseDown$1(x, y, width) {
3607
+ if (!unfilteredSelectedTime) {
3608
+ return;
3609
+ }
3610
+ onMouseDown(x, width, unfilteredSelectedTime, centerTime, secondsPerPx, isTimeBoxArea, setCursorStyle, setMouseDownInTimeBox);
3611
+ },
3612
+ onMouseMove: function onMouseMove$1(x, y, event, width) {
3613
+ if (!unfilteredSelectedTime) {
3614
+ return;
3615
+ }
3616
+ onMouseMove(x, width, unfilteredSelectedTime, centerTime, secondsPerPx, mouseDownInTimeBox, isTimeBoxArea, setCursorStyle);
3617
+ },
3618
+ onRenderCanvas: function onRenderCanvas(ctx, width, height) {
3619
+ setCanvasWidth(width);
3620
+ // Use the actual selected time without rounding to timestep
3621
+ renderTimeSliderCurrentTimeBox(ctx, theme, width, height, centerTime, unfilteredSelectedTime, secondsPerPx, span, isAutoUpdating);
3622
+ },
3623
+ ref: node
3624
+ }), jsx(CalendarButton, {
3625
+ calendarIconPx: calendarIconPx,
3626
+ dataEndTime: dataEndTime,
3627
+ dataStartTime: dataStartTime,
3628
+ onSelect: function onSelect(newSelectedTime) {
3629
+ if (newSelectedTime) {
3630
+ onCalendarSelect(newSelectedTime);
3631
+ if (onSetCenterTime) {
3632
+ onSetCenterTime(newSelectedTime - displayTime + centerTime);
3633
+ }
3634
+ }
3635
+ },
3636
+ selectedTime: displayTime
3637
+ })]
3638
+ });
3639
+ };
3640
+
3641
+ var TimesliderI18nProvider = function TimesliderI18nProvider(_ref) {
3642
+ var children = _ref.children;
3643
+ initTimesliderI18n();
3644
+ return jsx(I18nextProvider, {
3645
+ i18n: i18n,
3646
+ children: children
3647
+ });
3648
+ };
3649
+ var DemoWrapper = function DemoWrapper(_ref2) {
3650
+ var children = _ref2.children,
3651
+ _ref2$theme = _ref2.theme,
3652
+ theme = _ref2$theme === void 0 ? 'light' : _ref2$theme;
3653
+ var themeToApply = theme === 'light' ? lightTheme : darkTheme;
3654
+ return jsx(TimesliderI18nProvider, {
3655
+ children: jsx(ThemeWrapper, {
3656
+ theme: themeToApply,
3657
+ children: children
3658
+ })
3659
+ });
3660
+ };
3661
+
3662
+ export { AUTO_MOVE_AREA_PADDING, AnimationLength, AnimationLengthButton, AutoUpdateButton, _BackwardForwardStepButton as BackwardForwardStepButton, ControlButtons, DRAG_AREA_WIDTH, DemoWrapper, HideSliderButton, NowButton, OptionsMenu, OptionsMenuButton, PlayButton, Scale, SpeedButton, TIME_SLIDER_LEGEND_HEIGHT, TIME_SLIDER_NAMESPACE, TimeInMinutes, TimeSlider, TimeSliderButtons, TimeSliderCurrentTimeBox, TimeSliderLegend, TimeSliderMenu, TimeSpanButton, _TimeStepButton as TimeStepButton, calculateMouseTimeAndCheckBounds, convertStringTimeToUnix, defaultAnimationDelayAtStart, defaultDelay, defaultSecondsPerPx, defaultTimeSpan, defaultTimeStep, getAutoMoveAreaWidth, getFilteredTime, getFundamentalScale, getLargestTimeUnit, getNewCenterOfFixedPointZoom, getPixelsBetweenViewportAndTimesliderOnLeft, getPositions, getScaleFromSpan, getSpeedDelay, getTimeBoxWidth, getTimeSliderLegendElement, getTimeSliderLegendId, handleSetNowEvent, isDraggingEndWithinBounds, isDraggingStartWithinBounds, isInsideAnimationArea, isLeftAnimationIconArea, isRightAnimationIconArea, isSelectedTimeIconArea, marks$1 as marks, minutesToDescribedDuration, moveRelativeToTimePoint, moveSelectedTimePx, onsetNewDateDebounced, pixelToTimestamp, roundWithTimeStep, scaleToSecondsPerPx, scalingCoefficient, secondsPerPxFromCanvasWidth, secondsPerPxToScale, secondsPerPxValues, setNextTimeStep, setPreviousTimeStep, spanToScale, speedFactors, timeBoxGeom, timeSliderLegendDefaultProps, timeSliderUtils, timeValues, timesliderTranslations, timestampToPixel, timestampToPixelEdges, useCanvasTarget };