PageSourceSearch

https://www.ylakarjala.fi/asenna/

html ylakarjala.fi collected 2026-10-02 13:59:44 UTC 108,354 bytes, 2,060 lines download raw bytes

1
2<!doctype html>
3<html class="diks-no-js diks-site--ylakarjala diks-user--is-not-logged-in diks-user--is-not-subscriber diks-user--is-not-company-subscriber diks-site--layout-master diks-site--ads-disabled-from-page-level" lang="fi" prefix="og: http://ogp.me/ns#">
4	<head>
5		<meta charset="utf-8">
6		<meta name="viewport" content="width=device-width, initial-scale=1">
7		<title>Sovellus | Ylä-Karjala</title>
8		<link id="diks-stylesheet" rel="stylesheet" href="https://a.ylakarjala.fi/styles/2efe7af9/styles/diks-news.css">
9		<link rel="dns-prefetch" href="https://cdn.gravito.net">
10			<link rel="dns-prefetch" href="https://cdn.gravito.network">
11			<link rel="dns-prefetch" href="https://handshake.gravito.network">
12		
12<script>
13
14		const checkUserPreferenceEnabled = 1;
15		const darkmodeStylesheet = "https://a.ylakarjala.fi/styles/2efe7af9/styles/diks-news-darkmode.css";
16		const defaultStylesheet = "https://a.ylakarjala.fi/styles/2efe7af9/styles/diks-news.css";
17		const savedTheme = localStorage.getItem('theme');
18		const stylesheet = document.getElementById("diks-stylesheet");
19
20		// Check local storage for saved theme
21		if ( savedTheme == 'darkmode' ) {
22			stylesheet.href = darkmodeStylesheet;
23			document.documentElement.classList.add('diks-theme--darkmode');
24		}
25		// Check user's theme preference through an OS setting or a user agent setting
26		else if ( checkUserPreferenceEnabled && savedTheme != 'default' && ( window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ) ) {
27			stylesheet.href = darkmodeStylesheet;
28			document.documentElement.classList.add('diks-theme--darkmode');
29		}
30		else {
31			document.documentElement.classList.add('diks-theme--default');
32		}
33
34
35		// Darkmode toggle switch
36		document.addEventListener('DOMContentLoaded', function () {
37			const darkmodeButton = document.getElementById("diks-darkmode-toggler");
38
39			if (darkmodeButton) {
40				// Set darkmode button to checked if darkmode is already on
41				// Check local storage for saved theme
42				if (savedTheme == 'darkmode' ) {
43					darkmodeButton.checked = true;
44				}
45				// Check user's theme preference through an OS setting or a user agent setting
46				else if ( checkUserPreferenceEnabled && savedTheme != 'default' && ( window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ) ) {
47					darkmodeButton.checked = true;
48				}
49
50				// Change theme based on darkmode button checked/unchecked
51				darkmodeButton.addEventListener("click", function() {
52					// Swap out the URL for the different stylesheets
53					if ( stylesheet.getAttribute("href") == defaultStylesheet ) {
54						stylesheet.href = darkmodeStylesheet;
55						document.documentElement.classList.remove('diks-theme--default');
56						document.documentElement.classList.add('diks-theme--darkmode');
57						// Save theme to local storage
58						window.localStorage.setItem('theme', 'darkmode');
59					} else {
60						stylesheet.href = defaultStylesheet;
61						document.documentElement.classList.remove('diks-theme--darkmode');
62						document.documentElement.classList.add('diks-theme--default');
63						// Save theme to local storage
64						window.localStorage.setItem('theme', 'default');
65					}
66					// Dispatch event ThemeChanged when theme inside Local Storage changes
67					window.dispatchEvent(new Event("ThemeChanged"));
68				});
69			}
70		}, false);
71
72	</script>
72
73		
74		<link rel="preload" href="/gravito-cmp.js" as="script">
75			<link rel="preload" href="https://cdn.gravito.net/sdk/v6/latest/sdk.js" as="script"><link rel="preload" href="https://r209.ylakarjala.fi/script.js" as="script">
76			
76<script>
77		window.JankkoSSOConfig = {
78			accountOrigin: "YLKA"
79		};
80	</script>
80
81
82				
83	
83<script id="jankko-sso-script" src="https://sso.ylakarjala.fi/assets/jankko-sso-client.modern.min.js"></script>
83
84
85
86		
87		
88
89		
89<script>
90		// Hyphenopoly library initialization. The library will add soft-hyphen characters into the content if the
91		// browser doesn't support CSS hyphenation. For debugging on macOS Chrome: require: { 'fi': 'FORCEHYPHENOPOLY' }
92		const Hyphenopoly = {
93			require: { 'fi': 'yhdyssanahirviö' },
94			setup: {
95				defaultLanguage: "fi",
96				selectors: { '.diks-card__title': { minWordLength: 11, leftmin: 4, rightmin: 4 }, '.diks-article__headline': { minWordLength: 11, leftmin: 4, rightmin: 4 }, '.diks-parallax-content .diks-article-box .diks-sub-headline': { minWordLength: 11, leftmin: 4, rightmin: 4 } }
97			}
98		}
99		console.log('Hyphenopoly settings:', Hyphenopoly.setup)
100
101		// Helper function for hyphenating content that was added after pageload. We must query a nodelist and iterate
102		// each node because the library can't handle a nodelist.
103		// https://mnater.github.io/Hyphenopoly/Hyphenators.html
104		// https://github.com/mnater/Hyphenopoly/issues/92#issuecomment-597728300
105		const diksHyphenateContent = (containerSelector) => {
106			if (!Hyphenopoly.hyphenators) {
107				return
108			}
109			Hyphenopoly.hyphenators["HTML"].then((hyphenator) => {
110				for (const itemSelector in Hyphenopoly.setup.selectors) {
111					const containerNode = document.querySelector(containerSelector)
112					const itemNodeList = containerNode.querySelectorAll(itemSelector)
113					itemNodeList.forEach((itemNode) => { hyphenator(itemNode, itemSelector) })
114				}
115			})
116		}
117	</script>
117
118	
118<script src="https://a.ylakarjala.fi/styles/2efe7af9/includes/hyphenopoly/Hyphenopoly_Loader.js"></script>
118
119		
119<script src="/theme/css/includes/waypoints/lib/noframework.waypoints.min.js"></script>
119
120		<link rel="icon" type="image/png" href="/favicon.png" sizes="96x96" /><link rel="icon" href="/favicon.ico" sizes="48x48"><link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml" /><link rel="apple-touch-icon" href="/icon-180.png"/><meta name="theme-color" content="#FFFFFF" media="(prefers-color-scheme: light)" />
121		<meta name="theme-color" content="#121416" media="(prefers-color-scheme: dark)" /><link rel="alternate" type="application/rss+xml" title="Ylä-Karjala" href="https://www.ylakarjala.fi/feed/rss"><meta name="robots" content="max-image-preview:large">
121<script>
122	var pageData = {};
123	
124	pageData.section = {
125			'name': 'Sovellus',
126			'uname': 'asenna',
127			'url': 'https\u003A\/\/www.ylakarjala.fi\/asenna\/'
128		}
129	pageData.publication = {
130		'name': 'ylakarjala',
131		'url': 'https\u003A\/\/www.ylakarjala.fi\/',
132		'engage': 'YLKA',
133		'paywallEnabled': true,
134		'registrationWallEnabled': true,
135		'env':'prod'
136	}
137	pageData.user = {}
138	pageData.companyUser = {}
139
140	function isPwa() {
141		// window.navigator.standalone = iOS
142		// window.matchMedia('(display-mode: standalone)').matches = Android/universal
143		return (window.navigator.standalone) ||
144		       (["fullscreen", "standalone", "minimal-ui"].some(
145		        function(displayMode) { return window.matchMedia('(display-mode: ' + displayMode + ')')
146		        .matches }));
147	}
148
149	pageData.general = {
150		'browseMode': (isPwa() ? 'pwa' : 'browser')
151	}
152</script>
152
153	<meta property="og:site_name" content="Ylä-Karjala">
154	<meta property="og:locale" content="fi_FI"><meta name='description' content='Sovellus sisältää tuoreet juttumme, joita ilmestyy ympäri vuorokauden vuoden jokaisena päivänä sekä näköislehtemme liitteineen sekä näköislehtien arkiston.'>
155<meta property='og:title' content='Sovellus | Ylä-Karjala'>
156<meta property='og:description' content='Sovellus sisältää tuoreet juttumme, joita ilmestyy ympäri vuorokauden vuoden jokaisena päivänä sekä näköislehtemme liitteineen sekä näköislehtien arkiston.'>
157<meta property='og:url' content='https://www.ylakarjala.fi/asenna/'>
158<meta property='og:type' content='webpage'><meta property='og:image' content='https://a.ylakarjala.fi/styles/2efe7af9/images/default/og-image-ylakarjala.jpg'>
159<meta property='og:image:width' content='1200'>
160<meta property='og:image:height' content='630'>
161		<link rel="manifest" href="/manifest.webmanifest">
162		<style>@media (max-width: 600px) { .gravitoCMP-footer { margin-top: 1.5em; } }</style>
163		
163<script type="text/javascript">window.cX = window.cX || {};// Async load of cx.js
164		(function(d,s,e,t){e=d.createElement(s);e.type='text/java'+s;e.async='async';
165		e.src='http'+('https:'===location.protocol?'s://s':'://')+'cdn.cxense.com/cx.js';
166		t=d.getElementsByTagName(s)[0];t.parentNode.insertBefore(e,t);})(document,'script');
167	</script>
167
168									
168<script src="https://a.ylakarjala.fi/styles/2efe7af9/js/blueconic/dialog.min.js"></script>
168
169		
169<script>
170			BCinst = 'blueconic';
171			BCshortcode = 'YLKA';
172			BCHighImpactAdHidingEnabled = true;
173			BCHighImpactAdSizes = [[1600,1150],[970,970],[970,540],[970,170],[320,320],[300,240],[300,220],[300,210],[1,2]];
174			BCHighImpactPrerequisiteSlots = ["gam-ad-topscroll_skin","gam-ad-topscroll_mob"];
175			BCHighImpactPrerequisiteTimeout = 5000;
176			BCGAMAdsEnabled = false;
177						initHighImpactAdHiding();
178		</script>
178<script src="https://a.ylakarjala.fi/styles/2efe7af9/js/blueconic/events.min.js"></script>
178
179		
179<script>
180			const BCPlatform = "web";
181			const BCChannel = 'YLKA';
182
183			const BCArticleViewProperties = {};
184			const BCSessionStartProperties = {};
185
186			BCArticleViewProperties["platform"] = BCPlatform;
187			BCArticleViewProperties["channel"] = BCChannel;
188			BCSessionStartProperties["platform"] = BCPlatform;
189			BCSessionStartProperties["channel"] = BCChannel;
190
191			const BCArticleID = pageData?.article?.id || '';
192			const BCArticleMarketingCategories = pageData?.article?.marketingCategories || [];
193			const BCArticleTopics = pageData?.article?.topics || [];
194
195			if (BCArticleID) {
196				BCArticleViewProperties["articleID"] = BCArticleID;
197			}
198
199			if (Array.isArray(BCArticleMarketingCategories) && BCArticleMarketingCategories.length > 0) {
200				BCArticleViewProperties["marketing_categories"] = BCArticleMarketingCategories.join(', ');
201			}
202
203			if (Array.isArray(BCArticleTopics) && BCArticleTopics.length > 0) {
204				BCArticleViewProperties["tags"] = BCArticleTopics.join(', ');
205			}
206
207			const BCEventParams = {
208				currentPage: '/asenna/' || null,
209				pageType: 'section' || null,
210				dependenciesTimeout: 5000,
211				inHouseAdEnabled: true,
212				articleViewEventEnabled: true,
213				articleViewProperties: BCArticleViewProperties,
214				sessionStartEventEnabled: true,
215				sessionStartProperties: BCSessionStartProperties,
216				recommendationsEnabled: false,
217				recommendationsMaxItems: 3,
218				recommendationsTitle: 'Luitko\u0020jo\u0020n\u00E4m\u00E4\u003F'
219			};
220			InitializeEventScript(BCEventParams);
221		</script>
221<script>
222			window.BCDatalayer = [];
223		</script>
223<script>
224		(function () {
225			window.BCscriptInjected = false;
226			var scriptSrc = '';
227
228							scriptSrc = 'https://r209.ylakarjala.fi/script.js';
229			
230			window.addEventListener(
231				"gravito:tcfv2:client",
232				function (event) {
233					let eventType = event.detail.eventType;
234					let consentUpdateEventsList = [
235						"layer1:opt-out:all",
236						"layer2:opt-out:all",
237						"layer2:opt-in:selected",
238						"layer1:opt-in:all",
239						"layer2:opt-in:all",
240						"opt-in:previously",
241					];
242					if (consentUpdateEventsList.includes(eventType) && window.BCscriptInjected === false) {
243						window.BCscriptInjected = true;
244
245						var script = document.createElement("script");
246						script.src = scriptSrc;
247						document.head.appendChild(script);
248					}
249				},
250				true
251			);
252		}());
253	</script>
253
254				
255		
255<script type='text/javascript'>
256		(function() {
257			/** CONFIGURATION START **/
258			var _sf_async_config = window._sf_async_config = (window._sf_async_config || {});
259			_sf_async_config.uid = 60754;
260			_sf_async_config.domain = location.host.replace("www.","");
261			_sf_async_config.flickerControl = false;
262			_sf_async_config.useCanonical = true;
263			_sf_async_config.useCanonicalDomain = true;
264			/** CONFIGURATION END **/
265		})();
266	</script>
266<script>
267		function configureChartbeat(userType) {
268			/** CONFIGURATION START **/
269			var _sf_async_config = window._sf_async_config = (window._sf_async_config || {});
270			_sf_async_config.sections = pageData && pageData.section ? pageData.section.name : '';
271			_sf_async_config.authors = pageData && pageData.article && Array.isArray(pageData.article.authors) ? pageData.article.authors.toString() : '';
272
273			if (userType) {
274				var _cbq = window._cbq = (window._cbq || []);
275				_cbq.push(['_acct', userType]);
276			}
277			/** CONFIGURATION END **/
278			function loadChartbeat() {
279				var e = document.createElement('script');
280				var n = document.getElementsByTagName('script')[0];
281				e.type = 'text/javascript';
282				e.async = true;
283				e.src = 'https://static.chartbeat.com/js/chartbeat.js';
284				n.parentNode.insertBefore(e, n);
285			}
286			loadChartbeat();
287		};
288
289		if (typeof JankkoSSOClient !== 'undefined') {
290			JankkoSSOClient.getSession().then(function(data) {
291				if (data && data.user && data.user.id) {
292					var userType = Array.isArray(data.permissions) && data.permissions.includes("paywall") ? 'paid' : 'lgdin';
293
294					configureChartbeat(userType);
295				} else {
296					configureChartbeat('anon');
297				}
298			}).catch(function(error) {
299				configureChartbeat('anon');
300			});
301		} else {
302			configureChartbeat('anon');
303		}
304	</script>
304
305		
305<script>
306		const gtmContainerId = 'GTM-KTJNB7R';
307		const sendDatalayerPush = Boolean(1);
308		const context = 'sec';
309
310		(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
311		new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
312		j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
313		'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
314		})(window,document,'script','dataLayer',gtmContainerId);
315
316		if (sendDatalayerPush) {
317			window.dataLayer.push({'event':'pageDataPush','pageData': window.pageData});
318		}
319
320		(async function () {
321			const paywallEnabled = window?.pageData?.publication?.paywallEnabled ?? true;
322			const registrationWallEnabled = window?.pageData?.publication?.registrationWallEnabled ?? true;
323
324			const user = {};
325			const companyUser = {};
326
327			let articleState;
328			let articlePaywall = 'free'; // free is always the safer fallback
329
330			if (context === 'art') {
331				if (window?.pageData?.article?.effectivePaywall) {
332					articlePaywall = window.pageData.article.effectivePaywall;
333				} else if (window?.pageData?.article?.paywall){
334					articlePaywall = window.pageData.article.paywall;
335				}
336
337				if ((articlePaywall === 'free' || !paywallEnabled) || (articlePaywall === "registered" && !registrationWallEnabled)) {
338					articleState = "full";
339				}
340				else {
341					articleState = 'preview';
342				}
343			}
344
345			function getCookie(name) {
346				name = name + '=';
347				const decodedCookie = decodeURIComponent(document.cookie);
348				const cookies = decodedCookie.split(';');
349				for (let i = 0; i < cookies.length; i++) {
350					const cookie = cookies[i].trim();
351					if (cookie.indexOf(name) === 0) {
352						return cookie.substring(name.length, cookie.length);
353					}
354				}
355			}
356
357			function pushDataLayerEvent() {
358				let segmentsCookie = getCookie('jankkosegments');
359
360				if (segmentsCookie) {
361					let segmentsData = JSON.parse(segmentsCookie);
362					let segments = segmentsData.segments;
363
364					if (segments && typeof segments === 'object') {
365						user.segments = segments;
366					}
367				}
368				const pageData = {
369					'user': user,
370					'companyUser': companyUser
371				};
372				if (context === 'art') {
373					pageData.article = { 'state': articleState };
374				}
375				if (sendDatalayerPush) {
376					window.dataLayer.push({'event': 'userDataPush', 'pageData': pageData });
377				}
378			}
379
380			async function modifyDatalayerData() {
381				const sessionData = await JankkoSSOClient.getSession();
382				if (!sessionData) {
383					return;
384				}
385
386				user.id = sessionData?.personal?.personal_user_id;
387				user.products = sessionData?.personal?.personal_active_products;
388				user.permissions = sessionData?.personal?.personal_permissions;
389
390				companyUser.id = sessionData?.company?.company_user_id ?? null;
391				companyUser.products = sessionData?.company?.company_active_products ?? null;
392				companyUser.permissions = sessionData?.company?.company_permissions ?? null;
393
394				const permissions = sessionData?.permissions ?? [];
395				if (context === 'art') {
396					var userIsLoggedIn = false;if ((articlePaywall != "free" && permissions.includes("paywall") && articlePaywall != "registered") || (userIsLoggedIn === true && articlePaywall === "registered")) {
397						articleState = "full";
398					}
399				}
400			}
401
402			try {
403				await modifyDatalayerData();
404			}
405			catch (error) {
406				console.warn(error);
407			}
408
409			pushDataLayerEvent();
410		}());
411
412	</script>
412
413		
414	</head>
415		<body class="diks-body diks-body--page-type-apps">
416		<!-- Google Tag Manager (noscript) -->
vendor: 72 bytes, lines 416-417
416
417    <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
417GTM-KTJNB7R
vendor: 95 bytes, lines 417-419
417"
418        height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
419    
419<!-- End Google Tag Manager (noscript) -->
420		
420<script src='/gravito-cmp.js'></script>
420
421
422					
423		
424		
425										<header id="main-header" class="diks-header diks-header diks-header--is-fixed">
426	<div class="diks-skip-link-navigation diks-skip-link-navigation--top">
427		<ul class="diks-navigation diks-navigation--skip-links">
428							<li class="diks-navigation__item">
429					<a class="diks-button diks-button--primary diks-a11y__screen-reader diks-a11y__screen-reader--focusable" href="#sisalto" >Siirry suoraan sisältöön</a>
430				</li>
431					</ul>
432	</div>
433
434	<div class="diks-header-wrapper">
435		<div class="diks-container diks-container--header">
436			<div class="diks-header-container"><div class="diks-header__navigation-container diks-header__navigation-container--left">
437						<button class="diks-button diks-button--icon-only diks-button--ghost diks-navigation__link js-diks-toggler diks-dropdown-toggler diks-dropdown-toggler--main" id="diks-dropdown-toggle" data-toggle="diks-dropdown-navigation" aria-expanded="false" aria-controls="diks-dropdown-navigation" aria-label="Valikko"><span class="diks-icon diks-icon--size-m" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
438  <path fill-rule="evenodd" d="M22 6H2V4H22V6ZM22 13H2V11H22V13ZM22 20H2V18H22V20Z" clip-rule="evenodd"/>
439</svg>
440</span><span class="diks-icon diks-icon--size-m diks-icon--hidden" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
441  <path fill-rule="evenodd" d="M10.5858 12L4.2218 5.63603L5.63602 4.22182L12 10.5858L18.3639 4.22183L19.7782 5.63605L13.4142 12L19.7782 18.364L18.3639 19.7782L12 13.4142L5.63602 19.7782L4.2218 18.364L10.5858 12Z" clip-rule="evenodd"/>
442</svg>
443</span></button>
444
445		<div class="diks-dropdown-navigation" id="diks-dropdown-navigation">
446		<button id="diks-close-dropdown-main-nav" class="diks-button diks-button--outline diks-dropdown-navigation__close-button diks-a11y__screen-reader diks-a11y__screen-reader--focusable">Sulje valikko</button><div class="diks-dropdown-navigation__sign-container">
447				<img src="https://a.ylakarjala.fi/styles/2efe7af9/images/logos/keskisuomalainen-sign.svg" class="diks-logo diks-dropdown-navigation__sign" alt="Keskisuomalainen Oyj">
448			</div><form id="dropdown-navigation-search" name="dropdownnavigationsearch" class="diks-form diks-form--fluid" action="/haku/" method="get">
449					<div class="diks-form__field-wrapper diks-form__field-wrapper--padding-right diks-form__field-wrapper--required"><input class="diks-form__field" type="search" name="q" id="dropdown-navigation-searchSearch1"   aria-label="Haku" placeholder="Hae sivustolta" required  value=""></div>
450
451						<div class="diks-form__field-wrapper diks-form__field-wrapper--submit-button-icon-only">
452		<button class="diks-form__submit" type="submit" id="dropdown-navigation-searchSubmitbutton2"><span class="diks-icon diks-icon--color-primary" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
453  <path fill-rule="evenodd" d="M9.5 4C6.46243 4 4 6.46243 4 9.5C4 12.5376 6.46243 15 9.5 15C12.5376 15 15 12.5376 15 9.5C15 6.46243 12.5376 4 9.5 4ZM2 9.5C2 5.35786 5.35786 2 9.5 2C13.6421 2 17 5.35786 17 9.5C17 11.2106 16.4273 12.7874 15.4632 14.0493L19.7782 18.3642L18.3639 19.7784L14.049 15.4634C12.7872 16.4274 11.2105 17 9.5 17C5.35786 17 2 13.6421 2 9.5Z" clip-rule="evenodd"/>
454</svg>
455</span>Hae
456		</button>
457	</div>
458			</form>	<nav class="diks-navigation-wrapper diks-navigation-wrapper--border-bottom diks-navigation-wrapper--border-top" ><ul class="diks-navigation diks-navigation--row diks-navigation--mobile-row diks-navigation--no-active-links diks-navigation--size-s"  id="dropdown-highlights-nav"><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/asenna/">Sovellus</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/nakoislehti/">Lehdet</a></li><li class="diks-navigation__item diks-navigation__item--button diks-navigation__item--align-right diks-hide-from-subscribers" ><a class="diks-navigation__link diks-bc-order-button" href="/jatka/">Tilaa</a></li></ul>
459		</nav>	<nav class="diks-navigation-wrapper diks-navigation-wrapper--divider-bottom" ><ul class="diks-navigation diks-navigation--no-active-links diks-navigation--size-s"  id="dropdown-customer-upper-nav"><li class="diks-navigation__item " ><a class="diks-navigation__link " href="https://oma.media.fi/yla-karjala/"><span class="diks-icon diks-icon--size-m" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
460  <path d="M17 8H22V17H19.1875V20.8125L14.1045 17H9V13.4307L4.4375 17.0811V13H2V3H17V8ZM17 13H11V15H14.7705L17.1875 16.8125V15H20V10H17V13ZM4 11H6.4375V12.918L8.5625 11.2188L8.83691 11H15V5H4V11Z"/>
461</svg>
462</span>Asiakaspalvelu</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="https://oma.media.fi/yla-karjala/yhteystiedot/juttuvinkki/"><span class="diks-icon diks-icon--size-m" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
463  <path fill-rule="evenodd" d="M7.38197 4H16.618L17.618 6H22V20H2V6H6.38197L7.38197 4ZM8.61803 6L7.61803 8H4V18H20V8H16.382L15.382 6H8.61803ZM12 11C10.8954 11 10 11.8954 10 13C10 14.1046 10.8954 15 12 15C13.1046 15 14 14.1046 14 13C14 11.8954 13.1046 11 12 11ZM8 13C8 10.7909 9.79086 9 12 9C14.2091 9 16 10.7909 16 13C16 15.2091 14.2091 17 12 17C9.79086 17 8 15.2091 8 13Z" clip-rule="evenodd"/>
464</svg>
465</span>Lähetä juttuvinkki</a></li></ul>
466		</nav>	<nav class="diks-navigation-wrapper " ><ul class="diks-navigation diks-navigation--light"  id="dropdown-section-nav"><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/">Etusivu</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/uusimmat/">Uusimmat</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/luetuimmat/">Luetuimmat</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/paikalliset">Uutiset</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/paakirjoitus-mielipide/">Mielipiteet</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/aihe/blogit">Blogit</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/aihe/menneilta-vuosilta">Menneiltä vuosilta</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="https://pohjois-karjala.menoinfo.fi/fi-FI?sort=startDate&amp;area=area-143">Menoinfo</a></li></ul>
467		</nav><!-- ESI start element "recommendedTopics" generated at 02-10-2026 16:55:56.622804 -->	<nav class="diks-navigation-wrapper diks-navigation-wrapper--divider-top" ><ul class="diks-navigation diks-navigation--light diks-navigation--size-s" ><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/aihe/yla-karjalan-visat">Ylä-Karjalan visat</a></li></ul>
468		</nav><!-- ESI end element "recommendedTopics" --><!-- ESI start element "promotedAdvertisers" generated at 02-10-2026 16:55:26.115561 --><!-- ESI end element "promotedAdvertisers" -->	<nav class="diks-navigation-wrapper diks-navigation-wrapper--divider-top" ><h2 class="diks-navigation__title">Yhteystiedot</h2><ul class="diks-navigation diks-navigation--light diks-navigation--size-s"  id="dropdown-customer-nav"><li class="diks-navigation__item " ><a class="diks-navigation__link " href="https://www.meks.fi/mainonta/alueet/savon-media/">Mediamyynti</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="https://oma.media.fi/yla-karjala/yhteystiedot/">Kaikki yhteystiedot</a></li></ul>
469		</nav><div class="diks-navigation-wrapper diks-navigation-wrapper--divider-top"><h2 class="diks-navigation__title">Ulkoasu</h2><label for="diks-darkmode-toggler" class="diks-form__switch">
470					<span class="diks-form__switch-label"><span class="diks-icon diks-icon--size-m" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
471  <path fill-rule="evenodd" d="M13.7547 1.76065L11.7581 3.75666C10.6708 4.8436 10 6.34252 10 8C10 11.3137 12.6863 14 16 14C17.6575 14 19.1564 13.3292 20.2433 12.2419L22.2394 10.2453L21.9451 13.0531C21.4182 18.0815 17.1674 22 12 22C6.47715 22 2 17.5229 2 12C2 6.83263 5.91855 2.58178 10.9469 2.05488L13.7
471547 1.76065ZM8.70749 4.70657C5.93176 5.9617 4 8.75566 4 12C4 16.4183 7.58172 20 12 20C15.2443 20 18.0383 18.0682 19.2934 15.2925C18.289 15.7468 17.1738 16 16 16C11.5817 16 8 12.4183 8 8C8 6.82623 8.25316 5.71105 8.70749 4.70657Z" clip-rule="evenodd"/>
472</svg>
473</span>Käytä tummaa tilaa</span>
474					<div class="diks-form__switch-wrapper">
475						<input id="diks-darkmode-toggler" class="diks-form__switch-input" type="checkbox">
476						<span class="diks-form__switch-slider"></span>
477					</div>
478				</label>
479			</div></div>	<nav class="diks-navigation-wrapper " ><ul class="diks-navigation diks-navigation--main diks-navigation--size-s diks-navigation--row diks-navigation--mobile-row diks-navigation--no-active-links diks-hide-below-large" ><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/uusimmat/"><span class="diks-icon diks-hide-above-large" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
480  <path fill-rule="evenodd" d="M12 4a8 8 0 100 16 8 8 0 000-16zM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12zm9-6h2v5.586l2.707 2.707-1.414 1.414L11 12.414V6z" clip-rule="evenodd"/>
481</svg>
482</span>Uusimmat</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/luetuimmat/"><span class="diks-icon diks-hide-above-large" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
483  <path fill-rule="evenodd" d="M11.03 3.455c1.168-1.438 3.495-.652 3.55 1.2l.117 3.845h6a1.25 1.25 0 0 1 1.229 1.484l-1.905 10A1.25 1.25 0 0 1 18.793 21H9.06a1.25 1.25 0 0 1-.559-.132L6.764 20H3.25C2.56 20 2 19.44 2 18.75v-8.5C2 9.56 2.56 9 3.25 9h3.274l4.506-5.545ZM8 10.355v8.027L9.236 19h8.936l1.62-8.5h-5.58a1.5 1.5 0 0 1-1.499-1.455l-.131-4.33L8 10.356Zm10.056 9.255ZM4 11v7h2v-7H4Zm14.793 8.75.145.027Z" clip-rule="evenodd"/>
484</svg>
485</span>Luetuimmat</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/nakoislehti/"><span class="diks-icon diks-hide-above-large" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
486  <path fill-rule="evenodd" d="M4 2H20V22H4V2ZM6 4V20H18V4H6ZM8 6H16V12H8V6ZM10 8V10H14V8H10ZM16 15H8V13H16V15ZM16 18H8V16H16V18Z" clip-rule="evenodd"/>
487</svg>
488</span>Lehdet</a></li><li class="diks-navigation__item diks-navigation__item--button diks-navigation__item--align-right diks-hide-above-medium diks-hide-from-subscribers" ><a class="diks-navigation__link diks-bc-order-button" href="/jatka/">Tilaa</a></li></ul>
489		</nav></div><div class="diks-header__logo-container"><a class="diks-logo__link diks-header__logo-link diks-header__main-logo-link" href="/"><img src="https://a.ylakarjala.fi/styles/2efe7af9/images/logos/ylakarjala.svg" class="diks-logo diks-logo--default diks-header__logo diks-header__main-logo" alt="Ylä-Karjala"><img src="https://a.ylakarjala.fi/styles/2efe7af9/images/logos/ylakarjala-white.svg" class="diks-logo diks-logo--darkmode diks-header__logo diks-header__main-logo" alt="Ylä-Karjala"></a>
490					</div><div class="diks-header__navigation-container diks-header__navigation-container--right"><a class="diks-bc-order-button diks-button diks-button--primary diks-button--size-m diks-hide-from-subscribers diks-hide-below-medium " href="/jatka/">Tilaa</a><div class="diks-user-navigation-wrapper">
491	<button class="diks-button diks-button--icon-only diks-button--ghost diks-navigation__link diks-dropdown-toggler diks-dropdown-toggler--user" aria-expanded="false" id="diks-sso-user" data-diks-toggle="diks-user-navigation" data-diks-toggle-class="diks-user-navigation" aria-controls="diks-user-navigation"><span class="diks-icon diks-icon--size-m" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
492  <path fill-rule="evenodd" d="M4 12a8 8 0 1 1 13.496 5.814c-1.216-1.593-3.262-2.602-5.491-2.602-2.231 0-4.28 1.011-5.495 2.607A7.978 7.978 0 0 1 4 12Zm4.04 6.953A7.963 7.963 0 0 0 12 20a7.964 7.964 0 0 0 3.966-1.05c-.83-1.087-2.254-1.84-3.961-1.84-1.71 0-3.135.754-3.965 1.843ZM12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2Zm.005 5.898c-1.247 0-2.305 1.049-2.305 2.4 0 1.353 1.058 2.402 2.305 2.402s2.305-1.05 2.305-2.401c0-1.352-1.058-2.4-2.305-2.4Zm-4.203 2.4C7.802 7.952 9.658 6 12.005 6c2.347 0 4.203 1.95 4.203 4.299 0 2.348-1.856 4.299-4.203 4.299-2.347 0-4.203-1.951-4.203-4.3Z" clip-rule="evenodd"/>
493</svg>
494</span><span class="diks-icon diks-icon--size-m diks-icon--hidden" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
495  <path fill-rule="evenodd" d="M10.5858 12L4.2218 5.63603L5.63602 4.22182L12 10.5858L18.3639 4.22183L19.7782 5.63605L13.4142 12L19.7782 18.364L18.3639 19.7782L12 13.4142L5.63602 19.7782L4.2218 
49518.364L10.5858 12Z" clip-rule="evenodd"/>
496</svg>
497</span></button>
498
499	<div class="diks-navigation diks-sub-navigation diks-user-navigation" id="diks-user-navigation">
500		<button id="diks-close-dropdown-user-nav" class="diks-button diks-button--outline diks-dropdown-navigation__close-button diks-a11y__screen-reader diks-a11y__screen-reader--focusable">Sulje valikko</button>
501	<p id="diks-sso-username" class="diks-user-navigation__username diks-hide-from-company-subscribers"></p><p class="diks-user-navigation__username diks-show-for-company-subscribers">Yritystilaus tunnistettu</p><div class="diks-show-for-company-subscribers"><p>Voit käyttää palvelun kaikkia sisältöjä vapaasti. Jos haluat kommentoida, kirjaudu sisään henkilökohtaisella Mediatunnuksella.</p></div>	<ul class="diks-navigation diks-navigation--size-m"  id="diks-sso-links"><li class="diks-navigation__item " ><a class="diks-navigation__link " href="javascript:window.gravito.cmp.openPreferences();">Evästevalinnat</a></li></ul>
502	</div>
503</div>
504				</div>
505			</div>
506		</div>
507	</div><div class="diks-section-navigation-wrapper">
508			<div class="diks-container diks-container--narrow-mobile diks-container--full-width-before-l">
509					<nav class="diks-navigation-wrapper diks-navigation-wrapper--border-bottom"  aria-label="Osastovalikko"><ul class="diks-navigation diks-navigation--row diks-navigation--light diks-navigation--centered diks-navigation--mobile-row diks-navigation--draggable diks-navigation--size-xs diks-navigation--active-subtle"  id="osastovalikko"><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/paikalliset"draggable="false">Uutiset</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/paakirjoitus-mielipide/"draggable="false">Mielipiteet</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/aihe/blogit"draggable="false">Blogit</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/aihe/menneilta-vuosilta"draggable="false">Menneiltä vuosilta</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="https://pohjois-karjala.menoinfo.fi/fi-FI?sort=startDate&amp;area=area-143"draggable="false">Menoinfo</a></li></ul>
510		</nav>
511			</div>
512		</div><div class="diks-quicklinks-wrapper">
513			<div class="diks-container diks-container--narrow-mobile">
514					<nav class="diks-navigation-wrapper " ><ul class="diks-navigation diks-navigation--main diks-navigation--size-s diks-navigation--row diks-navigation--mobile-row diks-navigation--no-active-links diks-navigation--centered diks-hide-above-large" ><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/uusimmat/"><span class="diks-icon diks-hide-above-large" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
515  <path fill-rule="evenodd" d="M12 4a8 8 0 100 16 8 8 0 000-16zM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10S2 17.523 2 12zm9-6h2v5.586l2.707 2.707-1.414 1.414L11 12.414V6z" clip-rule="evenodd"/>
516</svg>
517</span>Uusimmat</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/luetuimmat/"><span class="diks-icon diks-hide-above-large" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
518  <path fill-rule="evenodd" d="M11.03 3.455c1.168-1.438 3.495-.652 3.55 1.2l.117 3.845h6a1.25 1.25 0 0 1 1.229 1.484l-1.905 10A1.25 1.25 0 0 1 18.793 21H9.06a1.25 1.25 0 0 1-.559-.132L6.764 20H3.25C2.56 20 2 19.44 2 18.75v-8.5C2 9.56 2.56 9 3.25 9h3.274l4.506-5.545ZM8 10.355v8.027L9.236 19h8.936l1.62-8.5h-5.58a1.5 1.5 0 0 1-1.499-1.455l-.131-4.33L8 10.356Zm10.056 9.255ZM4 11v7h2v-7H4Zm14.793 8.75.145.027Z" clip-rule="evenodd"/>
519</svg>
520</span>Luetuimmat</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/nakoislehti/"><span class="diks-icon diks-hide-above-large" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
521  <path fill-rule="evenodd" d="M4 2H20V22H4V2ZM6 4V20H18V4H6ZM8 6H16V12H8V6ZM10 8V10H14V8H10ZM16 15H8V13H16V15ZM16 18H8V16H16V18Z" clip-rule="evenodd"/>
522</svg>
523</span>Lehdet</a></li><li class="diks-navigation__item diks-navigation__item--button diks-navigation__item--align-right diks-hide-above-medium diks-hide-from-subscribers" ><a class="diks-navigation__link diks-bc-order-button" href="/jatka/">Tilaa</a></li></ul>
524		</nav>
525			</div>
526		</div><div id="diks-dropdown-navigation-shade" class="diks-dropdown-navigation-shade"></div></header>
526<script src="/theme/css/includes/waypoints/lib/noframework.waypoints.min.js"></script>
526
527	
527<script>
528	// Fix forEach for IE
529	if (window.NodeList && !NodeList.prototype.forEach) {
530		NodeList.prototype.forEach = Array.prototype.forEach;
531	}
532
533	// Element.closest() needs a polyfill for older browsers.
534	// While we only need the closest() functionality for mobile browsers,
535	// we don't want the code to fail even on old desktop browsers.
536	// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
537	// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility
538	if (!Element.prototype.matches) {
539		Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
540	}
541
542	if (!Element.prototype.closest) {
543		Element.prototype.closest = function(s) {
544			var el = this;
545
546			do {
547				if (el.matches(s)) return el;
548				el = el.parentElement || el.parentNode;
549			} while (el !== null && el.nodeType === 1);
550			return null;
551		};
552	}
553
554		(function () {
555		if (typeof JankkoSSOClient !== 'undefined') {
556			var stringToHTML = function (htmlString) {
557				var div = document.createElement('div');
558				div.innerHTML = htmlString.trim();
559				return div.firstChild;
560			};
561
562			var showUserRelatedItems = function(personalData) {
563				var usernameElement = document.querySelector('#diks-sso-username');
564				if (usernameElement) {
565					usernameElement.innerHTML = personalData.full_name;
566				}
567
568				var linksElement = document.querySelector('#diks-sso-links');
569				if (linksElement) {
570					var myAccountLink = stringToHTML('<li class="diks-navigation__item"><a class="diks-navigation__link" href="'+JankkoSSOClient.serviceUrls.myAccount+'">Omat tiedot</a></li>');
571					var logoutForm = stringToHTML('<li class="diks-navigation__item diks-navigation__item--logout"><form id="logout-form" action="'+JankkoSSOClient.serviceUrls.logout+'" method="post"><input class="diks-navigation__link" type="submit" value="Kirjaudu ulos"></form></li>');
572					linksElement.insertBefore(myAccountLink, linksElement.childNodes[0]);
573					linksElement.appendChild(logoutForm);
574				}
575
576				var htmlElement = document.querySelector('.diks-user--is-not-logged-in'); // Class is set to main html element
577				if (htmlElement) {
578					htmlElement.classList.replace('diks-user--is-not-logged-in', 'diks-user--is-logged-in');
579				}
580			}
581
582			var showMenuLinksForLoggedOutUser = function() {
583				const linksElement = document.querySelector('#diks-sso-links');
584				if (!linksElement) {
585					return;
586				}
587
588				// Pidetään vain tietyt query-parametrit. Alunperin tässä poistettiin kaikki query-parametrit.
589				// @todo Selvitetään voisiko tässä sallia kaikki query-parametrit.
590				const currentUrlObject = new URL(window.location.href);
591				const returnUrlObject = new URL(`${currentUrlObject.origin}${currentUrlObject.pathname}`);
592				const allowedParams = ['limit-active-products'];
593				allowedParams.forEach(function(name) {
594					if (currentUrlObject.searchParams.get(name)) {
595						returnUrlObject.searchParams.set(name, currentUrlObject.searchParams.get(name));
596					}
597				});
598
599				const loginPageUrlObject = new URL(`${window.location.origin}/kirjaudu/`);
600				loginPageUrlObject.searchParams.set('returnUrl', returnUrlObject.toString());
601				const loginLinkString = `<li class="diks-navigation__item"><a class="diks-navigation__link" href="${loginPageUrlObject.toString()}">Kirjaudu</a></li>`;
602
603				linksElement.insertBefore(stringToHTML(loginLinkString), linksElement.childNodes[0]);
604			}
605
606			var showCompanyUserRelatedItems = function(companyData) {
607				var htmlElement = document.querySelector('.diks-user--is-not-company-subscriber'); // Class is set to main html element
608				var permissions = companyData?.company_permissions || [];
609				if (htmlElement && permissions.length) {
610					htmlElement.classList.replace('diks-user--is-not-company-subscriber', 'diks-user--is-company-subscriber');
611				}
612			}
613
614			document.addEventListener("DOMContentLoaded", async function() {
615				try {
616					const data = await JankkoSSOClient.getSession();
617					if (data.company?.company_user_id) {
618						showCompanyUserRelatedItems(data.company);
619					}
620					if (data.personal?.personal_user_id) {
621						showUserRelatedItems(data.personal);
622					} else {
623						showMenuLinksForLoggedOutUser();
624					}
625				} catch (error) {
626					showMenuLinksForLoggedOutUser();
627				}
628			});
629		}
630	}());
631
632
633	//////////////////////////////////////////////////////////////////////////////////////////
634	// NAVIGATIONS
635	//////////////////////////////////////////////////////////////////////////////////////////
636
637	// Toggle icon inside a toggler
638	function toggleTogglerIcon(toggler) {
639		togglerIcons = toggler.querySelectorAll('.diks-icon');
640		if ( togglerIcons.length > 1 ) {
641			for (var j= 0; j < togglerIcons.length; j++) {
642				togglerIcons[j].classList.toggle('diks-icon--hidden');
643			}
644		}
645	}
646
647	// Function for closing all dropdown navigations
648	function closeAllDropdownNavigations() {
649		closeMainDropdownNavigation();
650		closeUserDropdownNavigation();
651	}
652
653	// Close main nav or user nav if hidden screen reader only close navigation button is clicked
654	let closeDropdownMainNav = document.getElementById('diks-close-dropdown-main-nav');
655	let closeDropdownUserNav = document.getElementById('diks-close-dropdown-user-nav');
656	if ( closeDropdownMainNav ) {
657		closeDropdownMainNav.addEventListener('click', function() {
658			closeMainDropdownNavigation();
659		});
660	}
661	if ( closeDropdownUserNav ) {
662		closeDropdownUserNav.addEventListener('click', function(e) {
663			e.stopPropagation();
664			closeUserDropdownNavigation();
665		});
666	}
667
668	// Trap focus inside opened dropdown navigation
669	document.addEventListener('keydown', function(event) {
670		// Initialize variables
671		var ssoLinks = document.getElementById('diks-sso-links');
672		var linksUserNav = "";
673		var firstElUserNav = "";
674		var lastElUserNav = "";
675		var mainDropdownLastNavLinks = document.getElementById('dropdown-customer-nav'); // Last navigation element inside of main dropdown navigation
676		var linksMainDropdownNav = "";
677		var firstElMainDropdownNav = ""
678		var lastElMainDropdownNav = "";
679
680		// Set user nav variable values if SSO links exist
681		if (ssoLinks) {
682			linksUserNav = ssoLinks.querySelectorAll('.diks-navigation__link');
683			firstElUserNav = document.getElementById('diks-close-dropdown-user-nav');
684			lastElUserNav = linksUserNav[linksUserNav.length - 1];
685		}
686
687		// Set main dropdown nav variable values if main dropdown last nav links exist
688		if (mainDropdownLastNavLinks) {
689			linksMainDropdownNav = mainDropdownLastNavLinks.querySelectorAll('.diks-navigation__link');
690			firstElMainDropdownNav = document.getElementById('diks-close-dropdown-main-nav');
691			lastElMainDropdownNav = linksMainDropdownNav[linksMainDropdownNav.length - 1];
692		}
693
694		// If darkmode-toggler is found set it as the last element of main dropdown nav
695		if ( document.getElementById('diks-darkmode-toggler') ) {
696			lastElMainDropdownNav = document.getElementById('diks-darkmode-toggler');
697		}
698
699		// Close all dropdown navigations & reposition fixed header when ESC key is pressed
700		if (event.key === "Escape" || event.key === "Esc") {
701			closeAllDropdownNavigations();
702		}
703		// Trap focus inside user navigation and/or main dropdown navigation when they are open
704		if (event.keyCode === 9) {
705			if (event.shiftKey && (document.activeElement === firstElUserNav || document.activeElement === firstElMainDropdownNav)) {
706				event.preventDefault();
707				if (document.activeElement === firstElUserNav) {
708					lastElUserNav.focus();
709				}
710				else if ( document.activeElement === firstElMainDropdownNav ) {
711					lastElMainDropdownNav.focus();
712				}
713			}
714			else if (!event.shiftKey && (document.activeElement === lastElUserNav || document.activeElement === lastElMainDropdownNav)) {
715				event.preventDefault();
716				if (document.activeElement === lastElUserNav) {
717					firstElUserNav.focus();
718				}
719				else if ( document.activeElement === lastElMainDropdownNav ) {
720					firstElMainDropdownNav.focus();
721				}
722			}
723		}
724	});
725
726
727	//////////////////////////////////////////////////////////////////////////////////////////
728	// User navigation
729	//////////////////////////////////////////////////////////////////////////////////////////
730
731	let userDropdownNavigation = document.getElementById('diks-user-navigation'); // user dropdown navigation
732	let userDropdownNavigationToggler = document.getElementById('diks-sso-user'); // user dropdown navigation toggler button (opens and closes user dropdown navigation)
733	let userDropdownNavigationCloseButton = document.getElementById('diks-close-dropdown-main-nav'); // Hidden screen-reader-only close button inside user dropdown navigation
734
735	// Close user dropdown navigation if hidden screen-reader-only close button is clicked
736	if ( userDropdownNavigationCloseButton ) {
737		userDropdownNavigationCloseButton.addEventListener('click', function() {
738			closeUserDropdownNavigation();
739		});
740	}
741
742	function closeUserDropdownNavigation() {
743		if (userDropdownNavigation) {
744			if (userDropdownNavigation.classList.contains('diks-user-navigation--is-open')) {
745				// Close user dropdown nav by removing --is-open class
746				userDropdownNavigation.classList.remove('diks-user-navigation--is-open');
747				// Remove --is-open class from user dropdown navigation toggler
748				userDropdownNavigationToggler.classList.remove('diks-dropdown-toggle--is-open');
749				// Toggle icon
750				toggleTogglerIcon(userDropdownNavigationToggler);
751
752				// Set aria-expanded to false for user dropdown toggler
753				userDropdownNavigationToggler.setAttribute('aria-expanded', 'false');
754			}
755		}
756	}
757
758	// User Navigation Dropdown
759	if (userDropdownNavigation) {
760		let userDropdownNavigationAriaControls = userDropdownNavigationToggler.getAttribute('data-diks-toggle'); // aria-controls value for user dropown navigation toggler
761		userDropdownNavigationToggler.setAttribute('aria-controls', userDropdownNavigationAriaControls);
762		userDropdownNavigationToggler.addEventListener('click', function(e) {
763			e.preventDefault();
764			// If the main dropdown navigation is already open (contains --is-open class) close it
765			if ( (userDropdownNavigation).classList.contains('diks-user-navigation--is-open') ) {
766				closeUserDropdownNavigation();
767			}
768			// If the main dropdown navigation isn't open (doesn't contain --is-open class) open it
769			else {
770				// If other toggles are open, close them
771				document.querySelectorAll('.diks-user-navigation--is-open').forEach(function(item) {
772					item.classList.remove('diks-user-navigation--is-open');
773					userDropdownNavigationToggler.classList.remove('diks-dropdown-toggler--is-open');
774				});
775
776				// Toggle icon
777				toggleTogglerIcon(userDropdownNavigationToggler);
778
779				// Set aria-expanded
780				userDropdownNavigationToggler.setAttribute('aria-expanded', 'true');
781
782				// Open this toggle
783				userDropdownNavigation.classList.add('diks-user-navigation--is-open');
784
785				// Close main dropdown navigation if it's open
786				closeMainDropdownNavigation();
787
788				// Add event listener to window when user nav toggler is clicked and user nav is open
789				window.addEventListener('click', function(e){
790					if (document.querySelector('.diks-user-navigation-wrapper').contains(e.target)){
791						// Clicked inside user nav, do nothing
792					}
793					else {
794						// Clicked outside user nav, close user nav
795						closeUserDropdownNavigation();
796					}
797				});
798
799			}
800		});
801	}
802
803	//////////////////////////////////////////////////////////////////////////////////////////
804	// Main navigation
805	//////////////////////////////////////////////////////////////////////////////////////////
806
807	let mainDropdownNavigation = document.getElementById('diks-dropdown-navigation'); // main dropdown navigation
808	let mainDropdownNavigationToggler = document.getElementById('diks-dropdown-toggle'); // main dropdown navigation toggler button (opens and closes main dropdown navigation)
809	let mainDropdownNavigationShade = document.querySelector('.diks-dropdown-navigation-shade'); // shade effect that is visible when main dropdown navigation is open
810	let mainDropdownNavigationCloseButton = document.getElementById('diks-close-dropdown-main-nav'); // Hidden screen-reader-only close button inside main dropdown navigation
811
812	// Close main dropdown navigation if hidden screen-reader-only close button is clicked
813	if ( mainDropdownNavigationCloseButton ) {
814		mainDropdownNavigationCloseButton.addEventListener('click', function() {
815			closeMainDropdownNavigation();
816		});
817	}
818
819	// Function for closing main dropdown navigation
820	function closeMainDropdownNavigation() {
821		// Main dropdown navigation
822		if (mainDropdownNavigation) {
823			if (mainDropdownNavigation.classList.contains('diks-dropdown-navigation--is-open')) {
824				// Close main dropdown nav by removing --is-open class
825				mainDropdownNavigation.classList.remove('diks-dropdown-navigation--is-open');
826				// Remove --is-open class from main dropdown navigation toggler
827				mainDropdownNavigationToggler.classList.remove('diks-dropdown-toggle--is-open');
828				// Toggle icon
829				toggleTogglerIcon(mainDropdownNavigationToggler);
830
831				// Set aria-expanded to false for main dropdown toggler
832				mainDropdownNavigationToggler.setAttribute('aria-expanded', 'false');
833
834				// Remove --is-open class from body
835				document.body.classList.remove('diks-body--dropdown-navigation-is-open');
836
837				// Turn off shade effect
838				mainDropdownNavigationShade.classList.remove('diks-dropdown-navigation-shade--is-visible');
839			}
840		}
841	}
842
843
844	// Main Navigation Dropdown
845	if (mainDropdownNavigation) {
846		let mainDropdownNavigationAriaControls = mainDropdownNavigationToggler.getAttribute('data-toggle'); // aria-controls value for main dropown navigation toggler
847		mainDropdownNavigationToggler.setAttribute('aria-controls', mainDropdownNavigationAriaControls);
848		mainDropdownNavigationToggler.addEventListener('click', function(e) {
849			e.preventDefault();
850			// If the main dropdown navigation is already open (contains --is-open class) close it
851			if ( (mainDropdownNavigation).classList.contains('diks-dropdown-navigation--is-open') ) {
852				closeMainDropdownNavigation();
853			}
854			// If the main dropdown navigation isn't open (doesn't contain --is-open class) open it
855			else {
856				// If other toggles are open, close them
857				document.querySelectorAll('.diks-dropdown-navigation--is-open').forEach(function(item) {
858					item.classList.remove('diks-dropdown-navigation--is-open');
859					mainDropdownNavigationToggler.classList.remove('diks-dropdown-toggler--is-open');
860				});
861
862				// Toggle icon
863				toggleTogglerIcon(mainDropdownNavigationToggler);
864
865				// Set aria-expanded
866				mainDropdownNavigationToggler.setAttribute('aria-expanded', 'true');
867
868				// Open this toggle
869				mainDropdownNavigation.classList.add('diks-dropdown-navigation--is-open');
870				// Add is-open class to body
871				document.body.classList.add('diks-body--dropdown-navigation-is-open');
872				// Turn on shade effect
873				mainDropdownNavigationShade.classList.add('diks-dropdown-navigation-shade--is-visible');
874
875				// Close main Dropdown Navigation when visible shade area is clicked
876				document.querySelector('.diks-dropdown-navigation-shade--is-visible').addEventListener('click', function() {
877					closeMainDropdownNavigation();
878				});
879
880				// Close user dropdown navigation if it's open
881				closeUserDropdownNavigation();
882
883			}
884		});
885	}
886
887
888</script>
888
889
890				
891																				
892																							
893																								
894																								
895																								
896							<div class="diks-note-wrapper "><div class="diks-container diks-container--narrower-mobile">
897			<div id="diks-segment-notes"></div><div id="diks-bc-notes"></div></div></div>
897<script>
898	let segmentTeasersContainer = document.getElementById("diks-segment-notes");
899
900	(function() {
901		function getCookie(name) {
902			name = name + '=';
903			const decodedCookie = decodeURIComponent(document.cookie);
904			const cookies = decodedCookie.split(';');
905
906			for (let i = 0; i < cookies.length; i++) {
907				const cookie = cookies[i].trim();
908				if (cookie.indexOf(name) == 0) {
909					return cookie.substring(name.length, cookie.length);
910				}
911			}
912		}
913
914		function injectSegmentTeasers(segmentsQueryString) {
915			var xhttp = new XMLHttpRequest();
916
917			xhttp.onreadystatechange = function() {
918				if (this.readyState == 4 && this.status == 200) {
919					var segmentTeasers = this.responseText.trim();
920
921					if (segmentTeasers) {
922						if (segmentTeasersContainer) {
923							segmentTeasersContainer.innerHTML = segmentTeasers;
924						}
925					}
926					else {
927						// Remove segment teaser container if there are no segment teasers
928						if (segmentTeasersContainer) {
929							segmentTeasersContainer.remove();
930						}
931					}
932				}
933			};
934
935			xhttp.open("GET", "/.ajax/segmentTeaser?" + segmentsQueryString, true);
936			xhttp.send();
937		}
938
939		var segmentsCookie = getCookie('jankkosegments');
940
941		if (segmentsCookie) {
942			var segmentsData = JSON.parse(segmentsCookie);
943			var segments = segmentsData.segments;
944
945			if (segments && typeof segments === 'object') {
946				var segmentsQueryString = "";
947
948				Object.keys(segments).forEach(function(key, index) {
949					segmentsQueryString = index === 0 ? "" : segmentsQueryString + "&";
950					var value = segments[key];
951
952					if (Array.isArray(value)) {
953						value = value.join(',');
954					}
955
956					segmentsQueryString = segmentsQueryString + key + "=" + value;
957				});
958
959				injectSegmentTeasers(segmentsQueryString);
960			}
961		}
962		else {
963			// Remove segment teaser container if there are no segment teasers
964			if (segmentTeasersContainer) {
965				segmentTeasersContainer.remove();
966			}
967		}
968	})();
969</script>
969
970
971	<div class="diks-custom-page diks-apps">
972		<div class="diks-container">
973			<div class="diks-grid">
974				<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-12 diks-column--xl-span-16"><nav aria-label="Murupolku">
975		<ul class="diks-breadcrumb"><li class="diks-breadcrumb__item"><a class="diks-breadcrumb__link" href="/">Etusivu</a></li><li class="diks-breadcrumb__item"><span class="diks-breadcrumb__sub-item">Sovellus</span></li></ul>
976	</nav></div>
977			</div>
978			<main id="sisalto">
979				<div class="diks-apps__content-wrapper">
980					<div class="diks-grid">
981						<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-12 diks-column--xl-span-2"></div>
982		<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-12 diks-column--xl-span-12">
983				<h1 class="diks-title diks-title--size-3xl" >Sovellus</h1>
984		</div>
985		<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-12 diks-column--xl-span-2"></div>
986						<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-12 diks-column--xl-span-2"></div><div class="diks-apps-installation-wrapper diks-column diks-column--span-4 diks-column--m-span-4 diks-column--l-span-6 diks-column--xl-span-6">
987				<div class="diks-apps__icon-wrapper">
988					<span class="diks-icon diks-icon--size-l diks-icon--color-primary" aria-hidden="true"><svg role="img" focusable="false" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
989  <path fill-rule="evenodd" d="M5 2H19V22H5V2ZM7 4V20H17V4H7ZM15 19H9V17H15V19Z" clip-rule="evenodd"/>
990</svg>
991</span>
992				</div>	<h2 class="diks-title diks-title--size-xl" >Sovellus</h2><p>Sovellus sisältää tuoreet juttumme, joita ilmestyy ympäri vuorokauden vuoden jokaisena päivänä sekä näköislehtemme liitteineen sekä näköislehtien arkiston. Asenna sovellus laitteesi sovelluskaupasta.</p><div class="diks-apps-image-wrapper">
993						<a class="diks-apps__app-link diks-hide-on-android" href="https://apps.apple.com/fi/app/yl%C3%A4-karjala/id6695740400"><img class="diks-apps__app-image" src="https://a.ylakarjala.fi/styles/2efe7af9/images/default/appstore-badge.svg" alt="Lataa sovellus App Storesta"></a>
994						<a class="diks-apps__app-link diks-hide-on-ios" href="https://play.google.com/store/apps/details?id=fi.media.ylakarjala"><img class="diks-apps__app-image" src="https://a.ylakarjala.fi/styles/2efe7af9/images/default/google-play-badge.svg" alt="Lataa sovellus Google Play -kaupasta"></a>
995					</div></div>
996								<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-12 diks-column--xl-span-2"></div>
997					</div>
998				</div>
999			</main>
1000		</div>
1001	</div>
1002					
1003								<footer class="diks-footer"><div class="diks-container diks-container--narrow-mobile diks-container--full-width-before-l">
1004			<div class="diks-footer__top">	<nav class="diks-navigation-wrapper "  aria-label="Osastovalikko"><ul class="diks-navigation diks-navigation--row diks-navigation--light diks-navigation--centered diks-navigation--mobile-row diks-navigation--draggable diks-navigation--size-xs diks-navigation--active-subtle" ><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/paikalliset"draggable="false">Uutiset</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/paakirjoitus-mielipide/"draggable="false">Mielipiteet</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/aihe/blogit"draggable="false">Blogit</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="/aihe/menneilta-vuosilta"draggable="false">Menneiltä vuosilta</a></li><li class="diks-navigation__item " ><a class="diks-navigation__link " href="https://pohjois-karjala.menoinfo.fi/fi-FI?sort=startDate&amp;area=area-143"draggable="false">Menoinfo</a></li></ul>
1005		</nav></div>
1006		</div><div class="diks-container"><div class="diks-footer__main">
1007				<div class="diks-grid">
1008					<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-4 diks-column--xl-span-4">
1009						<p><img src="https://a.ylakarjala.fi/styles/2efe7af9/images/logos/ylakarjala.svg" class="diks-logo diks-logo--default diks-footer__main-logo--wide" alt="Ylä-Karjala"><img src="https://a.ylakarjala.fi/styles/2efe7af9/images/logos/ylakarjala-w
1009hite.svg" class="diks-logo diks-logo--darkmode diks-footer__main-logo--wide" alt="Ylä-Karjala"></p>
1010						<p><strong>Päätoimittaja:</strong> Anu Saarelainen</p></div>
1011
1012					<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-4 diks-column--xl-span-5"><div class="diks-footer__main-secondary-logos-container"><div class="diks-footer__main-secondary-logo"><a href="https://vastuullistajournalismia.fi/"><img src="https://a.ylakarjala.fi/styles/2efe7af9/images/logos/vastuullista-journalismia.png" loading="lazy" alt="Vastuullisen journalismin merkki kertoo, että sitä käyttävä media on sitoutunut noudattamaan Julkisen sanan neuvoston laatimia Journalistin ohjeita."></a></div></div><div class="diks-footer__main-links-wrapper">
1013		<div class="diks-column diks-column--span-2"><a class="diks-footer__main-link" href="https://www.keskisuomalainen.com/tietosuojalauseke/">Tietosuojalauseke</a><a class="diks-footer__main-link" href="javascript:window.gravito.cmp.openPreferences();">Evästevalinnat</a><a class="diks-footer__main-link" href="https://www.keskisuomalainen.com/kayttoehdot/">Käyttöehdot</a><a class="diks-footer__main-link" href="https://keskisuomalainen.com/medianvapausasetus/">Medianvapausasetus</a><a class="diks-footer__main-link" href="https://oma.media.fi/tekoaly-journalismissamme/">Tekoäly journalismissamme</a></div>
1014		<div class="diks-column diks-column--span-2"><a class="diks-footer__main-link" href="https://oma.media.fi/yla-karjala/">Asiakaspalvelu</a><a class="diks-footer__main-link" href="https://www.meks.fi/mainonta/alueet/savon-media/">Mediamyynti</a><a class="diks-footer__main-link" href="https://oma.media.fi/yla-karjala/yhteystiedot/">Yhteystiedot</a></div>
1015	</div></div>
1016
1017					<div class="diks-column diks-column--span-4 diks-column--m-span-8 diks-column--l-span-4 diks-column--xl-span-5">
1018						<h2 class="diks-footer__main-title">Sovellus</h2><p>Sovellus sisältää tuoreet juttumme, joita ilmestyy ympäri vuorokauden vuoden jokaisena päivänä sekä näköislehtemme liitteineen sekä näköislehtien arkiston. Asenna sovellus laitteesi sovelluskaupasta.</p><div class="diks-footer__main-app-image-wrapper">
1019					<a class="diks-apps__app-link diks-hide-on-android" href="https://apps.apple.com/fi/app/yl%C3%A4-karjala/id6695740400"><img class="diks-apps__app-image" src="https://a.ylakarjala.fi/styles/2efe7af9/images/default/appstore-badge.svg" loading="lazy" alt="Lataa sovellus App Storesta"></a>
1020					<a class="diks-apps__app-link diks-hide-on-ios" href="https://play.google.com/store/apps/details?id=fi.media.ylakarjala"><img class="diks-apps__app-image" src="https://a.ylakarjala.fi/styles/2efe7af9/images/default/google-play-badge.svg" loading="lazy" alt="Lataa sovellus Google Play -kaupasta"></a>
1021				</div>
1022		
1023						
1024					</div>
1025				</div>
1026			</div><div class="diks-footer__bottom">
1027				<div class="diks-footer__bottom-row"><div class="diks-footer__bottom-logo-wrapper"><a href="https://www.keskisuomalainen.com/"><img class="diks-footer__bottom-logo" src="https://a.ylakarjala.fi/styles/2efe7af9/images/logos/keskisuomalainen-sign.svg" loading="lazy" alt="Keskisuomalainen Oyj"></a></div><span>Kuulumme Mediakonserni Keskisuomalaiseen</span></div>
1028				<div class="diks-footer__bottom-link-farm-wrapper">
1029			<p><a class='diks-footer__bottom-link-farm-item' href='https://www.aamuposti.fi/'>Aamuposti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.avecmedia.fi/'>Avec</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.esaimaa.fi/'>Etelä-Saimaa</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.ess.fi/'>Etelä-Suomen Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.forssanlehti.fi/'>Forssan Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.hankasalmensanomat.fi/'>Hankasalmen Sanomat </a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.heinavedenlehti.fi/'>Heinäveden Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.helsinginuutiset.fi/'>Helsingin Uutiset</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.hameensanomat.fi/'>Hämeen Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.hameenlinnankaupunkiuutiset.fi/'>Hämeenlinnan Kaupunkiuutiset</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.iisalmensanomat.fi/'>Iisalmen Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.itahame.fi/'>Itä-Häme</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.ita-savo.fi/'>Itä-Savo</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.joroistenlehti.fi/'>Joroisten Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.juvanlehti.fi/'>Juvan Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.kaakonkulma.fi/'>Kaakonkulma</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.kangasniemenlehti.fi/'>Kangasniemen Kunnallislehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.karjalainen.fi/'>Karjalainen</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.heili.fi/'>Karjalan Heili</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.karkkilalainen.fi/'>Karkkilalainen</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.keski-hame.fi/'>Keski-Häme</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.keski-uusimaa.fi/'>Keski-Uusimaa</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.keskilaakso.fi/'>Keskilaakso</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.ksml.fi/'>Keskisuomalainen</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.koillis-savo.fi/'>Koillis-Savo</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.kouvolansanomat.fi/'>Kouvolan Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.kymensanomat.fi/'>Kymen Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.lappeenrannanuutiset.fi/'>Lappeenrannan Uutiset</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.laukaa-konnevesi.fi/'>Laukaa-Konnevesi</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.lieksanlehti.fi/'>Lieksan Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.lopenlehti.fi/'>Lopen Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.loviisansanomat.fi/'>Loviisan Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.luumaenlehti.fi/'>Luumäen Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.lansisaimaa.fi/'>Länsi-Saimaan Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.lansi-savo.fi/'>Länsi-Savo</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.lansi-uusimaa.fi/'>Länsi-Uusimaa</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.lansivayla.fi/'>Länsiväylä</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.mattijaliisa.fi/'>Matti ja Liisa</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.meksi.fi/'>Meksi Urheilumedia</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.miilu.fi/'>Miilu</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.mikkelinkaupunkilehti.fi/'>Mikkelin Kaupunkilehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.mantsalanuutiset.fi/'>Mäntsälän Uutiset</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.aamuposti.fi/aihe/Nurmij%C3%A4rvi'>Nurmijärven Uutiset</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.outokummunseutu.fi/'>Outokummun Seutu</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.joutsenolehti.fi/'>Paikallislehti Joutseno</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.prsanomat.fi/'>Parikkalan-Rautjärven Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pernionseudunlehti.fi/'>Perniönseudun Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pieksamaenlehti.fi/'>Pieksämäen Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pielavesi-keitele.fi/'>Pielavesi-Keitele</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pielisjokiseutu.fi/'>Pielisjokiseutu</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pitajalainen.fi/'>Pitäjäläinen</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pitajanuutiset.fi/'>Pitäjänuutiset</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pogostansanomat.fi/'>Pogostan Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.puruvesi.net/'>Puruvesi</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.pyhtaanlehti.fi/'>Pyhtäänlehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.salonjokilaakso.fi/'>Salonjokilaakso</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.sampolehti.fi/'>Sampo</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.savonsanomat.fi/'>Savon Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.sinunsavo.fi/'>Sinun Savo</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.sisa-savolehti.fi/'>Sisä-Savo</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.sisasuomenlehti.fi/'>Sisä-Suomen Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.soisalonseutu.fi/'>Soisalon Seutu</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.sjl.fi/'>Suur-Jyväskylän Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.tamperelainen.fi/'>Tamperelainen</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.tollotin.fi/'>Töllötin</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.uusimaa.fi/'>Uusimaa</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.uutis-jousi.fi/'>Uutis-Jousi</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.uutisvuoksi.fi/'>Uutisvuoksi</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.vantaansanomat.fi/'>Vantaan Sanomat</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.vihdinuutiset.fi/'>Vihdin Uutiset</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.viikkosavo.fi/'>Viikkosavo</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.viispiikkinen.fi/'>
1029Viispiikkinen</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.viitasaarenseutu.fi/'>Viitasaaren Seutu</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.warkaudenlehti.fi/'>Warkauden Lehti</a> &bull; <a class='diks-footer__bottom-link-farm-item' href='https://www.ylakarjala.fi/'>Ylä-Karjala</a></p><p>Kaikki sisällöt voidaan julkaista kaikissa Mediakonserni Keskisuomalaisen medioissa.</p>
1030		</div>
1031			</div></div>
1032</footer>
1033
1034		
1035					
1035<script>
1036	if (!DOMTokenList.prototype.replace) {
1037		// IE Polyfill
1038		DOMTokenList.prototype.replace = function (a, b) {
1039			if (this.contains(a)) {
1040					this.add(b);
1041					this.remove(a);
1042					return true;
1043			}
1044			return false;
1045		}
1046	}
1047
1048	document.querySelector('.diks-no-js').classList.replace('diks-no-js', 'diks-js');
1049
1050	// User agent sniffing is not reliable and it's going away.
1051	// Use only to sprinkle a little bit of progressive enhancement on top.
1052	// Dear Apple, stop lying, iPad on iOS 13 is not a Mac. You're turning into 90s Microsoft.
1053	var userAgent = navigator.userAgent || navigator.vendor || window.opera;
1054	if (/android/i.test(userAgent)) {
1055		document.querySelector('html').classList.add('diks-user-agent--android');
1056	} else if (/iPad|iPhone|iPod/i.test(userAgent) && !window.MSStream) {
1057		document.querySelector('html').classList.add('diks-user-agent--ios');
1058	} else if (/macintosh/i.test(userAgent) && navigator.maxTouchPoints > 1) {
1059		document.querySelector('html').classList.add('diks-user-agent--ios');
1060	}
1061</script>
1061
1062
1063<script>
1064	// Fix forEach for IE
1065	if (window.NodeList && !NodeList.prototype.forEach) {
1066		NodeList.prototype.forEach = Array.prototype.forEach;
1067	}
1068
1069	// Element.closest() needs a polyfill for older browsers.
1070	// While we only need the closest() functionality for mobile browsers,
1071	// we don't want the code to fail even on old desktop browsers.
1072	// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
1073	// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Browser_compatibility
1074	if (!Element.prototype.matches) {
1075		Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
1076	}
1077
1078	if (!Element.prototype.closest) {
1079		Element.prototype.closest = function(s) {
1080			var el = this;
1081
1082			do {
1083				if (el.matches(s)) return el;
1084				el = el.parentElement || el.parentNode;
1085			} while (el !== null && el.nodeType === 1);
1086			return null;
1087		};
1088	}
1089
1090	function setAriaExpanded(toggler, ariaExpandedValue) {
1091		// Set aria-expanded attribute of dropdown toggler
1092		// If the toggler contains a button, set the aria-expanded attribute for the button instead
1093		if ( toggler.querySelector('button') != null ) {
1094			toggler.querySelector('button').setAttribute('aria-expanded', ariaExpandedValue);
1095		}
1096		else {
1097			toggler.setAttribute('aria-expanded', ariaExpandedValue);
1098		}
1099	}
1100
1101	function toggleElement(target, toggleClass, toggler) {
1102		if (toggleClass) {
1103			var isOpenClass = toggleClass + '--is-open';
1104			var isClosedClass = toggleClass + '--is-closed';
1105
1106			if (target.classList.contains(isOpenClass)) {
1107				// Close this toggle
1108				target.classList.remove(isOpenClass);
1109				target.classList.add(isClosedClass);
1110
1111				// Set aria-expanded to false for the toggler
1112				setAriaExpanded(toggler, 'false');
1113
1114			} else if (target.classList.contains(isClosedClass)) {
1115				// Open this toggle
1116				target.classList.remove(isClosedClass);
1117				target.classList.add(isOpenClass);
1118
1119				// Set aria-expanded to true for the toggler
1120				setAriaExpanded(toggler, 'true');
1121			} else {
1122				// Open this toggle as a fallback
1123				target.classList.add(isOpenClass);
1124
1125				// Set aria-expanded to true for the toggler
1126				setAriaExpanded(toggler, 'true');
1127			}
1128		} else {
1129			if (window.getComputedStyle(target).display !== 'none') {
1130				target.style.display = 'none';
1131			} else {
1132				target.style.display = 'block';
1133			}
1134		}
1135	};
1136
1137	document.querySelectorAll('.js-diks-toggler').forEach(function(toggler) {
1138		var toggleId = toggler.getAttribute('data-diks-toggle');
1139		var target = document.getElementById(toggleId);
1140		var eventListenerAttached = toggler.getAttribute('data-diks-event-click');
1141
1142		if (target && !eventListenerAttached) {
1143
1144			// Set aria-controls of toggler
1145			if ( toggler.querySelector('button') != null ) {
1146				toggler.querySelector('button').setAttribute('aria-controls', toggleId);
1147			}
1148			else {
1149				toggler.setAttribute('aria-controls', toggleId);
1150			}
1151
1152			toggler.addEventListener('click', function(e) {
1153				e.preventDefault();
1154
1155				var toggleClass = toggler.getAttribute('data-diks-toggle-class');
1156
1157				if (webShareAPIEnabled(toggleId)) {
1158					share();
1159				} else {
1160					toggleElement(target, toggleClass, toggler);
1161				}
1162			});
1163
1164			toggler.setAttribute('data-diks-event-click', true);
1165		}
1166	});
1167
1168	// Web Share and Clipboard API capabilities
1169
1170	function webShareAPIEnabled(toggleId) {
1171		const webShareAPIEnabled = true;
1172		const webShareAPIDropdownShareIds = ["jaa","jakopainikkeet"];
1173		const isMobileDevice = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
1174
1175		return webShareAPIEnabled && webShareAPIDropdownShareIds.includes(toggleId) && isMobileDevice && navigator.share ? true : false;
1176	}
1177
1178	function share() {
1179		const metaTitleElement = document.querySelector('meta[property="og:title"]');
1180		const metaDescriptionElement = document.querySelector('meta[name="description"]');
1181		const metaUrlElement = document.querySelector('meta[property="og:url"]');
1182		let title = '';
1183		let description = '';
1184		let url = document.location.href;
1185
1186		if (metaTitleElement && metaTitleElement.content) {
1187			title = metaTitleElement.content;
1188		}
1189
1190		if (metaDescriptionElement && metaDescriptionElement.content) {
1191			description = metaDescriptionElement.content;
1192		}
1193
1194		if (metaUrlElement && metaUrlElement.content) {
1195			url = metaUrlElement.content;
1196		}
1197
1198		navigator.share({
1199			title: title,
1200			text: description,
1201			url: url
1202		});
1203	}
1204
1205	document.querySelectorAll('.js-diks-share-clipboard').forEach(function(element) {
1206		element.addEventListener('click', function(e) {
1207			e.preventDefault();
1208
1209			let url = document.location.href;
1210			const metaUrlElement = document.querySelector('meta[property="og:url"]');
1211
1212			if (metaUrlElement && metaUrlElement.content) {
1213				url = metaUrlElement.content;
1214			}
1215
1216			// Copy URL to clipboard
1217			navigator.clipboard.writeText(url).then(function () {
1218				// Copying URL to clipboard succeeded
1219				const dropdownId = element.getAttribute('data-diks-dropdown-id');
1220				// Find closest dropdown toggler
1221				let dropdownToggler = element.closest('.diks-dropdown').querySelector('.js-diks-toggler');
1222
1223				if (dropdownId) {
1224					const dropdownElement = document.getElementById(dropdownId);
1225
1226					if (dropdownElement) {
1227						// Close currently open dropdown
1228						toggleElement(dropdownElement, 'diks-dropdown__content', dropdownToggler);
1229					}
1230
1231					// Show link copied notification text
1232					const notificationTextWrapperDiv = document.createElement('div');
1233					const notificationTextDiv = document.createElement('div');
1234					const notificationText = document.createTextNode('Linkki kopioitu leikepöydälle');
1235
1236					notificationTextDiv.classList.add('diks-dropdown__notification-text');
1237					notificationTextDiv.appendChild(notificationText);
1238					notificationTextWrapperDiv.classList.add('diks-dropdown__notification-text-wrapper');
1239					notificationTextWrapperDiv.appendChild(notificationTextDiv);
1240					dropdownElement.parentNode.insertBefore(notificationTextWrapperDiv, null);
1241
1242					setTimeout(function () {
1243						notificationTextWrapperDiv.remove();
1244					}, 5000);
1245				}
1246			});
1247		});
1248	});
1249
1250        const initContentBlockToggleButtons = () => {
1251        const toggleContainers = document.querySelectorAll('[data-diks-init="toggle"]');
1252        toggleContainers.forEach(container => {
1253            const toggleButton = container.querySelector('.diks-toggle-button');
1254            const toggleContent = container.querySelector('.diks-toggle-content-container');
1255            if (toggleButton && toggleContent) {
1256                toggleButton.addEventListener('click', () => {
1257                    toggleElement(toggleContent, 'diks-toggle', toggleButton);
1258                });
1259            }
1260        });
1261    };
1262    document.addEventListener('DOMContentLoaded', () => {
1263        initContentBlockToggleButtons();
1264    });
1265
1266</script>
1266
1267
1268<script>
1269	const useDragThreshold = true;
1270
1271	// Horizontally scrollable & draggable navigation
1272	class HorizontalScrollDragger {
1273		constructor(element) {
1274			this.slider = typeof element === 'string' ? document.querySelector(element) : element instanceof Element ? element : null;
1275			if (this.slider === null) return console.error('HorizontalScrollDragger: Element not found');
1276
1277			this.isDown = false;
1278			this.preventClick = false;
1279			this.startX;
1280			this.scrollLeft;
1281
1282			this.dragThreshold = 5;
1283			this.dragSensitivity = 1;
1284			this.dragged = false;
1285
1286			this.init();
1287		}
1288
1289		init() {
1290			this.slider.addEventListener('mousedown', (e) => this.handleMouseDown(e));
1291			this.slider.addEventListener('mouseleave', () => this.handleMouseLeave());
1292			this.slider.addEventListener('mouseup', () => this.handleMouseUp());
1293			this.slider.addEventListener('mousemove', (e) => this.handleMouseMove(e));
1294			this.slider.addEventListener('click', (e) => this.handleClick(e));
1295		}
1296
1297		handleMouseDown(e) {
1298			this.isDown = true;
1299			this.slider.classList.add('diks-navigation--draggable-active');
1300			this.startX = e.pageX - this.slider.offsetLeft;
1301			this.scrollLeft = this.slider.scrollLeft;
1302			this.preventClick = false;
1303		}
1304
1305		handleMouseLeave() {
1306			this.isDown = false;
1307			this.slider.classList.remove('diks-navigation--draggable-active');
1308		}
1309
1310		handleMouseUp() {
1311			this.isDown = false;
1312			this.slider.classList.remove('diks-navigation--draggable-active');
1313		}
1314
1315		handleMouseMove(e) {
1316			if (!this.isDown) return;
1317
1318			if ( useDragThreshold == true ) {
1319				const xWithThreshold = e.pageX - this.slider.offsetLeft;
1320				const delta = xWithThreshold - this.startX;
1321
1322				// If not yet dragging, check threshold
1323				if (!this.dragged && Math.abs(delta) > this.dragThreshold) {
1324					this.dragged = true;
1325					this.preventClick = true;
1326
1327					// Reset baseline so scrolling starts smoothly from here
1328					this.startX = xWithThreshold;
1329					this.scrollLeft = this.slider.scrollLeft;
1330				}
1331
1332				if (this.dragged) {
1333					e.preventDefault();
1334					const walkWithThreshold = (xWithThreshold - this.startX) * this.dragSensitivity; // adjust sensitivity
1335					this.slider.scrollLeft = this.scrollLeft - walkWithThreshold;
1336				}
1337			}
1338			else {
1339				e.preventDefault();
1340				const x = e.pageX - this.slider.offsetLeft;
1341				const walk = (x - this.startX) * this.dragSensitivity; // adjust sensitivity
1342				this.slider.scrollLeft = this.scrollLeft - walk;
1343				this.preventClick = true;
1344			}
1345
1346		}
1347
1348		handleClick(e) {
1349			if ( useDragThreshold == true && this.preventClick && this.dragged ) {
1350				e.preventDefault();
1351			}
1352			else if ( useDragThreshold == false && this.preventClick) {
1353				e.preventDefault();
1354			}
1355		}
1356	}
1357
1358	// Set the draggable navs (multiple) to handle their scrollbars
1359	let scrollableNavs = document.querySelectorAll('.diks-navigation--draggable');
1360
1361	// Make draggable navigation draggable
1362	if ( scrollableNavs ) {
1363		scrollableNavs.forEach(function(element) {
1364			new HorizontalScrollDragger(element);
1365		});
1366	}
1367
1368
1369	// Handle has-scrollbars class adding and removing
1370	function handleScrollableNavScrollbars(scrollableNavElement) {
1371		// If scrollable area is wider (scrollWidth) than what's visible (clientWidth) the element has scrollbars
1372		if ( scrollableNavElement.scrollWidth > scrollableNavElement.clientWidth ) {
1373			scrollableNavElement.classList.add('diks-navigation--draggable-has-scrollbars');
1374			scrollableNavElement.parentElement.classList.add('diks-navigation-wrapper--has-scrollbars');
1375		}
1376		// Remove the has-scrollbars class if it exists but shouldn't (element does not have scrollbars)
1377		else if ( scrollableNavElement.classList.contains('diks-navigation--draggable-has-scrollbars') ) {
1378			scrollableNavElement.classList.remove('diks-navigation--draggable-has-scrollbars');
1379			scrollableNavElement.parentElement.classList.remove('diks-navigation-wrapper--has-scrollbars');
1380		}
1381	}
1382
1383	// If scrollable nav exists add (or remove) necessary classes
1384	// "DOMContentLoaded" does not wait for styles to load and styles affect the size of the scrollable nav directly so we have to use "load" instead
1385	window.addEventListener('load', (event) => {
1386		if ( scrollableNavs ) {
1387			scrollableNavs.forEach(function(element) {
1388				handleScrollableNavScrollbars(element);
1389			});
1390		}
1391	});
1392
1393	// Check if scrollable nav has scrollbar
1394	window.addEventListener('resize', function(event){
1395		if ( scrollableNavs ) {
1396			scrollableNavs.forEach(function(element) {
1397				handleScrollableNavScrollbars(element);
1398			});
1399		}
1400	});
1401</script>
1401
1402
1403<script>
1404	// Back button handling
1405	document.querySelectorAll('a.js-diks-back-button').forEach(function(item) {
1406		var referrerIsSameDomain = false;
1407		// Check if referrer is found as referrer isn't always available (browser, tab, window, bookmark, privacy).
1408		if (typeof(document.referrer) === 'string' && document.referrer.length > 0) {
1409			// Set referrerIsSameDomain to true if referrer is in the same domain as current location hostname and referrer is not the same page as current page (window.location.href)
1410			if ( document.referrer.includes(document.location.hostname) && document.referrer != window.location.href ) {
1411				referrerIsSameDomain = true;
1412			}
1413		}
1414
1415		// Overwrite link with history.go, as it also remembers scroll position but only if referrer is the same domain as current location hostname
1416		if (history.length > 1 && referrerIsSameDomain == true) {
1417			// Set referrer as back button href to enable visual cue & opening to a new window
1418			item.setAttribute('href', document.referrer);
1419
1420			// Set back button text
1421			item.querySelector('.diks-header__cta-text').innerHTML = "Takaisin";
1422			
1423			var stepsToGoBack = -1;
1424
1425			item.addEventListener('click', function(e) {
1426				e.preventDefault();
1427				history.go(stepsToGoBack);
1428			});
1429		}
1430	});
1431</script>
1431
1432
1433			<link rel="stylesheet" href="/theme/css/includes/lightgallery/css/lightgallery-bundle.min.css">
1434	<style>.lg-sub-html { background-color: rgba(0,0,0, .6); }</style>
1435	
1435<script src="/theme/css/includes/lightgallery/lightgallery.min.js"></script>
1435
1436	
1436<script src="/theme/css/includes/lightgallery/plugins/autoplay/lg-autoplay.min.js"></script>
1436
1437	
1437<script src="/theme/css/includes/lightgallery/plugins/fullscreen/lg-fullscreen.min.js"></script>
1437
1438	
1438<script src="/theme/css/includes/lightgallery/plugins/thumbnail/lg-thumbnail.min.js"></script>
1438
1439	
1439<script src="/theme/css/includes/lightgallery/plugins/zoom/lg-zoom.min.js"></script>
1439
1440	
1440<script>
1441		// lightGallery
1442		// Separate gallery for every .js-lightgallery
1443		// Gallery items come from .js-lightgallery .js-lightgallery__link
1444		// https://www.lightgalleryjs.com/docs/getting-started/
1445		document.querySelectorAll('.js-diks-lightgallery').forEach(function(gallery) {
1446			var galleryImageLinks = gallery.getElementsByClassName('diks-gallery__link');
1447
1448			// Thumbnails come from img inside the links, unless links specify data-thumbnail
1449			var thumbnailSource = (galleryImageLinks[0].hasAttribute('data-thumbnail')) ? ('data-thumbnail') : (false);
1450
1451			// Adjust certain settings depending on whether the gallery has one or more images
1452			var galleryHasMultipleImages = (galleryImageLinks.length > 1 ? true : false);
1453
1454			// Initialize
1455			lightGallery(gallery, {
1456				autoplay: galleryHasMultipleImages,
1457				counter: galleryHasMultipleImages,
1458				download: false,
1459				exThumbImage: thumbnailSource,
1460				hideControlOnEnd: true,
1461				licenseKey: "96BAAD7E-3BF04397-BBB55AE3-6D5A2C0B",
1462				loop: false,
1463				plugins: [lgAutoplay, lgFullscreen, lgThumbnail, lgZoom],
1464				selector: '.diks-gallery__link',
1465				mobileSettings: {
1466					controls: true,
1467					showCloseIcon: true
1468				},
1469				strings: {
1470					closeGallery: 'Sulje galleria',
1471					toggleMaximize: 'Maksimointi',
1472					previousSlide: 'Edellinen',
1473					nextSlide: 'Seuraava',
1474					download: 'Lataa',
1475					playVideo: 'Katso video',
1476					mediaLoadingFailed: 'Sisällön lataus epäonnistui',
1477				},
1478				autoplayPluginStrings: {
1479					toggleAutoplay: 'Automaattinen toisto'
1480				},
1481				fullscreenPluginStrings: {
1482					toggleFullscreen: 'Kokoruututila'
1483				},
1484				thumbnailPluginStrings: {
1485					toggleThumbnails: 'Pikkukuvat'
1486				},
1487				zoomPluginStrings: {
1488					zoomIn: 'Suurenna',
1489					zoomOut: 'Pienennä',
1490					viewActualSize: 'Näytä täysikokoisena'
1491				}
1492			});
1493
1494			// After closing LightGallery return focus to the image link that opened the gallery 
1495			gallery.addEventListener('lgAfterClose', () => {
1496				galleryImageLinks[0].focus();
1497			});
1498
1499		});
1500
1501	</script>
1501
1502
1503<script>
1504	function loadScript(url, callback) {
1505		var script = document.createElement("script");
1506		script.type = "text/javascript";
1507		if (script.readyState) {  // IE
1508			script.onreadystatechange = function() {
1509				if (script.readyState === "loaded" || script.readyState === "complete") {
1510					script.onreadystatechange = null;
1511					callback();
1512				}
1513			};
1514		} else {  // Others
1515			script.onload = function() {
1516				callback();
1517			};
1518		}
1519		script.src = url;
1520		document.getElementsByTagName("head")[0].appendChild(script);
1521	}
1522	function checkAudioElements() {
1523		// load audioplayer script only when audio elements are found
1524		if (document.querySelector(".init-audio-player")) {
1525			loadScript("https://a.ylakarjala.fi/styles/2efe7af9/js/audioplayer/diks-audioplayer.min.js", function() {
1526				DiksAudioPlayer.init({
1527					selector: '.init-audio-player',
1528					stopOthersOnPlay: true,
1529					enableKeystrokes: true
1530				});
1531			});
1532		}
1533	}
1534	window.onload = (event) => {
1535		checkAudioElements();
1536	};
1537</script>
1537<script>
1538    // ================================================================
1539    // Unified Content Block Component
1540    // ================================================================
1541
1542    const DiksContentBlock = (() => {
1543        // Private utility functions
1544        const utils = {
1545            setCookie: (name, value, days = 30) => {
1546                const expires = new Date();
1547                expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000));
1548                document.cookie = `${name}=${encodeURIComponent(value)};expires=${expires.toUTCString()};path=/`;
1549            },
1550
1551            getCookie: (name) => {
1552                const value = `; ${document.cookie}`;
1553                const parts = value.split(`; ${name}=`);
1554                if (parts.length === 2) return decodeURIComponent(parts.pop().split(';').shift());
1555                return null;
1556            },
1557
1558            renderArticleCard: (article) => {
1559                let mainImage = article.mainImage;
1560
1561                // For ContentPackage: if mainImage is empty, get from first story in teaserStories
1562                if (article.type === 'ContentPackage' && (!mainImage || mainImage.length === 0)) {
1563                    if (article.teaserStories && article.teaserStories.length > 0) {
1564                        // Find first teaser story with a mainImage
1565                        for (const teaserStory of article.teaserStories) {
1566                            if (teaserStory.content &&
1567                                teaserStory.content.mainImage &&
1568                                teaserStory.content.mainImage.length > 0) {
1569                                mainImage = teaserStory.content.mainImage;
1570                                break;
1571                            }
1572                        }
1573                    }
1574                }
1575
1576                let imageHtml = '';
1577                if (mainImage && mainImage.length > 0) {
1578                    const imageFields = mainImage[0].content.fields;
1579                    const src = imageFields.landscape_720.href_full;
1580                    const srcset = `
1581                        ${imageFields.landscape_240.href_full} 240w,
1582                        ${imageFields.landscape_480.href_full} 480w,
1583                        ${imageFields.landscape_720.href_full} 720w,
1584                        ${imageFields.landscape_960.href_full} 960w
1585                    `;
1586                    imageHtml = `
1587                        <div class="diks-card__image-wrapper">
1588                            <img class="diks-card__image"
1589                                 src="${src}"
1590                                 loading="lazy"
1591                                 sizes="(max-width: 504px) 480px, (max-width: 1279px) 720px, 960px"
1592                                 srcset="${srcset}"
1593                                 decoding="async"
1594                                 alt="${article.headline}"
1595                                 pinger-seen="true">
1596                        </div>
1597                    `;
1598                }
1599
1600                const fullHeadline = article.headlinePrefix
1601                    ? `<span class="diks-ui-accent">${article.headlinePrefix} | </span>${article.headline}`
1602                    : article.headline;
1603
1604                const publishedDate = new Date(article.published).toLocaleString('fi-FI', {
1605                    day: 'numeric',
1606                    month: 'numeric',
1607                    year: 'numeric',
1608                    hour: 'numeric',
1609                    minute: 'numeric'
1610                });
1611
1612                return `
1613                    <article class="diks-card diks-card--size-s">
1614                        <div class="diks-card__main-wrapper">
1615                            ${imageHtml}
1616                            <div class="diks-card__text-wrapper">
1617                                <div class="diks-card__text-inner-wrapper">
1618                                    <h2 class="diks-card__title">
1619                                        <a class="diks-card__link" href="${article.href}">${fullHeadline}</a>
1620                                    </h2>
1621                                    <div class="diks-card__meta-wrapper">
1622                                        <div class="diks-meta">
1623                                            <div class="diks-date">
1624                                                <time class="diks-date__published" datetime="${article.published}">${publishedDate}</time>
1625                                            </div>
1626                                        </div>
1627                                    </div>
1628                                </div>
1629                            </div>
1630                        </div>
1631                    </article>
1632                `;
1633            },
1634
1635            getComponentType: (containerId) => {
1636                if (containerId.startsWith('diks-content-block-search-')) return 'search';
1637                if (containerId.startsWith('diks-content-block-aggregator-')) return 'aggregator';
1638                return null;
1639            },
1640
1641            getBlockId: (containerId, type) => {
1642                if (type === 'search') return containerId.replace('diks-content-block-search-', '');
1643                if (type === 'aggregator') return containerId.replace('diks-content-block-aggregator-', '');
1644                return containerId;
1645            },
1646
1647            getResultsId: (blockId, type) => {
1648                if (type === 'search') return `diks-search-results-${blockId}`;
1649                if (type === 'aggregator') return `diks-results-${blockId}`;
1650                return null;
1651            }
1652        };
1653
1654        // Build query parameters based on component type and filters
1655        const buildQueryParams = (containerId) => {
1656            const container = document.getElementById(containerId);
1657            const type = utils.getComponentType(containerId);
1658            const blockId = utils.getBlockId(containerId, type);
1659
1660            const params = new URLSearchParams({
1661                type: container.dataset.queryType || 'story',
1662                size: container.dataset.maxResults || 20
1663            });
1664
1665            if (type === 'search') {
1666                // Search-specific parameters
1667                const defaultSort = container.dataset.sort;
1668                const defaultPaywall = container.dataset.paywall;
1669                const defaultStoryTypes = container.dataset.storyTypes;
1670                const defaultTopics = container.dataset.topics;
1671                const defaultAdvertisers = container.dataset.advertisers;
1672                const dateRangeType = container.dataset.dateRangeType;
1673
1674                // Sort
1675                if (defaultSort && defaultSort !== '*') {
1676                    params.append('sort', defaultSort);
1677                }
1678
1679                // Paywall
1680                const paywallSelect = document.getElementById(`diks-search-paywall-${blockId}`);
1681                if (paywallSelect && paywallSelect.value) {
1682                    params.append('paywall', paywallSelect.value);
1683                } else if (defaultPaywall && defaultPaywall !== '*') {
1684                    params.append('paywall', defaultPaywall);
1685                }
1686
1687                // Story types
1688                let storyTypesValue = defaultStoryTypes;
1689                const storyTypesSelect = document.getElementById(`diks-search-story-types-${blockId}`);
1690                if (storyTypesSelect) {
1691                    const selectedOptions = Array.from(storyTypesSelect.selectedOptions).map(opt => opt.value);
1692                    if (selectedOptions.length > 0) {
1693                        storyTypesValue = selectedOptions.join(',');
1694                    }
1695                }
1696                if (storyTypesValue) {
1697                    params.append('storyTypes', storyTypesValue);
1698                }
1699
1700                // Topics
1701                if (defaultTopics) {
1702                    params.append('topics', defaultTopics);
1703                    const topicsOperator = container.dataset.topicsOperator || 'OR';
1704                    params.append('topicsOperator', topicsOperator);
1705                }
1706
1707                // Advertisers
1708                if (defaultAdvertisers) {
1709                    params.append('advertisers', defaultAdvertisers);
1710                    const advertisersOperator = container.dataset.advertisersOperator || 'OR';
1711                    params.append('advertisersOperator', advertisersOperator);
1712                }
1713
1714                // Date ranges
1715                const fromDateInput = document.getElementById(`diks-search-from-date-${blockId}`);
1716                const toDateInput = document.getElementById(`diks-search-to-date-${blockId}`);
1717                const monthInput = document.getElementById(`diks-search-month-${blockId}`);
1718
1719                if (dateRangeType === 'byMonth' && monthInput && monthInput.value) {
1720                    const [year, month] = monthInput.value.split('-').map(Number);
1721                    const fromDate = new Date(year, month - 1, 1, 0, 0, 0, 0);
1722                    const toDate = new Date(year, month, 0, 23, 59, 59, 999);
1723                    params.append('fromDate', fromDate.toISOString().split('.')[0] + 'Z');
1724                    params.append('toDate', toDate.toISOString().split('.')[0] + 'Z');
1725                } else {
1726                    if (fromDateInput && fromDateInput.value) {
1727                        const fromDate = new Date(fromDateInput.value);
1728                        fromDate.setHours(0, 0, 0, 0);
1729                        params.append('fromDate', fromDate.toISOString().split('.')[0] + 'Z');
1730                    }
1731                    if (toDateInput && toDateInput.value) {
1732                        const toDate = new Date(toDateInput.value);
1733                        toDate.setHours(23, 59, 59, 999);
1734                        params.append('toDate', toDate.toISOString().split('.')[0] + 'Z');
1735                    }
1736                }
1737            } else if (type === 'aggregator') {
1738                // Aggregator-specific parameters
1739                const selectedTopic = container.dataset.selectedTopic;
1740                if (selectedTopic) {
1741                    params.append('topics', selectedTopic);
1742                }
1743            }
1744
1745            return params;
1746        };
1747
1748        // Main fetch content function
1749        const fetchContent = async (containerId) => {
1750            const container = document.getElementById(containerId);
1751            const type = utils.getComponentType(containerId);
1752            const blockId = utils.getBlockId(containerId, type);
1753            const resultsId = utils.getResultsId(blockId, type);
1754            const resultsDiv = document.getElementById(resultsId);
1755
1756            if (!container || !resultsDiv) {
1757                console.error(`Content block container or results div not found: ${containerId}`);
1758                return;
1759            }
1760
1761            try {
1762                // Show loading state
1763                const loadingMessage = type === 'search'
1764                    ? '<p class="diks-content-block-search--loading">Ladataan...</p>'
1765                    : '<p class="diks-content-block-aggregator--loading">Ladataan...</p>';
1766                resultsDiv.innerHTML = loadingMessage;
1767
1768                // Build query parameters
1769                const params = buildQueryParams(containerId);
1770                const apiUrl = container.dataset.apiUrl || '/.content/items';
1771
1772                // Fetch data
1773                const response = await fetch(`${apiUrl}?${params.toString()}`, {
1774                    method: 'GET'
1775                });
1776
1777                if (!response.ok) {
1778                    throw new Error('Verkkovirhe.');
1779                }
1780
1781                const data = await response.json();
1782
1783                // Render results
1784                let html = '';
1785                if (data.items && data.items.length > 0) {
1786                    data.items.forEach(article => {
1787                        html += utils.renderArticleCard(article);
1788                    });
1789                } else {
1790                    const noResultsMessage = type === 'search'
1791                        ? '<p class="diks-content-block-search--no-results">Ei hakutuloksia.</p>'
1792                        : '<p>Ei sisältöä.</p>';
1793                    html = noResultsMessage;
1794                }
1795
1796                resultsDiv.innerHTML = html;
1797            } catch (error) {
1798                const errorMessage = type === 'search'
1799                    ? `<p class="diks-content-block-search--error">Virhe: ${error.message}</p>`
1800                    : `<p class="error">Error: ${error.message}</p>`;
1801                resultsDiv.innerHTML = errorMessage;
1802            }
1803        };
1804
1805        // Initialize search component
1806        const initializeSearch = (containerId) => {
1807            const container = document.getElementById(containerId);
1808            const blockId = utils.getBlockId(containerId, 'search');
1809            const dateRangeType = container.dataset.dateRangeType;
1810
1811            // Get UI elements
1812            const searchButton = document.getElementById(`diks-search-button-${blockId}`);
1813            const fromDateInput = document.getElementById(`diks-search-from-date-${blockId}`);
1814            const toDateInput = document.getElementById(`diks-search-to-date-${blockId}`);
1815            const monthInput = document.getElementById(`diks-search-month-${blockId}`);
1816
1817            // Set current month as default for byMonth type
1818            if (dateRangeType === 'byMonth' && monthInput) {
1819                const now = new Date();
1820                const year = now.getFullYear();
1821                const month = String(now.getMonth() + 1).padStart(2, '0');
1822                monthInput.value = `${year}-${month}`;
1823
1824                // Auto-trigger search on month change
1825                monthInput.addEventListener('change', () => fetchContent(containerId));
1826            }
1827
1828            // Search button click handler
1829            if (searchButton) {
1830                searchButton.addEventListener('click', () => fetchContent(containerId));
1831            }
1832
1833            // Enter key support
1834            [fromDateInput, toDateInput, monthInput].forEach(input => {
1835                if (input) {
1836                    input.addEventListener('keypress', (e) => {
1837                        if (e.key === 'Enter') fetchContent(containerId);
1838                    });
1839                }
1840            });
1841
1842            // Initial search
1843            fetchContent(containerId);
1844        };
1845
1846        // Initialize aggregator component
1847        const initializeAggregator = (containerId) => {
1848            const container = document.getElementById(containerId);
1849            const blockId = utils.getBlockId(containerId, 'aggregator');
1850            const topicLabels = JSON.parse(container.dataset.topicLabels || '{}');
1851            const cookieName = `selectedTopic_${blockId}`;
1852
1853            const listId = `diks-topic-list-${blockId}`;
1854            const labelId = `diks-selected-topic-label-${blockId}`;
1855            const toggleId = `diks-toggle-button-${blockId}`;
1856            const listContainerId = `diks-toggle-area-${blockId}`;
1857
1858            const topicItems = document.querySelectorAll(`#${listId} .diks-topic-list__item`);
1859            const labelElement = document.getElementById(labelId);
1860
1861            // Update topic label display
1862            const updateTopicLabel = (topic) => {
1863                if (labelElement && topicLabels[topic]) {
1864                    labelElement.textContent = topicLabels[topic];
1865                } else if (labelElement) {
1866                    labelElement.textContent = '';
1867                }
1868
1869                // Update active state
1870                topicItems.forEach(item => {
1871                    item.classList.toggle('diks-is-active', item.dataset.topic === topic);
1872                });
1873            };
1874
1875            // Handle single topic case
1876            if (Object.keys(topicLabels).length === 1) {
1877                const initialTopic = Object.keys(topicLabels)[0];
1878                container.dataset.selectedTopic = initialTopic;
1879                updateTopicLabel(initialTopic);
1880                fetchContent(containerId);
1881                return;
1882            }
1883
1884            // Handle multiple topics case
1885            if (topicItems.length > 0) {
1886                // Determine initial topic (cookie or first)
1887                const cookieTopic = utils.getCookie(cookieName);
1888                let initialTopic = topicItems[0].dataset.topic;
1889
1890                if (cookieTopic) {
1891                    const validTopic = Array.from(topicItems).some(item => item.dataset.topic === cookieTopic);
1892                    if (validTopic) {
1893                        initialTopic = cookieTopic;
1894                    }
1895                }
1896
1897                // Set up topic click handlers
1898                topicItems.forEach(item => {
1899                    item.addEventListener('click', () => {
1900                        const selectedTopic = item.dataset.topic;
1901                        container.dataset.selectedTopic = selectedTopic;
1902                        utils.setCookie(cookieName, selectedTopic);
1903                        updateTopicLabel(selectedTopic);
1904                        fetchContent(containerId);
1905
1906                        // Close toggle if open
1907                        const toggleButton = document.getElementById(toggleId);
1908                        const listContainer = document.getElementById(listContainerId);
1909                        if (toggleButton && listContainer) {
1910                            toggleButton.setAttribute('aria-expanded', 'false');
1911                            listContainer.classList.remove('diks-toggle--is-open');
1912                            listContainer.classList.add('diks-toggle--is-closed');
1913                            container.dataset.diksToggleState = 'closed';
1914                        }
1915                    });
1916                });
1917
1918                // Initial fetch
1919                container.dataset.selectedTopic = initialTopic;
1920                updateTopicLabel(initialTopic);
1921                fetchContent(containerId);
1922            }
1923        };
1924
1925        // Public API
1926        return {
1927            fetchContent,
1928            initialize: (containerId) => {
1929                const type = utils.getComponentType(containerId);
1930                if (type === 'search') {
1931                    initializeSearch(containerId);
1932                } else if (type === 'aggregator') {
1933                    initializeAggregator(containerId);
1934                }
1935            }
1936        };
1937    })();
1938
1939
1940    // ================================================================
1941    // Auto-initialize all content block components
1942    // ================================================================
1943
1944    document.addEventListener('DOMContentLoaded', () => {
1945        // Initialize all content block components (search + aggregator)
1946        const allContainers = document.querySelectorAll('[id^="diks-content-block-search-"], [id^="diks-content-block-aggregator-"]');
1947        allContainers.forEach(container => {
1948            DiksContentBlock.initialize(container.id);
1949        });
1950    });
1951</script>
vendor: 1 bytes, line 1951
1951
1952<script>
1953	// Service Worker
1954	if ('serviceWorker' in navigator) {
1955		window.addEventListener('load', function() {
1956			navigator.serviceWorker.register('/sw.js').then(
1957				function(registration) {
1958					console.log('PWA: Service worker registered to scope: ', registration.scope);
1959				},
1960				function(err) {
1961					console.error('PWA: Service worker failed to register with error: ', err);
1962				}
1963			);
1964		});
1965	}
1966
1967	// Show installation option, hide generic fallback instructions
1968	function pwaShowInstallationOption() {
1969		document.querySelectorAll('.js-diks-apps-pwa-installation').forEach(function(element) {
1970			element.style.display = 'block';
1971		});
1972		document.querySelectorAll('.js-diks-apps-pwa-instructions').forEach(function(element) {
1973			element.style.display = 'none';
1974		});
1975	}
1976
1977	let deferredPrompt;
1978	var dataLayer = window.dataLayer || [];
1979
1980	// Basic installation process
1981	window.addEventListener('beforeinstallprompt', (e) => {
1982		// Stash the event so it can be triggered later
1983		deferredPrompt = e;
1984
1985		const enablePrompt = 0;
1986
1987		if(!enablePrompt) {
1988			e.preventDefault();
1989		}
1990
1991		// Update the UI to notify the user they can install PWA
1992		pwaShowInstallationOption();
1993
1994		// Handle installation
1995		document.querySelectorAll('.js-diks-apps-pwa-installation-button').forEach(function(button) {
1996			button.addEventListener('click', (e) => {
1997				// Show the prompt
1998				deferredPrompt.prompt();
1999
2000				// Wait for user to respond
2001				deferredPrompt.userChoice.then((choiceResult) => {
2002					if (choiceResult.outcome === 'accepted') {
2003						console.log('PWA: Installed (prompt)');
2004						dataLayer.push({
2005							'event': 'PWA.installation',
2006							'eventData': 'success'
2007						});
2008					} else {
2009						console.log('PWA: User dismissed installation prompt');
2010						dataLayer.push({
2011							'event': 'PWA.installation',
2012							'eventData': 'canceled'
2013						});
2014					}
2015					deferredPrompt = null;
2016				});
2017			});
2018		});
2019	});
2020
2021	// iOS installation process (show instructions modal)
2022	if (!navigator.standalone) {
2023		var userAgent = navigator.userAgent.toLowerCase();
2024		var iPhoneUser = (/iphone/.test(userAgent));
2025		var iPadUser = (/ipad/.test(userAgent) || (/macintosh/.test(userAgent) && navigator.maxTouchPoints > 1));
2026		var safariUser = (/^(?!.*(brave|chrome|crios|duckduckgo|edgeios|firefox|fxios|opios|ucbrowser|yabrowser)).*safari.*$/.test(userAgent));
2027
2028		if (safariUser && (iPhoneUser || iPadUser)) {
2029			// Update the UI to notify the user they can install PWA
2030			pwaShowInstallationOption();
2031
2032			// Instructions
2033			var modals = document.querySelectorAll('.js-diks-apps-pwa-ios-instructions').forEach(function(element) {
2034				// Position on screen based on device
2035				if (iPhoneUser) {
2036					element.classList.add('diks-apps__pwa-ios-modal--bottom');
2037				} else if (iPadUser) {
2038					element.classList.add('diks-apps__pwa-ios-modal--top');
2039				}
2040			});
2041
2042			// Handle modal instructions from installation button
2043			document.querySelectorAll('.js-diks-apps-pwa-installation-button').forEach(function(button) {
2044				button.addEventListener('click', (e) => {
2045					// Show first modal
2046					document.querySelector('.js-diks-apps-pwa-ios-instructions').classList.toggle('diks-apps__pwa-ios-modal--is-visible');
2047					dataLayer.push({
2048						'event': 'PWA.instructions.shown',
2049						'eventData': 'iOS'
2050					});
2051				});
2052			});
2053		}
2054	}
2055</script>
2055
2056					
2056<script class="coral-script" src="//coral.prod.diks.fi/assets/js/count.js?v=9.3.1.3" defer></script>
2056
2057<div id="diks-bc-order-button" style="display: none;"></div>
2058			</body>
2059</html>
2060

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.