{"mappings":"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","sources":["src/Common/TopBar.tsx","src/Components/NearbyServices.tsx","node_modules/.pnpm/@parcel+runtime-js@2.6.0_@parcel+core@2.6.0/node_modules/@parcel/runtime-js/lib/runtime-1aaf359f78e4207a.js","src/Components/ImageCarouselWithFullScreenSupport.tsx","src/Components/FullScreenImageGallery.tsx","src/Components/OverlayGallery.tsx","src/Components/useEventListener.ts"],"sourcesContent":["import React, { useState, useEffect, useCallback, ReactNode } from 'react';\nimport { ResourceText, IUseResourceTexts, withResourceTextSupport } from '../Components/ResourceText';\nimport { Link } from 'react-router-dom';\nimport { withDocument } from './window';\n\nimport SocialShareIcons from './SocialShareIcons';\nimport { SocialShareContext } from '../Telemetry/TelemetryManager';\n\nexport interface TopBarProps {\n\tbackButton?: { target: string; text: React.ReactElement };\n\tchildren?: React.ReactElement;\n\trightSideChildren?: React.ReactElement;\n\tvariant?: 'bgWhite';\n\tbanner?: React.ReactNode;\n}\n\nfunction TopBar(props: TopBarProps & IUseResourceTexts) {\n\tconst [isSocialShareOpen, setIsSocialShareOpen] = useState(false);\n\n\tconst onGlobalClickEvent = useCallback(\n\t\t(e: MouseEvent) => {\n\t\t\tconst target = e.target as HTMLElement;\n\n\t\t\tconst socialShareBar = document.getElementsByClassName('atom-socialShare__list');\n\t\t\t// If click is outside of wrapper div, close the menu\n\t\t\tif (socialShareBar.length && !socialShareBar[0]!.contains(target)) {\n\t\t\t\te.preventDefault();\n\t\t\t\tsetIsSocialShareOpen(false);\n\t\t\t}\n\t\t},\n\t\t[setIsSocialShareOpen],\n\t);\n\n\tuseEffect(() => {\n\t\tif (isSocialShareOpen) {\n\t\t\twithDocument((d) => d.addEventListener('click', onGlobalClickEvent));\n\t\t} else {\n\t\t\twithDocument((d) => d.removeEventListener('click', onGlobalClickEvent));\n\t\t}\n\n\t\treturn () => withDocument((d) => d.removeEventListener('click', onGlobalClickEvent));\n\t}, [isSocialShareOpen]);\n\n\tconst shareText = props.getResourceText('TopBar_SocialShareText', 'Katso, miten hienon asunnon löysin osoitteesta');\n\n\treturn (\n\t\t<div className={'mod-topBar' + (props.variant ? ` -${props.variant}` : '')}>\n\t\t\t<div className=\"mod-topBar__wrapper\">\n\t\t\t\t<LeftActionButtonsWrapper>\n\t\t\t\t\t{props.backButton && (\n\t\t\t\t\t\t<Link to={props.backButton.target} className=\"mod-topBar__link -back\">\n\t\t\t\t\t\t\t{props.backButton.text}\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t)}\n\t\t\t\t\t{props.children && props.children}\n\t\t\t\t</LeftActionButtonsWrapper>\n\t\t\t\t{props.banner}\n\t\t\t\t<div className={'mod-topBar__rightSide' + (isSocialShareOpen ? ' -socialShareOpen' : '')}>\n\t\t\t\t\t{props.rightSideChildren && props.rightSideChildren}\n\t\t\t\t\t<button className=\"mod-topBar__link -socialShare\" onClick={() => setIsSocialShareOpen(true)}>\n\t\t\t\t\t\t<ResourceText resourceKey=\"General_Share\" defaultText=\"Jaa\" />\n\t\t\t\t\t</button>\n\t\t\t\t\t<div className=\"mod-topBar__socialShareWrapper\">\n\t\t\t\t\t\t<SocialShareIcons shareText={shareText} context={SocialShareContext.ApartmentPage} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nexport default withResourceTextSupport(TopBar);\n\nfunction LeftActionButtonsWrapper({ children }: { children: ReactNode }) {\n\treturn <div className=\"mod-topBar__leftActionButtonsWrapper\">{children}</div>;\n}\n","import * as React from 'react';\r\nimport { NearbyServiceList, LocationAM } from '../Apartments/Api/ApartmentAM';\r\nimport { NearbyServiceCategory } from '../Apartments/Api/ApartmentSearchResultAM';\r\nimport { ResourceText, IUseResourceTexts, withResourceTextSupport } from './ResourceText';\r\nimport { arrayMin, arrayMax } from './arrayUtilities';\r\nimport { formatDistance, formatDistanceRange } from './numberUtils';\r\nimport { PoiCategory } from './Map/PoiApiClient';\r\nimport { MapActivatedProps } from './Map/MapComponent';\r\nimport LoadableShim from './LoadableShim';\r\n\r\nimport {\r\n\tIconMapCultureFill,\r\n\tIconMapDaycareFill,\r\n\tIconMapGroceriesFill,\r\n\tIconMapHealthServicesFill,\r\n\tIconMapPublicTransportFill,\r\n\tIconMapRestaurantFill,\r\n\tIconMapSchoolFill,\r\n\tIconMapSportsFill,\r\n\tSpacingContainer,\r\n} from '@kojamo/lumo-dls';\r\n\r\nconst MapComponentWrapper = LoadableShim(() => import('./Map/MapComponentWrapper'));\r\n\r\nexport const NearbyServices = withResourceTextSupport(function (\r\n\tprops: {\r\n\t\tcenter: LocationAM;\r\n\t\tbusinessEntityId: string;\r\n\t\tservices: NearbyServiceList;\r\n\t\tshowPublicTransportBar?: boolean;\r\n\t} & IUseResourceTexts,\r\n) {\r\n\tconst [visibleCategories, setVisibleCategories] = React.useState<PoiCategory[]>([\r\n\t\t'businessentity',\r\n\t\t'marketingbusinessentity',\r\n\t]);\r\n\tconst [mapControls, setMapControls] = React.useState<MapActivatedProps | undefined>(undefined);\r\n\tconst setCategoryVisibility = (c: PoiCategory, visible: boolean) => {\r\n\t\tconst isCategoryVisible = visibleCategories.some((cat) => cat === c);\r\n\t\tif (visible && !isCategoryVisible) {\r\n\t\t\tsetVisibleCategories(visibleCategories.concat(c));\r\n\t\t} else if (!visible && isCategoryVisible) {\r\n\t\t\tsetVisibleCategories(visibleCategories.filter((cat) => cat != c));\r\n\t\t}\r\n\t};\r\n\r\n\tconst onNearbyCategoryClick = (serviceCategory: NearbyServiceCategory) => {\r\n\t\tconst c = mapToPoiCategory(serviceCategory);\r\n\t\tconst isVisible = visibleCategories.some((cat) => cat === c);\r\n\t\tsetCategoryVisibility(c, !isVisible);\r\n\t\tif (mapControls) {\r\n\t\t\tmapControls.reCenter();\r\n\t\t}\r\n\t};\r\n\r\n\tconst exludedCategories = ['Nature', 'CityCenter'];\r\n\r\n\treturn (\r\n\t\t<>\r\n\t\t\t<p className=\"l-visible-screen-reader-only\">\r\n\t\t\t\t<ResourceText textType=\"Plain\" resourceKey=\"NearbyServices_ScreenReaderNote\" />\r\n\t\t\t</p>\r\n\t\t\t<div className=\"mod-map -noBg -themeBrown\" id=\"map\" aria-hidden>\r\n\t\t\t\t<div className=\"mod-map__wrapper\">\r\n\t\t\t\t\t<MapComponentWrapper\r\n\t\t\t\t\t\tdefaultCenter={props.center}\r\n\t\t\t\t\t\tbusinessEntityId={props.businessEntityId}\r\n\t\t\t\t\t\tvisibleCategories={visibleCategories}\r\n\t\t\t\t\t\tonMapActivated={(c) => setMapControls(c)}\r\n\t\t\t\t\t/>\r\n\r\n\t\t\t\t\t<div className=\"mod-map__section mod-map__services\">\r\n\t\t\t\t\t\t<ul className=\"mod-map__list\">\r\n\t\t\t\t\t\t\t{Object.keys(props.services)\r\n\t\t\t\t\t\t\t\t.filter((c) => !exludedCategories.includes(c))\r\n\t\t\t\t\t\t\t\t.map((cat: NearbyServiceCategory) => {\r\n\t\t\t\t\t\t\t\t\tconst services = props.services[cat];\r\n\t\t\t\t\t\t\t\t\tif (!services.length) {\r\n\t\t\t\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\treturn (\r\n\t\t\t\t\t\t\t\t\t\t<li key={cat} className=\"mod-map__listItem\">\r\n\t\t\t\t\t\t\t\t\t\t\t<a className=\"mod-map__link\" onClick={() => onNearbyCategoryClick(cat)}>\r\n\t\t\t\t\t\t\t\t\t\t\t\t<FillMapIcon\r\n\t\t\t\t\t\t\t\t\t\t\t\t\tcategory={cat.toLowerCase() as PoiCategory}\r\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"mod-map__listIcon\"\r\n\t\t\t\t\t\t\t\t\t\t\t\t/>\r\n\r\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"mod-map__listLabel\">\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t{services.length > 1\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? services.length +\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t' ' +\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprops.getResourceText(\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t`NearbyServiceCategory_${cat}_Plural`,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcat,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: services[0].name}\r\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\r\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"mod-map__listLabel\">\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t{services.length > 1\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t? formatDistanceRange(\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tarrayMin(services, (s) => s.distance),\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tarrayMax(services, (s) => s.distance),\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t: formatDistance(services[0].distance)}\r\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\r\n\t\t\t\t\t\t\t\t\t\t\t</a>\r\n\t\t\t\t\t\t\t\t\t\t</li>\r\n\t\t\t\t\t\t\t\t\t);\r\n\t\t\t\t\t\t\t\t})}\r\n\t\t\t\t\t\t</ul>\r\n\t\t\t\t\t\t<p className=\"mod-map__note\">\r\n\t\t\t\t\t\t\t<ResourceText\r\n\t\t\t\t\t\t\t\tresourceKey=\"NearByServices_Note\"\r\n\t\t\t\t\t\t\t\tdefaultText=\"Tiedot perustuvat Fonectan tarjoamaan dataan. Etäisyydet palveluihin on mitattu kartalla\r\n\t\t\t\t\t\tlinnuntietä.\"\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</p>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t{props.showPublicTransportBar && props.services && props.services['PublicTransport'] && (\r\n\t\t\t\t\t\t<div className=\"mod-map__section mod-map__publicTransportation\">\r\n\t\t\t\t\t\t\t<h3 className=\"mod-map__heading\">\r\n\t\t\t\t\t\t\t\t<ResourceText\r\n\t\t\t\t\t\t\t\t\tresourceKey=\"NearbyServices_PublicTransport\"\r\n\t\t\t\t\t\t\t\t\tdefaultText=\"Julkinen liikenne\"\r\n\t\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t\t</h3>\r\n\t\t\t\t\t\t\t<ul className=\"mod-map__list\">\r\n\t\t\t\t\t\t\t\t<SpacingContainer columnGap={2}>\r\n\t\t\t\t\t\t\t\t\t{props.services['PublicTransport'].map((p, idx) => (\r\n\t\t\t\t\t\t\t\t\t\t<li className=\"mod-map__listItem\" key={idx}>\r\n\t\t\t\t\t\t\t\t\t\t\t<a\r\n\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"mod-map__link\"\r\n\t\t\t\t\t\t\t\t\t\t\t\tonClick={() => onNearbyCategoryClick('PublicTransport')}\r\n\t\t\t\t\t\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t\t\t\t\t\t<IconMapPublicTransportFill className=\"mod-map__listIcon\" />\r\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"mod-map__listLabel\">{p.name}</span>\r\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"mod-map__listLabel\">{formatDistance(p.distance)}</span>\r\n\t\t\t\t\t\t\t\t\t\t\t</a>\r\n\t\t\t\t\t\t\t\t\t\t</li>\r\n\t\t\t\t\t\t\t\t\t))}\r\n\t\t\t\t\t\t\t\t</SpacingContainer>\r\n\t\t\t\t\t\t\t</ul>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t)}\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</>\r\n\t);\r\n});\r\n\r\nfunction FillMapIcon({ category, className }: { category: PoiCategory; className: string }) {\r\n\tswitch (category) {\r\n\t\tcase 'schools':\r\n\t\t\treturn <IconMapSchoolFill className={className} />;\r\n\t\tcase 'daycare':\r\n\t\t\treturn <IconMapDaycareFill className={className} />;\r\n\t\tcase 'grocery':\r\n\t\t\treturn <IconMapGroceriesFill className={className} />;\r\n\t\tcase 'restaurants':\r\n\t\t\treturn <IconMapRestaurantFill className={className} />;\r\n\t\tcase 'health':\r\n\t\t\treturn <IconMapHealthServicesFill className={className} />;\r\n\t\tcase 'culture':\r\n\t\t\treturn <IconMapCultureFill className={className} />;\r\n\t\tcase 'sports':\r\n\t\t\treturn <IconMapSportsFill className={className} />;\r\n\t\tcase 'publictransport':\r\n\t\t\treturn <IconMapPublicTransportFill className={className} />;\r\n\t\tdefault:\r\n\t\t\treturn <></>;\r\n\t}\r\n}\r\n\r\nfunction mapToPoiCategory(c: NearbyServiceCategory): PoiCategory {\r\n\tswitch (c) {\r\n\t\tcase 'Sports':\r\n\t\t\treturn 'sports';\r\n\t\tcase 'Culture':\r\n\t\t\treturn 'culture';\r\n\t\tcase 'Daycare':\r\n\t\t\treturn 'daycare';\r\n\t\tcase 'Grocery':\r\n\t\t\treturn 'grocery';\r\n\t\tcase 'Health':\r\n\t\t\treturn 'health';\r\n\t\tcase 'PublicTransport':\r\n\t\t\treturn 'publictransport';\r\n\t\tcase 'Restaurants':\r\n\t\t\treturn 'restaurants';\r\n\t\tcase 'Schools':\r\n\t\t\treturn 'schools';\r\n\t\tdefault:\r\n\t\t\tthrow Error('Unknown nearby service category: ' + c);\r\n\t}\r\n}\r\n","module.exports = (require(\"./helpers/browser/js-loader\")(require('./helpers/bundle-url').getBundleURL('j4Jl4') + require('./helpers/bundle-manifest').resolve(\"gjH5T\"))).then(() => parcelRequire('9mVQa'));","import React, { ReactNode } from 'react';\nimport { MediaCarousel, MediaItem, MediaCarouselProps } from './MediaCarousel';\nimport { FullScreenImageGallery } from './FullScreenImageGallery';\n\ninterface Props {\n\tmediaItems: MediaItem[];\n\tselectedItemIndex?: number;\n\tonSelectedItemChanged?: (idx: number, isFromFullscreen: boolean) => void;\n\textraControls?: ReactNode;\n\tthumbDisplayMode: MediaCarouselProps['thumbDisplayMode'];\n\tonOpenChanged?: (isVisible: boolean) => void;\n\ttelemetryContext: 'apartment' | 'businessEntity' | 'marketingBusinessEntity';\n}\n\nexport function ImageCarouselWithFullScreenSupport(props: Props) {\n\tconst [showOverlay, setShowOverlay] = React.useState<boolean>(false);\n\tconst [overlaySelectedItemIndex, setOverlaySelectedImageIndex] = React.useState<number>(0);\n\n\tconst onSelectionChanged = (idx: number, isFullscreen: boolean) => {\n\t\tif (isFullscreen) {\n\t\t\tsetOverlaySelectedImageIndex(idx);\n\t\t}\n\n\t\tif (props.onSelectedItemChanged) {\n\t\t\tprops.onSelectedItemChanged(idx, isFullscreen);\n\t\t}\n\t};\n\n\tconst onItemClick = (idx: number) => {\n\t\tif (showOverlay) {\n\t\t\treturn;\n\t\t}\n\t\tsetOverlaySelectedImageIndex(idx);\n\t\tsetShowOverlay(true);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<div className=\"mod-imageCarousel\" id=\"carousel\">\n\t\t\t\t<MediaCarousel\n\t\t\t\t\tmedia={props.mediaItems}\n\t\t\t\t\tonItemClick={onItemClick}\n\t\t\t\t\tselectedItem={props.selectedItemIndex}\n\t\t\t\t\tonSelectionChanged={(idx) => onSelectionChanged(idx, false)}\n\t\t\t\t\tthumbDisplayMode={props.thumbDisplayMode}\n\t\t\t\t\textraControls={props.extraControls}\n\t\t\t\t\tshowFullScreenToggle={false}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div className=\"mod-imageGallery\">\n\t\t\t\t<FullScreenImageGallery\n\t\t\t\t\tmedia={props.mediaItems}\n\t\t\t\t\tselectedItemIndex={overlaySelectedItemIndex}\n\t\t\t\t\tonSelectedItemIndexChanged={(idx) => onSelectionChanged(idx, true)}\n\t\t\t\t\tisOpen={showOverlay}\n\t\t\t\t\tonOpenChanged={(isVisible) => {\n\t\t\t\t\t\tsetShowOverlay(isVisible);\n\t\t\t\t\t\tif (props.onOpenChanged) {\n\t\t\t\t\t\t\tprops.onOpenChanged(isVisible);\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t\textraControls={props.extraControls}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</>\n\t);\n}\n","import React, { ReactNode, useEffect, useRef } from 'react';\nimport { OverlayGallery } from './OverlayGallery';\nimport { MediaCarousel, MediaItem } from './MediaCarousel';\nimport { useEventListener } from './useEventListener';\nimport { housingImagesPresetConfig } from './realEstateMediaPresets';\nimport { withDocument } from '../Common/window';\n\ninterface Props {\n\tselectedItemIndex: number;\n\tonSelectedItemIndexChanged: (idx: number) => void;\n\tmedia: MediaItem[];\n\tisOpen: boolean;\n\tonOpenChanged: (isOpen: boolean) => void;\n\textraControls?: ReactNode;\n}\n\n/**\n * Renders an image gallery which is shown fullscreen when open.\n * Even if browser doesn't allow fullscreen, CSS styling is used to make element fill whole window.\n *\n * @export\n * @param {Props} props\n * @returns\n */\nexport function FullScreenImageGallery(props: Props) {\n\tconst galleryRootRef = useRef<HTMLDivElement | null>(null);\n\n\t// Toggle fullscreen on isOpen change, if supported\n\tuseEffect(() => {\n\t\tif (!document.fullscreenEnabled || galleryRootRef.current == null) {\n\t\t\treturn;\n\t\t}\n\t\tif (props.isOpen && !document.fullscreenElement) {\n\t\t\tgalleryRootRef.current.requestFullscreen();\n\t\t} else {\n\t\t\tif (document.fullscreenElement && document.exitFullscreen) {\n\t\t\t\tdocument.exitFullscreen();\n\t\t\t}\n\t\t}\n\t}, [props.isOpen]);\n\n\t// Attach event listener for fullscreenchange event to detect user pressing Esc or browser's \"exit fullscreen\" button.\n\t// Esc keypress in fullscreen doesn't go to below event handler but is handled by browser\n\tuseEventListener<'fullscreenchange'>(galleryRootRef.current, 'fullscreenchange', () => {\n\t\t// User is leaving fullscreen\n\t\tif (document.fullscreenElement == null) {\n\t\t\tprops.onOpenChanged(false);\n\t\t}\n\t});\n\n\twithDocument((d) =>\n\t\tuseEventListener<'keydown'>(d.body, 'keydown', (ev) => {\n\t\t\tswitch (ev.code) {\n\t\t\t\tcase 'ArrowLeft':\n\t\t\t\t\tprops.onSelectedItemIndexChanged(\n\t\t\t\t\t\tprops.selectedItemIndex === 0 ? props.media.length - 1 : props.selectedItemIndex - 1,\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'ArrowRight': {\n\t\t\t\t\tconst isLast = props.selectedItemIndex === props.media.length - 1;\n\t\t\t\t\tprops.onSelectedItemIndexChanged(isLast ? 0 : props.selectedItemIndex + 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase 'Escape':\n\t\t\t\t\tif (props.isOpen) {\n\t\t\t\t\t\tprops.onOpenChanged(false);\n\t\t\t\t\t}\n\t\t\t}\n\t\t}),\n\t);\n\tif (props.media.length === 0) {\n\t\treturn null;\n\t}\n\n\tconst media = props.media.map((m) => ({ ...m, eagerLoad: true }));\n\n\treturn (\n\t\t<OverlayGallery\n\t\t\tref={galleryRootRef}\n\t\t\tisOpen={props.isOpen}\n\t\t\tonOpenChanged={(v) => {\n\t\t\t\tprops.onOpenChanged(v);\n\t\t\t}}\n\t\t>\n\t\t\t<MediaCarousel\n\t\t\t\tmedia={media}\n\t\t\t\t{...housingImagesPresetConfig}\n\t\t\t\tonSelectionChanged={(idx) => props.onSelectedItemIndexChanged(idx)}\n\t\t\t\tselectedItem={props.selectedItemIndex}\n\t\t\t\tthumbDisplayMode=\"new-fullscreen-singlerow\"\n\t\t\t\textraControls={props.extraControls}\n\t\t\t\tisFullScreen={props.isOpen}\n\t\t\t/>\n\t\t</OverlayGallery>\n\t);\n}\n","import * as React from 'react';\nimport { withWindow } from '../Common/window';\nimport { ResourceText } from './ResourceText';\n\ninterface Props {\n\tchildren: React.ReactElement;\n\ttopBar?: React.ReactElement;\n\tisOpen: boolean;\n\tonOpenChanged: (isOpen: boolean) => void;\n\trenderChildrenEvenIfClosed?: boolean; // Defaults to false\n}\n\nexport const OverlayGallery = React.forwardRef<HTMLDivElement, Props>((props: Props, ref) => {\n\tconst [scrollPosOriginalY, setScrollPosOriginalY] = React.useState<number | undefined>();\n\n\tReact.useEffect(() => {\n\t\tif (props.isOpen) {\n\t\t\twithWindow((w) => setScrollPosOriginalY(w.scrollY));\n\t\t\tdocument.body.classList.add('-galleryOpen', 'hide-chat');\n\t\t}\n\n\t\tif (!props.isOpen && scrollPosOriginalY) {\n\t\t\twithWindow((w) => setTimeout(() => w.scrollTo(0, scrollPosOriginalY), 10));\n\t\t}\n\t\tif (!props.isOpen) {\n\t\t\tdocument.body.classList.remove('-galleryOpen', 'hide-chat');\n\t\t}\n\t}, [props.isOpen]);\n\n\treturn (\n\t\t<div\n\t\t\tclassName={'view-overlayGallery l-custom-mediaGallery-fullScreenWrapper' + (props.isOpen ? ' -isOpen' : '')}\n\t\t\tref={ref}\n\t\t>\n\t\t\t<div className=\"view-overlayGallery__topBar\">\n\t\t\t\t{props.topBar}\n\t\t\t\t<button className=\"view-overlayGallery__closeButton\" onClick={() => props.onOpenChanged(false)}>\n\t\t\t\t\t<ResourceText resourceKey=\"OverlayGallery_Close\" defaultText=\"Sulje\" />\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t{(props.isOpen || props.renderChildrenEvenIfClosed) && props.children}\n\t\t</div>\n\t);\n});\n","import { useEffect, useRef } from 'react';\n\nexport function useEventListener<K extends keyof HTMLElementEventMap>(\n\telement: Element | null,\n\teventName: keyof HTMLElementEventMap,\n\thandler: (this: Element, ev: HTMLElementEventMap[K]) => any,\n) {\n\t// Create a ref that stores handler\n\tconst savedHandler = useRef<(ev: HTMLElementEventMap[K]) => any>();\n\t// Update ref.current value if handler changes.\n\t// This allows our effect below to always get latest handler ...\n\t// ... without us needing to pass it in effect deps array ...\n\t// ... and potentially cause effect to re-run every render.\n\tuseEffect(() => {\n\t\tsavedHandler.current = handler;\n\t}, [handler]);\n\tuseEffect(() => {\n\t\t// Make sure element supports addEventListener\n\t\tif (!element || !element.addEventListener) {\n\t\t\treturn;\n\t\t}\n\t\t// Create event listener that calls handler function stored in ref\n\t\tconst eventListener = (event: HTMLElementEventMap[K]) => savedHandler.current!(event);\n\t\t// Add event listener\n\t\telement.addEventListener(eventName, eventListener);\n\t\t// Remove event listener on cleanup\n\t\treturn () => {\n\t\t\telement.removeEventListener(eventName, eventListener);\n\t\t};\n\t}, [eventName, element]); // Re-run if eventName or element changes\n}\n"],"names":["$ed3kz","parcelRequire","$e32afa4a6978cbdf$export$2e2bcd8739ae039","withResourceTextSupport","props","isSocialShareOpen","setIsSocialShareOpen","useState","onGlobalClickEvent","useCallback","e","target","socialShareBar","document","getElementsByClassName","length","contains","preventDefault","useEffect","withDocument","d","addEventListener","removeEventListener","shareText","getResourceText","jsx","className","variant","jsxs","$e32afa4a6978cbdf$var$LeftActionButtonsWrapper","backButton","$iffFd","Link","to","text","children","banner","rightSideChildren","onClick","$jjuiK","ResourceText","resourceKey","defaultText","$1l21R","default","context","SocialShareContext","ApartmentPage","LeftActionButtonsWrapper","MapComponentWrapper","LoadableShim","importedWrapper","NearbyServices","visibleCategories","setVisibleCategories","React","mapControls","setMapControls","undefined","onNearbyCategoryClick","serviceCategory","c","mapToPoiCategory","Error","isVisible","some","cat","setCategoryVisibility","visible","isCategoryVisible","concat","filter","reCenter","exludedCategories","Fragment","textType","id","$f69f110d27217cce$var$MapComponentWrapper","defaultCenter","center","businessEntityId","onMapActivated","Object","keys","services","includes","map","$f69f110d27217cce$var$FillMapIcon","category","toLowerCase","name","formatDistanceRange","arrayMin","s","distance","arrayMax","formatDistance","showPublicTransportBar","$icxVu","SpacingContainer","columnGap","p","idx","IconMapPublicTransportFill","$3U7tL","FillMapIcon","IconMapSchoolFill","IconMapDaycareFill","IconMapGroceriesFill","IconMapRestaurantFill","IconMapHealthServicesFill","IconMapCultureFill","IconMapSportsFill","module","exports","getBundleURL","resolve","then","ImageCarouselWithFullScreenSupport","showOverlay","setShowOverlay","overlaySelectedItemIndex","setOverlaySelectedImageIndex","onSelectionChanged","isFullscreen","onSelectedItemChanged","$55xvn","MediaCarousel","media","mediaItems","onItemClick","selectedItem","selectedItemIndex","thumbDisplayMode","extraControls","showFullScreenToggle","$14Ar4","FullScreenImageGallery","onSelectedItemIndexChanged","isOpen","onOpenChanged","galleryRootRef","useRef","fullscreenEnabled","current","fullscreenElement","requestFullscreen","exitFullscreen","useEventListener","body","ev","code","isLast","m","eagerLoad","$7dII4","OverlayGallery","ref","v","housingImagesPresetConfig","isFullScreen","scrollPosOriginalY","setScrollPosOriginalY","withWindow","w","scrollY","classList","add","setTimeout","scrollTo","remove","topBar","renderChildrenEvenIfClosed","$iU6fI","element","eventName","handler","savedHandler","eventListener","event"],"version":3,"file":"ApartmentPageNew.4794d849.js.map"}