Explorar o código

Translation Finnish (#6954)

* Add Finnish translation

* Add missing translations

* Fixes

---------

Co-authored-by: Frans de Jonge <fransdejonge@gmail.com>
Co-authored-by: Alexandre Alapetite <alexandre@alapetite.fr>
Minna N. hai 1 ano
pai
achega
66cedacfec

+ 1 - 0
.typos.toml

@@ -19,6 +19,7 @@ extend-exclude = [
 	"app/i18n/el/",
 	"app/i18n/es/",
 	"app/i18n/fa/",
+	"app/i18n/fi/",
 	"app/i18n/fr/",
 	"app/i18n/he/",
 	"app/i18n/hu/",

+ 1 - 0
app/i18n/cs/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/de/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/el/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/en-us/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/en/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',
 		'es' => 'Español',
 		'fa' => 'فارسی',
+		'fi' => 'Suomi',
 		'fr' => 'Français',
 		'he' => 'עברית',
 		'hu' => 'Magyar',

+ 1 - 0
app/i18n/es/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/fa/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 239 - 0
app/i18n/fi/admin.php

@@ -0,0 +1,239 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'auth' => array(
+		'allow_anonymous' => 'Salli kirjautumattomien käyttäjien lukea oletuskäyttäjän artikkeleita (%s)',
+		'allow_anonymous_refresh' => 'Salli kirjautumattomien käyttäjien päivittää artikkelit',
+		'api_enabled' => 'Salli <abbr>API</abbr>-käyttö <small>(pakollinen kännykkäsovelluksille)</small>',
+		'form' => 'Web-lomake (perinteinen, käyttää JavaScriptiä)',
+		'http' => 'HTTP (tai HTTPS edistyneille käyttäjille)',
+		'none' => 'Ei mitään (vaarallinen)',
+		'title' => 'Todentaminen',
+		'token' => 'Todentamisen päätunnisteväline',
+		'token_help' => 'Sallii käyttäjän kaikkien RSS-tulosteiden käyttämisen sekä syötteiden päivityksen ilman todennusta:',
+		'type' => 'Todentamismenetelmä',
+		'unsafe_autologin' => 'Salli suojaamaton automaattinen sisäänkirjaus: ',
+	),
+	'check_install' => array(
+		'cache' => array(
+			'nok' => 'Tarkista hakemiston <em>./data/cache</em> oikeudet. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Cache-hakemiston oikeudet ovat oikein.',
+		),
+		'categories' => array(
+			'nok' => 'Luokkataulu on määritetty väärin.',
+			'ok' => 'Luokkataulu on määritetty oikein.',
+		),
+		'connection' => array(
+			'nok' => 'Tietokantayhteyden muodostus ei onnistu.',
+			'ok' => 'Tietokantayhteys on muodostettu.',
+		),
+		'ctype' => array(
+			'nok' => 'Merkkilajien tarkastukseen tarvittavaa kirjastoa (php-ctype) ei löydy.',
+			'ok' => 'Merkkilajien tarkastukseen tarvittava kirjasto (ctype) löytyy.',
+		),
+		'curl' => array(
+			'nok' => 'cURL-kirjastoa (php-curl-paketti) ei löydy.',
+			'ok' => 'cURL-kirjasto löytyy.',
+		),
+		'data' => array(
+			'nok' => 'Tarkista hakemiston <em>./data</em> oikeudet. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Data-hakemiston oikeudet ovat oikein.',
+		),
+		'database' => 'Tietokannan asennus',
+		'dom' => array(
+			'nok' => 'DOM-rakenteen selaamiseen tarvittavaa kirjastoa ei löydy (php-xml-paketti).',
+			'ok' => 'DOM-rakenteen selaamiseen tarvittava kirjasto löytyy.',
+		),
+		'entries' => array(
+			'nok' => 'Merkintöjen taulu on määritetty väärin.',
+			'ok' => 'Merkintöjen taulu on määritetty oikein.',
+		),
+		'favicons' => array(
+			'nok' => 'Tarkista hakemiston <em>./data/favicons</em> oikeudet. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Favicons-hakemiston oikeudet ovat oikein.',
+		),
+		'feeds' => array(
+			'nok' => 'Syötetaulu on määritetty väärin.',
+			'ok' => 'Syötetaulukko on määritetty oikein.',
+		),
+		'fileinfo' => array(
+			'nok' => 'PHP fileinfo -kirjastoa (fileinfo-paketti) ei löydy.',
+			'ok' => 'Fileinfo-kirjasto löytyy.',
+		),
+		'files' => 'Tiedostojen asennus',
+		'json' => array(
+			'nok' => 'JSON-tukea (php-json-paketti) ei löydy.',
+			'ok' => 'JSON-laajennus on käytössä.',
+		),
+		'mbstring' => array(
+			'nok' => 'Unicodea varten suositeltua mbstring-kirjastoa ei löydy.',
+			'ok' => 'Unicodea varten suositeltu mbstring-kirjasto löytyy.',
+		),
+		'pcre' => array(
+			'nok' => 'Säännöllisiä lausekkeita varten tarvittavaa kirjastoa (php-pcre) ei löydy.',
+			'ok' => 'Säännöllisiä lausekkeita varten tarvittava kirjasto (PCRE) löytyy.',
+		),
+		'pdo' => array(
+			'nok' => 'PDO:ta tai jotain tuettua ohjainta (pdo_mysql, pdo_sqlite, pdo_pgsql) ei löydy.',
+			'ok' => 'PDO ja ainakin yksi tuetuista ohjaimista (pdo_mysql, pdo_sqlite, pdo_pgsql) löytyy.',
+		),
+		'php' => array(
+			'_' => 'PHP-asennus',
+			'nok' => 'Asennettu PHP-versio on %s, mutta FreshRSS edellyttää vähintään versiota %s.',
+			'ok' => 'Asennettu PHP-versio (%s) on yhteensopiva FreshRSS-sovelluksen kanssa.',
+		),
+		'tables' => array(
+			'nok' => 'Tietokannasta puuttuu ainakin yksi taulu.',
+			'ok' => 'Kaikki tarvittavat taulut ovat tietokannassa.',
+		),
+		'title' => 'Asennuksen tarkistus',
+		'tokens' => array(
+			'nok' => 'Tarkista hakemiston <em>./data/tokens</em> oikeudet. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Tokens-hakemiston oikeudet ovat oikein.',
+		),
+		'users' => array(
+			'nok' => 'Tarkista hakemiston <em>./data/users</em> oikeudet. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Users-hakemiston oikeudet ovat oikein.',
+		),
+		'zip' => array(
+			'nok' => 'ZIP-laajennusta ei löydy (php-zip-paketti).',
+			'ok' => 'ZIP-laajennus on asennettu.',
+		),
+	),
+	'extensions' => array(
+		'author' => 'Tekijä',
+		'community' => 'Käytettävissä olevat yhteisön tekemät laajennukset',
+		'description' => 'Kuvaus',
+		'disabled' => 'Poissa käytöstä',
+		'empty_list' => 'Asennettuja laajennuksia ei ole',
+		'empty_list_help' => 'Voit tarkistaa lokeista, miksi laajennusluettelo on tyhjä.',
+		'enabled' => 'Käytössä',
+		'latest' => 'Asennettu',
+		'name' => 'Nimi',
+		'no_configure_view' => 'Tätä laajennusta ei voi määrittää.',
+		'system' => array(
+			'_' => 'Järjestelmälaajennukset',
+			'no_rights' => 'Järjestelmälaajennus (sinulla ei ole tarvittavia käyttöoikeuksia)',
+		),
+		'title' => 'Laajennukset',
+		'update' => 'Päivitys saatavilla',
+		'user' => 'Käyttäjän laajennukset',
+		'version' => 'Versio',
+	),
+	'stats' => array(
+		'_' => 'Tilastot',
+		'all_feeds' => 'Kaikki syötteet',
+		'category' => 'Luokka',
+		'entry_count' => 'Artikkelien määrä',
+		'entry_per_category' => 'Artikkelit luokan mukaan',
+		'entry_per_day' => 'Artikkelit päivän mukaan (edelliset 30 päivää)',
+		'entry_per_day_of_week' => 'Artikkelit viikonpäivän mukaan (keskiarvo: %.2f viestiä)',
+		'entry_per_hour' => 'Tunnin mukaan (keskiarvo: %.2f viestiä)',
+		'entry_per_month' => 'Kuukauden mukaan (keskiarvo: %.2f viestiä)',
+		'entry_repartition' => 'Artikkelien uudelleenjaottelu',
+		'feed' => 'Syöte',
+		'feed_per_category' => 'Syötteitä luokassa',
+		'idle' => 'Hiljentyneet syötteet',
+		'main' => 'Päätilastot',
+		'main_stream' => 'Pääsyötevirta',
+		'no_idle' => 'Hiljentyneitä syötteitä ei ole.',
+		'number_entries' => '%d artikkelia',
+		'percent_of_total' => '% kaikista',
+		'repartition' => 'Artikkelien uudelleenjaottelu',
+		'status_favorites' => 'Suosikit',
+		'status_read' => 'Luetut',
+		'status_total' => 'Yhteensä',
+		'status_unread' => 'Lukemattomat',
+		'title' => 'Tilastot',
+		'top_feed' => '10 parasta syötettä',
+	),
+	'system' => array(
+		'_' => 'Järjestelmän määritys',
+		'auto-update-url' => 'Automaattisen päivityksen palvelimen URL',
+		'base-url' => array(
+			'_' => 'URL-pääosoite',
+			'recommendation' => 'Automaattinen suositus: <kbd>%s</kbd>',
+		),
+		'cookie-duration' => array(
+			'help' => 'sekunteina',
+			'number' => 'Sisäänkirjauksen kesto',
+		),
+		'force_email_validation' => 'Pakota sähköpostiosoitteen vahvistus',
+		'instance-name' => 'Instanssin nimi',
+		'max-categories' => 'Luokkien enimmäismäärä käyttäjää kohti',
+		'max-feeds' => 'Syötteiden enimmäismäärä käyttäjää kohti',
+		'registration' => array(
+			'number' => 'Tilien enimmäismäärä',
+			'select' => array(
+				'label' => 'Rekisteröintilomake',
+				'option' => array(
+					'noform' => 'Poissa käytöstä: ei rekisteröintilomaketta',
+					'nolimit' => 'Käytössä: rajaton määrä tilejä',
+					'setaccountsnumber' => 'Määritä tilien enimmäismäärä',
+				),
+			),
+			'status' => array(
+				'disabled' => 'Lomake poissa käytöstä',
+				'enabled' => 'Lomake käytössä',
+			),
+			'title' => 'Käyttäjän rekisteröintilomake',
+		),
+		'sensitive-parameter' => 'Suojattu parametri. Muokkaa suoraan <kbd>./data/config.php</kbd>-tiedostossa.',
+		'tos' => array(
+			'disabled' => 'ei käytössä',
+			'enabled' => '<a href="./?a=tos">käytössä</a>',
+			'help' => 'Kuinka <a href="https://freshrss.github.io/FreshRSS/en/admins/12_User_management.html#enable-terms-of-service-tos" target="_blank">ottaa käyttöehdot käyttöön</a>',
+		),
+		'websub' => array(
+			'help' => 'Tietoja <a href="https://freshrss.github.io/FreshRSS/en/users/WebSub.html" target="_blank">WebSub</a>-palvelusta',
+		),
+	),
+	'update' => array(
+		'_' => 'Päivitä FreshRSS',
+		'apply' => 'Aloita päivitys',
+		'changelog' => 'Muutokset',
+		'check' => 'Tarkista päivitykset',
+		'copiedFromURL' => 'update.php kopioitu osoitteesta %s hakemistoon ./data',
+		'current_version' => 'Asennettu versio',
+		'last' => 'Viimeksi tarkistettu',
+		'loading' => 'Päivitetään…',
+		'none' => 'Päivitystä ei ole',
+		'releaseChannel' => array(
+			'_' => 'Julkaisukanava',
+			'edge' => 'Uusin versio (“edge”)',
+			'latest' => 'Vakaa versio (“latest”)',
+		),
+		'title' => 'Päivitä FreshRSS',
+		'viaGit' => 'Päivitys gitin ja GitHub.comin avulla on aloitettu',
+	),
+	'user' => array(
+		'admin' => 'Pääkäyttäjä',
+		'article_count' => 'Artikkeleita',
+		'back_to_manage' => '← Palaa käyttäjäluetteloon',
+		'create' => 'Luo uusi käyttäjä',
+		'database_size' => 'Tietokannan koko',
+		'email' => 'Sähköpostiosoite',
+		'enabled' => 'Käytössä',
+		'feed_count' => 'Syötteet',
+		'is_admin' => 'Pääkäyttäjä',
+		'language' => 'Kieli',
+		'last_user_activity' => 'Viimeisin käyttäjän toiminta',
+		'list' => 'Käyttäjäluettelo',
+		'number' => '%d tili on luotu',
+		'numbers' => '%d tiliä on luotu',
+		'password_form' => 'Salasana<br /><small>(Web-lomakkeella kirjautumista varten)</small>',
+		'password_format' => 'Vähintään 7 merkkiä',
+		'title' => 'Hallinnoi käyttäjiä',
+		'username' => 'Käyttäjätunnus',
+	),
+);

+ 333 - 0
app/i18n/fi/conf.php

@@ -0,0 +1,333 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'archiving' => array(
+		'_' => 'Arkistointi',
+		'exception' => 'Poiston poikkeukset',
+		'help' => 'Lisäasetuksia on yksittäisen syötteen asetuksissa',
+		'keep_favourites' => 'Älä koskaan poista suosikkeja',
+		'keep_labels' => 'Älä koskaan poista merkintöjä',
+		'keep_max' => 'Enimmäismäärä säilytettäviä artikkeleita syötettä kohti',
+		'keep_min_by_feed' => 'Vähimmäismäärä säilytettäviä artikkeleita syötettä kohti',
+		'keep_period' => 'Vanhimmat säilytettävät artikkelit',
+		'keep_unreads' => 'Älä koskaan poista lukemattomia artikkeleita',
+		'maintenance' => 'Ylläpito',
+		'optimize' => 'Optimoi tietokanta',
+		'optimize_help' => 'Voit pienentää tietokannan kokoa ajamalla toiminnon silloin tällöin',
+		'policy' => 'Poistokäytäntö',
+		'policy_warning' => 'Jos poistokäytäntöä ei ole valittu, kaikki artikkelit säilytetään.',
+		'purge_now' => 'Poista artikkelit nyt',
+		'title' => 'Arkistointi',
+		'ttl' => 'Älä päivitä automaattisesti useammin kuin',
+	),
+	'display' => array(
+		'_' => 'Näkymä',
+		'darkMode' => array(
+			'_' => 'Automaattinen tumma tila',
+			'auto' => 'Automaattinen',
+			'help' => 'Toimii vain yhteensopivissa teemoissa',
+			'no' => 'Ei',
+		),
+		'icon' => array(
+			'bottom_line' => 'Alin rivi',
+			'display_authors' => 'Kirjoittajat',
+			'entry' => 'Artikkelien kuvakkeet',
+			'publication_date' => 'Julkaisupäivä',
+			'related_tags' => 'Artikkelin tunnisteet',
+			'sharing' => 'Jakaminen',
+			'summary' => 'Yhteenveto',
+			'top_line' => 'Ylin rivi',
+		),
+		'language' => 'Kieli',
+		'notif_html5' => array(
+			'seconds' => 'sekuntia (0 - ei taukoa)',
+			'timeout' => 'Tauko HTML5-ilmoitusten välissä',
+		),
+		'show_nav_buttons' => 'Näytä siirtymispainikkeet',
+		'theme' => array(
+			'_' => 'Teema',
+			'deprecated' => array(
+				'_' => 'Vanhentunut',
+				'description' => 'Teema ei ole enää tuettu, eikä se ole enää käytettävissä <a href="https://freshrss.github.io/FreshRSS/en/users/05_Configuration.html#theme" target="_blank">tulevissa FreshRSS-versioissa</a>',
+			),
+		),
+		'theme_not_available' => 'Teema “%s” ei ole enää käytettävissä. Valitse toinen teema.',
+		'thumbnail' => array(
+			'label' => 'Pikkukuva',
+			'landscape' => 'Vaakasuunta',
+			'none' => 'Ei mitään',
+			'portrait' => 'Pystysuunta',
+			'square' => 'Neliö',
+		),
+		'timezone' => 'Aikavyöhyke',
+		'title' => 'Näkymä',
+		'website' => array(
+			'full' => 'Kuvake ja nimi',
+			'icon' => 'Vain kuvake',
+			'label' => 'Siuvsto',
+			'name' => 'Vain nimi',
+			'none' => 'Ei mitään',
+		),
+		'width' => array(
+			'content' => 'Sisällön leveys',
+			'large' => 'Leveä',
+			'medium' => 'Keskisuuri',
+			'no_limit' => 'Täysi leveys',
+			'thin' => 'Kapea',
+		),
+	),
+	'logs' => array(
+		'loglist' => array(
+			'level' => 'Lokien tarkkuus',
+			'message' => 'Lokiviesti',
+			'timestamp' => 'Aikaleima',
+		),
+		'pagination' => array(
+			'first' => 'Ensimmäinen',
+			'last' => 'Viimeinen',
+			'next' => 'Seuraava',
+			'previous' => 'Edellinen',
+		),
+	),
+	'privacy' => array(
+		'_' => 'Tietosuoja',
+		'retrieve_extension_list' => 'Nouda laajennusluettelo',
+	),
+	'profile' => array(
+		'_' => 'Profiilien hallinta',
+		'api' => 'API-hallinta',
+		'delete' => array(
+			'_' => 'Tilin poisto',
+			'warn' => 'Tilisi ja kaikki siihen kuuluvat tiedot poistetaan.',
+		),
+		'email' => 'Sähköpostiosoite',
+		'password_api' => 'API-salasana<br /><small>(esimerkiksi kännykkäsovelluksille)</small>',
+		'password_form' => 'Salasana<br /><small>(Web-lomakkeella kirjautumista varten)</small>',
+		'password_format' => 'Vähintään 7 merkkiä',
+		'title' => 'Profiili',
+	),
+	'query' => array(
+		'_' => 'Käyttäjän kyselyt',
+		'deprecated' => 'Kysely ei enää kelpaa. Siinä käytetty luokka tai syöte on poistettu.',
+		'description' => 'Kuvaus',
+		'filter' => array(
+			'_' => 'Suodatin käytössä:',
+			'categories' => 'Näytä luokan mukaan',
+			'feeds' => 'Näytä syötteen mukaan',
+			'order' => 'Lajittele päivämäärän mukaan',
+			'search' => 'Lauseke',
+			'shareOpml' => 'Jaa kyselyä vastaavat luokat ja syötteet OPML-muodossa',
+			'shareRss' => 'Jaa HTML &amp; RSS -muodossa',
+			'state' => 'Tila',
+			'tags' => 'Näytä merkinnän mukaan',
+			'type' => 'Laji',
+		),
+		'get_all' => 'Näytä kaikki artikkelit',
+		'get_all_labels' => 'Näytä artikkelit, joissa on mikä tahansa merkintä',
+		'get_category' => 'Näytä luokka “%s”',
+		'get_favorite' => 'Näytä suosikkiartikkelit',
+		'get_feed' => 'Näytä syöte “%s”',
+		'get_important' => 'Näytä artikkelit tärkeistä syötteistä',
+		'get_label' => 'Näytä artikkelit, joissa on merkintä “%s”',
+		'help' => 'Lisätietoja <a href="https://freshrss.github.io/FreshRSS/en/users/user_queries.html" target="_blank">käyttäjän kyselyistä ja edelleenjakamisesta HTML/RSS/OPML-muodossa</a> on ohjeessa.',
+		'image_url' => 'Kuvan URL',
+		'name' => 'Nimi',
+		'no_filter' => 'Ei suodatinta',
+		'number' => 'Kysely %d',
+		'order_asc' => 'Näytä vanhimmat artikkelit ensin',
+		'order_desc' => 'Näytä uusimmat artikkelit ensin',
+		'search' => 'Hae sanaa “%s”',
+		'share' => array(
+			'_' => 'Jaa kysely linkin avulla',
+			'greader' => 'Linkki GReader JSON -muotoon jaettavaksi',
+			'help' => 'Voit jakaa kyselyn muiden kanssa antamalle heille tämän linkin',
+			'html' => 'Jaettava linkki HTML-sivuun',
+			'opml' => 'Jaettava linkki syötteiden OPML-luetteloon',
+			'rss' => 'Jaettava linkki RSS-syötteeseen',
+		),
+		'state_0' => 'Näytä kaikki artikkelit',
+		'state_1' => 'Näytä luetut artikkelit',
+		'state_2' => 'Näytä lukemattomat artikkelit',
+		'state_3' => 'Näytä kaikki artikkelit',
+		'state_4' => 'Näytä suosikkiartikkelit',
+		'state_5' => 'Näytä luetut suosikkiartikkelit',
+		'state_6' => 'Näytä lukemattomat suosikkiartikkelit',
+		'state_7' => 'Näytä suosikkiartikkelit',
+		'state_8' => 'Näytä muut kuin suosikkiartikkelit',
+		'state_9' => 'Näytä luetut muut kuin suosikkiartikkelit',
+		'state_10' => 'Näytä lukemattomat muut kuin suosikkiartikkelit',
+		'state_11' => 'Näytä muut kuin suosikkiartikkelit',
+		'state_12' => 'Näytä kaikki artikkelit',
+		'state_13' => 'Näytä luetut artikkelit',
+		'state_14' => 'Näytä lukemattomat artikkelit',
+		'state_15' => 'Näytä kaikki artikkelit',
+		'title' => 'Käyttäjän kyselyt',
+	),
+	'reading' => array(
+		'_' => 'Lukeminen',
+		'after_onread' => 'Kun valitset “merkitse kaikki luetuiksi”',
+		'always_show_favorites' => 'Näytä oletusarvoisesti kaikki suosikkiartikkelit',
+		'apply_to_individual_feed' => 'Asetus vaikuttaa jokaiseen syötteeseen erikseen',
+		'article' => array(
+			'authors_date' => array(
+				'_' => 'Kirjoittajat ja päiväys',
+				'both' => 'Ylä- ja alatunnisteessa',
+				'footer' => 'Alatunnisteessa',
+				'header' => 'Ylätunnisteessa',
+				'none' => 'Älä näytä',
+			),
+			'feed_name' => array(
+				'above_title' => 'Otsikon/tunnisteiden yläpuolella',
+				'none' => 'Älä näytä',
+				'with_authors' => 'Kirjoittajien ja päiväysten rivillä',
+			),
+			'feed_title' => 'Syötteen otsikko',
+			'icons' => array(
+				'_' => 'Artikkelin kuvakkeiden asettelu<br /><small>(vain lukunäkymä)</small>',
+				'above_title' => 'Otsikon yläpuolella',
+				'with_authors' => 'Kirjoittajien ja päiväysten rivillä',
+			),
+			'tags' => array(
+				'_' => '#Tunnisteet',
+				'both' => 'Ylä- ja alatunnisteessa',
+				'footer' => 'Alatunnisteessa',
+				'header' => 'Ylätunnisteessa',
+				'none' => 'Älä näytä',
+			),
+			'tags_max' => array(
+				'_' => 'Enimmäismäärä näytettäviä tunnisteita',
+				'help' => '0 - näytä kaikki tunnisteet tiivistämättä',
+			),
+		),
+		'articles_per_page' => 'Artikkelien määrä sivulla',
+		'auto_load_more' => 'Lataa lisää artikkeleita sivun lopussa',
+		'auto_remove_article' => 'Piilota artikkelit lukemisen jälkeen',
+		'confirm_enabled' => 'Pyydä vahvistusta “merkitse kaikki luetuiksi” -toiminnoille',
+		'display_articles_unfolded' => 'Näytä artikkelit oletusarvoisesti kokonaan',
+		'display_categories_unfolded' => 'Luokat, joiden artikkelit näytetään kokonaan',
+		'headline' => array(
+			'articles' => 'Artikkelit: avaa/sulje',
+			'articles_header_footer' => 'Artikkelit: ylätunniste/alatunniste',
+			'categories' => 'Vasen siirtymisvalikko: luokat',
+			'mark_as_read' => 'Merkitse artikkeli luetuksi',
+			'misc' => 'Sekalaista',
+			'view' => 'Näkymä',
+		),
+		'hide_read_feeds' => 'Piilota luokat ja syötteet, joissa ei ole lukemattomia artikkeleita (ei toimi jos “Näytä kaikki artikkelit” on määritetty)',
+		'img_with_lazyload' => 'Lataa kuvat <em>vain tarvittaessa</em>',
+		'jump_next' => 'siirry seuraavaan lukemattomaan artikkeliin samassa näkymässä',
+		'mark_updated_article_unread' => 'Merkitse päivitetyt artikkelit lukemattomiksi',
+		'number_divided_when_reader' => 'Jaa kahdella lukunäkymässä.',
+		'read' => array(
+			'article_open_on_website' => 'kun artikkeli avataan alkuperäisellä sivustolla',
+			'article_viewed' => 'kun artikkeli näytetään',
+			'focus' => 'kun artikkeli valitaan (paitsi tärkeät syötteet)',
+			'keep_max_n_unread' => 'Lukemattomana pidettävien artikkelien enimmäismäärä',
+			'scroll' => 'vieritettäessä näkymää (paitsi tärkeät syötteet)',
+			'upon_gone' => 'kun artikkeli ei ole enää alkuperäisessä uutissyötteessä',
+			'upon_reception' => 'kun artikkeli on vastaanotettu',
+			'when' => 'Merkitse artikkeli luetuksi…',
+			'when_same_title_in_category' => 'jos jollakin luokan <i>n</i> uusimmalla artikkelilla on sama otsikko',
+			'when_same_title_in_feed' => 'jos jollakin syötteen <i>n</i> uusimmalla artikkelilla on sama otsikko',
+		),
+		'show' => array(
+			'_' => 'Näytettävät artikkelit',
+			'active_category' => 'Käytössä oleva luokka',
+			'adaptive' => 'Säädä näkymää',
+			'all_articles' => 'Näytä kaikki artikkelit',
+			'all_categories' => 'Kaikki luokat',
+			'no_category' => 'Ei luokkaa',
+			'remember_categories' => 'Muista avoinna olevat luokat',
+			'unread' => 'Näytä vain lukemattomat',
+		),
+		'show_fav_unread_help' => 'Koskee myös merkintöjä',
+		'sides_close_article' => 'Artikkeli sulkeutuu napsauttamalla sen ulkopuolelle',
+		'sort' => array(
+			'_' => 'Lajittelujärjestys',
+			'newer_first' => 'Uusimmat ensin',
+			'older_first' => 'Vanhimmat ensin',
+		),
+		'star' => array(
+			'when' => 'Merkitse artikkeli suosikiksi…',
+		),
+		'sticky_post' => 'Kiinnitä artikkeli ylimmäksi avattaessa',
+		'title' => 'Lukeminen',
+		'view' => array(
+			'default' => 'Oletusnäkymä',
+			'global' => 'Yleinen näkymä',
+			'normal' => 'Tavallinen näkymä',
+			'reader' => 'Lukunäkymä',
+		),
+	),
+	'sharing' => array(
+		'_' => 'Jakaminen',
+		'add' => 'Lisää jakamistapa',
+		'deprecated' => 'Tämä palvelu on vanhentunut, ja se poistetaan FreshRSS-sovelluksen <a href="https://freshrss.github.io/FreshRSS/en/users/08_sharing_services.html" title="Lisätietoja ohjeissa" target="_blank">tulevasta versiosta</a>.',
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Sähköposti',
+		'facebook' => 'Facebook',	// IGNORE
+		'more_information' => 'Lisätietoja',
+		'print' => 'Tulostus',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'remove' => 'Poista jakamistapa',
+		'shaarli' => 'Shaarli',	// IGNORE
+		'share_name' => 'Näytettävä jakamistavan nimi',
+		'share_url' => 'Käytettävä jakamistavan URL-osoite',
+		'title' => 'Jakaminen',
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag',	// IGNORE
+	),
+	'shortcut' => array(
+		'_' => 'Pikanäppäimet',
+		'article_action' => 'Artikkelitoiminnot',
+		'auto_share' => 'Jaa',
+		'auto_share_help' => 'Jos jakamistapoja on vain yksi, sitä käytetään automaattisesti. Muussa tapauksessa jakamistavan voi valita numerolla.',
+		'close_dropdown' => 'Sulje valikot',
+		'collapse_article' => 'Sulje',
+		'first_article' => 'Avaa ensimmäinen artikkeli',
+		'focus_search' => 'Siirry hakukenttään',
+		'global_view' => 'Vaihda yleiseen näkymään',
+		'help' => 'Avaa ohje',
+		'javascript' => 'Pikanäppäinten käyttö vaatii JavaScriptin',
+		'last_article' => 'Avaa viimeinen artikkeli',
+		'load_more' => 'Lataa lisää artikkeleita',
+		'mark_favorite' => 'Suosikki / Ei suosikki',
+		'mark_read' => 'Luettu / Lukematon',
+		'navigation' => 'Siirtyminen',
+		'navigation_help' => 'Kun <kbd>⇧ Shift</kbd> -näppäin on painettuna, siirtymisen pikanäppäimet koskevat syötteitä.<br/>Kun <kbd>Alt ⎇</kbd> -näppäin on painettuna, siirtymisen pikanäppäimet koskevat luokkia.',
+		'navigation_no_mod_help' => 'Seuraavat siirtymisen pikanäppäimet eivät tue Shift/Alt-näppäintoimintoa.',
+		'next_article' => 'Avaa seuraava artikkeli',
+		'next_unread_article' => 'Avaa seuraava lukematon artikkeli',
+		'non_standard' => 'Jotkin näppäimet (<kbd>%s</kbd>) eivät ehkä toimi pikanäppäiminä.',
+		'normal_view' => 'Vaihda normaaliin näkymään',
+		'other_action' => 'Muut toiminnot',
+		'previous_article' => 'Avaa edellinen artikkeli',
+		'reading_view' => 'Vaihda lukunäkymään',
+		'rss_view' => 'Avaa RSS-syötteenä',
+		'see_on_website' => 'Avaa alkuperäiseen sivustoon',
+		'shift_for_all_read' => '+ <kbd>Alt ⎇</kbd> - merkitse edelliset artikkelit luetuiksi<br />+ <kbd>⇧ Shift</kbd> - merkitse kaikki artikkelit luetuiksi',
+		'skip_next_article' => 'Siirry seuraavaan, mutta älä avaa',
+		'skip_previous_article' => 'Siirry edelliseen, mutta älä avaa',
+		'title' => 'Pikanäppäimet',
+		'toggle_media' => 'Toista/keskeytä media',
+		'user_filter' => 'Siirry käyttäjän kyselyihin',
+		'user_filter_help' => 'Jos kyselyitä on vain yksi, sitä käytetään automaattisesti. Muussa tapauksessa kyselyn voi valita numerolla.',
+		'views' => 'Näkymät',
+	),
+	'user' => array(
+		'articles_and_size' => '%s artikkelia (%s)',
+		'current' => 'Nykyinen käyttäjä',
+		'is_admin' => 'on pääkäyttäjä',
+		'users' => 'Käyttäjät',
+	),
+);

