Browse Source

Merge branch 'releases'

Marien Fressinaud 13 năm trước cách đây
mục cha
commit
2e7afb7d34
68 tập tin đã thay đổi với 2664 bổ sung951 xóa
  1. 34 17
      README
  2. 27 0
      actualize_script.php
  3. 9 0
      app/App_FrontController.php
  4. 3 3
      app/controllers/apiController.php
  5. 40 17
      app/controllers/configureController.php
  6. 5 5
      app/controllers/entryController.php
  7. 207 169
      app/controllers/feedController.php
  8. 110 169
      app/controllers/indexController.php
  9. 270 0
      app/i18n/en.php
  10. 270 0
      app/i18n/fr.php
  11. 4 4
      app/layout/aside_configure.phtml
  12. 16 6
      app/layout/aside_feed.phtml
  13. 18 23
      app/layout/aside_flux.phtml
  14. 22 10
      app/layout/header.phtml
  15. 3 0
      app/layout/layout.phtml
  16. 55 17
      app/layout/nav_menu.phtml
  17. 1 1
      app/models/Category.php
  18. 144 0
      app/models/EntriesGetter.php
  19. 102 231
      app/models/Entry.php
  20. 7 0
      app/models/Exception/EntriesGetterException.php
  21. 6 0
      app/models/Exception/FeedException.php
  22. 68 7
      app/models/Feed.php
  23. 24 2
      app/models/RSSConfiguration.php
  24. 29 0
      app/models/RSSPaginator.php
  25. 10 10
      app/views/configure/categorize.phtml
  26. 39 27
      app/views/configure/display.phtml
  27. 24 23
      app/views/configure/feed.phtml
  28. 6 6
      app/views/configure/importExport.phtml
  29. 15 15
      app/views/configure/shortcut.phtml
  30. 12 12
      app/views/entry/note.phtml
  31. 5 2
      app/views/error/index.phtml
  32. 4 15
      app/views/helpers/pagination.phtml
  33. 1 1
      app/views/helpers/rss.phtml
  34. 12 12
      app/views/index/about.phtml
  35. 43 29
      app/views/index/index.phtml
  36. 1 1
      app/views/javascript/actualize.phtml
  37. 49 46
      lib/lib_rss.php
  38. BIN
      public/favicon.ico
  39. BIN
      public/favicon.png
  40. 174 58
      public/install.php
  41. BIN
      public/logo.png
  42. 535 0
      public/logo.svg
  43. 65 0
      public/theme/fallback.css
  44. 14 1
      public/theme/freshrss.css
  45. 47 12
      public/theme/global.css
  46. BIN
      public/theme/icons/add.png
  47. BIN
      public/theme/icons/all.png
  48. BIN
      public/theme/icons/category.png
  49. BIN
      public/theme/icons/close.png
  50. BIN
      public/theme/icons/configure.png
  51. BIN
      public/theme/icons/down.png
  52. BIN
      public/theme/icons/help.png
  53. BIN
      public/theme/icons/link.png
  54. BIN
      public/theme/icons/login.png
  55. BIN
      public/theme/icons/logout.png
  56. BIN
      public/theme/icons/non-starred.png
  57. BIN
      public/theme/icons/note.png
  58. BIN
      public/theme/icons/note_empty.png
  59. BIN
      public/theme/icons/read.png
  60. BIN
      public/theme/icons/refresh.png
  61. BIN
      public/theme/icons/rss.png
  62. BIN
      public/theme/icons/search.png
  63. BIN
      public/theme/icons/share.png
  64. BIN
      public/theme/icons/starred.png
  65. BIN
      public/theme/icons/tag.png
  66. 134 0
      public/theme/icons/tag.svg
  67. BIN
      public/theme/icons/unread.png
  68. BIN
      public/theme/icons/up.png

+ 34 - 17
README

@@ -1,10 +1,12 @@
 Un simple agrégateur de flux rss relativement léger et rapide par rapport aux
-mastodontes que sont RSSLounge et TinyTinyRSS
+mastodontes que sont RSSLounge et TinyTinyRSS.
+
+Une démo est disponible sur http://marienfressinaud.fr/projets/freshrss/
 
 @name FreshRSS
 @author Marien Fressinaud <dev@marienfressinaud.fr>
-@version 0.2.0
-@date 2013-04-17
+@version 0.3.0
+@date 2013-05-05
 @license AGPL3
 
 DISCLAIMER
@@ -16,9 +18,6 @@ mesure du possible aux demandes d'évolution si celles-ci me semblent justifiée
 Privilégiez pour cela des demandes sur GitHub
 (https://github.com/marienfressinaud/FreshRSS/issues) ou par mail
 
-De plus, je n'ai réellement testé FreshRSS que sous Firefox, il pourrait y
-avoir des soucis sur d'autres navigateurs.
-
 PRE-REQUIS
 ==========
 - Serveur Apache (non testé sur aucun autre)
@@ -32,29 +31,47 @@ INSTALLATION
 	1. Récupérez l'application FreshRSS via la commande git ou en
 	   téléchargeant l'archive
 	2. Exécutez le script ./build.sh ou en récupérant à la main la librairie
-	   Minz (https://github.com/marienfressinaud/MINZ) et en copian la lib
-	   dans /lib/minz
+	   Minz (https://github.com/marienfressinaud/MINZ) et en copiant la lib
+	   dans ./lib/minz
 	3. Déplacez l'application où vous voulez sur votre serveur (attention,
-	   la partie accessible se trouve dans le répertoire `/public`)
-	4. Accéder à FreshRSS à travers votre navigateur web et suivez les
-	   instructions !
+	   la partie accessible se trouve dans le répertoire `./public`)
+	4. Accédez à FreshRSS à travers votre navigateur web et suivez les
+	   instructions
 	5. Tout devrait fonctionner :) En cas de problème, n'hésitez pas à me
-	   contacter !
+	   contacter.
 
 SÉCURITÉ ET CONSEILS
 ====================
 	1. Si possible, faites pointer un sous-domaine sur le répertoire
-	   `/public`
+	   `./public`
 	2. Le fichier de log peut être utile à lire si vous avez des soucis
-	3. Le fichier `/public/index.php` défini les chemins d'accès aux
+	3. Le fichier `./public/index.php` défini les chemins d'accès aux
 	   répertoires clés de l'application. Si vous les bougez, tout se passe
 	   ici.
-	4. Vous pouvez ajouter une tâche CRON sur l'url de mise à jour des flux
-	   (clic droit sur le bouton d'actualisation puis "Copier l'adresse du
-	   lien") pour que celle-ci se fasse de manière transparente
+	4. Vous pouvez ajouter une tâche CRON sur le script d'actualisation des
+	   flux. Il s'agit d'un script PHP à exécuter avec la commande `php`.
+	   Par exemple, pour exécuter le script toutes les heures :
+	   0 * * * * php /chemin/vers/freshrss/actualize_script.php >/dev/null 2>&1
+	   Veuillez cependant vérifier que le fichier ./public/data/Configuration.array.php
+	   soit accessible en lecture / écriture par l'exécuteur du script
 
 CHANGELOG
 =========
+2013-05-05 changes with FreshRSS 0.3.0
+	*) Fallback pour les icônes SVG (utilisation de PNG à la place)
+	*) Fallback pour les propriétés CSS3 (utilisation de préfixes)
+	*) Affichage des tags associés aux articles
+	*) Internationalisation de l'application (gestion des langues anglaise
+	   et française)
+	*) Gestion des flux protégés par authentification HTTP
+	*) Mise en cache des favicons
+	*) Création d'un logo *temporaire*
+	*) Affichage des vidéos dans les articles
+	*) Gestion de la recherche et filtre par tags pleinement fonctionnels
+	*) Création d'un vrai script CRON permettant de mettre tous les flux à
+	   jour
+	*) Correction bugs divers
+
 2013-04-17 changes with FreshRSS 0.2.0
 	*) Création d'un installateur
 	*) Actualisation des flux en Ajax

+ 27 - 0
actualize_script.php

@@ -0,0 +1,27 @@
+<?php
+
+// Constantes de chemins
+define ('PUBLIC_PATH', realpath (dirname (__FILE__) . '/public'));
+define ('LIB_PATH', realpath (PUBLIC_PATH . '/../lib'));
+define ('APP_PATH', realpath (PUBLIC_PATH . '/../app'));
+define ('LOG_PATH', realpath (PUBLIC_PATH . '/../log'));
+define ('CACHE_PATH', realpath (PUBLIC_PATH . '/../cache'));
+
+$_GET['c'] = 'feed';
+$_GET['a'] = 'actualize';
+$_GET['force'] = true;
+$_SERVER['HTTP_HOST'] = '';
+
+set_include_path (get_include_path ()
+		 . PATH_SEPARATOR
+		 . LIB_PATH
+		 . PATH_SEPARATOR
+		 . LIB_PATH . '/minz'
+		 . PATH_SEPARATOR
+		 . APP_PATH);
+
+require (APP_PATH . '/App_FrontController.php');
+
+$front_controller = new App_FrontController ();
+$front_controller->init ();
+$front_controller->run ();

+ 9 - 0
app/App_FrontController.php

