{"version":3,"sources":["utils/cookies.ts","context/NiraContext.tsx","components/cookies/toggleCookieModal/index.ts","components/cookies/toggleCookieModal/ToggleCookieModal.component.tsx","hooks/clickOutside/index.ts","hooks/clickOutside/UseClickOutside.hook.tsx","components/button/index.ts","components/button/Button.component.tsx","components/dropdown/index.ts","components/dropdown/Dropdown.component.tsx","components/languageSwitcher/LanguageSwitcher.component.tsx","components/languageSwitcher/index.ts","components/misc/Loader.tsx","img/partners/safecote-logo-white.png","utils/Configuration.ts","img/partners/gaist-logo-white.png","utils/fetch.ts","utils/LoginManager.ts","pages/Login/Login.tsx","utils/Api.ts","pages/maps/Maps.types.ts","components/map/MapConstants.tsx","components/map/vectorlayers/NiraAlertsVectorTileLayers.tsx","components/map/vectorlayers/NiraVectorTileLayers.tsx","components/map/MapComponent.tsx","components/map/utils/HighlightFeature.tsx","img/ol/arrow.png","components/mapSidebar/SidebarItem.tsx","components/map/overlay/Legend/LegendWrapper/LegendWrapper.component.tsx","components/map/overlay/Legend/LegendWrapper/index.ts","components/map/overlay/Legend/GradientLegend/GradientLegend.component.tsx","components/timeline/Timeline.component.tsx","components/timeline/index.ts","utils/date.ts","components/datepicker/Datepicker.view.tsx","components/datepicker/MobileDatepicker.tsx","components/datepicker/index.ts","components/datepicker/Datepicker.component.tsx","components/map/overlay/ModeDescription.tsx","components/map/overlay/TimeSlider/TimeSlider.component.tsx","components/map/overlay/TimeSlider/index.ts","components/map/layer/NiraLinearScaleVectorLayer.tsx","components/map/overlay/DateTimePicker/DateTimePicker.component.tsx","components/map/overlay/DateTimePicker/index.ts","components/map/layer/NiraAirTemperatureVectorLayer.tsx","components/map/overlay/Legend/FrictionLegend/FrictionLegend.component.tsx","components/map/layer/NiraFrictionVectorLayer.tsx","components/map/layer/NiraHydroplaningAlertsVectorLayer.tsx","components/map/layer/icons/Aquaplaning.png","components/map/layer/NiraRoughnessVectorLayer.tsx","components/map/layer/NiraRscVectorLayerUtils.tsx","components/map/layer/NiraRscFrictionVectorLayer.tsx","components/map/overlay/Legend/RoadConditionLegend/RoadConditionLegend.component.tsx","components/map/layer/NiraRscRoadConditionVectorLayer.tsx","components/map/layer/NiraSeverePotholeAlertsVectorLayer.tsx","components/map/layer/icons/Pothole.png","components/map/layer/NiraSevereRoughnessAlertsVectorLayer.tsx","components/map/layer/icons/Bumpyroad.png","components/map/layer/NiraSlipperyAlertsVectorLayer.tsx","components/map/layer/icons/Slipperyroad.png","components/map/overlay/CheckBox.tsx","components/map/overlay/AlertsSelector.tsx","components/map/overlay/RadioButton.tsx","components/map/overlay/LayerSwitcher.tsx","img/icons/arrow-right.svg","components/mapActions/MapActions.tsx","components/map/overlay/AlertsSideMenuDetails.tsx","img/nira-logo-white-pms.svg","components/sidebar/Sidebar.tsx","img/icon-close.png","components/mapSidebar/FeatureMapItem.tsx","components/mapSidebar/MapSidebar.tsx","img/icons/double-arrow-left.svg","img/icons/double-arrow-right.svg","components/sidebar/SidebarToggle.tsx","components/mapSidebar/MapToggleSidebar.tsx","permissions.ts","components/restricted/Restricted.component.tsx","components/restricted/index.ts","components/userSidebar/UserSidebar.tsx","img/icons/car-driving-on-road.svg","pages/maps/LocationUtil.tsx","pages/maps/buttons/TrackButton.tsx","img/icons/location.svg","img/icons/region.svg","img/nira-logo-white.svg","pages/maps/Maps.tsx","pages/maps/MapUtil.tsx","components/map/overlay/ToggleButton.tsx","components/modal/index.ts","components/modal/Modal.component.tsx","components/cookies/modal/CookieModal.component.tsx","components/cookies/modal/index.ts","App.tsx","reportWebVitals.ts","i18n.ts","index.tsx"],"names":["COOKIE_URL","getCookie","async","cookie","Http","key","url","value","deleteCookie","NiraContext","createContext","NiraContextProvider","_ref","children","showCookieModal","setShowCookieModal","useState","useEffect","_jsx","Provider","ToggleCookieModal","className","niraContext","useContext","onClick","useClickOutside","handleClickOutside","ref","useRef","handleClick","e","_ref$current","current","contains","target","document","addEventListener","removeEventListener","Button","forwardRef","props","_props$variant","_Fragment","concat","active","color","variant","style","Dropdown","_selected$selectedLab","options","defaultValue","onSelect","buttonVariant","expandedDirection","open","setOpen","selected","setSelected","label","outsideRef","toggleOpen","_jsxs","map","option","handleSelect","selectedLabel","languages","language","languageCode","generateFlagOption","country","countryCode","LanguageSwitcher","_languageOptions$find","i18n","useTranslation","languageOptions","useMemo","_ref2","find","_ref3","changeLanguage","selectedOption","cookiePreferences","parsedCookiePreferences","JSON","parse","preferences","localStorage","setItem","Loader","React","constructor","super","this","state","componentDidMount","render","Configuration","AWS_REGION","process","AWS_USER_POOL","AWS_CLIENT_ID","GOOGLE_ANALYTICS_ID","BASE_URL","RSA_API_BASE_URL","RSC_API_BASE_URL","PARTNER_LOGOS","name","logo","permission","SafecoteLogo","request","Capacitor","isNativePlatform","axios","fetchVectorTiles","token","getItem","headers","Authorization","indexOf","Auth","currentSession","getIdToken","getJwtToken","mode","credentials","fetch","Amplify","configure","aws_project_region","aws_cognito_identity_pool_id","aws_cognito_region","aws_user_pools_id","aws_user_pools_web_client_id","oauth","identityPoolId","region","userPoolId","userPoolWebClientId","LoginManagerInstance","eventEmitter","session","userData","EventEmitter","setMaxListeners","undefined","addDataListener","callback","addListener","removeDataListener","removeListener","getSession","login","method","data","withCredentials","metaData","permissions","checkSignIn","res","currentAuthenticatedUser","signInUserSession","email","attributes","loginRes","getUserData","displayName","display_name","getMetaData","mapHome","layers","isOem","getPermissions","emit","setTileAccessTokenIfNative","error","response","console","log","tokens","getCurrentUserData","signOut","global","removeItem","signIn","username","password","_loginRes$data","_user$attributes2","_user$attributes","user","shouldResetPassword","challengeName","challenge","challengeParam","userSession","type","isErrorMessage","message","updatePasswordChallenge","newPassword","_loginRes$data2","_this$userData$user","_this$userData$user$a","completeNewPassword","statusCode","forgotPasswordSubmit","userName","verificationCode","sendForgotPasswordRequest","forgotPassword","SignIn","showLogInModal","signupstep","oemExpanded","acceptTerms","loading","success","callSubmitNewPassword","bind","callSetNewPassword","match","params","page","title","t","setState","verifyemail","test","String","toLowerCase","handleSubmitLogin","preventDefault","result","_result$challenge","newpassword","handleSubmitSignUp","handleSubmitSignUpDetails","company","position","signUpOem","handleSubmitForgotPassword","_this","setTimeout","body","messageBody","requestHeaders","Headers","set","stringify","errorText","text","status","ok","statusText","raw","resetSignUpData","resend","renderLoginComponent","onSubmit","id","autoFocus","autoComplete","placeholder","onChange","currentTarget","Link","to","display","textAlign","renderResetPasswordComponent","renderEnterNewPasswordComponent","renderSignUpComponent","checked","defaultChecked","Trans","i18nKey","href","rel","renderSignUpDetailsComponent","renderForgotPasswordRequest","renderDoneComponent","contentText","renderComponent","withTranslation","GpsModeDataTrack","clearWatch","initPosition","arguments","length","GpsModeType","GpsModeDefaultNone","None","modeData","locationError","getDevicePixelRatio","window","devicePixelRatio","MAP_TILE_LAYERS","v1","toString","attributions","tileSize","tilePixelRatio","v2","getAlertsVectorTileUrl","vectorLayer","timestamps","rsaApi","rsaApiBundleName","urlType","bundleName","getPointFeature","lat","lon","featureProperties","viewProjection","f","Feature","geometry","Point","transform","setProperties","groupData","zoomLevel","wktReader","WKT","Object","values","reduce","geom","readFeature","getGeometry","getFlatMidpoint","tileId","getTileId","level","degSize","Math","pow","tileY","floor","tileX","getTileLevelForZoomLevel","count","alert","v","amount","createAlertVectorTileLayerSource","VectorTileSource","format","MVT","minZoom","maxZoom","tileLoadFunction","tile","getTileCoord","setLoader","extent","resolution","projection","then","json","arrayBuffer","Error","layerName","features","d","featureProps","alertId","setFeatures","groupFunction","_","segmentStartPointLat","segmentStartPointLon","geometryWkt","getFirstCoordinate","getFormat","readFeatures","featureProjection","visibleFeatures","filterFunction","groupedFeatures","renderedFeature","geo","feature","getProperties","transformLineStringToPointFeature","catch","TileState","ERROR","getVectorTileUrl","guiBackend","MapComponent","Component","markerRef","vectorTileLayer","selectionLayer","alertVectorTileLayers","vectorTileLayerSource","refreshDataTimer","timerStartedAt","createRef","severeRoughness","slippery","severePothole","hydroplaning","attribution","Attribution","collapsible","collapsed","view","View","center","fromLonLat","currentView","zoom","getTileLayer","overlays","interactions","defaults","pinchRotate","controls","defaultControls","rotate","extend","Map","VectorLayer","source","VectorSource","selectedFeatureStyle","setMap","currentGpsMode","Track","highlightFeatureWithBorder","styles","defaultStyles","styleFunction","maxWidth","Array","isArray","max","getStroke","getWidth","forEachSegment","start","end","push","Style","stroke","Stroke","width","forEach","newStyle","getColor","highlightFeatureWithArrows","dx","dy","image","Icon","src","anchor","rotateWithView","rotation","atan2","updateAlertsVectorLayers","entries","alertsVectorLayers","layer","activeAlertsVectorLayers","includes","mountAlertLayer","unMountAlertLayer","shouldComponentUpdate","isEqual","refreshVectorTileLayer","currentVectorLayer","removeVectorTileLayer","addVectorTileLayer","unMountAlertLayers","coordinates","coords","getView","animate","duration","addPositionMarker","activeFeature","alertType","multiDirectional","getOrientedFlatCoordinates","LineString","GeometryLayout","XY","getSource","clear","addFeature","gotToHomeRegion","setTarget","mountAlertLayers","addClickListener","addZoomListener","addViewListener","addRenderListener","startRefreshDataTimer","ResizeObserver","resizeCallback","observe","alertLayer","createAlertsTileLayer","alertsSource","alertsLayer","VectorTileLayer","renderMode","VectorTileRenderType","HYBRID","number","addLayer","removeLayer","updateSize","componentWillUnmount","clearTimeout","shouldRefreshData","startDate","currentDate","wishedIntervalTimeInSeconds","shouldAutoRefresh","setUrl","refresh","Date","createVectorTileLayer","minZoomLevel","maxZoomLevel","tileCoord","replace","filter","roadClass","showRoadClass","functionalRoadClassZoomLevels","valueExtractor","dataToFeatures","getLayers","insertAt","marker","Overlay","offset","element","stopEvent","addOverlay","on","event","getFeaturesAtPixel","pixel","hitTolerance","layerFilter","featureClicked","getZoom","setShowError","toLonLat","getCenter","viewChanged","renderComplete","niraSource","olSource","TileLayer","zIndex","ColorBar","gradient","colors","backgroundImage","left","slice","reverse","index","subIndex","getSubIndex","min","pos","getPositionLeft","leftLabel","rightLabel","SidebarItem","amountText","header","valueString","fixed","toFixed","statusColor","backgroundColor","unit","colorBar","LegendWrapper","GradientLegend","topLabel","bottomLabel","margin","THREE_HOURS","brushInterval","timeMinute","every","Timeline","height","endDate","interval","setBounds","showSelection","svgRef","brushSelection","setBrushSelection","x","scaleTime","domain","rangeRound","brush","brushX","empty","call","attr","onBrushStart","onBrushEnd","startEvent","sourceEvent","selection","d0","invert","abs","getTime","d1","round","move","svg","select","selectAll","remove","tickInterval","getTickInterval","timeHour","ceil","append","g","axisBottom","ticks","tickSize","tickFormat","tickPadding","getHours","getMinutes","locales","en","de","sv","roundToPast10mins","minutes","seconds","milliseconds","monthIsCurrentOrFuture","startOfMonth","DatepickerViewComponent","selectedDate","handleDateSelect","handleHourSelect","handleMinuteSelect","handleMonthChange","handleTodayClick","datesToRender","weekdayLabels","locale","isVisible","setIsVisible","minuteSteps","showTimeSelect","referenceElement","selectedHourElement","selectedMinuteElement","popperElement","update","usePopper","placement","modifiers","enabled","_selectedHourElement$","_selectedMinuteElemen","scrollIntoView","renderMinuteList","step","eachMinuteOfInterval","startOfHour","endOfHour","getMinutesInHour","d2","isSameMinute","renderHourList","getHoursInDay","eachHourOfInterval","startOfDay","endOfDay","isSameHour","renderDateHeader","renderDates","getDate","getMonth","getFullYear","isSameDate","popper","MobileDatepicker","Datepicker","_locale$options3","isVisble","getDateFnsLocale","currentLanguage","_locale$options$weekS","_locale$options","_locale$options$weekS2","_locale$options2","weeksInMonth","eachWeekOfInterval","endOfMonth","weekStartsOn","eachDayOfInterval","lastDayOfWeek","setDate","date","year","month","isMobileOnly","setHours","setMinutes","operator","addMonths","subMonths","ModeDescription","isToday","isSameDay","formatInterval","rangeOptions","TimeSlider","changeMode","rangeLength","setRangeLength","intervalMaxDate","setIntervalMaxDate","intervalMinDate","subMilliseconds","previousMode","setPreviousMode","dropdownOptions","handleChangeMode","useCallback","nextMode","liveModeDateUpdate","timeout","selectedRangeLength","range","handleRangeChanged","roundToNearestMinutes","nearestTo","isFuture","NiraLinearScaleVectorLayer","visibleOem","visibleMaintenance","renderOrderFunction","timeSelectTool","scaleProps","legend","flipLegend","getColors","getValueDomain","endLabel","startLabel","sidebarProps","colorScale","chroma","scale","renderSidebarContent","currentValue","getSidebarHeader","displayUnitInSidebar","isNaN","hex","DateTimePicker","lastTimestamp","NiraAirTemperatureVectorLayer","Number","FrictionLegend","conditions","description","condition","item","short","FRICTION_DESCRIPTIONS","long","limit","semi","good","Infinity","NiraFrictionVectorLayer","friction","keys","a","b","properties","frictionUnit","frictionAverage","frictionMin","frictionMax","numberOfTGPs","standardDeviation","frictionDescription","_this$styles$find","NiraHydroplaningAlertsVectorLayer","icon","size","imgSize","anchorXUnits","anchorYUnits","setScale","NiraRoughnessVectorLayer","roughnessColor","results","acc","tileData","rough","dataProjection","setStyle","roughnessAverage","get","roughnessStateEstimate","ROAD_CONDITION_DESCRIPTIONS","iceSnow","veryWet","wet","dry","AVAILABLE_SIGNAL_TYPES_DESCRIPTIONS","externalWeather","fleetWeather","externalAndFleetWeather","fleetFriction","externalWeatherAndFleetFriction","fleetWeatherAndFriction","all","unknown","getRoadConditionDescription","roadCondition","expectedRoadWeather","expectedFriction","availableInputSources","availableInputSourcesDescription","availableSignalType","expectedRoadConditionDescription","NiraRscFrictionVectorLayer","RoadConditionLegend","NiraRscRoadConditionVectorLayer","NiraSeverePotholeAlertsVectorLayer","NiraSevereRoughnessAlertsVectorLayer","drivingForwardLinkDirection","functionalRoadClass","iriAvg","speedCategoryKmph","NiraSlipperyAlertsVectorLayer","frictionCoefficient","qualityIndex","speedCategory","CheckBox","tabIndex","AlertsSelector","alertVectorLayers","activeAlertVectorLayers","onAlertVectorLayersChanged","RadioButton","FLEET_FRICTION_BUNDLE_NAME","getMaintenanceLayerNames","LayerSwitcher","vectorLayers","layerChanged","createRadioButton","aggregatedLayers","showAggregatedFleetDataTitle","_extends","assign","i","prototype","hasOwnProperty","apply","SvgArrowRight","titleId","xmlns","xmlnsXlink","y","viewBox","xmlSpace","fill","ForwardRef","MapActions","minimized","ArrowIcon","Children","child","AlertsSideMenuDetails","alertLayers","renderAlertLayerContent","Sidebar","AnimatePresence","initial","isOpen","motion","div","exit","transition","bounce","transitionEnd","closeSidebar","alt","ImgLogo","FeatureMapItem","MapSidebar","renderFeatureContent","renderAlertFeatureContent","_this$props$feature","SidebarToggle","openSidebar","renderSidebar","ImgClose","renderOpenButton","ImgOpen","MapToggleSideBar","renderNoSegmentText","FULL_RIGHTS","GPS_TRACK_MODE","verifyPermissions","requiredPermission","userPermissions","Restricted","shouldShow","setShouldShow","UserSidebar","isSidebarOpen","userClicked","closeUserSidebar","getNameInitials","_filteredList$pop","filteredList","split","Boolean","initials","shift","charAt","pop","toUpperCase","renderUserContent","_this$props$userData","_this$props$userData2","_this$props$userData3","_path","ClearWatch","isNative","clearId","setNativeId","setClearId","SvgCarDrivingOnRoad","TrackButton","gpsMode","TrackIcon","MapsPage","resetErrorMessageTimer","mapRef","rscRoadCondition","rscFriction","roughness","temperature","isLoggedIn","activeVectorLayer","permissionToLayer","showZoomError","currentTimeMode","loginChanged","orientationChanged","getCurrentPosition","goToHomeRegion","changeTimeMode","toggleTrackMode","callFindClosestRoadSegment","handleGpsModeChanges","prevState","Geolocation","navigator","geolocation","Promise","resolve","reject","Once","gotPosition","currentPosition","longitude","latitude","failedToGetPosition","setGpsModeError","enableHighAccuracy","trackZoomLevel","gotClearWatch","newGpsState","positionCallback","watchPosition","isResolved","newPosition","currentMapRef","currentMap","getPixelFromCoordinate","metersPerPixel","getResolution","closestRoadSegment","lineStringFeatures","lineStringFeature","setId","getId","addFeatures","convertToVectorSource","getClosestFeatureToCoordinate","findClosestRoadSegment","componentDidUpdate","_prevProps","forceUpdate","currentLayerChanged","closeMapSidebar","activeAlertsLayersChanged","updatedList","elementIndex","isGettingLocation","renderPartnerLogos","partner","some","permissionName","renderGoToHomeRegionButton","HomeRegionIcon","renderTrackSidebar","MapToggleSidebar","renderMapButtons","isMobile","disabled","LocationIcon","filterVectorLayers","allowedLayers","fromEntries","filterAlertLayers","renderMapActions","toISOString","show","CompanyLogo","ToggleButton","Modal","footer","history","createBrowserHistory","CookieBar","setCookiePreferences","analytics","logPageView","ReactGoogleAnalytics","pageview","location","pathname","search","initGoogleAnalytics","initialize","listen","_location","_action","handleSaveClick","cookies","acceptAll","mapValues","expireDate","add","years","expire","setCookie","expires","toUTCString","path","ga","mapUrl","loginUrl","App","authenticated","loginPressed","isValid","Router","Switch","Route","component","exact","LoginPage","CookieModal","reportWebVitals","onPerfEntry","Function","getCLS","getFID","getFCP","getLCP","getTTFB","resources","translation","use","LanguageDetector","initReactI18next","init","fallbackLng","keySeparator","interpolation","escapeValue","detection","order","caches","ReactDOM","StrictMode","getElementById"],"mappings":"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","file":"static/js/main.a7cdaec3.chunk.js","sourcesContent":["import { Http } from '@capacitor-community/http'\n\n// Random URL required when using cookies on native platform.\n// If you need to change the URL ensure it does not exist to avoid sending local cookies to the server\nconst COOKIE_URL = 'https://native.roads.niradynamics.se'\n\nexport const getCookie = async (key: string) => {\n const cookie = await Http.getCookie({ key, url: COOKIE_URL })\n\n if (cookie.value) return cookie.value\n return ''\n}\n\nexport const setCookie = async (key: string, value: string, expire: Date) => {\n return await Http.setCookie({\n key,\n value,\n expires: expire.toUTCString(),\n path: '/',\n url: COOKIE_URL,\n })\n}\n\nexport const deleteCookie = async (key: string) => {\n await Http.deleteCookie({ key, url: COOKIE_URL })\n}\n","import { createContext, useState, useEffect } from 'react'\nimport { NiraContextType } from './NiraContext.types'\nimport { getCookie } from '../utils/cookies'\n\nexport const NiraContext = createContext<NiraContextType | null>(null)\n\nexport const NiraContextProvider = ({\n children,\n}: {\n children: JSX.Element[] | JSX.Element\n}) => {\n const [showCookieModal, setShowCookieModal] = useState(false)\n\n useEffect(() => {\n ;(async () => {\n const cookies = await getCookie('cookiePreferences')\n if (!cookies) {\n setShowCookieModal(true)\n }\n })()\n }, [])\n\n return (\n <NiraContext.Provider\n value={{\n showCookieModal,\n setShowCookieModal,\n }}\n >\n {children}\n </NiraContext.Provider>\n )\n}\n","import { ToggleCookieModal } from './ToggleCookieModal.component'\n\nexport default ToggleCookieModal\n","import { useContext } from 'react'\nimport { ToggleCookieModalComponent } from './ToggleCookieModal.types'\nimport { NiraContext } from '../../../context'\n\nexport const ToggleCookieModal: ToggleCookieModalComponent = ({\n children,\n className,\n}) => {\n const niraContext = useContext(NiraContext)\n return (\n <div\n className={className ?? ''}\n onClick={() => {\n if (niraContext) niraContext.setShowCookieModal(true)\n }}\n >\n {children}\n </div>\n )\n}\n","import { useClickOutside } from './UseClickOutside.hook'\nexport default useClickOutside\n","import { useRef, useEffect } from 'react'\n\nimport { UseClickOutsideHook } from './UseClickOutside.types'\n\nexport const useClickOutside: UseClickOutsideHook = (handleClickOutside) => {\n const ref = useRef<HTMLDivElement | null>(null)\n const handleClick = (e: MouseEvent) => {\n if (ref.current?.contains(e.target as Node)) {\n // Inside element\n return\n }\n // Outside element\n handleClickOutside()\n }\n useEffect(() => {\n document.addEventListener('mousedown', handleClick)\n return () => {\n document.removeEventListener('mousedown', handleClick)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [])\n return ref\n}\n","import { Button } from './Button.component'\n\nexport default Button\n","import { forwardRef } from 'react'\nimport { ButtonProps } from './Button.types'\nimport './Button.scss'\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>((props, ref) => {\n return (\n <>\n <button\n className={`button-base ${props.active ? 'active' : ''}\n color-${props.color} variant-${props.variant ?? 'default'}`}\n onClick={props.onClick}\n style={props.style}\n ref={ref}\n >\n {props.children}\n </button>\n </>\n )\n})\n","import { Dropdown } from './Dropdown.component'\n\nexport type { DropdownOption, DropdownExpandedDirection } from './Dropdown.types'\nexport default Dropdown\n","import React, { useState } from 'react'\nimport { DropdownComponent, DropdownOption } from './Dropdown.types'\nimport useClickOutside from '../../hooks/clickOutside'\nimport Button from '../button'\n\nimport './Dropdown.scss'\n\nexport const Dropdown: DropdownComponent = ({\n options,\n defaultValue,\n onSelect,\n color,\n buttonVariant,\n expandedDirection,\n}) => {\n const [open, setOpen] = useState(false)\n const [selected, setSelected] = useState<DropdownOption>(\n defaultValue ? defaultValue : { label: '', value: null }\n )\n const handleClickOutside = () => setOpen(false)\n const outsideRef = useClickOutside(handleClickOutside)\n\n const toggleOpen = () => setOpen(!open)\n\n const handleSelect = (option: DropdownOption) => {\n setSelected(option)\n onSelect(option)\n toggleOpen()\n }\n return (\n <div className=\"dropdown\">\n <div\n className={`dropdown-content${open ? ' show' : ''} ${color ?? ''} ${\n expandedDirection ?? 'down-right'\n }`}\n ref={outsideRef}\n >\n {options.map((option) => (\n <div\n className={`dropdown-option ${color ?? ''}`}\n onClick={() => handleSelect(option)}\n key={option.value}\n >\n {option.label}\n </div>\n ))}\n </div>\n\n <Button onClick={toggleOpen} color={color} variant={buttonVariant}>\n {selected.selectedLabel ?? selected.label}\n </Button>\n </div>\n )\n}\n","import { useMemo } from 'react'\nimport { LanguageSwitcherComponentProps } from './LanguageSwitcher.types'\nimport Dropdown from '../dropdown'\nimport { useTranslation } from 'react-i18next'\nimport { getCookie } from '../../utils/cookies'\nimport { CookiePreferences } from '../cookies/modal/CookieModal.component'\n\nimport './LanguageSwitcher.scss'\n\nconst languages = [\n { language: 'English', languageCode: 'en' },\n { language: 'German', languageCode: 'de' },\n { language: 'Swedish', languageCode: 'sv' },\n]\nconst generateFlagOption = (country: string, countryCode: string, label: boolean) => (\n <div className=\"language-switcher-option\">\n <div className={`flag ${countryCode}`} />\n {label && <div className=\"language-label\">{country}</div>}\n </div>\n)\n\nexport const LanguageSwitcherComponent: LanguageSwitcherComponentProps = ({\n expandedDirection,\n}) => {\n const { i18n } = useTranslation()\n\n const languageOptions = useMemo(\n () =>\n languages.map(({ language, languageCode }) => ({\n label: generateFlagOption(language, languageCode, true),\n selectedLabel: generateFlagOption(language, languageCode, false),\n value: languageCode,\n })),\n []\n )\n\n return (\n <>\n <Dropdown\n defaultValue={\n languageOptions.find(({ value }) => value === i18n.language) ?? {\n label: 'Choose language',\n value: '',\n }\n }\n color=\"light\"\n buttonVariant=\"text\"\n options={languageOptions}\n onSelect={async (selectedOption) => {\n i18n.changeLanguage(selectedOption.value)\n // Store in local storage for the future if cookie is accepted\n const cookiePreferences = await getCookie('cookiePreferences')\n if (cookiePreferences) {\n const parsedCookiePreferences: CookiePreferences =\n JSON.parse(cookiePreferences)\n\n if (parsedCookiePreferences && parsedCookiePreferences.preferences) {\n localStorage.setItem('i18nextLng', selectedOption.value)\n }\n }\n }}\n expandedDirection={expandedDirection}\n />\n </>\n )\n}\n","import { LanguageSwitcherComponent as LanguageSwitcher } from './LanguageSwitcher.component'\nexport default LanguageSwitcher\n","import * as React from 'react'\nimport './loader.scss'\n\nexport interface LoaderProps {}\n\nexport interface LoaderState {}\n\nclass Loader extends React.Component<LoaderProps, LoaderState> {\n constructor(props: LoaderProps) {\n super(props)\n this.state = {}\n }\n\n componentDidMount() {}\n\n render() {\n return (\n <div className=\"loader\">\n <div>\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n </div>\n )\n }\n}\n\nexport default Loader\n","export default __webpack_public_path__ + \"static/media/safecote-logo-white.31c5a68a.png\";","import GaistLogo from '../img/partners/gaist-logo-white.png'\nimport SafecoteLogo from '../img/partners/safecote-logo-white.png'\n\nexport default class Configuration {\n static readonly AWS_REGION = process.env.REACT_APP_AWS_REGION\n static readonly AWS_USER_POOL = process.env.REACT_APP_AWS_USER_POOL\n static readonly AWS_CLIENT_ID = process.env.REACT_APP_AWS_CLIENT_ID\n\n static readonly GOOGLE_ANALYTICS_ID = process.env.REACT_APP_GOOGLE_ANALYTICS_ID\n\n static readonly BASE_URL = process.env.REACT_APP_API_BASE_URL\n static readonly RSA_API_BASE_URL = process.env.REACT_APP_RSA_API_BASE_URL\n static readonly RSC_API_BASE_URL = process.env.REACT_APP_RSC_API_BASE_URL\n\n static readonly PARTNER_LOGOS: { name: string; permission: string; logo: string }[] = [\n { name: 'Gaist', logo: GaistLogo, permission: 'partnerLogoGaist' },\n { name: 'Safecote', logo: SafecoteLogo, permission: 'partnerLogoSafecote' },\n ]\n}\n","export default \"data:image/png;base64,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R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDoxMGE4NzkzNi1hYTM2LTRiNGYtOTlmMi03MWJlOTc0NjcxZDYiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OWQ3NGUzYWItNzExMS00ZjFhLWE5Y2QtM2ZkZmVlNzlhNjliIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NzI2ZTJiOTctYTRlMi00YWZmLTkwZWYtNTIzZjFlYjEzNDJhIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTWFjIE9TIgogICBHSU1QOlRpbWVTdGFtcD0iMTYzMzM0NTU4NTYxMDQ5NCIKICAgR0lNUDpWZXJzaW9uPSIyLjEwLjI0IgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAgMi4xMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjlkZWQ3YzVjLTkyODAtNGRjNy04NGZkLWE4M2JhNzhlYjY4ZSIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChNYWMgT1MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIxLTEwLTA0VDEzOjA2OjI1KzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PgFPPA4AAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAHdElNRQflCgQLBhlx60/AAAAABmJLR0QA/wD/AP+gvaeTAAAOIElEQVR42u2deZAVxR3H5+0uu8ByCIiAoAQVlMh6XyhE4hU0HqQgeOEdjTfGKIoY4q1UookmaKmU0RJENCgeJKIiGLXU8cDo4AlEJUZcWREEll2W/eSP/q159QK70z0zb/q919+qrgKWnf71r/vb1+9oz3MoKPhBWTs/yFT7Qaa904ZDiZMh09UPvHP9wJvvB96XfuDV+oG3wg+81/3Am+QHXj+nJYeSwRuLO2f8wBvjB97nfuDRSvnWD7zL/aC8wmnNochJ0SnjB95lfuA1t0GK7PKAI4dDkW+fvBM1SdFSpjjtORTrmWJrOUtgUDb4gbeb06JDMa4WlxqSoqVMd1p0KEZivBmRGHV+kOnkNOlQTNuoLmpgRyJGox94NU6bDsW0WvTxA29NRGLgB94wp02HYjt4fxuRFJv8wNvXadOh2FaNpRGJsdYPvG2dJh2KjRh3RCTGq6WoN6AcqAYGAGOAG4E5wPPAUW5kFT4xavzAa4hAjLElQoRuwChgMjADeAOoY/N4A8i40VX45JhqSIr5flBWWQKkGAZ8Q3gscsQojkN4Bz/wFmiS4gM/8PqWyGrxIHpwxCgiclT7gTdDbpnaIsVLpeR+DsxyxChpclSW+YF3hKwe63IcC+v9wHvHD7yT/KCsqsQO2o4YDt+fO/r6gXeQH3jH+IH3Iz/wdihVXThiODg4Yjg4OGI4ODhiWKjYDFAFdAG2BnYE9gRGAj8FzgDOzCo/Aw4FdgG6Ax1KQEftpa0/BA4DRufo5AzR1UhgH2AnoAfQGaiyjRj5UloZUCmD6VSxPt4pAj8OzANeTqjMBU4MMwOInO2B3YHTgVtExleBj8VSuklTyQ3AMuA54CbgQKAiAR0PAh4WfR4q+s5k/bxC2nUXcDVQHkOf7i59+QywVNqqgyagFvgQmA/cC1wKHCyTUHkbMpwCPBtiDHytKdfaEN98ChhhOsseID4oLwLfkS7GtiHvUGAhsC4PsiwTkmwXEynKgQU5dXwB/A2YDTwpxM7G6YZ1tZPZ309YRxuBd4H7gdNyJxNZjRtTHlOrgC5hFdcNuAgIgGbswUNtzH7vpiDTWlmVukUkRiWwRLPu3xrUMzwlPQFcmSPLKAvG1CZgtzCdcxawAjsxuxXZOwDLU5RtKXCgrcSQ1f8cYEOKOlpQcMQA+gIvYDdsJgayhRtlKTHOkq1NmlhYUMQA9gY+w37YTowWcoy0iRhyg7TeAt0UDjHkam4FhYFCIAbAV8D2FhHjRUv0kkuMn1hJDKAr8D6FgwcKhBjIVWB52sQAjrDoAiWXGJ2BtywgRk2u0u4qEEI0osIVBxcQMTYBwywgxn0W6WThZuSrkpVjAsoGslD0sDpPMv2HbOMtUBPDDUUjymD2BbAYdS/+KfClNKw5BqGnADsDZW0MgAq5GQqDBilrsspqlBHpa/nz2hjkn5smMVD2imUR5F8tffARKlR0kUw+y2X73aKresIZTZ8NqYsqlEV9F5QHwiQD3awE7m6j3A4Mya18uqGymoTVZ8r5pOsWBmkvYH+UVXW54SC7TnOffizKgjtXVsPJwHnACcCRwL7AHigL80CgD9A7q3RGBdf3ArYD9gLOB15H31rechDvnyIxehnI3Iyy8B8uv1/WyuDtJP9nADAEOEgG8rnAdbJavSjkqgWOttolBNgGM+vwEuAwg/qqZZA2GMxYqYduomwAZ2NmpT0pRWKMMJD3MSK6mhSsEyFwvIHCPgF6R2zcaQb13mZR50w0kH9qisQYayCvlYnb8kWMPxqcJYbHNPPqNnA5lni2opzivtKU/80CI0bHUibGQs1KXouxgQdr7tebgF0t6iDds9maFIlhsjM4tJSJoWvlvirGBnZE30t3jEUdNF5T9gZCOBgmRIzhBsT4ENihVImhewg+LuZGfqJZ/8UWddAYg23o9ikRoxtm/lErgFNKkRhNmpXsFXMjdbdyvy5gYmwEdk6JGOWoAC0TNANPh5HdESO+Ri5wxMib5fvqiEbKdfKNTqVADN2t1NExN/JDzfovcMQwJsa2xBPR+JEY/cqKmRifa1ZyRYwNrBIXDB2MdcQwI4Z8+5aY/IqagEeAfsVKDN09vk9MqUjEGqvrXrF/AoouE9eVbcR15VhxczlPyhVirc8tswqQGFsZXHi0hjrgcqBdsRFjqsFMMTqmwfiErh0A6BND3eXiKzUe+AvwpjgKJo3UiSHfH0r8SSLeAg4uJmKcaqCEVVGUIKS41sCZ8L0oq5U4t90s28dN5B9WEEPqGGdwvgzTvnuiugvZQoztMAt1bABuQyUry2jM1HsCf8fMw3ayoSIHy+rUQLqwiRgZ8VdLIr1QLSolT7uCJYZU9HAEJdSj/PNvR2WeGIlKQjYEOAQ4DpV+5z5UhGBThHoGaLarHfAb8pNbqqCIkVXXMIMLmLB4CdilkIlRgx0B8q1hhk7jxN1klmVtsI4YUl9PVMRcEplD1gAXEGPuWPKZuxYVTGIrVqKRUEAG1qMWtsNKYmTVewjwdgLtbgamEVNO23wToxKV+tE2NAPjNNsyyVKCW02MLNvSleg9/hgWc4D2hUaMzqjcqDZhk9yR62yhBse0LVyLilf/tJVSW2zEyJLhBzKQ4769eyTqoTyfZ4xKuSmyCfVyaM9otmWaYX2NqJjkC1Cx4L1RwUjtWyknFSsxsm4RjyJaEoXNYWKhEGOCZaRYjEGUIOqtCxND3XvAQaXgEmI4ELsA18tkFQfWk5u/yUI7Rs+E9pMmWAZcjGFIpRitdPEx0KtUfKUiEmQ31PsVsWypbCfG2RoV1AGvxHyt9zUqG8UJUW8tgDsM6h8Zob6SIkaW18IZRE9o14hhfEe+iDFTY/kbKvvOPiir6TTgNTmIftsKYRrl558D/5Sr1KvEuNQxjjtulCVXN0P7Z0QI+C9FYmTJ2B2VqCyKN8F4m4nxTsiPz2zlGx1kf98X6A/sgHq2qr+UvvLzahJ6JFAIqzuYnopYZ8kSI2syOgRzy/nDNhMj7JI4zbMYQgzd69M/O2LEovt+qBe3TC49MrYSY4nGtqO7xcSoMDj7/N4RIzb9D0I/48tKm4nxvEYF7wI/B3paSgzd/e7vHDFi7YN5BgZca4lxo4GLRj0qkm8KcDSaD6NYtJWa5ogRax88WkzEMAkvzcU6sQfcg3qDu38cPjEGxFiqKbdPhIB+R4z/k/sfmjLX5YkY/zYhRjnxe1RulI59VNw6BqOc0zIJdkoG5f+vgwbaer52y3UNRL2U5Ijhff9Ot27cy9uGdd2pWc8qU5eQkZgHEIXFcpT37kSxh7RLoHPuNJBrESEfrpcBeyzqEfoNhhNGmulzeogv2DniAzVE/q1MyJ5B3zctAxyA2TN19xr2800G2/8BpoNqKvnFN8BfpaMGx0SMXxrKUofK+j4alSVkkJS95Qx1GSrKsS6GlTStTIRlqGyCmxs0DaiXsN6Ry5jHgPtRoctTUFlSrkA9g9xSJoinwduYvzY1zrCfzzeoazYw0KSyKhmoaWCj3HhdSYQ0kKjXfKK6qzTJNzbKn5tjbmdaxKhAJUqzBWtMbzcxS1Dd4oGxfgtlndyq9dtchf1jmBWjYgMwH/XCaIWB0p7DXjhi/A+3RpgAe2D2olUYXJxb2VYa7iH5QDPKYXE/9AKVjiSd1DiOGHqGvb4RiFFBck8fX5J7MzXb0sHUAFxDyLfgpC3POmJYS4wm4MQYzpPX54MYJ1s8y35vjAu7tUKFZdY6YlhJjMnEkAwa5Zi6NjFiAF3lRkIHzwM/FtbOQz1Rmw9M0VDcUFmykx7oqxwxQrd9IjFmSAd+myQxfqH5i6vIeX4K5U5egzLmPS42iyRyFDUCQzUUtx/xxysjq+srcn8/q0CIUYb+WyRx4V9ECAhr4yZ1TlLE0LUW3xBS4EGoUNP7ZUWJiyjzDW4wphJP5pAGWS0Pb9nWoZJC69y49Q55uFykKdvlIb5bgwosq88TIepkVu/mJQRUoNtdMd5SXegBvTQHbD0G7yFIR+8DXCpE3BhxcO5oIMNAVFK5Zei/FLsYlepz1y24QiyV/9da2QBM0rxdqwvx3SbRaQ+Nb/cHjkG9jjQb9XhPo+glit2mWewBT6KShW+VR5eUocCDwGrDNmwCPgC290Q5Oh95nxhcOWQ1uQVzm8m4iPXXyBZyiihznmwzFogd5EFUVvSTCfFqqWxTtmmjVBvIWRniuz1jGliV0i8jgFOAXwE3yGr7ECof1IKc8gzqSedbUR4MI0zaGTNBquX8O17kmoHyacuW+wXZAt+OMiqPRSV6qGj5yIW6h+6YG9EHfR9+gJsTcEA08hUqJeTqqVB0pS03cInmgHwqAaG7G1yt3uuGqUOSTEqdGCLH65pyzHG952ATMV5OSI7XNOV4wvWeQ5LEON7g+q17zDJkUNF/Orjb9Z5DksTY2+Bq65qYZdjV4F79Jtd7DkkSo8LgyrRRruYqYqi/h1iQdXGm6z2HpMkxzdCQ8woqDX6PsJ6vUl+lXNNeJK4CJj43e7iec0iaGMMjWqLXi/vCHOBPYhSaIAaW8WIxvgH1xtvTYiTcEKG+952twSFf5JhL4eAs12MO+SLGTtjzRkZreI8I2ckdHEzIMSriFidpfAfs63rKIQ1ynIyd733XA6NdDzmkfRj/zCJSfJVEkIuDgwk5tgb+kMeAli3FQcwkZJZAB4d8EmSAXMHmM7HAeiHEcNcDDrYTpCPq8ciZWdFqcWK5XBmfL8E3zk7hUHAkaS+hkaNQqVCmixV8GfClrC4rJcRwtfy9VuK+l0gY5nTgWlQa/Z3SjvpycEiaNJUSWtgV6C0x5dVSKpyGHAoB/wVG+Njjen7G3wAAAABJRU5ErkJggg==\"","import { Auth } from '@aws-amplify/auth'\nimport { Http } from '@capacitor-community/http'\nimport { Capacitor } from '@capacitor/core'\nimport axios from 'axios'\n\ntype CrossPlatformRequest = {\n method: 'GET' | 'POST'\n url: string\n headers?: any\n data?: any\n withCredentials?: boolean\n}\n\ntype CrossPlatformResponse = {\n data: any\n status: number\n headers: any\n}\n\nexport const request = async (\n options: CrossPlatformRequest\n): Promise<CrossPlatformResponse> => {\n if (Capacitor.isNativePlatform()) return Http.request(options)\n return axios(options)\n}\n\nexport const fetchVectorTiles = async (url: string): Promise<Response> => {\n const options: RequestInit = {}\n if (Capacitor.isNativePlatform()) {\n // Get token from storage\n const token = localStorage.getItem('tileAccessTokens')\n options.headers = {\n Authorization: `Bearer ${token}`,\n }\n } else if (url.indexOf('rsa-api') > -1 || url.indexOf('rsc-api') > -1) {\n const token = await (await Auth.currentSession()).getIdToken().getJwtToken()\n options.headers = {\n Authorization: `Bearer ${token}`,\n 'Content-Type': 'application/json',\n }\n options.mode = 'cors'\n options.credentials = 'include'\n } else {\n options.credentials = 'include'\n }\n return fetch(url, options)\n}\n","import Amplify, { Auth } from '@aws-amplify/auth'\nimport { CognitoUserSession } from 'amazon-cognito-identity-js'\nimport { Capacitor } from '@capacitor/core'\n\nimport { request } from '../utils/fetch'\nimport { EventEmitter } from 'events'\n\nimport Configuration from './Configuration'\nimport { LatLon } from '../pages/maps/Maps.types'\n\nAmplify.configure({\n aws_project_region: Configuration.AWS_REGION,\n aws_cognito_identity_pool_id: Configuration.AWS_USER_POOL,\n aws_cognito_region: Configuration.AWS_REGION,\n aws_user_pools_id: Configuration.AWS_USER_POOL,\n aws_user_pools_web_client_id: Configuration.AWS_CLIENT_ID,\n oauth: {},\n Auth: {\n // REQUIRED - Amazon Cognito Identity Pool ID\n identityPoolId: Configuration.AWS_USER_POOL, //?\n // REQUIRED - Amazon Cognito Region\n region: Configuration.AWS_REGION,\n // OPTIONAL - Amazon Cognito User Pool ID\n userPoolId: Configuration.AWS_USER_POOL,\n // OPTIONAL - Amazon Cognito Web Client ID (26-char alphanumeric string)\n userPoolWebClientId: Configuration.AWS_CLIENT_ID,\n },\n})\n\nexport interface UserData {\n displayName?: string\n email?: string\n session?: CognitoUserSession\n challenge?: { challengeName: string; challengeParam: any }\n user?: any\n layers?: Array<String>\n mapHome?: LatLon\n isOem?: Boolean\n permissions?: string[]\n}\nexport interface UserMetaData {\n data: {\n layers?: Array<String>\n mapHome?: LatLon\n isOem?: Boolean\n }\n}\n\nexport interface ErrorMessage {\n type: string\n error: any\n}\nclass LoginManager {\n eventEmitter: EventEmitter\n session: CognitoUserSession | undefined\n userData: UserData\n\n constructor() {\n this.eventEmitter = new EventEmitter()\n this.eventEmitter.setMaxListeners(100)\n this.session = undefined\n this.userData = {}\n }\n\n addDataListener(callback: (...args: any[]) => void) {\n this.eventEmitter.addListener('userData', callback)\n }\n\n removeDataListener(callback: (...args: any[]) => void) {\n this.eventEmitter.removeListener('userData', callback)\n }\n\n getSession() {\n return this.session\n }\n\n async login(token: string) {\n return request({\n method: 'POST',\n url: `${Configuration.BASE_URL}user/login-idp`,\n data: {\n token: token,\n },\n headers: { 'Content-Type': 'application/json' },\n withCredentials: true,\n })\n }\n\n async metaData(token: string) {\n return request({\n method: 'GET',\n url: `${Configuration.BASE_URL}rsi-saas/metadata`,\n data: {\n token: token,\n },\n withCredentials: true,\n })\n }\n\n async permissions() {\n return request({\n method: 'GET',\n url: `${Configuration.BASE_URL}user/permissions`,\n withCredentials: true,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n\n async checkSignIn() {\n try {\n const res = await Auth.currentAuthenticatedUser()\n if (res.signInUserSession) {\n this.session = res.signInUserSession as CognitoUserSession\n this.userData.email = res.attributes.email\n this.userData.session = res.signInUserSession as CognitoUserSession\n const loginRes = await this.getUserData()\n this.userData.displayName = loginRes.data.display_name\n const metaData = await this.getMetaData()\n this.userData.mapHome = metaData.data.mapHome\n this.userData.layers = metaData.data.layers\n this.userData.isOem = metaData.data.isOem\n this.userData.permissions = await this.getPermissions()\n this.eventEmitter.emit('userData', this.userData)\n await this.setTileAccessTokenIfNative()\n }\n } catch (error) {\n this.session = undefined\n this.eventEmitter.emit('userData', undefined)\n }\n }\n\n async getPermissions(): Promise<string[]> {\n try {\n if (this.session) {\n const response = await this.permissions()\n\n if (response.data) return response.data.permissions\n }\n } catch (error) {\n console.log('No permissions received', error)\n }\n return []\n }\n\n async setTileAccessTokenIfNative(): Promise<void> {\n if (!Capacitor.isNativePlatform()) return\n try {\n const response = await request({\n method: 'GET',\n url: `${Configuration.BASE_URL}user/access-tokens`,\n withCredentials: true,\n })\n\n if (response.data) {\n localStorage.setItem('tileAccessTokens', response.data.tokens[0])\n }\n } catch (error) {\n console.error('Could not fetch access tokens.')\n }\n }\n\n async getMetaData(): Promise<UserMetaData> {\n try {\n if (this.session) {\n const metaData = await this.metaData(this.session.getIdToken().getJwtToken())\n return metaData\n }\n } catch (error) {\n console.log('No metadata received', error)\n }\n return { data: {} }\n }\n\n async getUserData(): Promise<any> {\n if (!this.session) {\n return undefined\n }\n const loginRes = await this.login(this.session.getIdToken().getJwtToken())\n\n return loginRes\n }\n\n getCurrentUserData(): UserData {\n return this.userData\n }\n\n async signOut() {\n try {\n await Auth.signOut({ global: true })\n localStorage.removeItem('tileAccessTokens')\n this.eventEmitter.emit('userData', undefined)\n } catch (error) {\n console.log('error signing out: ', error)\n }\n }\n\n async signIn(\n username?: string,\n password?: string\n ): Promise<UserData | ErrorMessage | undefined> {\n try {\n if (!username) {\n return undefined\n }\n\n var user = await Auth.signIn(username, password)\n\n if (this.shouldResetPassword(user?.challengeName)) {\n this.userData = {\n user: user,\n email: user?.attributes?.email,\n challenge: {\n challengeName: user?.challengeName,\n challengeParam: user.challengeParam,\n },\n }\n return this.userData\n }\n const session = await Auth.userSession(user)\n const loginRes = await this.login(session.getIdToken().getJwtToken())\n this.userData = {\n session: session,\n displayName: loginRes?.data?.display_name,\n email: user?.attributes?.email,\n }\n this.eventEmitter.emit('userData', this.userData)\n\n return this.userData\n // You should now have a cookie named AUTH_SESSION\n // and crsf token, these will be used in following api requests...\n } catch (error) {\n console.log('error signing in', error)\n return { type: 'error', error: error }\n }\n }\n\n public isErrorMessage(message: UserData | ErrorMessage): message is ErrorMessage {\n return (message as ErrorMessage).error !== undefined\n }\n\n public async updatePasswordChallenge(newPassword: string) {\n // Needed for refresh tokens\n Auth.currentSession()\n try {\n const data = await Auth.completeNewPassword(\n this.userData.user, // the Cognito User Object\n newPassword // the new password\n )\n const session = await Auth.userSession(this.userData.user)\n const loginRes = await this.login(session.getIdToken().getJwtToken())\n this.userData = {\n session: session,\n displayName: loginRes?.data?.display_name,\n email: this.userData.user?.attributes?.email,\n user: this.userData,\n }\n this.eventEmitter.emit('userData', this.userData)\n\n data.statusCode = 200\n return data\n } catch (error) {\n return error\n }\n }\n\n public async forgotPasswordSubmit(\n userName: string,\n newPassword: string,\n verificationCode: string\n ) {\n try {\n let data = { statusCode: 400 }\n await Auth.forgotPasswordSubmit(userName, verificationCode, newPassword)\n data.statusCode = 200\n return data\n } catch (error) {\n return error\n }\n }\n\n async sendForgotPasswordRequest(email: string) {\n try {\n const data = await Auth.forgotPassword(email)\n data.statusCode = 200\n return data\n } catch (error) {\n return error\n }\n }\n\n public shouldResetPassword(challengeName: string) {\n if (challengeName === 'NEW_PASSWORD_REQUIRED') {\n return true\n }\n return false\n }\n}\n\nconst LoginManagerInstance = new LoginManager()\nexport default LoginManagerInstance\n","import { Capacitor } from '@capacitor/core'\nimport * as React from 'react'\nimport { TFunction, Trans, withTranslation } from 'react-i18next'\nimport { Link, RouteComponentProps } from 'react-router-dom'\nimport ToggleCookieModal from '../../components/cookies/toggleCookieModal'\nimport LanguageSwitcher from '../../components/languageSwitcher'\nimport Loader from '../../components/misc/Loader'\nimport { signUpOem } from '../../utils/Api'\nimport { SelectOption, SignUpOemRequest } from '../../utils/Interfaces'\nimport LoginManagerInstance from '../../utils/LoginManager'\n\n// Styles & Graphics\nimport './login.scss'\n\ninterface LoginMatchParams {\n page: string\n}\n\nexport interface LoginProps extends RouteComponentProps<LoginMatchParams> {\n email?: string\n password?: string\n t: TFunction\n}\n\nexport interface LoginState {\n showLogInModal: boolean\n email?: string\n password?: string\n newpassword?: string\n verificationCode?: string\n signupstep?: string\n name?: string\n acceptTerms?: boolean\n oemExpanded?: boolean\n company?: string\n position?: string\n loading?: boolean\n error?: string\n success?: string\n dataCounties?: SelectOption[]\n dataRegion?: SelectOption[]\n}\n\n// Double exports is due to testinf reasons\n\nexport class SignIn extends React.Component<LoginProps, LoginState> {\n constructor(props: LoginProps) {\n super(props)\n this.state = {\n showLogInModal: false,\n signupstep: '',\n oemExpanded: false,\n acceptTerms: false,\n loading: false,\n success: undefined,\n error: undefined,\n email: props.email || undefined,\n password: props.password || undefined,\n }\n this.callSubmitNewPassword = this.callSubmitNewPassword.bind(this)\n this.callSetNewPassword = this.callSetNewPassword.bind(this)\n }\n componentDidMount() {\n if (this.props.match.params.page === 'signup') {\n document.title = this.props.t('Sign up') + ' | ' + process.env.REACT_APP_SITE_TITLE\n } else {\n document.title = this.props.t('Log in') + ' | ' + process.env.REACT_APP_SITE_TITLE\n }\n this.setState({ signupstep: '' })\n }\n\n verifyemail() {\n const email_reg =\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/\n if (!email_reg.test(String(this.state.email).toLowerCase())) {\n return false\n } else {\n return true\n }\n }\n\n async handleSubmitLogin(e: React.FormEvent) {\n e.preventDefault()\n if (!this.state.email || !this.state.password) {\n this.setState({ error: 'Fill in email and password.' })\n } else {\n this.setState({ loading: true })\n const result = await LoginManagerInstance.signIn(\n this.state.email,\n this.state.password\n )\n if (result) {\n if (LoginManagerInstance.isErrorMessage(result)) {\n this.setState({ error: result.error.message, loading: false })\n } else {\n if (LoginManagerInstance.shouldResetPassword(result.challenge?.challengeName)) {\n this.setState({\n signupstep: 'showResetPassword',\n loading: false,\n newpassword: '',\n })\n return\n }\n this.setState({ loading: false, success: \"You're in!\", error: '' })\n }\n } else {\n this.setState({ loading: false, error: 'Invalid email and/or password.' })\n }\n }\n }\n\n async handleSubmitSignUp(e: React.FormEvent) {\n e.preventDefault()\n if (!this.state.name || !this.state.email) {\n this.setState({ error: 'Fill in all fields.' })\n } else if (!this.verifyemail()) {\n this.setState({ error: 'Your email is incorrect.' })\n } else if (!this.state.acceptTerms) {\n this.setState({ error: 'You have to accept the terms and conditions' })\n } else {\n this.setState({ error: '', signupstep: 'details' })\n }\n }\n\n async handleSubmitSignUpDetails(e: React.FormEvent) {\n e.preventDefault()\n if (!this.state.company || !this.state.position) {\n this.setState({ error: 'Fill in your company and position.' })\n } else {\n this.signUpOem()\n }\n }\n\n async handleSubmitForgotPassword(e: React.FormEvent) {\n e.preventDefault()\n if (!this.state.email) {\n this.setState({ success: '', error: 'Fill in your email address.' })\n } else if (!this.verifyemail()) {\n this.setState({ success: '', error: 'Email is incorrect.' })\n } else {\n this.setState({ loading: true, success: '', error: '' })\n\n const response = await LoginManagerInstance.sendForgotPasswordRequest(\n this.state.email\n )\n\n const _this = this\n setTimeout(function () {\n if (response && response.statusCode === 200) {\n _this.setState({\n loading: false,\n success:\n 'Done! If that email address is in our database, we will send you an email to reset your password.',\n error: '',\n })\n } else if (response.message) {\n _this.setState({ loading: false, success: '', error: response.message })\n } else {\n _this.setState({\n loading: false,\n success: '',\n error:\n 'Something went wrong. Please try again or let us know via info@niradynamics.se',\n })\n }\n }, 500)\n }\n }\n\n async signUpOem() {\n if (\n !this.state.name ||\n !this.state.email ||\n !this.state.company ||\n !this.state.position\n ) {\n this.setState({\n loading: false,\n error: 'Some fields are missing. Fill them in and continue.',\n })\n } else {\n this.setState({ loading: true, error: '' })\n\n let body: SignUpOemRequest = {\n name: this.state.name,\n email: this.state.email,\n company: this.state.company,\n position: this.state.position,\n }\n\n const response = await signUpOem(body)\n\n if (response && response.statusCode === 200) {\n const _this = this\n setTimeout(function () {\n _this.setState({ loading: false, signupstep: 'done', error: '' })\n _this.resetSignUpData()\n }, 1000)\n } else if (response.statusText) {\n this.setState({ loading: false, error: response.statusText })\n } else {\n this.setState({\n loading: false,\n error:\n 'Something went wrong when signing up. Please try again or let us know via info@niradynamics.se',\n })\n }\n }\n }\n\n resetSignUpData() {\n this.setState({\n name: undefined,\n email: undefined,\n company: undefined,\n position: undefined,\n oemExpanded: false,\n acceptTerms: false,\n })\n }\n\n resend() {\n this.setState({ loading: true })\n const _this = this\n setTimeout(function () {\n _this.setState({ loading: false })\n }, 2000)\n }\n\n renderLoginComponent() {\n return (\n <form\n className=\"form-wrapper\"\n onSubmit={(e) => this.handleSubmitLogin(e)}\n key=\"login\"\n >\n <h2 id=\"login-header\"> {this.props.t('Log in')} </h2>\n\n <div className=\"form-message\">\n {this.state.error && (\n <span className=\"error\"> {this.props.t(this.state.error)} </span>\n )}\n {this.state.success && (\n <span className=\"success\"> {this.props.t(this.state.success)} </span>\n )}\n </div>\n <input\n id=\"email-input\"\n autoFocus={!Capacitor.isNativePlatform()}\n type=\"text\"\n name=\"email\"\n autoComplete=\"username\"\n placeholder={this.props.t('Email')}\n defaultValue={this.state.email}\n className={this.state.error && 'error'}\n onChange={(e) => this.setState({ error: '', email: e.currentTarget.value })}\n />\n <input\n id=\"password-input\"\n type=\"password\"\n name=\"password\"\n autoComplete=\"password\"\n placeholder={this.props.t('Password')}\n defaultValue={this.state.password}\n className={this.state.error && 'error'}\n onChange={(e) => this.setState({ error: '', password: e.currentTarget.value })}\n />\n <Link\n to={process.env.PUBLIC_URL + '/login/showResetPassword'}\n className=\"link\"\n style={{ display: 'block', textAlign: 'right' }}\n onClick={() => this.setState({ signupstep: '', error: '' })}\n >\n {this.props.t('Forgot password?')}\n </Link>\n\n <div className=\"buttons-wrapper\">\n <Link\n to={process.env.PUBLIC_URL + '/login/signup'}\n className=\"button signup-button inverted\"\n onClick={() => this.setState({ signupstep: '', error: '' })}\n >\n {this.props.t('Sign up')}\n </Link>\n {this.state.loading ? (\n <button>\n <Loader />\n </button>\n ) : (\n <button id=\"login-button\" type=\"submit\" className=\"button\">\n {' '}\n {this.props.t('Log in')}\n </button>\n )}\n </div>\n </form>\n )\n }\n\n async callSubmitNewPassword(e: React.FormEvent<HTMLFormElement>): Promise<void> {\n e.preventDefault()\n if (!this.state.newpassword) {\n this.setState({ success: '', error: 'Fill the new password.' })\n } else {\n this.setState({ loading: true, success: '', error: '' })\n\n const response = await LoginManagerInstance.updatePasswordChallenge(\n this.state.newpassword\n )\n\n const _this = this\n setTimeout(function () {\n if (response && response.statusCode === 200) {\n _this.setState({\n loading: false,\n newpassword: '',\n signupstep: 'done',\n error: '',\n })\n } else if (response.message) {\n _this.setState({\n loading: false,\n newpassword: '',\n success: '',\n error: response.message,\n })\n } else {\n _this.setState({\n loading: false,\n newpassword: '',\n success: '',\n error:\n 'Something went wrong. Please try again or let us know via info@niradynamics.se',\n })\n }\n }, 500)\n }\n }\n\n async callSetNewPassword(e: React.FormEvent<HTMLFormElement>): Promise<void> {\n e.preventDefault()\n\n if (!this.state.newpassword) {\n this.setState({ success: '', error: 'Fill the new password.' })\n } else if (!this.state.verificationCode) {\n this.setState({ success: '', error: 'Fill the verification code.' })\n } else {\n this.setState({ loading: true, success: '', error: '' })\n\n const response = await LoginManagerInstance.forgotPasswordSubmit(\n this.state.email,\n this.state.newpassword,\n this.state.verificationCode\n )\n\n const _this = this\n setTimeout(function () {\n if (response && response.statusCode === 200) {\n _this.setState({\n loading: false,\n newpassword: '',\n success: 'New password set. Go back and try to log in.',\n error: '',\n })\n } else if (response.message) {\n _this.setState({\n loading: false,\n newpassword: '',\n success: '',\n error: response.message,\n })\n } else {\n _this.setState({\n loading: false,\n newpassword: '',\n success: '',\n error:\n 'Something went wrong. Please try again or let us know via info@niradynamics.se',\n })\n }\n }, 500)\n }\n }\n\n renderResetPasswordComponent() {\n return (\n <form\n className=\"form-wrapper\"\n onSubmit={this.callSubmitNewPassword}\n key=\"resetPassword\"\n >\n <h2> {this.props.t('Reset password')} </h2>\n\n <div className=\"form-message\">\n {!this.state.error && (\n <span>{this.props.t('Please enter a new password.')}</span>\n )}\n {this.state.error && (\n <span className=\"error\"> {this.props.t(this.state.error)} </span>\n )}\n {this.state.success && (\n <span className=\"success\"> {this.props.t(this.state.success)} </span>\n )}\n </div>\n\n <input\n autoFocus\n type=\"password\"\n name=\"password\"\n autoComplete=\"password\"\n placeholder={this.props.t('Password')}\n className={this.state.error && 'error'}\n defaultValue={this.state.newpassword}\n onChange={(e) =>\n this.setState({ error: '', newpassword: e.currentTarget.value })\n }\n />\n\n <div className=\"buttons-wrapper\">\n {this.state.loading ? (\n <button>\n <Loader />\n </button>\n ) : (\n <input type=\"submit\" className=\"button\" />\n )}\n </div>\n <div className=\"form-message\">\n Password requirements:\n <br />\n <ul>\n <li>Minimum of 12 characters</li>\n <li>Minimum of one uppercase (A-Z)</li>\n <li>Minimum of one lowercase (a-z)</li>\n <li>Minimum of one number (0-9)</li>\n </ul>\n </div>\n </form>\n )\n }\n renderEnterNewPasswordComponent() {\n return (\n <form\n className=\"form-wrapper\"\n onSubmit={this.callSetNewPassword}\n key=\"resetPassword\"\n >\n <h2> {this.props.t('Reset password')}</h2>\n\n <div className=\"form-message\">\n {!this.state.error && (\n <span>{this.props.t('Please enter a new password.')}</span>\n )}\n {this.state.error && (\n <span className=\"error\"> {this.props.t(this.state.error)} </span>\n )}\n {this.state.success && (\n <span className=\"success\"> {this.props.t(this.state.success)} </span>\n )}\n </div>\n\n <input\n type=\"text\"\n name=\"email\"\n autoComplete=\"username\"\n placeholder={this.props.t('Email')}\n defaultValue={this.state.email}\n className={this.state.error && 'error'}\n onChange={(e) => this.setState({ error: '', email: e.currentTarget.value })}\n />\n\n <input\n autoFocus\n type=\"password\"\n name=\"code\"\n autoComplete=\"password\"\n placeholder={this.props.t('Verification code')}\n className={this.state.error && 'error'}\n defaultValue={this.state.verificationCode}\n onChange={(e) =>\n this.setState({ error: '', verificationCode: e.currentTarget.value })\n }\n />\n\n <input\n autoFocus\n type=\"password\"\n name=\"password\"\n autoComplete=\"password\"\n placeholder={this.props.t('Password')}\n className={this.state.error && 'error'}\n defaultValue={this.state.newpassword}\n onChange={(e) =>\n this.setState({ error: '', newpassword: e.currentTarget.value })\n }\n />\n <div className=\"buttons-wrapper\">\n <Link\n to={process.env.PUBLIC_URL + '/login'}\n className=\"button signup-button inverted\"\n onClick={(e) => this.setState({ success: '', error: '', signupstep: '' })}\n >\n {this.props.t('Back')}{' '}\n </Link>\n {this.state.loading ? (\n <button>\n <Loader />\n </button>\n ) : (\n <button type=\"submit\" className=\"button\">\n {this.props.t('Send')}\n </button>\n )}\n </div>\n <div className=\"form-message\">\n Password requirements:\n <br />\n <ul>\n <li>Minimum of 12 characters</li>\n <li>Minimum of one uppercase (A-Z)</li>\n <li>Minimum of one lowercase (a-z)</li>\n <li>Minimum of one number (0-9)</li>\n </ul>\n </div>\n </form>\n )\n }\n\n renderSignUpComponent() {\n return (\n <form\n className=\"form-wrapper\"\n onSubmit={(e) => this.handleSubmitSignUp(e)}\n key=\"signup\"\n >\n <h2> {this.props.t('Sign up')}</h2>\n\n <div className=\"form-message\">\n {this.state.error && (\n <span className=\"error\"> {this.props.t(this.state.error)} </span>\n )}\n {this.state.success && (\n <span className=\"success\"> {this.props.t(this.state.success)} </span>\n )}\n </div>\n\n <input\n autoFocus\n type=\"text\"\n name=\"name\"\n autoComplete=\"name\"\n placeholder={this.props.t('Name')}\n defaultValue={this.state.name}\n className={this.state.error ? ' error' : ''}\n onChange={(e) => this.setState({ error: '', name: e.currentTarget.value })}\n />\n <input\n type=\"text\"\n name=\"email\"\n autoComplete=\"username\"\n placeholder={this.props.t('Email')}\n defaultValue={this.state.email}\n className={this.state.error && 'error'}\n onChange={(e) => this.setState({ error: '', email: e.currentTarget.value })}\n />\n\n <div className=\"terms-checkbox\">\n <label className=\"clickable\">\n <input\n type=\"checkbox\"\n name=\"acceptTerms\"\n className=\"clickable\"\n onChange={(e) =>\n this.setState({ acceptTerms: e.currentTarget.checked, error: '' })\n }\n defaultChecked={this.state.acceptTerms}\n />{' '}\n <Trans i18nKey=\"I accept the Terms & conditions\">\n I accept the{' '}\n <a href=\"/terms\" className=\"link\" target=\"_blank\" rel=\"noopener noreferrer\">\n Terms & Conditions\n </a>\n </Trans>\n </label>\n </div>\n\n <div className={'oem-info' + (this.state.oemExpanded ? ' expanded' : '')}>\n <p>\n {this.props.t(\n 'As a representative from an OEM you will get access to a demo version of the map service. The demo is representative of the service but cannot be used as a tool.'\n )}{' '}\n </p>\n <p>\n {this.props.t(\n 'If you do not represent an OEM organization, leave the checkmark unchecked.'\n )}\n </p>\n </div>\n\n <div className=\"buttons-wrapper\">\n <Link to={process.env.PUBLIC_URL + '/login'} className=\"button inverted\">\n {this.props.t('Cancel')}\n </Link>\n <button type=\"submit\" className=\"button\">\n {this.props.t('Next')}\n </button>\n </div>\n </form>\n )\n }\n\n renderSignUpDetailsComponent() {\n return (\n <form\n className=\"form-wrapper\"\n onSubmit={(e) => this.handleSubmitSignUpDetails(e)}\n key=\"details\"\n >\n <h2>{this.props.t('Details')}</h2>\n\n <p className=\"bold\">{this.props.t('Let us get to know you')}</p>\n <div className=\"form-message\">\n {this.state.error && (\n <span className=\"error\"> {this.props.t(this.state.error)} </span>\n )}\n {this.state.success && (\n <span className=\"success\"> {this.props.t(this.state.success)} </span>\n )}\n </div>\n\n <input\n autoFocus\n type=\"text\"\n name=\"company\"\n autoComplete=\"company\"\n placeholder={this.props.t('Company/Organization')}\n defaultValue={this.state.company}\n className={this.state.error && 'error'}\n onChange={(e) => this.setState({ error: '', company: e.currentTarget.value })}\n />\n <input\n type=\"text\"\n name=\"position\"\n autoComplete=\"position\"\n placeholder={this.props.t('Position')}\n defaultValue={this.state.position}\n className={this.state.error && 'error'}\n onChange={(e) => this.setState({ error: '', position: e.currentTarget.value })}\n />\n\n <div className=\"buttons-wrapper\">\n <button\n className=\"button inverted\"\n onClick={(e) => this.setState({ error: '', signupstep: '' })}\n >\n {this.props.t('Back')}\n </button>\n {this.state.loading ? (\n <button>\n <Loader />\n </button>\n ) : (\n <button type=\"submit\" className=\"button\">\n {this.props.t('Next')}\n </button>\n )}\n </div>\n </form>\n )\n }\n renderForgotPasswordRequest() {\n return (\n <form\n className=\"form-wrapper\"\n onSubmit={(e) => this.handleSubmitForgotPassword(e)}\n key=\"requestpasswordreset\"\n >\n <h2> {this.props.t('Reset password')}</h2>\n <div className=\"form-message\">\n {this.state.error && (\n <span className=\"error\"> {this.props.t(this.state.error)} </span>\n )}\n {this.state.success && (\n <span className=\"success\"> {this.props.t(this.state.success)} </span>\n )}\n </div>\n\n <input\n autoFocus\n type=\"text\"\n name=\"email\"\n autoComplete=\"username\"\n placeholder={this.props.t('Email')}\n defaultValue={this.state.email}\n className={this.state.error && 'error'}\n onChange={(e) =>\n this.setState({ success: '', error: '', email: e.currentTarget.value })\n }\n />\n\n <div className=\"buttons-wrapper\">\n <Link\n to={process.env.PUBLIC_URL + '/login'}\n className=\"button signup-button inverted\"\n onClick={(e) => this.setState({ success: '', error: '', signupstep: '' })}\n >\n {this.props.t('Back')}{' '}\n </Link>\n\n {this.state.loading ? (\n <button>\n <Loader />\n </button>\n ) : (\n <button type=\"submit\" className=\"button\">\n {this.props.t('Send')}\n </button>\n )}\n </div>\n <div className=\"buttons-wrapper\">\n <Link\n to={process.env.PUBLIC_URL + '/login/enternewpassword'}\n className=\"link\"\n style={{ display: 'block', textAlign: 'right' }}\n onClick={() => this.setState({ signupstep: '', error: '', success: '' })}\n >\n {this.props.t('I have a verification code')}{' '}\n </Link>\n </div>\n </form>\n )\n }\n\n renderDoneComponent(title: string, contentText: string) {\n return (\n <div className=\"form-wrapper\" key=\"done\">\n <h2> {this.props.t(title)}</h2>\n <div className=\"bold\"> {this.props.t(contentText)} </div>\n <div className=\"done-email\"> </div>\n\n <div className=\"buttons-wrapper\">\n <Link to={process.env.PUBLIC_URL + '/login'} type=\"button\" className=\"button\">\n {this.props.t('Go to login')}\n </Link>\n </div>\n </div>\n )\n }\n\n renderComponent() {\n if (this.props.match.params.page === 'signup') {\n switch (this.state.signupstep) {\n case 'details':\n return this.renderSignUpDetailsComponent()\n case 'done':\n return this.renderDoneComponent(\n 'Registration done',\n 'A link to activate your account has been emailed to the address provided.'\n )\n case 'showResetPassword':\n return this.renderResetPasswordComponent()\n default:\n return this.renderSignUpComponent()\n }\n } else if (this.props.match.params.page === 'enternewpassword') {\n switch (this.state.signupstep) {\n case 'done':\n return this.renderDoneComponent(\n 'New password set',\n 'Go back and log in with the new password'\n )\n default:\n return this.renderEnterNewPasswordComponent()\n }\n } else if (this.props.match.params.page === 'showResetPassword') {\n switch (this.state.signupstep) {\n case 'done':\n return this.renderDoneComponent(\n 'Registration done',\n 'A link to activate your account has been emailed to the address provided.'\n )\n default:\n return this.renderForgotPasswordRequest()\n }\n } else {\n if (this.state.signupstep === 'showResetPassword') {\n return this.renderResetPasswordComponent()\n }\n\n return this.renderLoginComponent()\n }\n }\n\n render() {\n return (\n <div id=\"login-page\" className=\"page-content\">\n {/*** TOP ***/}\n <section className=\"top-wrapper\">\n <section className=\"content-wrapper\">\n <div className=\"row\">\n <div className=\"column column33\">\n <h2 className=\"title\"> {this.props.t('Live Road Surface Map')} </h2>\n <summary>\n <Trans i18nKey=\"LoginHeroDescription\">\n The future of road surface monitoring. <br />\n Powered by data RSI is the benchmark.\n </Trans>\n </summary>\n </div>\n <div className=\"column column67\">{this.renderComponent()}</div>\n </div>\n </section>\n </section>\n <div className=\"cookie-link\">\n <ToggleCookieModal>\n <>{this.props.t('Manage cookies')}</>\n </ToggleCookieModal>\n </div>\n\n <div className=\"language-switcher-wrapper\">\n <LanguageSwitcher expandedDirection=\"up-left\" />\n </div>\n </div>\n )\n }\n}\n\nexport default withTranslation()(SignIn)\n","import {\n BaseResponse,\n ErrorResponse,\n CountryResponse,\n RegionResponse,\n PostMessageRequest,\n SignUpWriRequest,\n SignUpOemRequest,\n IdValuePair,\n} from './Interfaces'\n\nimport Configuration from './Configuration'\n\nexport async function getCountries(): Promise<IdValuePair[]> {\n const response: Response = await fetch(Configuration.BASE_URL + 'rsi-saas/countries')\n var obj = {\n statusCode: response.status,\n ok: response.ok,\n statusText: response.statusText,\n raw: response,\n }\n\n var json: CountryResponse = await getJson(obj, response)\n\n const keys = Object.keys(json)\n let countries: IdValuePair[] = []\n keys.forEach((key) => {\n if (!isNaN(Number(key))) {\n countries.push(json[key])\n }\n })\n return countries\n}\n\nexport interface RecipeInfo {\n id: number\n updatedAt: string // Timestamp\n}\nexport async function getRegion(countryId: number) {\n const response: Response = await fetch(\n Configuration.BASE_URL + 'rsi-saas/regions/' + countryId\n )\n var obj = {\n statusCode: response.status,\n ok: response.ok,\n statusText: response.statusText,\n raw: response,\n }\n\n var json: RegionResponse = await getJson(obj, response)\n\n const keys = Object.keys(json)\n let regions: IdValuePair[] = []\n keys.forEach((key) => {\n if (!isNaN(Number(key))) {\n regions.push(json[key])\n }\n })\n return regions\n}\n\nexport async function postMessage(\n messageBody: PostMessageRequest\n): Promise<BaseResponse | ErrorResponse> {\n const requestHeaders: HeadersInit = new Headers()\n requestHeaders.set('Content-Type', 'application/json')\n const response: Response = await fetch(Configuration.BASE_URL + 'rsi-saas/contact-us', {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(messageBody),\n })\n var obj = {\n statusCode: response.status,\n ok: response.ok,\n statusText: response.statusText,\n raw: response,\n }\n return obj\n}\nexport async function signUpWri(\n messageBody: SignUpWriRequest\n): Promise<BaseResponse | ErrorResponse> {\n const requestHeaders: HeadersInit = new Headers()\n requestHeaders.set('Content-Type', 'application/json')\n\n const response: Response = await fetch(\n Configuration.BASE_URL + 'rsi-saas/wri/sign-up',\n {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(messageBody),\n }\n )\n\n const errorText = await response.text()\n\n var obj = {\n statusCode: response.status,\n ok: response.ok,\n statusText: errorText || response.statusText,\n raw: response,\n }\n\n return obj\n}\nexport async function signUpOem(\n messageBody: SignUpOemRequest\n): Promise<BaseResponse | ErrorResponse> {\n const requestHeaders: HeadersInit = new Headers()\n requestHeaders.set('Content-Type', 'application/json')\n const response: Response = await fetch(\n Configuration.BASE_URL + 'rsi-saas/oem/sign-up',\n {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify(messageBody),\n }\n )\n\n const errorText = await response.text()\n\n var obj = {\n statusCode: response.status,\n ok: response.ok,\n statusText: errorText || response.statusText,\n raw: response,\n }\n\n return obj\n}\n\nasync function getJson(obj: BaseResponse, response: Response): Promise<BaseResponse> {\n if (isJson(response.headers)) {\n return { ...obj, ...(await response.json()) }\n } else {\n return obj\n }\n}\n\nfunction isJson(headers: Headers): boolean {\n return (\n headers.has('content-type') &&\n headers.get('content-type')?.split(';')[0].toLowerCase() === 'application/json'\n )\n}\n","import { ClearWatch } from './LocationUtil'\n\nexport type TimeMode = {\n timestamps: Date[]\n label: 'live' | 'history' | 'interval'\n}\n\nexport interface GpsModeData {}\n\nexport class GpsModeDataTrack implements GpsModeData {\n clearWatch: ClearWatch | null = null\n initPosition: Boolean\n\n constructor(clearWatch: ClearWatch, initPosition: Boolean = false) {\n this.clearWatch = clearWatch\n this.initPosition = initPosition\n }\n}\n\nexport enum GpsModeType {\n None = 'none',\n Track = 'track',\n Once = 'once',\n Error = 'error',\n}\n\nexport type GpsMode = {\n type: GpsModeType\n modeData: GpsModeData\n locationError: string\n}\n\nexport const GpsModeDefaultNone: GpsMode = {\n type: GpsModeType.None,\n modeData: {},\n locationError: '',\n}\n\nexport type LatLon = { lat: number; lon: number }\n\nexport type View = {\n center: LatLon\n zoom: number\n}\n","import { Options as XYZSourceOptions } from 'ol/source/XYZ'\n\nexport const SEGMENT_STROKE_WIDTH = 2\n\nconst getDevicePixelRatio = (): number => (window.devicePixelRatio >= 2 ? 2 : 1)\n\nexport const MAP_TILE_LAYERS: Record<string, XYZSourceOptions> = {\n v1: {\n url: `https://api.maptiler.com/maps/a832e6fe-9fd0-4864-8788-65db8fb08206/{z}/{x}/{y}@${getDevicePixelRatio().toString()}x.png?key=2rAAs363nYRRQillIEgK`,\n attributions: '<a href=\"https://maptiler.com/copyright\">© MapTiler</a>',\n tileSize: 512,\n tilePixelRatio: getDevicePixelRatio(),\n },\n v2: {\n url: `https://api.maptiler.com/maps/f2c7456f-8144-4983-8e8c-8413c8797b60/{z}/{x}/{y}@${getDevicePixelRatio().toString()}x.png?key=fMgnS558G8rrOOyv5zUm`,\n attributions: '<a href=\"https://maptiler.com/copyright\">© MapTiler</a>',\n tileSize: 512,\n tilePixelRatio: getDevicePixelRatio(),\n },\n}\n\nexport const INTERVAL_MAX_DURATION = 3 * 60 * 60 * 1000 // Three hours in milliseconds\n\nexport interface InterableObject<T> {\n [index: string]: T\n}\n","import Feature from 'ol/Feature'\nimport VectorTile from 'ol/VectorTile'\nimport MVT from 'ol/format/MVT'\nimport WKT from 'ol/format/WKT'\nimport Geometry from 'ol/geom/Geometry'\nimport VectorTileLayer from 'ol/layer/VectorTile'\nimport VectorTileRenderType from 'ol/layer/VectorTileRenderType'\nimport RenderFeature from 'ol/render/Feature'\nimport VectorTileSource from 'ol/source/VectorTile'\nimport TileState from 'ol/src/TileState'\n\nimport LineString from 'ol/geom/LineString'\nimport Point from 'ol/geom/Point'\nimport Configuration from '../../../utils/Configuration'\nimport { fetchVectorTiles } from '../../../utils/fetch'\nimport NiraAlertVectorLayer from '../layer/NiraAlertVectorLayer'\n\nexport const getAlertsVectorTileUrl = (\n vectorLayer: NiraAlertVectorLayer,\n timestamps?: string[]\n): string => {\n if (vectorLayer.rsaApi) {\n return `${Configuration.RSA_API_BASE_URL}${vectorLayer.rsaApiBundleName}/vector/{z}/{x}/{y}?minutesDelta=120`\n } else {\n let url = `${Configuration.BASE_URL}${\n vectorLayer.urlType ? vectorLayer.urlType : 'alerts'\n }/vector/${vectorLayer.bundleName}/{z}/{x}/{y}`\n\n if (!timestamps) return url\n\n if (timestamps.length) url += '?time=' + timestamps[0]\n if (timestamps.length === 2) url += '&end_time=' + timestamps[1]\n return url\n }\n}\n\nexport const transformLineStringToPointFeature = (\n renderedFeature: RenderFeature\n): Feature<Geometry> => {\n const geo = renderedFeature.getGeometry()\n const feature = new Feature(new Point(geo.getFlatMidpoint()))\n feature.setProperties(renderedFeature.getProperties())\n return feature\n}\n\nexport const getPointFeature = (\n lat,\n lon,\n name,\n featureProperties = {},\n viewProjection = 'EPSG:3857'\n) => {\n let f = new Feature({\n geometry: new Point([lon, lat]).transform('EPSG:4326', viewProjection),\n name,\n })\n f.setProperties(featureProperties)\n return f\n}\n\nexport const getTileId = (lat: number, lon: number, level: number) => {\n const degSize = 180 / Math.pow(2, level),\n tileY = Math.floor((lat + 90) / degSize),\n tileX = Math.floor((lon + 180) / degSize)\n return tileY * 2 * Math.pow(2, level) + tileX\n}\n\nexport const getTileLevelForZoomLevel = (zoomLevel: number) => {\n if (zoomLevel < 5) return 6\n else if (zoomLevel < 8) return 8\n else if (zoomLevel < 10) return 10\n else if (zoomLevel < 11) return 11\n else if (zoomLevel < 12) return 12\n else return 16\n}\n\nconst groupData = (data: any[], zoomLevel: number) => {\n const wktReader = new WKT()\n return zoomLevel < 12\n ? Object.values(\n data.reduce((result, value: any) => {\n const geom = wktReader.readFeature(value.geometry).getGeometry() as LineString\n const [lon, lat] = geom.getFlatMidpoint()\n const tileId = getTileId(lat, lon, getTileLevelForZoomLevel(zoomLevel))\n if (!result[tileId]) {\n result[tileId] = { alert: value, count: 1 }\n } else {\n result[tileId].count++\n }\n return result\n }, {})\n ).map((v: any) => ({\n ...v.alert,\n amount: v.count,\n }))\n : data\n}\n\nexport const createAlertVectorTileLayerSource = (\n vectorLayer: NiraAlertVectorLayer,\n timestamps: string[]\n) => {\n return new VectorTileSource({\n format: new MVT(),\n minZoom: vectorLayer.minZoom,\n maxZoom: vectorLayer.maxZoom,\n url: getAlertsVectorTileUrl(vectorLayer, timestamps),\n tileLoadFunction: (tile, url) => {\n const t = tile as VectorTile\n const zoomLevel = t.getTileCoord()[0]\n t.setLoader((extent, resolution, projection) => {\n fetchVectorTiles(url)\n .then((res) => {\n if (res.ok) {\n if (vectorLayer.rsaApi) {\n return res.json()\n }\n return res.arrayBuffer()\n } else if (res.status !== 404) {\n throw new Error('Failed to fetch tile: ' + res.status + ' ' + url)\n }\n return null\n })\n .then((data) => {\n if (vectorLayer.rsaApi && vectorLayer.layerName === 'slippery') {\n const wktReader = new WKT()\n const features = groupData(data, zoomLevel).map((d) => {\n let { geometry, ...featureProps } = d\n const geom = wktReader.readFeature(geometry).getGeometry() as LineString\n const [lon, lat] = geom.getFlatMidpoint()\n return getPointFeature(lat, lon, d.alertId, featureProps)\n })\n t.setFeatures(\n vectorLayer.groupFunction\n ? vectorLayer.groupFunction(features, vectorLayer, zoomLevel)\n : features\n )\n } else if (vectorLayer.rsaApi && vectorLayer.layerName === 'hydroplaning') {\n t.setFeatures(\n groupData(data, zoomLevel).map((d) => {\n let { geometry: _, ...featureProps } = d\n return getPointFeature(\n d.segmentStartPointLat,\n d.segmentStartPointLon,\n d.alertId,\n featureProps\n )\n })\n )\n } else if (\n vectorLayer.rsaApi &&\n vectorLayer.layerName === 'severeRoughness'\n ) {\n const wktReader = new WKT()\n const features = groupData(data, zoomLevel).map((d) => {\n let { geometry, ...featureProps } = d\n const geom = wktReader.readFeature(geometry).getGeometry() as LineString\n const [lon, lat] = geom.getFlatMidpoint()\n return getPointFeature(lat, lon, d.alertId, featureProps)\n })\n t.setFeatures(features)\n } else if (vectorLayer.rsaApi && vectorLayer.layerName === 'severePothole') {\n const wktReader = new WKT()\n const features = data.map((d) => {\n let { geometryWkt, ...featureProps } = d\n const geom = wktReader.readFeature(geometryWkt).getGeometry() as Point\n const [lon, lat] = geom.getFirstCoordinate()\n return getPointFeature(lat, lon, d.alertId, featureProps)\n })\n t.setFeatures(features)\n } else {\n const format = t.getFormat()\n const features = format.readFeatures(data, {\n extent: extent,\n featureProjection: projection,\n }) as Feature<Geometry>[]\n const visibleFeatures = vectorLayer.filterFunction\n ? vectorLayer.filterFunction(features, vectorLayer, zoomLevel)\n : features\n const groupedFeatures = vectorLayer.groupFunction\n ? vectorLayer.groupFunction(visibleFeatures, vectorLayer, zoomLevel)\n : visibleFeatures\n t.setFeatures(\n groupedFeatures.map((renderedFeature: any) =>\n transformLineStringToPointFeature(renderedFeature)\n )\n )\n }\n })\n .catch((error) => t.setState(TileState.ERROR))\n })\n },\n })\n}\n\nexport const createAlertsTileLayer = (\n vectorLayer: NiraAlertVectorLayer,\n timestamps: string[]\n) => {\n const alertsSource = createAlertVectorTileLayerSource(vectorLayer, timestamps)\n const alertsLayer = new VectorTileLayer({\n source: alertsSource,\n renderMode: VectorTileRenderType.HYBRID,\n minZoom: vectorLayer.minZoom,\n style: (feature, number) => vectorLayer.styleFunction(feature, number),\n })\n vectorLayer.layer = alertsLayer\n vectorLayer.source = alertsSource\n return { alertsLayer, alertsSource }\n}\n","import Feature from 'ol/Feature'\nimport VectorTile from 'ol/VectorTile'\nimport MVT from 'ol/format/MVT'\nimport Geometry from 'ol/geom/Geometry'\nimport VectorTileLayer from 'ol/layer/VectorTile'\nimport VectorTileRenderType from 'ol/layer/VectorTileRenderType'\nimport VectorTileSource from 'ol/source/VectorTile'\n\nimport TileState from 'ol/TileState'\nimport Configuration from '../../../utils/Configuration'\nimport { fetchVectorTiles } from '../../../utils/fetch'\nimport NiraVectorLayer from '../layer/NiraVectorLayer'\n\nexport const MIN_ZOOM_LIMIT = 9\nexport const MAX_ZOOM_LIMIT = 18\n\nexport const getVectorTileUrl = (\n vectorLayer: NiraVectorLayer,\n timestamps?: string[]\n): string => {\n if (vectorLayer.guiBackend) {\n let url = `${Configuration.BASE_URL}tiles/vector/aggregated/${vectorLayer.bundleName}/{z}/{x}/{y}`\n\n if (!timestamps) return url\n\n if (timestamps.length) url += '?time=' + timestamps[0]\n if (timestamps.length === 2) url += '&end_time=' + timestamps[1]\n return url\n } else {\n return `${Configuration.RSC_API_BASE_URL}roughness/tile/avg/vector/{z}/{x}/{y}`\n }\n}\n\nexport const createVectorTileLayer = (\n vectorLayer: NiraVectorLayer,\n timestamps: string[]\n) => {\n const vectorTileLayerSource = new VectorTileSource({\n format: new MVT(),\n minZoom: vectorLayer.minZoomLevel,\n maxZoom: vectorLayer.maxZoomLevel,\n url: getVectorTileUrl(vectorLayer, timestamps),\n tileLoadFunction: (tile, url) => {\n const t = tile as VectorTile\n if (\n t.tileCoord[0] <= vectorLayer.maxZoomLevel &&\n t.tileCoord[0] >= vectorLayer.minZoomLevel\n ) {\n const zoomLevel = t.getTileCoord()[0]\n t.setLoader((extent, resolution, projection) => {\n fetchVectorTiles(zoomLevel > 13 && (vectorLayer.bundleName === 'roughness-long-term-aggregation') ? url.replace(/tile\\/avg/g, \"tile\") : url)\n .then((res) => {\n if (res.ok) {\n return vectorLayer.guiBackend ? res.arrayBuffer() : res.json()\n }\n throw new Error('Failed to fetch tile: ' + res.status + ' ' + url)\n })\n .then((data) => {\n if (vectorLayer.guiBackend) {\n const format = t.getFormat()\n const features = format.readFeatures(data, {\n extent: extent,\n featureProjection: projection,\n }) as Feature<Geometry>[]\n const visibleFeatures = features.filter((feature) => {\n const properties = feature.getProperties()\n const roadClass = properties['FunctionalRoadClass']\n const showRoadClass = roadClass &&\n vectorLayer.functionalRoadClassZoomLevels[roadClass === 1 ? 1 : roadClass === 2 ? 2 :roadClass === 3 ? 3 :roadClass === 4 ? 4 : 5] <= zoomLevel\n const hasValue = vectorLayer.valueExtractor(feature) !== undefined\n return hasValue && showRoadClass\n })\n t.setFeatures(visibleFeatures)\n } else {\n const features = vectorLayer.dataToFeatures(data, zoomLevel) as Feature<Geometry>[]\n t.setFeatures(features)\n }\n })\n .catch((error) => t.setState(TileState.ERROR))\n })\n } else {\n t.setState(TileState.ERROR)\n }\n },\n })\n\n const vectorTileLayer = new VectorTileLayer({\n source: vectorTileLayerSource,\n renderMode: VectorTileRenderType.HYBRID,\n minZoom: vectorLayer.minZoomLevel,\n style: (feature, number) => vectorLayer.styleFunction(feature, number),\n })\n return { vectorTileLayer, vectorTileLayerSource }\n}\n","import { isEqual } from 'lodash'\nimport React from 'react'\nimport { RefObject } from 'react-router/node_modules/@types/react'\n\nimport Feature, { FeatureLike } from 'ol/Feature'\nimport Map from 'ol/Map'\nimport Overlay from 'ol/Overlay'\nimport View from 'ol/View'\nimport { Attribution, defaults as defaultControls } from 'ol/control'\nimport GeometryLayout from 'ol/geom/GeometryLayout'\nimport LineString from 'ol/geom/LineString'\nimport { defaults } from 'ol/interaction'\nimport TileLayer from 'ol/layer/Tile'\nimport VectorLayer from 'ol/layer/Vector'\nimport VectorTileLayer from 'ol/layer/VectorTile'\nimport { fromLonLat, toLonLat } from 'ol/proj'\nimport * as olSource from 'ol/source'\nimport VectorSource from 'ol/source/Vector'\n\nimport {\n GpsMode,\n GpsModeType,\n LatLon,\n View as MapView,\n} from '../../pages/maps/Maps.types'\nimport { MAP_TILE_LAYERS } from './MapConstants'\nimport NiraAlertVectorLayer, {\n NiraAlertsVectorLayerName,\n} from './layer/NiraAlertVectorLayer'\nimport NiraVectorLayer from './layer/NiraVectorLayer'\nimport {\n highlightFeatureWithArrows,\n highlightFeatureWithBorder,\n} from './utils/HighlightFeature'\nimport { createAlertsTileLayer } from './vectorlayers/NiraAlertsVectorTileLayers'\nimport {\n MIN_ZOOM_LIMIT,\n createVectorTileLayer,\n getVectorTileUrl,\n} from './vectorlayers/NiraVectorTileLayers'\n\nimport { Coordinate } from 'ol/coordinate'\nimport './MapComponent.scss'\n\nconst REFRESH_INTERVAL = 60\n\ninterface MapComponentProps {\n isOem: Boolean\n activeFeature: FeatureLike | null\n featureClicked: (feature: FeatureLike | null) => void\n currentVectorLayer: NiraVectorLayer | null\n vectorLayers: Record<string, NiraVectorLayer>\n alertsVectorLayers: Record<string, NiraAlertVectorLayer>\n activeAlertsVectorLayers: NiraAlertsVectorLayerName[]\n coordinates?: MapView\n setShowError: (show: boolean) => void\n mapHome?: LatLon\n timestamps: string[]\n currentView: MapView\n currentGpsMode: GpsMode\n viewChanged: (view: MapView) => void\n renderComplete: () => void\n}\n\nexport default class MapComponent extends React.Component<MapComponentProps> {\n map: Map\n ref: RefObject<HTMLDivElement>\n markerRef: RefObject<HTMLDivElement>\n vectorTileLayer: VectorTileLayer | undefined\n selectionLayer: VectorLayer<VectorSource<LineString>> | undefined\n vectorLayer: NiraVectorLayer\n alertVectorTileLayers: Record<NiraAlertsVectorLayerName, VectorTileLayer | null>\n vectorTileLayerSource: olSource.VectorTile\n refreshDataTimer: NodeJS.Timeout\n timerStartedAt: Date | null\n\n constructor(props: MapComponentProps) {\n super(props)\n this.ref = React.createRef()\n this.markerRef = React.createRef()\n\n this.alertVectorTileLayers = {\n severeRoughness: null,\n slippery: null,\n severePothole: null,\n hydroplaning: null,\n }\n\n const attribution = new Attribution({\n collapsible: false,\n collapsed: true,\n })\n\n const options = {\n view: new View({\n center: fromLonLat([props.currentView.center.lon, props.currentView.center.lat]),\n zoom: props.currentView.zoom,\n maxZoom: 22,\n }),\n layers: [this.getTileLayer()],\n overlays: [],\n interactions: defaults({ pinchRotate: false }),\n controls: defaultControls({\n attribution: true,\n zoom: false,\n rotate: false,\n }).extend([attribution]),\n }\n\n this.map = new Map(options)\n this.selectionLayer = new VectorLayer({\n source: new VectorSource(),\n style: this.selectedFeatureStyle.bind(this),\n })\n this.selectionLayer.setMap(this.map)\n }\n\n selectedFeatureStyle(feature: FeatureLike, resolution: number) {\n if (this.props.currentGpsMode.type === GpsModeType.Track) {\n return highlightFeatureWithBorder(feature, resolution, this.vectorLayer)\n } else {\n return highlightFeatureWithArrows(feature, resolution)\n }\n }\n\n updateAlertsVectorLayers(props: MapComponentProps) {\n Object.entries(props.alertsVectorLayers).forEach(([key, layer]) => {\n if (props.activeAlertsVectorLayers.includes(key as NiraAlertsVectorLayerName)) {\n this.mountAlertLayer(key, layer)\n } else {\n this.unMountAlertLayer(key)\n }\n })\n }\n\n shouldComponentUpdate(props: MapComponentProps) {\n if (!isEqual(props.timestamps, this.props.timestamps)) {\n this.refreshVectorTileLayer(props.timestamps)\n this.updateAlertsVectorLayers(props)\n }\n if (\n this.props.currentVectorLayer !== props.currentVectorLayer ||\n !isEqual(this.props.alertsVectorLayers, props.alertsVectorLayers)\n ) {\n this.removeVectorTileLayer(this.vectorTileLayer)\n this.addVectorTileLayer(props.currentVectorLayer, props.timestamps)\n if (!props.isOem) {\n this.unMountAlertLayers()\n } else {\n this.updateAlertsVectorLayers(props)\n }\n }\n\n if (\n (props.isOem &&\n this.props.activeAlertsVectorLayers !== props.activeAlertsVectorLayers) ||\n !isEqual(this.props.activeAlertsVectorLayers, props.activeAlertsVectorLayers)\n ) {\n this.updateAlertsVectorLayers(props)\n }\n\n if (!isEqual(this.props.coordinates, props.coordinates) && !!props.coordinates) {\n const coords = fromLonLat([\n props.coordinates.center.lon,\n props.coordinates.center.lat,\n ])\n\n this.map.getView().animate({\n center: coords,\n duration: 500,\n zoom: props.coordinates.zoom,\n })\n this.addPositionMarker(coords)\n }\n\n if (this.props.activeFeature !== props.activeFeature) {\n if (\n this.props.currentVectorLayer &&\n props.activeFeature &&\n props.activeFeature.getProperties().alertType === undefined && // To not do the following for alerts\n this.props.currentVectorLayer.multiDirectional &&\n this.props.currentVectorLayer.guiBackend\n ) {\n const coordinates = props.activeFeature.getGeometry().getOrientedFlatCoordinates()\n const feature = new Feature(new LineString(coordinates, GeometryLayout.XY))\n feature.setProperties(props.activeFeature.getProperties())\n this.selectionLayer.getSource().clear()\n this.selectionLayer.getSource().addFeature(feature)\n } else {\n this.selectionLayer.getSource().clear()\n }\n }\n\n if (this.props.mapHome !== props.mapHome) {\n this.gotToHomeRegion()\n }\n\n return false\n }\n\n componentDidMount() {\n this.map.setTarget(this.ref.current)\n this.addVectorTileLayer(this.props.currentVectorLayer, this.props.timestamps)\n if (this.props.isOem) {\n this.mountAlertLayers(this.props.alertsVectorLayers)\n }\n this.addClickListener()\n this.addZoomListener()\n this.addViewListener()\n this.addRenderListener()\n this.startRefreshDataTimer()\n\n const resize_ob = new ResizeObserver(this.resizeCallback.bind(this))\n\n resize_ob.observe(this.ref.current)\n }\n\n mountAlertLayers(alertsVectorLayers) {\n this.unMountAlertLayers()\n const { severeRoughness, slippery, hydroplaning } = alertsVectorLayers\n this.mountAlertLayer('severeRoughness', severeRoughness)\n this.mountAlertLayer('slippery', slippery)\n this.mountAlertLayer('hydroplaning', hydroplaning)\n }\n\n mountAlertLayer(layerName: string, layer: any) {\n if (!this.alertVectorTileLayers[layerName]) {\n const alertLayer = createAlertsTileLayer(layer, [])\n this.alertVectorTileLayers[layerName] = alertLayer.alertsLayer\n if (layer.active) {\n this.map.addLayer(this.alertVectorTileLayers[layerName])\n }\n }\n }\n\n unMountAlertLayers() {\n this.unMountAlertLayer('slippery')\n this.unMountAlertLayer('severeRoughness')\n this.unMountAlertLayer('hydroplaning')\n }\n\n unMountAlertLayer(layerName: string) {\n if (this.alertVectorTileLayers[layerName]) {\n this.map.removeLayer(this.alertVectorTileLayers[layerName])\n this.alertVectorTileLayers[layerName] = null\n }\n }\n\n resizeCallback() {\n this.map.updateSize()\n }\n\n componentWillUnmount() {\n clearTimeout(this.refreshDataTimer)\n }\n\n gotToHomeRegion() {\n if (this.props.mapHome) {\n const coords = fromLonLat([this.props.mapHome.lon, this.props.mapHome.lat])\n this.map.getView().animate({\n center: coords,\n duration: 500,\n })\n }\n }\n\n shouldRefreshData(startDate, currentDate, wishedIntervalTimeInSeconds): boolean {\n var timeDiff = (currentDate - startDate) / 1000 // in seconds;\n return timeDiff > wishedIntervalTimeInSeconds\n }\n\n refreshVectorTileLayer(timestamps?: string[]) {\n if ((!timestamps && this.props.timestamps.length) || !this.props.currentVectorLayer || !this.props.currentVectorLayer.shouldAutoRefresh) {\n // Refresh timer initiated refresh but we are in interval or history mode, abort refresh.\n return\n }\n\n const url = getVectorTileUrl(this.props.currentVectorLayer, timestamps)\n\n this.vectorTileLayerSource.setUrl(url)\n this.vectorTileLayerSource.refresh() // clear tiles and refresh\n }\n\n startRefreshDataTimer() {\n if (this.refreshDataTimer) {\n clearTimeout(this.refreshDataTimer)\n }\n\n // Check if we just had a refresh and we should start the reset the inteval timer\n if (!this.timerStartedAt) {\n this.timerStartedAt = new Date()\n }\n\n if (this.shouldRefreshData(this.timerStartedAt, new Date(), REFRESH_INTERVAL)) {\n this.refreshVectorTileLayer()\n this.timerStartedAt = null\n }\n\n this.refreshDataTimer = setTimeout(() => {\n this.startRefreshDataTimer()\n }, 5000)\n }\n\n removeVectorTileLayer(layer?: VectorTileLayer) {\n if (layer) {\n this.map.removeLayer(layer)\n }\n }\n\n addVectorTileLayer(vectorLayer: NiraVectorLayer | null, timestamps: string[]) {\n if (!vectorLayer) {\n return\n }\n const { vectorTileLayer, vectorTileLayerSource } = createVectorTileLayer(\n vectorLayer,\n timestamps\n )\n\n this.vectorTileLayerSource = vectorTileLayerSource\n this.vectorTileLayer = vectorTileLayer\n\n this.vectorLayer = vectorLayer\n this.map.getLayers().insertAt(1, this.vectorTileLayer) // Layer 0 is the background map and the vectorTileLayer is desired right on top of the map\n }\n\n addPositionMarker(coords) {\n const marker = new Overlay({\n position: coords,\n offset: [-12, -12],\n element: this.markerRef.current,\n stopEvent: false,\n })\n\n this.map.addOverlay(marker)\n }\n\n addClickListener() {\n this.map.on('singleclick', (event) => {\n if (!this.vectorTileLayer) {\n return\n }\n\n if (this.props.currentGpsMode.type === GpsModeType.Track) {\n return\n }\n\n const features = this.map.getFeaturesAtPixel(event.pixel, {\n hitTolerance: 3,\n layerFilter: (layer) => layer !== this.selectionLayer,\n })\n if (features.length > 1 && features[0] === this.props.activeFeature) {\n this.props.featureClicked(features[1] || null)\n } else {\n this.props.featureClicked(features[0])\n }\n })\n }\n\n addZoomListener() {\n this.map.on('postrender', (e) => {\n const zoom = this.map.getView().getZoom() || 10\n if (zoom < MIN_ZOOM_LIMIT) {\n this.props.setShowError(true)\n } else {\n this.props.setShowError(false)\n }\n })\n }\n\n addViewListener() {\n this.map.on('postrender', (e) => {\n const view = this.map.getView()\n const [lon, lat] = toLonLat(view.getCenter() as Coordinate)\n this.props.viewChanged({ center: { lon, lat }, zoom: view.getZoom() || 10 })\n })\n }\n\n addRenderListener() {\n this.map.on('rendercomplete', (e) => {\n this.props.renderComplete()\n })\n }\n\n getTileLayer() {\n const niraSource = new olSource.XYZ(MAP_TILE_LAYERS.v2)\n\n const tileLayer = new TileLayer({\n source: niraSource,\n zIndex: 0,\n })\n\n return tileLayer\n }\n\n render() {\n return (\n <>\n <div ref={this.ref} className=\"mapComponentRoot\" id=\"map\" />\n <div ref={this.markerRef} id=\"marker\" className=\"mapMarker\">\n <span className=\"dot\"></span>\n </div>\n </>\n )\n }\n}\n","import { FeatureLike } from 'ol/Feature'\nimport Point from 'ol/geom/Point'\nimport Icon from 'ol/style/Icon'\nimport Stroke from 'ol/style/Stroke'\nimport Style from 'ol/style/Style'\n\nimport ArrowIcon from '../../../img/ol/arrow.png'\nimport NiraVectorLayer from '../layer/NiraVectorLayer'\n\nexport const highlightFeatureWithArrows = (feature: FeatureLike, resolution: number) => {\n const geometry = feature.getGeometry()\n const styles = []\n\n geometry.forEachSegment(function (start, end) {\n const dx = end[0] - start[0]\n const dy = end[1] - start[1]\n styles.push(\n new Style({\n geometry: new Point([start[0] + 0.5 * dx, start[1] + 0.5 * dy]),\n image: new Icon({\n src: ArrowIcon,\n anchor: [0.5, 0.5],\n rotateWithView: true,\n rotation: -Math.atan2(dy, dx),\n }),\n })\n )\n })\n return styles\n}\n\n/** Highlight a feature by adding an \"outline\" border */\nexport const highlightFeatureWithBorder = (\n feature: FeatureLike,\n resolution: number,\n vectorLayer: NiraVectorLayer\n) => {\n const geometry = feature.getGeometry()\n const styles = []\n const defaultStyles = vectorLayer.styleFunction(feature, resolution)\n\n let maxWidth = 1\n if (defaultStyles instanceof Object) {\n if (Array.isArray(defaultStyles)) {\n maxWidth = Math.max(...defaultStyles.map((style) => style.getStroke().getWidth()))\n } else {\n maxWidth = defaultStyles.getStroke().getWidth()\n }\n }\n\n geometry.forEachSegment(function (start, end) {\n styles.push(\n new Style({\n stroke: new Stroke({\n color: [255, 255, 255, 0.1],\n width: maxWidth + 6,\n }),\n })\n )\n styles.push(\n new Style({\n stroke: new Stroke({\n color: [255, 255, 255, 0.4],\n width: maxWidth + 4,\n }),\n })\n )\n styles.push(\n new Style({\n stroke: new Stroke({\n color: [255, 255, 255, 0.9],\n width: maxWidth + 2,\n }),\n })\n )\n if (defaultStyles instanceof Object) {\n if (Array.isArray(defaultStyles)) {\n defaultStyles.forEach((style) => {\n const newStyle = new Style({\n stroke: new Stroke({\n color: style.getStroke().getColor(),\n width: style.getStroke().getWidth() + 2,\n }),\n })\n styles.push(newStyle)\n })\n } else {\n const newStyle = new Style({\n stroke: new Stroke({\n color: defaultStyles.getStroke().getColor(),\n width: defaultStyles.getStroke().getWidth() + 2,\n }),\n })\n styles.push(newStyle)\n }\n }\n })\n return styles\n}\n","export default \"data:image/png;base64,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Ni0yYzZhZmRmZTVhY2IiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ZTlmOWIwZGMtYzgwOC00YmE4LTliNGEtZjQ0YTZhMTkyMzA5IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6MjQwN2VmNjAtMDMwNi00YTczLTk1MjMtYWM0ZTNhM2YxNmFjIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTWFjIE9TIgogICBHSU1QOlRpbWVTdGFtcD0iMTYzNTQwOTU3MDU4ODMxMiIKICAgR0lNUDpWZXJzaW9uPSIyLjEwLjI0IgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAgMi4xMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmU3MjBkMWVmLWJkYWMtNDM4Ni1hZmNiLTdmZDk1ZGZkYTIyZSIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChNYWMgT1MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIxLTEwLTI4VDEwOjI2OjEwKzAyOjAwIi8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PuhTlo4AAAB1UExURXxi9///////AP//AP+qVf+/QP/MM//VK//RLv/EO//MM//SLf/JNv/RLv/KNf/QL//KNf/OMf/MM//MM//MM//MM//MM//LNP/MM//LNP/MM//MM//MM//MM//LNP/MM//MM//MM//MM//MM//MM//MM//MM4wP0iUAAAABdFJOUwBA5thmAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB+UKHAgaCoTJkmoAAAAcSURBVAjXY2BgYGRAAEZGRmQ2HXm0YKP6B9mnACkvAFRWlo7ZAAAAAElFTkSuQmCC\"","import './SidebarItem.scss'\nimport { useTranslation } from 'react-i18next'\n\ninterface ColorBarProps {\n amount: number\n colors: string[]\n values: number[]\n leftLabel?: string\n rightLabel?: string\n}\n\nconst ColorBar: React.FC<ColorBarProps> = (props: ColorBarProps) => {\n const { t } = useTranslation()\n\n const gradient = 'linear-gradient(90deg,' + props.colors + ')'\n\n const getSubIndex = (start: number, end: number, value: number) => {\n return (value - start) / (end - start)\n }\n\n const getPositionLeft = (amount: number) => {\n const values = props.values.slice()\n const reverse = values[0] > values[1]\n if (reverse) values.reverse()\n let index = -1\n let subIndex = 1\n while (index < values.length - 2 && subIndex >= 1) {\n index++\n subIndex = getSubIndex(values[index], values[index + 1], amount)\n }\n subIndex = Math.min(1, Math.max(0, subIndex))\n let pos = (index + subIndex) / (values.length - 1)\n return (reverse ? 1 - pos : pos) * 100\n }\n\n return (\n <div className=\"colorBarWrapper\">\n {props.values && (\n <div className=\"textWrapper\">\n {props.values.map((value) => (\n <p key={value} className=\"text\">\n {value}\n </p>\n ))}\n </div>\n )}\n <div className=\"colorBar\" style={{ backgroundImage: gradient }}>\n <span\n className=\"marker\"\n style={{\n left: getPositionLeft(props.amount) + '%',\n transform: props.amount === 0 ? '' : 'translateX(-100%)',\n }}\n ></span>\n </div>\n <div className=\"textWrapper\">\n <p className=\"text\">{props.leftLabel ? t(props.leftLabel) : ''}</p>\n <p className=\"text\">{props.rightLabel ? t(props.rightLabel) : ''}</p>\n </div>\n </div>\n )\n}\n\nexport interface SidebarItemProps {\n header: string\n amount?: number\n amountText?: string\n text?: string\n unit?: string\n fixed?: number\n statusColor?: string\n colorBar?: ColorBarProps\n}\n\nconst SidebarItem = (props: SidebarItemProps) => {\n const { t } = useTranslation()\n\n if (props.amount === undefined && props.amountText === undefined) {\n return (\n <div className=\"sidebarItem\">\n <div className=\"header\">{t(props.header)}</div>\n <div className=\"amount\">{t('No value')}</div>\n </div>\n )\n }\n\n const amount = props.amount as number\n const valueString: string =\n props.amountText !== undefined\n ? props.amountText\n : props.fixed !== undefined\n ? amount.toFixed(props.fixed)\n : amount.toString()\n\n return (\n <div className=\"sidebarItem\">\n <div className=\"header\">\n {t(props.header)}\n {props.statusColor && (\n <span\n className=\"statusBanner\"\n style={{ backgroundColor: props.statusColor }}\n ></span>\n )}\n </div>\n <div className=\"amount\">\n {valueString}\n {props.unit && ' ' + t(props.unit)}\n </div>\n {props.text && <p className=\"text\">{t(props.text)}</p>}\n {props.colorBar && <ColorBar {...props.colorBar} />}\n </div>\n )\n}\n\nexport default SidebarItem\n","import { useTranslation } from 'react-i18next'\nimport { LegendWrapperComponent } from './LegendWrapper.types'\n\nimport './LegendWrapper.scss'\n\nconst LegendWrapper: LegendWrapperComponent = ({ position, children, title }) => {\n const { t } = useTranslation()\n return (\n <div className={`legendWrapper ${position}`}>\n {title && <div className=\"header\">{t(title)}</div>}\n {children}\n </div>\n )\n}\n\nexport default LegendWrapper\n","import LegendWrapper from './LegendWrapper.component'\n\nexport default LegendWrapper\n","import { useMemo } from 'react'\nimport LegendWrapper from '../LegendWrapper'\nimport { LegendComponent } from './GradientLegend.types'\n\nimport './GradientLegend.scss'\nimport { useTranslation } from 'react-i18next'\n\nconst GradientLegend: LegendComponent = ({\n colors,\n values,\n topLabel,\n bottomLabel,\n unit,\n}) => {\n const { t } = useTranslation()\n const gradient = useMemo(() => 'linear-gradient(180deg,' + colors + ')', [colors])\n return (\n <LegendWrapper position=\"middle\" title=\"\">\n <>\n {topLabel && <div className=\"subtitle\">{t(topLabel)}</div>}\n <div className=\"colorbarWrapper\">\n <div className=\"colorbar\" style={{ backgroundImage: gradient }} />\n <div className=\"text\">\n {values.map((value) => (\n <div key={value} className=\"label\">\n {value}\n </div>\n ))}\n </div>\n </div>\n {bottomLabel && <div className=\"subtitle\">{t(bottomLabel)}</div>}\n {unit && (\n <div className={`subtitle ${bottomLabel ? 'border' : ''}`}>[{unit}]</div>\n )}\n </>\n </LegendWrapper>\n )\n}\nexport default GradientLegend\n","import { useRef, useEffect, useMemo } from 'react'\n\nimport { TimeInterval, timeMinute, timeHour } from 'd3-time'\nimport { scaleTime } from 'd3-scale'\nimport { brushX } from 'd3-brush'\nimport { axisBottom } from 'd3-axis'\nimport { Selection, select } from 'd3-selection'\n\nimport { format } from 'date-fns'\nimport { TimelineComponent } from './Timeline.types'\n\nimport './Timeline.scss'\nimport { useState } from 'react'\n\nconst margin = { top: 10, right: 20, bottom: 20, left: 20 }\n\nconst TWO_HOURS = 2 * 60 * 60 * 1000\nconst THREE_HOURS = 3 * 60 * 60 * 1000\nconst SIX_HOURS = 6 * 60 * 60 * 1000\nconst TWELWE_HOURS = 12 * 60 * 60 * 1000\n\nconst getTickInterval = (start: Date, end: Date) => {\n const duration = end.getTime() - start.getTime()\n\n let tickInterval: TimeInterval\n if (duration <= TWO_HOURS) {\n tickInterval = timeMinute.every(10) as d3.TimeInterval\n } else if (duration <= SIX_HOURS) {\n tickInterval = timeMinute.every(30) as d3.TimeInterval\n } else if (duration <= TWELWE_HOURS) {\n tickInterval = timeHour.every(1) as d3.TimeInterval\n } else {\n tickInterval = timeHour.every(\n Math.ceil(duration / (12 * 60 * 60 * 1000))\n ) as d3.TimeInterval\n }\n\n return tickInterval\n}\n\nconst brushInterval = timeMinute.every(10) as TimeInterval\n\nconst Timeline: TimelineComponent = ({\n width,\n height,\n startDate,\n endDate,\n interval,\n setBounds,\n showSelection,\n}) => {\n const svgRef = useRef<any>()\n const [brushSelection, setBrushSelection] = useState<Selection<any, any, any, any>>()\n\n const x = useMemo(\n () =>\n scaleTime()\n .domain([startDate, endDate])\n .rangeRound([margin.left, width - margin.right]),\n [startDate, endDate, width]\n )\n const brush = useMemo(\n () =>\n brushX().extent([\n [margin.left, margin.top],\n [width - margin.right, height - margin.bottom],\n ]),\n [height, width]\n )\n\n useEffect(() => {\n if (!brushSelection) return\n if (brushSelection.filter('#interval').empty()) {\n // Init brush\n brushSelection.call(brush).attr('id', 'interval')\n const { onBrushStart, onBrushEnd } = (() => {\n // Event handlers\n let startEvent: Date[]\n return {\n onBrushStart(event: any) {\n // To prevent infinte loops\n if (!event.sourceEvent || !event.selection) return\n if (event.mode === 'handle') {\n const d0 = event.selection.map(x.invert)\n startEvent = d0\n }\n },\n onBrushEnd(event: any) {\n let d0\n if (event.type === 'end' && event.sourceEvent && !event.selection) {\n // Click event detected, use selection from previous start event since end event has no selection for click events\n d0 = startEvent\n } else if (!event.sourceEvent || !event.selection) {\n // Prevent infinite loops\n return\n } else {\n // Brush event ended, get selection\n d0 = event.selection.map(x.invert)\n }\n\n if (event.mode === 'handle') {\n if (Math.abs(d0[0].getTime() - d0[1].getTime()) > THREE_HOURS) {\n // Brush has interval longer than maximal interval\n if (startEvent[0].getTime() === d0[0].getTime()) {\n // Right interval changed\n d0[1] = new Date(d0[0].getTime() + THREE_HOURS)\n } else if (startEvent[1].getTime() === d0[1].getTime()) {\n // Left interval changed\n d0[0] = new Date(d0[1].getTime() - THREE_HOURS)\n }\n }\n }\n\n // Round selection to brush time interval\n const d1 = d0.map(brushInterval.round)\n // If empty when rounded, use floor instead.\n if (d1[0] >= d1[1]) {\n d1[0] = brushInterval.floor(d0[0])\n d1[1] = brushInterval.offset(d1[0])\n }\n setBounds(d1)\n },\n }\n })()\n brush.on('start', onBrushStart)\n brush.on('end', onBrushEnd)\n }\n\n // Adjust brush according to selection\n if (showSelection && interval) {\n brush.move(brushSelection, interval.map(x) as [number, number])\n } else {\n brush.clear(brushSelection)\n }\n }, [brush, brushSelection, x, interval, showSelection, setBounds])\n\n useEffect(() => {\n const svg = select(svgRef.current)\n svg.selectAll('g').remove()\n const tickInterval = getTickInterval(startDate, endDate)\n\n const xAxis = (g: any) =>\n g\n .attr('transform', `translate(0, ${height - margin.bottom})`)\n .call((g: any) =>\n g\n .append('g')\n .call(\n axisBottom(x)\n .ticks(tickInterval)\n .tickSize(-height + margin.top + margin.bottom)\n .tickFormat(() => '')\n )\n .call((g: any) =>\n g\n .select('.domain')\n .attr('fill', 'rgba(115, 151, 171, 0.5)')\n .attr('stroke', null)\n )\n .call((g: any) => g.selectAll('.tick line').attr('stroke', 'grey'))\n )\n .call((g: any) =>\n g\n .append('g')\n .call(\n axisBottom(x)\n .ticks(tickInterval)\n .tickPadding(0)\n .tickFormat((d: Date | d3.NumberValue) => {\n if (d instanceof Date) {\n if (d.getHours() === 0 && d.getMinutes() === 0) {\n return format(d, 'MM/d')\n }\n return format(d, 'HH:mm')\n }\n return ''\n })\n )\n .call((g: any) => g.select('.domain').remove())\n )\n\n svg.append('g').call(xAxis)\n setBrushSelection(svg.append('g'))\n }, [startDate, endDate, width, height, x, setBrushSelection])\n\n return (\n <div>\n <svg className=\"timeline\" ref={svgRef} height={height} width={width}></svg>\n </div>\n )\n}\nexport default Timeline\n","import Timeline from './Timeline.component'\n\nexport default Timeline\n","import i18n from 'i18next'\nimport en from 'date-fns/locale/en-GB'\nimport de from 'date-fns/locale/de'\nimport sv from 'date-fns/locale/sv'\nimport {\n Locale,\n format,\n isSameDay,\n isToday,\n set,\n startOfDay,\n endOfDay,\n eachHourOfInterval,\n eachMinuteOfInterval,\n startOfHour,\n endOfHour,\n startOfMonth,\n} from 'date-fns'\n\nconst locales: { [localeId: string]: Locale } = { en, de, sv }\n\n// Constants\nexport const NUMBER_OF_DAYS_IN_ONE_WEEK = 7\nexport const ISO_WEEK_START_DAY_INDEX = 1\n\n/**\n * Gets the current locale from i18n, if no locale is found EN-locale is used as fallback.\n *\n * @returns {Locale} - Current locale or EN-fallback locale.\n */\nexport const getDateFnsLocale = (): Locale => {\n const currentLanguage = i18n.language\n if (currentLanguage in locales) return locales[currentLanguage]\n else return en // Return default locale\n}\n\n/**\n * Creates a string that represents an interval.\n *\n * @param {Date} start - Start of interval to be formatted.\n * @param {Date} end - Start of interval to be formatted.\n * @returns {string} - Formatted string.\n */\nexport const formatInterval = (start: Date, end: Date): string => {\n if (isToday(start) && isToday(end))\n return `${i18n.t('Today')} ${format(start, 'HH:mm')}—${format(end, 'HH:mm')}`\n else if (isSameDay(start, end))\n return `${format(start, 'yyyy-MM-dd HH:mm')}—${format(end, 'HH:mm')}`\n else return `${format(start, 'yyyy-MM-dd HH:mm')}—${format(end, 'yyyy-MM-dd HH:mm')}`\n}\n\n/**\n * Rounds a given date down to nearest 10 minutes.\n *\n * @param {Date} d - Date to round.\n * @returns {Date} - Rounded date.\n */\nexport const roundToPast10mins = (d: Date): Date =>\n set(d, { minutes: Math.floor(d.getMinutes() / 10) * 10, seconds: 0, milliseconds: 0 })\n\n/**\n * Compares if two dates has the same year, month and day.\n *\n * @param {Date} d1 - Date to be compared to d2.\n * @param {Date} d2 - Date to be compared to d1.\n * @returns {boolean} - True if year, month and day of month is the same.\n */\nexport const isSameDate = (d1: Date, d2: Date): boolean =>\n d1.getDate() === d2.getDate() &&\n d1.getMonth() === d2.getMonth() &&\n d1.getFullYear() === d2.getFullYear()\n\n/**\n * Checks if two dates has the same hour.\n *\n * @param {Date} d1 - Date to be compared to d2.\n * @param {Date} d2 - Date to be compared to d1.\n * @returns {boolean} - True if both dates has the same hour of day.\n */\nexport const isSameHour = (d1: Date, d2: Date): boolean => d1.getHours() === d2.getHours()\n\n/**\n * Checks if two dates has the same minute.\n *\n * @param {Date} d1 - Date to be compared to d2.\n * @param {Date} d2 - Date to be compared to d1.\n * @returns {boolean} - True if both dates has the same miniute of hour.\n */\nexport const isSameMinute = (d1: Date, d2: Date): boolean =>\n d1.getMinutes() === d2.getMinutes()\n\n/**\n * Creates an array with dates where each element repsresent one hour of the day.\n *\n * @param {Date} d - Date to return hours for\n * @returns {Date[]} - Array of dates where each element represent one hour.\n */\nexport const getHoursInDay = (d: Date): Date[] =>\n eachHourOfInterval({ start: startOfDay(d), end: endOfDay(d) })\n\n/**\n * Creates an array with dates where each element repsresent a minute of a specified hour.\n *\n * @param {Date} d - Date to return minutes for\n * @param {number} step - Step size for minutes to be returned.\n * @returns {Date[]} - Array of dates where each element represent minutes in a the given hour.\n */\nexport const getMinutesInHour = (d: Date, step: number = 1): Date[] =>\n eachMinuteOfInterval({ start: startOfHour(d), end: endOfHour(d) }, { step })\n\n/**\n * Checks if next month for given date is the current month or in the future.\n *\n * @param {Date} d - Date to be evaluated.\n * @returns {boolean} - True if month of date(d) is current or in future\n */\nexport const monthIsCurrentOrFuture = (d: Date): boolean =>\n d.getTime() >= startOfMonth(new Date()).getTime()\n","import { useRef, useMemo, useEffect } from 'react'\nimport { usePopper } from 'react-popper'\nimport Button from '../button'\nimport useClickOutside from '../../hooks/clickOutside'\nimport { useTranslation } from 'react-i18next'\nimport {\n isSameDate,\n isSameHour,\n isSameMinute,\n getHoursInDay,\n getMinutesInHour,\n monthIsCurrentOrFuture,\n} from '../../utils/date'\nimport { format } from 'date-fns'\n\nimport { DatepickerView } from './Datepicker.types'\nimport './Datepicker.scss'\n\nexport const DatepickerViewComponent: DatepickerView = ({\n selectedDate,\n filter,\n handleDateSelect,\n handleHourSelect,\n handleMinuteSelect,\n handleMonthChange,\n handleTodayClick,\n datesToRender,\n weekdayLabels,\n locale,\n isVisible,\n setIsVisible,\n minuteSteps,\n showTimeSelect,\n}) => {\n const referenceElement = useRef<HTMLDivElement>(null)\n const selectedHourElement = useRef<HTMLDivElement>(null)\n const selectedMinuteElement = useRef<HTMLDivElement>(null)\n const popperElement = useRef<HTMLDivElement>(null)\n const outsideRef = useClickOutside(() => setIsVisible(false))\n const { t } = useTranslation()\n const { styles, attributes, update } = usePopper(\n referenceElement.current,\n popperElement.current,\n {\n placement: 'top',\n modifiers: [\n {\n name: 'offset',\n enabled: true,\n options: {\n offset: [0, 20],\n },\n },\n ],\n }\n )\n\n useEffect(() => {\n if (isVisible) {\n selectedHourElement.current?.scrollIntoView()\n selectedMinuteElement.current?.scrollIntoView()\n }\n }, [isVisible])\n\n const renderMinuteList = useMemo(\n () =>\n getMinutesInHour(selectedDate, minuteSteps).map((d) => {\n const selected = isSameMinute(d, selectedDate)\n return (\n <div\n ref={selected ? selectedMinuteElement : undefined}\n className={`item ${selected ? 'selected' : ''} ${\n filter && filter(d) ? 'disabled' : ''\n }`}\n onClick={() => handleMinuteSelect(d)}\n key={`minute-${d.toString()}`}\n >\n {format(d, 'mm')}\n </div>\n )\n }),\n [selectedDate, filter, minuteSteps, handleMinuteSelect]\n )\n\n const renderHourList = useMemo(\n () =>\n getHoursInDay(selectedDate).map((d) => {\n const selected = isSameHour(d, selectedDate)\n return (\n <div\n ref={selected ? selectedHourElement : undefined}\n className={`item ${selected ? 'selected' : ''} ${\n filter && filter(d) ? 'disabled' : ''\n }`}\n key={`hour-${d.toString()}`}\n onClick={() => handleHourSelect(d)}\n >\n {format(d, 'HH')}\n </div>\n )\n }),\n [selectedDate, filter, handleHourSelect]\n )\n\n const renderDateHeader = useMemo(\n () => (\n <div className=\"date-header\">\n <div className=\"nav-button\" onClick={() => handleMonthChange('dec')}>\n {'<'}\n </div>\n <div className=\"label\">{format(selectedDate, 'MMMM yyyy', { locale })}</div>\n <div\n className={`nav-button ${\n monthIsCurrentOrFuture(selectedDate) ? 'disabled' : ''\n }`}\n onClick={() =>\n !monthIsCurrentOrFuture(selectedDate) ? handleMonthChange('inc') : null\n }\n >\n {'>'}\n </div>\n <div className=\"today-button\" onClick={() => handleTodayClick()}>\n {t('Today')}\n </div>\n </div>\n ),\n [selectedDate, handleTodayClick, handleMonthChange, locale, t]\n )\n\n const renderDates = useMemo(\n () =>\n datesToRender.map((d) => (\n <div\n className={`date item ${isSameDate(d, selectedDate) ? 'selected' : ''} ${\n filter && filter(d) ? 'disabled' : ''\n }`}\n key={`date-${d.toString()}`}\n onClick={() => handleDateSelect(d)}\n >\n {d.getDate()}\n </div>\n )),\n [selectedDate, filter, handleDateSelect, datesToRender]\n )\n\n return (\n <div className=\"datepicker-wrapper\">\n <div ref={outsideRef}>\n <div ref={referenceElement}>\n <Button\n onClick={() => {\n setIsVisible(!isVisible)\n update && update()\n }}\n >\n <span>\n {format(selectedDate, 'yyyy-MM-dd')}\n {showTimeSelect && (\n <>\n <span className=\"space-between\" />\n {format(selectedDate, 'HH:mm')}\n </>\n )}\n </span>\n </Button>\n </div>\n <div\n className={`datepicker ${isVisible ? 'show' : 'hidden'}`}\n ref={popperElement}\n style={styles.popper}\n {...attributes.popper}\n >\n <div className=\"date-container\">\n <div className=\"date-header-container\">\n {renderDateHeader}\n <div className=\"date-grid\">{weekdayLabels}</div>\n </div>\n <div className=\"date-grid\">{renderDates}</div>\n </div>\n {showTimeSelect && (\n <>\n <div className=\"time-container border-left\">\n <div className=\"header\">{t('Hour')}</div>\n <div className=\"list\">{renderHourList}</div>\n </div>\n <div className=\"time-container\">\n <div className=\"header right\">{t('Minute')}</div>\n <div className=\"list\">{renderMinuteList}</div>\n </div>\n </>\n )}\n </div>\n </div>\n </div>\n )\n}\n","import { MobileDatepickerComponent } from './Datepicker.types'\nimport { format, parse } from 'date-fns'\n\nimport './MobileDatepicker.scss'\n\nexport const MobileDatepicker: MobileDatepickerComponent = ({ selected, onSelect }) => {\n return (\n <>\n <input\n type=\"datetime-local\"\n name=\"endtime\"\n className=\"mobile-datepicker\"\n value={format(selected, \"yyyy-MM-dd'T'HH:mm\")}\n onChange={(e) => {\n const d = parse(e.target.value, \"yyyy-MM-dd'T'HH:mm\", new Date())\n onSelect(d)\n }}\n />\n </>\n )\n}\n","import { Datepicker } from './Datepicker.component'\n\nexport default Datepicker\n","import { useMemo, useState } from 'react'\nimport { DatepickerComponent } from './Datepicker.types'\nimport {\n NUMBER_OF_DAYS_IN_ONE_WEEK,\n ISO_WEEK_START_DAY_INDEX,\n getDateFnsLocale,\n} from '../../utils/date'\nimport {\n startOfMonth,\n endOfMonth,\n eachWeekOfInterval,\n eachDayOfInterval,\n lastDayOfWeek,\n format,\n subMonths,\n addMonths,\n set,\n setHours,\n setMinutes,\n startOfDay,\n} from 'date-fns'\nimport { DatepickerViewComponent } from './Datepicker.view'\nimport { MobileDatepicker } from './MobileDatepicker'\nimport { isMobileOnly } from 'react-device-detect'\n\nexport const Datepicker: DatepickerComponent = ({\n selected,\n onSelect,\n filter,\n minuteSteps,\n showTimeSelect,\n}) => {\n const [isVisble, setIsVisible] = useState(false)\n\n const locale = getDateFnsLocale()\n\n const datesToRender = useMemo(() => {\n const weeksInMonth = eachWeekOfInterval(\n { start: startOfMonth(selected), end: endOfMonth(selected) },\n { weekStartsOn: locale.options?.weekStartsOn ?? ISO_WEEK_START_DAY_INDEX }\n )\n return eachDayOfInterval({\n start: weeksInMonth[0],\n end: lastDayOfWeek(weeksInMonth[weeksInMonth.length - 1], {\n weekStartsOn: locale.options?.weekStartsOn ?? ISO_WEEK_START_DAY_INDEX,\n }),\n })\n }, [selected, locale.options?.weekStartsOn])\n\n const weekdayLabels = useMemo(\n () =>\n datesToRender.slice(0, NUMBER_OF_DAYS_IN_ONE_WEEK).map((d) => (\n <div className=\"date label\" key={`label-${d.toString()}`}>\n {format(d, 'eeeeee', { locale })}\n </div>\n )),\n\n // Only needs to be recalculated when locale changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [locale]\n )\n\n const handleMonthChange = (operator: 'inc' | 'dec') => {\n if (operator === 'inc') {\n onSelect(addMonths(selected, 1))\n } else if (operator === 'dec') {\n onSelect(subMonths(selected, 1))\n }\n }\n\n const setDate = (d: Date) => {\n let date = set(selected, {\n year: d.getFullYear(),\n month: d.getMonth(),\n date: d.getDate(),\n })\n onSelect(date)\n\n if (!showTimeSelect) {\n setIsVisible(false)\n }\n }\n\n const handleHourSelect = (d: Date) => {\n const date = setHours(selected, d.getHours())\n onSelect(date)\n }\n\n const handleMinuteSelect = (d: Date) => {\n const date = setMinutes(selected, d.getMinutes())\n onSelect(date)\n }\n\n const handleTodayClick = () => {\n const date = startOfDay(new Date())\n setDate(date)\n }\n\n return isMobileOnly ? (\n <MobileDatepicker\n selected={selected}\n onSelect={(d: Date) => {\n onSelect(d)\n if (onSelect) {\n onSelect(d)\n }\n }}\n />\n ) : (\n <DatepickerViewComponent\n selectedDate={selected}\n filter={filter}\n handleDateSelect={setDate}\n handleHourSelect={handleHourSelect}\n handleMinuteSelect={handleMinuteSelect}\n handleMonthChange={handleMonthChange}\n handleTodayClick={handleTodayClick}\n datesToRender={datesToRender}\n weekdayLabels={weekdayLabels}\n locale={locale}\n isVisible={isVisble}\n setIsVisible={setIsVisible}\n minuteSteps={minuteSteps}\n showTimeSelect={showTimeSelect}\n />\n )\n}\n","import { useTranslation } from 'react-i18next'\nimport { formatInterval } from '../../../utils/date'\nimport { format } from 'date-fns'\nimport type { TimeMode } from '../../../pages/maps/Maps.types'\n\ninterface Props {\n mode: TimeMode\n}\n\nconst ModeDescription: React.FC<Props> = ({ mode }) => {\n const { t } = useTranslation()\n return (\n <>\n {mode.label === 'live' && t('Showing live data')}\n {mode.label === 'history' &&\n `${t('Historical data from')} ${format(mode.timestamps[0], 'yyyy-MM-dd HH:mm')}`}\n {mode.label === 'interval' &&\n mode.timestamps[0] &&\n mode.timestamps[1] &&\n `${t('Worst conditions for')}: ${formatInterval(\n mode.timestamps[0],\n mode.timestamps[1]\n )}`}\n </>\n )\n}\n\nexport default ModeDescription\n","import { useMemo, useState } from 'react'\nimport { TimeSliderComponent } from './TimeSlider.types'\nimport Timeline from '../../../timeline'\nimport { roundToPast10mins } from '../../../../utils/date'\nimport { subMilliseconds, roundToNearestMinutes, isFuture } from 'date-fns'\nimport { isMobileOnly } from 'react-device-detect'\nimport Datepicker from '../../../datepicker'\nimport { TimeMode } from '../../../../pages/maps/Maps.types'\nimport { INTERVAL_MAX_DURATION } from '../../MapConstants'\nimport ModeDescription from '../ModeDescription'\n\nimport './TimeSlider.scss'\nimport Dropdown, { DropdownOption } from '../../../dropdown'\nimport Button from '../../../button'\nimport { useCallback, useEffect } from 'react'\n\nconst ONE_HOUR = 60 * 60 * 1000 // One hour in milliseconds\n\nconst rangeOptions: DropdownOption[] = [\n { label: '1h', value: 1 * ONE_HOUR },\n { label: '2h', value: 2 * ONE_HOUR },\n { label: '3h', value: 3 * ONE_HOUR },\n { label: '6h', value: 6 * ONE_HOUR },\n { label: '12h', value: 12 * ONE_HOUR },\n { label: '24h', value: 24 * ONE_HOUR },\n { label: '48h', value: 48 * ONE_HOUR },\n { label: '72h', value: 72 * ONE_HOUR },\n]\n\nconst TimeSlider: TimeSliderComponent = ({ mode, changeMode }) => {\n const [rangeLength, setRangeLength] = useState<DropdownOption>(rangeOptions[0])\n const [intervalMaxDate, setIntervalMaxDate] = useState<Date>(\n roundToPast10mins(\n mode.timestamps.length > 0\n ? mode.timestamps[mode.timestamps.length - 1]\n : new Date()\n )\n )\n const intervalMinDate = useMemo(\n () => subMilliseconds(intervalMaxDate, rangeLength.value),\n [intervalMaxDate, rangeLength]\n )\n const [previousMode, setPreviousMode] = useState<TimeMode>({\n label: 'history',\n timestamps: [intervalMaxDate],\n })\n\n const dropdownOptions = useMemo(() => {\n if (isMobileOnly) {\n return rangeOptions.filter((option) => option.value <= INTERVAL_MAX_DURATION)\n }\n return rangeOptions\n }, [])\n\n const handleRangeChanged = (range: any) => {\n setRangeLength(range)\n if (isMobileOnly) {\n const [start, end] = [\n subMilliseconds(intervalMaxDate, range.value),\n intervalMaxDate,\n ]\n handleChangeMode({ label: 'interval', timestamps: [start, end] })\n }\n }\n\n const handleChangeMode = useCallback(\n (nextMode: TimeMode) => {\n setPreviousMode(mode)\n changeMode(nextMode)\n },\n [setPreviousMode, changeMode, mode]\n )\n\n const setBounds = useCallback(\n (d: [Date, Date]) => handleChangeMode({ label: 'interval', timestamps: d }),\n [handleChangeMode]\n )\n\n // Handle when range shrinks past interval\n useEffect(() => {\n if (mode.label === 'interval' && mode.timestamps.length === 2) {\n if (mode.timestamps[1] <= intervalMinDate) {\n // Interval outside timeline, switch to history mode\n handleChangeMode({ label: 'history', timestamps: [intervalMaxDate] })\n } else if (mode.timestamps[0] < intervalMinDate) {\n // Interval starts outside timeline, set start to lower limit\n handleChangeMode({\n label: 'interval',\n timestamps: [intervalMinDate, mode.timestamps[1]],\n })\n }\n }\n }, [mode, intervalMinDate, intervalMaxDate, handleChangeMode])\n\n const liveModeDateUpdate = () => {\n if (mode.label === 'live') {\n setIntervalMaxDate(roundToPast10mins(new Date()))\n }\n }\n useEffect(liveModeDateUpdate, [mode])\n useEffect(() => {\n const timeout = setTimeout(liveModeDateUpdate, 10000)\n return () => clearTimeout(timeout)\n })\n\n return (\n <div className=\"timeSliderWrapper\">\n <div className=\"timeSlider\">\n <div className={`toolRow ${isMobileOnly ? 'mobile' : ''}`}>\n <div className=\"live-button-wrapper\">\n <Button\n color=\"red\"\n active={mode.label === 'live'}\n onClick={() => {\n if (mode.label === 'live') {\n // Change to previous mode\n handleChangeMode(previousMode)\n } else {\n handleChangeMode({ label: 'live', timestamps: [] })\n }\n }}\n >\n Live\n </Button>\n </div>\n\n <div className={'pullRight'}>\n <div className=\"dropdownWrapper\">\n <Dropdown\n options={dropdownOptions}\n onSelect={(selectedRangeLength) =>\n handleRangeChanged(selectedRangeLength)\n }\n defaultValue={dropdownOptions[0]}\n expandedDirection=\"up\"\n />\n </div>\n <Datepicker\n selected={intervalMaxDate}\n onSelect={(d: Date) => {\n d = roundToNearestMinutes(d, { nearestTo: 10 })\n if (isFuture(d)) {\n d = roundToPast10mins(new Date())\n }\n setIntervalMaxDate(d)\n handleChangeMode({ label: 'history', timestamps: [d] })\n }}\n filter={(d: Date) => isFuture(d)}\n minuteSteps={10}\n showTimeSelect={true}\n />\n </div>\n </div>\n {!isMobileOnly && (\n <Timeline\n width={580}\n height={60}\n startDate={intervalMinDate}\n endDate={intervalMaxDate}\n interval={\n mode.label === 'interval' ? (mode.timestamps as [Date, Date]) : undefined\n }\n setBounds={setBounds}\n showSelection={mode.label === 'interval'}\n />\n )}\n <div className=\"centerText\">\n <ModeDescription mode={mode} />\n </div>\n </div>\n </div>\n )\n}\n\nexport default TimeSlider\n","import TimeSlider from './TimeSlider.component'\nexport default TimeSlider\n","import React from 'react'\n\nimport { FeatureLike } from 'ol/Feature'\nimport { OrderFunction } from 'ol/render'\nimport Stroke from 'ol/style/Stroke'\nimport Style from 'ol/style/Style'\n\nimport chroma from 'chroma-js'\nimport SidebarItem from '../../mapSidebar/SidebarItem'\nimport * as MapConstants from '../MapConstants'\nimport GradientLegend from '../overlay/Legend/GradientLegend/GradientLegend.component'\nimport TimeSlider from '../overlay/TimeSlider'\nimport { MAX_ZOOM_LIMIT, MIN_ZOOM_LIMIT } from '../vectorlayers/NiraVectorTileLayers'\nimport NiraVectorLayer from './NiraVectorLayer'\n\nexport interface ScaleProps {\n startLabel: string\n endLabel: string\n unit: string\n flipLegend?: boolean\n}\n\nexport interface SidebarProps {\n displayUnitInSidebar: boolean\n fixed?: number\n}\n\nexport default abstract class NiraLinearScaleVectorLayer implements NiraVectorLayer {\n abstract name: string\n abstract bundleName: string\n abstract visibleOem: boolean\n abstract visibleMaintenance: boolean\n minZoomLevel = MIN_ZOOM_LIMIT\n maxZoomLevel = MAX_ZOOM_LIMIT\n guiBackend = true\n shouldAutoRefresh = false\n abstract functionalRoadClassZoomLevels: Record<1 | 2 | 3 | 4 | 5, number>\n abstract valueExtractor(feature: FeatureLike): number | undefined\n\n renderOrderFunction?: OrderFunction = undefined\n multiDirectional = false\n\n timeSelectTool = (props: any) => <TimeSlider {...props} />\n\n abstract scaleProps: ScaleProps\n legend = () => {\n const scaleProps = this.scaleProps\n const colors = scaleProps.flipLegend\n ? this.getColors().slice().reverse()\n : this.getColors()\n const values = scaleProps.flipLegend\n ? this.getValueDomain().slice().reverse()\n : this.getValueDomain()\n return (\n <GradientLegend\n colors={colors}\n values={values}\n topLabel={scaleProps.flipLegend ? scaleProps.endLabel : scaleProps.startLabel}\n bottomLabel={scaleProps.flipLegend ? scaleProps.startLabel : scaleProps.endLabel}\n unit={scaleProps.unit}\n />\n )\n }\n\n abstract sidebarProps: SidebarProps\n abstract getSidebarHeader(): string\n renderSidebarContent(feature: FeatureLike) {\n const currentValue = this.valueExtractor(feature)\n const scaleProps = this.scaleProps\n return (\n <SidebarItem\n header={this.getSidebarHeader()}\n amount={currentValue}\n fixed={this.sidebarProps.fixed}\n unit={this.sidebarProps.displayUnitInSidebar ? scaleProps.unit : undefined}\n colorBar={{\n amount: currentValue as number,\n colors: this.getColors(),\n values: this.getValueDomain(),\n leftLabel: scaleProps.startLabel,\n rightLabel: scaleProps.endLabel,\n }}\n />\n )\n }\n\n abstract getColors(): Array<string>\n abstract getValueDomain(): Array<number>\n colorScale = chroma.scale(this.getColors()).domain(this.getValueDomain()).mode('hsl')\n\n dataToFeatures(data, zoomLevel) {\n return []\n }\n\n styles: { [x: string]: Style } = {}\n styleFunction(feature: FeatureLike) {\n const value = this.valueExtractor(feature)\n if (value === undefined || isNaN(value)) return undefined\n const index = Math.min(\n Math.max(value, this.getValueDomain()[0]),\n this.getValueDomain()[this.getValueDomain().length - 1]\n )\n const color = this.colorScale(index).hex()\n if (this.styles[color] === undefined) {\n this.styles[color] = new Style({\n stroke: new Stroke({\n color,\n width: MapConstants.SEGMENT_STROKE_WIDTH,\n }),\n })\n }\n return this.styles[color]\n }\n}\n","import { useState, useEffect, useCallback } from 'react'\nimport { DateTimePickerComponent } from './DateTimePicker.types'\nimport { roundToPast10mins } from '../../../../utils/date'\nimport { roundToNearestMinutes, isFuture } from 'date-fns'\nimport Datepicker from '../../../datepicker'\nimport { TimeMode } from '../../../../pages/maps/Maps.types'\n\nimport './DateTimePicker.scss'\nimport Button from '../../../button'\nimport ModeDescription from '../ModeDescription'\n\nconst DateTimePicker: DateTimePickerComponent = ({ mode, changeMode }) => {\n const [previousMode, setPreviousMode] = useState<TimeMode>({\n label: 'history',\n timestamps: [\n roundToPast10mins(mode.timestamps[mode.timestamps.length - 1] || new Date()),\n ],\n })\n\n useEffect(() => {\n if (!['live', 'history'].includes(mode.label)) {\n const lastTimestamp = mode.timestamps[mode.timestamps.length - 1]\n if (lastTimestamp) {\n changeMode({\n label: 'history',\n timestamps: [lastTimestamp],\n })\n } else {\n changeMode({ label: 'live', timestamps: [] })\n }\n }\n })\n\n const selected =\n mode.label === 'live' ? roundToPast10mins(new Date()) : mode.timestamps[0]\n\n const handleChangeMode = useCallback(\n (nextMode: TimeMode) => {\n setPreviousMode(mode)\n changeMode(nextMode)\n },\n [setPreviousMode, changeMode, mode]\n )\n\n return (\n <div className=\"dateTimePickerWrapper\">\n <div className=\"dateTimePicker\">\n <div className=\"toolRow\">\n <div className=\"liveButtonWrapper\">\n <Button\n color=\"red\"\n active={mode.label === 'live'}\n onClick={() => {\n if (mode.label === 'live') {\n // Change to previous mode\n handleChangeMode(previousMode)\n } else {\n handleChangeMode({ label: 'live', timestamps: [] })\n }\n }}\n >\n Live\n </Button>\n </div>\n\n <div className=\"pullRight\">\n <Datepicker\n selected={selected}\n onSelect={(d: Date) => {\n d = roundToNearestMinutes(d, { nearestTo: 10 })\n if (isFuture(d)) {\n d = roundToPast10mins(new Date())\n }\n handleChangeMode({ label: 'history', timestamps: [d] })\n }}\n filter={(d: Date) => isFuture(d)}\n minuteSteps={10}\n showTimeSelect={true}\n />\n </div>\n </div>\n <div className=\"description\">\n <ModeDescription mode={mode} />\n </div>\n </div>\n </div>\n )\n}\n\nexport default DateTimePicker\n","import DateTimePicker from './DateTimePicker.component'\nexport default DateTimePicker\n","import React from 'react'\n\nimport { FeatureLike } from 'ol/Feature'\n\nimport NiraLinearScaleVectorLayer from './NiraLinearScaleVectorLayer'\nimport DateTimePicker from '../overlay/DateTimePicker'\n\nexport default class NiraAirTemperatureVectorLayer extends NiraLinearScaleVectorLayer {\n name = 'Air Temperature'\n bundleName = 'vehicle-weather-aggregation'\n visibleOem = true\n visibleMaintenance = false\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n timeSelectTool = (props: any) => <DateTimePicker {...props} />\n\n scaleProps = {\n startLabel: '',\n endLabel: '',\n unit: '°C',\n flipLegend: true,\n }\n sidebarProps = { displayUnitInSidebar: true, fixed: 1 }\n getSidebarHeader() {\n return 'Air Temperature'\n }\n getColors(): string[] {\n return ['hsl(227,48%,49%)', 'hsl(0,100%,65%)']\n }\n getValueDomain(): number[] {\n return [-6, 6]\n }\n\n valueExtractor(feature: FeatureLike) {\n return Number(feature.getProperties()['Temperature-Average'])\n }\n}\n","import LegendWrapper from '../LegendWrapper'\nimport { FrictionLegendComponent } from './FrictionLegend.types'\n\nimport { useTranslation } from 'react-i18next'\n\nimport './FrictionLegend.scss'\n\nconst FrictionLegend: FrictionLegendComponent = ({ conditions, description }) => {\n const { t } = useTranslation()\n\n return (\n <LegendWrapper position=\"bottom\" title=\"Condition\">\n {conditions.map((condition) => {\n const item = description(condition)\n return (\n <div key={condition} className=\"legendItem\">\n <div className=\"colorIndicator\" style={{ backgroundColor: item.color }} />\n {t(item.short)}\n </div>\n )\n })}\n </LegendWrapper>\n )\n}\nexport default FrictionLegend\n","import { FeatureLike } from 'ol/Feature'\nimport Stroke from 'ol/style/Stroke'\nimport Style from 'ol/style/Style'\n\nimport { ColorStyle } from '../../../utils/Interfaces'\nimport SidebarItem from '../../mapSidebar/SidebarItem'\nimport * as MapConstants from '../MapConstants'\nimport { FrictionLegend } from '../overlay/Legend/FrictionLegend'\nimport TimeSlider from '../overlay/TimeSlider'\nimport { MAX_ZOOM_LIMIT, MIN_ZOOM_LIMIT } from '../vectorlayers/NiraVectorTileLayers'\nimport NiraVectorLayer from './NiraVectorLayer'\n\nexport type FrictionLevel = 'good' | 'semi' | 'slippery'\n\ninterface FrictionDescription {\n short: string\n long: string\n color: string\n limit: number\n}\n\nconst FRICTION_DESCRIPTIONS: Record<FrictionLevel, FrictionDescription> = {\n slippery: {\n short: 'Slippery',\n long: 'Critical slipperiness',\n color: '#FF0000', //red\n limit: 0.35,\n },\n semi: {\n short: 'Semi-slippery',\n long: 'Semi-slippery conditions',\n color: '#FFFF00', //yellow\n limit: 0.5,\n },\n good: {\n short: 'Good',\n long: 'Good conditions',\n color: '#008000', //green\n limit: Infinity,\n },\n}\n\nexport default class NiraFrictionVectorLayer implements NiraVectorLayer {\n name = 'Fleet Traction'\n bundleName = 'maintenance-aggregation'\n visibleOem = true\n visibleMaintenance = true\n multiDirectional = true\n guiBackend = true\n shouldAutoRefresh = true\n minZoomLevel = MIN_ZOOM_LIMIT\n maxZoomLevel = MAX_ZOOM_LIMIT\n\n dataToFeatures = () => []\n\n description = (friction: FrictionLevel | number): FrictionDescription => {\n if (typeof friction === 'number') {\n return (\n Object.values(FRICTION_DESCRIPTIONS).find(\n (description) => description.limit > friction\n ) || FRICTION_DESCRIPTIONS.good\n )\n }\n return FRICTION_DESCRIPTIONS[friction]\n }\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n timeSelectTool = (props: any) => <TimeSlider {...props} />\n legend() {\n return (\n <FrictionLegend\n conditions={Object.keys(FRICTION_DESCRIPTIONS) as FrictionLevel[]}\n description={this.description}\n />\n )\n }\n\n valueExtractor(feature: FeatureLike) {\n return Number(feature.getProperties()['Friction-Average'])\n }\n\n renderOrderFunction(a: FeatureLike, b: FeatureLike) {\n return this.valueExtractor(b) - this.valueExtractor(a)\n }\n\n renderSidebarContent(feature: FeatureLike) {\n const properties = feature.getProperties()\n const frictionUnit = 'μ'\n const frictionAverage = properties['Friction-Average'] as number\n const frictionMin = properties['Friction-Min'] as number\n const frictionMax = properties['Friction-Max'] as number\n const numberOfTGPs = properties['NumberOfTGPs'] as number\n let standardDeviation = properties['Friction-Average-StandardDeviation'] as number\n standardDeviation = standardDeviation < 0.001 ? 0.001 : standardDeviation\n const frictionDescription = this.description(frictionAverage)\n return (\n <>\n <SidebarItem\n header={'Average Friction'}\n amount={frictionAverage}\n unit={frictionUnit}\n fixed={2}\n text={frictionDescription.long}\n statusColor={frictionDescription.color}\n />\n <SidebarItem\n header={'Min Friction'}\n amount={frictionMin}\n unit={frictionUnit}\n fixed={2}\n />\n <SidebarItem\n header={'Max Friction'}\n amount={frictionMax}\n unit={frictionUnit}\n fixed={2}\n />\n <SidebarItem\n data-testid=\"id_standard_deviation\"\n header={'Standard Deviation'}\n amount={standardDeviation}\n unit={frictionUnit}\n fixed={3}\n />\n <SidebarItem header={'Number of Measurements'} amount={numberOfTGPs} />\n </>\n )\n }\n\n styles: ColorStyle[] = Object.values(FRICTION_DESCRIPTIONS).map((description) => {\n return {\n limit: description.limit,\n style: new Style({\n stroke: new Stroke({\n color: description.color,\n width: MapConstants.SEGMENT_STROKE_WIDTH,\n }),\n }),\n }\n })\n styleFunction(feature: FeatureLike) {\n const value = this.valueExtractor(feature)\n if (value === undefined) return undefined\n return this.styles.find((style) => style.limit > value)?.style\n }\n}\n","import React from 'react'\n\nimport Feature, { FeatureLike } from 'ol/Feature'\nimport Geometry from 'ol/geom/Geometry'\nimport VectorTileLayer from 'ol/layer/VectorTile'\nimport { OrderFunction } from 'ol/render'\nimport VectorTileSource from 'ol/source/VectorTile'\nimport Icon from 'ol/style/Icon'\nimport Style from 'ol/style/Style'\n\nimport NiraAlertVectorLayer, { NiraAlertsVectorLayerName } from './NiraAlertVectorLayer'\n\nimport HYDROPLANINGS_ICON from './icons/Aquaplaning.png'\n\nexport default class NiraHydroplaningAlertsVectorLayer implements NiraAlertVectorLayer {\n name = 'Hydroplaning'\n layerName: NiraAlertsVectorLayerName = 'hydroplaning'\n bundleName = 'hydroplaning-alerts'\n description = 'Hydroplaning Alerts'\n multiDirectional = false\n active = true\n rsaApi = true\n rsaApiBundleName = 'hydroplaning'\n\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n\n source: VectorTileSource | null = null\n layer: VectorTileLayer | null = null\n minZoom = 7\n maxZoom = 12\n\n renderOrderFunction?: OrderFunction | undefined\n\n timeSelectTool = (props: any) => <></>\n\n valueExtractor = (feature: FeatureLike) => 1\n\n renderSidebarContent = (feature: FeatureLike) => {\n return <></>\n }\n\n filterFunction = (\n features: Feature<Geometry>[],\n vectorLayer: NiraAlertVectorLayer,\n zoomLevel: number\n ) => (features.length > 0 ? [features[0]] : features)\n\n styleFunction = (feature: FeatureLike) => {\n const props = feature.getProperties()\n const icon = new Icon({\n anchor: [0, 0],\n size: [50, 50],\n imgSize: [50, 50],\n src: HYDROPLANINGS_ICON,\n anchorXUnits: 'fraction',\n anchorYUnits: 'pixels',\n })\n const scale = props.amount ? 0.6 + props.amount / 100 : 0.6\n icon.setScale(scale > 1.2 ? 1.2 : scale)\n return new Style({\n image: icon,\n })\n }\n\n legend = () => <div></div>\n}\n","export default \"data:image/png;base64,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\"","import React from 'react'\n\nimport { FeatureLike } from 'ol/Feature'\n\nimport WKT from 'ol/format/WKT'\nimport Stroke from 'ol/style/Stroke'\nimport Style from 'ol/style/Style'\nimport { SEGMENT_STROKE_WIDTH } from '../MapConstants'\nimport NiraLinearScaleVectorLayer from './NiraLinearScaleVectorLayer'\n\nexport default class NiraRoughnessVectorLayer extends NiraLinearScaleVectorLayer {\n name = 'Roughness'\n bundleName = 'roughness-long-term-aggregation'\n visibleOem = true\n visibleMaintenance = true\n guiBackend = false\n minZoomLevel = 9\n maxZoomLevel = 18\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 12 }\n timeSelectTool = (props: any) => <></>\n multiDirectional = true\n\n scaleProps = {\n startLabel: 'Smooth',\n endLabel: 'Rough',\n unit: 'IRI',\n flipLegend: false,\n }\n sidebarProps = { displayUnitInSidebar: false, fixed: 2 }\n getSidebarHeader() {\n return 'Roughness, [IRI]'\n }\n getColors(): string[] {\n return [\n '#30133B',\n '#466CE4',\n '#29BBEC',\n '#30F198',\n '#A4FD3D',\n '#EED03B',\n '#FB8122',\n '#D23104',\n '#790402',\n ]\n }\n getValueDomain(): number[] {\n return [0, 3, 12]\n }\n\n valueExtractor(feature: FeatureLike) {\n const rough = feature.get('roughness')\n return rough.roughnessStateEstimate\n }\n\n renderOrderFunction = (a: FeatureLike, b: FeatureLike) => {\n return this.valueExtractor(a) - this.valueExtractor(b)\n }\n\n roughnessColor = (value: number) => {\n const index = Math.min(\n Math.max(value, this.getValueDomain()[0]),\n this.getValueDomain()[this.getValueDomain().length - 1]\n )\n const color = this.colorScale(index).hex()\n return new Style({\n stroke: new Stroke({\n color,\n width: SEGMENT_STROKE_WIDTH,\n }),\n })\n }\n\n dataToFeatures = (data, zoomLevel) => {\n const wktReader = new WKT()\n const items = data.results.reduce((acc, v) => {\n return acc.concat(v.tileData)\n }, [])\n return items.filter(rough => {\n if (zoomLevel < 11) {\n return rough.roadClass < 4\n } else if (zoomLevel < 13) {\n return rough.roadClass < 5\n } else {\n return true\n }\n }).map((rough) => {\n const feature = wktReader.readFeature(rough.geometryWkt, {\n dataProjection: 'EPSG:4326',\n featureProjection: 'EPSG:3857',\n })\n feature.set('roughness', rough)\n feature.setStyle(this.roughnessColor(rough.roughnessAverage))\n return feature\n })\n }\n}\n","import { FeatureLike } from 'ol/Feature'\n\nimport SidebarItem from '../../mapSidebar/SidebarItem'\n\nexport type RoadConditionLevel = 'dry' | 'wet' | 'veryWet' | 'iceSnow'\n\ninterface RoadConditionDescription {\n short: string\n long: string\n color: string\n value: number\n}\n\nexport const ROAD_CONDITION_DESCRIPTIONS: Record<\n RoadConditionLevel,\n RoadConditionDescription\n> = {\n iceSnow: {\n short: 'Ice/Snow',\n long: 'Ice or snow',\n color: '#FF4D4D', //red\n value: 3,\n },\n veryWet: {\n short: 'Very Wet',\n long: 'Very wet',\n color: '#FF7B24', //orange\n value: 2,\n },\n wet: {\n short: 'Wet',\n long: 'Wet',\n color: '#FFB300', //yellow\n value: 1,\n },\n dry: {\n short: 'Dry',\n long: 'Dry',\n color: '#339900', //green\n value: 0,\n },\n}\n\ntype availableSignalTypes =\n | 'externalWeather'\n | 'fleetWeather'\n | 'externalAndFleetWeather'\n | 'fleetFriction'\n | 'externalWeatherAndFleetFriction'\n | 'fleetWeatherAndFriction'\n | 'all'\n | 'unknown'\n\ninterface AvailableSignalTypesDescription {\n short: string\n long?: string\n value: number\n}\n\nconst AVAILABLE_SIGNAL_TYPES_DESCRIPTIONS: Record<\n availableSignalTypes,\n AvailableSignalTypesDescription\n> = {\n externalWeather: {\n short: 'Third party weather',\n value: 1,\n },\n fleetWeather: {\n short: 'Fleet Weather',\n value: 2,\n },\n externalAndFleetWeather: {\n short: 'Third party weather and fleet weather',\n value: 3,\n },\n fleetFriction: {\n short: 'Fleet traction',\n value: 4,\n },\n externalWeatherAndFleetFriction: {\n short: 'Third party weather and fleet traction',\n value: 5,\n },\n fleetWeatherAndFriction: {\n short: 'Fleet weather and fleet traction',\n value: 6,\n },\n all: {\n short: 'All sources',\n long: 'Third party weather, fleet weather and fleet traction',\n value: 7,\n },\n unknown: {\n short: 'Unknown',\n value: 8,\n },\n}\n\nconst availableSignalTypesDescription = (\n availableSignalType: availableSignalTypes | number\n): AvailableSignalTypesDescription => {\n if (typeof availableSignalType === 'number') {\n return (\n Object.values(AVAILABLE_SIGNAL_TYPES_DESCRIPTIONS).find(\n (description) => description.value === availableSignalType\n ) || AVAILABLE_SIGNAL_TYPES_DESCRIPTIONS.unknown\n )\n }\n return AVAILABLE_SIGNAL_TYPES_DESCRIPTIONS[availableSignalType]\n}\n\nexport const getRoadConditionDescription = (\n roadCondition: RoadConditionLevel | number\n): RoadConditionDescription => {\n if (typeof roadCondition === 'number') {\n return (\n Object.values(ROAD_CONDITION_DESCRIPTIONS).find(\n (description) => description.value === roadCondition\n ) || ROAD_CONDITION_DESCRIPTIONS.dry\n )\n }\n return ROAD_CONDITION_DESCRIPTIONS[roadCondition]\n}\n\nexport const renderSidebarContent = (feature: FeatureLike) => {\n const properties = feature.getProperties()\n const expectedRoadWeather = properties['Expected-Road-Weather'] as number\n const expectedFriction = properties['Expected-Friction'] as number\n const availableInputSources = properties['Available-Input-Sources'] as number\n const availableInputSourcesDescription =\n availableSignalTypesDescription(availableInputSources)\n const expectedRoadConditionDescription =\n getRoadConditionDescription(expectedRoadWeather)\n return (\n <>\n <SidebarItem\n header={'Road Condition'}\n amountText={expectedRoadConditionDescription.long}\n fixed={2}\n />\n <SidebarItem header={'Traction'} amount={expectedFriction} unit={'μ'} fixed={2} />\n <SidebarItem\n header={'Available Input Sources'}\n amountText={availableInputSourcesDescription.short}\n text={\n availableInputSourcesDescription.long !== undefined\n ? availableInputSourcesDescription.long\n : ''\n }\n fixed={2}\n />\n </>\n )\n}\n","import React from 'react'\n\nimport { FeatureLike } from 'ol/Feature'\n\nimport NiraLinearScaleVectorLayer from './NiraLinearScaleVectorLayer'\nimport TimeSlider from '../overlay/TimeSlider'\nimport { renderSidebarContent } from './NiraRscVectorLayerUtils'\n\nexport default class NiraRscFrictionVectorLayer extends NiraLinearScaleVectorLayer {\n name = 'Traction'\n bundleName = 'road-surface-conditions-2'\n visibleOem = true\n visibleMaintenance = false\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n timeSelectTool = (props: any) => <TimeSlider {...props} />\n multiDirectional = true\n\n scaleProps = {\n startLabel: 'Slippery',\n endLabel: 'Non-slippery',\n unit: 'μ',\n flipLegend: true,\n }\n sidebarProps = { displayUnitInSidebar: false, fixed: 2 }\n getSidebarHeader() {\n return ''\n }\n renderSidebarContent = renderSidebarContent\n getColors(): string[] {\n return ['#ff4d4d', '#FF8000', '#ffe814', '#90DE11', '#339900']\n }\n getValueDomain(): number[] {\n return [0.35, 0.7]\n }\n\n valueExtractor(feature: FeatureLike) {\n return Number(feature.getProperties()['Expected-Friction'])\n }\n\n renderOrderFunction = (a: FeatureLike, b: FeatureLike) => {\n return this.valueExtractor(a) - this.valueExtractor(b)\n }\n}\n","import LegendWrapper from '../LegendWrapper'\nimport { RoadConditionLegendComponent } from './RoadConditionLegend.types'\n\nimport { useTranslation } from 'react-i18next'\n\nimport './RoadConditionLegend.scss'\n\nconst RoadConditionLegend: RoadConditionLegendComponent = ({\n conditions,\n description,\n}) => {\n const { t } = useTranslation()\n\n return (\n <LegendWrapper position=\"bottom\" title=\"Condition\">\n {conditions.map((condition) => {\n const item = description(condition)\n return (\n <div key={condition} className=\"legendItem\">\n <div className=\"colorIndicator\" style={{ backgroundColor: item.color }} />\n {t(item.short)}\n </div>\n )\n })}\n </LegendWrapper>\n )\n}\nexport default RoadConditionLegend\n","import React from 'react'\n\nimport { FeatureLike } from 'ol/Feature'\nimport Stroke from 'ol/style/Stroke'\nimport Style from 'ol/style/Style'\n\nimport { ColorStyle } from '../../../utils/Interfaces'\nimport * as MapConstants from '../MapConstants'\nimport { RoadConditionLegend } from '../overlay/Legend/RoadConditionLegend'\nimport TimeSlider from '../overlay/TimeSlider'\nimport { MAX_ZOOM_LIMIT, MIN_ZOOM_LIMIT } from '../vectorlayers/NiraVectorTileLayers'\nimport {\n ROAD_CONDITION_DESCRIPTIONS,\n RoadConditionLevel,\n getRoadConditionDescription,\n renderSidebarContent,\n} from './NiraRscVectorLayerUtils'\nimport NiraVectorLayer from './NiraVectorLayer'\n\nexport default class NiraRscRoadConditionVectorLayer implements NiraVectorLayer {\n description = ''\n guiBackend = true\n minZoomLevel = MIN_ZOOM_LIMIT\n maxZoomLevel = MAX_ZOOM_LIMIT\n shouldAutoRefresh = false\n dataToFeatures = (data: any, zoomLevel: number) => []\n name = 'Road Condition'\n bundleName = 'road-surface-conditions-2'\n visibleOem = true\n visibleMaintenance = false\n multiDirectional = true\n\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n timeSelectTool = (props: any) => <TimeSlider {...props} />\n legend() {\n return (\n <RoadConditionLegend\n conditions={Object.keys(ROAD_CONDITION_DESCRIPTIONS) as RoadConditionLevel[]}\n description={getRoadConditionDescription}\n />\n )\n }\n\n valueExtractor(feature: FeatureLike) {\n return Number(feature.getProperties()['Expected-Road-Weather'])\n }\n\n renderOrderFunction(a: FeatureLike, b: FeatureLike) {\n return this.valueExtractor(b) - this.valueExtractor(a)\n }\n\n renderSidebarContent = renderSidebarContent\n\n styles: ColorStyle[] = Object.values(ROAD_CONDITION_DESCRIPTIONS).map((description) => {\n return {\n limit: description.value,\n style: new Style({\n stroke: new Stroke({\n color: description.color,\n width: MapConstants.SEGMENT_STROKE_WIDTH,\n }),\n }),\n }\n })\n styleFunction(feature: FeatureLike) {\n const value = this.valueExtractor(feature)\n if (value === undefined) return undefined\n return this.styles.find((style) => style.limit === value)?.style\n }\n}\n","import React from 'react'\n\nimport Feature, { FeatureLike } from 'ol/Feature'\nimport Geometry from 'ol/geom/Geometry'\nimport VectorTileLayer from 'ol/layer/VectorTile'\nimport { OrderFunction } from 'ol/render'\nimport VectorTileSource from 'ol/source/VectorTile'\nimport Icon from 'ol/style/Icon'\nimport Style from 'ol/style/Style'\n\nimport NiraAlertVectorLayer, { NiraAlertsVectorLayerName } from './NiraAlertVectorLayer'\n\nimport SEVERE_POTHOLE_ICON from './icons/Pothole.png'\n\nexport default class NiraSeverePotholeAlertsVectorLayer implements NiraAlertVectorLayer {\n name = 'Road Damages'\n layerName: NiraAlertsVectorLayerName = 'severePothole'\n bundleName = 'obstacle-aggregation'\n urlType = 'obstacles'\n description = 'Road Damages - Map View'\n multiDirectional = false\n active = true\n rsaApi = true\n rsaApiBundleName = 'obstacles'\n\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n\n source: VectorTileSource | null = null\n layer: VectorTileLayer | null = null\n minZoom = 7\n maxZoom = 12\n\n renderOrderFunction?: OrderFunction | undefined\n\n timeSelectTool = (props: any) => <></>\n\n valueExtractor = (feature: FeatureLike) => 1\n\n renderSidebarContent = (feature: FeatureLike) => {\n return <>Road Damages</>\n }\n\n filterFunction = (\n features: Feature<Geometry>[],\n vectorLayer: NiraAlertVectorLayer,\n zoomLevel: number\n ) => (features.length > 0 ? [features[0]] : features)\n\n styleFunction = (feature: FeatureLike) => {\n const icon = new Icon({\n anchor: [0, 0],\n size: [50, 50],\n imgSize: [50, 50],\n src: SEVERE_POTHOLE_ICON,\n anchorXUnits: 'fraction',\n anchorYUnits: 'pixels',\n })\n icon.setScale(0.6)\n return new Style({\n image: icon,\n })\n }\n\n legend = () => <div></div>\n}\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAAB3RJTUUH5gsdCgQwlkicEgAACdtJREFUaN7tmX9QlNUax7/vuwuyi8Iuu4uy4FwQZfgV2yTjNai8sYhiIlv+mDIzTJa6oze5aY0sMOU0aWlXK8kxbereaNIVUAJMwSkwmkTF0EZHBNtACxIBkYVlgd33uX8sLLwsyKog9870nTmz+777nnOec57nfN7nnAX+1P+WmPFqmIiwev16WURERBgAXPj550vZWVktDDM+XY5Lq4br13EoJ2fO3wIC3pcYDLPBMLgVEFBZZjBsSkxIOBsaFDRe8zd2StZqsWztWkXF11+frFm8mM6xLJ1jWapJSKBTBQXfPb1mjeyltWsn2sw7Sy6Xg4hwKC8vtTY93VLJsnQWoLMAVbIs1WZmWg7m5r5KRPDy8hrTvgVj2ViaToeCkydnqWWyndaPPlJYWlrAwBa/RAQ0NrIytTpg+6FDxfOiolrLSksf4DQ7qYiICABgvyko+FetVjvgib7Sf1378st0tKBgBwAmLCxszPofs8Wuz8lBXVNTdIJYfLjn9de9e5ubHRonAK4KBVx27LhR0NHx9HSZ7NTzzz33IObZOS1cuBDTQkNFJ4uKDl1ZsmRYTwy+vqLRUFlR0QHPGTPc5sfFjYkNY+KRm83NyD92bNm8mzf/05GeLrZ2ddnWBQCBpydABGt7+8A9sRjuW7d2nvTyWh0fE3N4up/ffdvA3m8DyVotXtm8WaHy8Nhg0et5gwAA7/XroVi3Dui7xwCwmkzg9Hp3lUSy4R+ZmfIJx/FIuO0PoYsPPUTd166Rua6OLoaF8X7rx7G+D8cymey+bLkv/Kalp6OgrGyWWibbNRi3BIARCqHcsgUeMTEQSiQAw6C9uBjEcQ44fi8np/iJRx+dGBwPwu3Oobg9C9CV2FjqbW2lfvW2tFB1TAzvmSE4ZsPDw+/Znnte7CPhlgAIpkxBwIEDkDz1FK9OW2Ehfl25EtaODvuzLgoFXCcKxwvj4zEtLMyG24QEB7waXnyRrGYzDZW1q4sML7zgiOPERCorKjooCQx0ixsjHDulm83N2J+dvaxm167On0QiXrhc8PWljspKGkkdZ87QeaWSV+cnsZhqPvigY98XXzxz/fff78mmu8ZvckoK/t6P24MHHXArW7MG4kceGbG+ODIS8qQkAHwcW/pxnJ4+/jhWKBSj4tZcV0ejyWww0MXw8DHF8V3hNy09HYVlZUExQ7JbHm7V6lHbEUqlAMtODI55uE1OdsTt/Pk83I6mEXGckmLHcdhd4Nhp/Opzc1F/40b0YpHocM8bbziF29H0wHG8MD4ePuHhTuCW6yvOaTQcS2fOFI0pjptbW7E/O3t5zc6do+DWah+I0Wik9vZ24rg7D2xYHItEdKUPx781NDhl46iLXZuSgtySEsXSiIhdwr17A7vr6vjZ7YYN8Fq5EgwDgBiAYVBfX4+NGzfi8OHDOH/+PIxGI1xdXSEWiyEUCnntuyiVsLa2oqO8HIAt1jmLBcLbt12l8+cr0z/+uDBq9mxTVVXVvQ9EoVDg+++/B2OxvBxQWflSh17Pgsi+sEQREfDbsQNCiQREAMMw6OzsxJtvvolZs2YhOTkZFosFFRUVyM/PR3FxMWpqamAymSASieDu7g6WZTEpMBDGb7+FpanJ3raloQHSGTP8ZE880aDbvPl0VlYWurq67m0gPNx++KHC0trKx+1bb9lxyzAMrFYrdu/eDaPRiIyMDPj6+kKlUiEuLg5qtRr+/v5oaWlBaWkpvvrqK8hkMsycORNCiQTMHXC8/X5w7BRub93ixfv+/fvJy8uLNBoNff7551RVVUW3b992WCccx9G+ffsoLS2Nh+MravVIOH4fAHunw4oR8avPzUV9U1P0Yje34XF78CAkixbZn29ubkZcXBz6Y5llWUilUgQFBWHOnDmIioqCSqXC9OnTIRaLUV5eji+//BJ79uyBQGALjLaiIhuOjcbhcSyXn3r+2Wed98aouE1KcshuKyoqyNPTk/r6dyhCoZCUSiXFxsZSZmYm7d69mzQaDbW1tQ3g2GweWxy3jIbbc+ccMHrixAmSSqUjDmRoEQgE5OfnR9XV1Xwcnz07LI77s+PfR8Cxw2LXpqQgxync8qNSLBbj6tWrkEgkCAwMhMVigclkAsdxw3ZMRCAirFixAn6DTlFcfHzuiGOdMzj29vbuz27/WavTOWa3EREjZrdnzpwhDw8Pio6Opj/++INqa2spJyeHUlNTKSoqiuRyOTEMw/NKYGAg1dfXO2bHv/46fHackWHR5+ZuICLI5fKRPZKm0zmN26FqbGzEDz/8gHnz5kGj0UAmkyE0NBQLFizA8uXLsWTJEkRGRkIsFsNkMqG7uxsxMTFYvXq1fbH3axQc+2/PySl+fO7c4XEcoVIBAHvMadxyvGK1WqmpqYla7RkwN6TYlJ2dTSEhIbRp0yYyGAx3zI5HwvE3fTgefFhh3yFmZGZi+549j/o3N6/qzM+3xycBEHh4YGpqqu1Yx0G283aWZaFQKCCVSnn3B4pNP/74Iy5fvozg4GAEBAQMXjW8IvTygndqKgRTpth3kgDQeeQI/FtaVr2blfVXXUYGzwrEx8fjwm+/iQ5s2/bFtE8+WdZeWGivSABkSUn4y969YCdNsldsa2tDbW2NzeVOyt/fH7/8YkBp6XdYtWoVpk6disuXL6OnpwcsK0BQ0Cx4eHj2BzO47m7Ua7Voyc7m2eORmIhGrVa/9LXX1swOCOgqKS62/d566xbyjh5dPq+p6d8dOp3YajbbveHq64vAggK4D9mHl5WVYenSpejq6sLo/wsSOI4QGRmJ2Fi13ddXr/6CwsJC9PT0wM3NDXl5eXjyySftAwGAzspKXE1MRG9Dw0CEiESYvG1bZ5lM9uLi2Ng8pY8PGG1KCm5xnOKNhIQjk7duje48fZqHW5/MTCi3bHEwtrq6GllZWejt7XXaI8OhmGVt0e3i4oJ169YhJCSEPwVEaMjIQOPWrfYQIgDuc+fCqNOVv3vkyDNeAkHzwGHCMLi99PDD1H3tmtMbpfGSub6eLqlUI+H4VSKC8PW33w57ITj4FbNeL7Cjrm823EJDYaqqQue5c07P+niIYVm4hYTAdOGCPeiI42DW6wXBKtUrG7dsOcEczc//LKioKKnt00+ZftfZNWQTNKEiAqzWgcu+T0lKCl1ZtOgzoU93t6arpMRxEADIYplo83lihnwnAOaSEkapVmuEDMcJBxvsPEwfvAbbZsdxby8YjhOyTSJRsXtiIgn63hHM/0kBAMGkSRBrNHTDze248Pjp05uXLFjATQsPX8DcvCma6Fm/Kw95e3ddVyqPHT91Kp157Z13UH3xovvjjz0W5jF5sgx38aaeUDEMbnd0tJSXl1+aGRzcOdHm/Kmh+i83g2PiY4HFEQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMi0xMS0yOVQxMDowNDo0OCswMDowMLpPi+QAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjItMTEtMjlUMTA6MDQ6NDgrMDA6MDDLEjNYAAAAAElFTkSuQmCC\"","import React from 'react'\n\nimport Feature, { FeatureLike } from 'ol/Feature'\nimport Geometry from 'ol/geom/Geometry'\nimport VectorTileLayer from 'ol/layer/VectorTile'\nimport { OrderFunction } from 'ol/render'\nimport VectorTileSource from 'ol/source/VectorTile'\nimport Icon from 'ol/style/Icon'\nimport Style from 'ol/style/Style'\n\nimport SidebarItem from '../../mapSidebar/SidebarItem'\nimport NiraAlertVectorLayer, { NiraAlertsVectorLayerName } from './NiraAlertVectorLayer'\n\nimport SEVERE_ROUGHNESS_ICON from './icons/Bumpyroad.png'\n\nexport default class NiraSevereRoughnessAlertsVectorLayer\n implements NiraAlertVectorLayer\n{\n name = 'Rough Road'\n layerName: NiraAlertsVectorLayerName = 'severeRoughness'\n bundleName = 'roughness-alerts'\n description = 'Rough Road - Map View'\n multiDirectional = false\n active = true\n rsaApi = true\n rsaApiBundleName = 'roughness'\n\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n\n source: VectorTileSource | null = null\n layer: VectorTileLayer | null = null\n minZoom = 7\n maxZoom = 12\n\n renderOrderFunction?: OrderFunction | undefined\n\n timeSelectTool = (props: any) => <></>\n\n valueExtractor = (feature: FeatureLike) => 1\n\n renderSidebarContent = (feature: FeatureLike) => {\n const {\n drivingForwardLinkDirection,\n functionalRoadClass,\n iriAvg,\n speedCategoryKmph,\n } = feature.getProperties()\n return (\n <>\n <SidebarItem header={'Iri'} amount={iriAvg} unit={''} fixed={2} />\n <SidebarItem header={'Road Class'} amount={functionalRoadClass} />\n <SidebarItem header={'Road Speed Limit'} amount={speedCategoryKmph} unit=\"km/h\" />\n <SidebarItem\n header={'Driving Direction Forward'}\n amount={drivingForwardLinkDirection ? 1 : 0}\n />\n </>\n )\n }\n\n filterFunction = (\n features: Feature<Geometry>[],\n vectorLayer: NiraAlertVectorLayer,\n zoomLevel: number\n ) => (features.length > 0 ? [features[0]] : features)\n\n styleFunction = (feature: FeatureLike) => {\n const props = feature.getProperties()\n const icon = new Icon({\n anchor: [0, 0],\n size: [50, 50],\n imgSize: [50, 50],\n src: SEVERE_ROUGHNESS_ICON,\n anchorXUnits: 'fraction',\n anchorYUnits: 'pixels',\n })\n const scale = props.amount ? 0.6 + props.amount / 100 : 0.6\n icon.setScale(scale > 1.2 ? 1.2 : scale)\n return new Style({\n image: icon,\n })\n }\n\n legend = () => <div>nice</div>\n}\n","export default \"data:image/png;base64,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\"","import React from 'react'\n\nimport Feature, { FeatureLike } from 'ol/Feature'\nimport VectorTileLayer from 'ol/layer/VectorTile'\nimport { OrderFunction } from 'ol/render'\nimport VectorTileSource from 'ol/source/VectorTile'\nimport Icon from 'ol/style/Icon'\nimport Style from 'ol/style/Style'\n\nimport SidebarItem from '../../mapSidebar/SidebarItem'\nimport NiraAlertVectorLayer, { NiraAlertsVectorLayerName } from './NiraAlertVectorLayer'\n\nimport Geometry from 'ol/geom/Geometry'\nimport SLIPPERY_ICON from './icons/Slipperyroad.png'\n\nexport default class NiraSlipperyAlertsVectorLayer implements NiraAlertVectorLayer {\n name = 'Slippery'\n layerName: NiraAlertsVectorLayerName = 'slippery'\n bundleName = 'road-surface-alerts'\n description = 'Road Roughness Alerts - Map View'\n multiDirectional = false\n active = true\n rsaApi = true\n rsaApiBundleName = 'slippery'\n\n functionalRoadClassZoomLevels = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }\n\n source: VectorTileSource | null = null\n layer: VectorTileLayer | null = null\n minZoom = 7\n maxZoom = 12\n\n renderOrderFunction?: OrderFunction | undefined\n\n timeSelectTool = (props: any) => <></>\n\n valueExtractor = (feature: FeatureLike) => 1\n\n renderSidebarContent = (feature: FeatureLike) => {\n const { frictionCoefficient, functionalRoadClass, qualityIndex, speedCategory } =\n feature.getProperties()\n return (\n <>\n <SidebarItem header={'Quality Index'} amount={qualityIndex} fixed={2} />\n <SidebarItem\n header={'Friction Coefficient'}\n amount={frictionCoefficient}\n fixed={2}\n />\n <SidebarItem header={'Road Class'} amount={functionalRoadClass} />\n <SidebarItem header={'Road Speed Limit'} amount={speedCategory} />\n </>\n )\n }\n\n // Group per RSA event specific level\n groupFunction = (\n features: Feature<Geometry>[],\n vectorLayer: NiraAlertVectorLayer,\n zoomLevel: number\n ) => {\n return features\n }\n\n styleFunction = (feature: FeatureLike) => {\n const props = feature.getProperties()\n const icon = new Icon({\n anchor: [0, 0],\n size: [50, 50],\n imgSize: [50, 50],\n src: SLIPPERY_ICON,\n anchorXUnits: 'fraction',\n anchorYUnits: 'pixels',\n })\n const scale = props.amount ? 0.6 + props.amount / 100 : 0.6\n icon.setScale(scale > 1.2 ? 1.2 : scale)\n return new Style({\n image: icon,\n })\n }\n\n legend = () => <div>nice</div>\n}\n","export default \"data:image/png;base64,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\"","import React from 'react'\nimport './CheckBox.scss'\ninterface Props<T> {\n text: string\n value: T\n onClick: (value: T) => void\n selected: boolean\n}\nconst CheckBox = <ValueType,>(props: Props<ValueType>) => {\n const selected = props.selected ? 'selected' : ''\n return (\n <div\n className=\"checkBoxButtonContainer\"\n tabIndex={0}\n onClick={() => props.onClick(props.value)}\n >\n <span className={'checkBoxButtonTitle ' + selected}>{props.text}</span>\n <div className={'checkBoxButton ' + selected}>\n <div className={'dot ' + selected} />\n </div>\n </div>\n )\n}\nexport default CheckBox\n","import React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport CheckBox from './CheckBox'\nimport NiraAlertVectorLayer, {\n NiraAlertsVectorLayerName,\n} from '../layer/NiraAlertVectorLayer'\n\nimport './LayerSwitcher.scss'\n\ninterface Props {\n alertVectorLayers: Record<string, NiraAlertVectorLayer>\n activeAlertVectorLayers: NiraAlertsVectorLayerName[]\n onAlertVectorLayersChanged: (alertVectorLayers: NiraAlertsVectorLayerName) => void\n}\n\nconst AlertsSelector = ({\n alertVectorLayers,\n activeAlertVectorLayers,\n onAlertVectorLayersChanged,\n}: Props) => {\n const { t } = useTranslation()\n\n const layers = Object.entries(alertVectorLayers).map(([key, layer]) => {\n return (\n <CheckBox\n key={key}\n value={layer}\n text={layer.name}\n onClick={() => onAlertVectorLayersChanged(key as NiraAlertsVectorLayerName)}\n selected={\n activeAlertVectorLayers.find((layerName) => layerName === layer.layerName) !==\n undefined\n }\n />\n )\n })\n\n return (\n <div className=\"layerSwitcherRoot\">\n <p>{t('Road Surface Alerts')}</p>\n {layers}\n </div>\n )\n}\n\nexport default AlertsSelector\n","import { useTranslation } from 'react-i18next'\nimport './RadioButton.scss'\n\ninterface Props<T> {\n text: string\n value: T\n onClick: (value: T) => void\n selected: boolean\n}\n\nconst RadioButton = <ValueType,>(props: Props<ValueType>) => {\n const { t } = useTranslation()\n const selected = props.selected ? 'selected' : ''\n\n return (\n <div\n className=\"radioButtonContainer\"\n tabIndex={0}\n onClick={() => props.onClick(props.value)}\n >\n <span className={'radioButtonTitle ' + selected}>{t(props.text)}</span>\n <div className={'radioButton ' + selected}>\n <div className={'dot ' + selected} />\n </div>\n </div>\n )\n}\n\nexport default RadioButton\n","import React from 'react'\nimport { useTranslation } from 'react-i18next'\n\nimport NiraVectorLayer from '../layer/NiraVectorLayer'\nimport RadioButton from './RadioButton'\n\nimport './LayerSwitcher.scss'\n\nconst FLEET_FRICTION_BUNDLE_NAME = 'maintenance-aggregation'\n\ninterface Props {\n layerChanged: (layer: NiraVectorLayer | null) => void\n currentVectorLayer: NiraVectorLayer | null\n vectorLayers: Record<string, NiraVectorLayer>\n title: string\n}\n\nconst getMaintenanceLayerNames = (layer: NiraVectorLayer) => {\n return layer.bundleName === FLEET_FRICTION_BUNDLE_NAME &&\n layer.name === 'Fleet Traction'\n ? 'Friction'\n : layer.name\n}\n\nconst LayerSwitcher = (props: Props) => {\n const { t } = useTranslation()\n const { vectorLayers, title, layerChanged, currentVectorLayer } = props\n\n const layers = Object.entries(vectorLayers)\n\n function createRadioButton(key: React.Key | null | undefined, layer: NiraVectorLayer) {\n return (\n <RadioButton\n key={key}\n value={layer}\n text={\n props.title === 'Road Surface Conditions'\n ? layer.name\n : getMaintenanceLayerNames(layer)\n }\n onClick={(layer) => layerChanged(layer)}\n selected={layer === currentVectorLayer}\n />\n )\n }\n\n function showAggregatedFleetDataTitle(layers: [string, NiraVectorLayer][]) {\n const aggregatedLayers = layers.filter(\n ([key, layer]) => layer.bundleName === FLEET_FRICTION_BUNDLE_NAME\n )\n return props.title === 'Road Surface Conditions' && aggregatedLayers.length > 0\n }\n\n return (\n <div className=\"layerSwitcherRoot\">\n <p>{t(title)}</p>\n {layers.map(([key, layer]) => {\n return layer.bundleName !== FLEET_FRICTION_BUNDLE_NAME\n ? createRadioButton(key, layer)\n : null\n })}\n {showAggregatedFleetDataTitle(layers) ? <p>{'Aggregated Fleet Data'}</p> : <></>}\n {layers.map(([key, layer]) => {\n return layer.bundleName === FLEET_FRICTION_BUNDLE_NAME\n ? createRadioButton(key, layer)\n : null\n })}\n {<p>{'No Selected Layer'}</p>}\n <RadioButton\n value={null}\n text={'None'}\n onClick={() => layerChanged(null)}\n selected={!currentVectorLayer}\n />\n </div>\n )\n}\n\nexport default LayerSwitcher\n","function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nimport * as React from \"react\";\nfunction SvgArrowRight(_ref, svgRef) {\n let {\n title,\n titleId,\n ...props\n } = _ref;\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n id: \"Layer_1\",\n xmlns: \"http://www.w3.org/2000/svg\",\n xmlnsXlink: \"http://www.w3.org/1999/xlink\",\n x: \"0px\",\n y: \"0px\",\n viewBox: \"0 0 423 423\",\n xmlSpace: \"preserve\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, /*#__PURE__*/React.createElement(\"g\", null, /*#__PURE__*/React.createElement(\"path\", {\n style: {\n fill: \"white\"\n },\n d: \"M95.457,434.002l-33.105-45.076l234.094-171.928L62.352,45.077L95.456,0L360.24,194.459 c7.174,5.269,11.41,13.638,11.41,22.539c0,8.9-4.236,17.27-11.41,22.538L95.457,434.002z\"\n })));\n}\nconst ForwardRef = /*#__PURE__*/React.forwardRef(SvgArrowRight);\nexport default __webpack_public_path__ + \"static/media/arrow-right.e666cf6b.svg\";\nexport { ForwardRef as ReactComponent };","import React from 'react'\nimport { isMobileOnly } from 'react-device-detect'\n\nimport { ReactComponent as ArrowIcon } from './../../img/icons/arrow-right.svg'\n\nimport './MapActions.scss'\n\ninterface MapActionsProps {}\n\ninterface MapActionsState {\n minmized: boolean\n}\n\nexport default class MapActions extends React.Component<\n MapActionsProps,\n MapActionsState\n> {\n constructor(props: MapActionsProps) {\n super(props)\n\n this.state = {\n minimized: false,\n }\n }\n\n render() {\n return (\n <>\n {isMobileOnly && this.state.minimized ? (\n <div\n className=\"minimizedMapActionsContainer\"\n tabIndex={0}\n onClick={() => this.setState({ minimized: false })}>\n <ArrowIcon className=\"icon\" />\n </div>\n ) : (\n <div className=\"mapActionsContainer\">\n {isMobileOnly && (\n <div\n className=\"minimizedButton\"\n tabIndex={0}\n onClick={() => this.setState({ minimized: true })}>\n <ArrowIcon className=\"icon\" />\n </div>\n )}\n {React.Children.map(this.props.children, (child, i) => {\n return child ? <div className=\"mapActionsBox\">{child}</div> : <></>\n })}\n </div>\n )}\n </>\n )\n }\n}\n","import { FeatureLike } from 'ol/Feature'\nimport NiraAlertVectorLayer from '../layer/NiraAlertVectorLayer'\n\ninterface AlertsSideMenuDetailsProps {\n activeFeature: FeatureLike\n alertLayers: Record<string, NiraAlertVectorLayer>\n}\n\nexport default function AlertsSideMenuDetails({\n activeFeature,\n alertLayers,\n}: AlertsSideMenuDetailsProps) {\n const renderAlertLayerContent = () => {\n switch (activeFeature.getProperties().alertType) {\n case 'ROUGHNESS':\n return alertLayers.severeRoughness.renderSidebarContent(activeFeature)\n case 'SLIPPERY':\n return alertLayers.slippery.renderSidebarContent(activeFeature)\n }\n return null\n }\n\n return renderAlertLayerContent()\n}\n","export default __webpack_public_path__ + \"static/media/nira-logo-white-pms.97a80560.svg\";","import React from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\n\nimport './Sidebar.scss'\nimport ImgLogo from './../../img/nira-logo-white-pms.svg'\nimport ImgClose from './../../img/icon-close.png'\n\ninterface SidebarProps {\n isOpen: boolean\n closeSidebar: () => void\n}\n\nexport default class Sidebar extends React.Component<SidebarProps> {\n componentDidMount() {}\n\n render() {\n return (\n <AnimatePresence initial={false}>\n {this.props.isOpen && (\n <motion.div\n className=\"overlaySidebarContainer\"\n initial={{ x: 320, display: 'none' }}\n animate={{ x: 0.01, display: 'flex' }}\n exit={{\n x: 320,\n transition: {\n x: { type: 'spring', bounce: 0 },\n },\n transitionEnd: { display: 'none' },\n }}\n transition={{\n x: { type: 'spring', bounce: 0.25 },\n }}\n >\n <span className=\"closeIcon\" onClick={this.props.closeSidebar}>\n <img width=\"18\" height=\"18\" src={ImgClose} alt=\"\" />\n </span>\n {this.props.children}\n <div className=\"logoWrapper\">\n <img src={ImgLogo} alt=\"\" />\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n )\n }\n}\n","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2BAMAAAB+a3fuAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAANqADAAQAAAABAAAANgAAAADzQy6kAAAAFVBMVEUAAAArKyskJCQEBAQEBAQDAwMDAwM11bhVAAAABnRSTlMABgeHtucUurloAAAA1klEQVQ4y32UwQ3CMAxFI1aAARDqAlx6J0LdABYoeP8RSNI2JPHX66WK/V+UOPYP59c9qC/HZ/tcReq02BreZlHkJrNvzgkwYSk3mwITlva8mAAzZo/tFwWWgcmDVS/Av9yBjdqBrXgAO+0A9tJuNSi75Xi0Zu1O1gR8KWpEVKKGRAWPmKz8HlTYDt4W+dIFfEpsA810ZxVQYwcYZScXUGOYgz3pLHAHujvUjGoNb0RvCz1BvQQ9SL0LPU+zAjNGswkzTV4AHkLeQ55FXkceSd5Kngxe/gPGE66nB+qXqAAAAABJRU5ErkJggg==\"","import React from 'react'\nimport { FeatureLike } from 'ol/Feature'\nimport NiraVectorLayer from '../../components/map/layer/NiraVectorLayer'\n\ninterface FeatureMapItemProps {\n feature: FeatureLike\n currentVectorLayer: NiraVectorLayer | null\n}\ninterface FeatureMapItemState {}\n\nexport default class FeatureMapItem extends React.Component<\n FeatureMapItemProps,\n FeatureMapItemState\n> {\n render() {\n return this.props.currentVectorLayer ? (\n <div className=\"propertiesContainer\">\n {this.props.currentVectorLayer.renderSidebarContent(this.props.feature)}\n </div>\n ) : null\n }\n}\n","import React from 'react'\n\nimport { FeatureLike } from 'ol/Feature'\n\nimport NiraVectorLayer from '../../components/map/layer/NiraVectorLayer'\nimport NiraAlertVectorLayer from '../map/layer/NiraAlertVectorLayer'\nimport AlertsSideMenuDetails from '../map/overlay/AlertsSideMenuDetails'\nimport Sidebar from '../sidebar/Sidebar'\nimport FeatureMapItem from './FeatureMapItem'\n\ninterface MapSidebarProps {\n alertLayers: Record<string, NiraAlertVectorLayer>\n feature: FeatureLike | null\n isOpen: boolean\n closeSidebar: () => void\n currentVectorLayer: NiraVectorLayer\n}\ninterface MapSidebarState {}\n\nexport default class MapSidebar extends React.Component<\n MapSidebarProps,\n MapSidebarState\n> {\n renderFeatureContent(): React.ReactNode {\n if (!this.props.feature) return null\n return (\n <FeatureMapItem\n feature={this.props.feature}\n currentVectorLayer={this.props.currentVectorLayer}></FeatureMapItem>\n )\n }\n\n renderAlertFeatureContent(): React.ReactNode {\n const { feature, alertLayers } = this.props\n if (!feature) return null\n return <AlertsSideMenuDetails activeFeature={feature} alertLayers={alertLayers} />\n }\n\n render() {\n return (\n <Sidebar isOpen={this.props.isOpen} closeSidebar={this.props.closeSidebar}>\n {this.props.isOpen && this.props.feature?.getProperties().alertType\n ? this.renderAlertFeatureContent()\n : this.renderFeatureContent()}\n </Sidebar>\n )\n }\n}\n","export default __webpack_public_path__ + \"static/media/double-arrow-left.b4f088ae.svg\";","export default __webpack_public_path__ + \"static/media/double-arrow-right.b5b1d486.svg\";","import React from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport './Sidebar.scss'\nimport ImgLogo from './../../img/nira-logo-white-pms.svg'\nimport ImgOpen from './../../img/icons/double-arrow-left.svg'\nimport ImgClose from './../../img/icons/double-arrow-right.svg'\ninterface SidebarToggleProps {}\ninterface SidebarToggleState {\n isOpen: boolean\n}\nexport default class SidebarToggle extends React.Component<\n SidebarToggleProps,\n SidebarToggleState\n> {\n constructor(props: SidebarToggleProps) {\n super(props)\n this.state = { isOpen: false }\n }\n closeSidebar() {\n this.setState({\n isOpen: false,\n })\n }\n openSidebar() {\n this.setState({\n isOpen: true,\n })\n }\n\n renderSidebar() {\n return (\n <AnimatePresence>\n <motion.div\n className=\"sidebarContainer\"\n initial={{ width: '0px' }}\n animate={{ width: '320px' }}\n exit={{ width: '0px' }}\n >\n <span className=\"closeIcon\" onClick={this.closeSidebar.bind(this)}>\n <img width=\"18\" height=\"18\" src={ImgClose} alt=\"collapseSidebar\" />\n </span>\n {this.props.children}\n <div className=\"logoWrapper\">\n <img src={ImgLogo} alt=\"\" />\n </div>\n </motion.div>\n </AnimatePresence>\n )\n }\n renderOpenButton() {\n return (\n <div className=\"openButtonSidebarContainer\">\n <div className=\"openToggleIcon\" onClick={this.openSidebar.bind(this)}>\n <img width=\"18\" height=\"18\" src={ImgOpen} alt=\"expandSidebar\" />\n </div>\n </div>\n )\n }\n render() {\n return <>{this.state.isOpen ? this.renderSidebar() : this.renderOpenButton()}</>\n }\n}\n","import React from 'react'\nimport { FeatureLike } from 'ol/Feature'\nimport SidebarToggle from '../sidebar/SidebarToggle'\nimport NiraVectorLayer from '../../components/map/layer/NiraVectorLayer'\nimport FeatureMapItem from './FeatureMapItem'\n\ninterface MapToggleSideBarProps {\n feature: FeatureLike | null\n currentVectorLayer: NiraVectorLayer | null\n}\ninterface MapToggleSideBarState {}\n\nexport default class MapToggleSideBar extends React.Component<\n MapToggleSideBarProps,\n MapToggleSideBarState\n> {\n renderFeatureContent(): React.ReactNode {\n if (!this.props.feature) return null\n return (\n <FeatureMapItem\n feature={this.props.feature}\n currentVectorLayer={this.props.currentVectorLayer}\n ></FeatureMapItem>\n )\n }\n\n renderNoSegmentText(): React.ReactNode {\n return 'No segment data available'\n }\n\n render() {\n return (\n <SidebarToggle>\n {!!this.props.feature ? this.renderFeatureContent() : this.renderNoSegmentText()}\n </SidebarToggle>\n )\n }\n}\n","const permissions = {\n FULL_RIGHTS: 'fullRights',\n GPS_TRACK_MODE: 'rsiSaasGpsTrackModeRights',\n}\n\nexport default permissions\n","import { RestrictedComponentProps } from './Restricted.types'\nimport LoginManagerInstance from '../../utils/LoginManager'\nimport permissions from '../../permissions'\nimport { useEffect, useState, useCallback } from 'react'\n\nconst verifyPermissions = (requiredPermission: string): boolean => {\n const userPermissions = LoginManagerInstance.getCurrentUserData().permissions\n if (userPermissions) {\n return (\n userPermissions.includes(requiredPermission) ||\n userPermissions.includes(permissions.FULL_RIGHTS)\n )\n } else {\n return false\n }\n}\n\nexport const Restricted: RestrictedComponentProps = ({\n requiredPermission,\n children,\n}) => {\n const [shouldShow, setShouldShow] = useState(verifyPermissions(requiredPermission))\n\n const update = useCallback(\n () => setShouldShow(verifyPermissions(requiredPermission)),\n [requiredPermission]\n )\n\n useEffect(() => {\n LoginManagerInstance.addDataListener(update)\n\n return () => LoginManagerInstance.removeDataListener(update)\n }, [update])\n\n return <>{shouldShow ? children : null}</>\n}\n","import { Restricted } from './Restricted.component'\n\nexport default Restricted\n","import React from 'react'\n\nimport './UserSidebar.scss'\nimport Sidebar from '../sidebar/Sidebar'\nimport LoginManagerInstance, { UserData } from '../../utils/LoginManager'\nimport LanguageSwitcher from '../languageSwitcher'\nimport ToggleCookieModal from '../cookies/toggleCookieModal'\nimport { withTranslation, Trans, WithTranslation } from 'react-i18next'\n\ninterface UserSidebarProps extends WithTranslation {\n userData: UserData\n}\ninterface UserSidebarState {\n isSidebarOpen: boolean\n}\n\nclass UserSidebar extends React.Component<UserSidebarProps, UserSidebarState> {\n constructor(props: UserSidebarProps) {\n super(props)\n this.state = {\n isSidebarOpen: false,\n }\n }\n\n componentDidMount() {}\n\n userClicked() {\n this.setState({\n isSidebarOpen: true,\n })\n }\n\n closeUserSidebar() {\n this.setState({\n isSidebarOpen: false,\n })\n }\n\n getNameInitials(name?: string) {\n if (name === undefined) {\n return ''\n }\n const nameList = name.split(' ')\n const filteredList = nameList.filter(Boolean)\n let initials = filteredList.shift().charAt(0)\n initials += filteredList.length >= 1 ? filteredList.pop()?.charAt(0) : ''\n return initials.toUpperCase()\n }\n\n renderUserContent() {\n return (\n <div className=\"userContainer\">\n <div className=\"userInfo\">\n <p className=\"usernameText\">{this.props.userData?.displayName}</p>\n <p className=\"emailText\">{this.props.userData?.email}</p>\n <LanguageSwitcher />\n </div>\n <div className=\"userActions\">\n <p className=\"userLink\">\n <a href=\"/terms\" className=\"link\" target=\"_blank\" rel=\"noopener noreferrer\">\n {this.props.t('Terms & Conditions')}\n </a>\n </p>\n <p className=\"userLink\">\n <a\n href={process.env.PUBLIC_URL + '/static/attributions.txt'}\n className=\"link\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {this.props.t('Attributions')}\n </a>\n </p>\n <p className=\"userLink\">\n <Trans i18nKey=\"Contact Nira to manage your account\">\n <a href=\"/contact\" className=\"link\" target=\"_blank\">\n Contact Nira\n </a>\n to manage your account\n </Trans>\n </p>\n\n <ToggleCookieModal className=\"userLink\">\n <p className=\"userLink\">\n <span className=\"cookie-link\">{this.props.t('Manage cookies')}</span>\n </p>\n </ToggleCookieModal>\n\n <p className=\"logoutButton\" onClick={() => LoginManagerInstance.signOut()}>\n {this.props.t('Log out')}\n </p>\n </div>\n </div>\n )\n }\n\n render() {\n return (\n <>\n <div className=\"userInitials\" onClick={() => this.userClicked()}>\n <h6>{this.getNameInitials(this.props.userData?.displayName)}</h6>\n </div>\n <Sidebar\n isOpen={this.state.isSidebarOpen}\n closeSidebar={() => this.closeUserSidebar()}\n >\n {this.state.isSidebarOpen && this.renderUserContent()}\n </Sidebar>\n </>\n )\n }\n}\nexport default withTranslation()(UserSidebar)\n","var _path;\nfunction _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\nimport * as React from \"react\";\nfunction SvgCarDrivingOnRoad(_ref, svgRef) {\n let {\n title,\n titleId,\n ...props\n } = _ref;\n return /*#__PURE__*/React.createElement(\"svg\", _extends({\n id: \"Layer_1\",\n \"data-name\": \"Layer 1\",\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 122.88 116.34\",\n ref: svgRef,\n \"aria-labelledby\": titleId\n }, props), title ? /*#__PURE__*/React.createElement(\"title\", {\n id: titleId\n }, title) : null, _path || (_path = /*#__PURE__*/React.createElement(\"path\", {\n d: \"M0,116.34,30.11,0h7L11,116.34ZM28.85,83.7c-7.17-3.64-6.34-7.7.86-7.28l1.61,3,3.32-10.34C36,65,38.12,61.35,42.39,61.35h41c4.27,0,6.72,3.62,7.75,7.75l2.5,10L95,76.42c7.41-.43,8.07,3.87.23,7.59L96.53,86c5.15,5.3,4.66,10.58,3.86,23.66v4.3A2.43,2.43,0,0,1,98,116.34H87.63a2.43,2.43,0,0,1-2.42-2.42v-2H37.91v2a2.43,2.43,0,0,1-2.42,2.42H25.15a2.43,2.43,0,0,1-2.42-2.42v-5.58a2.25,2.25,0,0,1,0-.38c-.79-10-1.89-19.09,6.09-24.26Zm13.2,11.9-9.18-1.15c-2.17-.24-2.75.67-2,2.54l1,2.41a3.42,3.42,0,0,0,1.24,1.38,4.16,4.16,0,0,0,2.06.57l8.18.06c2,0,2.84-.79,2.22-2.61a4.44,4.44,0,0,0-3.5-3.2Zm39,0,9.18-1.15c2.16-.24,2.75.67,2,2.54l-1,2.41A3.49,3.49,0,0,1,90,100.78a4.19,4.19,0,0,1-2.06.57l-8.19.06c-2,0-2.83-.79-2.21-2.61a4.44,4.44,0,0,1,3.5-3.2ZM34.77,81.72H89.9L87.4,71.33c-.68-3.17-2.65-5.91-5.91-5.91H43.8c-3.25,0-4.91,2.82-5.91,5.91L34.77,81.72v0ZM64.14,0l.42,10.56H58.13L58.76,0ZM56.05,48.37H66.64l.6,7.31H55.55l.5-7.31Zm1.63-27.2h7.58l.79,16.66H56.83l.85-16.66ZM93.4,0l29.48,116.33H112.42L85.84,0Z\"\n })));\n}\nconst ForwardRef = /*#__PURE__*/React.forwardRef(SvgCarDrivingOnRoad);\nexport default __webpack_public_path__ + \"static/media/car-driving-on-road.a00b0942.svg\";\nexport { ForwardRef as ReactComponent };","import { Capacitor } from '@capacitor/core'\nimport {\n CallbackID,\n ClearWatchOptions,\n Geolocation,\n Position,\n WatchPositionCallback,\n} from '@capacitor/geolocation'\n\nexport class ClearWatch implements ClearWatchOptions {\n setNativeId(id: CallbackID) {\n this.isNative = true\n this.id = id\n }\n\n setClearId(clearId: number) {\n this.isNative = false\n this.clearId = clearId\n }\n isNative: boolean = false\n id: CallbackID = ''\n clearId: number = 0\n}\n\n/**\n * We use 2 different libraries to get position, one that is default available in browsers\n * and one that is specific for GPS. This is a wrapper function to abstract away from the internal\n * api's\n */\nexport function getPosition(): Promise<Position> {\n if (Capacitor.isNativePlatform()) {\n return Geolocation.getCurrentPosition().catch(() => {\n throw Error('Failed to get position')\n })\n } else if (navigator.geolocation) {\n return new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(\n (position) => {\n resolve(position)\n },\n () => {\n reject('Failed to get position')\n },\n {\n timeout: 8000,\n enableHighAccuracy: true,\n }\n )\n })\n } else {\n return new Promise((resolve, reject) => {\n reject('Position not available')\n })\n }\n}\n\nexport function watchPosition(\n positionCallback: WatchPositionCallback\n): Promise<ClearWatch> {\n if (Capacitor.isNativePlatform()) {\n return Geolocation.watchPosition({}, positionCallback).then((value: CallbackID) => {\n const clear = new ClearWatch()\n clear.setNativeId(value)\n return clear\n })\n } else if (navigator.geolocation) {\n return new Promise((resolve, reject) => {\n let isResolved = false\n const clearId = navigator.geolocation.watchPosition(\n (position) => {\n if (!isResolved) {\n const clear = new ClearWatch()\n clear.setClearId(clearId)\n resolve(clear)\n isResolved = true\n }\n positionCallback(position)\n },\n () => {\n reject('Failed to get position')\n },\n {\n timeout: 8000,\n enableHighAccuracy: true,\n }\n )\n })\n } else {\n return new Promise((resolve, reject) => {\n reject('Position not available')\n })\n }\n}\n\nexport function clearWatch(clear: ClearWatch): Promise<void> {\n if (clear.isNative) {\n return Geolocation.clearWatch(clear)\n } else if (navigator.geolocation) {\n return new Promise((resolve, reject) => {\n navigator.geolocation.clearWatch(clear.clearId)\n resolve()\n })\n }\n return new Promise((resolve, reject) => {\n resolve()\n })\n}\n","import * as React from 'react'\nimport type { GpsMode } from '../Maps.types'\nimport { GpsModeType } from './../Maps.types'\nimport { ReactComponent as TrackIcon } from '../../../img/icons/car-driving-on-road.svg'\n\nexport interface ButtonProps {\n gpsMode: GpsMode\n onClick: () => void\n}\n\nclass TrackButton extends React.Component<ButtonProps> {\n render() {\n return (\n <button\n data-testid=\"trackButton\"\n className={\n this.props.gpsMode.type === GpsModeType.Track\n ? 'mapIconButtonSelected mapIconButton trackButton'\n : 'mapIconButton trackButton'\n }\n onClick={this.props.onClick}\n >\n <TrackIcon />\n </button>\n )\n }\n}\n\nexport default TrackButton\n","export default __webpack_public_path__ + \"static/media/location.18c1628d.svg\";","export default __webpack_public_path__ + \"static/media/region.11c6d876.svg\";","export default __webpack_public_path__ + \"static/media/nira-logo-white.09c50146.svg\";","import * as React from 'react'\nimport { isMobile } from 'react-device-detect'\n\nimport { FeatureLike } from 'ol/Feature'\nimport { fromLonLat } from 'ol/proj'\n\nimport { Position } from '@capacitor/geolocation'\nimport { isEqual } from 'lodash'\nimport { TFunction, withTranslation } from 'react-i18next'\nimport MapComponent from '../../components/map/MapComponent'\nimport NiraAirTemperatureVectorLayer from '../../components/map/layer/NiraAirTemperatureVectorLayer'\nimport NiraAlertVectorLayer, {\n NiraAlertsVectorLayerName,\n} from '../../components/map/layer/NiraAlertVectorLayer'\nimport NiraFrictionVectorLayer from '../../components/map/layer/NiraFrictionVectorLayer'\nimport NiraHydroplaningAlertsVectorLayer from '../../components/map/layer/NiraHydroplaningAlertsVectorLayer'\nimport NiraRoughnessVectorLayer from '../../components/map/layer/NiraRoughnessVectorLayer'\nimport NiraRscFrictionVectorLayer from '../../components/map/layer/NiraRscFrictionVectorLayer'\nimport NiraRscRoadConditionVectorLayer from '../../components/map/layer/NiraRscRoadConditionVectorLayer'\nimport NiraSeverePotholeAlertsVectorLayer from '../../components/map/layer/NiraSeverePotholeAlertsVectorLayer'\nimport NiraSevereRoughnessAlertsVectorLayer from '../../components/map/layer/NiraSevereRoughnessAlertsVectorLayer'\nimport NiraSlipperyAlertsVectorLayer from '../../components/map/layer/NiraSlipperyAlertsVectorLayer'\nimport NiraVectorLayer, {\n NiraVectorLayerName,\n} from '../../components/map/layer/NiraVectorLayer'\nimport AlertsSelector from '../../components/map/overlay/AlertsSelector'\nimport LayerSwitcher from '../../components/map/overlay/LayerSwitcher'\nimport MapActions from '../../components/mapActions/MapActions'\nimport MapSidebar from '../../components/mapSidebar/MapSidebar'\nimport MapToggleSidebar from '../../components/mapSidebar/MapToggleSidebar'\nimport Restricted from '../../components/restricted'\nimport UserSidebar from '../../components/userSidebar/UserSidebar'\nimport permissions from '../../permissions'\nimport Configuration from '../../utils/Configuration'\nimport LoginManagerInstance, { UserData } from '../../utils/LoginManager'\nimport { ClearWatch, clearWatch, getPosition, watchPosition } from './LocationUtil'\nimport { findClosestRoadSegment } from './MapUtil'\nimport type { GpsMode, TimeMode, View } from './Maps.types'\nimport { GpsModeDataTrack, GpsModeDefaultNone, GpsModeType } from './Maps.types'\nimport TrackButton from './buttons/TrackButton'\n\nimport LocationIcon from '../../img/icons/location.svg'\nimport HomeRegionIcon from '../../img/icons/region.svg'\nimport CompanyLogo from '../../img/nira-logo-white.svg'\n\nimport './maps.scss'\n\nconst DEFAULT_IS_OEM = false\n\nexport interface MapsProps {\n t: TFunction\n}\nexport interface MapsState {\n isLoggedIn: boolean\n activeVectorLayer: NiraVectorLayer | null\n vectorLayers: Record<NiraVectorLayerName, NiraVectorLayer>\n alertsVectorLayers: Record<NiraAlertsVectorLayerName, NiraAlertVectorLayer>\n activeAlertsVectorLayers: NiraAlertsVectorLayerName[]\n activeFeature: FeatureLike | null\n userData: UserData\n currentPosition?: View\n showZoomError: boolean\n currentTimeMode: TimeMode\n currentView: View\n currentGpsMode: GpsMode\n}\n\nexport class MapsPage extends React.Component<MapsProps, MapsState> {\n resetErrorMessageTimer: NodeJS.Timeout\n mapRef: React.RefObject<MapComponent>\n constructor(props: MapsProps) {\n super(props)\n const vectorLayers: Record<NiraVectorLayerName, NiraVectorLayer> = {\n rscRoadCondition: new NiraRscRoadConditionVectorLayer(),\n rscFriction: new NiraRscFrictionVectorLayer(),\n roughness: new NiraRoughnessVectorLayer(),\n friction: new NiraFrictionVectorLayer(),\n temperature: new NiraAirTemperatureVectorLayer(),\n }\n const alertsVectorLayers: Record<NiraAlertsVectorLayerName, NiraAlertVectorLayer> = {\n severeRoughness: new NiraSevereRoughnessAlertsVectorLayer(),\n slippery: new NiraSlipperyAlertsVectorLayer(),\n severePothole: new NiraSeverePotholeAlertsVectorLayer(),\n hydroplaning: new NiraHydroplaningAlertsVectorLayer(),\n }\n const activeAlertsVectorLayers: NiraAlertsVectorLayerName[] = Object.entries(\n alertsVectorLayers\n ).map((value) => {\n return value[0] as NiraAlertsVectorLayerName\n })\n const userData = LoginManagerInstance.getCurrentUserData()\n this.state = {\n isLoggedIn: false,\n activeVectorLayer:\n userData.isOem &&\n this.permissionToLayer(userData, vectorLayers.rscRoadCondition.bundleName)\n ? vectorLayers.rscRoadCondition\n : vectorLayers.friction,\n vectorLayers,\n alertsVectorLayers,\n activeAlertsVectorLayers,\n activeFeature: null,\n userData,\n showZoomError: false,\n currentTimeMode: { label: 'live', timestamps: [] },\n currentView: {\n center: userData.mapHome || { lon: 15.56386, lat: 58.39652 },\n zoom: 10,\n },\n currentGpsMode: GpsModeDefaultNone,\n }\n this.mapRef = React.createRef()\n this.loginChanged = this.loginChanged.bind(this)\n this.orientationChanged = this.orientationChanged.bind(this)\n this.getCurrentPosition = this.getCurrentPosition.bind(this)\n this.goToHomeRegion = this.goToHomeRegion.bind(this)\n this.changeTimeMode = this.changeTimeMode.bind(this)\n this.toggleTrackMode = this.toggleTrackMode.bind(this)\n this.callFindClosestRoadSegment = this.callFindClosestRoadSegment.bind(this)\n }\n\n permissionToLayer(userData: UserData, bundleName: string): boolean {\n const { layers = [] } = userData\n return layers.find((layer) => layer === bundleName) !== undefined\n }\n\n componentDidMount() {\n document.title = this.props.t('Map') + ' | ' + process.env.REACT_APP_SITE_TITLE\n LoginManagerInstance.addDataListener(this.loginChanged)\n window.addEventListener('orientationchange', this.orientationChanged)\n }\n\n componentWillUnmount() {\n LoginManagerInstance.removeDataListener(this.loginChanged)\n window.removeEventListener('orientationchange', this.orientationChanged)\n }\n\n handleGpsModeChanges(prevState) {\n // Clear old stuff\n if (prevState.currentGpsMode.type === GpsModeType.Error) {\n clearTimeout(this.resetErrorMessageTimer)\n } else if (prevState.currentGpsMode.type === GpsModeType.Track) {\n const modeData: GpsModeDataTrack = prevState.currentGpsMode\n .modeData as GpsModeDataTrack\n if (modeData !== null && modeData.clearWatch !== null) {\n clearWatch(modeData.clearWatch)\n }\n this.setState({\n // Clear active feature when leaving track mode\n activeFeature: null,\n })\n }\n\n if (this.state.currentGpsMode.type === GpsModeType.Error) {\n this.resetErrorMessageTimer = setTimeout(() => {\n this.setState({ currentGpsMode: GpsModeDefaultNone })\n }, 5000)\n } else if (this.state.currentGpsMode.type === GpsModeType.Once) {\n const gotPosition = (position: Position) => {\n this.setState({\n currentPosition: {\n center: {\n lon: position.coords.longitude,\n lat: position.coords.latitude,\n },\n zoom: this.state.currentView.zoom,\n },\n currentGpsMode: GpsModeDefaultNone,\n })\n }\n\n const failedToGetPosition = (error: any) => {\n console.log('error when getting position', error)\n this.setGpsModeError()\n }\n\n getPosition().then(gotPosition).catch(failedToGetPosition)\n } else if (this.state.currentGpsMode.type === GpsModeType.Track) {\n const trackZoomLevel = 14\n const gotClearWatch = (clearWatch: ClearWatch) => {\n const modeData: GpsModeDataTrack = this.state.currentGpsMode\n .modeData as GpsModeDataTrack\n const newGpsState = {\n type: this.state.currentGpsMode.type,\n modeData: new GpsModeDataTrack(clearWatch, modeData.initPosition),\n locationError: '',\n }\n\n this.setState({\n currentGpsMode: newGpsState,\n activeFeature: null,\n })\n }\n\n const failedToGetPosition = (error: any) => {\n console.log('error when getting position', error)\n this.setGpsModeError()\n }\n\n const positionCallback = (position: Position) => {\n const modeData: GpsModeDataTrack = this.state.currentGpsMode\n .modeData as GpsModeDataTrack\n if (modeData.initPosition) {\n const newPosition = {\n center: {\n lon: position.coords.longitude,\n lat: position.coords.latitude,\n },\n zoom: Math.max(trackZoomLevel, this.state.currentView.zoom),\n }\n this.setState({\n currentPosition: undefined,\n })\n const newGpsState = {\n type: this.state.currentGpsMode.type,\n modeData: new GpsModeDataTrack(modeData.clearWatch),\n locationError: this.state.currentGpsMode.locationError,\n }\n this.setState({\n currentGpsMode: newGpsState,\n currentPosition: newPosition,\n })\n } else {\n const newPosition = {\n center: {\n lon: position.coords.longitude,\n lat: position.coords.latitude,\n },\n zoom: this.state.currentView.zoom,\n }\n if (!isEqual(this.state.currentPosition, newPosition)) {\n this.setState({ currentPosition: newPosition })\n }\n }\n }\n\n watchPosition(positionCallback).then(gotClearWatch).catch(failedToGetPosition)\n }\n }\n\n callFindClosestRoadSegment() {\n const { currentPosition } = this.state\n if (!currentPosition) return\n const coords = fromLonLat([currentPosition.center.lon, currentPosition.center.lat])\n const currentMapRef = this.mapRef\n const feature = findClosestRoadSegment(coords, currentMapRef)\n if (feature) this.featureClicked(feature)\n }\n\n componentDidUpdate(_prevProps, prevState) {\n if (prevState.currentGpsMode.type !== this.state.currentGpsMode.type) {\n this.handleGpsModeChanges(prevState)\n }\n }\n\n orientationChanged() {\n this.forceUpdate()\n }\n\n loginChanged(userData: UserData) {\n this.setState({ userData: userData })\n }\n\n currentLayerChanged(layer: NiraVectorLayer) {\n this.setState({\n activeVectorLayer: layer,\n })\n this.closeMapSidebar()\n }\n\n activeAlertsLayersChanged(layerName: NiraAlertsVectorLayerName) {\n var updatedList = this.state.activeAlertsVectorLayers\n const elementIndex = updatedList.indexOf(layerName)\n\n if (elementIndex === -1) {\n updatedList = [...updatedList, layerName]\n } else {\n updatedList = updatedList.filter((name) => name !== layerName)\n }\n\n this.setState({\n activeAlertsVectorLayers: updatedList,\n })\n }\n\n changeTimeMode(nextMode: TimeMode) {\n this.setState({ currentTimeMode: nextMode })\n }\n\n featureClicked(feature: FeatureLike | null) {\n if (feature) this.setState({ activeFeature: feature })\n }\n\n viewChanged(view: View) {\n this.setState({ currentView: view })\n }\n\n renderComplete() {\n if (\n !!this.state.currentPosition &&\n this.state.currentGpsMode.type === GpsModeType.Track\n ) {\n // This will be called multiple times since renderComplete is triggered multiple times.\n // We could not find a simple work around for this.\n this.callFindClosestRoadSegment()\n }\n }\n\n goToHomeRegion(): void {\n if (!this.mapRef.current) return\n this.mapRef.current.gotToHomeRegion()\n }\n\n setGpsModeError(): void {\n this.setState({\n currentGpsMode: {\n type: GpsModeType.Error,\n modeData: {},\n locationError: 'Could not get location',\n },\n })\n }\n\n getCurrentPosition() {\n const newGpsState: GpsMode = {\n type: GpsModeType.Once,\n modeData: { isGettingLocation: true },\n locationError: 'Getting location',\n }\n\n this.setState({ currentGpsMode: newGpsState })\n }\n\n toggleTrackMode() {\n if (this.state.currentGpsMode.type === GpsModeType.None) {\n this.setState({\n currentGpsMode: {\n type: GpsModeType.Track,\n modeData: new GpsModeDataTrack(null, true),\n locationError: '',\n },\n })\n } else {\n this.setState({\n currentGpsMode: { type: GpsModeType.None, modeData: {}, locationError: '' },\n })\n }\n }\n\n closeMapSidebar() {\n this.setState({\n activeFeature: null,\n })\n }\n\n renderPartnerLogos() {\n const permissions = this.state.userData.permissions || []\n return Configuration.PARTNER_LOGOS.filter((partner) =>\n permissions.some((permissionName) => permissionName === partner.permission)\n ).map((partner) => <img src={partner.logo} alt={partner.name} key={partner.logo} />)\n }\n\n renderGoToHomeRegionButton() {\n if (this.state.userData.mapHome) {\n return (\n <div className=\"buttonContainer\">\n <button className=\"mapIconButton\" onClick={() => this.goToHomeRegion()}>\n <img className=\"buttonIcon\" alt=\"go home\" src={HomeRegionIcon} />\n </button>\n </div>\n )\n }\n return <></>\n }\n\n renderSidebar() {\n if (!this.state.activeVectorLayer) return null\n return (\n <MapSidebar\n feature={this.state.activeFeature}\n isOpen={\n !!this.state.activeFeature &&\n this.state.currentGpsMode.type === GpsModeType.None\n }\n closeSidebar={() => this.closeMapSidebar()}\n currentVectorLayer={this.state.activeVectorLayer}\n alertLayers={this.state.alertsVectorLayers}\n />\n )\n }\n\n renderTrackSidebar() {\n if (this.state.currentGpsMode.type === GpsModeType.Track) {\n return (\n <MapToggleSidebar\n feature={this.state.activeFeature}\n currentVectorLayer={this.state.activeVectorLayer}\n />\n )\n }\n }\n\n renderMapButtons() {\n return (\n <div className={`mapButtons ${isMobile ? 'mobile' : 'desktop'}`}>\n <div className=\"buttonContainer\">\n <p className=\"errorMessage\">\n {this.props.t(this.state.currentGpsMode.locationError)}\n </p>\n </div>\n {this.renderGoToHomeRegionButton()}\n <div className=\"buttonContainer\">\n <button\n disabled={this.state.currentGpsMode.type === GpsModeType.Once}\n className=\"mapButton\"\n onClick={this.getCurrentPosition}>\n <img className=\"buttonIcon\" alt=\"location\" src={LocationIcon} />\n </button>\n </div>\n <div className=\"buttonContainer\">\n <Restricted requiredPermission={permissions.GPS_TRACK_MODE}>\n <TrackButton\n gpsMode={this.state.currentGpsMode}\n onClick={this.toggleTrackMode}\n />\n </Restricted>\n </div>\n </div>\n )\n }\n\n filterVectorLayers(): Record<string, NiraVectorLayer> {\n const { isOem, layers = [] } = this.state.userData\n const allowedLayers = Object.entries(this.state.vectorLayers).filter(([key, layer]) =>\n isOem ? layer.visibleOem : layer.visibleMaintenance\n )\n return Object.fromEntries(\n allowedLayers.filter(([key, layer]) => layers.includes(layer.bundleName))\n )\n }\n\n filterAlertLayers(): Record<string, NiraAlertVectorLayer> {\n const layers = this.state.userData.layers || []\n return Object.fromEntries(\n Object.entries(this.state.alertsVectorLayers).filter(([key, layer]) =>\n layers.includes(layer.bundleName)\n )\n )\n }\n\n renderMapActions() {\n const { userData } = this.state\n const vectorLayers = this.filterVectorLayers()\n if (Object.entries(vectorLayers).length < 2) {\n return <></>\n }\n return (\n <MapActions>\n <LayerSwitcher\n title={userData.isOem ? 'Road Surface Conditions' : 'Road Graphics'}\n currentVectorLayer={this.state.activeVectorLayer}\n vectorLayers={vectorLayers}\n layerChanged={(layer) => this.currentLayerChanged(layer)}\n />\n {userData.isOem && Object.keys(this.filterAlertLayers()).length > 0 ? (\n <AlertsSelector\n alertVectorLayers={this.filterAlertLayers()}\n activeAlertVectorLayers={this.state.activeAlertsVectorLayers}\n onAlertVectorLayersChanged={(layer) => this.activeAlertsLayersChanged(layer)}\n />\n ) : null}\n </MapActions>\n )\n }\n\n render() {\n const { activeVectorLayer, currentGpsMode, userData } = this.state\n return (\n <div id=\"maps\" className=\"map\">\n <div className=\"flexContainer\">\n <div className=\"mapContainer\">\n <MapComponent\n isOem={userData.isOem || DEFAULT_IS_OEM}\n timestamps={this.state.currentTimeMode.timestamps.map((d) =>\n d.toISOString()\n )}\n ref={this.mapRef}\n currentVectorLayer={activeVectorLayer}\n vectorLayers={this.state.vectorLayers}\n alertsVectorLayers={this.state.alertsVectorLayers}\n activeAlertsVectorLayers={this.state.activeAlertsVectorLayers}\n activeFeature={this.state.activeFeature}\n featureClicked={(feature) => this.featureClicked(feature)}\n coordinates={this.state.currentPosition}\n setShowError={(show) => this.setState({ showZoomError: show })}\n mapHome={userData.mapHome}\n currentView={this.state.currentView}\n currentGpsMode={currentGpsMode}\n viewChanged={(view) => this.viewChanged(view)}\n renderComplete={() => this.renderComplete()}\n />\n <div className=\"mapOverlay\">\n <div className=\"logos\">\n <img className=\"companyLogo\" alt=\"company logo\" src={CompanyLogo} />\n {this.renderPartnerLogos()}\n </div>\n <UserSidebar userData={userData} />\n {this.renderSidebar()}\n {this.renderMapButtons()}\n {this.renderMapActions()}\n {activeVectorLayer && activeVectorLayer.legend()}\n <div className={`zoomError ${this.state.showZoomError ? '' : 'hideError'}`}>\n {this.props.t('Zoom in to show road data')}\n </div>\n <div className={`${this.state.showZoomError ? 'hideTimeSlider' : ''}`}>\n {currentGpsMode.type !== GpsModeType.Track &&\n activeVectorLayer &&\n activeVectorLayer.timeSelectTool({\n mode: this.state.currentTimeMode,\n changeMode: this.changeTimeMode,\n })}\n </div>\n </div>\n </div>\n {this.renderTrackSidebar()}\n </div>\n </div>\n )\n }\n}\n\nexport default withTranslation()(MapsPage)\n","import VectorSource from 'ol/source/Vector'\nimport LineString from 'ol/geom/LineString'\nimport GeometryLayout from 'ol/geom/GeometryLayout'\nimport Feature, { FeatureLike } from 'ol/Feature'\n\nexport function findClosestRoadSegment(\n coords: number[],\n currentMapRef: any\n): FeatureLike | null {\n const currentMap = currentMapRef.current.map\n const pixel = currentMap.getPixelFromCoordinate(coords)\n const metersPerPixel = currentMap.getView().getResolution()\n const features = currentMap.getFeaturesAtPixel(pixel, {\n hitTolerance: 15 / metersPerPixel,\n layerFilter: (layer) => layer === currentMapRef.current.vectorTileLayer,\n })\n if (features.length > 0) {\n let source = convertToVectorSource()\n const closestRoadSegment = source.getClosestFeatureToCoordinate(coords)\n const closestFeature = features.find(\n (feature) => feature.getId() === closestRoadSegment.getId()\n )\n return closestFeature\n } else {\n return null\n }\n\n function convertToVectorSource() {\n let source = new VectorSource()\n const lineStringFeatures = features.map((feature) => {\n const coordinates = feature.getGeometry().getOrientedFlatCoordinates()\n let lineStringFeature = new Feature(new LineString(coordinates, GeometryLayout.XY))\n lineStringFeature.setId(feature.getId())\n return lineStringFeature\n })\n source.addFeatures(lineStringFeatures)\n return source\n }\n}\n","import './ToggleButton.scss'\nimport { useTranslation } from 'react-i18next'\n\ninterface Props {\n text: string\n onClick: () => void\n selected: boolean\n variant?: 'dark' | 'light'\n}\n\nconst ToggleButton = (props: Props) => {\n const selected = props.selected ? 'selected' : ''\n const variant = props.variant ?? 'dark'\n const { t } = useTranslation()\n\n return (\n <div className=\"toggleButtonContainer\" tabIndex={0} onClick={props.onClick}>\n <span className={`toggleButtonTitle ${selected} ${variant}`}>{t(props.text)}</span>\n <div className={`toggleButton ${selected} ${variant}`}>\n <div className={`dot ${selected} ${variant}`} />\n </div>\n </div>\n )\n}\n\nexport default ToggleButton\n","import { Modal } from './Modal.component'\nexport default Modal\n","import { ModalComponent } from './Modal.types'\nimport './Modal.scss'\n\nexport const Modal: ModalComponent = ({ children, title, footer }) => {\n return (\n <div className=\"modal-container\">\n <div className=\"modal\">\n <div className=\"modal-header\">\n <h3>{title}</h3>\n </div>\n <div className=\"modal-content\">{children}</div>\n <div className=\"modal-footer\">{footer}</div>\n </div>\n </div>\n )\n}\n","import { add } from 'date-fns'\nimport { createBrowserHistory } from 'history'\nimport { mapValues } from 'lodash'\nimport { useCallback, useContext, useEffect, useState } from 'react'\nimport ReactGoogleAnalytics from 'react-ga'\nimport { Trans, useTranslation } from 'react-i18next'\nimport { NiraContext } from '../../../context'\nimport Configuration from '../../../utils/Configuration'\nimport { deleteCookie, getCookie, setCookie } from '../../../utils/cookies'\nimport ToggleButton from '../../map/overlay/ToggleButton'\nimport Modal from '../../modal'\nimport './CookieModal.scss'\nimport { CookieBarComponent } from './CookieModal.types'\n\nconst history = createBrowserHistory()\n\n// Typescript workaround to be able to access Google Analytics properties\ndeclare global {\n interface Window {\n ga: any\n }\n}\n\nexport type CookiePreferences = {\n analytics: boolean\n preferences: boolean\n}\n\nexport const CookieBar: CookieBarComponent = () => {\n const { i18n, t } = useTranslation()\n const niraContext = useContext(NiraContext)\n\n const [cookiePreferences, setCookiePreferences] = useState<CookiePreferences>({\n analytics: false,\n preferences: false,\n })\n\n const logPageView = useCallback(() => {\n ReactGoogleAnalytics.pageview(window.location.pathname + window.location.search)\n }, [])\n\n const initGoogleAnalytics = useCallback(() => {\n ReactGoogleAnalytics.initialize(Configuration.GOOGLE_ANALYTICS_ID as string)\n history.listen((_location, _action) => {\n logPageView()\n })\n logPageView()\n }, [logPageView])\n\n useEffect(() => {\n ;(async () => {\n const cookiePreferences = await getCookie('cookiePreferences')\n if (cookiePreferences) {\n const parsedCookiePreferences: CookiePreferences = JSON.parse(cookiePreferences)\n setCookiePreferences(parsedCookiePreferences)\n if ('analytics' in parsedCookiePreferences && parsedCookiePreferences.analytics)\n initGoogleAnalytics()\n }\n })()\n }, [initGoogleAnalytics])\n\n const handleSaveClick = async (acceptAll?: boolean) => {\n if (niraContext) niraContext.setShowCookieModal(false)\n let cookies = cookiePreferences\n\n if (acceptAll) {\n cookies = mapValues(cookiePreferences, (_) => true)\n setCookiePreferences(cookies)\n }\n\n const expireDate = add(new Date(), { years: 1 })\n await setCookie('cookiePreferences', JSON.stringify(cookies), expireDate)\n\n if (cookiePreferences.analytics) {\n // User consents to Google Analytics\n initGoogleAnalytics()\n } else if (window.ga) {\n // Remove analytics cookies if any exists\n await Promise.all([deleteCookie('_ga'), deleteCookie('_gid'), deleteCookie('_gat')])\n window.ga('remove')\n }\n\n // Store current language\n if (cookiePreferences.preferences) {\n localStorage.setItem('i18nextLng', i18n.language)\n } else {\n localStorage.removeItem('i18nextLng')\n }\n }\n\n const footer = (\n <div className=\"cookie-footer\">\n <button onClick={async () => await handleSaveClick()} className=\"inverted\">\n {t('Save')}\n </button>\n <button onClick={async () => await handleSaveClick(true)}>{t('Accept all')}</button>\n </div>\n )\n\n return niraContext && niraContext.showCookieModal ? (\n <Modal title=\"Cookies\" footer={footer}>\n <div className=\"cookie-bar\">\n <div className=\"section-container\">\n <Trans i18nKey=\"cookieDescription\">\n <p>\n We use necessary cookies to make our site work. We would also like to set\n optional analytics cookies to help us improve the service and preference\n cookies for improving the user experience. We won't set optional cookies\n unless you enable them. Using this service will set a cookie to remeber your\n preferences.\n </p>\n <p>\n For more detailed information about the cookies we use, see our{' '}\n <a href=\"/terms\" target=\"_blank\" rel=\"noopener noreferrer\">\n Terms & Conditions\n </a>\n .\n </p>\n </Trans>\n\n <div className=\"section\">\n <div className=\"header\">\n <div className=\"title\">{t('Necessary')}</div>\n <ToggleButton\n text=\"\"\n onClick={() => true}\n selected={true}\n variant=\"light\"\n />\n </div>\n <div className=\"content\">\n <p>\n {t(\n 'We use necessary cookies to enable core functionality used to handle secure login and authentication. You may disable these by changing your browser settings, but this will affect how the website functions.'\n )}\n </p>\n </div>\n </div>\n\n <div className=\"section\">\n <div className=\"header\">\n <div className=\"title\">{t('Analytics')}</div>\n <ToggleButton\n text=\"\"\n onClick={() =>\n setCookiePreferences({\n ...cookiePreferences,\n analytics: !cookiePreferences.analytics,\n })\n }\n selected={cookiePreferences.analytics}\n variant=\"light\"\n />\n </div>\n <div className=\"content\">\n <p>\n {t(\n 'We use Google Analytics to help us improve the service by collecting information about how you use the service. The collected information does not directly identify anyone.'\n )}\n </p>\n </div>\n </div>\n\n <div className=\"section\">\n <div className=\"header\">\n <div className=\"title\">{t('Preferences')}</div>\n <ToggleButton\n text=\"\"\n onClick={() =>\n setCookiePreferences({\n ...cookiePreferences,\n preferences: !cookiePreferences.preferences,\n })\n }\n selected={cookiePreferences.preferences}\n variant=\"light\"\n />\n </div>\n <div className=\"content\">\n <p>{t('We use preference cookies to store your selected language.')}</p>\n </div>\n </div>\n </div>\n </div>\n </Modal>\n ) : (\n <></>\n )\n}\n","import { CookieBar } from './CookieModal.component'\nexport default CookieBar\n","import { createBrowserHistory } from 'history'\nimport React, { Component } from 'react'\nimport { Route, Router, Switch } from 'react-router-dom'\n\nimport './App.scss'\nimport { NiraContextProvider } from './context'\nimport LoginPage from './pages/Login/Login'\nimport MapsPage from './pages/maps/Maps'\nimport LoginManagerInstance, { UserData } from './utils/LoginManager'\n\nimport CookieModal from './components/cookies/modal'\n\nexport interface AppProps {}\nexport interface AppState {\n authenticated: boolean\n}\n\nconst history = createBrowserHistory()\nconst mapUrl = process.env.PUBLIC_URL ? process.env.PUBLIC_URL : '/'\nconst loginUrl = `${process.env.PUBLIC_URL}/login`\n\nclass App extends Component<AppProps, AppState> {\n constructor(props: AppProps) {\n super(props)\n this.state = { authenticated: false }\n this.loginPressed = this.loginPressed.bind(this)\n this.loginChanged = this.loginChanged.bind(this)\n }\n\n async componentDidMount() {\n LoginManagerInstance.addDataListener(this.loginChanged)\n await LoginManagerInstance.checkSignIn()\n }\n\n componentWillUnmount() {\n LoginManagerInstance.removeDataListener(this.loginChanged)\n }\n\n loginChanged(userData: UserData) {\n const userSession = userData?.session\n\n if (!userSession) {\n if (window.location.pathname !== loginUrl) {\n window.location.pathname = loginUrl\n }\n return\n }\n if (this.state.authenticated !== userSession.isValid()) {\n if (!userSession.isValid()) {\n if (window.location.pathname !== loginUrl) {\n window.location.pathname = loginUrl\n }\n } else {\n if (window.location.pathname !== mapUrl) {\n window.location.pathname = mapUrl\n }\n }\n }\n this.setState({ authenticated: userSession.isValid() })\n }\n\n loginPressed() {\n LoginManagerInstance.signIn()\n }\n\n render() {\n const userData = LoginManagerInstance.getCurrentUserData()\n // Before userdata is set, we should not show any page.\n if (\n (!userData.session || !userData.session.isValid()) &&\n window.location.pathname !== loginUrl\n ) {\n return <div className=\"page-content\"></div>\n }\n\n return (\n <NiraContextProvider>\n <Router history={history}>\n <Switch>\n <Route path={mapUrl} component={MapsPage} exact={true} />\n <Route path={[`${loginUrl}/:page`, loginUrl]} component={LoginPage} />\n <Route path={mapUrl}>\n <div className=\"notfound page-content\">\n <h4>404</h4>\n <div>Page not found</div>\n </div>\n </Route>\n </Switch>\n <CookieModal />\n </Router>\n </NiraContextProvider>\n )\n }\n}\n\nexport default App\n","import { ReportHandler } from 'web-vitals'\n\nconst reportWebVitals = (onPerfEntry?: ReportHandler) => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry)\n getFID(onPerfEntry)\n getFCP(onPerfEntry)\n getLCP(onPerfEntry)\n getTTFB(onPerfEntry)\n })\n }\n}\n\nexport default reportWebVitals\n","import i18n from 'i18next'\nimport { initReactI18next } from 'react-i18next'\nimport LanguageDetector from 'i18next-browser-languagedetector'\n\nimport translationEN from './translations/en/translation.json'\nimport translationDE from './translations/de/translation.json'\nimport translationSV from './translations/sv/translation.json'\n\n// the translations\nconst resources = {\n en: {\n translation: translationEN,\n },\n de: {\n translation: translationDE,\n },\n sv: {\n translation: translationSV,\n },\n}\n\ni18n\n // detect user language\n // learn more: https://github.com/i18next/i18next-browser-languageDetector\n .use(LanguageDetector)\n // pass the i18n instance to react-i18next.\n .use(initReactI18next)\n // init i18next\n // for all options read: https://www.i18next.com/overview/configuration-options\n .init({\n resources,\n fallbackLng: 'en',\n keySeparator: false,\n interpolation: {\n escapeValue: false, // not needed for react as it escapes by default\n },\n\n //lng: 'sv', // used to set a language, overrides languageDetector, only used for testing.\n detection: {\n order: ['localStorage', 'navigator'],\n caches: [], // Handle langugae cache manually\n },\n })\n\nexport default i18n\n","import React from 'react'\nimport ReactDOM from 'react-dom'\nimport App from './App'\nimport reportWebVitals from './reportWebVitals'\nimport './i18n'\n\nReactDOM.render(\n <React.StrictMode>\n <App />\n </React.StrictMode>,\n document.getElementById('root')\n)\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals()\n"],"sourceRoot":""}