+ 146 - 0
app/i18n/fi/feedback.php

@@ -0,0 +1,146 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'access' => array(
+		'denied' => 'Sinulla ei ole tämän sivun käyttöoikeutta',
+		'not_found' => 'Etsimääsi sivua ei ole',
+	),
+	'admin' => array(
+		'optimization_complete' => 'Optimointi on valmis',
+	),
+	'api' => array(
+		'password' => array(
+			'failed' => 'Salasanaa ei voi muuttaa',
+			'updated' => 'Salasana on muutettu',
+		),
+	),
+	'auth' => array(
+		'login' => array(
+			'invalid' => 'Sisäänkirjaus epäonnistui',
+			'success' => 'Yhteys on muodostettu',
+		),
+		'logout' => array(
+			'success' => 'Yhteys on katkaistu',
+		),
+	),
+	'conf' => array(
+		'error' => 'Määritysten tallennuksessa ilmeni virhe',
+		'query_created' => 'Kysely “%s” on luotu.',
+		'shortcuts_updated' => 'Pikanäppäimet on päivitetty',
+		'updated' => 'Määritykset on päivitetty',
+	),
+	'extensions' => array(
+		'already_enabled' => '%s on jo käytössä',
+		'cannot_remove' => 'Laajennusta %s ei voi poistaa',
+		'disable' => array(
+			'ko' => 'Laajennusta %s ei voi poistaa käytöstä. Lisätietoja on <a href="%s">FreshRSS-lokeissa</a>.',
+			'ok' => '%s on nyt poistettu käytöstä',
+		),
+		'enable' => array(
+			'ko' => 'Laajennusta %s ei voi ottaa käyttöön. Lisätietoja on <a href="%s">FreshRSS-lokeissa</a>.',
+			'ok' => '%s on nyt otettu käyttöön',
+		),
+		'no_access' => 'Sinulla ei ole laajennuksen %s käyttöoikeutta',
+		'not_enabled' => 'Laajennus %s ei ole käytössä',
+		'not_found' => 'Laajennusta %s ei ole',
+		'removed' => '%s on poistettu',
+	),
+	'import_export' => array(
+		'export_no_zip_extension' => 'ZIP-laajennusta ei löydy palvelimesta. Vie tiedostot yksitellen.',
+		'feeds_imported' => 'Syötteet on tuotu palveluun. Jos kaikki haluamasi syötteet on tuotu, voit nyt napsauttaa <i>Päivitä syötteet</i> -painiketta.',
+		'feeds_imported_with_errors' => 'Syötteet on tuotu palveluun, mutta tuonnissa ilmeni virheitä. Jos kaikki haluamasi syötteet on tuotu, voit nyt napsauttaa <i>Päivitä syötteet</i> -painiketta.',
+		'file_cannot_be_uploaded' => 'Tiedoston siirto palvelimeen ei onnistu!',
+		'no_zip_extension' => 'ZIP-laajennusta ei löydy palvelimesta.',
+		'zip_error' => 'ZIP-käsittelyssä on ilmennyt virhe.',
+	),
+	'profile' => array(
+		'error' => 'Profiilia ei voi muokata',
+		'updated' => 'Profiilia on muokattu',
+	),
+	'sub' => array(
+		'actualize' => 'Päivitetään',
+		'articles' => array(
+			'marked_read' => 'Valitut artikkelit on merkitty luetuiksi.',
+			'marked_unread' => 'Artikkelit on merkitty lukemattomiksi.',
+		),
+		'category' => array(
+			'created' => 'Luokka %s on luotu.',
+			'deleted' => 'Luokka on poistettu.',
+			'emptied' => 'Luokka on tyhjennetty',
+			'error' => 'Luokan päivitys ei onnistu',
+			'name_exists' => 'Luokan nimi on jo käytössä.',
+			'no_id' => 'Määritä luokan tunnus.',
+			'no_name' => 'Luokan nimi ei voi olla tyhjä.',
+			'not_delete_default' => 'Oletusluokkaa ei voi poistaa.',
+			'not_exist' => 'Luokkaa ei ole.',
+			'over_max' => 'Enimmäismäärä luokkia on luotu (%d)',
+			'updated' => 'Luokka on päivitetty.',
+		),
+		'feed' => array(
+			'actualized' => '<em>%s</em> on päivitetty',
+			'actualizeds' => 'RSS-syötteet on päivitetty',
+			'added' => 'RSS-syöte <em>%s</em> on lisätty',
+			'already_subscribed' => 'Olet jo tilannut syötteen <em>%s</em>',
+			'cache_cleared' => 'Välimuisti <em>%s</em> on tyhjennetty',
+			'deleted' => 'Syöte on poistettu',
+			'error' => 'Syötteen päivitys ei onnistu',
+			'internal_problem' => 'Uutissyötettä ei voinut lisätä. Lisätietoja on <a href="%s">FreshRSS-lokeissa</a>. Voit yrittää pakottaa lisäämisen liittämällä tekstin <code>#force_feed</code> URL-osoitteen loppuun.',
+			'invalid_url' => 'URL-osoite <em>%s</em> on virheellinen',
+			'n_actualized' => '%d syötettä on päivitetty',
+			'n_entries_deleted' => '%d artikkelia on poistettu',
+			'no_refresh' => 'Päivitettäviä syötteitä ei ole',
+			'not_added' => 'Syötteen <em>%s</em> lisäys ei onnistunut',
+			'not_found' => 'Syötettä ei löydy',
+			'over_max' => 'Enimmäismäärä syötteitä on lisätty (%d)',
+			'reloaded' => '<em>%s</em> on ladattu uudelleen',
+			'selector_preview' => array(
+				'http_error' => 'Sivuston sisällön lataus epäonnistui.',
+				'no_entries' => 'Syötteessä ei ole artikkeleita. Tarvitset ainakin yhden artikkelin luodaksesi esikatselun.',
+				'no_feed' => 'Sisäinen virhe (syötettä ei löydy).',
+				'no_result' => 'Valitsin ei vastannut mitään sisältöä. Varatoimena näytetään alkuperäisen syötteen teksti.',
+				'selector_empty' => 'Valitsin on tyhjä. Määritä ainakin yksi valitsin luodaksesi esikatselun.',
+			),
+			'updated' => 'Syöte on päivitetty',
+		),
+		'purge_completed' => 'Tyhjennys on valmis (%d artikkelia poistettu)',
+	),
+	'tag' => array(
+		'created' => 'Merkintä “%s” on luotu.',
+		'error' => 'Merkinnän päivitys ei onnistunut.',
+		'name_exists' => 'Samanniminen merkintä on lisätty aiemmin.',
+		'renamed' => 'Merkintä “%s” on nimetty uudelleen: “%s”.',
+		'updated' => 'Merkintä on päivitetty.',
+	),
+	'update' => array(
+		'can_apply' => 'FreshRSS-sovellukseen on saatavissa päivitys: <strong>versio %s</strong>.',
+		'error' => 'Päivityksessä on ilmennyt virhe: %s',
+		'file_is_nok' => 'FreshRSS-sovellukseen on saatavissa päivitys (<strong>version %s</strong>), mutta tarkista hakemiston <em>%s</em> oikeudet. HTTP-palvelimella on oltava kirjoitusoikeus.',
+		'finished' => 'Päivitys on valmis!',
+		'none' => 'Päivitystä ei ole saatavilla',
+		'server_not_found' => 'Päivityspalvelinta ei löydy. [%s]',
+	),
+	'user' => array(
+		'created' => array(
+			'_' => 'Käyttäjä %s on luotu',
+			'error' => 'Käyttäjän %s luonti ei onnistu',
+		),
+		'deleted' => array(
+			'_' => 'Käyttäjä %s on poistettu',
+			'error' => 'Käyttäjän %s poisto ei onnistu',
+		),
+		'updated' => array(
+			'_' => 'Käyttäjä %s on päivitetty',
+			'error' => 'Käyttäjää %s ei ole päivitetty',
+		),
+	),
+);