@@ -11,9 +11,12 @@ class App_FrontController extends FrontController {
 		$this->loadModels ();
 
 		Session::init (); // lancement de la session doit se faire après chargement des modèles sinon bug (pourquoi ?)
+
 		$this->loadParamsView ();
 		$this->loadStylesAndScripts ();
 		$this->loadNotifications ();
+
+		Translate::init ();
 	}
 
 	private function loadLibs () {
@@ -25,11 +28,14 @@ class App_FrontController extends FrontController {
 
 	private function loadModels () {
 		include (APP_PATH . '/models/Exception/FeedException.php');
+		include (APP_PATH . '/models/Exception/EntriesGetterException.php');
 		include (APP_PATH . '/models/RSSConfiguration.php');
 		include (APP_PATH . '/models/Days.php');
 		include (APP_PATH . '/models/Category.php');
 		include (APP_PATH . '/models/Feed.php');
 		include (APP_PATH . '/models/Entry.php');
+		include (APP_PATH . '/models/EntriesGetter.php');
+		include (APP_PATH . '/models/RSSPaginator.php');
 	}
 
 	private function loadParamsView () {
@@ -38,9 +44,12 @@ class App_FrontController extends FrontController {
 
 		$entryDAO = new EntryDAO ();
 		View::_param ('nb_not_read', $entryDAO->countNotRead ());
+
+		Session::_param ('language', $this->conf->language ());
 	}
 
 	private function loadStylesAndScripts () {
+		View::appendStyle (Url::display ('/theme/fallback.css'));
 		View::appendStyle (Url::display ('/theme/global.css'));
 		View::appendStyle (Url::display ('/theme/freshrss.css'));
 		if (login_is_conf ($this->conf)) {

+ 3 - 3
app/controllers/apiController.php

@@ -20,11 +20,11 @@ class apiController extends ActionController {
 			$notes = $e->notes ();
 			if ($notes == '') {
 				$feed = $e->feed (true);
-				$notes = 'Article publié initialement sur <a href="' . $feed->website () . '">' . $feed->name () . '</a>';
 				if($author != '') {
-					$notes .= ' par ' . $author;
+					$notes = Translate::t ('article_published_on_author', $feed->website (), $feed->name (), $author);
+				} else {
+					$notes = Translate::t ('article_published_on', $feed->website (), $feed->name ());
 				}
-				$notes .= ', mis en favoris dans <a href="https://github.com/marienfressinaud/FreshRSS">FreshRSS</a>';
 			}
 
 			$id = $e->id ();

+ 40 - 17
app/controllers/configureController.php

@@ -5,14 +5,17 @@ class configureController extends ActionController {
 		if (login_is_conf ($this->view->conf) && !is_logged ()) {
 			Error::error (
 				403,
-				array ('error' => array ('Vous n\'avez pas le droit d\'accéder à cette page'))
+				array ('error' => array (Translate::t ('access_denied')))
 			);
 		}
 	}
 
 	public function categorizeAction () {
+		$feedDAO = new FeedDAO ();
 		$catDAO = new CategoryDAO ();
 		$catDAO->checkDefault ();
+		$defaultCategory = $catDAO->getDefault ();
+		$defaultId = $defaultCategory->id ();
 
 		if (Request::isPost ()) {
 			$cats = Request::param ('categories', array ());
@@ -27,7 +30,8 @@ class configureController extends ActionController {
 						'color' => $cat->color ()
 					);
 					$catDAO->updateCategory ($ids[$key], $values);
-				} elseif ($ids[$key] != '000000') {
+				} elseif ($ids[$key] != $defaultId) {
+					$feedDAO->changeCategory ($ids[$key], $defaultId);
 					$catDAO->deleteCategory ($ids[$key]);
 				}
 			}
@@ -48,7 +52,7 @@ class configureController extends ActionController {
 			// notif
 			$notif = array (
 				'type' => 'good',
-				'content' => 'Les catégories ont été mises à jour'
+				'content' => Translate::t ('categories_updated')
 			);
 			Session::_param ('notification', $notif);
 
@@ -58,7 +62,7 @@ class configureController extends ActionController {
 		$this->view->categories = $catDAO->listCategories ();
 		$this->view->defaultCategory = $catDAO->getDefault ();
 
-		View::prependTitle ('Gestion des catégories - ');
+		View::prependTitle (Translate::t ('categories_management') . ' - ');
 	}
 
 	public function feedAction () {
@@ -80,7 +84,7 @@ class configureController extends ActionController {
 			if (!$this->view->flux) {
 				Error::error (
 					404,
-					array ('error' => array ('La page que vous cherchez n\'existe pas'))
+					array ('error' => array (Translate::t ('page_not_found')))
 				);
 			} else {
 				$catDAO = new CategoryDAO ();
@@ -90,11 +94,19 @@ class configureController extends ActionController {
 					$cat = Request::param ('category', 0);
 					$path = Request::param ('path_entries', '');
 					$priority = Request::param ('priority', 0);
+					$user = Request::param ('http_user', '');
+					$pass = Request::param ('http_pass', '');
+
+					$httpAuth = '';
+					if ($user != '' || $pass != '') {
+						$httpAuth = $user . ':' . $pass;
+					}
 
 					$values = array (
 						'category' => $cat,
 						'pathEntries' => $path,
-						'priority' => $priority
+						'priority' => $priority,
+						'httpAuth' => $httpAuth
 					);
 
 					if ($feedDAO->updateFeed ($id, $values)) {
@@ -102,12 +114,12 @@ class configureController extends ActionController {
 
 						$notif = array (
 							'type' => 'good',
-							'content' => 'Le flux a été mis à jour'
+							'content' => Translate::t ('feed_updated')
 						);
 					} else {
 						$notif = array (
 							'type' => 'bad',
-							'content' => 'Une erreur est survenue lors de la mise à jour'
+							'content' => Translate::t ('error_occurred_update')
 						);
 					}
 
@@ -115,15 +127,16 @@ class configureController extends ActionController {
 					Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => array ('id' => $id)), true);
 				}
 
-				View::prependTitle ('Gestion des flux RSS - ' . $this->view->flux->name () . ' - ');
+				View::prependTitle (Translate::t ('rss_feed_management') . ' - ' . $this->view->flux->name () . ' - ');
 			}
 		} else {
-			View::prependTitle ('Gestion des flux RSS - ');
+			View::prependTitle (Translate::t ('rss_feed_management') . ' - ');
 		}
 	}
 
 	public function displayAction () {
 		if (Request::isPost ()) {
+			$language = Request::param ('language', 'en');
 			$nb = Request::param ('posts_per_page', 10);
 			$view = Request::param ('default_view', 'all');
 			$display = Request::param ('display_posts', 'no');
@@ -135,6 +148,7 @@ class configureController extends ActionController {
 			$openPage = Request::param ('mark_open_page', 'no');
 			$urlShaarli = Request::param ('shaarli', '');
 
+			$this->view->conf->_language ($language);
 			$this->view->conf->_postsPerPage (intval ($nb));
 			$this->view->conf->_defaultView ($view);
 			$this->view->conf->_displayPosts ($display);
@@ -149,6 +163,7 @@ class configureController extends ActionController {
 			$this->view->conf->_urlShaarli ($urlShaarli);
 
 			$values = array (
+				'language' => $this->view->conf->language (),
 				'posts_per_page' => $this->view->conf->postsPerPage (),
 				'default_view' => $this->view->conf->defaultView (),
 				'display_posts' => $this->view->conf->displayPosts (),
@@ -164,28 +179,31 @@ class configureController extends ActionController {
 			Session::_param ('conf', $this->view->conf);
 			Session::_param ('mail', $this->view->conf->mailLogin ());
 
+			Session::_param ('language', $this->view->conf->language ());
+			Translate::reset ();
+
 			// notif
 			$notif = array (
 				'type' => 'good',
-				'content' => 'La configuration a été mise à jour'
+				'content' => Translate::t ('configuration_updated')
 			);
 			Session::_param ('notification', $notif);
 
 			Request::forward (array ('c' => 'configure', 'a' => 'display'), true);
 		}
 
-		View::prependTitle ('Gestion générale et affichage - ');
+		View::prependTitle (Translate::t ('general_and_reading_management') . ' - ');
 	}
 
 	public function importExportAction () {
 		$this->view->req = Request::param ('q');
 
 		if ($this->view->req == 'export') {
-			View::_title ('feeds_opml.xml');
+			View::_title ('freshrss_feeds.opml');
 
 			$this->view->_useLayout (false);
 			header('Content-Type: text/xml; charset=utf-8');
-			header('Content-disposition: attachment; filename=feeds_opml.xml');
+			header('Content-disposition: attachment; filename=freshrss_feeds.opml');
 
 			$feedDAO = new FeedDAO ();
 			$catDAO = new CategoryDAO ();
@@ -199,8 +217,11 @@ class configureController extends ActionController {
 			$this->view->categories = $list;
 		} elseif ($this->view->req == 'import' && Request::isPost ()) {
 			if ($_FILES['file']['error'] == 0) {
+				// on parse le fichier OPML pour récupérer les catégories et les flux associés
 				list ($categories, $feeds) = opml_import (file_get_contents ($_FILES['file']['tmp_name']));
 
+				// On redirige vers le controller feed qui va se charger d'insérer les flux en BDD
+				// les flux sont mis au préalable dans des variables de Request
 				Request::_param ('q', 'null');
 				Request::_param ('categories', $categories);
 				Request::_param ('feeds', $feeds);
@@ -210,9 +231,11 @@ class configureController extends ActionController {
 
 		$feedDAO = new FeedDAO ();
 		$this->view->feeds = $feedDAO->listFeeds ();
+
+		// au niveau de la vue, permet de ne pas voir un flux sélectionné dans la liste
 		$this->view->flux = false;
 
-		View::prependTitle ('Importation et exportation OPML - ');
+		View::prependTitle (Translate::t ('import_export_opml') . ' - ');
 	}
 
 	public function shortcutAction () {
@@ -251,13 +274,13 @@ class configureController extends ActionController {
 			// notif
 			$notif = array (
 				'type' => 'good',
-				'content' => 'Les raccourcis ont été mis à jour'
+				'content' => Translate::t ('shortcuts_updated')
 			);
 			Session::_param ('notification', $notif);
 
 			Request::forward (array ('c' => 'configure', 'a' => 'shortcut'), true);
 		}
 
-		View::prependTitle ('Gestion des raccourcis - ');
+		View::prependTitle (Translate::t ('shortcuts_management') . ' - ');
 	}
 }

+ 5 - 5
app/controllers/entryController.php

@@ -5,7 +5,7 @@ class entryController extends ActionController {
 		if (login_is_conf ($this->view->conf) && !is_logged ()) {
 			Error::error (
 				403,
-				array ('error' => array ('Vous n\'avez pas le droit d\'accéder à cette page'))
+				array ('error' => array (Translate::t ('access_denied')))
 			);
 		}
 
@@ -63,7 +63,7 @@ class entryController extends ActionController {
 			// notif
 			$notif = array (
 				'type' => 'good',
-				'content' => 'Les flux ont été marqués comme lu'
+				'content' => Translate::t ('feeds_marked_read')
 			);
 			Session::_param ('notification', $notif);
 		} else {
@@ -130,12 +130,12 @@ class entryController extends ActionController {
 					if ($entryDAO->updateEntry ($id, $values)) {
 						$notif = array (
 							'type' => 'good',
-							'content' => 'Modifications enregistrées'
+							'content' => Translate::t ('updated')
 						);
 					} else {
 						$notif = array (
 							'type' => 'bad',
-							'content' => 'Une erreur est survenue'
+							'content' => Translate::t ('error_occured')
 						);
 					}
 					Session::_param ('notification', $notif);
@@ -157,7 +157,7 @@ class entryController extends ActionController {
 		if ($not_found) {
 			Error::error (
 				404,
-				array ('error' => array ('La page que vous cherchez n\'existe pas'))
+				array ('error' => array (Translate::t ('page_not_found')))
 			);
 		} else {
 			$this->view->entry = $entry;

+ 207 - 169
app/controllers/feedController.php

@@ -2,94 +2,114 @@
 
 class feedController extends ActionController {
 	public function firstAction () {
+		if (login_is_conf ($this->view->conf) && !is_logged ()) {
+			Error::error (
+				403,
+				array ('error' => array (Translate::t ('access_denied')))
+			);
+		}
+
 		$catDAO = new CategoryDAO ();
 		$catDAO->checkDefault ();
 	}
 
 	public function addAction () {
-		if (login_is_conf ($this->view->conf) && !is_logged ()) {
-			Error::error (
-				403,
-				array ('error' => array ('Vous n\'avez pas le droit d\'accéder à cette page'))
-			);
-		} else {
-			if (Request::isPost ()) {
-				$url = Request::param ('url_rss');
-				$cat = Request::param ('category');
-				$params = array ();
-
-				try {
-					$feed = new Feed ($url);
-					$feed->_category ($cat);
-					$feed->load ();
-
-					$feedDAO = new FeedDAO ();
-					$values = array (
-						'id' => $feed->id (),
-						'url' => $feed->url (),
-						'category' => $feed->category (),
-						'name' => $feed->name (),
-						'website' => $feed->website (),
-						'description' => $feed->description (),
-						'lastUpdate' => time ()
-					);
+		if (Request::isPost ()) {
+			$url = Request::param ('url_rss');
+			$cat = Request::param ('category');
+			$user = Request::param ('username');
+			$pass = Request::param ('password');
+			$params = array ();
 
-					if ($feedDAO->searchByUrl ($values['url'])) {
-						$notif = array (
-							'type' => 'bad',
-							'content' => 'Vous êtes déjà abonné à <em>' . $feed->name () . '</em>'
-						);
-						Session::_param ('notification', $notif);
-					} elseif ($feedDAO->addFeed ($values)) {
-						$entryDAO = new EntryDAO ();
-						$entries = $feed->entries ();
-
-						foreach ($entries as $entry) {
-							$values = $entry->toArray ();
-							$entryDAO->addEntry ($values);
-						}
+			try {
+				$feed = new Feed ($url);
+				$feed->_category ($cat);
 
-						// notif
-						$notif = array (
-							'type' => 'good',
-							'content' => 'Le flux <em>' . $feed->name () . '</em> a bien été ajouté'
-						);
-						Session::_param ('notification', $notif);
-						$params['id'] = $feed->id ();
-					} else {
-						// notif
-						$notif = array (
-							'type' => 'bad',
-							'content' => '<em>' . $feed->name () . '</em> n\' a pas pu être ajouté'
-						);
-						Session::_param ('notification', $notif);
-					}
-				} catch (FeedException $e) {
-					Log::record ($e->getMessage (), Log::ERROR);
+				$httpAuth = '';
+				if ($user != '' || $pass != '') {
+					$httpAuth = $user . ':' . $pass;
+				}
+				$feed->_httpAuth ($httpAuth);
+
+				$feed->load ();
+
+				$feedDAO = new FeedDAO ();
+				$values = array (
+					'id' => $feed->id (),
+					'url' => $feed->url (),
+					'category' => $feed->category (),
+					'name' => $feed->name (),
+					'website' => $feed->website (),
+					'description' => $feed->description (),
+					'lastUpdate' => time (),
+					'httpAuth' => $feed->httpAuth (),
+				);
+
+				if ($feedDAO->searchByUrl ($values['url'])) {
+					// on est déjà abonné à ce flux
 					$notif = array (
 						'type' => 'bad',
-						'content' => 'Un problème interne a été rencontré, le flux n\'a pas pu être ajouté'
+						'content' => Translate::t ('already_subscribed', $feed->name ())
 					);
 					Session::_param ('notification', $notif);
-				} catch (FileNotExistException $e) {
-					Log::record ($e->getMessage (), Log::ERROR);
-					// notif
+				} elseif (!$feedDAO->addFeed ($values)) {
+					// problème au niveau de la base de données
 					$notif = array (
 						'type' => 'bad',
-						'content' => 'Un problème de configuration a empêché l\'ajout du flux. Voir les logs pour plus d\'informations'
+						'content' => Translate::t ('feed_not_added', $feed->name ())
 					);
 					Session::_param ('notification', $notif);
-				} catch (Exception $e) {
-					// notif
+				} else {
+					$entryDAO = new EntryDAO ();
+					$entries = $feed->entries ();
+
+					// on calcule la date des articles les plus anciens qu'on accepte
+					$nb_month_old = $this->view->conf->oldEntries ();
+					$date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old);
+
+					// on ajoute les articles en masse sans vérification
+					foreach ($entries as $entry) {
+						if ($entry->date (true) >= $date_min) {
+							$values = $entry->toArray ();
+							$entryDAO->addEntry ($values);
+						}
+					}
+
+					// ok, ajout terminé
 					$notif = array (
-						'type' => 'bad',
-						'content' => 'L\'url <em>' . $url . '</em> est invalide'
+						'type' => 'good',
+						'content' => Translate::t ('feed_added', $feed->name ())
 					);
 					Session::_param ('notification', $notif);
-				}
 
-				Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => $params), true);
+					// permet de rediriger vers la page de conf du flux
+					$params['id'] = $feed->id ();
+				}
+			} catch (BadUrlException $e) {
+				Log::record ($e->getMessage (), Log::ERROR);
+				$notif = array (
+					'type' => 'bad',
+					'content' => Translate::t ('invalid_url', $url)
+				);
+				Session::_param ('notification', $notif);
+			} catch (FeedException $e) {
+				Log::record ($e->getMessage (), Log::ERROR);
+				$notif = array (
+					'type' => 'bad',
+					'content' => Translate::t ('internal_problem_feed')
+				);
+				Session::_param ('notification', $notif);
+			} catch (FileNotExistException $e) {
+				// Répertoire de cache n'existe pas
+				Log::record ($e->getMessage (), Log::ERROR);
+				$notif = array (
+					'type' => 'bad',
+					'content' => Translate::t ('internal_problem_feed')
+				);
+				Session::_param ('notification', $notif);
 			}
+
+			Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => $params), true);
 		}
 	}
 
@@ -98,6 +118,11 @@ class feedController extends ActionController {
 		$entryDAO = new EntryDAO ();
 
 		$id = Request::param ('id');
+		$force = Request::param ('force', false);
+
+		// on créé la liste des flux à mettre à actualiser
+		// si on veut mettre un flux à jour spécifiquement, on le met
+		// dans la liste, mais seul (permet d'automatiser le traitement)
 		$feeds = array ();
 		if ($id) {
 			$feed = $feedDAO->searchById ($id);
@@ -108,7 +133,7 @@ class feedController extends ActionController {
 			$feeds = $feedDAO->listFeedsOrderUpdate ();
 		}
 
-		// pour ne pas ajouter des entrées trop anciennes
+		// on calcule la date des articles les plus anciens qu'on accepte
 		$nb_month_old = $this->view->conf->oldEntries ();
 		$date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old);
 
@@ -118,6 +143,11 @@ class feedController extends ActionController {
 				$feed->load ();
 				$entries = $feed->entries ();
 
+				// ajout des articles en masse sans se soucier des erreurs
+				// On ne vérifie pas que l'article n'est pas déjà en BDD
+				// car demanderait plus de ressources
+				// La BDD refusera l'ajout de son côté car l'id doit être
+				// unique
 				foreach ($entries as $entry) {
 					if ($entry->date (true) >= $date_min) {
 						$values = $entry->toArray ();
@@ -125,37 +155,45 @@ class feedController extends ActionController {
 					}
 				}
 
+				// on indique que le flux vient d'être mis à jour en BDD
 				$feedDAO->updateLastUpdate ($feed->id ());
 			} catch (FeedException $e) {
 				Log::record ($e->getMessage (), Log::ERROR);
+				// TODO si on a une erreur ici, il faut mettre
+				// le flux à jour en BDD (error = 1) (issue #70)
 			}
 
+			// On arrête à 10 flux pour ne pas surcharger le serveur
+			// sauf si le paramètre $force est à vrai
 			$i++;
-			if ($i >= 10) {
+			if ($i >= 10 && !$force) {
 				break;
 			}
 		}
 
 		$entryDAO->cleanOldEntries ($nb_month_old);
 
-		// notif
 		$url = array ();
 		if ($i == 1) {
+			// on a mis un seul flux à jour
+			// reset permet de récupérer ce flux
 			$feed = reset ($feeds);
 			$notif = array (
 				'type' => 'good',
-				'content' => '<em>' . $feed->name () . '</em> a été mis à jour'
+				'content' => Translate::t ('feed_actualized', $feed->name ())
 			);
 			$url['params'] = array ('get' => 'f_' . $feed->id ());
-		} elseif ($i > 0) {
+		} elseif ($i > 1) {
+			// plusieurs flux on été mis à jour
 			$notif = array (
 				'type' => 'good',
-				'content' => $i . ' flux ont été mis à jour'
+				'content' => Translate::t ('n_feeds_actualized', $i)
 			);
 		} else {
+			// aucun flux n'a été mis à jour, oups
 			$notif = array (
 				'type' => 'bad',
-				'content' => 'Aucun flux n\'a pu être mis à jour'
+				'content' => Translate::t ('no_feed_actualized')
 			);
 		}
 
@@ -163,124 +201,124 @@ class feedController extends ActionController {
 			Session::_param ('notification', $notif);
 			Request::forward ($url, true);
 		} else {
+			// Une requête Ajax met un seul flux à jour.
+			// Comme en principe plusieurs requêtes ont lieu,
+			// on indique que "plusieurs flux ont été mis à jour".
+			// Cela permet d'avoir une notification plus proche du
+			// ressenti utilisateur
 			$notif = array (
 				'type' => 'good',
-				'content' => 'Les flux ont été mis à jour'
+				'content' => Translate::t ('feeds_actualized')
 			);
 			Session::_param ('notification', $notif);
+			// et on désactive le layout car ne sert à rien
 			$this->view->_useLayout (false);
 		}
 	}
 
 	public function massiveImportAction () {
-		if (login_is_conf ($this->view->conf) && !is_logged ()) {
-			Error::error (
-				403,
-				array ('error' => array ('Vous n\'avez pas le droit d\'accéder à cette page'))
-			);
-		} else {
-			$entryDAO = new EntryDAO ();
-			$feedDAO = new FeedDAO ();
-
-			$categories = Request::param ('categories', array ());
-			$feeds = Request::param ('feeds', array ());
-
-			$this->addCategories ($categories);
-
-			$nb_month_old = $this->view->conf->oldEntries ();
-			$date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old);
-
-			$error = false;
-			$i = 0;
-			foreach ($feeds as $feed) {
-				try {
-					$feed->load ();
-
-					// Enregistrement du flux
-					$values = array (
-						'id' => $feed->id (),
-						'url' => $feed->url (),
-						'category' => $feed->category (),
-						'name' => $feed->name (),
-						'website' => $feed->website (),
-						'description' => $feed->description (),
-						'lastUpdate' => 0
-					);
+		$entryDAO = new EntryDAO ();
+		$feedDAO = new FeedDAO ();
 
-					if (!$feedDAO->searchByUrl ($values['url'])) {
-						if (!$feedDAO->addFeed ($values)) {
-							$error = true;
-						}
+		$categories = Request::param ('categories', array ());
+		$feeds = Request::param ('feeds', array ());
+
+		// on ajoute les catégories en masse dans une fonction à part
+		$this->addCategories ($categories);
+
+		// on calcule la date des articles les plus anciens qu'on accepte
+		$nb_month_old = $this->view->conf->oldEntries ();
+		$date_min = time () - (60 * 60 * 24 * 30 * $nb_month_old);
+
+		// la variable $error permet de savoir si une erreur est survenue
+		// Le but est de ne pas arrêter l'import même en cas d'erreur
+		// L'utilisateur sera mis au courant s'il y a eu des erreurs, mais
+		// ne connaîtra pas les détails. Ceux-ci seront toutefois logguées
+		$error = false;
+		$i = 0;
+		foreach ($feeds as $feed) {
+			try {
+				$feed->load ();
+
+				$values = array (
+					'id' => $feed->id (),
+					'url' => $feed->url (),
+					'category' => $feed->category (),
+					'name' => $feed->name (),
+					'website' => $feed->website (),
+					'description' => $feed->description (),
+					'lastUpdate' => 0
+				);
+
+				// ajout du flux que s'il n'est pas déjà en BDD
+				if (!$feedDAO->searchByUrl ($values['url'])) {
+					if (!$feedDAO->addFeed ($values)) {
+						$error = true;
 					}
-				} catch (FeedException $e) {
-					$error = true;
-					Log::record ($e->getMessage (), Log::ERROR);
 				}
+			} catch (FeedException $e) {
+				$error = true;
+				Log::record ($e->getMessage (), Log::ERROR);
 			}
+		}
 
-			if ($error) {
-				$res = 'Les flux ont été importés mais des erreurs sont survenus';
-			} else {
-				$res = 'Les flux ont été importés';
-			}
-			$notif = array (
-				'type' => 'good',
-				'content' => $res
-			);
-			Session::_param ('notification', $notif);
-
-			Request::forward (array (
-				'c' => 'configure',
-				'a' => 'importExport'
-			), true);
+		if ($error) {
+			$res = Translate::t ('feeds_imported_with_errors');
+		} else {
+			$res = Translate::t ('feeds_imported');
 		}
+
+		$notif = array (
+			'type' => 'good',
+			'content' => $res
+		);
+		Session::_param ('notification', $notif);
+
+		// et on redirige vers la page import/export
+		Request::forward (array (
+			'c' => 'configure',
+			'a' => 'importExport'
+		), true);
 	}
 
 	public function deleteAction () {
-		if (login_is_conf ($this->view->conf) && !is_logged ()) {
-			Error::error (
-				403,
-				array ('error' => array ('Vous n\'avez pas le droit d\'accéder à cette page'))
-			);
-		} else {
-			$type = Request::param ('type', 'feed');
-			$id = Request::param ('id');
+		$type = Request::param ('type', 'feed');
+		$id = Request::param ('id');
 
-			$feedDAO = new FeedDAO ();
-			if ($type == 'category') {
-				if ($feedDAO->deleteFeedByCategory ($id)) {
-					$notif = array (
-						'type' => 'good',
-						'content' => 'La catégorie a été vidée'
-					);
-				} else {
-					$notif = array (
-						'type' => 'bad',
-						'content' => 'Un problème est survenu'
-					);
-				}
+		$feedDAO = new FeedDAO ();
+		if ($type == 'category') {
+			if ($feedDAO->deleteFeedByCategory ($id)) {
+				$notif = array (
+					'type' => 'good',
+					'content' => Translate::t ('category_emptied')
+				);
 			} else {
-				if ($feedDAO->deleteFeed ($id)) {
-					$notif = array (
-						'type' => 'good',
-						'content' => 'Le flux a été supprimé'
-					);
-				} else {
-					$notif = array (
-						'type' => 'bad',
-						'content' => 'Un problème est survenu'
-					);
-				}
+				$notif = array (
+					'type' => 'bad',
+					'content' => Translate::t ('error_occured')
+				);
 			}
-
-			Session::_param ('notification', $notif);
-
-			if ($type == 'category') {
-				Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true);
+		} else {
+			if ($feedDAO->deleteFeed ($id)) {
+				$notif = array (
+					'type' => 'good',
+					'content' => Translate::t ('feed_deleted')
+				);
 			} else {
-				Request::forward (array ('c' => 'configure', 'a' => 'feed'), true);
+				$notif = array (
+					'type' => 'bad',
+					'content' => Translate::t ('error_occured')
+				);
 			}
 		}
+
+		Session::_param ('notification', $notif);
+
+		if ($type == 'category') {
+			Request::forward (array ('c' => 'configure', 'a' => 'categorize'), true);
+		} else {
+			Request::forward (array ('c' => 'configure', 'a' => 'feed'), true);
+		}
 	}
 
 	private function addCategories ($categories) {

+ 110 - 169
app/controllers/indexController.php

@@ -6,117 +6,136 @@ class indexController extends ActionController {
 	private $mode = 'all';
 
 	public function indexAction () {
-		View::appendScript (Url::display ('/scripts/shortcut.js'));
-		View::appendScript (Url::display (array ('c' => 'javascript', 'a' => 'main')));
-		View::appendScript (Url::display (array ('c' => 'javascript', 'a' => 'actualize')));
+		if (Request::param ('output') == 'rss') {
+			$this->view->_useLayout (false);
+		} else {
+			View::appendScript (Url::display ('/scripts/shortcut.js'));
+			View::appendScript (Url::display (array ('c' => 'javascript', 'a' => 'main')));
+			View::appendScript (Url::display (array ('c' => 'javascript', 'a' => 'actualize')));
+		}
 
 		$entryDAO = new EntryDAO ();
 		$feedDAO = new FeedDAO ();
 		$catDAO = new CategoryDAO ();
 
-		$error = false;
-
-		// pour optimiser
-		$page = Request::param ('page', 1);
-		$entryDAO->_nbItemsPerPage ($this->view->conf->postsPerPage ());
-		$entryDAO->_currentPage ($page);
-
-		// récupération de la catégorie/flux à filtrer
-		$this->initFilter ();
-		// Compte le nombre d'articles non lus en prenant en compte le filtre
-		$this->countNotRead ();
-		// mode de vue (tout ou seulement non lus)
-		$this->initCurrentMode ();
-		// ordre de listage des flux
-		$order = Session::param ('order', $this->view->conf->sortOrder ());
-		// recherche sur les titres (pour le moment)
-		$search = Request::param ('search');
-
-		// Récupère les flux par catégorie, favoris ou tous
-		if ($this->get['type'] == 'all') {
-			$entries = $entryDAO->listEntries ($this->mode, $search, $order);
-			View::prependTitle ('Vos flux RSS - ');
-		} elseif ($this->get['type'] == 'favoris') {
-			$entries = $entryDAO->listFavorites ($this->mode, $search, $order);
-			View::prependTitle ('Vos favoris - ');
-		} elseif ($this->get['type'] == 'public') {
-			$entries = $entryDAO->listPublic ($this->mode, $search, $order);
-			View::prependTitle ('Public - ');
-		} elseif ($this->get != false) {
-			if ($this->get['type'] == 'c') {
-				$cat = $catDAO->searchById ($this->get['filter']);
-
-				if ($cat) {
-					$entries = $entryDAO->listByCategory ($this->get['filter'], $this->mode, $search, $order);
-					View::prependTitle ($cat->name () . ' - ');
-				} else {
-					$error = true;
-				}
-			} elseif ($this->get['type'] == 'f') {
-				$feed = $feedDAO->searchById ($this->get['filter']);
-
-				if ($feed) {
-					$entries = $entryDAO->listByFeed ($this->get['filter'], $this->mode, $search, $order);
-					$this->view->get_c = $feed->category ();
-					View::prependTitle ($feed->name () . ' - ');
-				} else {
-					$error = true;
+		$this->view->cat_aside = $catDAO->listCategories ();
+		$this->view->nb_favorites = $entryDAO->countFavorites ();
+		$this->view->nb_total = $entryDAO->count ();
+
+		$this->view->get_c = '';
+		$this->view->get_f = '';
+
+		$type = $this->getType ();
+		$error = $this->checkAndProcessType ($type);
+		if (!$error) {
+			// On récupère les différents éléments de filtrage
+			$this->view->state = $state = Request::param ('state', $this->view->conf->defaultView ());
+			$filter = Request::param ('search', '');
+			$this->view->order = $order = Request::param ('order', $this->view->conf->sortOrder ());
+			$nb = Request::param ('nb', $this->view->conf->postsPerPage ());
+			$first = Request::param ('next', '');
+
+			try {
+				// EntriesGetter permet de déporter la complexité du filtrage
+				$getter = new EntriesGetter ($type, $state, $filter, $order, $nb, $first);
+				$getter->execute ();
+				$entries = $getter->getPaginator ();
+
+				// Si on a récupéré aucun article "non lus"
+				// on essaye de récupérer tous les articles
+				if ($state == 'not_read' && $entries->isEmpty ()) {
+					$this->view->state = 'all';
+					$getter->_state ('all');
+					$getter->execute ();
+					$entries = $getter->getPaginator ();
 				}
-			} else {
-				$error = true;
+
+				$this->view->entryPaginator = $entries;
+			} catch(EntriesGetterException $e) {
+				Log::record ($e->getMessage (), Log::NOTICE);
+				Error::error (
+					404,
+					array ('error' => array (Translate::t ('page_not_found')))
+				);
 			}
 		} else {
-			$error = true;
-		}
-
-		if ($error) {
 			Error::error (
 				404,
-				array ('error' => array ('La page que vous cherchez n\'existe pas'))
+				array ('error' => array (Translate::t ('page_not_found')))
 			);
-		} else {
-			$this->view->mode = $this->mode;
-			$this->view->order = $order;
-
-			try {
-				$this->view->entryPaginator = $entryDAO->getPaginator ($entries);
-			} catch (CurrentPagePaginationException $e) { }
-
-			$this->view->cat_aside = $catDAO->listCategories ();
-			$this->view->nb_favorites = $entryDAO->countFavorites ();
-			$this->view->nb_total = $entryDAO->count ();
-
-			if (Request::param ('output', '') == 'rss') {
-				$this->view->_useLayout (false);
-			}
 		}
 	}
 
-	public function aboutAction () {
-		View::prependTitle ('À propos - ');
-	}
-
-	public function changeModeAction () {
-		$mode = Request::param ('mode');
+	/*
+	 * Détermine le type d'article à récupérer :
+	 * "tous", "favoris", "public", "catégorie" ou "flux"
+	 */
+	private function getType () {
+		$get = Request::param ('get', 'all');
+		$typeGet = $get[0];
+		$id = substr ($get, 2);
 
-		if ($mode == 'not_read') {
-			Session::_param ('mode', 'not_read');
-		} else {
-			Session::_param ('mode', 'all');
+		$type = null;
+		if ($get == 'all' || $get == 'favoris' || $get == 'public') {
+			$type = array (
+				'type' => $get,
+				'id' => $get
+			);
+		} elseif ($typeGet == 'f' || $typeGet == 'c') {
+			$type = array (
+				'type' => $typeGet,
+				'id' => $id
+			);
 		}
 
-		Request::forward (array (), true);
+		return $type;
 	}
-	public function changeOrderAction () {
-		$order = Request::param ('order');
-
-		if ($order == 'low_to_high') {
-			Session::_param ('order', 'low_to_high');
+	/*
+	 * Vérifie que la catégorie / flux sélectionné existe
+	 * + Initialise correctement les variables de vue get_c et get_f
+	 * + Initialise le titre
+	 */
+	private function checkAndProcessType ($type) {
+		if ($type['type'] == 'all') {
+			View::prependTitle (Translate::t ('your_rss_feeds') . ' - ');
+			$this->view->get_c = $type['type'];
+			return false;
+		} elseif ($type['type'] == 'favoris') {
+			View::prependTitle (Translate::t ('your_favorites') . ' - ');
+			$this->view->get_c = $type['type'];
+			return false;
+		} elseif ($type['type'] == 'public') {
+			View::prependTitle (Translate::t ('public') . ' - ');
+			$this->view->get_c = $type['type'];
+			return false;
+		} elseif ($type['type'] == 'c') {
+			$catDAO = new CategoryDAO ();
+			$cat = $catDAO->searchById ($type['id']);
+			if ($cat) {
+				View::prependTitle ($cat->name () . ' - ');
+				$this->view->get_c = $type['id'];
+				return false;
+			} else {
+				return true;
+			}
+		} elseif ($type['type'] == 'f') {
+			$feedDAO = new FeedDAO ();
+			$feed = $feedDAO->searchById ($type['id']);
+			if ($feed) {
+				View::prependTitle ($feed->name () . ' - ');
+				$this->view->get_f = $type['id'];
+				$this->view->get_c = $feed->category ();
+				return false;
+			} else {
+				return true;
+			}
 		} else {
-			Session::_param ('order', 'high_to_low');
+			return true;
 		}
+	}
 
-		Request::forward (array (), true);
+	public function aboutAction () {
+		View::prependTitle (Translate::t ('about') . ' - ');
 	}
 
 	public function loginAction () {
@@ -143,7 +162,7 @@ class indexController extends ActionController {
 		} else {
 			$res = array ();
 			$res['status'] = 'failure';
-			$res['reason'] = 'L\'identifiant est invalide';
+			$res['reason'] = Translate::t ('invalid_login');
 		}
 
 		$this->view->res = json_encode ($res);
@@ -153,82 +172,4 @@ class indexController extends ActionController {
 		$this->view->_useLayout (false);
 		Session::_param ('mail');
 	}
-
-	private function initFilter () {
-		$get = Request::param ('get');
-		$this->view->get_c = false;
-		$this->view->get_f = false;
-
-		$typeGet = $get[0];
-		$filter = substr ($get, 2);
-
-		if ($get == 'favoris') {
-			$this->view->get_c = $get;
-
-			$this->get = array (
-				'type' => $get,
-				'filter' => $get
-			);
-		} elseif ($get == 'public') {
-			$this->view->get_c = $get;
-
-			$this->get = array (
-				'type' => $get,
-				'filter' => $get
-			);
-		} elseif ($get == false) {
-			$this->get = array (
-				'type' => 'all',
-				'filter' => 'all'
-			);
-		} else {
-			if ($typeGet == 'f') {
-				$this->view->get_f = $filter;
-
-				$this->get = array (
-					'type' => $typeGet,
-					'filter' => $filter
-				);
-			} elseif ($typeGet == 'c') {
-				$this->view->get_c = $filter;
-
-				$this->get = array (
-					'type' => $typeGet,
-					'filter' => $filter
-				);
-			} else {
-				$this->get = false;
-			}
-		}
-	}
-
-	private function countNotRead () {
-		$entryDAO = new EntryDAO ();
-
-		if ($this->get != false) {
-			if ($this->get['type'] == 'all') {
-				$this->nb_not_read = $this->view->nb_not_read;
-			} elseif ($this->get['type'] == 'favoris') {
-				$this->nb_not_read = $entryDAO->countNotReadFavorites ();
-			} elseif ($this->get['type'] == 'c') {
-				$this->nb_not_read = $entryDAO->countNotReadByCat ($this->get['filter']);
-			} elseif ($this->get['type'] == 'f') {
-				$this->nb_not_read = $entryDAO->countNotReadByFeed ($this->get['filter']);
-			}
-		}
-	}
-
-	private function initCurrentMode () {
-		$default_view = $this->view->conf->defaultView ();
-		$mode = Session::param ('mode');
-		if ($mode == false) {
-			if ($default_view == 'not_read' && $this->nb_not_read < 1) {
-				$mode = 'all';
-			} else {
-				$mode = $default_view;
-			}
-		}
-
-		$this->mode = $mode;
-	}
 }

+ 270 - 0
app/i18n/en.php

@@ -0,0 +1,270 @@
+<?php
+
+return array (
+	// LAYOUT
+	'login'				=> 'Login',
+	'logout'			=> 'Logout',
+	'search'			=> 'Search words or #tags',
+
+	'configuration'			=> 'Configuration',
+	'general_and_reading'		=> 'General and reading',
+	'categories'			=> 'Categories',
+	'category'			=> 'Category',
+	'shortcuts'			=> 'Shortcuts',
+	'about'				=> 'About',
+
+	'your_rss_feeds'		=> 'Your RSS feeds',
+	'add_rss_feed'			=> 'Add a RSS feed',
+	'no_rss_feed'			=> 'No RSS feed',
+	'import_export_opml'		=> 'Import / export (OPML)',
+
+	'subscription_management'	=> 'Subscriptions management',
+	'all_feeds'			=> 'All (%d)',
+	'favorite_feeds'		=> 'Favorites (%d)',
+	'not_read'			=> '%d unread',
+	'not_reads'			=> '%d unread',
+
+	'filter'			=> 'Filter',
+	'see_website'			=> 'See website',
+	'administration'		=> 'Manage',
+	'actualize'			=> 'Actualize',
+
+	'mark_read'			=> 'Mark as read',
+	'mark_favorite'			=> 'Mark as favorite',
+	'mark_all_read'			=> 'Mark all as read',
+	'mark_feed_read'		=> 'Mark feed as read',
+	'mark_cat_read'			=> 'Mark category as read',
+	'before_one_day'		=> 'Before one day',
+	'before_one_week'		=> 'Before one week',
+	'display'			=> 'Display',
+	'show_all_articles'		=> 'Show all articles',
+	'show_not_reads'		=> 'Show only unread',
+	'older_first'			=> 'Oldest first',
+	'newer_first'			=> 'Newer first',
+
+	// CONTROLLERS
+	'article_published_on'		=> 'This article originally appeared on <a href="%s">%s</a>',
+	'article_published_on_author'	=> 'This article originally appeared on <a href="%s">%s</a> by %s',
+
+	'access_denied'			=> 'You don\'t have permission to access this page',
+	'page_not_found'		=> 'You are looking for a page which doesn\'t exist',
+	'error_occurred'		=> 'An error occured',
+	'error_occurred_update'		=> 'An error occured during update',
+
+	'default_category'		=> 'Uncategorized',
+	'categories_updated'		=> 'Categories have been updated',
+	'categories_management'		=> 'Categories management',
+	'feed_updated'			=> 'Feed has been updated',
+	'rss_feed_management'		=> 'RSS feeds management',
+	'configuration_updated'		=> 'Configuration has been updated',
+	'general_and_reading_management'=> 'General and reading management',
+	'shortcuts_updated'		=> 'Shortcuts have been updated',
+	'shortcuts_management'		=> 'Shortcuts management',
+	'feeds_marked_read'		=> 'Feeds have been marked as read',
+	'updated'			=> 'Modifications have been updated',
+
+	'already_subscribed'		=> 'You have already subscribed to <em>%s</em>',
+	'feed_added'			=> 'RSS feed <em>%s</em> has been added',
+	'feed_not_added'		=> '<em>%s</em> could not be added',
+	'internal_problem_feed'		=> 'An internal problem occured, RSS feed could not be added',
+	'invalid_url'			=> 'URL <em>%s</em> is invalid',
+	'feed_actualized'		=> '<em>%s</em> has been updated',
+	'n_feeds_actualized'		=> '%d feeds have been updated',
+	'feeds_actualized'		=> 'RSS feeds have been updated',
+	'no_feed_actualized'		=> 'No RSS feed has been updated',
+	'feeds_imported_with_errors'	=> 'Feeds have been imported but errors occured',
+	'feeds_imported'		=> 'Feeds have been imported',
+	'category_emptied'		=> 'Category has been emptied',
+	'feed_deleted'			=> 'Feed has been deleted',
+
+	'your_rss_feeds'		=> 'Your RSS feeds',
+	'your_favorites'		=> 'Your favorites',
+	'public'			=> 'Public',
+	'invalid_login'			=> 'Login is invalid',
+
+	// VIEWS
+	'save'				=> 'Save',
+	'delete'			=> 'Delete',
+	'cancel'			=> 'Cancel',
+
+	'back_to_rss_feeds'		=> '← Go back to your RSS feeds',
+	'feeds_moved_category_deleted'	=> 'When you delete a category, their feeds are automatically classified under <em>%s</em>.',
+	'category_number'		=> 'Category n°%d',
+	'ask_empty'			=> 'Clear ?',
+	'number_feeds'			=> '%d feeds',
+	'can_not_be_deleted'		=> 'Can not be deleted',
+	'add_category'			=> 'Add a category',
+	'new_category'			=> 'New category',
+
+	'javascript_for_shortcuts'	=> 'Javascript must be enabled in order to use shortcuts',
+	'javascript_should_be_activated'=> 'Javascript must be enabled',
+	'shift_for_all_read'		=> '+ <code>shift</code> to mark all articles as read',
+	'see_on_website'		=> 'See article on its original website',
+	'next_article'			=> 'Skip to the next article',
+	'shift_for_last'		=> '+ <code>shift</code> to skip to the last article of page',
+	'previous_article'		=> 'Skip to the previous article',
+	'shift_for_first'		=> '+ <code>shift</code> to skip to the first article of page',
+	'next_page'			=> 'Skip to the next page',
+	'previous_page'			=> 'Skip to the previous page',
+
+	'file_to_import'		=> 'File to import',
+	'import'			=> 'Import',
+	'export'			=> 'Export',
+	'or'				=> 'or',
+
+	'informations'			=> 'Informations',
+	'website_url'			=> 'Website URL',
+	'feed_url'			=> 'Feed URL',
+	'number_articles'		=> 'Number of articles',
+	'categorize'			=> 'Store in a category',
+	'advanced'			=> 'Advanced',
+	'show_in_all_flux'		=> 'Show in principal stream',
+	'yes'				=> 'Yes',
+	'no'				=> 'No',
+	'css_path_on_website'		=> 'Articles CSS path on original website',
+	'retrieve_truncated_feeds'	=> 'Retrieves truncated RSS feeds (attention, requires more time!)',
+	'http_authentication'		=> 'HTTP Authentication',
+	'http_username'			=> 'HTTP username',
+	'http_password'			=> 'HTTP password',
+	'blank_to_disable'		=> 'Leave blank to disable',
+	'not_yet_implemented'		=> 'Not yet implemented',
+	'access_protected_feeds'	=> 'Connection allows to access HTTP protected RSS feeds',
+	'no_selected_feed'		=> 'No feed selected.',
+	'think_to_add'			=> 'Think to add RSS feeds!',
+
+	'general_configuration'		=> 'General configuration',
+	'language'			=> 'Language',
+	'delete_articles_every'		=> 'Remove articles every',
+	'month'				=> 'months',
+	'persona_connection_email'	=> 'Login mail address (use <a href="https://persona.org/">Persona</a>)',
+	'reading_configuration'		=> 'Reading configuration',
+	'articles_per_page'		=> 'Number of articles per page',
+	'default_view'			=> 'Default view',
+	'sort_order'			=> 'Sort order',
+	'display_articles_unfolded'	=> 'Show articles unfolded by default',
+	'auto_read_when'		=> 'Mark automatically as read when',
+	'article_selected'		=> 'Article is selected',
+	'article_open_on_website'	=> 'Article is opened on its original website',
+	'page_loaded'			=> 'Page is loaded',
+	'your_shaarli'			=> 'Your Shaarli',
+	'sharing'			=> 'Sharing',
+	'share'				=> 'Share',
+	'by_email'			=> 'By mail',
+	'on_shaarli'			=> 'On your Shaarli',
+
+	'note'				=> 'Note',
+	'add_note'			=> 'Add a note',
+	'update_note'			=> 'Update your note',
+	'ask_public_article'		=> 'Public article?',
+	'article'			=> 'Article',
+	'title'				=> 'Title',
+	'author'			=> 'Author',
+	'publication_date'		=> 'Date of publication',
+
+	'load_more'			=> 'Load more articles',
+	'nothing_to_load'		=> 'There is no more articles',
+
+	'rss_feeds_of'			=> 'RSS feed of %s',
+
+	'refresh'			=> 'Refresh',
+
+	'today'				=> 'Today',
+	'yesterday'			=> 'Yesterday',
+	'before_yesterday'		=> 'Before yesterday',
+	'by_author'			=> 'By <em>%s</em>',
+	'related_tags'			=> 'Related tags',
+	'no_feed_to_display'		=> 'No feed to show.',
+
+	'about_freshrss'		=> 'About FreshRSS',
+	'project_website'		=> 'Project website',
+	'lead_developer'		=> 'Lead developer',
+	'website'			=> 'Website',
+	'bugs_reports'			=> 'Bugs reports',
+	'github_or_email'		=> '<a href="https://github.com/marienfressinaud/FreshRSS/issues">on Github</a> or <a href="mailto:dev@marienfressinaud.fr">by mail</a>',
+	'license'			=> 'License',
+	'agpl3'				=> '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+	'freshrss_description'		=> 'FreshRSS is a RSS feeds aggregator to self-host like <a href="http://rsslounge.aditu.de/">RSSLounge</a>, <a href="http://tt-rss.org/redmine/projects/tt-rss/wiki">TinyTinyRSS</a> or <a href="http://projet.idleman.fr/leed/">Leed</a>. It is light and easy to take in hand while being powerful and configurable tool. Objective is to provide a serious alternative to Google Reader.',
+	'credits'			=> 'Credits',
+	'credits_content'		=> 'Some design elements come from <a href="http://twitter.github.io/bootstrap/">Bootstrap</a> although FreshRSS doesn\'t use this framework. <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">Icons</a> come from <a href="https://www.gnome.org/">GNOME project</a>. <em>Open Sans</em> font police used has been created by <a href="https://www.google.com/webfonts/specimen/Open+Sans">Steve Matteson</a>. Favicons are collected with <a href="https://getfavicon.appspot.com/">getFavicon API</a>. FreshRSS is based on <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, a PHP framework.',
+
+	// DATE
+	'january'			=> 'january',
+	'february'			=> 'february',
+	'march'				=> 'march',
+	'april'				=> 'april',
+	'may'				=> 'may',
+	'june'				=> 'june',
+	'july'				=> 'july',
+	'august'			=> 'august',
+	'september'			=> 'september',
+	'october'			=> 'october',
+	'november'			=> 'november',
+	'december'			=> 'december',
+	// special format for date() function
+	'Jan'				=> '\J\a\n\u\a\r\y',
+	'Feb'				=> '\F\e\b\r\u\a\r\y',
+	'Mar'				=> '\M\a\r\c\h',
+	'Apr'				=> '\A\p\r\i\l',
+	'May'				=> '\M\a\y',
+	'Jun'				=> '\J\u\n\e',
+	'Jul'				=> '\J\u\l\y',
+	'Aug'				=> '\A\u\g\u\s\t',
+	'Sep'				=> '\S\e\p\t\e\m\b\e\r',
+	'Oct'				=> '\O\c\t\o\b\e\r',
+	'Nov'				=> '\N\o\v\e\m\b\e\r',
+	'Dec'				=> '\D\e\c\e\m\b\e\r',
+	// format for date() function, %s allows to indicate month in letter
+	'format_date'			=> '%s dS Y',
+	'format_date_hour'		=> '%s dS Y \a\t H\.i',
+
+	// INSTALLATION
+	'freshrss_installation'		=> 'Installation - FreshRSS',
+	'freshrss'			=> 'FreshRSS',
+	'installation_step'		=> 'Installation - step %d',
+	'steps'				=> 'Steps',
+	'checks'			=> 'Checks',
+	'bdd_configuration'		=> 'Database configuration',
+	'this_is_the_end'		=> 'This is the end',
+
+	'ok'				=> 'Ok!',
+	'congratulations'		=> 'Congratulations!',
+	'attention'			=> 'Attention!',
+	'damn'				=> 'Damn!',
+	'oops'				=> 'Oops!',
+	'next_step'			=> 'Go to the next step',
+
+	'language_defined'		=> 'Language has been defined.',
+	'choose_language'		=> 'Choose a language for FreshRSS',
+
+	'javascript_is_better'		=> 'FreshRSS is more pleasant with Javascript enabled',
+	'php_is_ok'			=> 'Your PHP version is %s and it\'s compatible with FreshRSS',
+	'php_is_nok'			=> 'Your PHP version is %s. You must have at least version %s',
+	'minz_is_ok'			=> 'You have Minz framework',
+	'minz_is_nok'			=> 'You haven\'t Minz framework. You should execute <em>build.sh</em> script or <a href="https://github.com/marienfressinaud/MINZ">download it on Github</a> and install in <em>%s</em> directory the content of its <em>/lib</em> directory.',
+	'curl_is_ok'			=> 'You have version %s of cURL',
+	'curl_is_nok'			=> 'You haven\'t cURL',
+	'pdomysql_is_ok'		=> 'You have PDO and its driver for MySQL',
+	'pdomysql_is_nok'		=> 'You haven\'t PDO or its driver for MySQL',
+	'cache_is_ok'			=> 'Permissions on cache directory are good',
+	'log_is_ok'			=> 'Permissions on logs directory are good',
+	'conf_is_ok'			=> 'Permissions on configuration directory are good',
+	'data_is_ok'			=> 'Permissions on data directory are good',
+	'file_is_nok'			=> 'Check permissions on <em>%s</em> directory. HTTP server must have rights to write into',
+	'fix_errors_before'		=> 'Fix errors before skip to the next step.',
+
+	'general_conf_is_ok'		=> 'General configuration has been saved.',
+	'random_string'			=> 'Random string',
+	'change_value'			=> 'You should change this value by any other',
+	'base_url'			=> 'Base URL',
+	'do_not_change_if_doubt'	=> 'Don\'t change if you doubt about it',
+
+	'bdd_conf_is_ok'		=> 'Database configuration has been saved.',
+	'host'				=> 'Host',
+	'username'			=> 'Username',
+	'password'			=> 'Password',
+	'bdd'				=> 'Database',
+
+	'installation_is_ok'		=> 'Installation process is finished. You must delete <em>install.php</em> file to access FreshRSS... or simply click on following button :)',
+	'finish_installation'		=> 'Finish installation',
+	'install_not_deleted'		=> 'Something was going wrong, you muste delete <em>%s</em> file manually.',
+);

+ 270 - 0
app/i18n/fr.php

@@ -0,0 +1,270 @@
+<?php
+
+return array (
+	// LAYOUT
+	'login'				=> 'Connexion',
+	'logout'			=> 'Déconnexion',
+	'search'			=> 'Rechercher un terme ou des #tags',
+
+	'configuration'			=> 'Configuration',
+	'general_and_reading'		=> 'Général et lecture',
+	'categories'			=> 'Catégories',
+	'category'			=> 'Catégorie',
+	'shortcuts'			=> 'Raccourcis',
+	'about'				=> 'À propos',
+
+	'your_rss_feeds'		=> 'Vos flux RSS',
+	'add_rss_feed'			=> 'Ajouter un flux RSS',
+	'no_rss_feed'			=> 'Aucun flux RSS',
+	'import_export_opml'		=> 'Importer / exporter (OPML)',
+
+	'subscription_management'	=> 'Gestion des abonnements',
+	'all_feeds'			=> 'Tous (%d)',
+	'favorite_feeds'		=> 'Favoris (%d)',
+	'not_read'			=> '%d non lu',
+	'not_reads'			=> '%d non lus',
+
+	'filter'			=> 'Filtrer',
+	'see_website'			=> 'Voir le site',
+	'administration'		=> 'Gestion',
+	'actualize'			=> 'Actualiser',
+
+	'mark_read'			=> 'Marquer comme lu',
+	'mark_favorite'			=> 'Mettre en favori',
+	'mark_all_read'			=> 'Tout marquer comme lu',
+	'mark_feed_read'		=> 'Marquer le flux comme lu',
+	'mark_cat_read'			=> 'Marquer la catégorie comme lue',
+	'before_one_day'		=> 'Antérieurs à 1 jour',
+	'before_one_week'		=> 'Antérieurs à 1 semaine',
+	'display'			=> 'Affichage',
+	'show_all_articles'		=> 'Afficher tous les articles',
+	'show_not_reads'		=> 'Afficher les non lus',
+	'older_first'			=> 'Plus anciens en premier',
+	'newer_first'			=> 'Plus récents en premier',
+
+	// CONTROLLERS
+	'article_published_on'		=> 'Article publié initialement sur <a href="%s">%s</a>',
+	'article_published_on_author'	=> 'Article publié initialement sur <a href="%s">%s</a> par %s',
+
+	'access_denied'			=> 'Vous n\'avez pas le droit d\'accéder à cette page',
+	'page_not_found'		=> 'La page que vous cherchez n\'existe pas',
+	'error_occurred'		=> 'Une erreur est survenue',
+	'error_occurred_update'		=> 'Une erreur est survenue lors de la mise à jour',
+
+	'default_category'		=> 'Sans catégorie',
+	'categories_updated'		=> 'Les catégories ont été mises à jour',
+	'categories_management'		=> 'Gestion des catégories',
+	'feed_updated'			=> 'Le flux a été mis à jour',
+	'rss_feed_management'		=> 'Gestion des flux RSS',
+	'configuration_updated'		=> 'La configuration a été mise à jour',
+	'general_and_reading_management'=> 'Gestion générale et affichage',
+	'shortcuts_updated'		=> 'Les raccourcis ont été mis à jour',
+	'shortcuts_management'		=> 'Gestion des raccourcis',
+	'feeds_marked_read'		=> 'Les flux ont été marqués comme lu',
+	'updated'			=> 'Modifications enregistrées',
+
+	'already_subscribed'		=> 'Vous êtes déjà abonné à <em>%s</em>',
+	'feed_added'			=> 'Le flux <em>%s</em> a bien été ajouté',
+	'feed_not_added'		=> '<em>%s</em> n\' a pas pu être ajouté',
+	'internal_problem_feed'		=> 'Un problème interne a été rencontré, le flux n\'a pas pu être ajouté',
+	'invalid_url'			=> 'L\'url <em>%s</em> est invalide',
+	'feed_actualized'		=> '<em>%s</em> a été mis à jour',
+	'n_feeds_actualized'		=> '%d flux ont été mis à jour',
+	'feeds_actualized'		=> 'Les flux ont été mis à jour',
+	'no_feed_actualized'		=> 'Aucun flux n\'a pu être mis à jour',
+	'feeds_imported_with_errors'	=> 'Les flux ont été importés mais des erreurs sont survenues',
+	'feeds_imported'		=> 'Les flux ont été importés',
+	'category_emptied'		=> 'La catégorie a été vidée',
+	'feed_deleted'			=> 'Le flux a été supprimé',
+
+	'your_rss_feeds'		=> 'Vos flux RSS',
+	'your_favorites'		=> 'Vos favoris',
+	'public'			=> 'Public',
+	'invalid_login'			=> 'L\'identifiant est invalide',
+
+	// VIEWS
+	'save'				=> 'Enregistrer',
+	'delete'			=> 'Supprimer',
+	'cancel'			=> 'Annuler',
+
+	'back_to_rss_feeds'		=> '← Retour à vos flux RSS',
+	'feeds_moved_category_deleted'	=> 'Lors de la suppression d\'une catégorie, ses flux seront automatiquement classés dans <em>%s</em>.',
+	'category_number'		=> 'Catégorie n°%d',
+	'ask_empty'			=> 'Vider ?',
+	'number_feeds'			=> '%d flux',
+	'can_not_be_deleted'		=> 'Ne peut pas être supprimée',
+	'add_category'			=> 'Ajouter une catégorie',
+	'new_category'			=> 'Nouvelle catégorie',
+
+	'javascript_for_shortcuts'	=> 'Le javascript doit être activé pour pouvoir profiter des raccourcis',
+	'javascript_should_be_activated'=> 'Le javascript doit être activé',
+	'shift_for_all_read'		=> '+ <code>shift</code> pour marquer tous les articles comme lus',
+	'see_on_website'		=> 'Voir l\'article sur le site d\'origine',
+	'next_article'			=> 'Passer à l\'article suivant',
+	'shift_for_last'		=> '+ <code>shift</code> pour passer au dernier article de la page',
+	'previous_article'		=> 'Passer à l\'article précédent',
+	'shift_for_first'		=> '+ <code>shift</code> pour passer au premier article de la page',
+	'next_page'			=> 'Passer à la page suivante',
+	'previous_page'			=> 'Passer à la page précédente',
+
+	'file_to_import'		=> 'Fichier à importer',
+	'import'			=> 'Importer',
+	'export'			=> 'Exporter',
+	'or'				=> 'ou',
+
+	'informations'			=> 'Informations',
+	'website_url'			=> 'URL du site',
+	'feed_url'			=> 'URL du flux',
+	'number_articles'		=> 'Nombre d\'articles',
+	'categorize'			=> 'Ranger dans une catégorie',
+	'advanced'			=> 'Avancé',
+	'show_in_all_flux'		=> 'Afficher dans le flux principal',
+	'yes'				=> 'Oui',
+	'no'				=> 'Non',
+	'css_path_on_website'		=> 'Chemin CSS des articles sur le site d\'origine',
+	'retrieve_truncated_feeds'	=> 'Permet de récupérer les flux tronqués (attention, demande plus de temps !)',
+	'http_authentication'		=> 'Authentification HTTP',
+	'http_username'			=> 'Identifiant HTTP',
+	'http_password'			=> 'Mot de passe HTTP',
+	'blank_to_disable'		=> 'Laissez vide pour désactiver',
+	'not_yet_implemented'		=> 'Pas encore implémenté',
+	'access_protected_feeds'	=> 'La connexion permet d\'accéder aux flux protégés par une authentification HTTP',
+	'no_selected_feed'		=> 'Aucun flux sélectionné.',
+	'think_to_add'			=> 'Pensez à en ajouter !',
+
+	'general_configuration'		=> 'Configuration générale',
+	'language'			=> 'Langue',
+	'delete_articles_every'		=> 'Supprimer les articles tous les',
+	'month'				=> 'mois',
+	'persona_connection_email'	=> 'Adresse mail de connexion (utilise <a href="https://persona.org/">Persona</a>)',
+	'reading_configuration'		=> 'Configuration de lecture',
+	'articles_per_page'		=> 'Nombre d\'articles par page',
+	'default_view'			=> 'Vue par défaut',
+	'sort_order'			=> 'Ordre de tri',
+	'display_articles_unfolded'	=> 'Afficher les articles dépliés par défaut',
+	'auto_read_when'		=> 'Marquer automatiquement comme lu lorsque',
+	'article_selected'		=> 'L\'article est sélectionné',
+	'article_open_on_website'	=> 'L\'article est ouvert sur le site d\'origine',
+	'page_loaded'			=> 'La page est chargée',
+	'your_shaarli'			=> 'Votre Shaarli',
+	'sharing'			=> 'Partage',
+	'share'				=> 'Partager',
+	'by_email'			=> 'Par mail',
+	'on_shaarli'			=> 'Sur votre Shaarli',
+
+	'note'				=> 'Note',
+	'add_note'			=> 'Ajouter une note',
+	'update_note'			=> 'Modifier votre note',
+	'ask_public_article'		=> 'Article public ?',
+	'article'			=> 'Article',
+	'title'				=> 'Titre',
+	'author'			=> 'Auteur',
+	'publication_date'		=> 'Date de publication',
+
+	'load_more'			=> 'Charger plus d\'articles',
+	'nothing_to_load'		=> 'Il n\'y a pas plus d\'article',
+
+	'rss_feeds_of'			=> 'Flux RSS de %s',
+
+	'refresh'			=> 'Actualisation',
+
+	'today'				=> 'Aujourd\'hui',
+	'yesterday'			=> 'Hier',
+	'before_yesterday'		=> 'À partir d\'avant-hier',
+	'by_author'			=> 'Par <em>%s</em>',
+	'related_tags'			=> 'Tags associés',
+	'no_feed_to_display'		=> 'Il n\'y a aucun flux à afficher.',
+
+	'about_freshrss'		=> 'À propos de FreshRSS',
+	'project_website'		=> 'Site du projet',
+	'lead_developer'		=> 'Développeur principal',
+	'website'			=> 'Site Internet',
+	'bugs_reports'			=> 'Rapports de bugs',
+	'github_or_email'		=> '<a href="https://github.com/marienfressinaud/FreshRSS/issues">sur Github</a> ou <a href="mailto:dev@marienfressinaud.fr">par mail</a>',
+	'license'			=> 'Licence',
+	'agpl3'				=> '<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a>',
+	'freshrss_description'		=> 'FreshRSS est un agrégateur de flux RSS à auto-héberger à l\'image de <a href="http://rsslounge.aditu.de/">RSSLounge</a>, <a href="http://tt-rss.org/redmine/projects/tt-rss/wiki">TinyTinyRSS</a> ou <a href="http://projet.idleman.fr/leed/">Leed</a>. Il se veut léger et facile à prendre en main tout en étant un outil puissant et paramétrable. L\'objectif étant d\'offrir une alternative sérieuse au futur feu-Google Reader.',
+	'credits'			=> 'Crédits',
+	'credits_content'		=> 'Des éléments de design sont issus du <a href="http://twitter.github.io/bootstrap/">projet Bootstrap</a> bien que FreshRSS n\'utilise pas ce framework. Les <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icônes</a> sont issues du <a href="https://www.gnome.org/">projet GNOME</a>. La police <em>Open Sans</em> utilisée a été créée par <a href="https://www.google.com/webfonts/specimen/Open+Sans">Steve Matteson</a>. Les favicons sont récupérés grâce au site <a href="https://getfavicon.appspot.com/">getFavicon</a>. FreshRSS repose sur <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.',
+
+	// DATE
+	'january'			=> 'janvier',
+	'february'			=> 'février',
+	'march'				=> 'mars',
+	'april'				=> 'avril',
+	'may'				=> 'mai',
+	'june'				=> 'juin',
+	'july'				=> 'juillet',
+	'august'			=> 'août',
+	'september'			=> 'septembre',
+	'october'			=> 'octobre',
+	'november'			=> 'novembre',
+	'december'			=> 'décembre',
+	// format spécial pour la fonction date()
+	'Jan'				=> '\j\a\n\v\i\e\r',
+	'Feb'				=> '\f\é\v\r\i\e\r',
+	'Mar'				=> '\m\a\r\s',
+	'Apr'				=> '\a\v\r\i\l',
+	'May'				=> '\m\a\i',
+	'Jun'				=> '\j\u\i\n',
+	'Jul'				=> '\j\u\i\l\l\e\t',
+	'Aug'				=> '\a\o\û\t',
+	'Sep'				=> '\s\e\p\t\e\m\b\r\e',
+	'Oct'				=> '\o\c\t\o\b\r\e',
+	'Nov'				=> '\n\o\v\e\m\b\r\e',
+	'Dec'				=> '\d\é\c\e\m\b\r\e',
+	// format pour la fonction date(), %s permet d'indiquer le mois en toutes lettres
+	'format_date'			=> 'd %s Y',
+	'format_date_hour'		=> '\l\e d %s Y \à H\:i',
+
+	// INSTALLATION
+	'freshrss_installation'		=> 'Installation - FreshRSS',
+	'freshrss'			=> 'FreshRSS',
+	'installation_step'		=> 'Installation - étape %d',
+	'steps'				=> 'Étapes',
+	'checks'			=> 'Vérifications',
+	'bdd_configuration'		=> 'Configuration de la base de données',
+	'this_is_the_end'		=> 'This is the end',
+
+	'ok'				=> 'Ok !',
+	'congratulations'		=> 'Félicitations !',
+	'attention'			=> 'Attention !',
+	'damn'				=> 'Arf !',
+	'oops'				=> 'Oups !',
+	'next_step'			=> 'Passer à l\'étape suivante',
+
+	'language_defined'		=> 'La langue a bien été définie.',
+	'choose_language'		=> 'Choisissez la langue pour FreshRSS',
+
+	'javascript_is_better'		=> 'FreshRSS est plus agréable à utiliser avec le Javascript d\'activé',
+	'php_is_ok'			=> 'Votre version de PHP est la %s et est compatible avec FreshRSS',
+	'php_is_nok'			=> 'Votre version de PHP est la %s. Vous devriez avoir au moins la version %s',
+	'minz_is_ok'			=> 'Vous disposez du framework Minz',
+	'minz_is_nok'			=> 'Vous ne disposez pas de la librairie Minz. Vous devriez exécuter le script <em>build.sh</em> ou bien <a href="https://github.com/marienfressinaud/MINZ">la télécharger sur Github</a> et installer dans le répertoire <em>%s</em> le contenu de son répertoire <em>/lib</em>.',
+	'curl_is_ok'			=> 'Vous disposez de cURL dans sa version %s',
+	'curl_is_nok'			=> 'Vous ne disposez pas de cURL',
+	'pdomysql_is_ok'		=> 'Vous disposez de PDO et de son driver pour MySQL',
+	'pdomysql_is_nok'		=> 'Vous ne disposez pas de PDO ou de son driver pour MySQL',
+	'cache_is_ok'			=> 'Les droits sur le répertoire de cache sont bons',
+	'log_is_ok'			=> 'Les droits sur le répertoire des logs sont bons',
+	'conf_is_ok'			=> 'Les droits sur le répertoire de configuration sont bons',
+	'data_is_ok'			=> 'Les droits sur le répertoire de data sont bons',
+	'file_is_nok'			=> 'Veuillez vérifier les droits sur le répertoire <em>%s</em>. Le serveur HTTP doit être capable d\'écrire dedans',
+	'fix_errors_before'		=> 'Veuillez corriger les erreurs avant de passer à l\'étape suivante.',
+
+	'general_conf_is_ok'		=> 'La configuration générale a été enregistrée.',
+	'random_string'			=> 'Chaîne aléatoire',
+	'change_value'			=> 'Vous devriez changer cette valeur par n\'importe quelle autre',
+	'base_url'			=> 'Base de l\'url',
+	'do_not_change_if_doubt'	=> 'Laissez tel quel dans le doute',
+
+	'bdd_conf_is_ok'		=> 'La configuration de la base de données a été enregistrée.',
+	'host'				=> 'Hôte',
+	'username'			=> 'Nom utilisateur',
+	'password'			=> 'Mot de passe',
+	'bdd'				=> 'Base de données',
+
+	'installation_is_ok'		=> 'L\'installation s\'est bien passée. Il faut maintenant supprimer le fichier <em>install.php</em> pour pouvoir accéder à FreshRSS... ou simplement cliquer sur le bouton ci-dessous :)',
+	'finish_installation'		=> 'Terminer l\'installation',
+	'install_not_deleted'		=> 'Quelque chose s\'est mal passé, vous devez supprimer le fichier <em>%s</em> à la main.',
+);

+ 4 - 4
app/layout/aside_configure.phtml

@@ -1,13 +1,13 @@
 <div class="nav nav-list aside">
-	<li class="nav-header">Configuration</li>
+	<li class="nav-header"><?php echo Translate::t ('configuration'); ?></li>
 
 	<li class="item<?php echo Request::actionName () == 'display' ? ' active' : ''; ?>">
-		<a href="<?php echo Url::display (array ('c' => 'configure', 'a' => 'display')); ?>">Général et lecture</a>
+		<a href="<?php echo Url::display (array ('c' => 'configure', 'a' => 'display')); ?>"><?php echo Translate::t ('general_and_reading'); ?></a>
 	</li>
 	<li class="item<?php echo Request::actionName () == 'categorize' ? ' active' : ''; ?>">
-		<a href="<?php echo Url::display (array ('c' => 'configure', 'a' => 'categorize')); ?>">Catégories</a>
+		<a href="<?php echo Url::display (array ('c' => 'configure', 'a' => 'categorize')); ?>"><?php echo Translate::t ('categories'); ?></a>
 	</li>
 	<li class="item<?php echo Request::actionName () == 'shortcut' ? ' active' : ''; ?>">
-		<a href="<?php echo Url::display (array ('c' => 'configure', 'a' => 'shortcut')); ?>">Raccourcis</a>
+		<a href="<?php echo Url::display (array ('c' => 'configure', 'a' => 'shortcut')); ?>"><?php echo Translate::t ('shortcuts'); ?></a>
 	</li>
 </div>

+ 16 - 6
app/layout/aside_feed.phtml

@@ -1,9 +1,9 @@
 <ul class="nav nav-list aside aside_feed">
-	<li class="nav-header">Vos flux RSS</li>
+	<li class="nav-header"><?php echo Translate::t ('your_rss_feeds'); ?></li>
 
 	<li class="nav-form"><form id="add_rss" method="post" action="<?php echo Url::display (array ('c' => 'feed', 'a' => 'add')); ?>">
 		<div class="stick">
-			<input type="url" name="url_rss" placeholder="Ajouter un flux RSS" />
+			<input type="url" name="url_rss" placeholder="<?php echo Translate::t ('add_rss_feed'); ?>" />
 			<div class="dropdown">
 				<div id="dropdown-cat" class="dropdown-target"></div>
 
@@ -11,7 +11,7 @@
 				<ul class="dropdown-menu">
 					<li class="dropdown-close"><a href="#close"><i class="icon i_close"></i></a></li>
 
-					<li class="dropdown-header">Catégorie</li>
+					<li class="dropdown-header"><?php echo Translate::t ('category'); ?></li>
 
 					<?php foreach ($this->categories as $cat) { ?>
 					<li class="item">
@@ -21,13 +21,23 @@
 					</label>
 					</li>
 					<?php } ?>
+
+					<li class="separator"></li>
+
+					<li class="dropdown-header"><?php echo Translate::t ('http_authentication'); ?></li>
+					<li class="input">
+						<input type="text" name="username" id="username" placeholder="<?php echo Translate::t ('username'); ?>" />
+					</li>
+					<li class="input">
+						<input type="password" name="password" id="password" placeholder="<?php echo Translate::t ('password'); ?>" />
+					</li>
 				</ul>
 			</div>
 			<button class="btn" type="submit"><i class="icon i_add"></i></button>
 		</div>
 	</form></li>
 
-	<li class="item<?php echo Request::actionName () == 'importExport' ? ' active' : ''; ?>"><a href="<?php echo _url ('configure', 'importExport'); ?>">Import / Export OPML</a></li>
+	<li class="item<?php echo Request::actionName () == 'importExport' ? ' active' : ''; ?>"><a href="<?php echo _url ('configure', 'importExport'); ?>"><?php echo Translate::t ('import_export_opml'); ?></a></li>
 
 	<li class="separator"></li>
 
@@ -35,12 +45,12 @@
 	<?php foreach ($this->feeds as $feed) { ?>
 	<li class="item<?php echo ($this->flux && $this->flux->id () == $feed->id ()) ? ' active' : ''; ?>">
 		<a href="<?php echo _url ('configure', 'feed', 'id', $feed->id ()); ?>">
-			<img class="favicon" src="http://g.etfv.co/<?php echo $feed->website (); ?>" alt="" />
+			<img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="" />
 			<?php echo $feed->name (); ?>
 		</a>
 	</li>
 	<?php } ?>
 	<?php } else { ?>
-	<li class="item disable">Aucun flux</li>
+	<li class="item disable"><?php echo Translate::t ('no_rss_feed'); ?></li>
 	<?php } ?>
 </ul>

+ 18 - 23
app/layout/aside_flux.phtml

@@ -3,26 +3,21 @@
 
 	<ul class="categories">
 		<?php
-			$get = Request::param ('get', '');
-			$search = Request::param ('search', '');
+			$params = Request::params ();
+			$params['output'] = 'rss';
+			if (isset ($params['search'])) {
+				$params['search'] = urlencode ($params['search']);
+			}
 			$url = array (
 				'c' => 'index',
 				'a' => 'index',
-				'params' => array (
-					'output' => 'rss'
-				)
+				'params' => $params
 			);
-			if ($get != '') {
-				$url['params']['get'] = $get;
-			}
-			if ($search != '') {
-				$url['params']['search'] = $search;
-			}
 		?>
 		<?php if (!login_is_conf ($this->conf) || is_logged ()) { ?>
 		<li>
 			<div class="stick">
-				<a class="btn btn-important" href="<?php echo _url ('configure', 'feed'); ?>">Gestion des abonnements</a>
+				<a class="btn btn-important" href="<?php echo _url ('configure', 'feed'); ?>"><?php echo Translate::t ('subscription_management'); ?></a>
 				<a class="btn btn-important" href="<?php echo Url::display ($url); ?>"><i class="icon i_rss"></i></a>
 			</div>
 		</li>
@@ -30,11 +25,11 @@
 
 		<li>
 			<div class="all">
-				<a class="btn<?php echo !$this->get_c ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index'); ?>">
+				<a class="btn<?php echo $this->get_c == 'all' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index'); ?>">
 					<i class="icon i_all"></i>
-					Tous (<?php echo $this->nb_total; ?>)
+					<?php echo Translate::t ('all_feeds', $this->nb_total); ?>
 					<?php if ($this->nb_not_read > 0) { ?>
-					<span class="notRead"><?php echo $this->nb_not_read; ?> non lu<?php echo $this->nb_not_read > 1 ? 's' : ''; ?></span>
+					<span class="notRead"><?php echo $this->nb_not_read > 1 ? Translate::t ('not_reads', $this->nb_not_read) : Translate::t ('not_read', $this->nb_not_read); ?></span>
 					<?php } ?>
 				</a>
 			</div>
@@ -44,7 +39,7 @@
 			<div class="favorites">
 				<a class="btn<?php echo $this->get_c == 'favoris' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 'favoris'); ?>">
 					<i class="icon i_bookmark"></i>
-					Favoris (<?php echo $this->nb_favorites; ?>)
+					<?php echo Translate::t ('favorite_feeds', $this->nb_favorites); ?>
 				</a>
 			</div>
 		</li>
@@ -58,7 +53,7 @@
 				<a class="btn<?php echo $c_active ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 'c_' . $cat->id ()); ?>">
 					<?php echo $cat->name (); ?>
 					<?php if ($catNotRead > 0) { ?>
-					<span class="notRead"><?php echo $catNotRead ?> non lu<?php echo $catNotRead > 1 ? 's' : ''; ?></span>
+					<span class="notRead"><?php echo $catNotRead > 1 ? Translate::t ('not_reads', $catNotRead) : Translate::t ('not_read', $catNotRead); ?></span>
 					<?php } ?>
 				</a>
 			</div>
@@ -73,21 +68,21 @@
 						<a class="dropdown-toggle" href="#dropdown-<?php echo $feed->id(); ?>"><i class="icon i_configure"></i></a>
 						<ul class="dropdown-menu">
 							<li class="dropdown-close"><a href="#close"><i class="icon i_close"></i></a></li>
-							<li class="item"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>">Filtrer</a></li>
-							<li class="item"><a target="_blank" href="<?php echo $feed->website (); ?>">Voir le site</a></li>
+							<li class="item"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>"><?php echo Translate::t ('filter'); ?></a></li>
+							<li class="item"><a target="_blank" href="<?php echo $feed->website (); ?>"><?php echo Translate::t ('see_website'); ?></a></li>
 							<?php if (!login_is_conf ($this->conf) || is_logged ()) { ?>
 							<li class="separator"></li>
 
-							<li class="item"><a href="<?php echo _url ('configure', 'feed', 'id', $feed->id ()); ?>">Gestion</a></li>
-							<li class="item"><a href="<?php echo _url ('feed', 'actualize', 'id', $feed->id ()); ?>">Actualiser</a></li>
-							<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', 'f_' . $feed->id ()); ?>">Marquer comme lu</a></li>
+							<li class="item"><a href="<?php echo _url ('configure', 'feed', 'id', $feed->id ()); ?>"><?php echo Translate::t ('administration'); ?></a></li>
+							<li class="item"><a href="<?php echo _url ('feed', 'actualize', 'id', $feed->id ()); ?>"><?php echo Translate::t ('actualize'); ?></a></li>
+							<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', 'f_' . $feed->id ()); ?>"><?php echo Translate::t ('mark_read'); ?></a></li>
 							<?php } ?>
 						</ul>
 					</div>
 
 					<?php $not_read = $feed->nbNotRead (); ?>
 
-					<img class="favicon" src="http://g.etfv.co/<?php echo $feed->website (); ?>" alt="" />
+					<img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="" />
 					<?php echo $not_read > 0 ? '<b>' : ''; ?>
 					<a class="feed" href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>">
 						<?php echo $not_read > 0 ? '(' . $not_read . ') ' : ''; ?>

+ 22 - 10
app/layout/header.phtml

@@ -1,23 +1,35 @@
 <?php if (login_is_conf ($this->conf)) { ?>
 <ul class="nav nav-head">
 	<?php if (!is_logged ()) { ?>
-	<li class="item"><i class="icon i_login"></i> <a id="signin" href="#">Connexion</a></li>
+	<li class="item"><i class="icon i_login"></i> <a id="signin" href="#"><?php echo Translate::t ('login'); ?></a></li>
 	<?php } else { ?>
-	<li class="item"><i class="icon i_logout"></i> <a id="signout" href="#">Déconnexion</a></li>
+	<li class="item"><i class="icon i_logout"></i> <a id="signout" href="#"><?php echo Translate::t ('logout'); ?></a></li>
 	<?php } ?>
 </ul>
 <?php } ?>
 
 <div class="header">
 	<div class="item title">
-		<h1><a href="<?php echo _url ('index', 'index'); ?>">FreshRSS</a></h1>
+		<h1><a href="<?php echo _url ('index', 'index'); ?>"><?php echo Configuration::title (); ?></a></h1>
+		<img class="logo" src="<?php echo Url::display ('/logo.png'); ?>" alt="" />
 	</div>
 
 	<div class="item search">
-		<form action="<?php echo _url ('index', 'index'); ?>" method="get">
+		<?php
+			$params = Request::params ();
+			if (isset ($params['search'])) {
+				unset ($params['search']);
+			}
+			$url = array (
+				'c' => 'index',
+				'a' => 'index',
+				'params' => $params
+			);
+		?>
+		<form action="<?php echo Url::display ($url); ?>" method="get">
 			<div class="stick">
 				<?php $s = Request::param ('search', ''); ?>
-				<input type="text" name="search" id="search" value="<?php echo $s; ?>" placeholder="Rechercher sur les titres" />
+				<input type="text" name="search" id="search" value="<?php echo $s; ?>" placeholder="<?php echo Translate::t ('search'); ?>" />
 				<button class="btn" type="submit"><i class="icon i_search"></i></button>
 			</div>
 		</form>
@@ -31,12 +43,12 @@
 			<a class="btn dropdown-toggle" href="#dropdown-configure"><i class="icon i_configure"></i></a>
 			<ul class="dropdown-menu">
 				<li class="dropdown-close"><a href="#close"><i class="icon i_close"></i></a></li>
-				<li class="dropdown-header">Configuration</li>
-				<li class="item"><a href="<?php echo _url ('configure', 'display'); ?>">Général et lecture</a></li>
-				<li class="item"><a href="<?php echo _url ('configure', 'categorize'); ?>">Catégories</a></li>
-				<li class="item"><a href="<?php echo _url ('configure', 'shortcut'); ?>">Raccourcis</a></li>
+				<li class="dropdown-header"><?php echo Translate::t ('configuration'); ?></li>
+				<li class="item"><a href="<?php echo _url ('configure', 'display'); ?>"><?php echo Translate::t ('general_and_reading'); ?></a></li>
+				<li class="item"><a href="<?php echo _url ('configure', 'categorize'); ?>"><?php echo Translate::t ('categories'); ?></a></li>
+				<li class="item"><a href="<?php echo _url ('configure', 'shortcut'); ?>"><?php echo Translate::t ('shortcuts'); ?></a></li>
 				<li class="separator"></li>
-				<li class="item"><a href="<?php echo _url ('index', 'about'); ?>">À propos</a></li>
+				<li class="item"><a href="<?php echo _url ('index', 'about'); ?>"><?php echo Translate::t ('about'); ?></a></li>
 			</ul>
 		</div>
 	</div>

+ 3 - 0
app/layout/layout.phtml

@@ -3,6 +3,9 @@
 	<head>
 		<meta charset="utf-8">
 		<meta name="viewport" content="initial-scale=1.0">
+		<link rel="icon" type="image/x-icon" href="<?php echo Url::display ('/favicon.ico'); ?>" />
+		<link rel="icon" type="image/png" href="<?php echo Url::display ('/favicon.ico'); ?>" />
+
 		<?php echo self::headTitle (); ?>
 		<?php echo self::headStyle (); ?>
 		<?php echo self::headScript (); ?>

+ 55 - 17
app/layout/nav_menu.phtml

@@ -1,23 +1,26 @@
 <div class="nav_menu">
 	<a class="btn toggle_aside" href="#aside_flux"><i class="icon i_category"></i></a>
 
+	<?php if (!login_is_conf ($this->conf) || is_logged ()) { ?>
 	<a id="actualize" class="btn" href="<?php echo _url ('feed', 'actualize'); ?>"><i class="icon i_refresh"></i></a>
 
 	<?php
 		$get = false;
-		$string_mark = 'Tout marquer comme lu';
+		$string_mark = Translate::t ('mark_all_read');
 		if ($this->get_f) {
 			$get = 'f_' . $this->get_f;
-			$string_mark = 'Marquer le flux comme lu';
-		} elseif ($this->get_c) {
+			$string_mark = Translate::t ('mark_feed_read');
+		} elseif ($this->get_c &&
+		          $this->get_c != 'all' &&
+		          $this->get_c != 'favoris' &&
+		          $this->get_c != 'public') {
 			$get = 'c_' . $this->get_c;
-			$string_mark = 'Marquer la catégorie comme lue';
+			$string_mark = Translate::t ('mark_cat_read');
 		}
 	?>
 
-	<?php if (!login_is_conf ($this->conf) || is_logged ()) { ?>
 	<div class="stick">
-		<a class="read_all btn" href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', $get); ?>">Marquer comme lu</a>
+		<a class="read_all btn" href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', $get); ?>"><?php echo Translate::t ('mark_read'); ?></a>
 		<div class="dropdown">
 			<div id="dropdown-read" class="dropdown-target"></div>
 
@@ -32,32 +35,67 @@
 	$today = mktime (0, 0, 0, $date['mon'], $date['mday'], $date['year']);
 	$one_week = $today - 604800;
 ?>
-				<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', $get, 'dateMax', $today); ?>">Antérieurs à 1 jour</a></li>
-				<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', $get, 'dateMax', $one_week); ?>">Antérieurs à 1 semaine</a></li>
+				<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', $get, 'dateMax', $today); ?>"><?php echo Translate::t ('before_one_day'); ?></a></li>
+				<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', $get, 'dateMax', $one_week); ?>"><?php echo Translate::t ('before_one_week'); ?></a></li>
 			</ul>
 		</div>
 	</div>
 	<?php } ?>
 
+	<?php
+		$params = Request::params ();
+		if (isset ($params['search'])) {
+			$params['search'] = urlencode ($params['search']);
+		}
+		$url = array (
+			'c' => 'index',
+			'a' => 'index',
+			'params' => $params
+		);
+	?>
 	<div class="dropdown">
 		<div id="dropdown-views" class="dropdown-target"></div>
-		<a class="dropdown-toggle btn" href="#dropdown-views">Affichage <i class="icon i_down"></i></a>
+		<a class="dropdown-toggle btn" href="#dropdown-views"><?php echo Translate::t ('display'); ?> <i class="icon i_down"></i></a>
 		<ul class="dropdown-menu">
 			<li class="dropdown-close"><a href="#close"><i class="icon i_close"></i></a></li>
 
 			<li class="item">
-				<?php if ($this->mode == 'not_read') { ?>
-				<a class="print_all" href="<?php echo _url ('index', 'changeMode', 'mode', 'all'); ?>">Tout afficher</a>
-				<?php } else { ?>
-				<a class="print_non_read" href="<?php echo _url ('index', 'changeMode', 'mode', 'not_read'); ?>">Afficher les non lus</a>
+				<?php
+					if ($this->state == 'not_read') {
+						$url['params']['state'] = 'all';
+				?>
+				<a class="print_all" href="<?php echo Url::display ($url); ?>"><?php echo Translate::t ('show_all_articles'); ?></a>
+				<?php
+					} else {
+						$url['params']['state'] = 'not_read';
+				?>
+				<a class="print_non_read" href="<?php echo Url::display ($url); ?>"><?php echo Translate::t ('show_not_reads'); ?></a>
 				<?php } ?>
 			</li>
 			<li class="separator"></li>
+
+			<?php
+				$params = Request::params ();
+				if (isset ($params['search'])) {
+					$params['search'] = urlencode ($params['search']);
+				}
+				$url = array (
+					'c' => 'index',
+					'a' => 'index',
+					'params' => $params
+				);
+			?>
 			<li class="item">
-				<?php if ($this->order == 'low_to_high') { ?>
-				<a href="<?php echo _url ('index', 'changeOrder', 'order', 'high_to_low'); ?>">Plus anciens en premier</a>
-				<?php } else { ?>
-				<a href="<?php echo _url ('index', 'changeOrder', 'order', 'low_to_high'); ?>">Plus récents en premier</a>
+				<?php
+					if ($this->order == 'low_to_high') {
+						$url['params']['order'] = 'high_to_low';
+				?>
+				<a href="<?php echo Url::display ($url); ?>"><?php echo Translate::t ('older_first'); ?></a>
+				<?php
+					} else {
+						$url['params']['order'] = 'low_to_high';
+				?>
+				<a href="<?php echo Url::display ($url); ?>"><?php echo Translate::t ('newer_first'); ?></a>
 				<?php } ?>
 			</li>
 		</ul>

+ 1 - 1
app/models/Category.php

@@ -176,7 +176,7 @@ class CategoryDAO extends Model_pdo {
 		$def_cat = $this->searchById ('000000');
 
 		if (!$def_cat) {
-			$cat = new Category ('Sans catégorie');
+			$cat = new Category (Translate::t ('default_category'));
 			$cat->_id ('000000');
 
 			$values = array (

+ 144 - 0
app/models/EntriesGetter.php

@@ -0,0 +1,144 @@
+<?php
+
+class EntriesGetter {
+	private $type = array (
+		'type' => 'all',
+		'id' => 'all'
+	);
+	private $state = 'all';
+	private $filter = array (
+		'words' => array (),
+		'tags' => array (),
+	);
+	private $order = 'high_to_low';
+	private $entries = array ();
+
+	private $nb = 1;
+	private $first = '';
+	private $next = '';
+
+	public function __construct ($type, $state, $filter, $order, $nb, $first = '') {
+		$this->_type ($type);
+		$this->_state ($state);
+		$this->_filter ($filter);
+		$this->_order ($order);
+		$this->nb = $nb;
+		$this->first = $first;
+	}
+
+	public function type () {
+		return $this->type;
+	}
+	public function state () {
+		return $this->state;
+	}
+	public function filter () {
+		return $this->filter;
+	}
+	public function order () {
+		return $this->order;
+	}
+	public function entries () {
+		return $this->entries;
+	}
+
+	public function _type ($value) {
+		if (!is_array ($value) ||
+		    !isset ($value['type']) ||
+		    !isset ($value['id'])) {
+			throw new EntriesGetterException ('Bad type line ' . __LINE__ . ' in file ' . __FILE__);
+		}
+
+		$type = $value['type'];
+		$id = $value['id'];
+
+		if ($type != 'all' && $type != 'favoris' && $type != 'public' && $type != 'c' && $type != 'f') {
+			throw new EntriesGetterException ('Bad type line ' . __LINE__ . ' in file ' . __FILE__);
+		}
+
+		if (($type == 'all' || $type == 'favoris' || $type == 'public') &&
+		    ($type != $id)) {
+			throw new EntriesGetterException ('Bad type line ' . __LINE__ . ' in file ' . __FILE__);
+		}
+
+		$this->type = $value;
+	}
+	public function _state ($value) {
+		if ($value != 'all' && $value != 'not_read' && $value != 'read') {
+			throw new EntriesGetterException ('Bad state line ' . __LINE__ . ' in file ' . __FILE__);
+		}
+
+		$this->state = $value;
+	}
+	public function _filter ($value) {
+		$value = trim ($value);
+		$terms = explode (' ', $value);
+
+		foreach ($terms as $word) {
+			if (!empty ($word) && $word[0] == '#' && isset ($word[1])) {
+				$tag = substr ($word, 1);
+				$this->filter['tags'][$tag] = $tag;
+			} elseif (!empty ($word)) {
+				$this->filter['words'][$word] = $word;
+			}
+		}
+	}
+	public function _order ($value) {
+		if ($value != 'high_to_low' && $value != 'low_to_high') {
+			throw new EntriesGetterException ('Bad order line ' . __LINE__ . ' in file ' . __FILE__);
+		}
+
+		$this->order = $value;
+	}
+
+	public function execute () {
+		$entryDAO = new EntryDAO ();
+
+		HelperEntry::$nb = $this->nb;
+		HelperEntry::$first = $this->first;
+		HelperEntry::$filter = $this->filter;
+
+		switch ($this->type['type']) {
+		case 'all':
+			list ($this->entries, $this->next) = $entryDAO->listEntries (
+				$this->state,
+				$this->order
+			);
+			break;
+		case 'favoris':
+			list ($this->entries, $this->next) = $entryDAO->listFavorites (
+				$this->state,
+				$this->order
+			);
+			break;
+		case 'public':
+			list ($this->entries, $this->next) = $entryDAO->listPublic (
+				$this->state,
+				$this->order
+			);
+			break;
+		case 'c':
+			list ($this->entries, $this->next) = $entryDAO->listByCategory (
+				$this->type['id'],
+				$this->state,
+				$this->order
+			);
+			break;
+		case 'f':
+			list ($this->entries, $this->next) = $entryDAO->listByFeed (
+				$this->type['id'],
+				$this->state,
+				$this->order
+			);
+			break;
+		default:
+			throw new EntriesGetterException ('Bad type line ' . __LINE__ . ' in file ' . __FILE__);
+		}
+	}
+
+	public function getPaginator () {
+		$paginator = new RSSPaginator ($this->entries, $this->next);
+
+		return $paginator;
+	}
+}

+ 102 - 231
app/models/Entry.php

@@ -216,7 +216,7 @@ class Entry extends Model {
 
 class EntryDAO extends Model_pdo {
 	public function addEntry ($valuesTmp) {
-		$sql = 'INSERT INTO entry(id, guid, title, author, content, link, date, is_read, is_favorite, is_public, id_feed, lastUpdate) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
+		$sql = 'INSERT INTO entry(id, guid, title, author, content, link, date, is_read, is_favorite, is_public, id_feed, lastUpdate, tags) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
 		$stm = $this->bd->prepare ($sql);
 
 		$values = array (
@@ -232,6 +232,7 @@ class EntryDAO extends Model_pdo {
 			$valuesTmp['is_public'],
 			$valuesTmp['id_feed'],
 			$valuesTmp['lastUpdate'],
+			$valuesTmp['tags'],
 		);
 
 		if ($stm && $stm->execute ($values)) {
@@ -367,7 +368,7 @@ class EntryDAO extends Model_pdo {
 
 		$stm->execute ($values);
 		$res = $stm->fetchAll (PDO::FETCH_ASSOC);
-		$entry = HelperEntry::daoToEntry ($res);
+		list ($entry, $next) = HelperEntry::daoToEntry ($res);
 
 		if (isset ($entry[0])) {
 			return $entry[0];
@@ -376,16 +377,11 @@ class EntryDAO extends Model_pdo {
 		}
 	}
 
-	public function listEntries ($mode, $search = false, $order = 'high_to_low') {
-		$where = ' WHERE priority > 0';
-		if ($mode == 'not_read') {
-			$where .= ' AND is_read=0';
-		}
-
-		$values = array();
-		if ($search) {
-			$values[] = '%'.$search.'%';
-			$where .= ' AND title LIKE ?';
+	public function listWhere ($where, $state, $order, $values = array ()) {
+		if ($state == 'not_read') {
+			$where .= ' AND is_read = 0';
+		} elseif ($state == 'read') {
+			$where .= ' AND is_read = 1';
 		}
 
 		if ($order == 'low_to_high') {
@@ -394,181 +390,28 @@ class EntryDAO extends Model_pdo {
 			$order = '';
 		}
 
-		$sql = 'SELECT COUNT(*) AS count FROM entry e INNER JOIN feed f ON e.id_feed = f.id' . $where;
-		$stm = $this->bd->prepare ($sql);
-		$stm->execute ($values);
-		$res = $stm->fetchAll (PDO::FETCH_ASSOC);
-		$this->nbItems = $res[0]['count'];
-
-		$deb = ($this->currentPage () - 1) * $this->nbItemsPerPage;
-		$fin = $this->nbItemsPerPage;
-
 		$sql = 'SELECT e.* FROM entry e'
 		     . ' INNER JOIN feed f ON e.id_feed = f.id' . $where
-		     . ' ORDER BY date' . $order
-		     . ' LIMIT ' . $deb . ', ' . $fin;
+		     . ' ORDER BY date' . $order;
 		$stm = $this->bd->prepare ($sql);
 		$stm->execute ($values);
 
 		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
 	}
-
-	public function listFavorites ($mode, $search = false, $order = 'high_to_low') {
-		$where = ' WHERE is_favorite=1';
-		if ($mode == 'not_read') {
-			$where .= ' AND is_read=0';
-		}
-
-		$values = array();
-		if ($search) {
-			$values[] = '%'.$search.'%';
-			$where .= ' AND title LIKE ?';
-		}
-
-		if ($order == 'low_to_high') {
-			$order = ' DESC';
-		} else {
-			$order = '';
-		}
-
-		$sql = 'SELECT COUNT(*) AS count FROM entry' . $where;
-		$stm = $this->bd->prepare ($sql);
-		$stm->execute ($values);
-		$res = $stm->fetchAll (PDO::FETCH_ASSOC);
-		$this->nbItems = $res[0]['count'];
-
-		if($this->nbItemsPerPage < 0) {
-			$sql = 'SELECT * FROM entry' . $where
-			     . ' ORDER BY date' . $order;
-		} else {
-			$deb = ($this->currentPage () - 1) * $this->nbItemsPerPage;
-			$fin = $this->nbItemsPerPage;
-
-			$sql = 'SELECT * FROM entry' . $where
-			     . ' ORDER BY date' . $order
-			     . ' LIMIT ' . $deb . ', ' . $fin;
-		}
-		$stm = $this->bd->prepare ($sql);
-
-		$stm->execute ($values);
-
-		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
+	public function listEntries ($state, $order = 'high_to_low') {
+		return $this->listWhere (' WHERE priority > 0', $state, $order);
 	}
-
-	public function listPublic ($mode, $search = false, $order = 'high_to_low') {
-		$where = ' WHERE is_public=1';
-		if ($mode == 'not_read') {
-			$where .= ' AND is_read=0';
-		}
-
-		$values = array();
-		if ($search) {
-			$values[] = '%'.$search.'%';
-			$where .= ' AND title LIKE ?';
-		}
-
-		if ($order == 'low_to_high') {
-			$order = ' DESC';
-		} else {
-			$order = '';
-		}
-
-		$sql = 'SELECT COUNT(*) AS count FROM entry' . $where;
-		$stm = $this->bd->prepare ($sql);
-		$stm->execute ($values);
-		$res = $stm->fetchAll (PDO::FETCH_ASSOC);
-		$this->nbItems = $res[0]['count'];
-
-		if($this->nbItemsPerPage < 0) {
-			$sql = 'SELECT * FROM entry' . $where
-			     . ' ORDER BY date' . $order;
-		} else {
-			$deb = ($this->currentPage () - 1) * $this->nbItemsPerPage;
-			$fin = $this->nbItemsPerPage;
-
-			$sql = 'SELECT * FROM entry' . $where
-			     . ' ORDER BY date' . $order
-			     . ' LIMIT ' . $deb . ', ' . $fin;
-		}
-		$stm = $this->bd->prepare ($sql);
-
-		$stm->execute ($values);
-
-		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
+	public function listFavorites ($state, $order = 'high_to_low') {
+		return $this->listWhere (' WHERE is_favorite = 1', $state, $order);
 	}
-
-	public function listByCategory ($cat, $mode, $search = false, $order = 'high_to_low') {
-		$where = ' WHERE category=?';
-		if ($mode == 'not_read') {
-			$where .= ' AND is_read=0';
-		}
-
-		$values = array ($cat);
-		if ($search) {
-			$values[] = '%'.$search.'%';
-			$where .= ' AND title LIKE ?';
-		}
-
-		if ($order == 'low_to_high') {
-			$order = ' DESC';
-		} else {
-			$order = '';
-		}
-
-		$sql = 'SELECT COUNT(*) AS count FROM entry e INNER JOIN feed f ON e.id_feed = f.id' . $where;
-		$stm = $this->bd->prepare ($sql);
-		$stm->execute ($values);
-		$res = $stm->fetchAll (PDO::FETCH_ASSOC);
-		$this->nbItems = $res[0]['count'];
-
-		$deb = ($this->currentPage () - 1) * $this->nbItemsPerPage;
-		$fin = $this->nbItemsPerPage;
-		$sql = 'SELECT e.* FROM entry e INNER JOIN feed f ON e.id_feed = f.id' . $where
-		     . ' ORDER BY date' . $order
-		     . ' LIMIT ' . $deb . ', ' . $fin;
-
-		$stm = $this->bd->prepare ($sql);
-
-		$stm->execute ($values);
-
-		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
+	public function listPublic ($state, $order = 'high_to_low') {
+		return $this->listWhere (' WHERE is_public = 1', $state, $order);
 	}
-
-	public function listByFeed ($feed, $mode, $search = false, $order = 'high_to_low') {
-		$where = ' WHERE id_feed=?';
-		if ($mode == 'not_read') {
-			$where .= ' AND is_read=0';
-		}
-
-		$values = array($feed);
-		if ($search) {
-			$values[] = '%'.$search.'%';
-			$where .= ' AND title LIKE ?';
-		}
-
-		if ($order == 'low_to_high') {
-			$order = ' DESC';
-		} else {
-			$order = '';
-		}
-
-		$sql = 'SELECT COUNT(*) AS count FROM entry' . $where;
-		$stm = $this->bd->prepare ($sql);
-		$stm->execute ($values);
-		$res = $stm->fetchAll (PDO::FETCH_ASSOC);
-		$this->nbItems = $res[0]['count'];
-
-		$deb = ($this->currentPage () - 1) * $this->nbItemsPerPage;
-		$fin = $this->nbItemsPerPage;
-		$sql = 'SELECT * FROM entry e' . $where
-		     . ' ORDER BY date' . $order
-		     . ' LIMIT ' . $deb . ', ' . $fin;
-
-		$stm = $this->bd->prepare ($sql);
-
-		$stm->execute ($values);
-
-		return HelperEntry::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
+	public function listByCategory ($cat, $state, $order = 'high_to_low') {
+		return $this->listWhere (' WHERE category = ?', $state, $order, array ($cat));
+	}
+	public function listByFeed ($feed, $state, $order = 'high_to_low') {
+		return $this->listWhere (' WHERE id_feed = ?', $state, $order, array ($feed));
 	}
 
 	public function count () {
@@ -579,7 +422,6 @@ class EntryDAO extends Model_pdo {
 
 		return $res[0]['count'];
 	}
-
 	public function countNotRead () {
 		$sql = 'SELECT COUNT(*) AS count FROM entry e INNER JOIN feed f ON e.id_feed = f.id WHERE is_read=0 AND priority > 0';
 		$stm = $this->bd->prepare ($sql);
@@ -615,7 +457,6 @@ class EntryDAO extends Model_pdo {
 
 		return $res[0]['count'];
 	}
-
 	public function countFavorites () {
 		$sql = 'SELECT COUNT(*) AS count FROM entry WHERE is_favorite=1';
 		$stm = $this->bd->prepare ($sql);
@@ -624,73 +465,103 @@ class EntryDAO extends Model_pdo {
 
 		return $res[0]['count'];
 	}
+}
 
-	// gestion de la pagination directement via le DAO
-	private $nbItemsPerPage = 1;
-	private $currentPage = 1;
-	private $nbItems = 0;
-	public function _nbItemsPerPage ($value) {
-		$this->nbItemsPerPage = $value;
-	}
-	public function _currentPage ($value) {
-		$this->currentPage = $value;
-	}
-	public function currentPage () {
-		if ($this->currentPage < 1) {
-			return 1;
+class HelperEntry {
+	public static $nb = 1;
+	public static $first = '';
+
+	public static $filter = array (
+		'words' => array (),
+		'tags' => array (),
+	);
+
+	public static function daoToEntry ($listDAO) {
+		$list = array ();
+
+		if (!is_array ($listDAO)) {
+			$listDAO = array ($listDAO);
 		}
 
-		$maxPage = ceil ($this->nbItems / $this->nbItemsPerPage);
-		if ($this->currentPage > $maxPage) {
-			return $maxPage;
+		$count = 0;
+		$first_is_found = false;
+		$break_after = false;
+		$next = '';
+		foreach ($listDAO as $key => $dao) {
+			$dao['content'] = unserialize (gzinflate (base64_decode ($dao['content'])));
+			$dao['tags'] = preg_split('/[\s#]/', $dao['tags']);
+
+			if (self::tagsMatchEntry ($dao) &&
+			    self::searchMatchEntry ($dao)) {
+				if ($break_after) {
+					$next = $dao['id'];
+					break;
+				}
+				if ($first_is_found || $dao['id'] == self::$first || self::$first == '') {
+					$list[$key] = self::createEntry ($dao);
+
+					$count++;
+					$first_is_found = true;
+				}
+				if ($count >= self::$nb) {
+					$break_after = true;
+				}
+			}
 		}
 
-		return $this->currentPage;
+		unset ($listDAO);
 
+		return array ($list, $next);
 	}
 
-	public function getPaginator ($entries) {
-		$paginator = new Paginator ($entries);
-		$paginator->_nbItems ($this->nbItems);
-		$paginator->_nbItemsPerPage ($this->nbItemsPerPage);
-		$paginator->_currentPage ($this->currentPage ());
+	private static function createEntry ($dao) {
+		$entry = new Entry (
+			$dao['id_feed'],
+			$dao['guid'],
+			$dao['title'],
+			$dao['author'],
+			$dao['content'],
+			$dao['link'],
+			$dao['date'],
+			$dao['is_read'],
+			$dao['is_favorite'],
+			$dao['is_public']
+		);
 
-		return $paginator;
-	}
-}
+		$entry->_notes ($dao['annotation']);
+		$entry->_lastUpdate ($dao['lastUpdate']);
+		$entry->_tags ($dao['tags']);
 
-class HelperEntry {
-	public static function daoToEntry ($listDAO, $mode = 'all', $favorite = false) {
-		$list = array ();
+		if (isset ($dao['id'])) {
+			$entry->_id ($dao['id']);
+		}
 
-		if (!is_array ($listDAO)) {
-			$listDAO = array ($listDAO);
+		return $entry;
+	}
+
+	private static function tagsMatchEntry ($dao) {
+		$tags = self::$filter['tags'];
+		foreach ($tags as $tag) {
+			if (!in_array ($tag, $dao['tags'])) {
+				return false;
+			}
 		}
 
-		foreach ($listDAO as $key => $dao) {
-			$list[$key] = new Entry (
-				$dao['id_feed'],
-				$dao['guid'],
-				$dao['title'],
-				$dao['author'],
-				unserialize (gzinflate (base64_decode ($dao['content']))),
-				$dao['link'],
-				$dao['date'],
-				$dao['is_read'],
-				$dao['is_favorite'],
-				$dao['is_public']
-			);
-
-			$tags = preg_split('/[\s#]/', $dao['tags']);
-			$list[$key]->_notes ($dao['annotation']);
-			$list[$key]->_lastUpdate ($dao['lastUpdate']);
-			$list[$key]->_tags ($tags);
-
-			if (isset ($dao['id'])) {
-				$list[$key]->_id ($dao['id']);
+		return true;
+	}
+	private static function searchMatchEntry ($dao) {
+		$words = self::$filter['words'];
+
+		foreach ($words as $word) {
+			$word = strtolower ($word);
+			if (strpos (strtolower ($dao['title']), $word) === false &&
+			    strpos (strtolower ($dao['content']), $word) === false &&
+			    strpos (strtolower ($dao['link']), $word) === false &&
+			    strpos (strtolower ($dao['annotation']), $word) === false) {
+				return false;
 			}
 		}
 
-		return $list;
+		return true;
 	}
 }

+ 7 - 0
app/models/Exception/EntriesGetterException.php

@@ -0,0 +1,7 @@
+<?php
+
+class EntriesGetterException extends Exception {
+	public function __construct ($message) {
+		parent::__construct ($message);
+	}
+}

+ 6 - 0
app/models/Exception/FeedException.php

@@ -5,3 +5,9 @@ class FeedException extends Exception {
 		parent::__construct ($message);
 	}
 }
+
+class BadUrlException extends FeedException {
+	public function __construct ($url) {
+		parent::__construct ('`' . $url . '` is not a valid URL');
+	}
+}

+ 68 - 7
app/models/Feed.php

@@ -59,9 +59,13 @@ class Feed extends Model {
 		if ($raw) {
 			return $this->httpAuth;
 		} else {
+			$pos_colon = strpos ($this->httpAuth, ':');
+			$user = substr ($this->httpAuth, 0, $pos_colon);
+			$pass = substr ($this->httpAuth, $pos_colon + 1);
+
 			return array (
-				'username' => '',
-				'password' => ''
+				'username' => $user,
+				'password' => $pass
 			);
 		}
 	}
@@ -73,6 +77,16 @@ class Feed extends Model {
 		$feedDAO = new FeedDAO ();
 		return $feedDAO->countNotRead ($this->id ());
 	}
+	public function favicon () {
+		$file = '/data/favicons/' . $this->id () . '.ico';
+
+		$favicon_url = Url::display ($file);
+		if (!file_exists (PUBLIC_PATH . $file)) {
+			$favicon_url = dowload_favicon ($this->website (), $this->id ());
+		}
+
+		return $favicon_url;
+	}
 
 	public function _id ($value) {
 		$this->id = $value;
@@ -85,7 +99,7 @@ class Feed extends Model {
 		if (!is_null ($value) && filter_var ($value, FILTER_VALIDATE_URL)) {
 			$this->url = $value;
 		} else {
-			throw new Exception ();
+			throw new BadUrlException ($value);
 		}
 	}
 	public function _category ($value) {
@@ -134,22 +148,40 @@ class Feed extends Model {
 				);
 			} else {
 				$feed = new SimplePie ();
-				$feed->set_feed_url (preg_replace ('/&amp;/', '&', $this->url));
+				$url = preg_replace ('/&amp;/', '&', $this->url);
+				if ($this->httpAuth != '') {
+					$url = preg_replace ('#((.+)://)(.+)#', '${1}' . $this->httpAuth . '@${3}', $url);
+				}
+
+				$feed->set_feed_url ($url);
 				$feed->set_cache_location (CACHE_PATH);
+				$feed->strip_htmltags (array (
+					'base', 'blink', 'body', 'doctype',
+					'font', 'form', 'frame', 'frameset', 'html',
+					'input', 'marquee', 'meta', 'noscript',
+					'param', 'script', 'style'
+				));
 				$feed->init ();
 
-				if ($feed->error()) {
+				if ($feed->error ()) {
 					throw new FeedException ($feed->error);
 				}
 
+				// si on a utilisé l'auto-discover, notre url va avoir changé
 				$subscribe_url = $feed->subscribe_url ();
 				if (!is_null ($subscribe_url) && $subscribe_url != $this->url) {
+					if ($this->httpAuth != '') {
+						// on enlève les id si authentification HTTP
+						$subscribe_url = preg_replace ('#((.+)://)((.+)@)(.+)#', '${1}${5}', $subscribe_url);
+					}
 					$this->_url ($subscribe_url);
 				}
 				$title = $feed->get_title ();
 				$this->_name (!is_null ($title) ? $title : $this->url);
 				$this->_website ($feed->get_link ());
 				$this->_description ($feed->get_description ());
+
+				// et on charge les articles du flux
 				$this->loadEntries ($feed);
 			}
 		}
@@ -205,7 +237,7 @@ class Feed extends Model {
 
 class FeedDAO extends Model_pdo {
 	public function addFeed ($valuesTmp) {
-		$sql = 'INSERT INTO feed (id, url, category, name, website, description, lastUpdate, priority, error) VALUES(?, ?, ?, ?, ?, ?, ?, 10, 0)';
+		$sql = 'INSERT INTO feed (id, url, category, name, website, description, lastUpdate, priority, httpAuth, error) VALUES(?, ?, ?, ?, ?, ?, ?, 10, ?, 0)';
 		$stm = $this->bd->prepare ($sql);
 
 		$values = array (
@@ -216,6 +248,7 @@ class FeedDAO extends Model_pdo {
 			$valuesTmp['website'],
 			$valuesTmp['description'],
 			$valuesTmp['lastUpdate'],
+			base64_encode ($valuesTmp['httpAuth']),
 		);
 
 		if ($stm && $stm->execute ($values)) {
@@ -231,6 +264,10 @@ class FeedDAO extends Model_pdo {
 		$set = '';
 		foreach ($valuesTmp as $key => $v) {
 			$set .= $key . '=?, ';
+
+			if ($key == 'httpAuth') {
+				$valuesTmp[$key] = base64_encode ($v);
+			}
 		}
 		$set = substr ($set, 0, -2);
 
@@ -269,6 +306,30 @@ class FeedDAO extends Model_pdo {
 		}
 	}
 
+	public function changeCategory ($idOldCat, $idNewCat) {
+		$catDAO = new CategoryDAO ();
+		$newCat = $catDAO->searchById ($idNewCat);
+		if (!$newCat) {
+			$newCat = $catDAO->getDefault ();
+		}
+
+		$sql = 'UPDATE feed SET category=? WHERE category=?';
+		$stm = $this->bd->prepare ($sql);
+
+		$values = array (
+			$newCat->id (),
+			$idOldCat
+		);
+
+		if ($stm && $stm->execute ($values)) {
+			return true;
+		} else {
+			$info = $stm->errorInfo();
+			Log::record ('SQL error : ' . $info[2], Log::ERROR);
+			return false;
+		}
+	}
+
 	public function deleteFeed ($id) {
 		$sql = 'DELETE FROM feed WHERE id=?';
 		$stm = $this->bd->prepare ($sql);
@@ -408,7 +469,7 @@ class HelperFeed {
 			$list[$key]->_lastUpdate ($dao['lastUpdate']);
 			$list[$key]->_priority ($dao['priority']);
 			$list[$key]->_pathEntries ($dao['pathEntries']);
-			$list[$key]->_httpAuth ($dao['httpAuth']);
+			$list[$key]->_httpAuth (base64_decode ($dao['httpAuth']));
 
 			if (isset ($dao['id'])) {
 				$list[$key]->_id ($dao['id']);

+ 24 - 2
app/models/RSSConfiguration.php

@@ -1,6 +1,11 @@
 <?php
 
 class RSSConfiguration extends Model {
+	private $available_languages = array (
+		'en' => 'English',
+		'fr' => 'Français',
+	);
+	private $language;
 	private $posts_per_page;
 	private $default_view;
 	private $display_posts;
@@ -13,6 +18,7 @@ class RSSConfiguration extends Model {
 	
 	public function __construct () {
 		$confDAO = new RSSConfigurationDAO ();
+		$this->_language ($confDAO->language);
 		$this->_postsPerPage ($confDAO->posts_per_page);
 		$this->_defaultView ($confDAO->default_view);
 		$this->_displayPosts ($confDAO->display_posts);
@@ -24,6 +30,12 @@ class RSSConfiguration extends Model {
 		$this->_urlShaarli ($confDAO->url_shaarli);
 	}
 	
+	public function availableLanguages () {
+		return $this->available_languages;
+	}
+	public function language () {
+		return $this->language;
+	}
 	public function postsPerPage () {
 		return $this->posts_per_page;
 	}
@@ -60,7 +72,13 @@ class RSSConfiguration extends Model {
 	public function urlShaarli () {
 		return $this->url_shaarli;
 	}
-	
+
+	public function _language ($value) {
+		if (!isset ($this->available_languages[$value])) {
+			$value = 'en';
+		}
+		$this->language = $value;
+	}
 	public function _postsPerPage ($value) {
 		if (is_int (intval ($value))) {
 			$this->posts_per_page = $value;
@@ -122,6 +140,7 @@ class RSSConfiguration extends Model {
 }
 
 class RSSConfigurationDAO extends Model_array {
+	public $language = 'en';
 	public $posts_per_page = 20;
 	public $default_view = 'not_read';
 	public $display_posts = 'no';
@@ -146,7 +165,10 @@ class RSSConfigurationDAO extends Model_array {
 
 	public function __construct () {
 		parent::__construct (PUBLIC_PATH . '/data/Configuration.array.php');
-		
+
+		if (isset ($this->array['language'])) {
+			$this->language = $this->array['language'];
+		}
 		if (isset ($this->array['posts_per_page'])) {
 			$this->posts_per_page = $this->array['posts_per_page'];
 		}

+ 29 - 0
app/models/RSSPaginator.php

@@ -0,0 +1,29 @@
+<?php
+
+// Un système de pagination beaucoup plus simple que Paginator
+// mais mieux adapté à nos besoins
+class RSSPaginator {
+	private $items = array ();
+	private $next = '';
+
+	public function __construct ($items, $next) {
+		$this->items = $items;
+		$this->next = $next;
+	}
+
+	public function isEmpty () {
+		return empty ($this->items);
+	}
+
+	public function items () {
+		return $this->items;
+	}
+
+	public function render ($view, $getteur) {
+		$view = APP_PATH . '/views/helpers/'.$view;
+
+		if (file_exists ($view)) {
+			include ($view);
+		}
+	}
+}

+ 10 - 10
app/views/configure/categorize.phtml

@@ -1,23 +1,23 @@
 <?php $this->partial ('aside_configure'); ?>
 
 <div class="post">
-	<a href="<?php echo _url ('index', 'index'); ?>">← Retour à vos flux RSS</a>
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a>
 
 	<form method="post" action="<?php echo _url ('configure', 'categorize'); ?>">
-		<legend>Gestion des catégories - <a href="<?php echo _url ('configure', 'feed'); ?>">gestion des flux</a></legend>
+		<legend><?php echo Translate::t ('categories_management'); ?> - <a href="<?php echo _url ('configure', 'feed'); ?>"><?php echo Translate::t ('rss_feed_management'); ?></a></legend>
 
-		<p class="alert alert-warn">Lors de la suppression d'une catégorie, ses flux seront automatiquement classés dans <em><?php echo $this->defaultCategory->name (); ?></em>.</p>
+		<p class="alert alert-warn"><?php echo Translate::t ('feeds_moved_category_deleted', $this->defaultCategory->name ()); ?></p>
 
 		<?php $i = 0; foreach ($this->categories as $cat) { $i++; ?>
 		<div class="form-group">
 			<label class="group-name" for="cat_<?php echo $cat->id (); ?>">
-				Catégorie n°<?php echo $i; ?>
+				<?php echo Translate::t ('category_number', $i); ?>
 			</label>
 			<div class="group-controls">
 				<input type="text" id="cat_<?php echo $cat->id (); ?>" name="categories[]" value="<?php echo $cat->name (); ?>" />
-				<a href="<?php echo _url ('feed', 'delete', 'id', $cat->id (), 'type', 'category'); ?>">Vider ?</a> (<?php echo $cat->nbFeed (); ?> flux)
+				<a href="<?php echo _url ('feed', 'delete', 'id', $cat->id (), 'type', 'category'); ?>"><?php echo Translate::t ('ask_empty'); ?></a> (<?php echo Translate::t ('number_feeds', $cat->nbFeed ()); ?>)
 				<?php if ($cat->id () == $this->defaultCategory->id ()) { ?>
-				<i class="icon i_help"></i> ne peut pas être supprimée
+				<i class="icon i_help"></i> <?php echo Translate::t ('can_not_be_deleted'); ?>
 				<?php } ?>
 				<input type="hidden" name="ids[]" value="<?php echo $cat->id (); ?>" />
 			</div>
@@ -25,16 +25,16 @@
 		<?php } ?>
 
 		<div class="form-group">
-			<label class="group-name" for="new_category">Ajouter une catégorie</label>
+			<label class="group-name" for="new_category"><?php echo Translate::t ('add_category'); ?></label>
 			<div class="group-controls">
-				<input type="text" id="new_category" name="new_category" placeholder="Nouvelle catégorie" />
+				<input type="text" id="new_category" name="new_category" placeholder="<?php echo Translate::t ('new_category'); ?>" />
 			</div>
 		</div>
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button type="submit" class="btn btn-important">Sauvegarder</button>
-				<button type="reset" class="btn">Annuler</button>
+				<button type="submit" class="btn btn-important"><?php echo Translate::t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo Translate::t ('cancel'); ?></button>
 			</div>
 		</div>
 	</form>

+ 39 - 27
app/views/configure/display.phtml

@@ -1,104 +1,116 @@
 <?php $this->partial ('aside_configure'); ?>
 
 <div class="post">
-	<a href="<?php echo _url ('index', 'index'); ?>">← Retour à vos flux RSS</a>
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a>
 
 	<form method="post" action="<?php echo _url ('configure', 'display'); ?>">
-		<legend>Configuration générale</legend>
+		<legend><?php echo Translate::t ('general_configuration'); ?></legend>
 
 		<div class="form-group">
-			<label class="group-name" for="old_entries">Supprimer les articles tous les</label>
+			<label class="group-name" for="language"><?php echo Translate::t ('language'); ?></label>
 			<div class="group-controls">
-				<input type="number" id="old_entries" name="old_entries" value="<?php echo $this->conf->oldEntries (); ?>" /> mois
+				<select name="language" id="language">
+				<?php $languages = $this->conf->availableLanguages (); ?>
+				<?php foreach ($languages as $short => $lib) { ?>
+				<option value="<?php echo $short; ?>"<?php echo $this->conf->language () == $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></option>
+				<?php } ?>
+				</select>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="old_entries"><?php echo Translate::t ('delete_articles_every'); ?></label>
+			<div class="group-controls">
+				<input type="number" id="old_entries" name="old_entries" value="<?php echo $this->conf->oldEntries (); ?>" /> <?php echo Translate::t ('month'); ?>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="mail_login">Adresse mail de connexion (utilise <a href="https://persona.org/">Persona</a>)</label>
+			<label class="group-name" for="mail_login"><?php echo Translate::t ('persona_connection_email'); ?></label>
 		<?php $mail = $this->conf->mailLogin (); ?>
 			<div class="group-controls">
-				<input type="email" id="mail_login" name="mail_login" value="<?php echo $mail ? $mail : ''; ?>" placeholder="Laissez vide pour désactiver" />
-				<noscript><b>nécessite que javascript soit activé</b></noscript>
+				<input type="email" id="mail_login" name="mail_login" value="<?php echo $mail ? $mail : ''; ?>" placeholder="<?php echo Translate::t ('blank_to_disable'); ?>" />
+				<noscript><b><?php echo Translate::t ('javascript_should_be_activated'); ?></b></noscript>
 			</div>
 		</div>
 	
-		<legend>Configuration de lecture</legend>
+		<legend><?php echo Translate::t ('reading_configuration'); ?></legend>
 
 		<div class="form-group">
-			<label class="group-name" for="posts_per_page">Nombre d'articles par page</label>
+			<label class="group-name" for="posts_per_page"><?php echo Translate::t ('articles_per_page'); ?></label>
 			<div class="group-controls">
 				<input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->postsPerPage (); ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name">Vue par défaut</label>
+			<label class="group-name"><?php echo Translate::t ('default_view'); ?></label>
 			<div class="group-controls">
 				<label class="radio" for="radio_all">
 					<input type="radio" name="default_view" id="radio_all" value="all"<?php echo $this->conf->defaultView () == 'all' ? ' checked="checked"' : ''; ?> />
-					Tout afficher
+					<?php echo Translate::t ('show_all_articles'); ?>
 				</label>
 				<label class="radio" for="radio_not_read">
 					<input type="radio" name="default_view" id="radio_not_read" value="not_read"<?php echo $this->conf->defaultView () == 'not_read' ? ' checked="checked"' : ''; ?> />
-					Afficher les non lus
+					<?php echo Translate::t ('show_not_reads'); ?>
 				</label>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="sort_order">Ordre de tri</label>
+			<label class="group-name" for="sort_order"><?php echo Translate::t ('sort_order'); ?></label>
 			<div class="group-controls">
 				<select name="sort_order" id="sort_order">
-					<option value="low_to_high"<?php echo $this->conf->sortOrder () == 'low_to_high' ? ' selected="selected"' : ''; ?>>Du plus récent au plus ancien</option>
-					<option value="high_to_low"<?php echo $this->conf->sortOrder () == 'high_to_low' ? ' selected="selected"' : ''; ?>>Du plus ancien au plus récent</option>
+					<option value="low_to_high"<?php echo $this->conf->sortOrder () == 'low_to_high' ? ' selected="selected"' : ''; ?>><?php echo Translate::t ('newer_first'); ?></option>
+					<option value="high_to_low"<?php echo $this->conf->sortOrder () == 'high_to_low' ? ' selected="selected"' : ''; ?>><?php echo Translate::t ('older_first'); ?></option>
 				</select>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name">Afficher les articles dépliés par défaut</label>
+			<label class="group-name"><?php echo Translate::t ('display_articles_unfolded'); ?></label>
 			<div class="group-controls">
 				<label class="radio" for="radio_yes">
 					<input type="radio" name="display_posts" id="radio_yes" value="yes"<?php echo $this->conf->displayPosts () == 'yes' ? ' checked="checked"' : ''; ?> />
-					Oui
+					<?php echo Translate::t ('yes'); ?>
 				</label>
 				<label class="radio" for="radio_no">
 					<input type="radio" name="display_posts" id="radio_no" value="no"<?php echo $this->conf->displayPosts () == 'no' ? ' checked="checked"' : ''; ?> />
-					Non<noscript> - <b>nécessite que javascript soit activé</b></noscript>
+					<?php echo Translate::t ('no'); ?><noscript> - <b><?php echo Translate::t ('javascript_should_be_activated'); ?></b></noscript>
 				</label>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name">Article automatiquement marqué comme lu lorsque</label>
+			<label class="group-name"><?php echo Translate::t ('auto_read_when'); ?></label>
 			<div class="group-controls">
 				<label class="checkbox" for="check_open_article">
 					<input type="checkbox" name="mark_open_article" id="check_open_article" value="yes"<?php echo $this->conf->markWhenArticle () == 'yes' ? ' checked="checked"' : ''; ?> />
-					l'article est sélectionné
+					<?php echo Translate::t ('article_selected'); ?>
 				</label>
 				<label class="checkbox" for="check_open_site">
 					<input type="checkbox" name="mark_open_site" id="check_open_site" value="yes"<?php echo $this->conf->markWhenSite () == 'yes' ? ' checked="checked"' : ''; ?> />
-					l'article est ouvert sur le site d'origine
+					<?php echo Translate::t ('article_open_on_website'); ?>
 				</label>
 				<label class="checkbox" for="check_open_page">
 					<input type="checkbox" name="mark_open_page" id="check_open_page" value="yes"<?php echo $this->conf->markWhenPage () == 'yes' ? ' checked="checked"' : ''; ?> />
-					la page est chargée
+					<?php echo Translate::t ('page_loaded'); ?>
 				</label>
 			</div>
 		</div>
 
-		<legend>Partage</legend>
+		<legend><?php echo Translate::t ('sharing'); ?></legend>
 		<div class="form-group">
-			<label class="group-name" for="shaarli">Votre Shaarli</label>
+			<label class="group-name" for="shaarli"><?php echo Translate::t ('your_shaarli'); ?></label>
 			<div class="group-controls">
-				<input type="text" id="shaarli" name="shaarli" value="<?php echo $this->conf->urlShaarli (); ?>" placeholder="Laissez vide pour désactiver"/>
+				<input type="text" id="shaarli" name="shaarli" value="<?php echo $this->conf->urlShaarli (); ?>" placeholder="<?php echo Translate::t ('blank_to_disable'); ?>"/>
 			</div>
 		</div>
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button type="submit" class="btn btn-important">Valider</button>
-				<button type="reset" class="btn">Annuler</button>
+				<button type="submit" class="btn btn-important"><?php echo Translate::t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo Translate::t ('cancel'); ?></button>
 			</div>
 		</div>
 	</form>

+ 24 - 23
app/views/configure/feed.phtml

@@ -2,35 +2,35 @@
 
 <?php if ($this->flux) { ?>
 <div class="post">
-	<a href="<?php echo _url ('index', 'index'); ?>">← Retour à vos flux RSS</a>
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a> <?php echo Translate::t ('or'); ?> <a href="<?php echo _url ('index', 'index', 'get', 'f_' . $this->flux->id ()); ?>"><?php echo Translate::t ('filter'); ?></a>
 
 	<h1><?php echo $this->flux->name (); ?></h1>
 	<?php echo $this->flux->description (); ?>
 
 	<form method="post" action="<?php echo _url ('configure', 'feed', 'id', $this->flux->id ()); ?>">
-		<legend>Informations</legend>
+		<legend><?php echo Translate::t ('informations'); ?></legend>
 		<div class="form-group">
-			<label class="group-name">URL du site</label>
+			<label class="group-name"><?php echo Translate::t ('website_url'); ?></label>
 			<div class="group-controls">
 				<span class="control"><a target="_blank" href="<?php echo $this->flux->website (); ?>"><?php echo $this->flux->website (); ?></a></span>
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="group-name">URL du flux</label>
+			<label class="group-name"><?php echo Translate::t ('feed_url'); ?></label>
 			<div class="group-controls">
 				<span class="control"><a target="_blank" href="<?php echo $this->flux->url (); ?>"><?php echo $this->flux->url (); ?></a></span>
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="group-name">Nombre d'articles</label>
+			<label class="group-name"><?php echo Translate::t ('number_articles'); ?></label>
 			<div class="group-controls">
 				<span class="control"><?php echo $this->flux->nbEntries (); ?></span>
 			</div>
 		</div>
 
-		<legend>Catégorie - <a href="<?php echo _url ('configure', 'categorize'); ?>">gestion</a></legend>
+		<legend><?php echo Translate::t ('category'); ?> - <a href="<?php echo _url ('configure', 'categorize'); ?>"><?php echo Translate::t ('categories_management'); ?></a></legend>
 		<div class="form-group">
-			<label class="group-name">Ranger dans une catégorie</label>
+			<label class="group-name"><?php echo Translate::t ('categorize'); ?></label>
 			<div class="group-controls">
 				<?php foreach ($this->categories as $cat) { ?>
 				<label class="radio" for="cat_<?php echo $cat->id (); ?>">
@@ -41,46 +41,47 @@
 			</div>
 		</div>
 
-		<legend>Avancé</legend>
+		<legend><?php echo Translate::t ('advanced'); ?></legend>
 		<div class="form-group">
-			<label class="group-name" for="priority">Afficher dans le flux principal</label>
+			<label class="group-name" for="priority"><?php echo Translate::t ('show_in_all_flux'); ?></label>
 			<div class="group-controls">
 				<label class="checkbox" for="priority">
 					<input type="checkbox" name="priority" id="priority" value="10"<?php echo $this->flux->priority () > 0 ? ' checked="checked"' : ''; ?> />
-					Oui
+					<?php echo Translate::t ('yes'); ?>
 				</label>
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="group-name" for="path_entries">Chemin CSS des articles sur le site d'origine</label>
+			<label class="group-name" for="path_entries"><?php echo Translate::t ('css_path_on_website'); ?></label>
 			<div class="group-controls">
-				<input type="text" name="path_entries" id="path_entries" value="<?php echo $this->flux->pathEntries (); ?>" placeholder="Laissez vide pour désactiver" />
-				<i class="icon i_help"></i> Permet de récupérer les flux tronqués (attention, demande plus de temps !)
+				<input type="text" name="path_entries" id="path_entries" value="<?php echo $this->flux->pathEntries (); ?>" placeholder="<?php echo Translate::t ('blank_to_disable'); ?>" />
+				<i class="icon i_help"></i> <?php echo Translate::t ('retrieve_truncated_feeds'); ?>
 			</div>
 		</div>
-<!--
+
+		<?php $auth = $this->flux->httpAuth (false); ?>
 		<div class="form-group">
-			<label class="group-name" for="http_user">Username HTTP</label>
+			<label class="group-name" for="http_user"><?php echo Translate::t ('http_username'); ?></label>
 			<div class="group-controls">
-				<input type="text" name="http_user" id="http_user" value="Pas encore implémenté" />
-				<i class="icon i_help"></i> La connexion permet d'accéder aux flux protégés par une authentification HTTP
+				<input type="text" name="http_user" id="http_user" value="<?php echo $auth['username']; ?>" />
+				<i class="icon i_help"></i> <?php echo Translate::t ('access_protected_feeds'); ?>
 			</div>
 
-			<label class="group-name" for="http_pass">Password HTTP</label>
+			<label class="group-name" for="http_pass"><?php echo Translate::t ('http_password'); ?></label>
 			<div class="group-controls">
-				<input type="text" name="http_pass" id="http_pass" value="Pas encore implémenté" />
+				<input type="password" name="http_pass" id="http_pass" value="<?php echo $auth['password']; ?>" />
 			</div>
 		</div>
--->
+
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button class="btn btn-important">Valider</button>
-				<button class="btn btn-attention" formaction="<?php echo Url::display (array ('c' => 'feed', 'a' => 'delete', 'params' => array ('id' => $this->flux->id ()))); ?>">Supprimer</button>
+				<button class="btn btn-important"><?php echo Translate::t ('save'); ?></button>
+				<button class="btn btn-attention" formaction="<?php echo Url::display (array ('c' => 'feed', 'a' => 'delete', 'params' => array ('id' => $this->flux->id ()))); ?>"><?php echo Translate::t ('delete'); ?></button>
 			</div>
 		</div>
 	</form>
 </div>
 <?php } else { ?>
-<div class="alert"><span class="alert-head">Aucun flux sélectionné.</span> Pensez à en ajouter !</div>
+<div class="alert alert-warn"><span class="alert-head"><?php echo Translate::t ('no_selected_feed'); ?></span> <?php echo Translate::t ('think_to_add'); ?></div>
 <?php } ?>

+ 6 - 6
app/views/configure/importExport.phtml

@@ -14,12 +14,12 @@
 <?php $this->partial ('aside_feed'); ?>
 
 <div class="post ">
-	<a href="<?php echo _url ('index', 'index'); ?>">← Retour à vos flux RSS</a>
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a>
 
 	<form method="post" action="<?php echo Url::display (array ('c' => 'configure', 'a' => 'importExport', 'params' => array ('q' => 'import'))); ?>" enctype="multipart/form-data">
-		<legend>Import / export au format OPML</legend>
+		<legend><?php echo Translate::t ('import_export_opml'); ?></legend>
 		<div class="form-group">
-			<label class="group-name" for="file">Fichier à importer</label>
+			<label class="group-name" for="file"><?php echo Translate::t ('file_to_import'); ?></label>
 			<div class="group-controls">
 				<input type="file" name="file" id="file" />
 			</div>
@@ -27,9 +27,9 @@
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button type="submit" class="btn btn-important">Importer</button>
-				ou
-				<a target="_blank" class="btn btn-important" href="<?php echo _url ('configure', 'importExport', 'q', 'export'); ?>">Exporter</a>
+				<button type="submit" class="btn btn-important"><?php echo Translate::t ('import'); ?></button>
+				<?php echo Translate::t ('or'); ?>
+				<a target="_blank" class="btn btn-important" href="<?php echo _url ('configure', 'importExport', 'q', 'export'); ?>"><?php echo Translate::t ('export'); ?></a>
 			</div>
 		</div>
 	</form>

+ 15 - 15
app/views/configure/shortcut.phtml

@@ -1,7 +1,7 @@
 <?php $this->partial ('aside_configure'); ?>
 
 <div class="post">
-	<a href="<?php echo _url ('index', 'index'); ?>">← Retour à vos flux RSS</a>
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a>
 
 	<datalist id="keys">
 		<?php foreach ($this->list_keys as $key) { ?>
@@ -12,57 +12,57 @@
 	<?php $s = $this->conf->shortcuts (); ?>
 
 	<form method="post" action="<?php echo _url ('configure', 'shortcut'); ?>">
-		<legend>Gestion des raccourcis</legend>
+		<legend><?php echo Translate::t ('shortcuts_management'); ?></legend>
 
-		<noscript><b>Le javascript doit être activé pour pouvoir profiter des raccourcis</b></noscript>
+		<noscript><p class="alert alert-error"><?php echo Translate::t ('javascript_for_shortcuts'); ?></p></noscript>
 
 		<div class="form-group">
-			<label class="group-name" for="mark_read">Marquer l'article comme lu</label>
+			<label class="group-name" for="mark_read"><?php echo Translate::t ('mark_read'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="mark_read" name="shortcuts[mark_read]" list="keys" value="<?php echo $s['mark_read']; ?>" />
-				+ <code>shift</code> pour marquer tous les articles comme non lus
+				<?php echo Translate::t ('shift_for_all_read'); ?>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="mark_favorite">Mettre l'article  en favori</label>
+			<label class="group-name" for="mark_favorite"><?php echo Translate::t ('mark_favorite'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="mark_favorite" name="shortcuts[mark_favorite]" list="keys" value="<?php echo $s['mark_favorite']; ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="go_website">Voir l'article sur le site d'origine</label>
+			<label class="group-name" for="go_website"><?php echo Translate::t ('see_on_website'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="go_website" name="shortcuts[go_website]" list="keys" value="<?php echo $s['go_website']; ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="next_entry">Passer à l'article suivant</label>
+			<label class="group-name" for="next_entry"><?php echo Translate::t ('next_article'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="next_entry" name="shortcuts[next_entry]" list="keys" value="<?php echo $s['next_entry']; ?>" />
-				+ <code>shift</code> pour passer au dernier article de la page
+				<?php echo Translate::t ('shift_for_last'); ?>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="prev_entry">Passer à l'article précédent</label>
+			<label class="group-name" for="prev_entry"><?php echo Translate::t ('previous_article'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="prev_entry" name="shortcuts[prev_entry]" list="keys" value="<?php echo $s['prev_entry']; ?>" />
-				+ <code>shift</code> pour passer au premier article de la page
+				<?php echo Translate::t ('shift_for_first'); ?>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="next_page">Passer à la page suivante</label>
+			<label class="group-name" for="next_page"><?php echo Translate::t ('next_page'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="next_page" name="shortcuts[next_page]" list="keys" value="<?php echo $s['next_page']; ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="prev_page">Passer à la page précédente</label>
+			<label class="group-name" for="prev_page"><?php echo Translate::t ('previous_page'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="prev_page" name="shortcuts[prev_page]" list="keys" value="<?php echo $s['prev_page']; ?>" />
 			</div>
@@ -70,8 +70,8 @@
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button type="submit" class="btn btn-important">Sauvegarder</button>
-				<button type="reset" class="btn">Annuler</button>
+				<button type="submit" class="btn btn-important"><?php echo Translate::t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo Translate::t ('cancel'); ?></button>
 			</div>
 		</div>
 	</form>

+ 12 - 12
app/views/entry/note.phtml

@@ -1,37 +1,37 @@
 <?php $this->partial ('aside_flux'); ?>
 
 <div class="post">
-	<a href="<?php echo _url ('index', 'index'); ?>">← Retour à vos flux RSS</a>
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a>
 
 	<form method="post" action="<?php echo _url ('entry', 'note', 'id', $this->entry->id ()); ?>">
-		<legend>Note</legend>
+		<legend><?php echo Translate::t ('note'); ?></legend>
 
 		<div class="form-group">
-			<label class="group-name" for="note">Ajouter une note</label>
+			<label class="group-name" for="note"><?php echo Translate::t ('add_note'); ?></label>
 			<div class="group-controls">
 				<textarea rows="5" cols="80" name="note" id="note"><?php echo $this->entry->notes (); ?></textarea>
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="group-name" for="public_note">Article public ?</label>
+			<label class="group-name" for="public_note"><?php echo Translate::t ('ask_public_article'); ?></label>
 			<div class="group-controls">
 				<label class="checkbox" for="public">
-					<input type="checkbox" name="public" id="public" value="yes"<?php echo $this->entry->isPublic () ? ' checked="checked"' : ''; ?> /> Oui
+					<input type="checkbox" name="public" id="public" value="yes"<?php echo $this->entry->isPublic () ? ' checked="checked"' : ''; ?> /> <?php echo Translate::t ('yes'); ?>
 				</label>
 			</div>
 		</div>
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button type="submit" class="btn btn-important">Sauvegarder</button>
-				<button type="reset" class="btn">Annuler</button>
+				<button type="submit" class="btn btn-important"><?php echo Translate::t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo Translate::t ('cancel'); ?></button>
 			</div>
 		</div>
 
-		<legend>Article</legend>
+		<legend><?php echo Translate::t ('article'); ?></legend>
 
 		<div class="form-group">
-			<label class="group-name">Titre</label>
+			<label class="group-name"><?php echo Translate::t ('title'); ?></label>
 			<div class="group-controls">
 				<span class="control"><a href="<?php echo $this->entry->link (); ?>"><?php echo $this->entry->title (); ?></a></span>
 			</div>
@@ -41,7 +41,7 @@
 		$author = $this->entry->author ();
 		if ($author) { ?>
 		<div class="form-group">
-			<label class="group-name">Auteur</label>
+			<label class="group-name"><?php echo Translate::t ('author'); ?></label>
 			<div class="group-controls">
 				<span class="control"><?php echo $author; ?></span>
 			</div>
@@ -49,14 +49,14 @@
 		<?php } ?>
 
 		<div class="form-group">
-			<label class="group-name">Date de publication</label>
+			<label class="group-name"><?php echo Translate::t ('publication_date'); ?></label>
 			<div class="group-controls">
 				<span class="control"><?php echo $this->entry->date (); ?></span>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name">Article</label>
+			<label class="group-name"><?php echo Translate::t ('article'); ?></label>
 			<div class="group-controls">
 				<span class="control"><?php echo $this->entry->content (); ?></span>
 			</div>

+ 5 - 2
app/views/error/index.phtml

@@ -1,7 +1,10 @@
 <div class="post">
-	<div class="alert">
+	<div class="alert alert-error">
 		<h1 class="alert-head"><?php echo $this->code; ?></h1>
 
-		<p><a href="<?php echo Url::display (); ?>">Revenir à l'accueil</a></p>
+		<p>
+			<?php echo Translate::t ('page_not_found'); ?><br />
+			<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a>
+		</p>
 	</div>
 </div>

+ 4 - 15
app/views/helpers/pagination.phtml

@@ -5,23 +5,12 @@
 ?>
 
 <ul class="pagination">
-	<li class="item pager-previous">
-	<?php if ($this->currentPage > 1) { ?>
-	<?php $params[$getteur] = $this->currentPage - 1; ?>
-	<a href="<?php echo Url::display (array ('c' => $c, 'a' => $a, 'params' => $params)); ?>">‹ plus récents</a>
-	<?php } else { ?>
-	&nbsp;
-	<?php } ?>
-	</li>
-
-	<li class="item pager-current">page <?php echo $this->currentPage; ?> / <?php echo $this->nbPage; ?></li>
-
 	<li class="item pager-next">
-	<?php if ($this->currentPage < $this->nbPage) { ?>
-	<?php $params[$getteur] = $this->currentPage + 1; ?>
-	<a href="<?php echo Url::display (array ('c' => $c, 'a' => $a, 'params' => $params)); ?>">plus anciens ›</a>
+	<?php if ($this->next != '') { ?>
+	<?php $params[$getteur] = $this->next; ?>
+	<a href="<?php echo Url::display (array ('c' => $c, 'a' => $a, 'params' => $params)); ?>"><?php echo Translate::t ('load_more'); ?></a>
 	<?php } else { ?>
-	&nbsp;
+	<?php echo Translate::t ('nothing_to_load'); ?>
 	<?php } ?>
 	</li>
 </ul>

+ 1 - 1
app/views/helpers/rss.phtml

@@ -3,7 +3,7 @@
 	<channel>
 		<title><?php echo View::title(); ?></title>
 		<link><?php echo Url::display(); ?></link>
-		<description>Flux RSS de <?php echo View::title(); ?></description>
+		<description><?php echo Translate::t ('rss_feeds_of', View::title()); ?></description>
 		<pubDate><?php echo date('D, d M Y H:i:s O'); ?></pubDate>
 		<lastBuildDate><?php echo gmdate('D, d M Y H:i:s'); ?> GMT</lastBuildDate>
 		<atom:link href="<?php echo _url ('index', 'index', 'output', 'rss'); ?>" rel="self" type="application/rss+xml" />

+ 12 - 12
app/views/index/about.phtml

@@ -1,24 +1,24 @@
 <div class="post content">
-	<a href="<?php echo _url ('index', 'index'); ?>">← Retour à vos flux RSS</a>
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Translate::t ('back_to_rss_feeds'); ?></a>
 
-	<h1>À propos de FreshRSS</h1>
+	<h1><?php echo Translate::t ('about_freshrss'); ?></h1>
 
 	<dl class="infos">
-		<dt>Url du projet</dt>
+		<dt><?php echo Translate::t ('project_website'); ?></dt>
 		<dd><a href="https://github.com/marienfressinaud/FreshRSS">https://github.com/marienfressinaud/FreshRSS</a></dd>
 
-		<dt>Développeur principal</dt>
-		<dd><a href="mailto:contact@marienfressinaud.fr">Marien Fressinaud</a> - <a href="http://marienfressinaud.fr">site Internet</a></dd>
+		<dt><?php echo Translate::t ('lead_developer'); ?></dt>
+		<dd><a href="mailto:contact@marienfressinaud.fr">Marien Fressinaud</a> - <a href="http://marienfressinaud.fr"><?php echo Translate::t ('website'); ?></a></dd>
 
-		<dt>Pour les rapports de bugs</dt>
-		<dd><a href="https://github.com/marienfressinaud/FreshRSS/issues">sur Github</a> ou <a href="mailto:dev@marienfressinaud.fr">par mail</a></dd>
+		<dt><?php echo Translate::t ('bugs_reports'); ?></dt>
+		<dd><?php echo Translate::t ('github_or_email'); ?></dd>
 
-		<dt>Licence</dt>
-		<dd><a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPL 3</a></dd>
+		<dt><?php echo Translate::t ('license'); ?></dt>
+		<dd><?php echo Translate::t ('agpl3'); ?></dd>
 	</dl>
 
-	<p>FreshRSS est un agrégateur de flux RSS à auto-héberger à l'image de <a href="http://rsslounge.aditu.de/">RSSLounge</a>, <a href="http://tt-rss.org/redmine/projects/tt-rss/wiki">TinyTinyRSS</a> ou <a href="http://projet.idleman.fr/leed/">Leed</a>. Il se veut léger et facile à prendre en main tout en étant un outil puissant et paramétrable. L'objectif étant d'offrir une alternative sérieuse au futur feu-Google Reader.</p>
+	<p><?php echo Translate::t ('freshrss_description'); ?></p>
 
-	<h1>Crédits</h1>
-	Des éléments de design sont issus du <a href="http://twitter.github.io/bootstrap/">projet Bootstrap</a> bien que FreshRSS n'utilise pas ce framework. Les <a href="https://git.gnome.org/browse/gnome-icon-theme-symbolic">icônes</a> sont issues du <a href="https://www.gnome.org/">projet GNOME</a>. La police <em>Open Sans</em> utilisée a été créée par <a href="https://www.google.com/webfonts/specimen/Open+Sans">Steve Matteson</a>. Les favicons sont récupérés grâce au site <a href="https://getfavicon.appspot.com/">getFavicon</a>. FreshRSS repose sur <a href="https://github.com/marienfressinaud/MINZ">Minz</a>, un framework PHP.
+	<h1><?php echo Translate::t ('credits'); ?></h1>
+	<p><?php echo Translate::t ('credits_content'); ?></p>
 </div>

+ 43 - 29
app/views/index/index.phtml

@@ -1,18 +1,16 @@
 <?php
-if (Request::param ('output', '') == 'rss') {
-	$this->renderHelper ('rss');
-	return;
-}
-?>
-
-<?php $this->partial ('aside_flux'); ?>
+$output = Request::param ('output', 'normal');
 
-<?php $this->partial ('nav_menu'); ?>
+if ($output == 'rss') {
+	$this->renderHelper ('rss');
+} else {
+	$this->partial ('aside_flux');
+	$this->partial ('nav_menu');
 
-<?php
-if (isset ($this->entryPaginator)) {
-	$items = $this->entryPaginator->items (true);
+	if (isset ($this->entryPaginator) && !$this->entryPaginator->isEmpty ()) {
+		$items = $this->entryPaginator->items ();
 ?>
+
 <div id="stream">
 	<?php
 		$display_today = true;
@@ -22,13 +20,13 @@ if (isset ($this->entryPaginator)) {
 	<?php foreach ($items as $item) { ?>
 
 	<?php if ($display_today && $item->isDay (Days::TODAY)) { ?>
-	<div class="day">Aujourd'hui - <?php echo timestamptodate (time (), false); ?></div>
+	<div class="day"><?php echo Translate::t ('today'); ?> - <?php echo timestamptodate (time (), false); ?></div>
 	<?php $display_today = false; } ?>
 	<?php if ($display_yesterday && $item->isDay (Days::YESTERDAY)) { ?>
-	<div class="day">Hier - <?php echo timestamptodate (time () - 86400, false); ?></div>
+	<div class="day"><?php echo Translate::t ('yesterday'); ?> - <?php echo timestamptodate (time () - 86400, false); ?></div>
 	<?php $display_yesterday = false; } ?>
 	<?php if ($display_others && $item->isDay (Days::BEFORE_YESTERDAY)) { ?>
-	<div class="day">À partir d'avant-hier</div>
+	<div class="day"><?php echo Translate::t ('before_yesterday'); ?></div>
 	<?php $display_others = false; } ?>
 
 	<div class="flux<?php echo !$item->isRead () ? ' not_read' : ''; ?><?php echo $item->isFavorite () ? ' favorite' : ''; ?>" id="flux_<?php echo $item->id (); ?>">
@@ -49,9 +47,9 @@ if (isset ($this->entryPaginator)) {
 			</li>
 			<?php } ?>
 			<?php $feed = $item->feed (true); ?>
-			<li class="item website"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>"><img class="favicon" src="http://g.etfv.co/<?php echo $feed->website (); ?>" alt="" /> <span><?php echo $feed->name (); ?></span></a></li>
+			<li class="item website"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>"><img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="" /> <span><?php echo $feed->name (); ?></span></a></li>
 			<li class="item title"><?php echo $item->title (); ?></li>
-			<li class="item date">le <?php echo $item->date (); ?></li>
+			<li class="item date"><?php echo $item->date (); ?></li>
 			<li class="item link"><a target="_blank" href="<?php echo $item->link (); ?>">&nbsp;</a></li>
 		</ul>
 
@@ -59,48 +57,64 @@ if (isset ($this->entryPaginator)) {
 			<div class="content">
 				<h1 class="title"><?php echo $item->title (); ?></h1>
 				<?php $author = $item->author (); ?>
-				<?php echo $author != '' ? '<div class="author">Par <em>' . $author . '</em></div>' : ''; ?>
+				<?php echo $author != '' ? '<div class="author">' . Translate::t ('by_author', $author) . '</div>' : ''; ?>
 				<?php echo $item->content (); ?>
 			</div>
 
 			<ul class="horizontal-list bottom">
 				<li class="item">
 					<?php if ($item->notes () != '') { ?>
-					<i class="icon i_note"></i> <a class="note" href="<?php echo _url ('entry', 'note', 'id', $item->id ()); ?>">Modifier votre note</a>
+					<i class="icon i_note"></i> <a class="note" href="<?php echo _url ('entry', 'note', 'id', $item->id ()); ?>"><?php echo Translate::t ('update_note'); ?></a>
 					<?php } else { ?>
-					<i class="icon i_note_empty"></i> <a class="note" href="<?php echo _url ('entry', 'note', 'id', $item->id ()); ?>">Ajouter une note</a>
+					<i class="icon i_note_empty"></i> <a class="note" href="<?php echo _url ('entry', 'note', 'id', $item->id ()); ?>"><?php echo Translate::t ('add_note'); ?></a>
 					<?php } ?>
 				</li>
 				<li class="item">
 					<div class="dropdown">
 						<div id="dropdown-share-<?php echo $item->id ();?>" class="dropdown-target"></div>
-						<i class="icon i_share"></i> <a class="dropdown-toggle" href="#dropdown-share-<?php echo $item->id ();?>">Partager</a>
+						<i class="icon i_share"></i> <a class="dropdown-toggle" href="#dropdown-share-<?php echo $item->id ();?>"><?php echo Translate::t ('share'); ?></a>
 
 						<ul class="dropdown-menu">
 							<li class="dropdown-close"><a href="#close"><i class="icon i_close"></i></a></li>
 
-							<li class="item"><a href="mailto:?subject=<?php echo $item->title (); ?>&amp;body=J'ai trouvé cet article intéressant, tu peux le lire à cette adresse : <?php echo urlencode($item->link ()); ?>">Par mail</a></li>
+							<li class="item"><a href="mailto:?subject=<?php echo $item->title (); ?>&amp;body=J'ai trouvé cet article intéressant, tu peux le lire à cette adresse : <?php echo urlencode($item->link ()); ?>"><?php echo Translate::t ('by_email'); ?></a></li>
 							<?php
 							$shaarli = $this->conf->urlShaarli ();
 							if ($shaarli) {
 							?>
-							<li class="item"><a target="_blank" href="<?php echo $shaarli . '?post=' . urlencode($item->link ()) . '&amp;title=' . urlencode ($item->title ()) . '&amp;source=bookmarklet'; ?>">Shaarli</a></li>
+							<li class="item"><a target="_blank" href="<?php echo $shaarli . '?post=' . urlencode($item->link ()) . '&amp;title=' . urlencode ($item->title ()) . '&amp;source=bookmarklet'; ?>"><?php echo Translate::t ('on_shaarli'); ?></a></li>
 							<?php } ?>
 						</ul>
 					</div>
 				</li>
+				<?php $tags = $item->tags(); ?>
+				<?php if(!empty($tags)) { ?>
+				<li class="item">
+					<div class="dropdown">
+						<div id="dropdown-tags-<?php echo $item->id ();?>" class="dropdown-target"></div>
+						<i class="icon i_tag"></i> <a class="dropdown-toggle" href="#dropdown-tags-<?php echo $item->id ();?>"><?php echo Translate::t ('related_tags'); ?></a>
+
+						<ul class="dropdown-menu">
+							<li class="dropdown-close"><a href="#close"><i class="icon i_close"></i></a></li>
+
+							<?php foreach($tags as $tag) { ?>
+							<li class="item"><span><?php echo $tag; ?></span></li>
+							<?php } ?>
+						</ul>
+					</div>
+				</li>
+				<?php } ?>
 			</ul>
 		</div>
 	</div>
 	<?php } ?>
 	
-	<?php $this->entryPaginator->render ('pagination.phtml', 'page'); ?>
+	<?php $this->entryPaginator->render ('pagination.phtml', 'next'); ?>
 </div>
-<?php } else { ?>
-<div class="alert">
-	<span class="alert-head">Il n'y a aucun flux à afficher.</span>
-	<?php if (Session::param ('mode', 'all') == 'not_read') { ?>
-	<a class="print_all" href="<?php echo _url ('index', 'changeMode', 'mode', 'all'); ?>">Afficher tous les articles ?</a>
-	<?php }	?>
+
+	<?php } else { ?>
+<div class="alert alert-warn">
+	<span class="alert-head"><?php echo Translate::t ('no_feed_to_display'); ?></span>
 </div>
+	<?php } ?>
 <?php } ?>

+ 1 - 1
app/views/javascript/actualize.phtml

@@ -6,7 +6,7 @@ feeds.push ("<?php echo Url::display (array ('c' => 'feed', 'a' => 'actualize',
 function initProgressBar (init) {
 	if (init) {
 		$("body").after ("\<div id=\"actualizeProgress\" class=\"actualizeProgress\">\
-			Actualisation <span class=\"progress\">0 / " + feeds.length + "</span><br />\
+			<?php echo Translate::t ('refresh'); ?> <span class=\"progress\">0 / " + feeds.length + "</span><br />\
 			<progress id=\"actualizeProgressBar\" value=\"0\" max=\"" + feeds.length + "\"></progress>\
 		</div>");
 	} else {

+ 49 - 46
lib/lib_rss.php

@@ -20,55 +20,14 @@ function small_hash ($txt) {
 }
 
 function timestamptodate ($t, $hour = true) {
-	$jour = date ('d', $t);
-	$mois = date ('m', $t);
-	$annee = date ('Y', $t);
-	
-	switch ($mois) {
-	case 1:
-		$mois = 'janvier';
-		break;
-	case 2:
-		$mois = 'février';
-		break;
-	case 3:
-		$mois = 'mars';
-		break;
-	case 4:
-		$mois = 'avril';
-		break;
-	case 5:
-		$mois = 'mai';
-		break;
-	case 6:
-		$mois = 'juin';
-		break;
-	case 7:
-		$mois = 'juillet';
-		break;
-	case 8:
-		$mois = 'août';
-		break;
-	case 9:
-		$mois = 'septembre';
-		break;
-	case 10:
-		$mois = 'octobre';
-		break;
-	case 11:
-		$mois = 'novembre';
-		break;
-	case 12:
-		$mois = 'décembre';
-		break;
-	}
-	
-	$date = $jour . ' ' . $mois . ' ' . $annee;
+	$month = Translate::t (date('M', $t));
 	if ($hour) {
-		return $date . date (' \à H\:i', $t);
+		$date = Translate::t ('format_date_hour', $month);
 	} else {
-		return $date;
+		$date = Translate::t ('format_date', $month);
 	}
+
+	return date ($date, $t);
 }
 
 function sortEntriesByDate ($entry1, $entry2) {
@@ -124,6 +83,12 @@ function opml_import ($xml) {
 			}
 			
 			if ($title) {
+				// Permet d'éviter les soucis au niveau des id :
+				// ceux-ci sont générés en fonction de la date,
+				// un flux pourrait être dans une catégorie X avec l'id Y
+				// alors qu'il existe déjà la catégorie X mais avec l'id Z
+				// Y ne sera pas ajouté et le flux non plus vu que l'id
+				// de sa catégorie n'exisera pas
 				$catDAO = new CategoryDAO ();
 				$cat = $catDAO->searchByName ($title);
 				if ($cat === false) {
@@ -193,3 +158,41 @@ function get_content_by_parsing ($url, $path) {
 		throw new Exception ();
 	}
 }
+
+/* Télécharge le favicon d'un site, le place sur le serveur et retourne l'URL */
+function dowload_favicon ($website, $id) {
+	$url = 'http://g.etfv.co/' . $website;
+	$favicons_dir = PUBLIC_PATH . '/data/favicons';
+	$dest = $favicons_dir . '/' . $id . '.ico';
+	$favicon_url = '/data/favicons/' . $id . '.ico';
+
+	if (!is_dir ($favicons_dir)) {
+		if (!mkdir ($favicons_dir, 0755, true)) {
+			return $url;
+		}
+	}
+
+	if (!file_exists ($dest)) {
+		$c = curl_init ($url);
+		curl_setopt ($c, CURLOPT_HEADER, false);
+		curl_setopt ($c, CURLOPT_RETURNTRANSFER, true);
+		curl_setopt ($c, CURLOPT_BINARYTRANSFER, true);
+		$imgRaw = curl_exec ($c);
+
+		if (curl_getinfo ($c, CURLINFO_HTTP_CODE) == 200) {
+			$file = fopen ($dest, 'w');
+			if ($file === false) {
+				return $url;
+			}
+
+			fwrite ($file, $imgRaw);
+			fclose ($file);
+		} else {
+			return $url;
+		}
+
+		curl_close ($c);
+	}
+
+	return $favicon_url;
+}

BIN
public/favicon.ico


BIN
public/favicon.png


+ 174 - 58
public/install.php

@@ -70,7 +70,66 @@ function writeArray ($f, $array) {
 	}
 }
 
+// gestion internationalisation
+$translates = array ();
+$actual = 'en';
+function initTranslate () {
+	global $translates;
+	global $actual;
+
+	$l = getBetterLanguage ('en');
+	if (isset ($_SESSION['language'])) {
+		$l = $_SESSION['language'];
+	}
+	$actual = $l;
+
+	$file = APP_PATH . '/i18n/' . $actual . '.php';
+	if (file_exists ($file)) {
+		$translates = include ($file);
+	}
+}
+function getBetterLanguage ($fallback) {
+	$available = availableLanguages ();
+	$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
+	$language = strtolower (substr ($accept, 0, 2));
+
+	if (isset ($available[$language])) {
+		return $language;
+	} else {
+		return $fallback;
+	}
+}
+function availableLanguages () {
+	return array (
+		'en' => 'English',
+		'fr' => 'Français'
+	);
+}
+function _t ($key) {
+	global $translates;
+	$translate = $key;
+	if (isset ($translates[$key])) {
+		$translate = $translates[$key];
+	}
+
+	$args = func_get_args ();
+	unset($args[0]);
+
+	return vsprintf ($translate, $args);
+}
+
 /*** SAUVEGARDES ***/
+function saveLanguage () {
+	if (!empty ($_POST)) {
+		if (!isset ($_POST['language'])) {
+			return false;
+		}
+
+		$_SESSION['language'] = $_POST['language'];
+
+		header ('Location: index.php?step=1');
+	}
+}
 function saveStep2 () {
 	if (!empty ($_POST)) {
 		if (empty ($_POST['sel']) ||
@@ -95,6 +154,7 @@ function saveStep2 () {
 		writeLine ($f, '<?php');
 		writeLine ($f, 'return array (');
 		writeArray ($f, array (
+			'language' => $_SESSION['language'],
 			'old_entries' => $_SESSION['old_entries'],
 			'mail_login' => $_SESSION['mail_login']
 		));
@@ -149,10 +209,13 @@ function deleteInstall () {
 
 /*** VÉRIFICATIONS ***/
 function checkStep () {
+	$s0 = checkStep0 ();
 	$s1 = checkStep1 ();
 	$s2 = checkStep2 ();
 	$s3 = checkStep3 ();
-	if (STEP > 1 && $s1['all'] != 'ok') {
+	if (STEP > 0 && $s0['all'] != 'ok') {
+		header ('Location: index.php?step=0');
+	} elseif (STEP > 1 && $s1['all'] != 'ok') {
 		header ('Location: index.php?step=1');
 	} elseif (STEP > 2 && $s2['all'] != 'ok') {
 		header ('Location: index.php?step=2');
@@ -160,6 +223,16 @@ function checkStep () {
 		header ('Location: index.php?step=3');
 	}
 }
+function checkStep0 () {
+	$languages = availableLanguages ();
+	$language = isset ($_SESSION['language']) &&
+	            isset ($languages[$_SESSION['language']]);
+
+	return array (
+		'language' => $language ? 'ok' : 'ko',
+		'all' => $language ? 'ok' : 'ko'
+	);
+}
 function checkStep1 () {
 	$php = version_compare (PHP_VERSION, '5.1.0') >= 0;
 	$minz = file_exists (LIB_PATH . '/minz');
@@ -234,64 +307,98 @@ function checkBD () {
 }
 
 /*** AFFICHAGE ***/
+function printStep0 () {
+	global $actual;
+?>
+	<?php $s0 = checkStep0 (); if ($s0['all'] == 'ok') { ?>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('language_defined'); ?></p>
+	<?php } ?>
+
+	<form action="index.php?step=0" method="post">
+		<legend><?php echo _t ('choose_language'); ?></legend>
+		<div class="form-group">
+			<label class="group-name" for="language"><?php echo _t ('language'); ?></label>
+			<div class="group-controls">
+				<select name="language" id="language">
+				<?php $languages = availableLanguages (); ?>
+				<?php foreach ($languages as $short => $lib) { ?>
+				<option value="<?php echo $short; ?>"<?php echo $actual == $short ? ' selected="selected"' : ''; ?>><?php echo $lib; ?></option>
+				<?php } ?>
+				</select>
+			</div>
+		</div>
+
+		<div class="form-group form-actions">
+			<div class="group-controls">
+				<button type="submit" class="btn btn-important"><?php echo _t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo _t ('cancel'); ?></button>
+				<?php if ($s0['all'] == 'ok') { ?>
+				<a class="btn btn-important next-step" href="?step=1"><?php echo _t ('next_step'); ?></a>
+				<?php } ?>
+			</div>
+		</div>
+	</form>
+<?php
+}
+
 function printStep1 () {
 	$res = checkStep1 ();
 ?>
-	<noscript><p class="alert alert-warn"><span class="alert-head">Attention !</span> FreshRSS est plus agréable à utiliser avec le Javascript d'activé</p></noscript>
+	<noscript><p class="alert alert-warn"><span class="alert-head"><?php echo _t ('attention'); ?></span> <?php echo _t ('javascript_is_better'); ?></p></noscript>
 
 	<?php if ($res['php'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Votre version de PHP est la <?php echo PHP_VERSION; ?> et est compatible avec FreshRSS</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('php_is_ok', PHP_VERSION); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Votre version de PHP est la <?php echo PHP_VERSION; ?>. Vous devriez avoir au moins la version 5.1.0</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('php_is_nok', PHP_VERSION, '5.1.0'); ?></p>
 	<?php } ?>
 
 	<?php if ($res['minz'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Vous disposez du framework Minz</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('minz_is_ok'); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Vous ne disposez pas de la librairie Minz. Vous devriez exécuter le script <em>build.sh</em> ou bien <a href="https://github.com/marienfressinaud/MINZ">la télécharger sur Github</a> et installer dans le répertoire <em><?php echo LIB_PATH . '/minz'; ?></em> le contenu de son répertoire <em>/lib</em>.</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('minz_is_nok', LIB_PATH . '/minz'); ?></p>
 	<?php } ?>
 
 	<?php $version = curl_version(); ?>
 	<?php if ($res['curl'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Vous disposez de cURL dans sa version <?php echo $version['version']; ?></p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('curl_is_ok', $version['version']); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Vous ne disposez pas de cURL</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('curl_is_nok'); ?></p>
 	<?php } ?>
 
 	<?php if ($res['pdo-mysql'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Vous disposez de PDO et de son driver pour MySQL</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('pdomysql_is_ok'); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Vous ne disposez pas de PDO ou de son driver pour MySQL</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('pdomysql_is_nok'); ?></p>
 	<?php } ?>
 
 	<?php if ($res['cache'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Les droits sur le répertoire de cache sont bons</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('cache_is_ok'); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Veuillez vérifier les droits sur le répertoire <em><?php echo PUBLIC_PATH . '/../cache'; ?></em>. Le serveur HTTP doit être capable d'écrire dedans</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('file_is_nok', PUBLIC_PATH . '/../cache'); ?></p>
 	<?php } ?>
 
 	<?php if ($res['log'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Les droits sur le répertoire des logs sont bons</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('log_is_ok'); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Veuillez vérifier les droits sur le répertoire <em><?php echo PUBLIC_PATH . '/../log'; ?></em>. Le serveur HTTP doit être capable d'écrire dedans</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('file_is_nok', PUBLIC_PATH . '/../log'); ?></p>
 	<?php } ?>
 
 	<?php if ($res['configuration'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Les droits sur le répertoire de configuration sont bons</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('conf_is_ok'); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Veuillez vérifier les droits sur le répertoire <em><?php echo APP_PATH . '/configuration'; ?></em>. Le serveur HTTP doit être capable d'écrire dedans</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('file_is_nok', APP_PATH . '/configuration'); ?></p>
 	<?php } ?>
 
 	<?php if ($res['data'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> Les droits sur le répertoire de data sont bons</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('data_is_ok'); ?></p>
 	<?php } else { ?>
-	<p class="alert alert-error"><span class="alert-head">Arf !</span> Veuillez vérifier les droits sur le répertoire <em><?php echo PUBLIC_PATH . '/data'; ?></em>. Le serveur HTTP doit être capable d'écrire dedans</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('damn'); ?></span> <?php echo _t ('file_is_nok', PUBLIC_PATH . '/data'); ?></p>
 	<?php } ?>
 
 	<?php if ($res['all'] == 'ok') { ?>
-	<a class="btn btn-important next-step" href="?step=2">Passer à l'étape suivante</a>
+	<a class="btn btn-important next-step" href="?step=2"><?php echo _t ('next_step'); ?></a>
 	<?php } else { ?>
-	Veuillez corriger les erreurs avant de passer à l'étape suivante.
+	<p class="alert alert-error"><?php echo _t ('fix_errors_before'); ?></p>
 	<?php } ?>
 <?php
 }
@@ -299,15 +406,15 @@ function printStep1 () {
 function printStep2 () {
 ?>
 	<?php $s2 = checkStep2 (); if ($s2['all'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> La configuration générale a été enregistrée.</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('general_conf_is_ok'); ?></p>
 	<?php } ?>
 
 	<form action="index.php?step=2" method="post">
-		<legend>Configuration générale</legend>
+		<legend><?php echo _t ('general_configuration'); ?></legend>
 		<div class="form-group">
-			<label class="group-name" for="sel">Chaîne aléatoire</label>
+			<label class="group-name" for="sel"><?php echo _t ('random_string'); ?></label>
 			<div class="group-controls">
-				<input type="text" id="sel" name="sel" value="<?php echo isset ($_SESSION['sel']) ? $_SESSION['sel'] : '123~abcdefghijklmnopqrstuvwxyz~321'; ?>" /> <i class="icon i_help"></i> Vous devriez changer cette valeur par n'importe quelle autre
+				<input type="text" id="sel" name="sel" value="<?php echo isset ($_SESSION['sel']) ? $_SESSION['sel'] : '123~abcdefghijklmnopqrstuvwxyz~321'; ?>" /> <i class="icon i_help"></i> <?php echo _t ('change_value'); ?>
 			</div>
 		</div>
 
@@ -315,40 +422,40 @@ function printStep2 () {
 			$url = substr ($_SERVER['PHP_SELF'], 0, -10);
 		?>
 		<div class="form-group">
-			<label class="group-name" for="base_url">Base de l'url</label>
+			<label class="group-name" for="base_url"><?php echo _t ('base_url'); ?></label>
 			<div class="group-controls">
-				<input type="text" id="base_url" name="base_url" value="<?php echo isset ($_SESSION['base_url']) ? $_SESSION['base_url'] : $url; ?>" /> <i class="icon i_help"></i> Laissez tel quel dans le doute
+				<input type="text" id="base_url" name="base_url" value="<?php echo isset ($_SESSION['base_url']) ? $_SESSION['base_url'] : $url; ?>" /> <i class="icon i_help"></i> <?php echo _t ('do_not_change_if_doubt'); ?>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="title">Titre</label>
+			<label class="group-name" for="title"><?php echo _t ('title'); ?></label>
 			<div class="group-controls">
-				<input type="text" id="title" name="title" value="<?php echo isset ($_SESSION['title']) ? $_SESSION['title'] : 'FreshRSS'; ?>" />
+				<input type="text" id="title" name="title" value="<?php echo isset ($_SESSION['title']) ? $_SESSION['title'] : _t ('freshrss'); ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="old_entries">Supprimer les articles tous les</label>
+			<label class="group-name" for="old_entries"><?php echo _t ('delete_articles_every'); ?></label>
 			<div class="group-controls">
-				<input type="number" id="old_entries" name="old_entries" value="<?php echo isset ($_SESSION['old_entries']) ? $_SESSION['old_entries'] : '3'; ?>" /> mois
+				<input type="number" id="old_entries" name="old_entries" value="<?php echo isset ($_SESSION['old_entries']) ? $_SESSION['old_entries'] : '3'; ?>" /> <?php echo _t ('month'); ?>
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="mail_login">Adresse mail de connexion (utilise <a href="https://persona.org/">Persona</a>)</label>
+			<label class="group-name" for="mail_login"><?php echo _t ('persona_connection_email'); ?></label>
 			<div class="group-controls">
-				<input type="email" id="mail_login" name="mail_login" value="<?php echo isset ($_SESSION['mail_login']) ? $_SESSION['mail_login'] : ''; ?>" placeholder="Laissez vide pour désactiver" />
-				<noscript><b>nécessite que javascript soit activé</b></noscript>
+				<input type="email" id="mail_login" name="mail_login" value="<?php echo isset ($_SESSION['mail_login']) ? $_SESSION['mail_login'] : ''; ?>" placeholder="<?php echo _t ('blank_to_disable'); ?>" />
+				<noscript><b><?php echo _t ('javascript_should_be_activated'); ?></b></noscript>
 			</div>
 		</div>
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button type="submit" class="btn btn-important">Valider</button>
-				<button type="reset" class="btn">Annuler</button>
+				<button type="submit" class="btn btn-important"><?php echo _t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo _t ('cancel'); ?></button>
 				<?php if ($s2['all'] == 'ok') { ?>
-				<a class="btn btn-important next-step" href="?step=3">Passer à l'étape suivante</a>
+				<a class="btn btn-important next-step" href="?step=3"><?php echo _t ('next_step'); ?></a>
 				<?php } ?>
 			</div>
 		</div>
@@ -359,34 +466,34 @@ function printStep2 () {
 function printStep3 () {
 ?>
 	<?php $s3 = checkStep3 (); if ($s3['all'] == 'ok') { ?>
-	<p class="alert alert-success"><span class="alert-head">Ok !</span> La configuration de la base de données a été enregistrée.</p>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('ok'); ?></span> <?php echo _t ('bdd_conf_is_ok'); ?></p>
 	<?php } ?>
 
 	<form action="index.php?step=3" method="post">
-		<legend>Configuration de la base de données</legend>
+		<legend><?php echo _t ('bdd_configuration'); ?></legend>
 		<div class="form-group">
-			<label class="group-name" for="host">Host</label>
+			<label class="group-name" for="host"><?php echo _t ('host'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="host" name="host" value="<?php echo isset ($_SESSION['bd_host']) ? $_SESSION['bd_host'] : 'localhost'; ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="user">Username</label>
+			<label class="group-name" for="user"><?php echo _t ('username'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="user" name="user" value="<?php echo isset ($_SESSION['bd_user']) ? $_SESSION['bd_user'] : ''; ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="pass">Password</label>
+			<label class="group-name" for="pass"><?php echo _t ('password'); ?></label>
 			<div class="group-controls">
 				<input type="password" id="pass" name="pass" value="<?php echo isset ($_SESSION['bd_pass']) ? $_SESSION['bd_pass'] : ''; ?>" />
 			</div>
 		</div>
 
 		<div class="form-group">
-			<label class="group-name" for="base">Base de données</label>
+			<label class="group-name" for="base"><?php echo _t ('bdd'); ?></label>
 			<div class="group-controls">
 				<input type="text" id="base" name="base" value="<?php echo isset ($_SESSION['bd_name']) ? $_SESSION['bd_name'] : ''; ?>" />
 			</div>
@@ -394,10 +501,10 @@ function printStep3 () {
 
 		<div class="form-group form-actions">
 			<div class="group-controls">
-				<button type="submit" class="btn btn-important">Valider</button>
-				<button type="reset" class="btn">Annuler</button>
+				<button type="submit" class="btn btn-important"><?php echo _t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo _t ('cancel'); ?></button>
 				<?php if ($s3['all'] == 'ok') { ?>
-				<a class="btn btn-important next-step" href="?step=4">Passer à l'étape suivante</a>
+				<a class="btn btn-important next-step" href="?step=4"><?php echo _t ('next_step'); ?></a>
 				<?php } ?>
 			</div>
 		</div>
@@ -407,23 +514,27 @@ function printStep3 () {
 
 function printStep4 () {
 ?>
-	<p class="alert alert-success"><span class="alert-head">Félicitations !</span> L'installation s'est bien passée. Il faut maintenant supprimer le fichier <em>install.php</em> pour pouvoir accéder à FreshRSS... ou simplement cliquer sur le bouton ci-dessous ;)</p>
-	<a class="btn btn-important next-step" href="?step=5">Terminer l'installation</a>
+	<p class="alert alert-success"><span class="alert-head"><?php echo _t ('congratulations'); ?></span> <?php echo _t ('installation_is_ok'); ?></p>
+	<a class="btn btn-important next-step" href="?step=5"><?php echo _t ('finish_installation'); ?></a>
 <?php
 }
 
 function printStep5 () {
 ?>
-	<p class="alert alert-error"><span class="alert-head">Oups !</span> Quelque chose s'est mal passé, vous devriez supprimer le fichier <?php echo PUBLIC_PATH . '/install.php' ?> à la main.</p>
+	<p class="alert alert-error"><span class="alert-head"><?php echo _t ('oops'); ?></span> <?php echo _t ('install_not_deleted', PUBLIC_PATH . '/install.php'); ?></p>
 <?php
 }
 
+initTranslate ();
 
 checkStep ();
 
 switch (STEP) {
-case 1:
+case 0:
 default:
+	saveLanguage ();
+	break;
+case 1:
 	break;
 case 2:
 	saveStep2 ();
@@ -443,7 +554,8 @@ case 5:
 	<head>
 		<meta charset="utf-8">
 		<meta name="viewport" content="initial-scale=1.0">
-		<title>Installation - FreshRSS</title>
+		<title><?php echo _t ('freshrss_installation'); ?></title>
+		<link rel="stylesheet" type="text/css" media="all" href="theme/fallback.css" />
 		<link rel="stylesheet" type="text/css" media="all" href="theme/global.css" />
 		<link rel="stylesheet" type="text/css" media="all" href="theme/freshrss.css" />
 	</head>
@@ -451,25 +563,29 @@ case 5:
 
 <div class="header">
 	<div class="item title">
-		<h1><a href="index.php">FreshRSS</a></h1>
-		<h2>Installation - étape <?php echo STEP; ?></h2>
+		<h1><a href="index.php"><?php echo _t ('freshrss'); ?></a></h1>
+		<h2><?php echo _t ('installation_step', STEP); ?></h2>
 	</div>
 </div>
 
 <div id="global">
 	<ul class="nav nav-list aside">
-		<li class="nav-header">Étapes</li>
-		<li class="item<?php echo STEP == 1 ? ' active' : ''; ?>"><a href="?step=1">Vérifications</a></li>
-		<li class="item<?php echo STEP == 2 ? ' active' : ''; ?>"><a href="?step=2">Configuration générale</a></li>
-		<li class="item<?php echo STEP == 3 ? ' active' : ''; ?>"><a href="?step=3">Configuration de la base de données</a></li>
-		<li class="item<?php echo STEP == 4 ? ' active' : ''; ?>"><a href="?step=4">This is the end</a></li>
+		<li class="nav-header"><?php echo _t ('steps'); ?></li>
+		<li class="item<?php echo STEP == 0 ? ' active' : ''; ?>"><a href="?step=0"><?php echo _t ('language'); ?></a></li>
+		<li class="item<?php echo STEP == 1 ? ' active' : ''; ?>"><a href="?step=1"><?php echo _t ('checks'); ?></a></li>
+		<li class="item<?php echo STEP == 2 ? ' active' : ''; ?>"><a href="?step=2"><?php echo _t ('general_configuration'); ?></a></li>
+		<li class="item<?php echo STEP == 3 ? ' active' : ''; ?>"><a href="?step=3"><?php echo _t ('bdd_configuration'); ?></a></li>
+		<li class="item<?php echo STEP == 4 ? ' active' : ''; ?>"><a href="?step=4"><?php echo _t ('this_is_the_end'); ?></a></li>
 	</ul>
 
 	<div class="post">
 		<?php
 		switch (STEP) {
-		case 1:
+		case 0:
 		default:
+			printStep0 ();
+			break;
+		case 1:
 			printStep1 ();
 			break;
 		case 2:

BIN
public/logo.png


+ 535 - 0
public/logo.svg

@@ -0,0 +1,535 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 13.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 14948)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   x="0px"
+   y="0px"
+   width="64"
+   height="64"
+   viewBox="0 0 64.000001 64"
+   enable-background="new 0 0 1094.658 1790.375"
+   xml:space="preserve"
+   id="svg2"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="logo.svg"
+   inkscape:export-filename="/home/marien/Téléchargements/logo.png"
+   inkscape:export-xdpi="45"
+   inkscape:export-ydpi="45"><metadata
+     id="metadata491"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs489"><inkscape:path-effect
+       effect="spiro"
+       id="path-effect7565"
+       is_visible="true" /><inkscape:path-effect
+       effect="knot"
+       id="path-effect7563"
+       is_visible="true"
+       interruption_width="3"
+       prop_to_stroke_width="true"
+       add_stroke_width="true"
+       add_other_stroke_width="true"
+       switcher_size="15"
+       crossing_points_vector="" /><inkscape:path-effect
+       effect="gears"
+       id="path-effect7561"
+       is_visible="true"
+       teeth="7"
+       phi="5" /><inkscape:path-effect
+       effect="bend_path"
+       id="path-effect7559"
+       is_visible="true"
+       bendpath="m -248.45246,916.99823 199.14128,0"
+       prop_scale="1"
+       scale_y_rel="false"
+       vertical="false" /><inkscape:path-effect
+       effect="bend_path"
+       id="path-effect7555"
+       is_visible="true"
+       bendpath="m 224.32971,226.68881 799.18099,0"
+       prop_scale="1"
+       scale_y_rel="false"
+       vertical="false" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#SVGID_2_"
+       id="radialGradient3547"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.808,0,0,0.7533,3.8687,-16.2244)"
+       cx="845.57233"
+       cy="986.60498"
+       r="1001.9801" /><radialGradient
+       inkscape:collect="always"
+       xlink:href="#SVGID_3_"
+       id="radialGradient3549"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.808,0,0,0.7533,3.8687,-16.2244)"
+       cx="1011.6025"
+       cy="976.11871"
+       r="923.77258" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#SVGID_4_"
+       id="linearGradient3551"
+       gradientUnits="userSpaceOnUse"
+       x1="263.9678"
+       y1="1034.9419"
+       x2="358.27261"
+       y2="523.93848" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#SVGID_5_"
+       id="linearGradient3553"
+       gradientUnits="userSpaceOnUse"
+       x1="319.9375"
+       y1="1044.5796"
+       x2="414.20291"
+       y2="533.79028" /><linearGradient
+       inkscape:collect="always"
+       xlink:href="#SVGID_8_"
+       id="linearGradient3555"
+       gradientUnits="userSpaceOnUse"
+       x1="391.4819"
+       y1="1189.481"
+       x2="919.40527"
+       y2="1189.481" /><filter
+       inkscape:collect="always"
+       id="filter4359"
+       color-interpolation-filters="sRGB"><feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.0569585"
+         id="feGaussianBlur4361" /></filter><filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter4359-8"><feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.0569585"
+         id="feGaussianBlur4361-8" /></filter><filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter4359-6"><feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.0569585"
+         id="feGaussianBlur4361-9" /></filter><filter
+       color-interpolation-filters="sRGB"
+       inkscape:collect="always"
+       id="filter4359-6-6"><feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="1.0569585"
+         id="feGaussianBlur4361-9-8" /></filter><inkscape:path-effect
+       effect="spiro"
+       id="path-effect7565-6"
+       is_visible="true" /><inkscape:path-effect
+       effect="spiro"
+       id="path-effect7565-6-6"
+       is_visible="true" /><inkscape:path-effect
+       effect="spiro"
+       id="path-effect7565-4"
+       is_visible="true" /></defs><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="709"
+     id="namedview487"
+     showgrid="false"
+     inkscape:zoom="8.4362214"
+     inkscape:cx="22.970248"
+     inkscape:cy="8.9627389"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     borderlayer="true" /><pattern
+     x="-129.418"
+     y="1715.368"
+     width="69"
+     height="69"
+     patternUnits="userSpaceOnUse"
+     id="Unnamed_Pattern"
+     viewBox="2.125 -70.896 69 69"
+     overflow="visible"><g
+       id="g5"><polygon
+         fill="none"
+         points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896   "
+         id="polygon7" /><polygon
+         fill="#F7C158"
+         points="71.125,-1.896 2.125,-1.896 2.125,-70.896 71.125,-70.896   "
+         id="polygon9" /><g
+         id="g11"><path
+           fill="#FFFFFF"
+           d="M61.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path13" /><path
+           fill="#FFFFFF"
+           d="M54.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path15" /><path
+           fill="#FFFFFF"
+           d="M46.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path17" /><path
+           fill="#FFFFFF"
+           d="M38.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path19" /><path
+           fill="#FFFFFF"
+           d="M31.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path21" /><path
+           fill="#FFFFFF"
+           d="M23.439-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path23" /><path
+           fill="#FFFFFF"
+           d="M15.772-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path25" /><path
+           fill="#FFFFFF"
+           d="M8.105-71.653c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path27" /><path
+           fill="#FFFFFF"
+           d="M0.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19C0.361-71.362,0.3-71.4,0.248-71.335     c-0.051,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path29" /></g><g
+         id="g31"><path
+           fill="#FFFFFF"
+           d="M69.439-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.063-0.165,0.128     c-0.051,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path33" /></g><path
+         fill="#FFFFFF"
+         d="M0.495-71.653c0.018,0.072,0.008,0.127-0.026,0.19c-0.052,0.101-0.113,0.063-0.165,0.128    c-0.051,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161    c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631    c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45    c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221    c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337    c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207    c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224C0.5-71.68,0.503-71.744,0.51-71.626    c-0.021,0.011-0.021-0.005-0.03-0.025"
+         id="path35" /><g
+         id="g37"><g
+           id="g39"><path
+             fill="#FFFFFF"
+             d="M69.439-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path41" /><path
+             fill="#FFFFFF"
+             d="M61.778-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path43" /><path
+             fill="#FFFFFF"
+             d="M54.118-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path45" /><path
+             fill="#FFFFFF"
+             d="M46.458-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path47" /><path
+             fill="#FFFFFF"
+             d="M38.797-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path49" /><path
+             fill="#FFFFFF"
+             d="M31.137-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path51" /><path
+             fill="#FFFFFF"
+             d="M23.477-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path53" /><path
+             fill="#FFFFFF"
+             d="M15.816-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path55" /><path
+             fill="#FFFFFF"
+             d="M8.156-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path57" /><path
+             fill="#FFFFFF"
+             d="M0.495-64.001c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143C2-61.45,2.217-61.397,2.391-61.46c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path59" /></g><g
+           id="g61"><path
+             fill="#FFFFFF"
+             d="M69.439-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path63" /><path
+             fill="#FFFFFF"
+             d="M61.778-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path65" /><path
+             fill="#FFFFFF"
+             d="M54.118-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path67" /><path
+             fill="#FFFFFF"
+             d="M46.458-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path69" /><path
+             fill="#FFFFFF"
+             d="M38.797-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path71" /><path
+             fill="#FFFFFF"
+             d="M31.137-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path73" /><path
+             fill="#FFFFFF"
+             d="M23.477-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path75" /><path
+             fill="#FFFFFF"
+             d="M15.816-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path77" /><path
+             fill="#FFFFFF"
+             d="M8.156-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path79" /><path
+             fill="#FFFFFF"
+             d="M0.495-56.348c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-56.374,0.503-56.438,0.51-56.32      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path81" /></g><g
+           id="g83"><path
+             fill="#FFFFFF"
+             d="M69.439-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path85" /><path
+             fill="#FFFFFF"
+             d="M61.778-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path87" /><path
+             fill="#FFFFFF"
+             d="M54.118-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path89" /><path
+             fill="#FFFFFF"
+             d="M46.458-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path91" /><path
+             fill="#FFFFFF"
+             d="M38.797-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path93" /><path
+             fill="#FFFFFF"
+             d="M31.137-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path95" /><path
+             fill="#FFFFFF"
+             d="M23.477-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path97" /><path
+             fill="#FFFFFF"
+             d="M15.816-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path99" /><path
+             fill="#FFFFFF"
+             d="M8.156-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path101" /><path
+             fill="#FFFFFF"
+             d="M0.495-48.695c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path103" /></g><g
+           id="g105"><path
+             fill="#FFFFFF"
+             d="M69.439-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path107" /><path
+             fill="#FFFFFF"
+             d="M61.778-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path109" /><path
+             fill="#FFFFFF"
+             d="M54.118-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path111" /><path
+             fill="#FFFFFF"
+             d="M46.458-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path113" /><path
+             fill="#FFFFFF"
+             d="M38.797-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path115" /><path
+             fill="#FFFFFF"
+             d="M31.137-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path117" /><path
+             fill="#FFFFFF"
+             d="M23.477-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path119" /><path
+             fill="#FFFFFF"
+             d="M15.816-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path121" /><path
+             fill="#FFFFFF"
+             d="M8.156-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      C8.15-41.004,8.149-41.02,8.14-41.04"
+             id="path123" /><path
+             fill="#FFFFFF"
+             d="M0.495-41.042c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path125" /></g><g
+           id="g127"><path
+             fill="#FFFFFF"
+             d="M69.439-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path129" /><path
+             fill="#FFFFFF"
+             d="M61.778-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path131" /><path
+             fill="#FFFFFF"
+             d="M54.118-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path133" /><path
+             fill="#FFFFFF"
+             d="M46.458-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path135" /><path
+             fill="#FFFFFF"
+             d="M38.797-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path137" /><path
+             fill="#FFFFFF"
+             d="M31.137-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path139" /><path
+             fill="#FFFFFF"
+             d="M23.477-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path141" /><path
+             fill="#FFFFFF"
+             d="M15.816-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path143" /><path
+             fill="#FFFFFF"
+             d="M8.156-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path145" /><path
+             fill="#FFFFFF"
+             d="M0.495-33.39c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-33.416,0.503-33.48,0.51-33.362      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path147" /></g><g
+           id="g149"><path
+             fill="#FFFFFF"
+             d="M69.439-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path151" /><path
+             fill="#FFFFFF"
+             d="M61.778-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path153" /><path
+             fill="#FFFFFF"
+             d="M54.118-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path155" /><path
+             fill="#FFFFFF"
+             d="M46.458-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path157" /><path
+             fill="#FFFFFF"
+             d="M38.797-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path159" /><path
+             fill="#FFFFFF"
+             d="M31.137-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path161" /><path
+             fill="#FFFFFF"
+             d="M23.477-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path163" /><path
+             fill="#FFFFFF"
+             d="M15.816-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path165" /><path
+             fill="#FFFFFF"
+             d="M8.156-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path167" /><path
+             fill="#FFFFFF"
+             d="M0.495-25.736c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path169" /></g><g
+           id="g171"><path
+             fill="#FFFFFF"
+             d="M69.439-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path173" /><path
+             fill="#FFFFFF"
+             d="M61.778-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path175" /><path
+             fill="#FFFFFF"
+             d="M54.118-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path177" /><path
+             fill="#FFFFFF"
+             d="M46.458-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path179" /><path
+             fill="#FFFFFF"
+             d="M38.797-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path181" /><path
+             fill="#FFFFFF"
+             d="M31.137-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path183" /><path
+             fill="#FFFFFF"
+             d="M23.477-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path185" /><path
+             fill="#FFFFFF"
+             d="M15.816-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path187" /><path
+             fill="#FFFFFF"
+             d="M8.156-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path189" /><path
+             fill="#FFFFFF"
+             d="M0.495-18.084c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224C0.5-18.11,0.503-18.175,0.51-18.057      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path191" /></g><g
+           id="g193"><path
+             fill="#FFFFFF"
+             d="M69.439-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362C69-9.692,69.159-9.523,69.154-9.4c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path195" /><path
+             fill="#FFFFFF"
+             d="M61.778-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path197" /><path
+             fill="#FFFFFF"
+             d="M54.118-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path199" /><path
+             fill="#FFFFFF"
+             d="M46.458-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path201" /><path
+             fill="#FFFFFF"
+             d="M38.797-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path203" /><path
+             fill="#FFFFFF"
+             d="M31.137-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path205" /><path
+             fill="#FFFFFF"
+             d="M23.477-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path207" /><path
+             fill="#FFFFFF"
+             d="M15.816-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.009,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      c0.177,0.042,0.384-0.104,0.543-0.143c0.18-0.043,0.397,0.01,0.571-0.053C17.933-7.969,17.839-8.227,18-8.34      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path209" /><path
+             fill="#FFFFFF"
+             d="M8.156-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      C7.915-10.05,7.866-9.836,7.886-9.75C7.717-9.692,7.876-9.523,7.871-9.4C7.868-9.351,7.83-9.295,7.826-9.239      c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631      C9.114-7.652,9.321-7.799,9.48-7.837c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path211" /><path
+             fill="#FFFFFF"
+             d="M0.495-10.431c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128      C0.254-10.05,0.205-9.836,0.225-9.75C0.056-9.692,0.215-9.523,0.21-9.4c-0.002,0.05-0.041,0.105-0.045,0.161      c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-8.671,0.501-8.456,0.668-8.325c0.19,0.148,0.365,0.572,0.608,0.631      C1.454-7.652,1.66-7.799,1.819-7.837C2-7.88,2.217-7.827,2.391-7.89c0.222-0.079,0.127-0.337,0.288-0.45      c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46C3.477-8.933,3.471-8.995,3.5-9.071      c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337      c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207      c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169      c-0.021,0.011-0.021-0.005-0.03-0.025"
+             id="path213" /></g></g><g
+         id="g215"><path
+           fill="#FFFFFF"
+           d="M69.439-2.778c0.018,0.072,0.008,0.127-0.026,0.19C69.361-2.487,69.3-2.525,69.248-2.46     c-0.051,0.063-0.099,0.276-0.079,0.362C69-2.04,69.159-1.871,69.154-1.748c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C70.397,0,70.604-0.146,70.763-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.215,0.124-0.215,0.224c0.002,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path217" /><path
+           fill="#FFFFFF"
+           d="M61.778-2.778c0.018,0.072,0.007,0.127-0.026,0.19C61.7-2.487,61.64-2.525,61.587-2.46     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C62.737,0,62.943-0.146,63.103-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C61.915-3.117,61.78-3.02,61.781-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path219" /><path
+           fill="#FFFFFF"
+           d="M54.118-2.778c0.018,0.072,0.007,0.127-0.026,0.19C54.04-2.487,53.98-2.525,53.927-2.46     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C55.077,0,55.283-0.146,55.442-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C54.255-3.117,54.12-3.02,54.121-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path221" /><path
+           fill="#FFFFFF"
+           d="M46.458-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C47.416,0,47.623-0.146,47.782-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C46.594-3.117,46.459-3.02,46.46-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path223" /><path
+           fill="#FFFFFF"
+           d="M38.797-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C39.756,0,39.962-0.146,40.122-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C38.934-3.117,38.799-3.02,38.8-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path225" /><path
+           fill="#FFFFFF"
+           d="M31.137-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C32.095,0,32.302-0.146,32.461-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224C31.273-3.117,31.139-3.02,31.14-2.92c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path227" /><path
+           fill="#FFFFFF"
+           d="M23.477-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C24.435,0,24.642-0.146,24.801-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     c-0.021,0.011-0.021-0.005-0.03-0.025"
+           id="path229" /><path
+           fill="#FFFFFF"
+           d="M15.816-2.778c0.018,0.072,0.007,0.127-0.026,0.19c-0.053,0.101-0.112,0.063-0.165,0.128     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C16.774,0,16.981-0.146,17.14-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789c-0.18,0.034-0.287,0.126-0.442,0.207     c-0.17,0.088-0.139,0.166-0.318,0.224c-0.081,0.026-0.216,0.124-0.215,0.224c0.001,0.115,0.005,0.051,0.012,0.169     C15.81-2.74,15.809-2.756,15.8-2.776"
+           id="path231" /><path
+           fill="#FFFFFF"
+           d="M8.156-2.778c0.018,0.072,0.007,0.127-0.026,0.19C8.077-2.487,8.018-2.525,7.965-2.46     c-0.05,0.063-0.099,0.276-0.079,0.362c-0.169,0.058-0.01,0.227-0.015,0.35C7.868-1.698,7.83-1.643,7.826-1.587     c-0.01,0.119,0.017,0.266,0.068,0.37c0.097,0.198,0.268,0.413,0.435,0.544c0.19,0.148,0.365,0.572,0.608,0.631     C9.114,0,9.321-0.146,9.48-0.185c0.18-0.043,0.397,0.01,0.571-0.053c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.069,0.339-0.263,0.376-0.46c0.016-0.082,0.01-0.145,0.039-0.221     c0.039-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.052-0.12-0.064-0.187c-0.022-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C8.954-3.54,8.847-3.448,8.692-3.367     c-0.17,0.088-0.139,0.166-0.318,0.224C8.292-3.117,8.158-3.02,8.159-2.92C8.16-2.805,8.164-2.869,8.17-2.751     C8.15-2.74,8.149-2.756,8.14-2.776"
+           id="path233" /><path
+           fill="#FFFFFF"
+           d="M0.495-2.778c0.018,0.072,0.008,0.127-0.026,0.19C0.417-2.487,0.356-2.525,0.304-2.46     C0.253-2.397,0.205-2.184,0.225-2.098C0.056-2.04,0.215-1.871,0.21-1.748c-0.002,0.05-0.041,0.105-0.045,0.161     c-0.01,0.119,0.017,0.266,0.068,0.37C0.33-1.019,0.501-0.804,0.668-0.673c0.19,0.148,0.365,0.572,0.608,0.631     C1.454,0,1.66-0.146,1.819-0.185C2-0.228,2.217-0.175,2.391-0.237c0.222-0.079,0.127-0.337,0.288-0.45     c0.104-0.074,0.287-0.01,0.406-0.051c0.2-0.07,0.339-0.263,0.376-0.46C3.477-1.28,3.471-1.343,3.5-1.419     c0.038-0.103,0.111-0.16,0.09-0.293c-0.01-0.062-0.051-0.12-0.064-0.187c-0.021-0.114,0.002-0.224,0-0.337     c-0.003-0.2,0.017-0.379-0.078-0.55c-0.38-0.688-1.236-0.929-1.975-0.789C1.293-3.54,1.187-3.448,1.031-3.367     c-0.17,0.088-0.139,0.166-0.318,0.224C0.632-3.117,0.498-3.02,0.498-2.92C0.5-2.805,0.503-2.869,0.51-2.751     C0.489-2.74,0.488-2.756,0.479-2.776"
+           id="path235" /></g></g></pattern><g
+     inkscape:groupmode="layer"
+     id="layer1"
+     inkscape:label="Calque"
+     style="display:inline"
+     transform="translate(-515.76112,-810.41437)" /><path
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccc"
+     id="path2888-1"
+     d="m 3.3578203,-5.267552e-6 0,14.760871267552 C 29.42896,16.784066 46.69792,29.918443 49.32849,61.531279 l 14.67151,0 C 61.35789,26.053521 43.35779,3.6573148 3.3578203,-5.267552e-6 z"
+     style="fill:#333333;fill-opacity:1;stroke:none" /><path
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccc"
+     id="path2888"
+     d="m 0.35026032,2.0766248 0,14.7608612 C 26.4214,18.860686 43.69038,31.995071 46.32095,63.607882 l 14.6715,0 C 58.35033,28.130136 40.35023,5.7339448 0.35026032,2.0766248 z"
+     style="fill:#0069cc;fill-opacity:1;stroke:none" /><path
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccc"
+     id="path2878-3"
+     d="m 1.7633203,20.950173 0,12.436529 C 19.7331,34.943711 29.15588,44.808215 30.45359,62.570171 l 12.29581,0 C 40.38115,38.120659 27.46785,23.546161 1.7633203,20.950173 z"
+     style="fill:#333333;fill-opacity:1;stroke:none" /><path
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccc"
+     id="path2878"
+     d="m 0.37570032,22.275047 0,12.436529 C 18.34547,36.268585 27.76826,46.133089 29.06596,63.895045 l 12.29583,0 C 38.99353,39.445532 26.08023,24.871034 0.37570032,22.275047 z"
+     style="fill:#0069cc;fill-opacity:1;stroke:none" /><path
+     transform="matrix(0.15445355,0,0,0.15712532,57.01273,-24.178134)"
+     d="m -240.4163,495.76813 a 63.63961,63.63961 0 1 1 -127.27922,0 63.63961,63.63961 0 1 1 127.27922,0 z"
+     sodipodi:ry="63.63961"
+     sodipodi:rx="63.63961"
+     sodipodi:cy="495.76813"
+     sodipodi:cx="-304.05591"
+     id="path2872"
+     style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     sodipodi:type="arc" /><path
+     transform="matrix(0.16357265,0,0,0.16656745,60.14682,-29.181044)"
+     d="m -241.52652,507.6035 a 63.63961,63.63961 0 1 1 -75.29649,-74.18119 l 12.7671,62.34582 z"
+     sodipodi:ry="63.63961"
+     sodipodi:rx="63.63961"
+     sodipodi:cy="495.76813"
+     sodipodi:cx="-304.05591"
+     id="path2872-8"
+     style="fill:#0069cc;fill-opacity:1;fill-rule:evenodd;stroke:none"
+     sodipodi:type="arc"
+     sodipodi:start="0.18706395"
+     sodipodi:end="4.5104026" /></svg>

+ 65 - 0
public/theme/fallback.css

@@ -0,0 +1,65 @@
+.btn {
+	background: #fff;
+	background: -moz-linear-gradient(top, #fff 0%, #eee 100%);
+	background: -webkit-linear-gradient(top, #fff 0%, #eee 100%);
+	background: -o-linear-gradient(top, #fff 0%, #eee 100%);
+	background: -ms-linear-gradient(top, #fff 0%, #eee 100%);
+}
+	.btn:hover {
+		background: #f0f0f0;
+		background: -moz-linear-gradient(top, #f8f8f8 0%, #f0f0f0 100%);
+		background: -webkit-linear-gradient(top, #f8f8f8 0%, #f0f0f0 100%);
+		background: -o-linear-gradient(top, #f8f8f8 0%, #f0f0f0 100%);
+		background: -ms-linear-gradient(top, #f8f8f8 0%, #f0f0f0 100%);
+	}
+	.btn.btn-important {
+		background: #0084CC;
+		background: -moz-linear-gradient(top, #0084CC 0%, #0045CC 100%);
+		background: -webkit-linear-gradient(top, #0084CC 0%, #0045CC 100%);
+		background: -o-linear-gradient(top, #0084CC 0%, #0045CC 100%);
+		background: -ms-linear-gradient(top, #0084CC 0%, #0045CC 100%);
+	}
+		.btn.btn-important:hover {
+			background: -moz-linear-gradient(top, #0066CC 0%, #0045CC 100%);
+			background: -webkit-linear-gradient(top, #0066CC 0%, #0045CC 100%);
+			background: -o-linear-gradient(top, #0066CC 0%, #0045CC 100%);
+			background: -ms-linear-gradient(top, #0066CC 0%, #0045CC 100%);
+		}
+	.btn.btn-attention {
+		background: #E95B57;
+		background: -moz-linear-gradient(top, #E95B57 0%, #BD362F 100%);
+		background: -webkit-linear-gradient(top, #E95B57 0%, #BD362F 100%);
+		background: -o-linear-gradient(top, #E95B57 0%, #BD362F 100%);
+		background: -ms-linear-gradient(top, #E95B57 0%, #BD362F 100%);
+	}
+		.btn.btn-attention:hover {
+			background: -moz-linear-gradient(top, #D14641 0%, #BD362F 100%);
+			background: -webkit-linear-gradient(top, #D14641 0%, #BD362F 100%);
+			background: -o-linear-gradient(top, #D14641 0%, #BD362F 100%);
+			background: -ms-linear-gradient(top, #D14641 0%, #BD362F 100%);
+		}
+
+
+.nav-head {
+	background: #fff;
+	background: -moz-linear-gradient(top, #fff 0%, #f0f0f0 100%);
+	background: -webkit-linear-gradient(top, #fff 0%, #f0f0f0 100%);
+	background: -o-linear-gradient(top, #fff 0%, #f0f0f0 100%);
+	background: -ms-linear-gradient(top, #fff 0%, #f0f0f0 100%);
+}
+
+.header > .item.search input {
+	-moz-transition: width 200ms linear;
+	 -webkit-transition: width 200ms linear;
+	-o-transition: width 200ms linear;
+	-ms-transition: width 200ms linear;
+}
+
+@media(max-width: 840px) {
+	.aside {
+		-moz-transition: width 200ms linear;
+		 -webkit-transition: width 200ms linear;
+		-o-transition: width 200ms linear;
+		-ms-transition: width 200ms linear;
+	}
+}

+ 14 - 1
public/theme/freshrss.css

@@ -15,16 +15,23 @@
 		.header > .item.title {
 			width: 250px;
 		}
+			.header > .item.title .logo {
+				display: inline-block;
+				width: 32px;
+				padding: 10px;
+			}
 			.header > .item.title h1 {
+				display: inline-block;
 				margin: 0;
 				text-shadow: 1px -1px 0 #ccc;
+				vertical-align: bottom;
 			}
 			.header > .item.title a:hover {
 				text-decoration: none;
 			}
 		.header > .item.search input {
 			width: 200px;
-			transition: all 200ms linear;
+			transition: width 200ms linear;
 		}
 			.header .item.search input:focus {
 				width: 300px;
@@ -127,6 +134,7 @@
 		}
 			.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle i,
 			.categories .feeds .item:hover .dropdown-toggle i {
+				background-image: url("icons/configure.png");
 				background-image: url("icons/configure.svg");
 			}
 	.categories .notRead {
@@ -199,6 +207,7 @@
 				display: inline-block;
 				width: 30px;
 				height: 40px;
+				background: url("icons/read.png") center center no-repeat;
 				background: url("icons/read.svg") center center no-repeat;
 				vertical-align: middle;
 			}
@@ -206,12 +215,14 @@
 					text-decoration: none;
 				}
 				.flux.not_read .flux_header .item.manage .read {
+					background: url("icons/unread.png") center center no-repeat;
 					background: url("icons/unread.svg") center center no-repeat;
 				}
 			.flux_header .item.manage .bookmark {
 				display: inline-block;
 				width: 30px;
 				height: 40px;
+				background: url("icons/non-starred.png") center center no-repeat;
 				background: url("icons/non-starred.svg") center center no-repeat;
 				vertical-align: middle;
 			}
@@ -219,6 +230,7 @@
 					text-decoration: none;
 				}
 				.flux.favorite .flux_header .item.manage .bookmark {
+					background: url("icons/starred.png") center center no-repeat;
 					background: url("icons/starred.svg") center center no-repeat;
 				}
 		.flux_header .item.website {
@@ -260,6 +272,7 @@
 				display: inline-block;
 				width: 35px;
 				height: 40px;
+				background: url("icons/link.png") center center no-repeat;
 				background: url("icons/link.svg") center center no-repeat;
 				vertical-align: middle;
 			}

+ 47 - 12
public/theme/global.css

@@ -42,6 +42,7 @@ h1, h2, h3 {
 
 /* IMG */
 img {
+	height: auto;
 	max-width: 100%;
 	vertical-align: middle;
 }
@@ -172,8 +173,7 @@ input, select, textarea {
 	min-height: 37px;
 	min-width: 15px;
 	padding: 5px 10px;
-	background: #fff;
-	background: linear-gradient(#fff, #eee);
+	background: linear-gradient(to bottom, #fff 0%, #eee 100%);
 	border-radius: 3px;
 	border: 1px solid #ddd;
 	border-bottom: 1px solid #aaa;
@@ -189,8 +189,7 @@ input, select, textarea {
 		line-height: 25px;
 	}
 	.btn:hover {
-		background: #f0f0f0;
-		background: linear-gradient(#f8f8f8, #f0f0f0);
+		background: linear-gradient(to bottom, #f8f8f8, #f0f0f0);
 		text-decoration: none;
 	}
 	.btn.active,
@@ -200,14 +199,13 @@ input, select, textarea {
 	}
 
 	.btn.btn-important {
-		background: #0084CC;
-		background: linear-gradient(#0084CC, #0045CC);
+		background: linear-gradient(to bottom, #0084CC, #0045CC);
 		color: #fff;
 		border: 1px solid #0062B7;
 		text-shadow: 0px -1px 0 #aaa;
 	}
 		.btn.btn-important:hover {
-			background: linear-gradient(#0066CC, #0045CC);
+			background: linear-gradient(to bottom, #0066CC, #0045CC);
 		}
 		.btn.btn-important:active {
 			background: #0044CB;
@@ -215,14 +213,13 @@ input, select, textarea {
 		}
 
 	.btn.btn-attention {
-		background: #E95B57;
-		background: linear-gradient(#E95B57, #BD362F);
+		background: linear-gradient(to bottom, #E95B57, #BD362F);
 		color: #fff;
 		border: 1px solid #C44742;
 		text-shadow: 0px -1px 0px #666;
 	}
 		.btn.btn-attention:hover {
-			background: linear-gradient(#D14641, #BD362F);
+			background: linear-gradient(to bottom, #D14641, #BD362F);
 		}
 		.btn.btn-attention:active {
 			background: #BD362F;
@@ -288,8 +285,7 @@ input, select, textarea {
 .nav-head {
 	display: block;
 	margin: 0;
-	background: #fff;
-	background: linear-gradient(#fff, #f0f0f0);
+	background: linear-gradient(to bottom, #fff, #f0f0f0);
 	border-bottom: 1px solid #ddd;
 	text-align: right;
 }
@@ -360,6 +356,20 @@ input, select, textarea {
 					color: #fff;
 					text-decoration: none;
 				}
+		.dropdown .dropdown-menu .input {
+			display: block;
+			height: 40px;
+			font-size: 90%;
+			line-height: 30px;
+		}
+			.dropdown .dropdown-menu .input input {
+				display: block;
+				height: 20px;
+				width: 95%;
+				margin: auto;
+				padding: 2px 5px;
+				border-radius: 3px;
+			}
 		.dropdown .dropdown-menu .separator {
 			display: block;
 			height: 0;
@@ -432,65 +442,90 @@ input, select, textarea {
 	background: center center no-repeat;
 }
 	.icon.i_refresh {
+		background-image: url("icons/refresh.png");
 		background-image: url("icons/refresh.svg");
 	}
 	.icon.i_bookmark {
+		background-image: url("icons/starred.png");
 		background-image: url("icons/starred.svg");
 	}
 	.icon.i_not_bookmark {
+		background-image: url("icons/unstarred.png");
 		background-image: url("icons/unstarred.svg");
 	}
 	.icon.i_read {
+		background-image: url("icons/read.png");
 		background-image: url("icons/read.svg");
 	}
 	.icon.i_unread {
+		background-image: url("icons/unread.png");
 		background-image: url("icons/unread.svg");
 	}
 	.icon.i_all {
+		background-image: url("icons/all.png");
 		background-image: url("icons/all.svg");
 	}
 	.icon.i_close {
+		background-image: url("icons/close.png");
 		background-image: url("icons/close.svg");
 	}
 	.icon.i_search {
+		background-image: url("icons/search.png");
 		background-image: url("icons/search.svg");
 	}
 	.icon.i_configure {
+		background-image: url("icons/configure.png");
 		background-image: url("icons/configure.svg");
 	}
 	.icon.i_login {
+		background-image: url("icons/login.png");
 		background-image: url("icons/login.svg");
 	}
 	.icon.i_logout {
+		background-image: url("icons/logout.png");
 		background-image: url("icons/logout.svg");
 	}
 	.icon.i_add {
+		background-image: url("icons/add.png");
 		background-image: url("icons/add.svg");
 	}
 	.icon.i_link {
+		background-image: url("icons/link.png");
 		background-image: url("icons/link.svg");
 	}
 	.icon.i_down {
+		background-image: url("icons/down.png");
 		background-image: url("icons/down.svg");
 	}
 	.icon.i_up {
+		background-image: url("icons/up.png");
 		background-image: url("icons/up.svg");
 	}
 	.icon.i_help {
+		background-image: url("icons/help.png");
 		background-image: url("icons/help.svg");
 	}
 	.icon.i_note {
+		background-image: url("icons/note.png");
 		background-image: url("icons/note.svg");
 	}
 	.icon.i_note_empty {
+		background-image: url("icons/note_empty.png");
 		background-image: url("icons/note_empty.svg");
 	}
 	.icon.i_category {
+		background-image: url("icons/category.png");
 		background-image: url("icons/category.svg");
 	}
 	.icon.i_rss {
+		background-image: url("icons/rss.png");
 		background-image: url("icons/rss.svg");
 	}
 	.icon.i_share {
+		background-image: url("icons/share.png");
 		background-image: url("icons/share.svg");
 	}
+	.icon.i_tag {
+		background-image: url("icons/tag.png");
+		background-image: url("icons/tag.svg");
+	}

BIN
public/theme/icons/add.png


BIN
public/theme/icons/all.png


BIN
public/theme/icons/category.png


BIN
public/theme/icons/close.png


BIN
public/theme/icons/configure.png


BIN
public/theme/icons/down.png


BIN
public/theme/icons/help.png


BIN
public/theme/icons/link.png


BIN
public/theme/icons/login.png


BIN
public/theme/icons/logout.png


BIN
public/theme/icons/non-starred.png


BIN
public/theme/icons/note.png


BIN
public/theme/icons/note_empty.png


BIN
public/theme/icons/read.png


BIN
public/theme/icons/refresh.png


BIN
public/theme/icons/rss.png


BIN
public/theme/icons/search.png


BIN
public/theme/icons/share.png


BIN
public/theme/icons/starred.png


BIN
public/theme/icons/tag.png


+ 134 - 0
public/theme/icons/tag.svg

@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="tag.svg"
+   height="16"
+   id="svg7384"
+   inkscape:version="0.48.4 r9939"
+   version="1.1"
+   width="16">
+  <metadata
+     id="metadata90">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:bbox-paths="false"
+     bordercolor="#666666"
+     borderopacity="1"
+     inkscape:current-layer="layer12"
+     inkscape:cx="63.620645"
+     inkscape:cy="27.761176"
+     gridtolerance="10"
+     inkscape:guide-bbox="true"
+     guidetolerance="10"
+     id="namedview88"
+     inkscape:object-nodes="false"
+     inkscape:object-paths="false"
+     objecttolerance="10"
+     pagecolor="#555753"
+     inkscape:pageopacity="1"
+     inkscape:pageshadow="2"
+     showborder="false"
+     showgrid="false"
+     showguides="true"
+     inkscape:snap-bbox="true"
+     inkscape:snap-bbox-midpoints="false"
+     inkscape:snap-global="true"
+     inkscape:snap-grids="true"
+     inkscape:snap-nodes="false"
+     inkscape:snap-others="false"
+     inkscape:snap-to-guides="true"
+     inkscape:window-height="709"
+     inkscape:window-maximized="1"
+     inkscape:window-width="1366"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:zoom="4">
+    <inkscape:grid
+       empspacing="2"
+       enabled="true"
+       id="grid4866"
+       snapvisiblegridlinesonly="true"
+       spacingx="1px"
+       spacingy="1px"
+       type="xygrid"
+       visible="true" />
+  </sodipodi:namedview>
+  <title
+     id="title9167">Gnome Symbolic Icon Theme</title>
+  <defs
+     id="defs7386" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer9"
+     inkscape:label="status"
+     style="display:inline"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer10"
+     inkscape:label="devices"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer11"
+     inkscape:label="apps"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer13"
+     inkscape:label="places"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer14"
+     inkscape:label="mimetypes"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer15"
+     inkscape:label="emblems"
+     style="display:inline"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="g71291"
+     inkscape:label="emotes"
+     style="display:inline"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="g4953"
+     inkscape:label="categories"
+     style="display:inline"
+     transform="translate(-141.0002,-807)" />
+  <g
+     inkscape:groupmode="layer"
+     id="layer12"
+     inkscape:label="actions"
+     style="display:inline"
+     transform="translate(-141.0002,-807)">
+    <path
+       inkscape:connector-curvature="0"
+       d="m 149.0002,809 0,13 4,-4 4,4 c 0.0525,-6.84943 -0.0285,-10.58353 0,-13 z"
+       id="path12292"
+       sodipodi:nodetypes="cccccc"
+       style="fill:#bebebe;fill-opacity:1;stroke:none" />
+  </g>
+</svg>

BIN
public/theme/icons/unread.png


BIN
public/theme/icons/up.png