@digitransit-component/digitransit-component-datetimepicker 1.1.0 → 1.1.2
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.
- package/lib/index.development.js +2 -2
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/package.json +3 -3
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/helpers/utils.js","../src/helpers/DesktopDatetimepicker.js","../../../../node_modules/style-inject/dist/style-inject.es.js","../src/helpers/translations.js","../src/helpers/mobileDetection.js","../src/helpers/MobileDatepicker.js","../../../../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../src/helpers/MobileTimepicker.js","../src/helpers/MobilePickerModal.js","../src/helpers/Datetimepicker.js","../src/helpers/dateTimeInputIsSupported.js","../src/index.js"],"sourcesContent":["import moment from 'moment-timezone';\n\n/**\n * Handle typing time and adding necessary :\n *\n * @param {string} typedValue\n *\n * @return {string}\n */\nexport function parseTypedTime(typedValue) {\n let actualValue = typedValue;\n if (\n actualValue.length === 3 &&\n actualValue.split('').every(n => Number.isInteger(Number(n)))\n ) {\n // add ':' if user types three numbers in a row\n if (Number(actualValue.slice(0, 2)) <= 23) {\n actualValue = `${actualValue.slice(0, 2)}:${actualValue[2]}`;\n } else {\n actualValue = `${actualValue[0]}:${actualValue.slice(1)}`;\n }\n }\n return actualValue;\n}\n\nconst validateClock = (hours, minutes) => {\n const hoursValid = !Number.isNaN(hours) && hours >= 0 && hours <= 23;\n const minutesLen = minutes.length;\n const minutesValid =\n minutesLen === 2\n ? !Number.isNaN(minutes) && Number(minutes) >= 0 && Number(minutes <= 59)\n : !Number.isNaN(minutes) && Number(minutes) >= 0 && Number(minutes <= 5);\n return hoursValid && minutesValid;\n};\n\nexport function validateInput(inputValue) {\n if (inputValue.length <= 2) {\n // Too many options, don't validate\n return false;\n }\n if (inputValue.length === 3) {\n let hours;\n let minutes;\n if (inputValue.includes(':')) {\n [hours, minutes] = inputValue.split(':');\n } else if (inputValue.startsWith('0')) {\n hours = inputValue.substring(0, inputValue.length - 1);\n minutes = inputValue.substring(inputValue.length - 1 || 0);\n if (Number(minutes) > 5) {\n return true;\n }\n } else {\n // This is how basically moment handles string formatting.\n // If the first letter of the string is 1, then rest are minutes.\n // if the first letter is 2, then if second letter is 0,1,2 or 3, then second letter is hour, else rest are minutes\n // else, first letter is hour, rest of them are minutes.\n const values = inputValue.split('');\n if (Number(values[0]) === 1) {\n [hours, minutes] = [values[0].concat(values[1]), values[2]];\n } else if (Number(values[0]) === 2) {\n if (Number(values[1] <= 3)) {\n [hours, minutes] = [values[0].concat(values[1]), values[2]];\n } else {\n [hours, minutes] = [values[0], values[1].concat(values[2])];\n }\n } else {\n [hours, minutes] = [values[0], values[1].concat(values[2])];\n }\n return !validateClock(hours, minutes);\n }\n return !validateClock(hours, minutes);\n }\n if (inputValue.length === 5 || inputValue.length === 4) {\n const values = inputValue.split(':');\n const hours = values[0];\n const minutes = values[1];\n if (\n inputValue.startsWith('0') &&\n minutes.length === 1 &&\n Number(minutes) > 5\n ) {\n return true;\n }\n\n return !validateClock(hours, minutes);\n }\n return false;\n}\n\nexport const getTs = (inputValue, currentTimestamp) => {\n const trimmed = inputValue.trim();\n if (trimmed.match(/^[0-9]{1,2}(\\.|:)[0-9]{2}$/) !== null) {\n const splitter = trimmed.includes('.') ? '.' : ':';\n const values = trimmed.split(splitter);\n const hours = Number(values[0]);\n const hoursValid = !Number.isNaN(hours) && hours >= 0 && hours <= 23;\n const minutes = Number(values[1]);\n const minutesValid =\n !Number.isNaN(minutes) && minutes >= 0 && minutes <= 59;\n if (!minutesValid || !hoursValid) {\n return null;\n }\n const newStamp = moment(currentTimestamp)\n .hours(hours)\n .minutes(minutes)\n .valueOf();\n return newStamp;\n }\n return null;\n};\n\nexport default { parseTypedTime, validateInput, getTs };\n","import PropTypes from 'prop-types';\nimport React, { useState, useEffect } from 'react';\nimport moment from 'moment-timezone';\nimport Select from 'react-select';\nimport i18next from 'i18next';\nimport cx from 'classnames';\nimport { parseTypedTime, validateInput, getTs } from './utils';\nimport styles from './styles.scss';\n\n/**\n * Component to display a date or time input on desktop.\n *\n * @param {Object} props\n * @param {Number} props.value Currently selected time. Unix timestamp in milliseconds\n * @param {function} props.onChange This is called with new timestamp when input is changed\n * @param {function} props.getDisplay Function to get a string representation from a timestamp\n * @param {array} props.timeChoices Array of timestamps to choose from\n * @param {string} id Id prefix for labels and aria attributes. Should be unique in page\n * @param {string} label Text to show as input label\n * @param {node} icon JSX for icon to show in input\n * @param {boolean} disableTyping Set to true to disable typing in the input\n * @param {boolean} datePicker Is the picker DatePicker or TimePicker\n *\n * @example\n * <DesktopDatetimepicker\n * value={1590133823000}\n * onChange={timestamp => update(timestamp)}\n * getDisplay={timestamp => formatTime(timestamp)}\n * timeChoices={[1590133823000]}\n * id=\"timeinput\"\n * icon=\"<Icon />\"\n * disableTyping={false} // can be omitted if not true\n * datePicker={true} // can be omitted if not true\n */\nfunction DesktopDatetimepicker({\n value,\n onChange,\n getDisplay,\n timeChoices,\n id,\n label,\n icon,\n disableTyping,\n timeZone,\n datePicker,\n translationSettings,\n}) {\n moment.tz.setDefault(timeZone);\n const [displayValue, changeDisplayValue] = useState(getDisplay(value));\n const [typing, setTyping] = useState(false);\n const [showAllOptions, setShowAllOptions] = useState(true);\n const [invalidInput, setinvalidInput] = useState(false);\n useEffect(() => {\n changeDisplayValue(getDisplay(value));\n if (!datePicker) {\n setinvalidInput(false);\n }\n }, [value]);\n\n // newValue is string\n const handleTimestamp = newValue => {\n const asNumber = Number(newValue);\n if (\n Number.isNaN(asNumber) ||\n !moment(asNumber).isValid() ||\n moment(asNumber).valueOf() !== asNumber\n ) {\n // TODO handle error?\n return;\n }\n onChange(asNumber);\n };\n function isinvalidInput(str) {\n const regex = /[a-zA-Z§ÄäÖö.-\\s]/g;\n if (str.length < displayValue?.length) {\n const valid = validateInput(str);\n setinvalidInput(valid);\n\n return true;\n }\n if (regex.test(str)) {\n return false;\n }\n const time = str.length > 5 ? str.slice(0, -1) : str;\n const valid = validateInput(time);\n setinvalidInput(valid);\n return str.length <= 5;\n }\n const onInputChange = (newValue, { action }) => {\n if (action === 'menu-close') {\n setShowAllOptions(true);\n } else if (showAllOptions) {\n setShowAllOptions(false);\n }\n if (disableTyping || (newValue && !isinvalidInput(newValue))) {\n return;\n }\n if (action === 'input-change') {\n const validated = parseTypedTime(newValue);\n changeDisplayValue(validated);\n setTyping(true);\n }\n };\n const options = timeChoices.map(t => {\n return { value: t.toString(), label: getDisplay(t) };\n });\n\n // Time picker has a list of minutes, instead of 15 minutes. We need to filter those out\n // so closest option will show up in the list.\n const closestOptions = datePicker\n ? options\n : options.filter(o => o.label.split(':')[1] % 15 === 0);\n const closestOption =\n closestOptions.length > 0\n ? closestOptions?.reduce((a, b) =>\n Math.abs(value - a.value) < Math.abs(value - b.value) ? a : b,\n )\n : undefined;\n const inputId = `${id}-input`;\n const labelId = `${id}-label`;\n const filterOptions = (option, input) => {\n const hour = input.length <= 2 ? input : input.split(':')[0];\n const isValidHour = /^([0-1]?[0-9]|2[0-3])$/.test(hour);\n const comp = hour.length === 1 ? '0'.concat(input) : input;\n return isValidHour\n ? option.label.split(':')[0] === comp.split(':')[0]\n : true;\n };\n const ariaError = i18next.t('invalid-input', translationSettings);\n return (\n <label className={styles['combobox-container']} htmlFor={inputId}>\n <span className={styles['sr-only']} id={labelId}>\n {label} {displayValue}\n </span>\n {icon}\n <Select\n aria-labelledby={labelId}\n ariaLiveMessages={{\n guidance: context => {\n // When user types invalid value, isDisabled becomes undefined instead of false\n if (context.isDisabled === undefined && invalidInput) {\n return ariaError;\n }\n return '.'; // this can't be empty for some reason\n },\n onChange: () => {\n return '';\n },\n onFilter: () => {\n return '';\n },\n onFocus: ({ context, label: itemLabel }) => {\n if (context === 'menu') {\n return itemLabel;\n }\n return '';\n },\n }}\n options={options}\n inputId={inputId}\n onChange={time => {\n const currentTime = moment(value).format('HH:mm');\n const ts = getTs(displayValue, value);\n if (typing) {\n if (ts !== null) {\n if (currentTime !== displayValue && time.value === value) {\n handleTimestamp(ts);\n } else {\n handleTimestamp(time.value);\n }\n setTyping(false);\n } else {\n if (time.value !== value) {\n handleTimestamp(time.value);\n } else {\n // reset value\n changeDisplayValue(getDisplay(value));\n }\n setTyping(false);\n }\n if (!datePicker) {\n setinvalidInput(false);\n }\n return;\n }\n if (!datePicker) {\n setinvalidInput(false);\n }\n handleTimestamp(time.value);\n }}\n components={{\n IndicatorsContainer: () => null,\n }}\n className={cx(\n styles['datetimepicker-select-container'],\n invalidInput ? 'datetimepicker-invalid-input' : '',\n )}\n classNamePrefix=\"datetimepicker-select\"\n onInputChange={onInputChange}\n inputValue={!disableTyping && displayValue}\n value={closestOption}\n noOptionsMessage={() => {\n return '';\n }}\n filterOption={(option, input) => {\n if (datePicker) {\n return true;\n }\n const completeInput =\n input.length === 5 ||\n (input.length === 4 && input.split(':')[0].length === 1);\n const isMod15 = option.label.split(':')[1] % 15 === 0;\n const minuteInput = input.split(':')[1]?.length === 1;\n\n if (showAllOptions && isMod15) {\n return true;\n }\n if (minuteInput) {\n const inputH =\n input.split(':')[0].length === 1\n ? '0'.concat(input.split(':')[0])\n : input.split(':')[0];\n const inputM = input.split(':')[1];\n const optH = option.label.split(':')[0];\n const optM = option.label.split(':')[1];\n if (inputH === optH) {\n const t = Number(inputM) * 10;\n const total = Number(optM) - t;\n if (total >= 0 && total <= 9) {\n return true;\n }\n return false;\n }\n }\n if (completeInput && !showAllOptions) {\n return input.length === 4\n ? '0'.concat(input) === option.label\n : input === option.label;\n }\n if (isMod15) {\n return filterOptions(option, input);\n }\n\n return false;\n }}\n controlShouldRenderValue={disableTyping}\n tabSelectsValue={false}\n placeholder=\"\"\n onFocus={e => {\n if (!disableTyping) {\n e.target.select();\n }\n }}\n onBlur={() => {\n // removing focus also locks in value\n if (typing) {\n const validated = getTs(displayValue, value);\n if (validated !== null) {\n handleTimestamp(validated);\n setTyping(false);\n } else {\n changeDisplayValue(getDisplay(value));\n setTyping(false);\n }\n }\n if (!datePicker) {\n setinvalidInput(false);\n }\n }}\n onKeyDown={e => {\n if (['ArrowDown', 'ArrowUp'].includes(e.key)) {\n setTyping(false);\n }\n }}\n isSearchable={!disableTyping}\n />\n </label>\n );\n}\nDesktopDatetimepicker.propTypes = {\n value: PropTypes.number.isRequired,\n onChange: PropTypes.func.isRequired,\n getDisplay: PropTypes.func.isRequired,\n timeChoices: PropTypes.arrayOf(PropTypes.number).isRequired,\n id: PropTypes.string.isRequired,\n label: PropTypes.node.isRequired,\n icon: PropTypes.node.isRequired,\n disableTyping: PropTypes.bool,\n timeZone: PropTypes.string,\n datePicker: PropTypes.bool,\n translationSettings: PropTypes.shape({ lng: PropTypes.string.isRequired }),\n};\n\nDesktopDatetimepicker.defaultProps = {\n disableTyping: false,\n timeZone: 'Europe/Helsinki',\n datePicker: false,\n translationSettings: { lng: 'fi' },\n};\n\nexport default DesktopDatetimepicker;\n","function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","const translations = {\n de: {\n today: 'Heute',\n tomorrow: 'Morgen',\n 'accessible-close': 'Schließe die Auswahl',\n 'accessible-closed': 'Auswahl geschlossen',\n 'accessible-open': 'Öffne die Auswahl',\n 'accessible-opened': 'Auswahl geöffnet',\n 'accessible-title': 'Datum und Uhrzeitauswahl',\n arrival: 'Ankunft',\n date: 'Datum',\n departure: 'Abfahrt',\n 'departure-now': 'Abfahrt jetzt',\n 'choose-time': 'Zeit wählen',\n ready: 'Fertig',\n time: 'Zeit',\n cancel: 'Abbrechen',\n },\n en: {\n today: 'Today',\n tomorrow: 'Tomorrow',\n 'accessible-close': 'Close the picker',\n 'accessible-closed': 'Timepicker closed',\n 'accessible-open': 'Open the picker',\n 'accessible-opened': 'Timepicker opened',\n 'accessible-title': 'Date and timepicker',\n 'accessible-update-instructions':\n 'Changing time parameters will trigger a new search.',\n arrival: 'Arrival',\n date: 'Date',\n departure: 'Departure',\n 'departure-now': 'Leaving now',\n time: 'Time',\n 'choose-time': 'Choose time',\n ready: 'Ready',\n cancel: 'Cancel',\n 'invalid-input': 'The time you entered is invalid',\n },\n fi: {\n today: 'Tänään',\n tomorrow: 'Huomenna',\n 'accessible-close': 'Sulje valitsin',\n 'accessible-closed': 'Valitsin suljettu',\n 'accessible-open': 'Avaa valitsin',\n 'accessible-opened': 'Valitsin avattu',\n 'accessible-title': 'Aika- ja päivämäärävalitsin',\n 'accessible-update-instructions':\n 'Aikavalintojen muuttaminen laukaisee uuden haun.',\n arrival: 'Perillä',\n date: 'Päivä',\n departure: 'Lähtöaika',\n 'departure-now': 'Lähtö nyt',\n time: 'Aika',\n 'choose-time': 'Valitse aika',\n ready: 'Valmis',\n cancel: 'Peruuta',\n 'invalid-input': 'Syöttämäsi aika on virheellinen',\n },\n sv: {\n today: 'I dag',\n tomorrow: 'I morgon',\n 'accessible-close': 'Stäng väljaren',\n 'accessible-closed': 'Väljaren stängde',\n 'accessible-open': 'Öppna väljaren',\n 'accessible-opened': 'Väljaren öppnade',\n 'accessible-title': 'Tid- och datumväljaren',\n 'accessible-update-instructions':\n 'Om du ändrar tiderna, startas en ny sökning automatiskt.',\n arrival: 'Anländer',\n date: 'Datum',\n departure: 'Avgångstid',\n 'departure-now': 'Avgår nu',\n time: 'Tid',\n 'choose-time': 'Välj tid',\n ready: 'Färdig',\n cancel: 'Avbryt',\n 'invalid-input': 'Tiden du angav är felaktig',\n },\n};\n\nexport default translations;\n","/**\n * Detect if user is on a mobile device by parsing userAgent. This is not 100% reliable but close enough.\n *\n * @return {boolean}\n */\nfunction isMobile() {\n const userAgent = navigator.userAgent || navigator.vendor || window.opera;\n const mobile =\n /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(\n userAgent,\n );\n return mobile;\n}\n\n/**\n * Detect if user is on an android device. Not 100% reliable.\n */\nfunction isAndroid() {\n const userAgent = navigator.userAgent.toLowerCase();\n return userAgent.indexOf('android') > -1;\n}\n\nexport { isMobile, isAndroid };\n","import PropTypes from 'prop-types';\nimport React, { useState, useRef, useLayoutEffect } from 'react';\nimport moment from 'moment-timezone';\nimport Autosuggest from 'react-autosuggest';\nimport styles from './styles.scss';\nimport { isAndroid } from './mobileDetection';\n\n/**\n * Component to display a date input on mobile\n */\nfunction MobileDatepicker({\n value,\n getDisplay,\n onChange,\n itemCount,\n startTime,\n id,\n label,\n icon,\n timeZone,\n}) {\n moment.tz.setDefault(timeZone);\n\n const [open, changeOpen] = useState(false);\n const scrollRef = useRef(null);\n const dateChoices = Array(itemCount)\n .fill()\n .map((_, i) => moment(startTime).add(i, 'day').valueOf());\n const minute = 1000 * 60;\n const diffs = dateChoices.map(t => value - t);\n const scrollIndex = diffs.findIndex(t => t < minute); // when time is now, the times might differ by less than one minute\n const elementHeight = 50;\n // scroll to selected time when dropdown is opened\n useLayoutEffect(() => {\n if (open && scrollRef.current) {\n scrollRef.current.scrollTop = elementHeight * scrollIndex;\n }\n }, [value, open]);\n const nativeInput = !isAndroid();\n const inputId = `${id}-input`;\n const labelId = `${id}-label`;\n return (\n <label className={styles['input-container']} htmlFor={inputId}>\n <span>{icon}</span>\n <span className={styles['sr-only']} id={labelId}>\n {label}\n </span>\n {nativeInput ? (\n <select\n className={styles['mobile-input-display']}\n onChange={e => onChange(Number(e.target.value))}\n value={value}\n >\n {dateChoices.map(date => {\n return (\n <option key={date} value={date}>\n {getDisplay(date)}\n </option>\n );\n })}\n </select>\n ) : (\n <Autosuggest\n id={id}\n suggestions={dateChoices}\n getSuggestionValue={s => s.toString()}\n renderSuggestion={s => getDisplay(s)}\n onSuggestionsFetchRequested={() => null}\n shouldRenderSuggestions={() => true}\n inputProps={{\n value: getDisplay(value),\n onChange: (_, { newValue }) => {\n onChange(Number(newValue));\n },\n onFocus: () => {\n changeOpen(true);\n },\n onBlur: () => {\n changeOpen(false);\n },\n 'aria-labelledby': labelId,\n 'aria-autocomplete': 'none',\n readOnly: true,\n }}\n focusInputOnSuggestionClick={false}\n onSuggestionsClearRequested={() => null}\n renderSuggestionsContainer={({ containerProps, children }) => {\n // set refs for autosuggest library and scrollbar positioning\n const { ref, ...otherRefs } = containerProps;\n const containerRef = elem => {\n if (elem) {\n scrollRef.current = elem;\n ref(elem);\n }\n };\n return (\n <div tabIndex=\"-1\" {...otherRefs} ref={containerRef}>\n {children}\n </div>\n );\n }}\n theme={styles}\n />\n )}\n </label>\n );\n}\nMobileDatepicker.propTypes = {\n value: PropTypes.number.isRequired,\n getDisplay: PropTypes.func.isRequired,\n onChange: PropTypes.func.isRequired,\n itemCount: PropTypes.number.isRequired,\n startTime: PropTypes.number.isRequired,\n id: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.node,\n dateTimeCombined: PropTypes.bool,\n timeZone: PropTypes.string,\n};\n\nMobileDatepicker.defaultProps = {\n icon: null,\n dateTimeCombined: false,\n timeZone: 'Europe/Helsinki',\n};\n\nexport default MobileDatepicker;\n","export default function _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n return target;\n}","import PropTypes from 'prop-types';\nimport React, { useRef, useLayoutEffect, useState } from 'react';\nimport moment from 'moment-timezone';\nimport cx from 'classnames';\nimport styles from './styles.scss';\nimport { parseTypedTime, getTs, validateInput } from './utils';\n\n/**\n * Component to display a time input on mobile\n */\nfunction MobileTimepicker({\n value,\n getDisplay,\n onChange,\n id,\n label,\n icon,\n timeZone,\n}) {\n const [inputValue, changeInputValue] = useState(getDisplay(value));\n const [invalidInput, setinvalidInput] = useState(false);\n moment.tz.setDefault(timeZone);\n const inputId = `${id}-input`;\n const labelId = `${id}-label`;\n const timeInputRef = useRef(null);\n useLayoutEffect(() => {\n if (timeInputRef.current) {\n timeInputRef.current.focus();\n }\n }, []);\n return (\n <label className={styles['input-container']} htmlFor={inputId}>\n <span>{icon}</span>\n <span className={styles['sr-only']} id={labelId}>\n {label}\n </span>\n <input\n id={inputId}\n inputMode=\"numeric\"\n type=\"text\"\n maxLength=\"6\"\n className={cx(\n styles['time-input-mobile'],\n invalidInput ? 'mobile-datetimepicker-invalid-input' : '',\n )}\n value={inputValue}\n onFocus={e => {\n e.target.setSelectionRange(0, 0); // set caret to start of input\n }}\n onChange={event => {\n let newValue = event.target.value;\n const valid = validateInput(newValue);\n setinvalidInput(valid);\n if (\n // number typed as first char => clear rest of the input\n newValue.match(/[0-9]{3}:[0-9]{2}/) &&\n newValue.slice(1) === inputValue\n ) {\n newValue = newValue.charAt(0);\n }\n if (newValue.length > 5) {\n return;\n }\n const actual = parseTypedTime(newValue);\n changeInputValue(actual);\n const timestamp = getTs(actual, value);\n if (timestamp) {\n onChange(timestamp);\n }\n }}\n ref={timeInputRef}\n />\n </label>\n );\n}\nMobileTimepicker.propTypes = {\n value: PropTypes.number.isRequired,\n getDisplay: PropTypes.func.isRequired,\n onChange: PropTypes.func.isRequired,\n id: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.node,\n timeZone: PropTypes.string,\n};\n\nMobileTimepicker.defaultProps = {\n icon: null,\n timeZone: 'Europe/Helsinki',\n};\n\nexport default MobileTimepicker;\n","import PropTypes from 'prop-types';\nimport React, { useState } from 'react';\nimport moment from 'moment-timezone';\nimport 'moment/locale/fi';\nimport uniqueId from 'lodash/uniqueId';\nimport i18next from 'i18next';\nimport Modal from 'react-modal';\nimport Icon from '@digitransit-component/digitransit-component-icon';\nimport MobileDatepicker from './MobileDatepicker';\nimport MobileTimepicker from './MobileTimepicker';\nimport translations from './translations';\nimport styles from './styles.scss';\n\nmoment.locale('en');\ni18next.init({ lng: 'en', resources: {} });\nObject.keys(translations).forEach(lang =>\n i18next.addResourceBundle(lang, 'translation', translations[lang]),\n);\n\n/**\n * TODO\n */\nfunction MobilePickerModal({\n departureOrArrival,\n onNowClick,\n lang,\n color,\n timeZone,\n onSubmit,\n onCancel,\n timestamp,\n getTimeDisplay,\n dateSelectItemCount,\n getDateDisplay,\n fontWeights,\n}) {\n moment.tz.setDefault(timeZone);\n const translationSettings = { lng: lang };\n\n const [displayTimestamp, changeTimestamp] = useState(timestamp);\n\n const [departureOrArrivalCurrent, changeDepartureOrArrival] =\n useState(departureOrArrival);\n\n function onArrivalClick() {\n changeDepartureOrArrival('arrival');\n }\n\n function onDepartureClick() {\n changeDepartureOrArrival('departure');\n }\n\n // for input labels\n const [htmlId] = useState(uniqueId('datetimepicker-'));\n const dateSelectStartTime = moment()\n .startOf('day')\n .hour(moment(displayTimestamp).hour())\n .minute(moment(displayTimestamp).minute())\n .valueOf();\n\n return (\n <Modal\n appElement={document ? document.querySelector('#app') : undefined}\n isOpen\n className={styles['mobile-modal-content']}\n overlayClassName={styles['mobile-modal-overlay']}\n >\n <div\n style={{\n '--color': `${color}`,\n '--font-weight-medium': fontWeights.medium,\n }}\n >\n <div className={styles['top-row']}>\n <h3 className={styles['modal-title']}>\n {i18next.t('choose-time', translationSettings)}\n </h3>\n <button\n type=\"button\"\n className={styles['departure-now-button']}\n onClick={onNowClick}\n >\n {i18next.t('departure-now', translationSettings)}\n </button>\n </div>\n <div className={styles['tab-row']}>\n <label\n htmlFor={`${htmlId}-modal-departure`}\n className={`${styles['radio-tab-label']}\n ${\n styles[\n departureOrArrivalCurrent === 'departure'\n ? 'active'\n : undefined\n ]\n }`}\n >\n {i18next.t('departure', translationSettings)}\n <input\n id={`${htmlId}-modal-departure`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"departure\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onDepartureClick();\n }}\n checked={departureOrArrivalCurrent === 'departure'}\n />\n </label>\n <label\n htmlFor={`${htmlId}-modal-arrival`}\n className={`${styles['radio-tab-label']}\n ${\n styles[\n departureOrArrivalCurrent === 'arrival'\n ? 'active'\n : undefined\n ]\n }`}\n >\n {i18next.t('arrival', translationSettings)}\n <input\n id={`${htmlId}-modal-arrival`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"arrival\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onArrivalClick();\n }}\n checked={departureOrArrivalCurrent === 'arrival'}\n />\n </label>\n </div>\n <div className={styles['input-row']}>\n <MobileDatepicker\n value={displayTimestamp}\n getDisplay={getDateDisplay}\n onChange={changeTimestamp}\n itemCount={dateSelectItemCount}\n startTime={dateSelectStartTime}\n id={`${htmlId}-date`}\n label={i18next.t('date', translationSettings)}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['date-input-icon']}`}\n >\n <Icon img=\"calendar\" color={color} />\n </span>\n }\n timeZone={timeZone}\n />\n <MobileTimepicker\n value={displayTimestamp}\n getDisplay={getTimeDisplay}\n onChange={changeTimestamp}\n id={`${htmlId}-time`}\n label={i18next.t('time', translationSettings)}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['time-input-icon']}`}\n >\n <Icon img=\"time\" color={color} />\n </span>\n }\n timeZone={timeZone}\n />\n </div>\n <div className={styles['buttons-row']}>\n <button\n type=\"button\"\n className={styles['ready-button']}\n onClick={() =>\n onSubmit(displayTimestamp, departureOrArrivalCurrent)\n }\n >\n {i18next.t('ready', translationSettings)}\n </button>\n <button\n type=\"button\"\n className={styles['cancel-button']}\n onClick={onCancel}\n >\n {i18next.t('cancel', translationSettings)}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n\nMobilePickerModal.propTypes = {\n timeZone: PropTypes.string,\n departureOrArrival: PropTypes.oneOf(['departure', 'arrival']).isRequired,\n onNowClick: PropTypes.func.isRequired,\n lang: PropTypes.string.isRequired,\n color: PropTypes.string,\n onSubmit: PropTypes.func.isRequired,\n onCancel: PropTypes.func.isRequired,\n timestamp: PropTypes.number.isRequired,\n getTimeDisplay: PropTypes.func.isRequired,\n dateSelectItemCount: PropTypes.number.isRequired,\n getDateDisplay: PropTypes.func.isRequired,\n fontWeights: PropTypes.shape({\n medium: PropTypes.number.isRequired,\n }).isRequired,\n};\n\nMobilePickerModal.defaultProps = {\n color: '#007ac9',\n timeZone: 'Europe/Helsinki',\n};\n\nexport default MobilePickerModal;\n","import PropTypes from 'prop-types';\nimport React, { useState, useEffect, useRef } from 'react';\nimport moment from 'moment-timezone';\nimport 'moment/locale/fi';\nimport uniqueId from 'lodash/uniqueId';\nimport i18next from 'i18next';\nimport Icon from '@digitransit-component/digitransit-component-icon';\nimport DesktopDatetimepicker from './DesktopDatetimepicker';\nimport translations from './translations';\nimport styles from './styles.scss';\nimport { isMobile } from './mobileDetection';\nimport dateTimeInputIsSupported from './dateTimeInputIsSupported';\nimport MobilePickerModal from './MobilePickerModal';\n\nmoment.locale('en');\ni18next.init({\n lng: 'fi',\n fallbackLng: 'fi',\n defaultNS: 'translation',\n interpolation: {\n escapeValue: false, // not needed for react as it escapes by default\n },\n});\n\n/**\n * This component renders combobox style inputs for selecting date and time. This is a controlled component, timestamp is the current value of both inputs.\n * @param {Object} props\n *\n * @param {Number} props.timestamp Currently selected time as a unix timestamp in milliseconds. Set to null to signify that \"now\" is selected. Displayed time is updated in realtime when set to null\n * @param {function} props.onTimeChange Called with new timestamp when time input changes\n * @param {function} props.onDateChange Called with new timestamp when date input changes\n * @param {'arrival'|'departure'} props.departureOrArrival Determine if input is set to choose departure or arrival time\n * @param {function} props.onNowClick Called when \"depart now\" button is clicked\n * @param {function} props.onDepartureClick Called when \"departure\" button is clicked\n * @param {function} props.onArrivalClick Called when \"arrival\" button is clicked\n * @param {node} props.embedWhenClosed JSX element to render in the corner when input is closed\n * @param {node} props.embedWhenOpen JSX element to render when input is open\n * @param {string} props.lang Language selection\n * @param {number} props.serviceTimeRange Determine number of days shown in timepicker. Optional. default is 30.\n * @param {function} props.onOpen Determine what to do when timepicker is open. Optional. no default implementation.\n * @param {function} props.onClose Determine what to do when timepicker is closed. Optional. no default implementation.\n * @param {function} props.openPicker Determine if timepicker should be open in intial render. Optional. Default is undefined.\n *\n *\n * @example\n * <Datetimepicker\n * timestamp={1590133823000}\n * onTimeChange={(newTimestamp) => update(newTimestamp)}\n * onDateChange={(newTimestamp) => update(newTimestamp)}\n * departureOrArrival={'departure'}\n * onNowClick={() => setTimestampToNull()}\n * onDepartureClick={() => departureClicked()}\n * onArrivalClick={() => arrivalClicked()}\n * embedWhenClosed={<button />}\n * lang={'en'}\n * serviceTimeRange={15}\n * />\n */\nfunction Datetimepicker({\n timestamp,\n onTimeChange,\n onDateChange,\n departureOrArrival,\n onNowClick,\n onDepartureClick,\n onArrivalClick,\n embedWhenClosed,\n embedWhenOpen,\n lang,\n color,\n timeZone,\n onModalSubmit,\n fontWeights,\n serviceTimeRange,\n onOpen,\n onClose,\n openPicker,\n}) {\n moment.tz.setDefault(timeZone);\n const [isOpen, changeOpen] = useState(openPicker || false);\n const [displayTimestamp, changeDisplayTimestamp] = useState(\n timestamp || moment().valueOf(),\n );\n // timer for updating displayTimestamp in real time\n const [timerId, setTimer] = useState(null);\n // for input labels\n const [htmlId] = useState(uniqueId('datetimepicker-'));\n const [useMobileInputs] = useState(isMobile() && dateTimeInputIsSupported());\n const openPickerRef = useRef();\n const inputRef = useRef();\n const alertRef = useRef();\n\n const translationSettings = { lng: lang };\n\n useEffect(() => {\n Object.keys(translations).forEach(language =>\n i18next.addResourceBundle(language, 'translation', translations[lang]),\n );\n }, []);\n\n useEffect(() => {\n moment.locale(lang);\n }, [lang]);\n\n const nowSelected = timestamp === null;\n useEffect(() => {\n if (nowSelected) {\n changeDisplayTimestamp(moment().valueOf());\n } else {\n // clear timer\n if (timerId) {\n clearInterval(timerId);\n setTimer(null);\n }\n changeDisplayTimestamp(timestamp);\n }\n }, [timestamp]);\n\n // set timer to update displayTimestamp when minute changes if nowSelected\n useEffect(() => {\n if (!nowSelected) {\n return undefined;\n }\n if (timerId) {\n clearInterval(timerId);\n }\n const newId = setInterval(() => {\n const now = moment().valueOf();\n const sameMinute = moment(displayTimestamp).isSame(now, 'minute');\n if (!sameMinute) {\n clearInterval(newId);\n setTimer(null);\n changeDisplayTimestamp(now);\n }\n }, 5000);\n setTimer(newId);\n return () => clearInterval(newId);\n }, [displayTimestamp]);\n\n const prevIsOpenRef = useRef();\n useEffect(() => {\n prevIsOpenRef.current = isOpen;\n });\n\n // param date is timestamp\n const getDateDisplay = date => {\n const time = moment(date);\n let formatted;\n if (time.isSame(moment(), 'day')) {\n formatted = i18next.t('today', translationSettings);\n } else if (time.isSame(moment().add(1, 'day'), 'day')) {\n formatted = i18next.t('tomorrow', translationSettings);\n } else {\n formatted = time.format('dd D.M.');\n }\n formatted = `${formatted.charAt(0).toUpperCase()}${formatted.slice(1)}`;\n return formatted;\n };\n\n // param time is timestamp\n const getTimeDisplay = time => {\n return moment(time).format('HH:mm');\n };\n\n const selectedMoment = moment(displayTimestamp);\n const timeSelectStartTime = moment(displayTimestamp).startOf('day').valueOf();\n let timeChoices = [];\n const current = moment(timeSelectStartTime);\n while (current.isSame(timeSelectStartTime, 'day')) {\n timeChoices.push(current.valueOf());\n if (isMobile()) {\n current.add(15, 'minutes');\n } else {\n current.add(1, 'minutes');\n }\n }\n if (timestamp === null) {\n // if time is set to now\n // add times in 5 min intervals for next 30 mins\n const fiveMinutes = 1000 * 60 * 5;\n const nextFiveMin = Math.ceil(displayTimestamp / fiveMinutes) * fiveMinutes;\n const timesToAdd = Array(7)\n .fill()\n .map((_, i) => nextFiveMin + i * fiveMinutes);\n const closestIndexAfter = timeChoices\n .map(t => displayTimestamp - t)\n .findIndex(t => t <= 0);\n timeChoices.splice(closestIndexAfter, 0, ...timesToAdd);\n timeChoices = Array.from(new Set(timeChoices)); // remove duplicates\n }\n\n const dateSelectStartTime = moment()\n .startOf('day')\n .hour(selectedMoment.hour())\n .minute(selectedMoment.minute())\n .valueOf();\n const dateChoices = Array(serviceTimeRange)\n .fill()\n .map((_, i) => moment(dateSelectStartTime).add(i, 'day').valueOf());\n\n function showScreenreaderCloseAlert() {\n if (alertRef.current) {\n alertRef.current.innerHTML = i18next.t(\n 'accessible-closed',\n translationSettings,\n );\n setTimeout(() => {\n alertRef.current.innerHTML = null;\n }, 100);\n }\n }\n\n function showScreenreaderOpenAlert() {\n if (alertRef.current) {\n alertRef.current.innerHTML = i18next.t(\n 'accessible-opened',\n translationSettings,\n );\n setTimeout(() => {\n alertRef.current.innerHTML = null;\n }, 100);\n }\n }\n\n function renderOpen() {\n if (useMobileInputs) {\n return (\n isOpen && (\n <MobilePickerModal\n departureOrArrival={departureOrArrival}\n onNowClick={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n onNowClick();\n }}\n lang={lang}\n color={color}\n onSubmit={(newTimestamp, newDepartureOrArrival) => {\n onModalSubmit(newTimestamp, newDepartureOrArrival);\n changeOpen(false);\n showScreenreaderCloseAlert();\n }}\n onCancel={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n if (onClose) {\n onClose();\n }\n }}\n getTimeDisplay={getTimeDisplay}\n timeZone={timeZone}\n timestamp={displayTimestamp}\n getDateDisplay={getDateDisplay}\n dateSelectItemCount={serviceTimeRange}\n getDisplay={getTimeDisplay}\n fontWeights={fontWeights}\n />\n )\n );\n }\n\n return (\n <>\n <div\n className={`${styles['datetimepicker-open-container']} ${\n !isOpen ? styles.hidden : ''\n }`}\n >\n <div\n className={\n isOpen\n ? `${styles['top-row-container']} datetimepicker-top-row`\n : `${styles.hidden} datetimepicker-top-row`\n }\n >\n {' '}\n <span role=\"alert\" className={styles['sr-only']} ref={alertRef} />\n <span />\n {/* This empty span prevents a weird focus bug on chrome */}\n <span className={styles['departure-or-arrival-container']}>\n <label\n htmlFor={`${htmlId}-departure`}\n className={`${styles['radio-textbutton-label']}\n ${\n styles[\n departureOrArrival === 'departure' ? 'active' : undefined\n ]\n }`}\n >\n {i18next.t('departure', translationSettings)}\n <input\n id={`${htmlId}-departure`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"departure\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onDepartureClick();\n }}\n checked={departureOrArrival === 'departure'}\n />\n </label>\n <label\n htmlFor={`${htmlId}-arrival`}\n className={`${styles['radio-textbutton-label']}\n ${\n styles[\n departureOrArrival === 'arrival' ? 'active' : undefined\n ]\n }`}\n >\n {i18next.t('arrival', translationSettings)}\n <input\n id={`${htmlId}-arrival`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"arrival\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onArrivalClick();\n }}\n checked={departureOrArrival === 'arrival'}\n />\n </label>\n </span>\n <button\n id={`${htmlId}-now`}\n type=\"button\"\n className={styles['departure-now-button']}\n onClick={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n if (onClose) {\n onClose();\n }\n onNowClick();\n }}\n ref={inputRef}\n >\n {i18next.t('departure-now', translationSettings)}\n </button>\n <span className={styles['right-edge']}>\n <button\n type=\"button\"\n className={styles['close-button']}\n aria-controls={`${htmlId}-root`}\n aria-expanded=\"true\"\n onClick={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n if (onClose) {\n onClose();\n }\n }}\n >\n <span className={styles['close-icon']}>\n <Icon img=\"close\" color={color} />\n </span>\n <span className={styles['sr-only']}>\n {i18next.t('accessible-close', translationSettings)}\n </span>\n </button>\n </span>\n </div>\n <div\n className={\n isOpen\n ? `${styles['picker-container']}`\n : `${styles.hidden} datetimepicker-top-row`\n }\n >\n <span className={styles['combobox-left']}>\n <DesktopDatetimepicker\n value={displayTimestamp}\n onChange={newValue => {\n onDateChange(newValue);\n }}\n getDisplay={getDateDisplay}\n timeChoices={dateChoices}\n validate={() => null}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['date-input-icon']}`}\n >\n <Icon img=\"calendar\" color={color} />\n </span>\n }\n id={`${htmlId}-date`}\n label={i18next.t('date', translationSettings)}\n disableTyping\n timeZone={timeZone}\n datePicker\n />\n </span>\n <span className={styles['combobox-right']}>\n <DesktopDatetimepicker\n value={displayTimestamp}\n onChange={newValue => {\n onTimeChange(newValue);\n }}\n getDisplay={getTimeDisplay}\n timeChoices={timeChoices}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['time-input-icon']}`}\n >\n <Icon img=\"time\" color={color} />\n </span>\n }\n id={`${htmlId}-time`}\n label={i18next.t('time', translationSettings)}\n timeZone={timeZone}\n translationSettings={translationSettings}\n />\n </span>\n </div>\n </div>\n <span className={isOpen ? '' : styles.hidden}>{embedWhenOpen}</span>\n <div className={isOpen ? 'datetimepicker-bottom-row-open' : ''} />\n </>\n );\n }\n\n return (\n <fieldset\n className={styles['dt-datetimepicker']}\n id={`${htmlId}-root`}\n style={{\n '--color': `${color}`,\n '--font-weight-medium': fontWeights.medium,\n }}\n >\n <legend className={styles['sr-only']}>\n {i18next.t('accessible-title', translationSettings)}\n </legend>\n <span className={styles['sr-only']}>\n {i18next.t('accessible-update-instructions', translationSettings)}\n </span>\n <div\n className={\n !isOpen\n ? `${styles['top-row-container']} ${styles.closed} datetimepicker-top-row`\n : `${styles.hidden} datetimepicker-top-row`\n }\n >\n <label className={styles['label-open']} htmlFor={`${htmlId}-open`}>\n <span className={styles['time-icon']}>\n <Icon img=\"time\" color={color} />\n </span>\n <span className={styles['sr-only']}>\n {i18next.t('accessible-open', translationSettings)}\n </span>\n <span role=\"alert\" className={styles['sr-only']} ref={alertRef} />\n <button\n id={`${htmlId}-open`}\n type=\"button\"\n className={`${styles.textbutton} ${styles.active} ${styles['open-button']}`}\n aria-controls={`${htmlId}-root`}\n aria-expanded=\"false\"\n onClick={() => {\n changeOpen(true);\n showScreenreaderOpenAlert();\n if (onOpen) {\n onOpen();\n }\n }}\n ref={openPickerRef}\n >\n <span>\n {nowSelected && departureOrArrival === 'departure' ? (\n i18next.t('departure-now', translationSettings)\n ) : (\n <>\n {i18next.t(\n departureOrArrival === 'departure'\n ? 'departure'\n : 'arrival',\n translationSettings,\n )}\n {` ${\n moment().isSame(moment(displayTimestamp), 'day')\n ? ''\n : getDateDisplay(displayTimestamp).toLowerCase()\n } ${getTimeDisplay(displayTimestamp)}`}\n </>\n )}\n </span>\n <span className={styles['dropdown-icon']}>\n <Icon img=\"arrow-dropdown\" color={color} />\n </span>\n </button>\n </label>\n <span className={styles['right-edge']}>{embedWhenClosed}</span>\n </div>\n <div />\n {renderOpen()}\n </fieldset>\n );\n}\n\nDatetimepicker.propTypes = {\n timestamp: PropTypes.number,\n timeZone: PropTypes.string,\n onTimeChange: PropTypes.func.isRequired,\n onDateChange: PropTypes.func.isRequired,\n departureOrArrival: PropTypes.oneOf(['departure', 'arrival']).isRequired,\n onNowClick: PropTypes.func.isRequired,\n onDepartureClick: PropTypes.func.isRequired,\n onArrivalClick: PropTypes.func.isRequired,\n embedWhenClosed: PropTypes.node,\n embedWhenOpen: PropTypes.node,\n lang: PropTypes.string.isRequired,\n color: PropTypes.string,\n onModalSubmit: PropTypes.func.isRequired,\n fontWeights: PropTypes.shape({\n medium: PropTypes.number.isRequired,\n }).isRequired,\n serviceTimeRange: PropTypes.number,\n onOpen: PropTypes.func,\n onClose: PropTypes.func,\n openPicker: PropTypes.bool,\n};\n\nDatetimepicker.defaultProps = {\n timestamp: null,\n embedWhenClosed: null,\n embedWhenOpen: null,\n color: '#007ac9',\n timeZone: 'Europe/Helsinki',\n serviceTimeRange: 30,\n onOpen: null,\n onClose: null,\n openPicker: undefined,\n};\n\nexport default Datetimepicker;\n","/**\n * Detect if input type=\"date\" and type=\"time\" are supported in by the browser\n *\n * @return {boolean}\n */\nfunction dateTimeInputIsSupported() {\n if (typeof window === 'undefined' || window === null) {\n return false;\n }\n const elem = document.createElement('input');\n elem.type = 'date';\n if (elem.type !== 'date') {\n return false;\n }\n elem.type = 'time';\n if (elem.type !== 'time') {\n return false;\n }\n return true;\n}\n\nexport default dateTimeInputIsSupported;\n","import PropTypes from 'prop-types';\nimport React, { useState, useEffect } from 'react';\nimport moment from 'moment-timezone';\nimport debounce from 'lodash/debounce';\nimport Datetimepicker from './helpers/Datetimepicker';\n\n/**\n * This component renders an input to choose a date and time. Renders separate input fields for date and time selection. Values for timestamp and arriveBy correspond to Digitransit query params time and arriveBy. This component will display a native date input on mobile and a custom one for desktop. Mobile detection is done by parsing user agent.\n *\n * @alias Datetimepicker\n *\n * @param {Object} props\n *\n * @param {boolean} props.realtime Determine if selected time should be updated in realtime when 'now' is selected.\n * @param {Number} props.initialTimestamp Initial value for selected time. Unix timestamp in seconds. Updating this will change timepicker value but the correct value is kept in component state even if this is not updated.\n * @param {boolean} props.initialArriveBy Initial value for arriveBy. Determines if picker is in arrival mode (true) or departure mode (false). Correct value is kept in component state even if this is not updated. Changing this will also trigger change in the component.\n * @param {function} props.onTimeChange Called with (time, arriveBy) when time input changes. time is number timestamp in seconds, arriveBy is boolean\n * @param {function} props.onDateChange Called with (time, arriveBy) when date input changes. time is number timestamp in seconds, arriveBy is boolean\n * @param {function} props.onNowClick Called when \"depart now\" button is clicked. time is current input value in seconds\n * @param {function} props.onDepartureClick Called with (time) when \"departure\" button is clicked. time is current input value in seconds\n * @param {function} props.onArrivalClick Called with (time) when \"arrival\" button is clicked. time is current input value in seconds\n * @param {node} props.embedWhenClosed JSX element to render in the corner when input is closed\n * @param {node} props.embedWhenOpen JSX element to render when input is open\n * @param {string} props.lang Language selection. Default 'en'\n * @param {number} props.serviceTimeRange Determine number of days shown in timepicker. Optional. default is 30.\n * @param {function} props.onOpen Determine what to do when timepicker is open. Optional. no default implementation.\n * @param {function} props.onClose Determine what to do when timepicker is closed. Optional. no default implementation.\n * @param {function} props.openPicker Determine if timepicker should be open in intial render. Optional. Default is undefined.\n * @example\n * <Datetimepicker\n * realtime={true}\n * initialTimestamp={1590133823}\n * initialArriveBy={false}\n * onTimeChange={(time, arriveBy) => changeUrl(time, arriveBy)}\n * onDateChange={(time, arriveBy) => changeUrl(time, arriveBy)}\n * onNowClick={(time) => changeUrl(undefined, undefined)}\n * onDepartureClick={(time) => changeUrl(time, 'true')}\n * onArrivalClick={(time) => changeUrl(time, undefined)}\n * embedWhenClosed={<button />}\n * lang={'en'}\n * serviceTimeRange={15}\n * />\n */\nfunction DatetimepickerStateContainer({\n realtime,\n initialArriveBy,\n initialTimestamp,\n onDepartureClick,\n onArrivalClick,\n onTimeChange,\n onDateChange,\n onNowClick,\n embedWhenClosed,\n embedWhenOpen,\n lang,\n color,\n timeZone,\n fontWeights,\n serviceTimeRange,\n onOpen,\n onClose,\n openPicker,\n}) {\n moment.locale(lang);\n moment.tz.setDefault(timeZone);\n const initialNow = realtime ? null : moment().valueOf();\n const [timestamp, changeTimestampState] = useState(\n initialTimestamp ? initialTimestamp * 1000 : initialNow,\n );\n const [departureOrArrival, changeDepartureOrArrival] = useState(\n initialArriveBy === true ? 'arrival' : 'departure',\n );\n\n // update state if props change\n useEffect(() => {\n const bothNull = timestamp === null && initialTimestamp === undefined;\n const oneNull = timestamp === null || initialTimestamp === undefined;\n const sameTime = Math.round(timestamp / 1000) === initialTimestamp;\n const timestampChanged = !bothNull && (oneNull || !sameTime);\n if (timestampChanged) {\n if (initialTimestamp === undefined) {\n changeTimestampState(null);\n } else {\n changeTimestampState(initialTimestamp * 1000);\n }\n }\n if (!initialArriveBy === (departureOrArrival === 'arrival')) {\n changeDepartureOrArrival(\n initialArriveBy === true ? 'arrival' : 'departure',\n );\n }\n }, [initialTimestamp, initialArriveBy]);\n\n const timeChanged = debounce(newTime => {\n if (newTime === null) {\n changeTimestampState(moment().valueOf());\n onTimeChange(\n Math.round(moment().valueOf() / 1000),\n departureOrArrival === 'arrival',\n );\n return;\n }\n changeTimestampState(newTime);\n onTimeChange(Math.round(newTime / 1000), departureOrArrival === 'arrival');\n }, 10);\n\n const dateChanged = debounce(newDate => {\n if (newDate === null) {\n changeTimestampState(moment().valueOf());\n onDateChange(\n Math.round(moment().valueOf() / 1000),\n departureOrArrival === 'arrival',\n );\n return;\n }\n changeTimestampState(newDate);\n onDateChange(Math.round(newDate / 1000), departureOrArrival === 'arrival');\n }, 10);\n\n const nowClicked = () => {\n changeDepartureOrArrival('departure');\n const newTimestamp = realtime ? null : moment().valueOf();\n changeTimestampState(newTimestamp);\n onNowClick(Math.round(newTimestamp / 1000));\n };\n\n const departureClicked = () => {\n let changed = false;\n let newTime = timestamp;\n if (timestamp === null) {\n const now = moment().valueOf();\n changeTimestampState(now);\n newTime = now;\n changed = true;\n }\n if (departureOrArrival !== 'departure') {\n changeDepartureOrArrival('departure');\n changed = true;\n }\n if (changed) {\n onDepartureClick(Math.round(newTime / 1000));\n }\n };\n\n const arrivalClicked = () => {\n let changed = false;\n let newTime = timestamp;\n if (timestamp === null) {\n const now = moment().valueOf();\n changeTimestampState(now);\n newTime = now;\n changed = true;\n }\n if (departureOrArrival !== 'arrival') {\n changeDepartureOrArrival('arrival');\n changed = true;\n }\n if (changed) {\n onArrivalClick(Math.round(newTime / 1000));\n }\n };\n const onModalSubmit = (time, mode) => {\n changeTimestampState(time);\n changeDepartureOrArrival(mode);\n onTimeChange(time / 1000, mode === 'arrival', true);\n };\n\n return (\n <Datetimepicker\n timestamp={timestamp}\n onTimeChange={timeChanged}\n onDateChange={dateChanged}\n departureOrArrival={departureOrArrival}\n onNowClick={nowClicked}\n onDepartureClick={departureClicked}\n onArrivalClick={arrivalClicked}\n embedWhenClosed={embedWhenClosed}\n embedWhenOpen={embedWhenOpen}\n lang={lang}\n color={color}\n timeZone={timeZone}\n onModalSubmit={onModalSubmit}\n fontWeights={fontWeights}\n serviceTimeRange={serviceTimeRange}\n onOpen={onOpen}\n onClose={onClose}\n openPicker={openPicker}\n />\n );\n}\n\nDatetimepickerStateContainer.propTypes = {\n realtime: PropTypes.bool,\n initialTimestamp: PropTypes.number,\n initialArriveBy: PropTypes.bool,\n onDepartureClick: PropTypes.func.isRequired,\n onArrivalClick: PropTypes.func.isRequired,\n onTimeChange: PropTypes.func.isRequired,\n onDateChange: PropTypes.func.isRequired,\n onNowClick: PropTypes.func.isRequired,\n embedWhenClosed: PropTypes.node,\n embedWhenOpen: PropTypes.node,\n lang: PropTypes.string,\n color: PropTypes.string,\n timeZone: PropTypes.string,\n fontWeights: PropTypes.shape({\n medium: PropTypes.number,\n }),\n serviceTimeRange: PropTypes.number,\n onOpen: PropTypes.func,\n onClose: PropTypes.func,\n openPicker: PropTypes.bool,\n};\n\nDatetimepickerStateContainer.defaultProps = {\n realtime: false,\n initialArriveBy: undefined,\n initialTimestamp: undefined,\n embedWhenClosed: null,\n embedWhenOpen: null,\n lang: 'en',\n color: '#007ac9',\n timeZone: 'Europe/Helsinki',\n fontWeights: {\n medium: 500,\n },\n onOpen: null,\n onClose: null,\n openPicker: undefined,\n};\n\nexport default DatetimepickerStateContainer;\n"],"names":["parseTypedTime","typedValue","actualValue","length","split","every","n","Number","isInteger","slice","validateClock","hours","minutes","hoursValid","isNaN","minutesValid","validateInput","inputValue","includes","startsWith","values","concat","substring","getTs","currentTimestamp","trimmed","trim","match","splitter","moment","valueOf","DesktopDatetimepicker","value","onChange","getDisplay","timeChoices","id","label","icon","disableTyping","timeZone","datePicker","translationSettings","tz","setDefault","displayValue","changeDisplayValue","useState","typing","setTyping","showAllOptions","setShowAllOptions","invalidInput","setinvalidInput","useEffect","handleTimestamp","newValue","asNumber","isValid","options","map","t","toString","closestOptions","filter","o","closestOption","reduce","a","b","Math","abs","undefined","inputId","labelId","ariaError","i18next","React","createElement","className","styles","htmlFor","Select","ariaLiveMessages","guidance","context","isDisabled","onFilter","onFocus","itemLabel","time","currentTime","format","ts","components","IndicatorsContainer","cx","classNamePrefix","onInputChange","action","str","valid","test","isinvalidInput","validated","noOptionsMessage","filterOption","option","input","_input$split$","completeInput","isMod15","minuteInput","inputH","inputM","optH","optM","total","filterOptions","hour","isValidHour","comp","controlShouldRenderValue","tabSelectsValue","placeholder","e","target","select","onBlur","onKeyDown","key","isSearchable","css","ref","insertAt","document","head","getElementsByTagName","style","type","firstChild","insertBefore","appendChild","styleSheet","cssText","createTextNode","process","env","NODE_ENV","propTypes","PropTypes","number","isRequired","func","arrayOf","string","node","bool","shape","lng","defaultProps","translations","de","today","tomorrow","arrival","date","departure","ready","cancel","en","fi","sv","isMobile","userAgent","navigator","vendor","window","opera","MobileDatepicker","itemCount","startTime","open","changeOpen","scrollRef","useRef","dateChoices","Array","fill","_","i","add","scrollIndex","findIndex","useLayoutEffect","current","scrollTop","nativeInput","toLowerCase","indexOf","Autosuggest","suggestions","getSuggestionValue","s","renderSuggestion","onSuggestionsFetchRequested","shouldRenderSuggestions","inputProps","readOnly","focusInputOnSuggestionClick","onSuggestionsClearRequested","renderSuggestionsContainer","containerProps","children","otherRefs","source","excluded","sourceKeys","Object","keys","_objectWithoutPropertiesLoose","_excluded","assign","tabIndex","elem","theme","MobileTimepicker","changeInputValue","timeInputRef","focus","inputMode","maxLength","setSelectionRange","event","charAt","actual","timestamp","MobilePickerModal","departureOrArrival","onNowClick","lang","color","onSubmit","onCancel","getTimeDisplay","dateSelectItemCount","getDateDisplay","fontWeights","displayTimestamp","changeTimestamp","departureOrArrivalCurrent","changeDepartureOrArrival","htmlId","uniqueId","dateSelectStartTime","startOf","minute","Modal","appElement","querySelector","isOpen","overlayClassName","medium","onClick","name","checked","Icon","img","Datetimepicker","onTimeChange","onDateChange","onDepartureClick","onArrivalClick","embedWhenClosed","embedWhenOpen","onModalSubmit","serviceTimeRange","onOpen","onClose","openPicker","changeDisplayTimestamp","timerId","setTimer","useMobileInputs","dateTimeInputIsSupported","openPickerRef","inputRef","alertRef","forEach","language","addResourceBundle","locale","nowSelected","clearInterval","newId","setInterval","now","isSame","prevIsOpenRef","formatted","toUpperCase","selectedMoment","timeSelectStartTime","push","fiveMinutes","nextFiveMin","ceil","timesToAdd","closestIndexAfter","splice","from","Set","showScreenreaderCloseAlert","innerHTML","setTimeout","hidden","closed","role","textbutton","active","Fragment","newTimestamp","newDepartureOrArrival","validate","DatetimepickerStateContainer","realtime","initialArriveBy","initialTimestamp","initialNow","changeTimestampState","bothNull","oneNull","sameTime","round","timeChanged","debounce","newTime","dateChanged","newDate","nowClicked","departureClicked","changed","arrivalClicked","mode","dateTimeCombined","init","resources","oneOf","fallbackLng","defaultNS","interpolation","escapeValue"],"mappings":"ymCASO,SAASA,EAAeC,GAC7B,IAAIC,EAAcD,EAYlB,OAVyB,IAAvBC,EAAYC,QACZD,EAAYE,MAAM,IAAIC,OAAMC,GAAKC,OAAOC,UAAUD,OAAOD,QAIvDJ,EADEK,OAAOL,EAAYO,MAAM,EAAG,KAAO,GACtB,GAAEP,EAAYO,MAAM,EAAG,MAAMP,EAAY,KAEzC,GAAEA,EAAY,MAAMA,EAAYO,MAAM,MAGlDP,CACT,CAEA,MAAMQ,EAAgBA,CAACC,EAAOC,KAC5B,MAAMC,GAAcN,OAAOO,MAAMH,IAAUA,GAAS,GAAKA,GAAS,GAE5DI,EACW,IAFEH,EAAQT,QAGpBI,OAAOO,MAAMF,IAAYL,OAAOK,IAAY,GAAKL,OAAOK,GAAW,KACnEL,OAAOO,MAAMF,IAAYL,OAAOK,IAAY,GAAKL,OAAOK,GAAW,GAC1E,OAAOC,GAAcE,CAAY,EAG5B,SAASC,EAAcC,GAC5B,GAAIA,EAAWd,QAAU,EAEvB,OAAO,EAET,GAA0B,IAAtBc,EAAWd,OAAc,CAC3B,IAAIQ,EACAC,EACJ,GAAIK,EAAWC,SAAS,MACrBP,EAAOC,GAAWK,EAAWb,MAAM,SAC/B,KAAIa,EAAWE,WAAW,KAM1B,CAKL,MAAMC,EAASH,EAAWb,MAAM,IAYhC,OAX0B,IAAtBG,OAAOa,EAAO,KAEe,IAAtBb,OAAOa,EAAO,KACnBb,OAAOa,EAAO,IAAM,IAFvBT,EAAOC,GAAW,CAACQ,EAAO,GAAGC,OAAOD,EAAO,IAAKA,EAAO,KAQvDT,EAAOC,GAAW,CAACQ,EAAO,GAAIA,EAAO,GAAGC,OAAOD,EAAO,MAEjDV,EAAcC,EAAOC,GApB7B,GAFAD,EAAQM,EAAWK,UAAU,EAAGL,EAAWd,OAAS,GACpDS,EAAUK,EAAWK,UAAUL,EAAWd,OAAS,GAAK,GACpDI,OAAOK,GAAW,EACpB,OAAO,EAqBX,OAAQF,EAAcC,EAAOC,GAE/B,GAA0B,IAAtBK,EAAWd,QAAsC,IAAtBc,EAAWd,OAAc,CACtD,MAAMiB,EAASH,EAAWb,MAAM,KAC1BO,EAAQS,EAAO,GACfR,EAAUQ,EAAO,GACvB,SACEH,EAAWE,WAAW,MACH,IAAnBP,EAAQT,QACRI,OAAOK,GAAW,KAKZF,EAAcC,EAAOC,GAE/B,OAAO,CACT,CAEO,MAAMW,EAAQA,CAACN,EAAYO,KAChC,MAAMC,EAAUR,EAAWS,OAC3B,GAAoD,OAAhDD,EAAQE,MAAM,8BAAwC,CACxD,MAAMC,EAAWH,EAAQP,SAAS,KAAO,IAAM,IACzCE,EAASK,EAAQrB,MAAMwB,GACvBjB,EAAQJ,OAAOa,EAAO,IACtBP,GAAcN,OAAOO,MAAMH,IAAUA,GAAS,GAAKA,GAAS,GAC5DC,EAAUL,OAAOa,EAAO,IAG9B,MADGb,OAAOO,MAAMF,IAAYA,GAAW,GAAKA,GAAW,MACjCC,EACpB,OAAO,KAMT,OAJiBgB,UAAOL,GACrBb,MAAMA,GACNC,QAAQA,GACRkB,UAGL,OAAO,IAAI,4vEC1Eb,SAASC,GAAsBC,MAC7BA,EAAKC,SACLA,EAAQC,WACRA,EAAUC,YACVA,EAAWC,GACXA,EAAEC,MACFA,EAAKC,KACLA,EAAIC,cACJA,EAAaC,SACbA,EAAQC,WACRA,EAAUC,oBACVA,IAEAb,UAAOc,GAAGC,WAAWJ,GACrB,MAAOK,EAAcC,GAAsBC,WAASb,EAAWF,KACxDgB,EAAQC,GAAaF,YAAS,IAC9BG,EAAgBC,GAAqBJ,YAAS,IAC9CK,EAAcC,GAAmBN,YAAS,GACjDO,aAAU,KACRR,EAAmBZ,EAAWF,IACzBS,GACHY,GAAgB,KAEjB,CAACrB,IAGJ,MAAMuB,EAAkBC,IACtB,MAAMC,EAAWlD,OAAOiD,IAEtBjD,OAAOO,MAAM2C,IACZ5B,UAAO4B,GAAUC,WAClB7B,UAAO4B,GAAU3B,YAAc2B,GAKjCxB,EAASwB,EAAS,EAkBpB,MAeME,EAAUxB,EAAYyB,KAAIC,IACvB,CAAE7B,MAAO6B,EAAEC,WAAYzB,MAAOH,EAAW2B,OAK5CE,EAAiBtB,EACnBkB,EACAA,EAAQK,QAAOC,GAAKA,EAAE5B,MAAMjC,MAAM,KAAK,GAAK,IAAO,IACjD8D,EACJH,EAAe5D,OAAS,EACpB4D,eAAAA,EAAgBI,QAAO,CAACC,EAAGC,IACzBC,KAAKC,IAAIvC,EAAQoC,EAAEpC,OAASsC,KAAKC,IAAIvC,EAAQqC,EAAErC,OAASoC,EAAIC,SAE9DG,EACAC,EAAW,GAAErC,UACbsC,EAAW,GAAEtC,UASbuC,EAAYC,UAAQf,EAAE,gBAAiBnB,GAC7C,OACEmC,UAAAC,uBAAOC,UAAWC,EAAO,sBAAuBC,QAASR,GACvDI,UAAAC,sBAAMC,UAAWC,EAAO,WAAY5C,GAAIsC,GACrCrC,EAAM,IAAEQ,GAEVP,EACDuC,UAAAC,cAACI,WACC,kBAAiBR,EACjBS,iBAAkB,CAChBC,SAAUC,QAEmBb,IAAvBa,EAAQC,YAA4BlC,EAC/BuB,EAEF,IAET1C,SAAUA,IACD,GAETsD,SAAUA,IACD,GAETC,QAASA,EAAGH,UAAShD,MAAOoD,KACV,SAAZJ,EACKI,EAEF,IAGX9B,QAASA,EACTc,QAASA,EACTxC,SAAUyD,IACR,MAAMC,EAAc9D,UAAOG,GAAO4D,OAAO,SACnCC,EAAKtE,EAAMsB,EAAcb,GAC/B,GAAIgB,EAoBF,OAnBW,OAAP6C,GACEF,IAAgB9C,GAAgB6C,EAAK1D,QAAUA,EACjDuB,EAAgBsC,GAEhBtC,EAAgBmC,EAAK1D,OAEvBiB,GAAU,KAENyC,EAAK1D,QAAUA,EACjBuB,EAAgBmC,EAAK1D,OAGrBc,EAAmBZ,EAAWF,IAEhCiB,GAAU,SAEPR,GACHY,GAAgB,IAIfZ,GACHY,GAAgB,GAElBE,EAAgBmC,EAAK1D,MAAM,EAE7B8D,WAAY,CACVC,oBAAqBA,IAAM,MAE7BhB,UAAWiB,UACThB,EAAO,mCACP5B,GAAe,gCAEjB6C,gBAAgB,wBAChBC,cA9GgBA,CAAC1C,GAAY2C,aAMjC,GALe,eAAXA,EACFhD,GAAkB,GACTD,GACTC,GAAkB,KAEhBZ,GAAkBiB,IAtBxB,SAAwB4C,GAEtB,GAAIA,EAAIjG,QAAS0C,eAAAA,EAAc1C,QAAQ,CACrC,MAAMkG,EAAQrF,EAAcoF,GAG5B,OAFA/C,EAAgBgD,IAET,EAET,GAPc,qBAOJC,KAAKF,GACb,OAAO,EAET,MACMC,EAAQrF,EADDoF,EAAIjG,OAAS,EAAIiG,EAAI3F,MAAM,GAAI,GAAK2F,GAGjD,OADA/C,EAAgBgD,GACTD,EAAIjG,QAAU,EAQcoG,CAAe/C,KAGnC,iBAAX2C,EAA2B,CAC7B,MAAMK,EAAYxG,EAAewD,GACjCV,EAAmB0D,GACnBvD,GAAU,KAmGRhC,YAAasB,GAAiBM,EAC9Bb,MAAOkC,EACPuC,iBAAkBA,IACT,GAETC,aAAcA,CAACC,EAAQC,KAAU,IAAAC,EAC/B,GAAIpE,EACF,OAAO,EAET,MAAMqE,EACa,IAAjBF,EAAMzG,QACY,IAAjByG,EAAMzG,QAA+C,IAA/ByG,EAAMxG,MAAM,KAAK,GAAGD,OACvC4G,EAAUJ,EAAOtE,MAAMjC,MAAM,KAAK,GAAK,IAAO,EAC9C4G,EAA8C,aAAhCH,EAAAD,EAAMxG,MAAM,KAAK,cAAEyG,SAAnBA,EAAqB1G,QAEzC,GAAI+C,GAAkB6D,EACpB,OAAO,EAET,GAAIC,EAAa,CACf,MAAMC,EAC2B,IAA/BL,EAAMxG,MAAM,KAAK,GAAGD,OAChB,IAAIkB,OAAOuF,EAAMxG,MAAM,KAAK,IAC5BwG,EAAMxG,MAAM,KAAK,GACjB8G,EAASN,EAAMxG,MAAM,KAAK,GAC1B+G,EAAOR,EAAOtE,MAAMjC,MAAM,KAAK,GAC/BgH,EAAOT,EAAOtE,MAAMjC,MAAM,KAAK,GACrC,GAAI6G,IAAWE,EAAM,CACnB,MAAMtD,EAAqB,GAAjBtD,OAAO2G,GACXG,EAAQ9G,OAAO6G,GAAQvD,EAC7B,OAAIwD,GAAS,GAAKA,GAAS,GAM/B,OAAIP,IAAkB5D,EACI,IAAjB0D,EAAMzG,OACT,IAAIkB,OAAOuF,KAAWD,EAAOtE,MAC7BuE,IAAUD,EAAOtE,QAEnB0E,GAvHUO,EAACX,EAAQC,KAC7B,MAAMW,EAAOX,EAAMzG,QAAU,EAAIyG,EAAQA,EAAMxG,MAAM,KAAK,GACpDoH,EAAc,yBAAyBlB,KAAKiB,GAC5CE,EAAuB,IAAhBF,EAAKpH,OAAe,IAAIkB,OAAOuF,GAASA,EACrD,OAAOY,GACHb,EAAOtE,MAAMjC,MAAM,KAAK,KAAOqH,EAAKrH,MAAM,KAAK,EAC3C,EAkHOkH,CAAcX,EAAQC,EAGnB,EAEdc,yBAA0BnF,EAC1BoF,iBAAiB,EACjBC,YAAY,GACZpC,QAASqC,IACFtF,GACHsF,EAAEC,OAAOC,UAGbC,OAAQA,KAEN,GAAIhF,EAAQ,CACV,MAAMwD,EAAYjF,EAAMsB,EAAcb,GACpB,OAAdwE,GACFjD,EAAgBiD,GAChBvD,GAAU,KAEVH,EAAmBZ,EAAWF,IAC9BiB,GAAU,IAGTR,GACHY,GAAgB,IAGpB4E,UAAWJ,IACL,CAAC,YAAa,WAAW3G,SAAS2G,EAAEK,MACtCjF,GAAU,IAGdkF,cAAe5F,IAIvB,ECtRA,SAAqB6F,EAAKC,QACX,IAARA,IAAiBA,EAAM,IAC5B,IAAIC,EAAWD,EAAIC,SAEnB,GAAKF,GAA2B,oBAAbG,SAAnB,CAEA,IAAIC,EAAOD,SAASC,MAAQD,SAASE,qBAAqB,QAAQ,GAC9DC,EAAQH,SAASzD,cAAc,SACnC4D,EAAMC,KAAO,WAEI,QAAbL,GACEE,EAAKI,WACPJ,EAAKK,aAAaH,EAAOF,EAAKI,YAKhCJ,EAAKM,YAAYJ,GAGfA,EAAMK,WACRL,EAAMK,WAAWC,QAAUZ,EAE3BM,EAAMI,YAAYP,SAASU,eAAeb,IAE9C,2qlBD8PAc,QAAAC,IAAAC,WAAArH,EAAsBsH,UAAY,CAChCrH,MAAOsH,UAAUC,OAAOC,WACxBvH,SAAUqH,UAAUG,KAAKD,WACzBtH,WAAYoH,UAAUG,KAAKD,WAC3BrH,YAAamH,UAAUI,QAAQJ,UAAUC,QAAQC,WACjDpH,GAAIkH,UAAUK,OAAOH,WACrBnH,MAAOiH,UAAUM,KAAKJ,WACtBlH,KAAMgH,UAAUM,KAAKJ,WACrBjH,cAAe+G,UAAUO,KACzBrH,SAAU8G,UAAUK,OACpBlH,WAAY6G,UAAUO,KACtBnH,oBAAqB4G,UAAUQ,MAAM,CAAEC,IAAKT,UAAUK,OAAOH,eAG/DzH,EAAsBiI,aAAe,CACnCzH,eAAe,EACfC,SAAU,kBACVC,YAAY,EACZC,oBAAqB,CAAEqH,IAAK,OEzS9B,MAAME,EAAe,CACnBC,GAAI,CACFC,MAAO,QACPC,SAAU,SACV,mBAAoB,uBACpB,oBAAqB,sBACrB,kBAAmB,oBACnB,oBAAqB,mBACrB,mBAAoB,2BACpBC,QAAS,UACTC,KAAM,QACNC,UAAW,UACX,gBAAiB,gBACjB,cAAe,cACfC,MAAO,SACP9E,KAAM,OACN+E,OAAQ,aAEVC,GAAI,CACFP,MAAO,QACPC,SAAU,WACV,mBAAoB,mBACpB,oBAAqB,oBACrB,kBAAmB,kBACnB,oBAAqB,oBACrB,mBAAoB,sBACpB,iCACE,sDACFC,QAAS,UACTC,KAAM,OACNC,UAAW,YACX,gBAAiB,cACjB7E,KAAM,OACN,cAAe,cACf8E,MAAO,QACPC,OAAQ,SACR,gBAAiB,mCAEnBE,GAAI,CACFR,MAAO,SACPC,SAAU,WACV,mBAAoB,iBACpB,oBAAqB,oBACrB,kBAAmB,gBACnB,oBAAqB,kBACrB,mBAAoB,8BACpB,iCACE,mDACFC,QAAS,UACTC,KAAM,QACNC,UAAW,YACX,gBAAiB,YACjB7E,KAAM,OACN,cAAe,eACf8E,MAAO,SACPC,OAAQ,UACR,gBAAiB,mCAEnBG,GAAI,CACFT,MAAO,QACPC,SAAU,WACV,mBAAoB,iBACpB,oBAAqB,mBACrB,kBAAmB,iBACnB,oBAAqB,mBACrB,mBAAoB,yBACpB,iCACE,2DACFC,QAAS,WACTC,KAAM,QACNC,UAAW,aACX,gBAAiB,WACjB7E,KAAM,MACN,cAAe,WACf8E,MAAO,SACPC,OAAQ,SACR,gBAAiB,+BCvErB,SAASI,IACP,MAAMC,EAAYC,UAAUD,WAAaC,UAAUC,QAAUC,OAAOC,MAKpE,MAHE,2TAA2T5E,KACzTwE,EAGN,iBCFA,SAASK,GAAiBnJ,MACxBA,EAAKE,WACLA,EAAUD,SACVA,EAAQmJ,UACRA,EAASC,UACTA,EAASjJ,GACTA,EAAEC,MACFA,EAAKC,KACLA,EAAIE,SACJA,IAEAX,UAAOc,GAAGC,WAAWJ,GAErB,MAAO8I,EAAMC,GAAcxI,YAAS,GAC9ByI,EAAYC,SAAO,MACnBC,EAAcC,MAAMP,GACvBQ,OACAhI,KAAI,CAACiI,EAAGC,IAAMjK,UAAOwJ,GAAWU,IAAID,EAAG,OAAOhK,YAG3CkK,EADQN,EAAY9H,KAAIC,GAAK7B,EAAQ6B,IACjBoI,WAAUpI,GAAKA,EAF1B,MAKfqI,mBAAgB,KACVZ,GAAQE,EAAUW,UACpBX,EAAUW,QAAQC,UAJA,GAI4BJ,KAE/C,CAAChK,EAAOsJ,IACX,MAAMe,IDpBYtB,UAAUD,UAAUwB,cACrBC,QAAQ,YAAc,GCoBjC9H,EAAW,GAAErC,UACbsC,EAAW,GAAEtC,UACnB,OACEyC,UAAAC,uBAAOC,UAAWC,EAAO,mBAAoBC,QAASR,GACpDI,UAAAC,0BAAOxC,GACPuC,UAAAC,sBAAMC,UAAWC,EAAO,WAAY5C,GAAIsC,GACrCrC,GAEFgK,EACCxH,UAAAC,wBACEC,UAAWC,EAAO,wBAClB/C,SAAU4F,GAAK5F,EAAS1B,OAAOsH,EAAEC,OAAO9F,QACxCA,MAAOA,GAEN0J,EAAY9H,KAAI0G,GAEbzF,UAAAC,wBAAQoD,IAAKoC,EAAMtI,MAAOsI,GACvBpI,EAAWoI,OAMpBzF,UAAAC,cAAC0H,WACCpK,GAAIA,EACJqK,YAAaf,EACbgB,mBAAoBC,GAAKA,EAAE7I,WAC3B8I,iBAAkBD,GAAKzK,EAAWyK,GAClCE,4BAA6BA,IAAM,KACnCC,wBAAyBA,KAAM,EAC/BC,WAAY,CACV/K,MAAOE,EAAWF,GAClBC,SAAUA,CAAC4J,GAAKrI,eACdvB,EAAS1B,OAAOiD,GAAU,EAE5BgC,QAASA,KACP+F,GAAW,EAAK,EAElBvD,OAAQA,KACNuD,GAAW,EAAM,EAEnB,kBAAmB7G,EACnB,oBAAqB,OACrBsI,UAAU,GAEZC,6BAA6B,EAC7BC,4BAA6BA,IAAM,KACnCC,2BAA4BA,EAAGC,iBAAgBC,eAE7C,MAAMhF,IAAEA,GAAsB+E,EAAdE,ECxFb,SAAuCC,EAAQC,GAC5D,GAAc,MAAVD,EAAgB,MAAO,GAC3B,IAEIrF,EAAK4D,EAFLhE,EAAS,GACT2F,EAAaC,OAAOC,KAAKJ,GAE7B,IAAKzB,EAAI,EAAGA,EAAI2B,EAAWtN,OAAQ2L,IACjC5D,EAAMuF,EAAW3B,GACb0B,EAASjB,QAAQrE,IAAQ,IAC7BJ,EAAOI,GAAOqF,EAAOrF,IAEvB,OAAOJ,CACT,CD6EqC8F,CAAKR,EAAcS,GAO5C,OACEhJ,UAAAC,oBAAA4I,OAAAI,QAAKC,SAAS,MAAST,GAAWjF,IAPf2F,IACfA,IACFxC,EAAUW,QAAU6B,EACpB3F,EAAI2F,OAKHX,EACG,EAGVY,MAAOjJ,IAKjB,CEhGA,SAASkJ,GAAiBlM,MACxBA,EAAKE,WACLA,EAAUD,SACVA,EAAQG,GACRA,EAAEC,MACFA,EAAKC,KACLA,EAAIE,SACJA,IAEA,MAAOvB,EAAYkN,GAAoBpL,WAASb,EAAWF,KACpDoB,EAAcC,GAAmBN,YAAS,GACjDlB,UAAOc,GAAGC,WAAWJ,GACrB,MAAMiC,EAAW,GAAErC,UACbsC,EAAW,GAAEtC,UACbgM,EAAe3C,SAAO,MAM5B,OALAS,mBAAgB,KACVkC,EAAajC,SACfiC,EAAajC,QAAQkC,UAEtB,IAEDxJ,UAAAC,uBAAOC,UAAWC,EAAO,mBAAoBC,QAASR,GACpDI,UAAAC,0BAAOxC,GACPuC,UAAAC,sBAAMC,UAAWC,EAAO,WAAY5C,GAAIsC,GACrCrC,GAEHwC,UAAAC,uBACE1C,GAAIqC,EACJ6J,UAAU,UACV3F,KAAK,OACL4F,UAAU,IACVxJ,UAAWiB,UACThB,EAAO,qBACP5B,GAAe,uCAEjBpB,MAAOf,EACPuE,QAASqC,IACPA,EAAEC,OAAO0G,kBAAkB,EAAG,EAAE,EAElCvM,SAAUwM,IACR,IAAIjL,EAAWiL,EAAM3G,OAAO9F,MAC5B,MAAMqE,EAAQrF,EAAcwC,GAS5B,GARAH,EAAgBgD,GAGd7C,EAAS7B,MAAM,sBACf6B,EAAS/C,MAAM,KAAOQ,IAEtBuC,EAAWA,EAASkL,OAAO,IAEzBlL,EAASrD,OAAS,EACpB,OAEF,MAAMwO,EAAS3O,EAAewD,GAC9B2K,EAAiBQ,GACjB,MAAMC,EAAYrN,EAAMoN,EAAQ3M,GAC5B4M,GACF3M,EAAS2M,IAGbvG,IAAK+F,IAIb,CCpDA,SAASS,GAAkBC,mBACzBA,EAAkBC,WAClBA,EAAUC,KACVA,EAAIC,MACJA,EAAKzM,SACLA,EAAQ0M,SACRA,EAAQC,SACRA,EAAQP,UACRA,EAASQ,eACTA,EAAcC,oBACdA,EAAmBC,eACnBA,EAAcC,YACdA,IAEA1N,UAAOc,GAAGC,WAAWJ,GACrB,MAAME,EAAsB,CAAEqH,IAAKiF,IAE5BQ,EAAkBC,GAAmB1M,WAAS6L,IAE9Cc,EAA2BC,GAChC5M,WAAS+L,GAWX,MAAOc,GAAU7M,WAAS8M,UAAS,oBAC7BC,EAAsBjO,YACzBkO,QAAQ,OACRxI,KAAK1F,UAAO2N,GAAkBjI,QAC9ByI,OAAOnO,UAAO2N,GAAkBQ,UAChClO,UAEH,OACE+C,UAAAC,cAACmL,WACCC,WAAY3H,SAAWA,SAAS4H,cAAc,aAAU3L,EACxD4L,UACArL,UAAWC,EAAO,wBAClBqL,iBAAkBrL,EAAO,yBAEzBH,UAAAC,qBACE4D,MAAO,CACL,UAAY,GAAEuG,IACd,uBAAwBM,EAAYe,SAGtCzL,UAAAC,qBAAKC,UAAWC,EAAO,YACrBH,UAAAC,oBAAIC,UAAWC,EAAO,gBACnBJ,UAAQf,EAAE,cAAenB,IAE5BmC,UAAAC,wBACE6D,KAAK,SACL5D,UAAWC,EAAO,wBAClBuL,QAASxB,GAERnK,UAAQf,EAAE,gBAAiBnB,KAGhCmC,UAAAC,qBAAKC,UAAWC,EAAO,YACrBH,UAAAC,uBACEG,QAAU,GAAE2K,oBACZ7K,UAAY,GAAEC,EAAO,uCAEfA,EACgC,cAA9B0K,EACI,cACAlL,MAIXI,UAAQf,EAAE,YAAanB,GACxBmC,UAAAC,uBACE1C,GAAK,GAAEwN,oBACPY,KAAK,qBACL7H,KAAK,QACL3G,MAAM,YACN+C,UAAWC,EAAO,oBAClB/C,SAAUA,KAvDpB0N,EAAyB,YAwDK,EAEpBc,QAAuC,cAA9Bf,KAGb7K,UAAAC,uBACEG,QAAU,GAAE2K,kBACZ7K,UAAY,GAAEC,EAAO,uCAEfA,EACgC,YAA9B0K,EACI,cACAlL,MAIXI,UAAQf,EAAE,UAAWnB,GACtBmC,UAAAC,uBACE1C,GAAK,GAAEwN,kBACPY,KAAK,qBACL7H,KAAK,QACL3G,MAAM,UACN+C,UAAWC,EAAO,oBAClB/C,SAAUA,KAnFpB0N,EAAyB,UAoFG,EAElBc,QAAuC,YAA9Bf,MAIf7K,UAAAC,qBAAKC,UAAWC,EAAO,cACrBH,UAAAC,cAACqG,GACCnJ,MAAOwN,EACPtN,WAAYoN,EACZrN,SAAUwN,EACVrE,UAAWiE,EACXhE,UAAWyE,EACX1N,GAAK,GAAEwN,SACPvN,MAAOuC,UAAQf,EAAE,OAAQnB,GACzBJ,KACEuC,UAAAC,sBACEC,UAAY,GAAEC,EAAO,oBAAoBA,EAAO,sBAEhDH,UAAAC,cAAC4L,WAAKC,IAAI,WAAW1B,MAAOA,KAGhCzM,SAAUA,IAEZqC,UAAAC,cAACoJ,GACClM,MAAOwN,EACPtN,WAAYkN,EACZnN,SAAUwN,EACVrN,GAAK,GAAEwN,SACPvN,MAAOuC,UAAQf,EAAE,OAAQnB,GACzBJ,KACEuC,UAAAC,sBACEC,UAAY,GAAEC,EAAO,oBAAoBA,EAAO,sBAEhDH,UAAAC,cAAC4L,WAAKC,IAAI,OAAO1B,MAAOA,KAG5BzM,SAAUA,KAGdqC,UAAAC,qBAAKC,UAAWC,EAAO,gBACrBH,UAAAC,wBACE6D,KAAK,SACL5D,UAAWC,EAAO,gBAClBuL,QAASA,IACPrB,EAASM,EAAkBE,IAG5B9K,UAAQf,EAAE,QAASnB,IAEtBmC,UAAAC,wBACE6D,KAAK,SACL5D,UAAWC,EAAO,iBAClBuL,QAASpB,GAERvK,UAAQf,EAAE,SAAUnB,MAMjC,CCpIA,SAASkO,GAAehC,UACtBA,EAASiC,aACTA,EAAYC,aACZA,EAAYhC,mBACZA,EAAkBC,WAClBA,EAAUgC,iBACVA,EAAgBC,eAChBA,EAAcC,gBACdA,EAAeC,cACfA,EAAalC,KACbA,EAAIC,MACJA,EAAKzM,SACLA,EAAQ2O,cACRA,EAAa5B,YACbA,EAAW6B,iBACXA,EAAgBC,OAChBA,EAAMC,QACNA,EAAOC,WACPA,IAEA1P,UAAOc,GAAGC,WAAWJ,GACrB,MAAO4N,EAAQ7E,GAAcxI,WAASwO,IAAc,IAC7C/B,EAAkBgC,GAA0BzO,WACjD6L,GAAa/M,YAASC,YAGjB2P,EAASC,GAAY3O,WAAS,OAE9B6M,GAAU7M,WAAS8M,UAAS,qBAC5B8B,GAAmB5O,WAAS8H,KClFrC,WACE,GAAsB,oBAAXI,QAAqC,OAAXA,OACnC,OAAO,EAET,MAAM+C,EAAOzF,SAASzD,cAAc,SAEpC,OADAkJ,EAAKrF,KAAO,OACM,SAAdqF,EAAKrF,OAGTqF,EAAKrF,KAAO,OACM,SAAdqF,EAAKrF,KAIX,CDoEmDiJ,IAC3CC,EAAgBpG,WAChBqG,EAAWrG,WACXsG,EAAWtG,WAEX/I,EAAsB,CAAEqH,IAAKiF,GAEnC1L,aAAU,KACRoK,OAAOC,KAAK1D,GAAc+H,SAAQC,GAChCrN,UAAQsN,kBAAkBD,EAAU,cAAehI,EAAa+E,KACjE,GACA,IAEH1L,aAAU,KACRzB,UAAOsQ,OAAOnD,EAAK,GAClB,CAACA,IAEJ,MAAMoD,EAA4B,OAAdxD,EACpBtL,aAAU,KACJ8O,EACFZ,EAAuB3P,YAASC,YAG5B2P,IACFY,cAAcZ,GACdC,EAAS,OAEXF,EAAuB5C,MAExB,CAACA,IAGJtL,aAAU,KACR,IAAK8O,EACH,OAEEX,GACFY,cAAcZ,GAEhB,MAAMa,EAAQC,aAAY,KACxB,MAAMC,EAAM3Q,YAASC,UACFD,UAAO2N,GAAkBiD,OAAOD,EAAK,YAEtDH,cAAcC,GACdZ,EAAS,MACTF,EAAuBgB,MAExB,KAEH,OADAd,EAASY,GACF,IAAMD,cAAcC,EAAM,GAChC,CAAC9C,IAEJ,MAAMkD,EAAgBjH,WACtBnI,aAAU,KACRoP,EAAcvG,QAAUiE,CAAM,IAIhC,MAAMd,EAAiBhF,IACrB,MAAM5E,EAAO7D,UAAOyI,GACpB,IAAIqI,EASJ,OAPEA,EADEjN,EAAK+M,OAAO5Q,YAAU,OACZ+C,UAAQf,EAAE,QAASnB,GACtBgD,EAAK+M,OAAO5Q,YAASkK,IAAI,EAAG,OAAQ,OACjCnH,UAAQf,EAAE,WAAYnB,GAEtBgD,EAAKE,OAAO,WAE1B+M,EAAa,GAAEA,EAAUjE,OAAO,GAAGkE,gBAAgBD,EAAUlS,MAAM,KAC5DkS,CAAS,EAIZvD,EAAiB1J,GACd7D,UAAO6D,GAAME,OAAO,SAGvBiN,EAAiBhR,UAAO2N,GACxBsD,EAAsBjR,UAAO2N,GAAkBO,QAAQ,OAAOjO,UACpE,IAAIK,EAAc,GAClB,MAAMgK,EAAUtK,UAAOiR,GACvB,KAAO3G,EAAQsG,OAAOK,EAAqB,QACzC3Q,EAAY4Q,KAAK5G,EAAQrK,WACrB+I,IACFsB,EAAQJ,IAAI,GAAI,WAEhBI,EAAQJ,IAAI,EAAG,WAGnB,GAAkB,OAAd6C,EAAoB,CAGtB,MAAMoE,EAAc,IACdC,EAAc3O,KAAK4O,KAAK1D,EAAmBwD,GAAeA,EAC1DG,EAAaxH,MAAM,GACtBC,OACAhI,KAAI,CAACiI,EAAGC,IAAMmH,EAAcnH,EAAIkH,IAC7BI,EAAoBjR,EACvByB,KAAIC,GAAK2L,EAAmB3L,IAC5BoI,WAAUpI,GAAKA,GAAK,IACvB1B,EAAYkR,OAAOD,EAAmB,KAAMD,GAC5ChR,EAAcwJ,MAAM2H,KAAK,IAAIC,IAAIpR,IAGnC,MAAM2N,EAAsBjO,YACzBkO,QAAQ,OACRxI,KAAKsL,EAAetL,QACpByI,OAAO6C,EAAe7C,UACtBlO,UACG4J,EAAcC,MAAMyF,GACvBxF,OACAhI,KAAI,CAACiI,EAAGC,IAAMjK,UAAOiO,GAAqB/D,IAAID,EAAG,OAAOhK,YAE3D,SAAS0R,IACHzB,EAAS5F,UACX4F,EAAS5F,QAAQsH,UAAY7O,UAAQf,EACnC,oBACAnB,GAEFgR,YAAW,KACT3B,EAAS5F,QAAQsH,UAAY,IAAI,GAChC,MAuNP,OACE5O,UAAAC,0BACEC,UAAWC,EAAO,qBAClB5C,GAAK,GAAEwN,SACPlH,MAAO,CACL,UAAY,GAAEuG,IACd,uBAAwBM,EAAYe,SAGtCzL,UAAAC,wBAAQC,UAAWC,EAAO,YACvBJ,UAAQf,EAAE,mBAAoBnB,IAEjCmC,UAAAC,sBAAMC,UAAWC,EAAO,YACrBJ,UAAQf,EAAE,iCAAkCnB,IAE/CmC,UAAAC,qBACEC,UACGqL,EAEI,GAAEpL,EAAO2O,gCADT,GAAE3O,EAAO,wBAAwBA,EAAO4O,iCAI/C/O,UAAAC,uBAAOC,UAAWC,EAAO,cAAeC,QAAU,GAAE2K,UAClD/K,UAAAC,sBAAMC,UAAWC,EAAO,cACtBH,UAAAC,cAAC4L,WAAKC,IAAI,OAAO1B,MAAOA,KAE1BpK,UAAAC,sBAAMC,UAAWC,EAAO,YACrBJ,UAAQf,EAAE,kBAAmBnB,IAEhCmC,UAAAC,sBAAM+O,KAAK,QAAQ9O,UAAWC,EAAO,WAAYqD,IAAK0J,IACtDlN,UAAAC,wBACE1C,GAAK,GAAEwN,SACPjH,KAAK,SACL5D,UAAY,GAAEC,EAAO8O,cAAc9O,EAAO+O,UAAU/O,EAAO,iBAC3D,gBAAgB,GAAE4K,SAClB,gBAAc,QACdW,QAASA,KACPhF,GAAW,GAvPjBwG,EAAS5F,UACX4F,EAAS5F,QAAQsH,UAAY7O,UAAQf,EACnC,oBACAnB,GAEFgR,YAAW,KACT3B,EAAS5F,QAAQsH,UAAY,IAAI,GAChC,MAkPSpC,GACFA,KAGJhJ,IAAKwJ,GAELhN,UAAAC,0BACGsN,GAAsC,cAAvBtD,EACdlK,UAAQf,EAAE,gBAAiBnB,GAE3BmC,UAAAC,cAAAD,UAAAmP,cACGpP,UAAQf,EACgB,cAAvBiL,EACI,YACA,UACJpM,GAEA,IACAb,YAAS4Q,OAAO5Q,UAAO2N,GAAmB,OACtC,GACAF,EAAeE,GAAkBlD,iBACnC8C,EAAeI,OAIzB3K,UAAAC,sBAAMC,UAAWC,EAAO,kBACtBH,UAAAC,cAAC4L,WAAKC,IAAI,iBAAiB1B,MAAOA,OAIxCpK,UAAAC,sBAAMC,UAAWC,EAAO,eAAgBiM,IAE1CpM,UAAAC,0BA7QE6M,EAEAvB,GACEvL,UAAAC,cAAC+J,GACCC,mBAAoBA,EACpBC,WAAYA,KACVxD,GAAW,GACXiI,IACAzE,GAAY,EAEdC,KAAMA,EACNC,MAAOA,EACPC,SAAUA,CAAC+E,EAAcC,KACvB/C,EAAc8C,EAAcC,GAC5B3I,GAAW,GACXiI,GAA4B,EAE9BrE,SAAUA,KACR5D,GAAW,GACXiI,IACIlC,GACFA,KAGJlC,eAAgBA,EAChB5M,SAAUA,EACVoM,UAAWY,EACXF,eAAgBA,EAChBD,oBAAqB+B,EACrBlP,WAAYkN,EACZG,YAAaA,IAOnB1K,UAAAC,cAAAD,UAAAmP,cACEnP,UAAAC,qBACEC,UAAY,GAAEC,EAAO,oCAClBoL,EAAyB,GAAhBpL,EAAO2O,UAGnB9O,UAAAC,qBACEC,UACEqL,EACK,GAAEpL,EAAO,8CACT,GAAEA,EAAO2O,iCAGf,IACD9O,UAAAC,sBAAM+O,KAAK,QAAQ9O,UAAWC,EAAO,WAAYqD,IAAK0J,IACtDlN,UAAAC,2BAEAD,UAAAC,sBAAMC,UAAWC,EAAO,mCACtBH,UAAAC,uBACEG,QAAU,GAAE2K,cACZ7K,UAAY,GAAEC,EAAO,8CAEnBA,EACyB,cAAvB8J,EAAqC,cAAWtK,MAInDI,UAAQf,EAAE,YAAanB,GACxBmC,UAAAC,uBACE1C,GAAK,GAAEwN,cACPY,KAAK,qBACL7H,KAAK,QACL3G,MAAM,YACN+C,UAAWC,EAAO,oBAClB/C,SAAUA,KACR8O,GAAkB,EAEpBN,QAAgC,cAAvB3B,KAGbjK,UAAAC,uBACEG,QAAU,GAAE2K,YACZ7K,UAAY,GAAEC,EAAO,8CAEnBA,EACyB,YAAvB8J,EAAmC,cAAWtK,MAIjDI,UAAQf,EAAE,UAAWnB,GACtBmC,UAAAC,uBACE1C,GAAK,GAAEwN,YACPY,KAAK,qBACL7H,KAAK,QACL3G,MAAM,UACN+C,UAAWC,EAAO,oBAClB/C,SAAUA,KACR+O,GAAgB,EAElBP,QAAgC,YAAvB3B,MAIfjK,UAAAC,wBACE1C,GAAK,GAAEwN,QACPjH,KAAK,SACL5D,UAAWC,EAAO,wBAClBuL,QAASA,KACPhF,GAAW,GACXiI,IACIlC,GACFA,IAEFvC,GAAY,EAEd1G,IAAKyJ,GAEJlN,UAAQf,EAAE,gBAAiBnB,IAE9BmC,UAAAC,sBAAMC,UAAWC,EAAO,eACtBH,UAAAC,wBACE6D,KAAK,SACL5D,UAAWC,EAAO,gBAClB,gBAAgB,GAAE4K,SAClB,gBAAc,OACdW,QAASA,KACPhF,GAAW,GACXiI,IACIlC,GACFA,MAIJzM,UAAAC,sBAAMC,UAAWC,EAAO,eACtBH,UAAAC,cAAC4L,WAAKC,IAAI,QAAQ1B,MAAOA,KAE3BpK,UAAAC,sBAAMC,UAAWC,EAAO,YACrBJ,UAAQf,EAAE,mBAAoBnB,OAKvCmC,UAAAC,qBACEC,UACEqL,EACK,GAAEpL,EAAO,sBACT,GAAEA,EAAO2O,iCAGhB9O,UAAAC,sBAAMC,UAAWC,EAAO,kBACtBH,UAAAC,cAAC/C,GACCC,MAAOwN,EACPvN,SAAUuB,IACRsN,EAAatN,EAAS,EAExBtB,WAAYoN,EACZnN,YAAauJ,EACbyI,SAAUA,IAAM,KAChB7R,KACEuC,UAAAC,sBACEC,UAAY,GAAEC,EAAO,oBAAoBA,EAAO,sBAEhDH,UAAAC,cAAC4L,WAAKC,IAAI,WAAW1B,MAAOA,KAGhC7M,GAAK,GAAEwN,SACPvN,MAAOuC,UAAQf,EAAE,OAAQnB,GACzBH,iBACAC,SAAUA,EACVC,iBAGJoC,UAAAC,sBAAMC,UAAWC,EAAO,mBACtBH,UAAAC,cAAC/C,GACCC,MAAOwN,EACPvN,SAAUuB,IACRqN,EAAarN,EAAS,EAExBtB,WAAYkN,EACZjN,YAAaA,EACbG,KACEuC,UAAAC,sBACEC,UAAY,GAAEC,EAAO,oBAAoBA,EAAO,sBAEhDH,UAAAC,cAAC4L,WAAKC,IAAI,OAAO1B,MAAOA,KAG5B7M,GAAK,GAAEwN,SACPvN,MAAOuC,UAAQf,EAAE,OAAQnB,GACzBF,SAAUA,EACVE,oBAAqBA,OAK7BmC,UAAAC,sBAAMC,UAAWqL,EAAS,GAAKpL,EAAO2O,QAASzC,GAC/CrM,UAAAC,qBAAKC,UAAWqL,EAAS,iCAAmC,MAgFpE,CEvcA,SAASgE,GAA6BC,SACpCA,EAAQC,gBACRA,EAAeC,iBACfA,EAAgBxD,iBAChBA,EAAgBC,eAChBA,EAAcH,aACdA,EAAYC,aACZA,EAAY/B,WACZA,EAAUkC,gBACVA,EAAeC,cACfA,EAAalC,KACbA,EAAIC,MACJA,EAAKzM,SACLA,EAAQ+M,YACRA,EAAW6B,iBACXA,EAAgBC,OAChBA,EAAMC,QACNA,EAAOC,WACPA,IAEA1P,UAAOsQ,OAAOnD,GACdnN,UAAOc,GAAGC,WAAWJ,GACrB,MAAMgS,EAAaH,EAAW,KAAOxS,YAASC,WACvC8M,EAAW6F,GAAwB1R,WACxCwR,EAAsC,IAAnBA,EAA0BC,IAExC1F,EAAoBa,GAA4B5M,YACjC,IAApBuR,EAA2B,UAAY,aAIzChR,aAAU,KACR,MAAMoR,EAAyB,OAAd9F,QAA2CpK,IAArB+P,EACjCI,EAAwB,OAAd/F,QAA2CpK,IAArB+P,EAChCK,EAAWtQ,KAAKuQ,MAAMjG,EAAY,OAAU2F,GACxBG,IAAaC,IAAYC,IAG/CH,OADuBjQ,IAArB+P,EACmB,KAEmB,IAAnBA,IAGpBD,IAA4C,YAAvBxF,IACxBa,GACsB,IAApB2E,EAA2B,UAAY,eAG1C,CAACC,EAAkBD,IAEtB,MAAMQ,EAAcC,WAASC,IAC3B,GAAgB,OAAZA,EAMF,OALAP,EAAqB5S,YAASC,gBAC9B+O,EACEvM,KAAKuQ,MAAMhT,YAASC,UAAY,KACT,YAAvBgN,GAIJ2F,EAAqBO,GACrBnE,EAAavM,KAAKuQ,MAAMG,EAAU,KAA8B,YAAvBlG,EAAiC,GACzE,IAEGmG,EAAcF,WAASG,IAC3B,GAAgB,OAAZA,EAMF,OALAT,EAAqB5S,YAASC,gBAC9BgP,EACExM,KAAKuQ,MAAMhT,YAASC,UAAY,KACT,YAAvBgN,GAIJ2F,EAAqBS,GACrBpE,EAAaxM,KAAKuQ,MAAMK,EAAU,KAA8B,YAAvBpG,EAAiC,GACzE,IAkDH,OACEjK,UAAAC,cAAC8L,GACChC,UAAWA,EACXiC,aAAciE,EACdhE,aAAcmE,EACdnG,mBAAoBA,EACpBC,WAtDeoG,KACjBxF,EAAyB,aACzB,MAAMsE,EAAeI,EAAW,KAAOxS,YAASC,UAChD2S,EAAqBR,GACrBlF,EAAWzK,KAAKuQ,MAAMZ,EAAe,KAAM,EAmDzClD,iBAhDqBqE,KACvB,IAAIC,GAAU,EACVL,EAAUpG,EACd,GAAkB,OAAdA,EAAoB,CACtB,MAAM4D,EAAM3Q,YAASC,UACrB2S,EAAqBjC,GACrBwC,EAAUxC,EACV6C,GAAU,EAEe,cAAvBvG,IACFa,EAAyB,aACzB0F,GAAU,GAERA,GACFtE,EAAiBzM,KAAKuQ,MAAMG,EAAU,OAmCtChE,eA/BmBsE,KACrB,IAAID,GAAU,EACVL,EAAUpG,EACd,GAAkB,OAAdA,EAAoB,CACtB,MAAM4D,EAAM3Q,YAASC,UACrB2S,EAAqBjC,GACrBwC,EAAUxC,EACV6C,GAAU,EAEe,YAAvBvG,IACFa,EAAyB,WACzB0F,GAAU,GAERA,GACFrE,EAAe1M,KAAKuQ,MAAMG,EAAU,OAkBpC/D,gBAAiBA,EACjBC,cAAeA,EACflC,KAAMA,EACNC,MAAOA,EACPzM,SAAUA,EACV2O,cApBkBA,CAACzL,EAAM6P,KAC3Bd,EAAqB/O,GACrBiK,EAAyB4F,GACzB1E,EAAanL,EAAO,IAAe,YAAT6P,GAAoB,EAAK,EAkBjDhG,YAAaA,EACb6B,iBAAkBA,EAClBC,OAAQA,EACRC,QAASA,EACTC,WAAYA,GAGlB,gBNlFArI,QAAAC,IAAAC,WAAA+B,EAAiB9B,UAAY,CAC3BrH,MAAOsH,UAAUC,OAAOC,WACxBtH,WAAYoH,UAAUG,KAAKD,WAC3BvH,SAAUqH,UAAUG,KAAKD,WACzB4B,UAAW9B,UAAUC,OAAOC,WAC5B6B,UAAW/B,UAAUC,OAAOC,WAC5BpH,GAAIkH,UAAUK,OAAOH,WACrBnH,MAAOiH,UAAUK,OAAOH,WACxBlH,KAAMgH,UAAUM,KAChB4L,iBAAkBlM,UAAUO,KAC5BrH,SAAU8G,UAAUK,SAGtBwB,EAAiBnB,aAAe,CAC9B1H,KAAM,KACNkT,kBAAkB,EAClBhT,SAAU,kCEhDZ0G,QAAAC,IAAAC,WAAA8E,EAAiB7E,UAAY,CAC3BrH,MAAOsH,UAAUC,OAAOC,WACxBtH,WAAYoH,UAAUG,KAAKD,WAC3BvH,SAAUqH,UAAUG,KAAKD,WACzBpH,GAAIkH,UAAUK,OAAOH,WACrBnH,MAAOiH,UAAUK,OAAOH,WACxBlH,KAAMgH,UAAUM,KAChBpH,SAAU8G,UAAUK,SAGtBuE,EAAiBlE,aAAe,CAC9B1H,KAAM,KACNE,SAAU,6BC1EL2P,OAAO,gBACNsD,KAAK,CAAE1L,IAAK,KAAM2L,UAAW,KACrChI,OAAOC,KAAK1D,GAAc+H,SAAQhD,GAChCpK,UAAQsN,kBAAkBlD,EAAM,cAAe/E,EAAa+E,qBAgL9D9F,QAAAC,IAAAC,WAAAyF,EAAkBxF,UAAY,CAC5B7G,SAAU8G,UAAUK,OACpBmF,mBAAoBxF,UAAUqM,MAAM,CAAC,YAAa,YAAYnM,WAC9DuF,WAAYzF,UAAUG,KAAKD,WAC3BwF,KAAM1F,UAAUK,OAAOH,WACvByF,MAAO3F,UAAUK,OACjBuF,SAAU5F,UAAUG,KAAKD,WACzB2F,SAAU7F,UAAUG,KAAKD,WACzBoF,UAAWtF,UAAUC,OAAOC,WAC5B4F,eAAgB9F,UAAUG,KAAKD,WAC/B6F,oBAAqB/F,UAAUC,OAAOC,WACtC8F,eAAgBhG,UAAUG,KAAKD,WAC/B+F,YAAajG,UAAUQ,MAAM,CAC3BwG,OAAQhH,UAAUC,OAAOC,aACxBA,aAGLqF,EAAkB7E,aAAe,CAC/BiF,MAAO,UACPzM,SAAU,6BCrML2P,OAAO,gBACNsD,KAAK,CACX1L,IAAK,KACL6L,YAAa,KACbC,UAAW,cACXC,cAAe,CACbC,aAAa,oBAgejB7M,QAAAC,IAAAC,WAAAwH,EAAevH,UAAY,CACzBuF,UAAWtF,UAAUC,OACrB/G,SAAU8G,UAAUK,OACpBkH,aAAcvH,UAAUG,KAAKD,WAC7BsH,aAAcxH,UAAUG,KAAKD,WAC7BsF,mBAAoBxF,UAAUqM,MAAM,CAAC,YAAa,YAAYnM,WAC9DuF,WAAYzF,UAAUG,KAAKD,WAC3BuH,iBAAkBzH,UAAUG,KAAKD,WACjCwH,eAAgB1H,UAAUG,KAAKD,WAC/ByH,gBAAiB3H,UAAUM,KAC3BsH,cAAe5H,UAAUM,KACzBoF,KAAM1F,UAAUK,OAAOH,WACvByF,MAAO3F,UAAUK,OACjBwH,cAAe7H,UAAUG,KAAKD,WAC9B+F,YAAajG,UAAUQ,MAAM,CAC3BwG,OAAQhH,UAAUC,OAAOC,aACxBA,WACH4H,iBAAkB9H,UAAUC,OAC5B8H,OAAQ/H,UAAUG,KAClB6H,QAAShI,UAAUG,KACnB8H,WAAYjI,UAAUO,OAGxB+G,EAAe5G,aAAe,CAC5B4E,UAAW,KACXqC,gBAAiB,KACjBC,cAAe,KACfjC,MAAO,UACPzM,SAAU,kBACV4O,iBAAkB,GAClBC,OAAQ,KACRC,QAAS,KACTC,gBAAY/M,kBErVd0E,QAAAC,IAAAC,WAAAgL,EAA6B/K,UAAY,CACvCgL,SAAU/K,UAAUO,KACpB0K,iBAAkBjL,UAAUC,OAC5B+K,gBAAiBhL,UAAUO,KAC3BkH,iBAAkBzH,UAAUG,KAAKD,WACjCwH,eAAgB1H,UAAUG,KAAKD,WAC/BqH,aAAcvH,UAAUG,KAAKD,WAC7BsH,aAAcxH,UAAUG,KAAKD,WAC7BuF,WAAYzF,UAAUG,KAAKD,WAC3ByH,gBAAiB3H,UAAUM,KAC3BsH,cAAe5H,UAAUM,KACzBoF,KAAM1F,UAAUK,OAChBsF,MAAO3F,UAAUK,OACjBnH,SAAU8G,UAAUK,OACpB4F,YAAajG,UAAUQ,MAAM,CAC3BwG,OAAQhH,UAAUC,SAEpB6H,iBAAkB9H,UAAUC,OAC5B8H,OAAQ/H,UAAUG,KAClB6H,QAAShI,UAAUG,KACnB8H,WAAYjI,UAAUO,OAGxBuK,EAA6BpK,aAAe,CAC1CqK,UAAU,EACVC,qBAAiB9P,EACjB+P,sBAAkB/P,EAClByM,gBAAiB,KACjBC,cAAe,KACflC,KAAM,KACNC,MAAO,UACPzM,SAAU,kBACV+M,YAAa,CACXe,OAAQ,KAEVe,OAAQ,KACRC,QAAS,KACTC,gBAAY/M"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","../../../../node_modules/@babel/runtime/helpers/esm/slicedToArray.js","../../../../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","../../../../node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js","../../../../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","../../../../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","../src/helpers/utils.js","../src/helpers/DesktopDatetimepicker.js","../../../../node_modules/style-inject/dist/style-inject.es.js","../src/helpers/translations.js","../src/helpers/mobileDetection.js","../../../../node_modules/@babel/runtime/helpers/esm/objectWithoutProperties.js","../../../../node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js","../src/helpers/MobileDatepicker.js","../src/helpers/MobileTimepicker.js","../src/helpers/MobilePickerModal.js","../src/helpers/Datetimepicker.js","../src/helpers/dateTimeInputIsSupported.js","../src/index.js"],"sourcesContent":["export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(r, l) {\n var t = null == r ? null : \"undefined\" != typeof Symbol && r[Symbol.iterator] || r[\"@@iterator\"];\n if (null != t) {\n var e,\n n,\n i,\n u,\n a = [],\n f = !0,\n o = !1;\n try {\n if (i = (t = t.call(r)).next, 0 === l) {\n if (Object(t) !== t) return;\n f = !1;\n } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);\n } catch (r) {\n o = !0, n = r;\n } finally {\n try {\n if (!f && null != t[\"return\"] && (u = t[\"return\"](), Object(u) !== u)) return;\n } finally {\n if (o) throw n;\n }\n }\n return a;\n }\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","import moment from 'moment-timezone';\n\n/**\n * Handle typing time and adding necessary :\n *\n * @param {string} typedValue\n *\n * @return {string}\n */\nexport function parseTypedTime(typedValue) {\n let actualValue = typedValue;\n if (\n actualValue.length === 3 &&\n actualValue.split('').every(n => Number.isInteger(Number(n)))\n ) {\n // add ':' if user types three numbers in a row\n if (Number(actualValue.slice(0, 2)) <= 23) {\n actualValue = `${actualValue.slice(0, 2)}:${actualValue[2]}`;\n } else {\n actualValue = `${actualValue[0]}:${actualValue.slice(1)}`;\n }\n }\n return actualValue;\n}\n\nconst validateClock = (hours, minutes) => {\n const hoursValid = !Number.isNaN(hours) && hours >= 0 && hours <= 23;\n const minutesLen = minutes.length;\n const minutesValid =\n minutesLen === 2\n ? !Number.isNaN(minutes) && Number(minutes) >= 0 && Number(minutes <= 59)\n : !Number.isNaN(minutes) && Number(minutes) >= 0 && Number(minutes <= 5);\n return hoursValid && minutesValid;\n};\n\nexport function validateInput(inputValue) {\n if (inputValue.length <= 2) {\n // Too many options, don't validate\n return false;\n }\n if (inputValue.length === 3) {\n let hours;\n let minutes;\n if (inputValue.includes(':')) {\n [hours, minutes] = inputValue.split(':');\n } else if (inputValue.startsWith('0')) {\n hours = inputValue.substring(0, inputValue.length - 1);\n minutes = inputValue.substring(inputValue.length - 1 || 0);\n if (Number(minutes) > 5) {\n return true;\n }\n } else {\n // This is how basically moment handles string formatting.\n // If the first letter of the string is 1, then rest are minutes.\n // if the first letter is 2, then if second letter is 0,1,2 or 3, then second letter is hour, else rest are minutes\n // else, first letter is hour, rest of them are minutes.\n const values = inputValue.split('');\n if (Number(values[0]) === 1) {\n [hours, minutes] = [values[0].concat(values[1]), values[2]];\n } else if (Number(values[0]) === 2) {\n if (Number(values[1] <= 3)) {\n [hours, minutes] = [values[0].concat(values[1]), values[2]];\n } else {\n [hours, minutes] = [values[0], values[1].concat(values[2])];\n }\n } else {\n [hours, minutes] = [values[0], values[1].concat(values[2])];\n }\n return !validateClock(hours, minutes);\n }\n return !validateClock(hours, minutes);\n }\n if (inputValue.length === 5 || inputValue.length === 4) {\n const values = inputValue.split(':');\n const hours = values[0];\n const minutes = values[1];\n if (\n inputValue.startsWith('0') &&\n minutes.length === 1 &&\n Number(minutes) > 5\n ) {\n return true;\n }\n\n return !validateClock(hours, minutes);\n }\n return false;\n}\n\nexport const getTs = (inputValue, currentTimestamp) => {\n const trimmed = inputValue.trim();\n if (trimmed.match(/^[0-9]{1,2}(\\.|:)[0-9]{2}$/) !== null) {\n const splitter = trimmed.includes('.') ? '.' : ':';\n const values = trimmed.split(splitter);\n const hours = Number(values[0]);\n const hoursValid = !Number.isNaN(hours) && hours >= 0 && hours <= 23;\n const minutes = Number(values[1]);\n const minutesValid =\n !Number.isNaN(minutes) && minutes >= 0 && minutes <= 59;\n if (!minutesValid || !hoursValid) {\n return null;\n }\n const newStamp = moment(currentTimestamp)\n .hours(hours)\n .minutes(minutes)\n .valueOf();\n return newStamp;\n }\n return null;\n};\n\nexport default { parseTypedTime, validateInput, getTs };\n","import PropTypes from 'prop-types';\nimport React, { useState, useEffect } from 'react';\nimport moment from 'moment-timezone';\nimport Select from 'react-select';\nimport i18next from 'i18next';\nimport cx from 'classnames';\nimport { parseTypedTime, validateInput, getTs } from './utils';\nimport styles from './styles.scss';\n\n/**\n * Component to display a date or time input on desktop.\n *\n * @param {Object} props\n * @param {Number} props.value Currently selected time. Unix timestamp in milliseconds\n * @param {function} props.onChange This is called with new timestamp when input is changed\n * @param {function} props.getDisplay Function to get a string representation from a timestamp\n * @param {array} props.timeChoices Array of timestamps to choose from\n * @param {string} id Id prefix for labels and aria attributes. Should be unique in page\n * @param {string} label Text to show as input label\n * @param {node} icon JSX for icon to show in input\n * @param {boolean} disableTyping Set to true to disable typing in the input\n * @param {boolean} datePicker Is the picker DatePicker or TimePicker\n *\n * @example\n * <DesktopDatetimepicker\n * value={1590133823000}\n * onChange={timestamp => update(timestamp)}\n * getDisplay={timestamp => formatTime(timestamp)}\n * timeChoices={[1590133823000]}\n * id=\"timeinput\"\n * icon=\"<Icon />\"\n * disableTyping={false} // can be omitted if not true\n * datePicker={true} // can be omitted if not true\n */\nfunction DesktopDatetimepicker({\n value,\n onChange,\n getDisplay,\n timeChoices,\n id,\n label,\n icon,\n disableTyping,\n timeZone,\n datePicker,\n translationSettings,\n}) {\n moment.tz.setDefault(timeZone);\n const [displayValue, changeDisplayValue] = useState(getDisplay(value));\n const [typing, setTyping] = useState(false);\n const [showAllOptions, setShowAllOptions] = useState(true);\n const [invalidInput, setinvalidInput] = useState(false);\n useEffect(() => {\n changeDisplayValue(getDisplay(value));\n if (!datePicker) {\n setinvalidInput(false);\n }\n }, [value]);\n\n // newValue is string\n const handleTimestamp = newValue => {\n const asNumber = Number(newValue);\n if (\n Number.isNaN(asNumber) ||\n !moment(asNumber).isValid() ||\n moment(asNumber).valueOf() !== asNumber\n ) {\n // TODO handle error?\n return;\n }\n onChange(asNumber);\n };\n function isinvalidInput(str) {\n const regex = /[a-zA-Z§ÄäÖö.-\\s]/g;\n if (str.length < displayValue?.length) {\n const valid = validateInput(str);\n setinvalidInput(valid);\n\n return true;\n }\n if (regex.test(str)) {\n return false;\n }\n const time = str.length > 5 ? str.slice(0, -1) : str;\n const valid = validateInput(time);\n setinvalidInput(valid);\n return str.length <= 5;\n }\n const onInputChange = (newValue, { action }) => {\n if (action === 'menu-close') {\n setShowAllOptions(true);\n } else if (showAllOptions) {\n setShowAllOptions(false);\n }\n if (disableTyping || (newValue && !isinvalidInput(newValue))) {\n return;\n }\n if (action === 'input-change') {\n const validated = parseTypedTime(newValue);\n changeDisplayValue(validated);\n setTyping(true);\n }\n };\n const options = timeChoices.map(t => {\n return { value: t.toString(), label: getDisplay(t) };\n });\n\n // Time picker has a list of minutes, instead of 15 minutes. We need to filter those out\n // so closest option will show up in the list.\n const closestOptions = datePicker\n ? options\n : options.filter(o => o.label.split(':')[1] % 15 === 0);\n const closestOption =\n closestOptions.length > 0\n ? closestOptions?.reduce((a, b) =>\n Math.abs(value - a.value) < Math.abs(value - b.value) ? a : b,\n )\n : undefined;\n const inputId = `${id}-input`;\n const labelId = `${id}-label`;\n const filterOptions = (option, input) => {\n const hour = input.length <= 2 ? input : input.split(':')[0];\n const isValidHour = /^([0-1]?[0-9]|2[0-3])$/.test(hour);\n const comp = hour.length === 1 ? '0'.concat(input) : input;\n return isValidHour\n ? option.label.split(':')[0] === comp.split(':')[0]\n : true;\n };\n const ariaError = i18next.t('invalid-input', translationSettings);\n return (\n <label className={styles['combobox-container']} htmlFor={inputId}>\n <span className={styles['sr-only']} id={labelId}>\n {label} {displayValue}\n </span>\n {icon}\n <Select\n aria-labelledby={labelId}\n ariaLiveMessages={{\n guidance: context => {\n // When user types invalid value, isDisabled becomes undefined instead of false\n if (context.isDisabled === undefined && invalidInput) {\n return ariaError;\n }\n return '.'; // this can't be empty for some reason\n },\n onChange: () => {\n return '';\n },\n onFilter: () => {\n return '';\n },\n onFocus: ({ context, label: itemLabel }) => {\n if (context === 'menu') {\n return itemLabel;\n }\n return '';\n },\n }}\n options={options}\n inputId={inputId}\n onChange={time => {\n const currentTime = moment(value).format('HH:mm');\n const ts = getTs(displayValue, value);\n if (typing) {\n if (ts !== null) {\n if (currentTime !== displayValue && time.value === value) {\n handleTimestamp(ts);\n } else {\n handleTimestamp(time.value);\n }\n setTyping(false);\n } else {\n if (time.value !== value) {\n handleTimestamp(time.value);\n } else {\n // reset value\n changeDisplayValue(getDisplay(value));\n }\n setTyping(false);\n }\n if (!datePicker) {\n setinvalidInput(false);\n }\n return;\n }\n if (!datePicker) {\n setinvalidInput(false);\n }\n handleTimestamp(time.value);\n }}\n components={{\n IndicatorsContainer: () => null,\n }}\n className={cx(\n styles['datetimepicker-select-container'],\n invalidInput ? 'datetimepicker-invalid-input' : '',\n )}\n classNamePrefix=\"datetimepicker-select\"\n onInputChange={onInputChange}\n inputValue={!disableTyping && displayValue}\n value={closestOption}\n noOptionsMessage={() => {\n return '';\n }}\n filterOption={(option, input) => {\n if (datePicker) {\n return true;\n }\n const completeInput =\n input.length === 5 ||\n (input.length === 4 && input.split(':')[0].length === 1);\n const isMod15 = option.label.split(':')[1] % 15 === 0;\n const minuteInput = input.split(':')[1]?.length === 1;\n\n if (showAllOptions && isMod15) {\n return true;\n }\n if (minuteInput) {\n const inputH =\n input.split(':')[0].length === 1\n ? '0'.concat(input.split(':')[0])\n : input.split(':')[0];\n const inputM = input.split(':')[1];\n const optH = option.label.split(':')[0];\n const optM = option.label.split(':')[1];\n if (inputH === optH) {\n const t = Number(inputM) * 10;\n const total = Number(optM) - t;\n if (total >= 0 && total <= 9) {\n return true;\n }\n return false;\n }\n }\n if (completeInput && !showAllOptions) {\n return input.length === 4\n ? '0'.concat(input) === option.label\n : input === option.label;\n }\n if (isMod15) {\n return filterOptions(option, input);\n }\n\n return false;\n }}\n controlShouldRenderValue={disableTyping}\n tabSelectsValue={false}\n placeholder=\"\"\n onFocus={e => {\n if (!disableTyping) {\n e.target.select();\n }\n }}\n onBlur={() => {\n // removing focus also locks in value\n if (typing) {\n const validated = getTs(displayValue, value);\n if (validated !== null) {\n handleTimestamp(validated);\n setTyping(false);\n } else {\n changeDisplayValue(getDisplay(value));\n setTyping(false);\n }\n }\n if (!datePicker) {\n setinvalidInput(false);\n }\n }}\n onKeyDown={e => {\n if (['ArrowDown', 'ArrowUp'].includes(e.key)) {\n setTyping(false);\n }\n }}\n isSearchable={!disableTyping}\n />\n </label>\n );\n}\nDesktopDatetimepicker.propTypes = {\n value: PropTypes.number.isRequired,\n onChange: PropTypes.func.isRequired,\n getDisplay: PropTypes.func.isRequired,\n timeChoices: PropTypes.arrayOf(PropTypes.number).isRequired,\n id: PropTypes.string.isRequired,\n label: PropTypes.node.isRequired,\n icon: PropTypes.node.isRequired,\n disableTyping: PropTypes.bool,\n timeZone: PropTypes.string,\n datePicker: PropTypes.bool,\n translationSettings: PropTypes.shape({ lng: PropTypes.string.isRequired }),\n};\n\nDesktopDatetimepicker.defaultProps = {\n disableTyping: false,\n timeZone: 'Europe/Helsinki',\n datePicker: false,\n translationSettings: { lng: 'fi' },\n};\n\nexport default DesktopDatetimepicker;\n","function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","const translations = {\n de: {\n today: 'Heute',\n tomorrow: 'Morgen',\n 'accessible-close': 'Schließe die Auswahl',\n 'accessible-closed': 'Auswahl geschlossen',\n 'accessible-open': 'Öffne die Auswahl',\n 'accessible-opened': 'Auswahl geöffnet',\n 'accessible-title': 'Datum und Uhrzeitauswahl',\n arrival: 'Ankunft',\n date: 'Datum',\n departure: 'Abfahrt',\n 'departure-now': 'Abfahrt jetzt',\n 'choose-time': 'Zeit wählen',\n ready: 'Fertig',\n time: 'Zeit',\n cancel: 'Abbrechen',\n },\n en: {\n today: 'Today',\n tomorrow: 'Tomorrow',\n 'accessible-close': 'Close the picker',\n 'accessible-closed': 'Timepicker closed',\n 'accessible-open': 'Open the picker',\n 'accessible-opened': 'Timepicker opened',\n 'accessible-title': 'Date and timepicker',\n 'accessible-update-instructions':\n 'Changing time parameters will trigger a new search.',\n arrival: 'Arrival',\n date: 'Date',\n departure: 'Departure',\n 'departure-now': 'Leaving now',\n time: 'Time',\n 'choose-time': 'Choose time',\n ready: 'Ready',\n cancel: 'Cancel',\n 'invalid-input': 'The time you entered is invalid',\n },\n fi: {\n today: 'Tänään',\n tomorrow: 'Huomenna',\n 'accessible-close': 'Sulje valitsin',\n 'accessible-closed': 'Valitsin suljettu',\n 'accessible-open': 'Avaa valitsin',\n 'accessible-opened': 'Valitsin avattu',\n 'accessible-title': 'Aika- ja päivämäärävalitsin',\n 'accessible-update-instructions':\n 'Aikavalintojen muuttaminen laukaisee uuden haun.',\n arrival: 'Perillä',\n date: 'Päivä',\n departure: 'Lähtöaika',\n 'departure-now': 'Lähtö nyt',\n time: 'Aika',\n 'choose-time': 'Valitse aika',\n ready: 'Valmis',\n cancel: 'Peruuta',\n 'invalid-input': 'Syöttämäsi aika on virheellinen',\n },\n sv: {\n today: 'I dag',\n tomorrow: 'I morgon',\n 'accessible-close': 'Stäng väljaren',\n 'accessible-closed': 'Väljaren stängde',\n 'accessible-open': 'Öppna väljaren',\n 'accessible-opened': 'Väljaren öppnade',\n 'accessible-title': 'Tid- och datumväljaren',\n 'accessible-update-instructions':\n 'Om du ändrar tiderna, startas en ny sökning automatiskt.',\n arrival: 'Anländer',\n date: 'Datum',\n departure: 'Avgångstid',\n 'departure-now': 'Avgår nu',\n time: 'Tid',\n 'choose-time': 'Välj tid',\n ready: 'Färdig',\n cancel: 'Avbryt',\n 'invalid-input': 'Tiden du angav är felaktig',\n },\n};\n\nexport default translations;\n","/**\n * Detect if user is on a mobile device by parsing userAgent. This is not 100% reliable but close enough.\n *\n * @return {boolean}\n */\nfunction isMobile() {\n const userAgent = navigator.userAgent || navigator.vendor || window.opera;\n const mobile =\n /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(\n userAgent,\n );\n return mobile;\n}\n\n/**\n * Detect if user is on an android device. Not 100% reliable.\n */\nfunction isAndroid() {\n const userAgent = navigator.userAgent.toLowerCase();\n return userAgent.indexOf('android') > -1;\n}\n\nexport { isMobile, isAndroid };\n","import objectWithoutPropertiesLoose from \"./objectWithoutPropertiesLoose.js\";\nexport default function _objectWithoutProperties(source, excluded) {\n if (source == null) return {};\n var target = objectWithoutPropertiesLoose(source, excluded);\n var key, i;\n if (Object.getOwnPropertySymbols) {\n var sourceSymbolKeys = Object.getOwnPropertySymbols(source);\n for (i = 0; i < sourceSymbolKeys.length; i++) {\n key = sourceSymbolKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;\n target[key] = source[key];\n }\n }\n return target;\n}","export default function _objectWithoutPropertiesLoose(source, excluded) {\n if (source == null) return {};\n var target = {};\n var sourceKeys = Object.keys(source);\n var key, i;\n for (i = 0; i < sourceKeys.length; i++) {\n key = sourceKeys[i];\n if (excluded.indexOf(key) >= 0) continue;\n target[key] = source[key];\n }\n return target;\n}","import PropTypes from 'prop-types';\nimport React, { useState, useRef, useLayoutEffect } from 'react';\nimport moment from 'moment-timezone';\nimport Autosuggest from 'react-autosuggest';\nimport styles from './styles.scss';\nimport { isAndroid } from './mobileDetection';\n\n/**\n * Component to display a date input on mobile\n */\nfunction MobileDatepicker({\n value,\n getDisplay,\n onChange,\n itemCount,\n startTime,\n id,\n label,\n icon,\n timeZone,\n}) {\n moment.tz.setDefault(timeZone);\n\n const [open, changeOpen] = useState(false);\n const scrollRef = useRef(null);\n const dateChoices = Array(itemCount)\n .fill()\n .map((_, i) => moment(startTime).add(i, 'day').valueOf());\n const minute = 1000 * 60;\n const diffs = dateChoices.map(t => value - t);\n const scrollIndex = diffs.findIndex(t => t < minute); // when time is now, the times might differ by less than one minute\n const elementHeight = 50;\n // scroll to selected time when dropdown is opened\n useLayoutEffect(() => {\n if (open && scrollRef.current) {\n scrollRef.current.scrollTop = elementHeight * scrollIndex;\n }\n }, [value, open]);\n const nativeInput = !isAndroid();\n const inputId = `${id}-input`;\n const labelId = `${id}-label`;\n return (\n <label className={styles['input-container']} htmlFor={inputId}>\n <span>{icon}</span>\n <span className={styles['sr-only']} id={labelId}>\n {label}\n </span>\n {nativeInput ? (\n <select\n className={styles['mobile-input-display']}\n onChange={e => onChange(Number(e.target.value))}\n value={value}\n >\n {dateChoices.map(date => {\n return (\n <option key={date} value={date}>\n {getDisplay(date)}\n </option>\n );\n })}\n </select>\n ) : (\n <Autosuggest\n id={id}\n suggestions={dateChoices}\n getSuggestionValue={s => s.toString()}\n renderSuggestion={s => getDisplay(s)}\n onSuggestionsFetchRequested={() => null}\n shouldRenderSuggestions={() => true}\n inputProps={{\n value: getDisplay(value),\n onChange: (_, { newValue }) => {\n onChange(Number(newValue));\n },\n onFocus: () => {\n changeOpen(true);\n },\n onBlur: () => {\n changeOpen(false);\n },\n 'aria-labelledby': labelId,\n 'aria-autocomplete': 'none',\n readOnly: true,\n }}\n focusInputOnSuggestionClick={false}\n onSuggestionsClearRequested={() => null}\n renderSuggestionsContainer={({ containerProps, children }) => {\n // set refs for autosuggest library and scrollbar positioning\n const { ref, ...otherRefs } = containerProps;\n const containerRef = elem => {\n if (elem) {\n scrollRef.current = elem;\n ref(elem);\n }\n };\n return (\n <div tabIndex=\"-1\" {...otherRefs} ref={containerRef}>\n {children}\n </div>\n );\n }}\n theme={styles}\n />\n )}\n </label>\n );\n}\nMobileDatepicker.propTypes = {\n value: PropTypes.number.isRequired,\n getDisplay: PropTypes.func.isRequired,\n onChange: PropTypes.func.isRequired,\n itemCount: PropTypes.number.isRequired,\n startTime: PropTypes.number.isRequired,\n id: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.node,\n dateTimeCombined: PropTypes.bool,\n timeZone: PropTypes.string,\n};\n\nMobileDatepicker.defaultProps = {\n icon: null,\n dateTimeCombined: false,\n timeZone: 'Europe/Helsinki',\n};\n\nexport default MobileDatepicker;\n","import PropTypes from 'prop-types';\nimport React, { useRef, useLayoutEffect, useState } from 'react';\nimport moment from 'moment-timezone';\nimport cx from 'classnames';\nimport styles from './styles.scss';\nimport { parseTypedTime, getTs, validateInput } from './utils';\n\n/**\n * Component to display a time input on mobile\n */\nfunction MobileTimepicker({\n value,\n getDisplay,\n onChange,\n id,\n label,\n icon,\n timeZone,\n}) {\n const [inputValue, changeInputValue] = useState(getDisplay(value));\n const [invalidInput, setinvalidInput] = useState(false);\n moment.tz.setDefault(timeZone);\n const inputId = `${id}-input`;\n const labelId = `${id}-label`;\n const timeInputRef = useRef(null);\n useLayoutEffect(() => {\n if (timeInputRef.current) {\n timeInputRef.current.focus();\n }\n }, []);\n return (\n <label className={styles['input-container']} htmlFor={inputId}>\n <span>{icon}</span>\n <span className={styles['sr-only']} id={labelId}>\n {label}\n </span>\n <input\n id={inputId}\n inputMode=\"numeric\"\n type=\"text\"\n maxLength=\"6\"\n className={cx(\n styles['time-input-mobile'],\n invalidInput ? 'mobile-datetimepicker-invalid-input' : '',\n )}\n value={inputValue}\n onFocus={e => {\n e.target.setSelectionRange(0, 0); // set caret to start of input\n }}\n onChange={event => {\n let newValue = event.target.value;\n const valid = validateInput(newValue);\n setinvalidInput(valid);\n if (\n // number typed as first char => clear rest of the input\n newValue.match(/[0-9]{3}:[0-9]{2}/) &&\n newValue.slice(1) === inputValue\n ) {\n newValue = newValue.charAt(0);\n }\n if (newValue.length > 5) {\n return;\n }\n const actual = parseTypedTime(newValue);\n changeInputValue(actual);\n const timestamp = getTs(actual, value);\n if (timestamp) {\n onChange(timestamp);\n }\n }}\n ref={timeInputRef}\n />\n </label>\n );\n}\nMobileTimepicker.propTypes = {\n value: PropTypes.number.isRequired,\n getDisplay: PropTypes.func.isRequired,\n onChange: PropTypes.func.isRequired,\n id: PropTypes.string.isRequired,\n label: PropTypes.string.isRequired,\n icon: PropTypes.node,\n timeZone: PropTypes.string,\n};\n\nMobileTimepicker.defaultProps = {\n icon: null,\n timeZone: 'Europe/Helsinki',\n};\n\nexport default MobileTimepicker;\n","import PropTypes from 'prop-types';\nimport React, { useState } from 'react';\nimport moment from 'moment-timezone';\nimport 'moment/locale/fi';\nimport uniqueId from 'lodash/uniqueId';\nimport i18next from 'i18next';\nimport Modal from 'react-modal';\nimport Icon from '@digitransit-component/digitransit-component-icon';\nimport MobileDatepicker from './MobileDatepicker';\nimport MobileTimepicker from './MobileTimepicker';\nimport translations from './translations';\nimport styles from './styles.scss';\n\nmoment.locale('en');\ni18next.init({ lng: 'en', resources: {} });\nObject.keys(translations).forEach(lang =>\n i18next.addResourceBundle(lang, 'translation', translations[lang]),\n);\n\n/**\n * TODO\n */\nfunction MobilePickerModal({\n departureOrArrival,\n onNowClick,\n lang,\n color,\n timeZone,\n onSubmit,\n onCancel,\n timestamp,\n getTimeDisplay,\n dateSelectItemCount,\n getDateDisplay,\n fontWeights,\n}) {\n moment.tz.setDefault(timeZone);\n const translationSettings = { lng: lang };\n\n const [displayTimestamp, changeTimestamp] = useState(timestamp);\n\n const [departureOrArrivalCurrent, changeDepartureOrArrival] =\n useState(departureOrArrival);\n\n function onArrivalClick() {\n changeDepartureOrArrival('arrival');\n }\n\n function onDepartureClick() {\n changeDepartureOrArrival('departure');\n }\n\n // for input labels\n const [htmlId] = useState(uniqueId('datetimepicker-'));\n const dateSelectStartTime = moment()\n .startOf('day')\n .hour(moment(displayTimestamp).hour())\n .minute(moment(displayTimestamp).minute())\n .valueOf();\n\n return (\n <Modal\n appElement={document ? document.querySelector('#app') : undefined}\n isOpen\n className={styles['mobile-modal-content']}\n overlayClassName={styles['mobile-modal-overlay']}\n >\n <div\n style={{\n '--color': `${color}`,\n '--font-weight-medium': fontWeights.medium,\n }}\n >\n <div className={styles['top-row']}>\n <h3 className={styles['modal-title']}>\n {i18next.t('choose-time', translationSettings)}\n </h3>\n <button\n type=\"button\"\n className={styles['departure-now-button']}\n onClick={onNowClick}\n >\n {i18next.t('departure-now', translationSettings)}\n </button>\n </div>\n <div className={styles['tab-row']}>\n <label\n htmlFor={`${htmlId}-modal-departure`}\n className={`${styles['radio-tab-label']}\n ${\n styles[\n departureOrArrivalCurrent === 'departure'\n ? 'active'\n : undefined\n ]\n }`}\n >\n {i18next.t('departure', translationSettings)}\n <input\n id={`${htmlId}-modal-departure`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"departure\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onDepartureClick();\n }}\n checked={departureOrArrivalCurrent === 'departure'}\n />\n </label>\n <label\n htmlFor={`${htmlId}-modal-arrival`}\n className={`${styles['radio-tab-label']}\n ${\n styles[\n departureOrArrivalCurrent === 'arrival'\n ? 'active'\n : undefined\n ]\n }`}\n >\n {i18next.t('arrival', translationSettings)}\n <input\n id={`${htmlId}-modal-arrival`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"arrival\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onArrivalClick();\n }}\n checked={departureOrArrivalCurrent === 'arrival'}\n />\n </label>\n </div>\n <div className={styles['input-row']}>\n <MobileDatepicker\n value={displayTimestamp}\n getDisplay={getDateDisplay}\n onChange={changeTimestamp}\n itemCount={dateSelectItemCount}\n startTime={dateSelectStartTime}\n id={`${htmlId}-date`}\n label={i18next.t('date', translationSettings)}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['date-input-icon']}`}\n >\n <Icon img=\"calendar\" color={color} />\n </span>\n }\n timeZone={timeZone}\n />\n <MobileTimepicker\n value={displayTimestamp}\n getDisplay={getTimeDisplay}\n onChange={changeTimestamp}\n id={`${htmlId}-time`}\n label={i18next.t('time', translationSettings)}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['time-input-icon']}`}\n >\n <Icon img=\"time\" color={color} />\n </span>\n }\n timeZone={timeZone}\n />\n </div>\n <div className={styles['buttons-row']}>\n <button\n type=\"button\"\n className={styles['ready-button']}\n onClick={() =>\n onSubmit(displayTimestamp, departureOrArrivalCurrent)\n }\n >\n {i18next.t('ready', translationSettings)}\n </button>\n <button\n type=\"button\"\n className={styles['cancel-button']}\n onClick={onCancel}\n >\n {i18next.t('cancel', translationSettings)}\n </button>\n </div>\n </div>\n </Modal>\n );\n}\n\nMobilePickerModal.propTypes = {\n timeZone: PropTypes.string,\n departureOrArrival: PropTypes.oneOf(['departure', 'arrival']).isRequired,\n onNowClick: PropTypes.func.isRequired,\n lang: PropTypes.string.isRequired,\n color: PropTypes.string,\n onSubmit: PropTypes.func.isRequired,\n onCancel: PropTypes.func.isRequired,\n timestamp: PropTypes.number.isRequired,\n getTimeDisplay: PropTypes.func.isRequired,\n dateSelectItemCount: PropTypes.number.isRequired,\n getDateDisplay: PropTypes.func.isRequired,\n fontWeights: PropTypes.shape({\n medium: PropTypes.number.isRequired,\n }).isRequired,\n};\n\nMobilePickerModal.defaultProps = {\n color: '#007ac9',\n timeZone: 'Europe/Helsinki',\n};\n\nexport default MobilePickerModal;\n","import PropTypes from 'prop-types';\nimport React, { useState, useEffect, useRef } from 'react';\nimport moment from 'moment-timezone';\nimport 'moment/locale/fi';\nimport uniqueId from 'lodash/uniqueId';\nimport i18next from 'i18next';\nimport Icon from '@digitransit-component/digitransit-component-icon';\nimport DesktopDatetimepicker from './DesktopDatetimepicker';\nimport translations from './translations';\nimport styles from './styles.scss';\nimport { isMobile } from './mobileDetection';\nimport dateTimeInputIsSupported from './dateTimeInputIsSupported';\nimport MobilePickerModal from './MobilePickerModal';\n\nmoment.locale('en');\ni18next.init({\n lng: 'fi',\n fallbackLng: 'fi',\n defaultNS: 'translation',\n interpolation: {\n escapeValue: false, // not needed for react as it escapes by default\n },\n});\n\n/**\n * This component renders combobox style inputs for selecting date and time. This is a controlled component, timestamp is the current value of both inputs.\n * @param {Object} props\n *\n * @param {Number} props.timestamp Currently selected time as a unix timestamp in milliseconds. Set to null to signify that \"now\" is selected. Displayed time is updated in realtime when set to null\n * @param {function} props.onTimeChange Called with new timestamp when time input changes\n * @param {function} props.onDateChange Called with new timestamp when date input changes\n * @param {'arrival'|'departure'} props.departureOrArrival Determine if input is set to choose departure or arrival time\n * @param {function} props.onNowClick Called when \"depart now\" button is clicked\n * @param {function} props.onDepartureClick Called when \"departure\" button is clicked\n * @param {function} props.onArrivalClick Called when \"arrival\" button is clicked\n * @param {node} props.embedWhenClosed JSX element to render in the corner when input is closed\n * @param {node} props.embedWhenOpen JSX element to render when input is open\n * @param {string} props.lang Language selection\n * @param {number} props.serviceTimeRange Determine number of days shown in timepicker. Optional. default is 30.\n * @param {function} props.onOpen Determine what to do when timepicker is open. Optional. no default implementation.\n * @param {function} props.onClose Determine what to do when timepicker is closed. Optional. no default implementation.\n * @param {function} props.openPicker Determine if timepicker should be open in intial render. Optional. Default is undefined.\n *\n *\n * @example\n * <Datetimepicker\n * timestamp={1590133823000}\n * onTimeChange={(newTimestamp) => update(newTimestamp)}\n * onDateChange={(newTimestamp) => update(newTimestamp)}\n * departureOrArrival={'departure'}\n * onNowClick={() => setTimestampToNull()}\n * onDepartureClick={() => departureClicked()}\n * onArrivalClick={() => arrivalClicked()}\n * embedWhenClosed={<button />}\n * lang={'en'}\n * serviceTimeRange={15}\n * />\n */\nfunction Datetimepicker({\n timestamp,\n onTimeChange,\n onDateChange,\n departureOrArrival,\n onNowClick,\n onDepartureClick,\n onArrivalClick,\n embedWhenClosed,\n embedWhenOpen,\n lang,\n color,\n timeZone,\n onModalSubmit,\n fontWeights,\n serviceTimeRange,\n onOpen,\n onClose,\n openPicker,\n}) {\n moment.tz.setDefault(timeZone);\n const [isOpen, changeOpen] = useState(openPicker || false);\n const [displayTimestamp, changeDisplayTimestamp] = useState(\n timestamp || moment().valueOf(),\n );\n // timer for updating displayTimestamp in real time\n const [timerId, setTimer] = useState(null);\n // for input labels\n const [htmlId] = useState(uniqueId('datetimepicker-'));\n const [useMobileInputs] = useState(isMobile() && dateTimeInputIsSupported());\n const openPickerRef = useRef();\n const inputRef = useRef();\n const alertRef = useRef();\n\n const translationSettings = { lng: lang };\n\n useEffect(() => {\n Object.keys(translations).forEach(language =>\n i18next.addResourceBundle(language, 'translation', translations[lang]),\n );\n }, []);\n\n useEffect(() => {\n moment.locale(lang);\n }, [lang]);\n\n const nowSelected = timestamp === null;\n useEffect(() => {\n if (nowSelected) {\n changeDisplayTimestamp(moment().valueOf());\n } else {\n // clear timer\n if (timerId) {\n clearInterval(timerId);\n setTimer(null);\n }\n changeDisplayTimestamp(timestamp);\n }\n }, [timestamp]);\n\n // set timer to update displayTimestamp when minute changes if nowSelected\n useEffect(() => {\n if (!nowSelected) {\n return undefined;\n }\n if (timerId) {\n clearInterval(timerId);\n }\n const newId = setInterval(() => {\n const now = moment().valueOf();\n const sameMinute = moment(displayTimestamp).isSame(now, 'minute');\n if (!sameMinute) {\n clearInterval(newId);\n setTimer(null);\n changeDisplayTimestamp(now);\n }\n }, 5000);\n setTimer(newId);\n return () => clearInterval(newId);\n }, [displayTimestamp]);\n\n const prevIsOpenRef = useRef();\n useEffect(() => {\n prevIsOpenRef.current = isOpen;\n });\n\n // param date is timestamp\n const getDateDisplay = date => {\n const time = moment(date);\n let formatted;\n if (time.isSame(moment(), 'day')) {\n formatted = i18next.t('today', translationSettings);\n } else if (time.isSame(moment().add(1, 'day'), 'day')) {\n formatted = i18next.t('tomorrow', translationSettings);\n } else {\n formatted = time.format('dd D.M.');\n }\n formatted = `${formatted.charAt(0).toUpperCase()}${formatted.slice(1)}`;\n return formatted;\n };\n\n // param time is timestamp\n const getTimeDisplay = time => {\n return moment(time).format('HH:mm');\n };\n\n const selectedMoment = moment(displayTimestamp);\n const timeSelectStartTime = moment(displayTimestamp).startOf('day').valueOf();\n let timeChoices = [];\n const current = moment(timeSelectStartTime);\n while (current.isSame(timeSelectStartTime, 'day')) {\n timeChoices.push(current.valueOf());\n if (isMobile()) {\n current.add(15, 'minutes');\n } else {\n current.add(1, 'minutes');\n }\n }\n if (timestamp === null) {\n // if time is set to now\n // add times in 5 min intervals for next 30 mins\n const fiveMinutes = 1000 * 60 * 5;\n const nextFiveMin = Math.ceil(displayTimestamp / fiveMinutes) * fiveMinutes;\n const timesToAdd = Array(7)\n .fill()\n .map((_, i) => nextFiveMin + i * fiveMinutes);\n const closestIndexAfter = timeChoices\n .map(t => displayTimestamp - t)\n .findIndex(t => t <= 0);\n timeChoices.splice(closestIndexAfter, 0, ...timesToAdd);\n timeChoices = Array.from(new Set(timeChoices)); // remove duplicates\n }\n\n const dateSelectStartTime = moment()\n .startOf('day')\n .hour(selectedMoment.hour())\n .minute(selectedMoment.minute())\n .valueOf();\n const dateChoices = Array(serviceTimeRange)\n .fill()\n .map((_, i) => moment(dateSelectStartTime).add(i, 'day').valueOf());\n\n function showScreenreaderCloseAlert() {\n if (alertRef.current) {\n alertRef.current.innerHTML = i18next.t(\n 'accessible-closed',\n translationSettings,\n );\n setTimeout(() => {\n alertRef.current.innerHTML = null;\n }, 100);\n }\n }\n\n function showScreenreaderOpenAlert() {\n if (alertRef.current) {\n alertRef.current.innerHTML = i18next.t(\n 'accessible-opened',\n translationSettings,\n );\n setTimeout(() => {\n alertRef.current.innerHTML = null;\n }, 100);\n }\n }\n\n function renderOpen() {\n if (useMobileInputs) {\n return (\n isOpen && (\n <MobilePickerModal\n departureOrArrival={departureOrArrival}\n onNowClick={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n onNowClick();\n }}\n lang={lang}\n color={color}\n onSubmit={(newTimestamp, newDepartureOrArrival) => {\n onModalSubmit(newTimestamp, newDepartureOrArrival);\n changeOpen(false);\n showScreenreaderCloseAlert();\n }}\n onCancel={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n if (onClose) {\n onClose();\n }\n }}\n getTimeDisplay={getTimeDisplay}\n timeZone={timeZone}\n timestamp={displayTimestamp}\n getDateDisplay={getDateDisplay}\n dateSelectItemCount={serviceTimeRange}\n getDisplay={getTimeDisplay}\n fontWeights={fontWeights}\n />\n )\n );\n }\n\n return (\n <>\n <div\n className={`${styles['datetimepicker-open-container']} ${\n !isOpen ? styles.hidden : ''\n }`}\n >\n <div\n className={\n isOpen\n ? `${styles['top-row-container']} datetimepicker-top-row`\n : `${styles.hidden} datetimepicker-top-row`\n }\n >\n {' '}\n <span role=\"alert\" className={styles['sr-only']} ref={alertRef} />\n <span />\n {/* This empty span prevents a weird focus bug on chrome */}\n <span className={styles['departure-or-arrival-container']}>\n <label\n htmlFor={`${htmlId}-departure`}\n className={`${styles['radio-textbutton-label']}\n ${\n styles[\n departureOrArrival === 'departure' ? 'active' : undefined\n ]\n }`}\n >\n {i18next.t('departure', translationSettings)}\n <input\n id={`${htmlId}-departure`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"departure\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onDepartureClick();\n }}\n checked={departureOrArrival === 'departure'}\n />\n </label>\n <label\n htmlFor={`${htmlId}-arrival`}\n className={`${styles['radio-textbutton-label']}\n ${\n styles[\n departureOrArrival === 'arrival' ? 'active' : undefined\n ]\n }`}\n >\n {i18next.t('arrival', translationSettings)}\n <input\n id={`${htmlId}-arrival`}\n name=\"departureOrArrival\"\n type=\"radio\"\n value=\"arrival\"\n className={styles['radio-textbutton']}\n onChange={() => {\n onArrivalClick();\n }}\n checked={departureOrArrival === 'arrival'}\n />\n </label>\n </span>\n <button\n id={`${htmlId}-now`}\n type=\"button\"\n className={styles['departure-now-button']}\n onClick={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n if (onClose) {\n onClose();\n }\n onNowClick();\n }}\n ref={inputRef}\n >\n {i18next.t('departure-now', translationSettings)}\n </button>\n <span className={styles['right-edge']}>\n <button\n type=\"button\"\n className={styles['close-button']}\n aria-controls={`${htmlId}-root`}\n aria-expanded=\"true\"\n onClick={() => {\n changeOpen(false);\n showScreenreaderCloseAlert();\n if (onClose) {\n onClose();\n }\n }}\n >\n <span className={styles['close-icon']}>\n <Icon img=\"close\" color={color} />\n </span>\n <span className={styles['sr-only']}>\n {i18next.t('accessible-close', translationSettings)}\n </span>\n </button>\n </span>\n </div>\n <div\n className={\n isOpen\n ? `${styles['picker-container']}`\n : `${styles.hidden} datetimepicker-top-row`\n }\n >\n <span className={styles['combobox-left']}>\n <DesktopDatetimepicker\n value={displayTimestamp}\n onChange={newValue => {\n onDateChange(newValue);\n }}\n getDisplay={getDateDisplay}\n timeChoices={dateChoices}\n validate={() => null}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['date-input-icon']}`}\n >\n <Icon img=\"calendar\" color={color} />\n </span>\n }\n id={`${htmlId}-date`}\n label={i18next.t('date', translationSettings)}\n disableTyping\n timeZone={timeZone}\n datePicker\n />\n </span>\n <span className={styles['combobox-right']}>\n <DesktopDatetimepicker\n value={displayTimestamp}\n onChange={newValue => {\n onTimeChange(newValue);\n }}\n getDisplay={getTimeDisplay}\n timeChoices={timeChoices}\n icon={\n <span\n className={`${styles['combobox-icon']} ${styles['time-input-icon']}`}\n >\n <Icon img=\"time\" color={color} />\n </span>\n }\n id={`${htmlId}-time`}\n label={i18next.t('time', translationSettings)}\n timeZone={timeZone}\n translationSettings={translationSettings}\n />\n </span>\n </div>\n </div>\n <span className={isOpen ? '' : styles.hidden}>{embedWhenOpen}</span>\n <div className={isOpen ? 'datetimepicker-bottom-row-open' : ''} />\n </>\n );\n }\n\n return (\n <fieldset\n className={styles['dt-datetimepicker']}\n id={`${htmlId}-root`}\n style={{\n '--color': `${color}`,\n '--font-weight-medium': fontWeights.medium,\n }}\n >\n <legend className={styles['sr-only']}>\n {i18next.t('accessible-title', translationSettings)}\n </legend>\n <span className={styles['sr-only']}>\n {i18next.t('accessible-update-instructions', translationSettings)}\n </span>\n <div\n className={\n !isOpen\n ? `${styles['top-row-container']} ${styles.closed} datetimepicker-top-row`\n : `${styles.hidden} datetimepicker-top-row`\n }\n >\n <label className={styles['label-open']} htmlFor={`${htmlId}-open`}>\n <span className={styles['time-icon']}>\n <Icon img=\"time\" color={color} />\n </span>\n <span className={styles['sr-only']}>\n {i18next.t('accessible-open', translationSettings)}\n </span>\n <span role=\"alert\" className={styles['sr-only']} ref={alertRef} />\n <button\n id={`${htmlId}-open`}\n type=\"button\"\n className={`${styles.textbutton} ${styles.active} ${styles['open-button']}`}\n aria-controls={`${htmlId}-root`}\n aria-expanded=\"false\"\n onClick={() => {\n changeOpen(true);\n showScreenreaderOpenAlert();\n if (onOpen) {\n onOpen();\n }\n }}\n ref={openPickerRef}\n >\n <span>\n {nowSelected && departureOrArrival === 'departure' ? (\n i18next.t('departure-now', translationSettings)\n ) : (\n <>\n {i18next.t(\n departureOrArrival === 'departure'\n ? 'departure'\n : 'arrival',\n translationSettings,\n )}\n {` ${\n moment().isSame(moment(displayTimestamp), 'day')\n ? ''\n : getDateDisplay(displayTimestamp).toLowerCase()\n } ${getTimeDisplay(displayTimestamp)}`}\n </>\n )}\n </span>\n <span className={styles['dropdown-icon']}>\n <Icon img=\"arrow-dropdown\" color={color} />\n </span>\n </button>\n </label>\n <span className={styles['right-edge']}>{embedWhenClosed}</span>\n </div>\n <div />\n {renderOpen()}\n </fieldset>\n );\n}\n\nDatetimepicker.propTypes = {\n timestamp: PropTypes.number,\n timeZone: PropTypes.string,\n onTimeChange: PropTypes.func.isRequired,\n onDateChange: PropTypes.func.isRequired,\n departureOrArrival: PropTypes.oneOf(['departure', 'arrival']).isRequired,\n onNowClick: PropTypes.func.isRequired,\n onDepartureClick: PropTypes.func.isRequired,\n onArrivalClick: PropTypes.func.isRequired,\n embedWhenClosed: PropTypes.node,\n embedWhenOpen: PropTypes.node,\n lang: PropTypes.string.isRequired,\n color: PropTypes.string,\n onModalSubmit: PropTypes.func.isRequired,\n fontWeights: PropTypes.shape({\n medium: PropTypes.number.isRequired,\n }).isRequired,\n serviceTimeRange: PropTypes.number.isRequired,\n onOpen: PropTypes.func,\n onClose: PropTypes.func,\n openPicker: PropTypes.bool,\n};\n\nDatetimepicker.defaultProps = {\n timestamp: null,\n embedWhenClosed: null,\n embedWhenOpen: null,\n color: '#007ac9',\n timeZone: 'Europe/Helsinki',\n onOpen: null,\n onClose: null,\n openPicker: undefined,\n};\n\nexport default Datetimepicker;\n","/**\n * Detect if input type=\"date\" and type=\"time\" are supported in by the browser\n *\n * @return {boolean}\n */\nfunction dateTimeInputIsSupported() {\n if (typeof window === 'undefined' || window === null) {\n return false;\n }\n const elem = document.createElement('input');\n elem.type = 'date';\n if (elem.type !== 'date') {\n return false;\n }\n elem.type = 'time';\n if (elem.type !== 'time') {\n return false;\n }\n return true;\n}\n\nexport default dateTimeInputIsSupported;\n","import PropTypes from 'prop-types';\nimport React, { useState, useEffect } from 'react';\nimport moment from 'moment-timezone';\nimport debounce from 'lodash/debounce';\nimport Datetimepicker from './helpers/Datetimepicker';\n\n/**\n * This component renders an input to choose a date and time. Renders separate input fields for date and time selection. Values for timestamp and arriveBy correspond to Digitransit query params time and arriveBy. This component will display a native date input on mobile and a custom one for desktop. Mobile detection is done by parsing user agent.\n *\n * @alias Datetimepicker\n *\n * @param {Object} props\n *\n * @param {boolean} props.realtime Determine if selected time should be updated in realtime when 'now' is selected.\n * @param {Number} props.initialTimestamp Initial value for selected time. Unix timestamp in seconds. Updating this will change timepicker value but the correct value is kept in component state even if this is not updated.\n * @param {boolean} props.initialArriveBy Initial value for arriveBy. Determines if picker is in arrival mode (true) or departure mode (false). Correct value is kept in component state even if this is not updated. Changing this will also trigger change in the component.\n * @param {function} props.onTimeChange Called with (time, arriveBy) when time input changes. time is number timestamp in seconds, arriveBy is boolean\n * @param {function} props.onDateChange Called with (time, arriveBy) when date input changes. time is number timestamp in seconds, arriveBy is boolean\n * @param {function} props.onNowClick Called when \"depart now\" button is clicked. time is current input value in seconds\n * @param {function} props.onDepartureClick Called with (time) when \"departure\" button is clicked. time is current input value in seconds\n * @param {function} props.onArrivalClick Called with (time) when \"arrival\" button is clicked. time is current input value in seconds\n * @param {node} props.embedWhenClosed JSX element to render in the corner when input is closed\n * @param {node} props.embedWhenOpen JSX element to render when input is open\n * @param {string} props.lang Language selection. Default 'en'\n * @param {number} props.serviceTimeRange Determine number of days shown in timepicker. Optional. default is 30.\n * @param {function} props.onOpen Determine what to do when timepicker is open. Optional. no default implementation.\n * @param {function} props.onClose Determine what to do when timepicker is closed. Optional. no default implementation.\n * @param {function} props.openPicker Determine if timepicker should be open in intial render. Optional. Default is undefined.\n * @example\n * <Datetimepicker\n * realtime={true}\n * initialTimestamp={1590133823}\n * initialArriveBy={false}\n * onTimeChange={(time, arriveBy) => changeUrl(time, arriveBy)}\n * onDateChange={(time, arriveBy) => changeUrl(time, arriveBy)}\n * onNowClick={(time) => changeUrl(undefined, undefined)}\n * onDepartureClick={(time) => changeUrl(time, 'true')}\n * onArrivalClick={(time) => changeUrl(time, undefined)}\n * embedWhenClosed={<button />}\n * lang={'en'}\n * serviceTimeRange={15}\n * />\n */\nfunction DatetimepickerStateContainer({\n realtime,\n initialArriveBy,\n initialTimestamp,\n onDepartureClick,\n onArrivalClick,\n onTimeChange,\n onDateChange,\n onNowClick,\n embedWhenClosed,\n embedWhenOpen,\n lang,\n color,\n timeZone,\n fontWeights,\n serviceTimeRange,\n onOpen,\n onClose,\n openPicker,\n}) {\n moment.locale(lang);\n moment.tz.setDefault(timeZone);\n const initialNow = realtime ? null : moment().valueOf();\n const [timestamp, changeTimestampState] = useState(\n initialTimestamp ? initialTimestamp * 1000 : initialNow,\n );\n const [departureOrArrival, changeDepartureOrArrival] = useState(\n initialArriveBy === true ? 'arrival' : 'departure',\n );\n\n // update state if props change\n useEffect(() => {\n const bothNull = timestamp === null && initialTimestamp === undefined;\n const oneNull = timestamp === null || initialTimestamp === undefined;\n const sameTime = Math.round(timestamp / 1000) === initialTimestamp;\n const timestampChanged = !bothNull && (oneNull || !sameTime);\n if (timestampChanged) {\n if (initialTimestamp === undefined) {\n changeTimestampState(null);\n } else {\n changeTimestampState(initialTimestamp * 1000);\n }\n }\n if (!initialArriveBy === (departureOrArrival === 'arrival')) {\n changeDepartureOrArrival(\n initialArriveBy === true ? 'arrival' : 'departure',\n );\n }\n }, [initialTimestamp, initialArriveBy]);\n\n const timeChanged = debounce(newTime => {\n if (newTime === null) {\n changeTimestampState(moment().valueOf());\n onTimeChange(\n Math.round(moment().valueOf() / 1000),\n departureOrArrival === 'arrival',\n );\n return;\n }\n changeTimestampState(newTime);\n onTimeChange(Math.round(newTime / 1000), departureOrArrival === 'arrival');\n }, 10);\n\n const dateChanged = debounce(newDate => {\n if (newDate === null) {\n changeTimestampState(moment().valueOf());\n onDateChange(\n Math.round(moment().valueOf() / 1000),\n departureOrArrival === 'arrival',\n );\n return;\n }\n changeTimestampState(newDate);\n onDateChange(Math.round(newDate / 1000), departureOrArrival === 'arrival');\n }, 10);\n\n const nowClicked = () => {\n changeDepartureOrArrival('departure');\n const newTimestamp = realtime ? null : moment().valueOf();\n changeTimestampState(newTimestamp);\n onNowClick(Math.round(newTimestamp / 1000));\n };\n\n const departureClicked = () => {\n let changed = false;\n let newTime = timestamp;\n if (timestamp === null) {\n const now = moment().valueOf();\n changeTimestampState(now);\n newTime = now;\n changed = true;\n }\n if (departureOrArrival !== 'departure') {\n changeDepartureOrArrival('departure');\n changed = true;\n }\n if (changed) {\n onDepartureClick(Math.round(newTime / 1000));\n }\n };\n\n const arrivalClicked = () => {\n let changed = false;\n let newTime = timestamp;\n if (timestamp === null) {\n const now = moment().valueOf();\n changeTimestampState(now);\n newTime = now;\n changed = true;\n }\n if (departureOrArrival !== 'arrival') {\n changeDepartureOrArrival('arrival');\n changed = true;\n }\n if (changed) {\n onArrivalClick(Math.round(newTime / 1000));\n }\n };\n const onModalSubmit = (time, mode) => {\n changeTimestampState(time);\n changeDepartureOrArrival(mode);\n onTimeChange(Math.round(time / 1000), mode === 'arrival', true);\n };\n\n return (\n <Datetimepicker\n timestamp={timestamp}\n onTimeChange={timeChanged}\n onDateChange={dateChanged}\n departureOrArrival={departureOrArrival}\n onNowClick={nowClicked}\n onDepartureClick={departureClicked}\n onArrivalClick={arrivalClicked}\n embedWhenClosed={embedWhenClosed}\n embedWhenOpen={embedWhenOpen}\n lang={lang}\n color={color}\n timeZone={timeZone}\n onModalSubmit={onModalSubmit}\n fontWeights={fontWeights}\n serviceTimeRange={serviceTimeRange}\n onOpen={onOpen}\n onClose={onClose}\n openPicker={openPicker}\n />\n );\n}\n\nDatetimepickerStateContainer.propTypes = {\n realtime: PropTypes.bool,\n initialTimestamp: PropTypes.number,\n initialArriveBy: PropTypes.bool,\n onDepartureClick: PropTypes.func.isRequired,\n onArrivalClick: PropTypes.func.isRequired,\n onTimeChange: PropTypes.func.isRequired,\n onDateChange: PropTypes.func.isRequired,\n onNowClick: PropTypes.func.isRequired,\n embedWhenClosed: PropTypes.node,\n embedWhenOpen: PropTypes.node,\n lang: PropTypes.string,\n color: PropTypes.string,\n timeZone: PropTypes.string,\n fontWeights: PropTypes.shape({\n medium: PropTypes.number,\n }),\n serviceTimeRange: PropTypes.number,\n onOpen: PropTypes.func,\n onClose: PropTypes.func,\n openPicker: PropTypes.bool,\n};\n\nDatetimepickerStateContainer.defaultProps = {\n realtime: false,\n initialArriveBy: undefined,\n initialTimestamp: undefined,\n embedWhenClosed: null,\n embedWhenOpen: null,\n lang: 'en',\n color: '#007ac9',\n timeZone: 'Europe/Helsinki',\n fontWeights: {\n medium: 500,\n },\n onOpen: null,\n onClose: null,\n openPicker: undefined,\n serviceTimeRange: 30,\n};\n\nexport default DatetimepickerStateContainer;\n"],"names":["_arrayLikeToArray","arr","len","length","i","arr2","Array","_slicedToArray","isArray","arrayWithHoles","r","l","t","Symbol","iterator","e","n","u","a","f","o","call","next","Object","done","push","value","iterableToArrayLimit","minLen","arrayLikeToArray","prototype","toString","slice","constructor","name","from","test","unsupportedIterableToArray","TypeError","nonIterableRest","parseTypedTime","typedValue","actualValue","split","every","Number","isInteger","validateClock","hours","minutes","hoursValid","isNaN","minutesValid","validateInput","inputValue","includes","_inputValue$split2","startsWith","values","_ref","concat","_ref2","_ref3","_ref4","substring","getTs","currentTimestamp","trimmed","trim","match","splitter","moment","valueOf","DesktopDatetimepicker","onChange","getDisplay","timeChoices","id","label","icon","disableTyping","timeZone","datePicker","translationSettings","tz","setDefault","_useState2","useState","displayValue","changeDisplayValue","_useState4","typing","setTyping","_useState6","showAllOptions","setShowAllOptions","_useState8","invalidInput","setinvalidInput","useEffect","handleTimestamp","newValue","asNumber","isValid","options","map","closestOptions","filter","closestOption","reduce","b","Math","abs","undefined","inputId","labelId","ariaError","i18next","React","createElement","className","styles","htmlFor","Select","ariaLiveMessages","guidance","context","isDisabled","onFilter","onFocus","itemLabel","time","currentTime","format","ts","components","IndicatorsContainer","cx","classNamePrefix","onInputChange","action","str","valid","isinvalidInput","validated","noOptionsMessage","filterOption","option","input","_input$split$","completeInput","isMod15","minuteInput","inputH","inputM","optH","optM","total","filterOptions","hour","isValidHour","comp","controlShouldRenderValue","tabSelectsValue","placeholder","target","select","onBlur","onKeyDown","key","isSearchable","css","ref","insertAt","document","head","getElementsByTagName","style","type","firstChild","insertBefore","appendChild","styleSheet","cssText","createTextNode","process","env","NODE_ENV","propTypes","PropTypes","number","isRequired","func","arrayOf","string","node","bool","shape","lng","defaultProps","translations","de","today","tomorrow","arrival","date","departure","ready","cancel","en","fi","sv","isMobile","userAgent","navigator","vendor","window","opera","_objectWithoutProperties","source","excluded","sourceKeys","keys","indexOf","objectWithoutPropertiesLoose","getOwnPropertySymbols","sourceSymbolKeys","propertyIsEnumerable","MobileDatepicker","itemCount","startTime","open","changeOpen","scrollRef","useRef","dateChoices","fill","_","add","scrollIndex","findIndex","useLayoutEffect","current","scrollTop","nativeInput","toLowerCase","Autosuggest","suggestions","getSuggestionValue","s","renderSuggestion","onSuggestionsFetchRequested","shouldRenderSuggestions","inputProps","readOnly","focusInputOnSuggestionClick","onSuggestionsClearRequested","renderSuggestionsContainer","containerProps","children","otherRefs","_excluded","assign","tabIndex","elem","theme","MobileTimepicker","changeInputValue","timeInputRef","focus","inputMode","maxLength","setSelectionRange","event","charAt","actual","timestamp","MobilePickerModal","departureOrArrival","onNowClick","lang","color","onSubmit","onCancel","getTimeDisplay","dateSelectItemCount","getDateDisplay","fontWeights","displayTimestamp","changeTimestamp","departureOrArrivalCurrent","changeDepartureOrArrival","htmlId","uniqueId","dateSelectStartTime","startOf","minute","Modal","appElement","querySelector","isOpen","overlayClassName","medium","onClick","checked","Icon","img","Datetimepicker","onTimeChange","onDateChange","onDepartureClick","onArrivalClick","embedWhenClosed","embedWhenOpen","onModalSubmit","serviceTimeRange","onOpen","onClose","openPicker","changeDisplayTimestamp","timerId","setTimer","useMobileInputs","dateTimeInputIsSupported","openPickerRef","inputRef","alertRef","forEach","language","addResourceBundle","locale","nowSelected","clearInterval","newId","setInterval","now","isSame","prevIsOpenRef","formatted","toUpperCase","selectedMoment","timeSelectStartTime","fiveMinutes","nextFiveMin","ceil","timesToAdd","closestIndexAfter","splice","Set","showScreenreaderCloseAlert","innerHTML","setTimeout","hidden","closed","role","textbutton","active","Fragment","newTimestamp","newDepartureOrArrival","validate","DatetimepickerStateContainer","realtime","initialArriveBy","initialTimestamp","initialNow","changeTimestampState","bothNull","oneNull","sameTime","round","timeChanged","debounce","newTime","dateChanged","newDate","nowClicked","departureClicked","changed","arrivalClicked","mode","dateTimeCombined","init","resources","oneOf","fallbackLng","defaultNS","interpolation","escapeValue"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitransit-component/digitransit-component-datetimepicker",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "digitransit-component datetimepicker module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build:index": "ENV=production NAME=digitransit-component-datetimepicker webpack --config ../webpack.config.babel.js && yarn run docs",
|
|
15
|
-
"build:test": "babel test.js --presets=@babel/preset-react,@babel/preset-env --plugins=@babel/plugin-
|
|
15
|
+
"build:test": "babel test.js --presets=@babel/preset-react,@babel/preset-env --plugins=@babel/plugin-transform-class-properties,@babel/plugin-transform-numeric-separator --out-file test.generated",
|
|
16
16
|
"watch": "ENV=development NAME=digitransit-component-datetimepicker webpack --watch --config ../webpack.config.babel.js",
|
|
17
17
|
"clean": "rm -rf ./lib ./node_modules",
|
|
18
18
|
"test": "mocha -r esm test.generated",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"react-modal": "~3.11.2",
|
|
43
43
|
"react-select": "5.8.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "13d8973aa724ccbc79b554b7af517a07b09341d2"
|
|
46
46
|
}
|