+ 260 - 0
app/i18n/fi/gen.php

@@ -0,0 +1,260 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'action' => array(
+		'actualize' => 'Päivitä syötteet',
+		'add' => 'Lisää',
+		'back' => '← Palaa',
+		'back_to_rss_feeds' => '← Palaa RSS-syötteisiin',
+		'cancel' => 'Peruuta',
+		'create' => 'Luo',
+		'delete_muted_feeds' => 'Poista vaimennetut syötteet',
+		'demote' => 'Laske tärkeyttä',
+		'disable' => 'Poista käytöstä',
+		'download' => 'Lataa',
+		'empty' => 'Tyhjennä',
+		'enable' => 'Ota käyttöön',
+		'export' => 'Vie',
+		'filter' => 'Suodata',
+		'import' => 'Tuo',
+		'load_default_shortcuts' => 'Lataa oletuspikanäppäimet',
+		'manage' => 'Hallinnoi',
+		'mark_read' => 'Merkitse luetuksi',
+		'menu' => array(
+			'open' => 'Avaa valikko',
+		),
+		'nav_buttons' => array(
+			'next' => 'Seuraava artikkeli',
+			'prev' => 'Edellinen artikkeli',
+			'up' => 'Siirry ylöspäin',
+		),
+		'open_url' => 'Avaa URL-osoite',
+		'promote' => 'Nosta tärkeyttä',
+		'purge' => 'Tyhjennä',
+		'refresh_opml' => 'Päivitä OPML',
+		'remove' => 'Poista',
+		'rename' => 'Nimeä uudelleen',
+		'see_website' => 'Siirry sivustolle',
+		'submit' => 'Lähetä',
+		'truncate' => 'Poista kaikki artikkelit',
+		'update' => 'Päivitä',
+	),
+	'auth' => array(
+		'accept_tos' => 'Hyväksyn <a href="%s">käyttöehdot</a>.',
+		'email' => 'Sähköpostiosoite',
+		'keep_logged_in' => 'Pidä minut kirjautuneena <small>(%s päivää)</small>',
+		'login' => 'Kirjaudu sisään',
+		'logout' => 'Kirjaudu ulos',
+		'password' => array(
+			'_' => 'Salasana',
+			'format' => '<small>Vähintään 7 merkkiä</small>',
+		),
+		'registration' => array(
+			'_' => 'Uusi tili',
+			'ask' => 'Haluatko luoda tilin?',
+			'title' => 'Tilin luonti',
+		),
+		'username' => array(
+			'_' => 'Käyttäjätunnus',
+			'format' => '<small>Enintään 16 aakkosnumeerista merkkiä</small>',
+		),
+	),
+	'date' => array(
+		'Apr' => '\\h\\u\\h\\t\\i\\k\\u\\u',
+		'Aug' => '\\e\\l\\o\\k\\u\\u',
+		'Dec' => '\\j\\o\\u\\l\\u\\k\\u\\u',
+		'Feb' => '\\h\\e\\l\\m\\i\\k\\u\\u',
+		'Jan' => '\\t\\a\\m\\m\\i\\k\\u\\u',
+		'Jul' => '\\h\\e\\i\\n\\ä\\k\\u\\u',
+		'Jun' => '\\k\\e\\s\\ä\\k\\u\\u',
+		'Mar' => '\\m\\a\\a\\l\\i\\s\\k\\u\\u',
+		'May' => '\\t\\o\\u\\k\\o\\k\\u\\u',
+		'Nov' => '\\m\\a\\r\\r\\a\\s\\k\\u\\u',
+		'Oct' => '\\l\\o\\k\\a\\k\\u\\u',
+		'Sep' => '\\s\\y\\y\\s\\k\\u\\u',
+		'apr' => 'huhti',
+		'april' => 'huhtikuu',
+		'aug' => 'elo',
+		'august' => 'elokuu',
+		'before_yesterday' => 'Ennen eilistä',
+		'dec' => 'joulu',
+		'december' => 'joulukuu',
+		'feb' => 'helmi',
+		'february' => 'helmikuu',
+		'format_date' => 'j\\. %s\\t\\a Y',
+		'format_date_hour' => 'j\\. %s\\t\\a Y klo H\\:i',
+		'fri' => 'pe',
+		'jan' => 'tammi',
+		'january' => 'tammikuu',
+		'jul' => 'heinä',
+		'july' => 'heinäkuu',
+		'jun' => 'kesä',
+		'june' => 'kesäkuu',
+		'last_2_year' => 'Edelliset kaksi vuotta',
+		'last_3_month' => 'Edelliset kolme kuukautta',
+		'last_3_year' => 'Edelliset kolme vuotta',
+		'last_5_year' => 'Edelliset viisi vuotta',
+		'last_6_month' => 'Edelliset kuusi kuukautta',
+		'last_month' => 'Viime kuukausi',
+		'last_week' => 'Viime viikko',
+		'last_year' => 'Viime vuosi',
+		'mar' => 'maalis',
+		'march' => 'maaliskuu',
+		'may' => 'touko',
+		'may_' => 'toukokuu',
+		'mon' => 'ma',
+		'month' => 'kuukautta',
+		'nov' => 'marras',
+		'november' => 'marraskuu',
+		'oct' => 'loka',
+		'october' => 'lokakuu',
+		'sat' => 'la',
+		'sep' => 'syys',
+		'september' => 'syyskuu',
+		'sun' => 'su',
+		'thu' => 'to',
+		'today' => 'Tänään',
+		'tue' => 'ti',
+		'wed' => 'ke',
+		'yesterday' => 'Eilen',
+	),
+	'dir' => 'ltr',	// IGNORE
+	'freshrss' => array(
+		'_' => 'FreshRSS',	// IGNORE
+		'about' => 'Tietoja FreshRSS-sovelluksesta',
+	),
+	'js' => array(
+		'category_empty' => 'Tyhjennä luokka',
+		'confirm_action' => 'Haluatko varmasti toteuttaa toiminnon? Sitä ei voi peruuttaa!',
+		'confirm_action_feed_cat' => 'Haluatko varmasti toteuttaa toiminnon? Luokkaan kuuluvat suosikit ja kyselyt poistetaan. Tätä ei voi peruuttaa!',
+		'feedback' => array(
+			'body_new_articles' => 'FreshRSS-sovelluksessa on %%d uutta artikkelia luettavana.',
+			'body_unread_articles' => '(lukematta: %%d)',
+			'request_failed' => 'Pyyntö epäonnistui. Internetyhteydessä on ehkä ollut ongelmia.',
+			'title_new_articles' => 'FreshRSS: uusia artikkeleita!',
+		),
+		'labels_empty' => 'Ei tunnisteita',
+		'new_article' => 'Uusia artikkeleita on saatavilla. Päivitä sivu napsauttamalla.',
+		'should_be_activated' => 'JavaScriptin on oltava käytössä',
+	),
+	'lang' => array(
+		'cs' => 'Čeština',	// IGNORE
+		'de' => 'Deutsch',	// IGNORE
+		'el' => 'Ελληνικά',	// IGNORE
+		'en' => 'English',	// IGNORE
+		'en-us' => 'English (United States)',	// IGNORE
+		'es' => 'Español',	// IGNORE
+		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
+		'fr' => 'Français',	// IGNORE
+		'he' => 'עברית',	// IGNORE
+		'hu' => 'Magyar',	// IGNORE
+		'id' => 'Bahasa Indonesia',	// IGNORE
+		'it' => 'Italiano',	// IGNORE
+		'ja' => '日本語',	// IGNORE
+		'ko' => '한국어',	// IGNORE
+		'lv' => 'Latviešu',	// IGNORE
+		'nl' => 'Nederlands',	// IGNORE
+		'oc' => 'Occitan',	// IGNORE
+		'pl' => 'Polski',	// IGNORE
+		'pt-br' => 'Português (Brasil)',	// IGNORE
+		'ru' => 'Русский',	// IGNORE
+		'sk' => 'Slovenčina',	// IGNORE
+		'tr' => 'Türkçe',	// IGNORE
+		'zh-cn' => '简体中文',	// IGNORE
+		'zh-tw' => '正體中文',	// IGNORE
+	),
+	'menu' => array(
+		'about' => 'Tietoja',
+		'account' => 'Tili',
+		'admin' => 'Hallinta',
+		'archiving' => 'Arkistointi',
+		'authentication' => 'Todentaminen',
+		'check_install' => 'Asennuksen tarkistus',
+		'configuration' => 'Määritys',
+		'display' => 'Näkymä',
+		'extensions' => 'Laajennukset',
+		'logs' => 'Lokit',
+		'privacy' => 'Tietosuoja',
+		'queries' => 'Käyttäjän kyselyt',
+		'reading' => 'Lukeminen',
+		'search' => 'Hae sanoja tai #tunnisteita',
+		'search_help' => 'Ohjeessa on tietoja <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">haun lisäparametreista</a>',
+		'sharing' => 'Jakaminen',
+		'shortcuts' => 'Pikanäppäimet',
+		'stats' => 'Tilastot',
+		'system' => 'Järjestelmän määritys',
+		'update' => 'Päivitys',
+		'user_management' => 'Hallinnoi käyttäjiä',
+		'user_profile' => 'Profiili',
+	),
+	'period' => array(
+		'days' => 'päivää',
+		'hours' => 'tuntia',
+		'months' => 'kuukautta',
+		'weeks' => 'viikkoa',
+		'years' => 'vuotta',
+	),
+	'share' => array(
+		'Known' => 'Known-sivustot',
+		'archiveIS' => 'archive.is',	// IGNORE
+		'archiveORG' => 'archive.org',	// IGNORE
+		'archivePH' => 'archive.ph',	// IGNORE
+		'buffer' => 'Buffer',	// IGNORE
+		'clipboard' => 'Clipboard',	// IGNORE
+		'diaspora' => 'Diaspora*',	// IGNORE
+		'email' => 'Sähköposti',
+		'email-webmail-firefox-fix' => 'Sähköposti (webposti - korjaus Firefoxia varten)',
+		'facebook' => 'Facebook',	// IGNORE
+		'gnusocial' => 'GNU social',	// IGNORE
+		'jdh' => 'Journal du hacker',	// IGNORE
+		'lemmy' => 'Lemmy',	// IGNORE
+		'linkding' => 'Linkding',	// IGNORE
+		'linkedin' => 'LinkedIn',	// IGNORE
+		'mastodon' => 'Mastodon',	// IGNORE
+		'movim' => 'Movim',	// IGNORE
+		'omnivore' => 'Omnivore',	// IGNORE
+		'pinboard' => 'Pinboard',	// IGNORE
+		'pinterest' => 'Pinterest',	// IGNORE
+		'pocket' => 'Pocket',	// IGNORE
+		'print' => 'Tulostus',
+		'raindrop' => 'Raindrop.io',	// IGNORE
+		'reddit' => 'Reddit',	// IGNORE
+		'shaarli' => 'Shaarli',	// IGNORE
+		'telegram' => 'Telegram',	// IGNORE
+		'twitter' => 'Twitter',	// IGNORE
+		'wallabag' => 'wallabag v1',	// IGNORE
+		'wallabagv2' => 'wallabag v2',	// IGNORE
+		'web-sharing-api' => 'Järjestelmän oma jakovalikko',
+		'whatsapp' => 'WhatsApp',
+		'xing' => 'Xing',	// IGNORE
+	),
+	'short' => array(
+		'attention' => 'Varoitus!',
+		'blank_to_disable' => 'Poista käytöstä jättämällä tämä tyhjäksi',
+		'by_author' => 'Kirjoittaja:',
+		'by_default' => 'Oletusarvo',
+		'damn' => 'Pahus!',
+		'default_category' => 'Luokittelematon',
+		'no' => 'Ei',
+		'not_applicable' => 'Ei käytettävissä',
+		'ok' => 'Selvä!',
+		'or' => 'tai',
+		'yes' => 'Kyllä',
+	),
+	'stream' => array(
+		'load_more' => 'Lataa lisää artikkeleita',
+		'mark_all_read' => 'Merkitse kaikki luetuiksi',
+		'nothing_to_load' => 'Artikkeleita ei ole enempää',
+	),
+);

+ 76 - 0
app/i18n/fi/index.php

@@ -0,0 +1,76 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'about' => array(
+		'_' => 'Tietoja',
+		'agpl3' => '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',	// IGNORE
+		'bugs_reports' => 'Virheraportit',
+		'credits' => 'Tekijät',
+		'credits_content' => 'Jotkin suunnitteluelementit perustuvat <a href="http://twitter.github.io/bootstrap/">Bootstrapiin</a>, mutta FreshRSS ei käytä tätä kehystä. <a href="https://gitlab.gnome.org/Archive/gnome-icon-theme-symbolic">Kuvakkeet</a> tulevat <a href="https://www.gnome.org/">GNOME-projektista</a>. <em>Open Sans</em> -fontin on luonut <a href="https://fonts.google.com/specimen/Open+Sans">Steve Matteson</a>. FreshRSS perustuu PHP-kehykseen <a href="https://framagit.org/marienfressinaud/MINZ">Minz</a>.',
+		'documentation' => 'Ohjeet',
+		'freshrss_description' => 'FreshRSS on itse asennettava RSS-syötteiden luku- ja hallintaohjelma. Sen avulla voit helposti lukea ja seurata useita uutissivustoja yhdessä näkymässä, eikä sinun tarvitse siirtyä sivustolta toiselle. FreshRSS on kevyt, muokattavissa ja helppokäyttöinen.',
+		'github' => '<a href="https://github.com/FreshRSS/FreshRSS/issues">GitHubissa</a>',
+		'license' => 'Käyttöoikeus',
+		'project_website' => 'Projektin sivusto',
+		'title' => 'Tietoja',
+		'version' => 'Versio',
+	),
+	'feed' => array(
+		'empty' => 'Näytettäviä artikkeleita ei ole.',
+		'rss_of' => 'Sivuston %s RSS-syöte',
+		'title' => 'Pääsyötevirta',
+		'title_fav' => 'Suosikit',
+		'title_global' => 'Yleisnäkymä',
+	),
+	'log' => array(
+		'_' => 'Lokit',
+		'clear' => 'Tyhjennä lokit',
+		'empty' => 'Lokitiedosto on tyhjä',
+		'title' => 'Lokit',
+	),
+	'menu' => array(
+		'about' => 'Tietoja FreshRSS-sovelluksesta',
+		'before_one_day' => 'Vanhemmat kuin yksi päivä',
+		'before_one_week' => 'Vanhemmat kuin yksi viikko',
+		'bookmark_query' => 'Tallenna tämä kysely kirjanmerkiksi',
+		'favorites' => 'Suosikit (%s)',
+		'global_view' => 'Yleisnäkymä',
+		'important' => 'Tärkeät syötteet',
+		'main_stream' => 'Pääsyötevirta',
+		'mark_all_read' => 'Merkitse kaikki luetuiksi',
+		'mark_cat_read' => 'Merkitse luokka luetuksi',
+		'mark_feed_read' => 'Merkitse syöte luetuksi',
+		'mark_selection_unread' => 'Merkitse valitut lukemattomiksi',
+		'newer_first' => 'Uusin ensin',
+		'non-starred' => 'Näytä muut kuin suosikit',
+		'normal_view' => 'Tavallinen näkymä',
+		'older_first' => 'Vanhin ensin',
+		'queries' => 'Käyttäjän tekemät kyselyt',
+		'read' => 'Näytä luetut',
+		'reader_view' => 'Lukunäkymä',
+		'rss_view' => 'RSS-syöte',
+		'search_short' => 'Haku',
+		'starred' => 'Näytä suosikit',
+		'stats' => 'Tilastot',
+		'subscription' => 'Tilausten hallinta',
+		'tags' => 'Omat tunnisteet',
+		'unread' => 'Näytä lukemattomat',
+	),
+	'share' => 'Jaa',
+	'tag' => array(
+		'related' => 'Artikkelin tunnisteet',
+	),
+	'tos' => array(
+		'title' => 'Käyttöehdot',
+	),
+);

+ 136 - 0
app/i18n/fi/install.php

@@ -0,0 +1,136 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'action' => array(
+		'finish' => 'Tee asennus loppuun',
+		'fix_errors_before' => 'Korjaa kaikki virheet, ennen kuin siirryt seuraavaan vaiheeseen.',
+		'keep_install' => 'Säilytä edelliset määritykset',
+		'next_step' => 'Siirry seuraavaan vaiheeseen',
+		'reinstall' => 'Asenna FreshRSS uudelleen',
+	),
+	'auth' => array(
+		'form' => 'Web-lomake (perinteinen, käyttää JavaScriptiä)',
+		'http' => 'HTTP (tai HTTPS edistyneille käyttäjille)',
+		'none' => 'Ei mitään (vaarallinen)',
+		'password_form' => 'Salasana<br /><small>(Web-lomakkeella kirjautumista varten)</small>',
+		'password_format' => 'Vähintään 7 merkkiä',
+		'type' => 'Todentamismenetelmä',
+	),
+	'bdd' => array(
+		'_' => 'Tietokanta',
+		'conf' => array(
+			'_' => 'Tietokannan määritys',
+			'ko' => 'Tarkista tietokannan määritys.',
+			'ok' => 'Tietokannan määritys on tallennettu.',
+		),
+		'host' => 'Palvelin',
+		'password' => 'Tietokannan salasana',
+		'prefix' => 'Taulun etuliite',
+		'type' => 'Tietokannan laji',
+		'username' => 'Tietokantakäyttäjän tunnus',
+	),
+	'check' => array(
+		'_' => 'Tarkistukset',
+		'already_installed' => 'FreshRSS on jo asennettu!',
+		'cache' => array(
+			'nok' => 'Tarkista käyttäjän <em>%2$s</em> oikeudet hakemistoon <em>%1$s</em>. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Cache-hakemiston oikeudet ovat oikein.',
+		),
+		'ctype' => array(
+			'nok' => 'Merkkilajien tarkastukseen tarvittavaa kirjastoa (php-ctype) ei löydy.',
+			'ok' => 'Merkkilajien tarkastukseen tarvittava kirjasto (ctype) löytyy.',
+		),
+		'curl' => array(
+			'nok' => 'cURL-kirjastoa (php-curl-paketti) ei löydy.',
+			'ok' => 'cURL-kirjasto löytyy.',
+		),
+		'data' => array(
+			'nok' => 'Tarkista käyttäjän <em>%2$s</em> oikeudet hakemistoon <em>%1$s</em>. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Data-hakemiston oikeudet ovat oikein.',
+		),
+		'dom' => array(
+			'nok' => 'DOM-rakenteen selaamiseen tarvittavaa kirjastoa ei löydy.',
+			'ok' => 'DOM-rakenteen selaamiseen tarvittava kirjasto löytyy.',
+		),
+		'favicons' => array(
+			'nok' => 'Tarkista käyttäjän <em>%2$s</em> oikeudet hakemistoon <em>%1$s</em>. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Favicons-hakemiston oikeudet ovat oikein.',
+		),
+		'fileinfo' => array(
+			'nok' => 'PHP fileinfo -kirjastoa (fileinfo-paketti) ei löydy.',
+			'ok' => 'Fileinfo-kirjasto löytyy.',
+		),
+		'json' => array(
+			'nok' => 'JSON-sisällön jäsentämiseen suositeltua kirjastoa ei löydy.',
+			'ok' => 'JSON-sisällön jäsentämiseen suositeltu kirjasto löytyy.',
+		),
+		'mbstring' => array(
+			'nok' => 'Unicodea varten suositeltua mbstring-kirjastoa ei löydy.',
+			'ok' => 'Unicodea varten suositeltu mbstring-kirjasto löytyy.',
+		),
+		'pcre' => array(
+			'nok' => 'Säännöllisiä lausekkeita varten tarvittavaa kirjastoa (php-pcre) ei löydy.',
+			'ok' => 'Säännöllisiä lausekkeita varten tarvittava kirjasto (PCRE) löytyy.',
+		),
+		'pdo' => array(
+			'nok' => 'PDO:ta tai jotain tuettua ohjainta (pdo_mysql, pdo_sqlite, pdo_pgsql) ei löydy.',
+			'ok' => 'PDO ja ainakin yksi tuetuista ohjaimista (pdo_mysql, pdo_sqlite, pdo_pgsql) löytyy.',
+		),
+		'php' => array(
+			'nok' => 'Asennettu PHP-versio on %s, mutta FreshRSS edellyttää vähintään versiota %s.',
+			'ok' => 'Asennettu PHP-versio, %s, on yhteensopiva FreshRSS-sovelluksen kanssa.',
+		),
+		'reload' => 'Tarkista uudelleen',
+		'tmp' => array(
+			'nok' => 'Tarkista käyttäjän <em>%2$s</em> oikeudet hakemistoon <em>%1$s</em>. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Temp-hakemiston oikeudet ovat oikein.',
+		),
+		'unknown_process_username' => 'tuntematon',
+		'users' => array(
+			'nok' => 'Tarkista käyttäjän <em>%2$s</em> oikeudet hakemistoon <em>%1$s</em>. HTTP-palvelimella on oltava kirjoitusoikeus.',
+			'ok' => 'Users-hakemiston oikeudet ovat oikein.',
+		),
+		'xml' => array(
+			'nok' => 'XML-sisällön jäsentämiseen tarvittavaa kirjastoa ei löydy.',
+			'ok' => 'XML-sisällön jäsentämiseen tarvittava kirjasto löytyy.',
+		),
+	),
+	'conf' => array(
+		'_' => 'Yleinen määritykset',
+		'ok' => 'Yleiset määritykset on tallennettu.',
+	),
+	'congratulations' => 'Onneksi olkoon!',
+	'default_user' => array(
+		'_' => 'Oletuskäyttäjän käyttäjätunnus',
+		'max_char' => 'Enintään 16 aakkosnumeerista merkkiä',
+	),
+	'fix_errors_before' => 'Korjaa virheet, ennen kuin siirryt seuraavaan vaiheeseen.',
+	'javascript_is_better' => 'FreshRSS-sovellusta on miellyttävämpi käyttää, kun JavaScript on käytössä',
+	'js' => array(
+		'confirm_reinstall' => 'Jos asennat FreshRSS-sovelluksen uudelleen, menetät kaikki aiemmin tekemäsi määritykset. Haluatko varmasti jatkaa?',
+	),
+	'language' => array(
+		'_' => 'Kieli',
+		'choose' => 'Valitse FreshRSS-sovelluksen kieli',
+		'defined' => 'Kieli on määritetty.',
+	),
+	'missing_applied_migrations' => 'Jotain meni pieleen. Luo tyhjä tiedosto <em>%s</em> itse.',
+	'ok' => 'Asennus onnistui.',
+	'session' => array(
+		'nok' => 'Web-palvelinta ei ole määritetty oikein PHP-istuntojen tarvitsemia evästeitä varten.',
+	),
+	'step' => 'vaihe %d',
+	'steps' => 'Vaiheet',
+	'this_is_the_end' => 'Asennus päättyy tähän',
+	'title' => 'Asennus · FreshRSS',
+);

+ 293 - 0
app/i18n/fi/sub.php

@@ -0,0 +1,293 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'api' => array(
+		'documentation' => 'Kopioi seuraava URL-osoite, niin voit käyttää sitä ulkoisessa työkalussa.',
+		'title' => 'API',	// IGNORE
+	),
+	'bookmarklet' => array(
+		'documentation' => 'Vedä tämä painike kirjanmerkkien työkalupalkkiin tai napsauta sitä hiiren kakkospainikkeella ja valitse Bookmark This Link (Tallenna linkki kirjanmerkkeihin). Napsauta sitten Tilaa-painiketta millä tahansa sivulla, jonka päivityksiä haluat seurata.',
+		'label' => 'Tilaa',
+		'title' => 'Kirjanmerkkisovelma',
+	),
+	'category' => array(
+		'_' => 'Luokka',
+		'add' => 'Lisää luokka',
+		'archiving' => 'Arkistointi',
+		'dynamic_opml' => array(
+			'_' => 'Dynaaminen OPML',
+			'help' => 'Voit tuoda syötteet tähän luokkaan automaattisesti antamalla <a href="http://opml.org/" target="_blank">OPML-tiedoston</a> URL-osoitteen',
+		),
+		'empty' => 'Tyhjä luokka',
+		'expand' => 'Laajenna luokka',
+		'information' => 'Tiedot',
+		'open' => 'Avaa luokka',
+		'opml_url' => 'OPML-tiedoston URL-osoite',
+		'position' => 'Näyttöjärjestys',
+		'position_help' => 'Määritä luokkien lajittelujärjestys',
+		'title' => 'Otsikko',
+	),
+	'feed' => array(
+		'accept_cookies' => 'Hyväksy evästeet',
+		'accept_cookies_help' => 'Salli syötepalvelimen määrittää evästeitä (tallennetaan vain pyynnön käsittelyn ajaksi)',
+		'add' => 'Lisää syöte',
+		'advanced' => 'Lisäasetukset',
+		'archiving' => 'Arkistointi',
+		'auth' => array(
+			'configuration' => 'Sisäänkirjaus',
+			'help' => 'Mahdollistaa HTTP-suojattujen RSS-syötteiden käytön',
+			'http' => 'HTTP-todennus',
+			'password' => 'HTTP-salasana',
+			'username' => 'HTTP-käyttäjätunnus',
+		),
+		'clear_cache' => 'Tyhjennä välimuisti aina',
+		'content_action' => array(
+			'_' => 'Toiminto noudettaessa artikkelin sisältö',
+			'append' => 'Lisää aiemman sisällön perään',
+			'prepend' => 'Lisää ennen aiempaa sisältöä',
+			'replace' => 'Korvaa aiempi sisältö',
+		),
+		'css_cookie' => 'Käytä evästeitä noudettaessa artikkelin sisältö',
+		'css_cookie_help' => 'Esimerkki: <kbd>foo=bar; gdpr_consent=true; cookie=value</kbd>',
+		'css_help' => 'Noutaa lyhennetyt RSS-syötteet (huomautus: kestää pidempään!)',
+		'css_path' => 'Artikkelin CSS-valitsin alkuperäisellä sivustolla',
+		'css_path_filter' => array(
+			'_' => 'Poistettavien elementtien CSS-valitsin',
+			'help' => 'CSS-valitsin voi olla luettelo, kuten: <kbd>.footer, .aside, p[data-sanitized-class="menu"]</kbd>',
+		),
+		'description' => 'Kuvaus',
+		'empty' => 'Syöte on tyhjä. Varmista, että sitä ylläpidetään edelleen.',
+		'error' => 'Syötteessä on ilmennyt ongelma. Varmista, että se on aina tavoitettavissa ja päivitä se sitten.',
+		'export-as-opml' => array(
+			'download' => 'Lataa',
+			'help' => 'XML-tiedosto (osa tiedoista. <a href="https://freshrss.github.io/FreshRSS/en/developers/OPML.html" target="_blank">Katso ohje</a>)',
+			'label' => 'Vie OPML-tiedostoksi',
+		),
+		'filteractions' => array(
+			'_' => 'Suodatustoiminnot',
+			'help' => 'Kirjoita kukin hakusuodatin omalle rivilleen. Lisätietoja operaattoreista <a href="https://freshrss.github.io/FreshRSS/en/users/10_filter.html#with-the-search-field" target="_blank">ohjeissa</a>.',
+		),
+		'http_headers' => 'HTTP-otsikot',
+		'http_headers_help' => 'Otsikot erotellaan rivinvaihdoin, ja nimi ja arvo erotellaan kaksoispisteellä. Esimerkki: <kbd><code>Accept: application/atom+xml<br />Authorization: Bearer some-token</code></kbd>).',
+		'information' => 'Tiedot',
+		'keep_min' => 'Säilytettävien artikkeleiden vähimmäismäärä',
+		'kind' => array(
+			'_' => 'Syötteen lähteen laji',
+			'html_json' => array(
+				'_' => 'HTML + XPath + JSON-pistemerkintä (JSON HTML:ssä)',
+				'xpath' => array(
+					'_' => 'XPath (JSON HTML:ssä)',
+					'help' => 'Esimerkki: <code>//script[@type="application/json"]</code>',
+				),
+			),
+			'html_xpath' => array(
+				'_' => 'HTML + XPath (sivujen haravointi)',
+				'feed_title' => array(
+					'_' => 'syötteen otsikko',
+					'help' => 'Esimerkki: <code>//title</code> tai staattinen merkkijono: <code>"Oma syötteeni"</code>',
+				),
+				'help' => '<dfn><a href="https://www.w3.org/TR/xpath-10/" target="_blank">XPath 1.0</a></dfn> on standardinmukainen kyselykieli edistyneille käyttäjille, jonka avulla FreshRSS toteuttaa verkkosivujen haravoinnin.',
+				'item' => array(
+					'_' => '<strong>uutisten</strong> haku<br /><small>(tärkein)</small>',
+					'help' => 'Esimerkki: <code>//div[@class="news-item"]</code>',
+				),
+				'item_author' => array(
+					'_' => 'tekstin kirjoittaja',
+					'help' => 'Voi olla myös staattinen merkkijono. Esimerkki: <code>"Anonyymi"</code>',
+				),
+				'item_categories' => 'tekstin avainsanat (tag)',
+				'item_content' => array(
+					'_' => 'tekstin sisältö',
+					'help' => 'Esimerkiksi koko tekstin sisältö: <code>.</code>',
+				),
+				'item_thumbnail' => array(
+					'_' => 'tekstin pikkukuva',
+					'help' => 'Esimerkki: <code>descendant::img/@src</code>',
+				),
+				'item_timeFormat' => array(
+					'_' => 'Mukautettu päivämäärän/kellonajan muoto',
+					'help' => 'Valinnainen. <a href="https://php.net/datetime.createfromformat" target="_blank"><code>DateTime::createFromFormat()</code></a>-funktion tukema muoto, kuten <code>d-m-Y H:i:s</code>',
+				),
+				'item_timestamp' => array(
+					'_' => 'tekstin päivämäärä',
+					'help' => '<a href="https://php.net/strtotime" target="_blank"><code>strtotime()</code></a>-funktio jäsentää tuloksen',
+				),
+				'item_title' => array(
+					'_' => 'tekstin otsikko',
+					'help' => 'Käytä erityisesti <a href="https://developer.mozilla.org/docs/Web/XPath/Axes" target="_blank">XPath-siirtymää</a> <code>descendant::</code>, esimerkiksi <code>descendant::h2</code>',
+				),
+				'item_uid' => array(
+					'_' => 'tekstin yksilöllinen tunnus',
+					'help' => 'Valinnainen. Esimerkki: <code>descendant::div/@data-uri</code>',
+				),
+				'item_uri' => array(
+					'_' => 'tekstin URL-osoite',
+					'help' => 'Esimerkki: <code>descendant::a/@href</code>',
+				),
+				'relative' => 'XPath (suhteessa tekstiin) kohteelle:',
+				'xpath' => 'XPath kohteelle:',
+			),
+			'json_dotnotation' => array(
+				'_' => 'JSON (pistemerkintä)',
+				'feed_title' => array(
+					'_' => 'syötteen otsikko',
+					'help' => 'Esimerkki: <code>meta.title</code> tai staattinen merkkijono: <code>"Mukautettu syötteeni"</code>',
+				),
+				'help' => 'JSON-pistemerkintä käyttää pisteitä objektien välissä ja hakasulkeita taulukoissa (esimerkki: <code>data.items[0].title</code>)',
+				'item' => array(
+					'_' => '<strong>uutisten</strong> haku<br /><small>(tärkein)</small>',
+					'help' => 'JSON-polku taulukkoon, joka sisältää tekstit, esimerkiksi <code>$</code> tai <code>newsItems</code>',
+				),
+				'item_author' => 'tekstin kirjoittaja',
+				'item_categories' => 'tekstin avainsanat (tag)',
+				'item_content' => array(
+					'_' => 'tekstin sisältö',
+					'help' => 'Tunniste, jossa sisältö on, esimerkiksi <code>content</code>',
+				),
+				'item_thumbnail' => array(
+					'_' => 'tekstin pikkukuva',
+					'help' => 'Esimerkki: <code>image</code>',
+				),
+				'item_timeFormat' => array(
+					'_' => 'Mukautettu päivämäärän/kellonajan muoto',
+					'help' => 'Valinnainen. <a href="https://php.net/datetime.createfromformat" target="_blank"><code>DateTime::createFromFormat()</code></a>-funktion tukema muoto, kuten <code>d-m-Y H:i:s</code>',
+				),
+				'item_timestamp' => array(
+					'_' => 'tekstin päivämäärä',
+					'help' => '<a href="https://php.net/strtotime" target="_blank"><code>strtotime()</code></a>-funktio jäsentää tuloksen',
+				),
+				'item_title' => 'tekstin otsikko',
+				'item_uid' => 'tekstin yksilöllinen tunnus',
+				'item_uri' => array(
+					'_' => 'tekstin URL-osoite',
+					'help' => 'Esimerkki: <code>permalink</code>',
+				),
+				'json' => 'pistemerkintä kohteelle:',
+				'relative' => 'pistemerkitty polku (suhteessa tekstiin) kohteelle:',
+			),
+			'jsonfeed' => 'JSON-syöte',
+			'rss' => 'RSS/Atom (oletus)',
+			'xml_xpath' => 'XML + XPath',	// IGNORE
+		),
+		'maintenance' => array(
+			'clear_cache' => 'Tyhjennä välimuisti',
+			'clear_cache_help' => 'Tyhjennä syötteen välimuisti.',
+			'reload_articles' => 'Lataa artikkelit uudelleen',
+			'reload_articles_help' => 'Lataa määritetty lukumäärä artikkeleita uudelleen ja nouda koko sisältö, jos valitsin on määritetty.',
+			'title' => 'Ylläpito',
+		),
+		'max_http_redir' => 'Enimmäismäärä HTTP-uudelleenohjauksia',
+		'max_http_redir_help' => 'Voit määrittää arvoksi myös 0 tai tyhjä (poista käytöstä) tai -1 (rajaton määrä uudelleenohjauksia)',
+		'method' => array(
+			'_' => 'HTTP-metodi',
+		),
+		'method_help' => 'POST-tiedot tukevat automaattisesti <code>application/x-www-form-urlencoded</code>- ja <code>application/json</code>-sisältöä',
+		'method_postparams' => 'POST-menetelmän tiedot',
+		'moved_category_deleted' => 'Kun poistat luokan, sen syötteet siirretään automaattisesti luokkaan <em>%s</em>.',
+		'mute' => array(
+			'_' => 'vaimenna',
+			'state_is_muted' => 'Syöte on vaimennettu',
+		),
+		'no_selected' => 'Syötettä ei ole valittu.',
+		'number_entries' => '%d artikkelia',
+		'open_feed' => 'Avaa syöte %s',
+		'priority' => array(
+			'_' => 'Näkyvyys',
+			'archived' => 'Älä näytä (arkistoitu)',
+			'category' => 'Näytä luokassaan',
+			'important' => 'Näytä tärkeissä syötteissä',
+			'main_stream' => 'Näytä pääsyötevirrassa',
+		),
+		'proxy' => 'Nouda syöte käyttämällä välityspalvelinta',
+		'proxy_help' => 'Valitse protokolla (esimerkki: SOCKS5) ja kirjoita välityspalvelimen osoite (esimerkki: <kbd>127.0.0.1:1080</kbd> tai <kbd>käyttäjätunnus:salasana@127.0.0.1:1080</kbd>)',
+		'selector_preview' => array(
+			'show_raw' => 'Näytä lähdekoodi',
+			'show_rendered' => 'Näytä sisältö',
+		),
+		'show' => array(
+			'all' => 'Näytä kaikki syötteet',
+			'error' => 'Näytä vain syötteet, joissa on virheitä',
+		),
+		'showing' => array(
+			'error' => 'Näkyvissä vain syötteet, joissa on virheitä',
+		),
+		'ssl_verify' => 'Varmenna SSL-suojaus',
+		'stats' => 'Tilastot',
+		'think_to_add' => 'Haluat ehkä lisätä joitakin syötteitä.',
+		'timeout' => 'Aikakatkaisu sekunteina',
+		'title' => 'Otsikko',
+		'title_add' => 'Lisää RSS-syöte',
+		'ttl' => 'Älä päivitä automaattisesti useammin kuin',
+		'unicityCriteria' => array(
+			'_' => 'Artikkelin yksilöivät ehdot',
+			'forced' => '<span title="Estä yksilöivät ehdot, vaikka syötteen artikkeleista olisi kaksoiskappaleita">pakotettu</span>',
+			'help' => 'Olennainen virheellisille syötteille.<br />⚠️ Käytännön muuttaminen luo kaksoiskappaleita.',
+			'id' => 'Perustunnus (oletus)',
+			'link' => 'Linkki',
+			'sha1:link_published' => 'Linkki + päiväys',
+			'sha1:link_published_title' => 'Linkki + päiväys + otsikko',
+			'sha1:link_published_title_content' => 'Linkki + päiväys + otsikko + sisältö',
+		),
+		'url' => 'Syötteen URL-osoite',
+		'useragent' => 'Määritä syötteen noutamiseen käytettävä käyttäjäagentti',
+		'useragent_help' => 'Esimerkki: <kbd>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0)</kbd>',
+		'validator' => 'Tarkista syötteen kelpoisuus',
+		'website' => 'Sivuston URL-osoite',
+		'websub' => 'Välittömät ilmoitukset WebSubin avulla',
+	),
+	'import_export' => array(
+		'export' => array(
+			'_' => 'Vie',
+			'sqlite' => 'Lataa käyttäjän tietokanta SQLite-muodossa',
+		),
+		'export_labelled' => 'Vie merkityt artikkelit',
+		'export_opml' => 'Vie syöteluettelo (OPML)',
+		'export_starred' => 'Vie suosikit',
+		'feed_list' => 'Syötteen %s artikkelit',
+		'file_to_import' => 'Tuotava tiedosto<br />(OPML, JSON tai ZIP)',
+		'file_to_import_no_zip' => 'Tuotava tiedosto<br />(OPML tai JSON)',
+		'import' => 'Tuo tiedostosta',
+		'starred_list' => 'Suosikkiartikkelit',
+		'title' => 'Tuonti / Vienti',
+	),
+	'menu' => array(
+		'add' => 'Lisää syöte tai luokka',
+		'import_export' => 'Tuonti / Vienti',
+		'label_management' => 'Tunnisteiden hallinta',
+		'stats' => array(
+			'idle' => 'Hiljentyneet syötteet',
+			'main' => 'Tilastot',
+			'repartition' => 'Artikkelien uudelleenjaottelu',
+		),
+		'subscription_management' => 'Tilausten hallinta',
+		'subscription_tools' => 'Tilaustyökalut',
+	),
+	'tag' => array(
+		'auto_label' => 'Lisää merkintä uusiin artikkeleihin',
+		'name' => 'Nimi',
+		'new_name' => 'Uusi nimi',
+		'old_name' => 'Vanha nimi',
+	),
+	'title' => array(
+		'_' => 'Tilausten hallinta',
+		'add' => 'Lisää syöte tai luokka',
+		'add_category' => 'Lisää luokkaa',
+		'add_dynamic_opml' => 'Lisää dynaaminen OPML',
+		'add_feed' => 'Lisää syöte',
+		'add_label' => 'Lisää tunniste',
+		'delete_label' => 'Poista tunniste',
+		'feed_management' => 'RSS-syötteiden hallinta',
+		'rename_label' => 'Nimeä tunniste uudelleen',
+		'subscription_tools' => 'Tilaustyökalut',
+	),
+);

+ 54 - 0
app/i18n/fi/user.php

@@ -0,0 +1,54 @@
+<?php
+
+/******************************************************************************/
+/* Each entry of that file can be associated with a comment to indicate its   */
+/* state. When there is no comment, it means the entry is fully translated.   */
+/* The recognized comments are (comment matching is case-insensitive):        */
+/*   + TODO: the entry has never been translated.                             */
+/*   + DIRTY: the entry has been translated but needs to be updated.          */
+/*   + IGNORE: the entry does not need to be translated.                      */
+/* When a comment is not recognized, it is discarded.                         */
+/******************************************************************************/
+
+return array(
+	'email' => array(
+		'feedback' => array(
+			'invalid' => 'Sähköpostiosoite on virheellinen.',
+			'required' => 'Sähköpostiosoite on pakollinen.',
+		),
+		'validation' => array(
+			'change_email' => 'Voit muuttaa sähköpostiosoitteesi <a href="%s">profiilisivulla</a>.',
+			'email_sent_to' => 'Sähköposti on lähetetty osoitteeseen <strong>%s</strong>. Vahvista sähköpostiosoitteesi seuraamalla sen ohjeita.',
+			'feedback' => array(
+				'email_failed' => 'Sähköpostiviestin lähetys ei onnistunut palvelimen määritysvirheen vuoksi.',
+				'email_sent' => 'Sähköpostiviesti on lähetetty osoitteeseesi.',
+				'error' => 'Sähköpostiosoitteen vahvistaminen ei onnistunut.',
+				'ok' => 'Sähköpostiosoite on vahvistettu.',
+				'unnecessary' => 'Sähköpostiosoite on vahvistettu aiemmin.',
+				'wrong_token' => 'Sähköpostiosoitteen vahvistus epäonnistui väärän suojaustunnuksen vuoksi.',
+			),
+			'need_to' => 'Sinun on vahvistettava sähköpostiosoitteesi, ennen kuin voit käyttää sovellusta %s.',
+			'resend_email' => 'Lähetä sähköposti uudelleen',
+			'title' => 'Sähköpostiosoitteen vahvistus',
+		),
+	),
+	'mailer' => array(
+		'email_need_validation' => array(
+			'body' => 'Olet juuri rekisteröitynyt sovellukseen %s, mutta sinun on vielä vahvistettava sähköpostiosoitteesi. Seuraa vain linkkiä:',
+			'title' => 'Tili on vahvistettava',
+			'welcome' => 'Tervetuloa Welcome %s,',
+		),
+	),
+	'password' => array(
+		'invalid' => 'Salasana on väärä.',
+	),
+	'tos' => array(
+		'feedback' => array(
+			'invalid' => 'Rekisteröityminen edellyttää palvelun käyttöehtojen hyväksymistä.',
+		),
+	),
+	'username' => array(
+		'invalid' => 'Käyttäjätunnus on virheellinen.',
+		'taken' => 'Käyttäjätunnus, %s, on jo käytössä.',
+	),
+);

+ 1 - 0
app/i18n/fr/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/he/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/hu/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/id/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/it/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/ja/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/ko/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/lv/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/nl/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/oc/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/pl/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/pt-br/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/ru/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/sk/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/tr/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/zh-cn/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE

+ 1 - 0
app/i18n/zh-tw/gen.php

@@ -155,6 +155,7 @@ return array(
 		'en-us' => 'English (United States)',	// IGNORE
 		'es' => 'Español',	// IGNORE
 		'fa' => 'فارسی',	// IGNORE
+		'fi' => 'Suomi',	// IGNORE
 		'fr' => 'Français',	// IGNORE
 		'he' => 'עברית',	// IGNORE
 		'hu' => 'Magyar',	// IGNORE