Line 53... |
Line 53... |
53 |
private $suffixeLangue = '';
|
53 |
private $suffixeLangue = '';
|
Line 54... |
Line 54... |
54 |
|
54 |
|
Line 55... |
Line 55... |
55 |
private $user = null;
|
55 |
private $user = null;
|
- |
|
56 |
|
- |
|
57 |
private $service_del_url = null;
|
56 |
|
58 |
private $userCache = [];
|
57 |
private $service_del_url = null;
|
59 |
|
58 |
/**
|
60 |
/**
|
59 |
* Méthode appelée par défaut pour charger ce widget.
|
61 |
* Méthode appelée par défaut pour charger ce widget.
|
60 |
*/
|
62 |
*/
|
Line 72... |
Line 74... |
72 |
$this->service_images_url = $this->config['photo']['celUrlImages'];
|
74 |
$this->service_images_url = $this->config['photo']['celUrlImages'];
|
73 |
$this->flux_rss_url = $this->config['photo']['fluxRssUrl'];
|
75 |
$this->flux_rss_url = $this->config['photo']['fluxRssUrl'];
|
Line 74... |
Line 76... |
74 |
|
76 |
|
75 |
$cache_activation = $this->config['photo.cache']['activation'];
|
77 |
$cache_activation = $this->config['photo.cache']['activation'];
|
- |
|
78 |
$cache_stockage = $this->config['photo.cache']['stockageDossier'];
|
- |
|
79 |
if (!is_dir($cache_stockage)) {
|
- |
|
80 |
mkdir($cache_stockage, 0777, true);
|
76 |
$cache_stockage = $this->config['photo.cache']['stockageDossier'];
|
81 |
}
|
77 |
$ddv = $this->config['photo.cache']['dureeDeVie'];
|
82 |
$ddv = $this->config['photo.cache']['dureeDeVie'];
|
78 |
$cache = new Cache($cache_stockage, $ddv, $cache_activation);
|
83 |
$cache = new Cache($cache_stockage, $ddv, $cache_activation);
|
79 |
$id_cache = 'photo-'.hash('adler32', print_r($this->parametres, true));
|
84 |
$id_cache = 'photo-'.hash('adler32', print_r($this->parametres, true));
|
Line 109... |
Line 114... |
109 |
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
|
114 |
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
|
110 |
$cache->sauver($id_cache, $contenu);
|
115 |
$cache->sauver($id_cache, $contenu);
|
Line 111... |
Line 116... |
111 |
|
116 |
|
112 |
} else {
|
117 |
} else {
|
113 |
$this->messages[] = 'Les données à transmettre au squelette sont nulles.';
|
- |
|
114 |
|
118 |
$this->messages[] = 'Les données à transmettre au squelette sont nulles.';
|
115 |
}
|
119 |
}
|
116 |
}
|
120 |
}
|
117 |
}
|
121 |
}
|
118 |
if (isset($_GET['callback'])) {
|
122 |
if (isset($_GET['callback'])) {
|
Line 119... |
Line 123... |
119 |
$this->envoyerJsonp(['contenu' => $contenu]);
|
123 |
$this->envoyerJsonp(['contenu' => $contenu]);
|
120 |
|
124 |
|
121 |
} else {
|
- |
|
122 |
$this->envoyer($contenu);
|
125 |
} else {
|
Line 123... |
Line 126... |
123 |
|
126 |
$this->envoyer($contenu);
|
124 |
}
|
127 |
}
|
125 |
|
128 |
|
Line 206... |
Line 209... |
206 |
return $widget;
|
209 |
return $widget;
|
207 |
}
|
210 |
}
|
Line 208... |
Line 211... |
208 |
|
211 |
|
209 |
private function executerPhoto() {
|
212 |
private function executerPhoto() {
|
- |
|
213 |
$widget = null;
|
Line 210... |
Line 214... |
210 |
$widget = null;
|
214 |
session_start();
|
211 |
|
215 |
|
- |
|
216 |
$this->parametres['start'] = $this->parametres['start'] ?? self::START_DEFAUT;
|
Line 212... |
Line -... |
212 |
$this->parametres['start'] = $this->parametres['start'] ?? self::START_DEFAUT;
|
- |
|
213 |
$this->parametres['limit'] = $this->parametres['limit'] ?? self::LIMIT_DEFAUT;
|
- |
|
214 |
|
217 |
$this->parametres['limit'] = $this->parametres['limit'] ?? self::LIMIT_DEFAUT;
|
215 |
extract($this->parametres);
|
218 |
$limit = $this->parametres['limit'];
|
216 |
|
219 |
|
217 |
$hasTriedValueInConfig = false;
|
220 |
$hasTriedValueInConfig = false;
|
218 |
while (!isset($vignette) || !preg_match('/^[0-9]+,[0-9]+$/', $vignette)) {
|
221 |
while (!isset($vignette) || !preg_match('/^[0-9]+,[0-9]+$/', $vignette)) {
|
Line 223... |
Line 226... |
223 |
$id = '-'.(isset($id) ? $id : '1');
|
226 |
$id = '-'.(isset($id) ? $id : '1');
|
224 |
$titre = isset($titre) ? htmlentities(rawurldecode($titre)) : '';
|
227 |
$titre = isset($titre) ? htmlentities(rawurldecode($titre)) : '';
|
Line 225... |
Line 228... |
225 |
|
228 |
|
226 |
$icone_rss = (isset($_GET['rss']) && $_GET['rss'] != 1) ? false : true;
|
229 |
$icone_rss = (isset($_GET['rss']) && $_GET['rss'] != 1) ? false : true;
|
227 |
$utilise_fancybox = (isset($_GET['mode_zoom']) && $_GET['mode_zoom'] != 'fancybox') ? false : true;
|
230 |
$utilise_fancybox = (isset($_GET['mode_zoom']) && $_GET['mode_zoom'] != 'fancybox') ? false : true;
|
- |
|
231 |
|
228 |
|
232 |
$champ_recherche = $champ_recherche ?? null;
|
- |
|
233 |
$champ_recherche = $champ_recherche ? $this->obtenirBooleen($champ_recherche) : ($this->config['photo']['champRecherche'] ? $this->obtenirBooleen($this->config['photo']['champRecherche']) : false) ;
|
229 |
$champ_recherche = $champ_recherche ? $this->obtenirBooleen($champ_recherche) : ($this->config['photo']['champRecherche'] ? $this->obtenirBooleen($this->config['photo']['champRecherche']) : false) ;
|
234 |
$extra = $extra ?? null;
|
230 |
|
235 |
|
231 |
// Affichage mode e-flore avec le paramètre mode_eflore
|
236 |
// Affichage mode e-flore avec le paramètre mode_eflore
|
232 |
if ($_GET['mode_eflore']) {
|
237 |
if ($_GET['mode_eflore']) {
|
233 |
$champ_recherche = false;
|
238 |
$champ_recherche = false;
|
234 |
$vignette ='5,2';
|
239 |
$vignette = '5,2';
|
235 |
|
240 |
|
236 |
$tags = [
|
241 |
$tags = [
|
237 |
'fleur',
|
242 |
'fleur',
|
238 |
'feuille',
|
243 |
'feuille',
|
239 |
'fruit',
|
244 |
'fruit',
|
240 |
'ecorce',
|
245 |
'ecorce',
|
241 |
'port',
|
246 |
'port',
|
242 |
'rameau',
|
247 |
'rameau',
|
- |
|
248 |
];
|
243 |
];
|
249 |
|
244 |
foreach ($tags as $tag) {
|
250 |
foreach ($tags as $tag) {
|
245 |
$widget = $this->getImages($vignette, $extra, $limit, $id, $titre, $icone_rss, $utilise_fancybox,
|
- |
|
246 |
true, $tag, $widget,$champ_recherche);
|
251 |
$widget = $this->getImages($vignette, $extra, $limit, $id, $titre, $icone_rss, $utilise_fancybox,true, $tag, $widget, false);
|
247 |
$widget['donnees']['champ_recherche'] = $champ_recherche;
|
252 |
$widget['donnees']['champ_recherche'] = false;
|
248 |
}
|
253 |
}
|
249 |
$widget['donnees']['tagToDisplay'] = 'fleur';
|
254 |
$widget['donnees']['tagToDisplay'] = 'fleur';
|
250 |
} else {
|
255 |
} else {
|
- |
|
256 |
$widget = $this->getImages($vignette, $extra, $limit, $id, $titre, $icone_rss, $utilise_fancybox, false, 'non_eflore', $widget, $champ_recherche);
|
251 |
$widget = $this->getImages($vignette, $extra, $limit, $id, $titre, $icone_rss, $utilise_fancybox,false, 'non_eflore', $widget,$champ_recherche);
|
257 |
|
- |
|
258 |
$widget['donnees']['champ_recherche'] = $champ_recherche;
|
252 |
$widget['donnees']['champ_recherche'] = $champ_recherche;
|
259 |
|
Line 253... |
Line 260... |
253 |
}
|
260 |
}
|
254 |
|
261 |
|
Line 397... |
Line 404... |
397 |
fclose($flux);
|
404 |
fclose($flux);
|
398 |
}
|
405 |
}
|
399 |
return $contenu;
|
406 |
return $contenu;
|
400 |
}
|
407 |
}
|
Line 401... |
Line 408... |
401 |
|
408 |
|
402 |
public function formaterDate($item, $image){
|
409 |
public function formaterDates($item, $image){
|
403 |
$item['date_photo'] = $image['date_photo'] ?? $image['obs']['date_obs'];
|
410 |
$item['date_photo'] = $image['date_photo'] ?? $image['obs']['date_obs'];
|
404 |
$item['date_redige'] = strftime('%A %d %B %Y', strtotime($item['date_photo']));
|
411 |
$item['date_redige'] = strftime('%A %d %B %Y', strtotime($item['date_photo']));
|
405 |
$item['date'] = date_format(date_create($item['date_photo']),"d/m/Y");
|
412 |
$item['date'] = date_format(date_create($item['date_photo']),"d/m/Y");
|
406 |
$item['lien'] = sprintf($this->eflore_url_tpl, $image['obs']['nom_referentiel'], $image['obs']['nom_sel_nn']);
|
413 |
$item['lien'] = sprintf($this->eflore_url_tpl, $image['obs']['nom_referentiel'], $image['obs']['nom_sel_nn']);
|
Line 422... |
Line 429... |
422 |
$tag, $widget, $champ_recherche){
|
429 |
$tag, $widget, $champ_recherche){
|
423 |
if ($fromEflore){
|
430 |
if ($fromEflore){
|
424 |
$this->parametres['tag'] = $tag;
|
431 |
$this->parametres['tag'] = $tag;
|
425 |
}
|
432 |
}
|
426 |
list($colonne, $ligne) = explode(',', $vignette);
|
433 |
list($colonne, $ligne) = explode(',', $vignette);
|
- |
|
434 |
|
427 |
$extra = (isset($extra) && $extra == 0) ? false : (!$this->config['photo']['extraActif'] ? false : ($colonne == 1 || $ligne == 1 ? false : true));
|
435 |
$extra = !($extra === 0) && (($this->config['photo']['extraActif'] && (($colonne == 1 || $ligne == 1 ? false : true))));
|
428 |
|
436 |
|
429 |
$max_photo = $colonne * $ligne;
|
437 |
$max_photo = $colonne * $ligne;
|
430 |
if ( $extra && 2 == $colonne ) {
|
438 |
if ( $extra && 2 == $colonne ) {
|
431 |
$max_photo = $max_photo - 1;
|
439 |
$max_photo = $max_photo - 1;
|
432 |
} elseif ( $extra && 2 < $colonne ) {
|
440 |
} elseif ( $extra && 2 < $colonne ) {
|
433 |
$max_photo = $max_photo - 3;
|
441 |
$max_photo = $max_photo - 3;
|
434 |
}
|
442 |
}
|
435 |
|
443 |
|
436 |
$limit = $limit < $max_photo ? $limit : $max_photo;
|
444 |
$limit = $limit < $max_photo ? $limit : $max_photo;
|
437 |
$this->parametres['limit'] = $limit;
|
445 |
$this->parametres['limit'] = $limit;
|
- |
|
446 |
|
438 |
$parametresTraites = $this->traiterParametres();
|
447 |
$parametresTraites = $this->traiterParametres();
|
439 |
$this->flux_rss_url .= $parametresTraites;
|
448 |
$this->flux_rss_url .= $parametresTraites;
|
440 |
$url = $this->service_images_url.(!empty($parametresTraites) ? $parametresTraites.'&' : '?');
|
449 |
$url = $this->service_images_url.(!empty($parametresTraites) ? $parametresTraites.'&' : '?');
|
441 |
$json = $this->getDao()->consulter($url);
|
450 |
$json = $this->getDao()->consulter($url);
|
442 |
if ($fromEflore) {
|
- |
|
443 |
unset($this->parametres['tag']);
|
- |
|
444 |
}
|
451 |
|
445 |
if (empty($json) || !strpos($json,'images') ) {
|
452 |
if (empty($json) || !strpos($json, 'images')) {
|
446 |
$this->messages[] = "L'URI suivante est invalide : $this->service_images_url.\n".
|
453 |
$this->messages[] = "L'URI suivante est invalide : $url.\n".
|
447 |
"Veuillez vérifier les paramêtres indiqués et la présence d'images associées.";
|
454 |
"Veuillez vérifier les paramêtres indiqués et la présence d'images associées.";
|
448 |
|
- |
|
449 |
} else {
|
455 |
$this->logError("L'URI est invalide: $url");
|
450 |
$tableau = json_decode($json, true);
|
456 |
return $widget;
|
- |
|
457 |
}
|
Line 451... |
Line -... |
451 |
|
- |
|
452 |
if (empty($tableau['total']) || empty($tableau['images'])) {
|
458 |
|
453 |
$this->messages[] = 'Aucune photo ne correspond à vos critères';
|
- |
|
Line -... |
Line 459... |
- |
|
459 |
$tableau = json_decode($json, true);
|
- |
|
460 |
|
- |
|
461 |
if (empty($tableau['total']) || empty($tableau['images'])) {
|
- |
|
462 |
$this->logError('Aucune photo ne correspond à vos critères');
|
- |
|
463 |
return $widget;
|
454 |
} else {
|
464 |
}
|
455 |
|
465 |
|
456 |
$parametres_photo_suivante = $parametres_photo_precedente = $this->parametres;
|
466 |
$parametres_photo_suivante = $parametres_photo_precedente = $this->parametres;
|
457 |
$start = $this->parametres['start'] ? : 0;
|
467 |
$start = $this->parametres['start'] ? : 0;
|
458 |
$parametres_photo_suivante['start'] = $start + $limit;
|
468 |
$parametres_photo_suivante['start'] = $start + $limit;
|
459 |
$parametres_photo_precedente['start'] = 0 < $start - $limit ? $start - $limit : 0;
|
469 |
$parametres_photo_precedente['start'] = 0 < $start - $limit ? $start - $limit : 0;
|
460 |
|
470 |
|
461 |
$widget['donnees']['total'] = $tableau['total'];
|
471 |
$widget['donnees']['total'] = $tableau['total'];
|
462 |
$widget['donnees']['id'] = $id;
|
472 |
$widget['donnees']['id'] = $id;
|
463 |
$widget['donnees']['titre'] = $titre;
|
473 |
$widget['donnees']['titre'] = $titre;
|
464 |
$widget['donnees']['flux_rss_url'] = $this->flux_rss_url;
|
474 |
$widget['donnees']['flux_rss_url'] = $this->flux_rss_url;
|
465 |
$widget['donnees']['url_widget'] = $this->url_widget;
|
475 |
$widget['donnees']['url_widget'] = $this->url_widget;
|
466 |
$widget['donnees']['url_widget_photos_suivantes'] = $this->url_widget.'?'.http_build_query($parametres_photo_suivante);
|
476 |
$widget['donnees']['url_widget_photos_suivantes'] = $this->url_widget.'?'.http_build_query($parametres_photo_suivante);
|
467 |
$widget['donnees']['url_widget_photos_precedente'] = $this->url_widget.'?'.http_build_query($parametres_photo_precedente);
|
477 |
$widget['donnees']['url_widget_photos_precedente'] = $this->url_widget.'?'.http_build_query($parametres_photo_precedente);
|
468 |
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/css/');
|
478 |
$widget['donnees']['url_css'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/css/');
|
469 |
$widget['donnees']['url_js'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/js/');
|
479 |
$widget['donnees']['url_js'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], 'modules/photo/squelettes/js/');
|
470 |
$widget['donnees']['colonne'] = $colonne;
|
480 |
$widget['donnees']['colonne'] = $colonne;
|
471 |
$widget['donnees']['ligne'] = $ligne;
|
481 |
$widget['donnees']['ligne'] = $ligne;
|
472 |
$widget['donnees']['extra_actif'] = $extra;
|
482 |
$widget['donnees']['extra_actif'] = $extra ?? null;
|
473 |
$widget['donnees']['icone_rss'] = $icone_rss;
|
483 |
$widget['donnees']['icone_rss'] = $icone_rss ?? null;
|
474 |
$widget['donnees']['champ_recherche'] = $champ_recherche;
|
484 |
$widget['donnees']['champ_recherche'] = $champ_recherche;
|
475 |
$widget['donnees']['start'] = $start;
|
485 |
$widget['donnees']['start'] = $start;
|
476 |
$widget['donnees']['limit'] = $limit;
|
486 |
$widget['donnees']['limit'] = $limit;
|
477 |
$widget['donnees']['utilise_fancybox'] = $utilise_fancybox;
|
487 |
$widget['donnees']['utilise_fancybox'] = $utilise_fancybox;
|
478 |
$widget['donnees']['prod'] = ($this->config['parametres']['modeServeur'] === 'prod');
|
488 |
$widget['donnees']['prod'] = ($this->config['parametres']['modeServeur'] === 'prod');
|
479 |
$widget['donnees']['filtres'] = $this->parametres;
|
489 |
$widget['donnees']['filtres'] = $this->parametres;
|
480 |
|
490 |
|
481 |
$num = 0;
|
491 |
$num = 0;
|
482 |
$galerie_id = md5(http_build_query($_GET));
|
492 |
$galerie_id = md5(http_build_query($_GET));
|
483 |
$widget['donnees']['galerie_id'] = $galerie_id;
|
- |
|
484 |
|
493 |
$widget['donnees']['galerie_id'] = $galerie_id;
|
485 |
session_start();
|
494 |
|
486 |
$_SESSION[$galerie_id]['max_photo'] = $max_photo;
|
495 |
$_SESSION[$galerie_id]['max_photo'] = $max_photo;
|
- |
|
496 |
$_SESSION[$galerie_id]['start'] = $start;
|
- |
|
497 |
|
- |
|
498 |
// *************************************** C'est cette boucle qui prend grave du temps ****************************************
|
487 |
$_SESSION[$galerie_id]['start'] = $start;
|
499 |
// Cache pour les tailles d'images
|
488 |
|
500 |
// $imageSizeCache = [];
|
489 |
foreach ($tableau['images'] as $key => $image) {
|
501 |
foreach ($tableau['images'] as $key => $image) {
|
490 |
if ($key == $max_photo) {
|
502 |
if ($key == $max_photo) {
|
- |
|
503 |
break;
|
491 |
break;
|
504 |
}
|
492 |
}
|
505 |
|
- |
|
506 |
// Utilisation du cache pour l'utilisateur -> fait gagner un peu de temps de chargement si plusieures photos du même utilisateur
|
493 |
// On vérifie si l'auteur de la photo est un utilisateur tela
|
507 |
$courriel = $image['utilisateur']['mail_utilisateur'];
|
- |
|
508 |
if (!isset($this->userCache[$courriel])) {
|
- |
|
509 |
$this->userCache[$courriel] = $this->recupererUtilisateursIdentite([$courriel])[$courriel];
|
- |
|
510 |
}
|
494 |
$courriel = [$image['utilisateur']['mail_utilisateur']];
|
511 |
$auteurId = $this->userCache[$courriel]['id'];
|
495 |
$auteurId = $this->recupererUtilisateursIdentite($courriel)[$courriel[0]]['id'];
|
512 |
|
496 |
$auteurId ? $isTelaUser = true : $isTelaUser = false;
|
513 |
$isTelaUser = $auteurId ? true : false;
|
497 |
$auteurTruncatedEmail = $this->tronquerCourriel($image['utilisateur']['mail_utilisateur']);
|
514 |
$auteurTruncatedEmail = $this->tronquerCourriel($courriel);
|
498 |
|
515 |
|
499 |
$auteur = trim($image['utilisateur']['nom_utilisateur']) ? $image['utilisateur']['nom_utilisateur'] : $auteurTruncatedEmail;
|
516 |
$auteur = trim($image['utilisateur']['nom_utilisateur']) ? $image['utilisateur']['nom_utilisateur'] : $auteurTruncatedEmail;
|
500 |
|
- |
|
501 |
$item = $image;
|
517 |
|
502 |
|
- |
|
503 |
$item = $this->formaterDate($item, $image);
|
518 |
$item = $image;
|
504 |
|
519 |
$item = $this->formaterDates($item, $image);
|
505 |
$item = $this->formaterTitre($item, $image, $auteur);
|
520 |
$item = $this->formaterTitre($item, $image, $auteur);
|
506 |
|
- |
|
507 |
$item['tag_eflore'] = $tag;
|
521 |
|
508 |
|
- |
|
509 |
$item['is_auteur_tela'] = $isTelaUser;
|
- |
|
510 |
// Ajout aux items et si première photo à extra
|
- |
|
511 |
if ($key == 0) {
|
- |
|
512 |
$widget['donnees']['extra'] = $item;
|
522 |
$item['tag_eflore'] = $tag;
|
513 |
}
|
- |
|
514 |
|
- |
|
515 |
$widget['donnees']['items'][$tag][$num++] = $item;
|
- |
|
516 |
$url_galerie_popup = sprintf($item['url_tpl'],'O');
|
523 |
$item['is_auteur_tela'] = $isTelaUser;
|
517 |
$image_size = getimagesize($url_galerie_popup);
|
- |
|
518 |
$item['width'] = $image_size[0];
|
- |
|
519 |
$item['height'] = $image_size[1];
|
- |
|
520 |
|
- |
|
521 |
// Récupération des votes pictoflora
|
- |
|
522 |
$item['votes'] = $this->getVotes($item);
|
- |
|
523 |
|
- |
|
524 |
// Récupération des tags pictoflora
|
- |
|
525 |
$item['tags_pf'] = $this->getPfTags($item);
|
- |
|
526 |
|
- |
|
527 |
$_SESSION[$galerie_id]['infos_images'][$url_galerie_popup] = $item;
|
- |
|
528 |
}
|
524 |
|
529 |
|
525 |
if ($key == 0) {
|
- |
|
526 |
$widget['donnees']['extra'] = $item;
|
- |
|
527 |
}
|
- |
|
528 |
|
- |
|
529 |
$widget['donnees']['items'][$tag][$num++] = $item;
|
- |
|
530 |
//
|
- |
|
531 |
$url_galerie_popup = sprintf($item['url_tpl'], 'O');
|
- |
|
532 |
// if (!isset($imageSizeCache[$url_galerie_popup])) {
|
- |
|
533 |
// $imageSizeCache[$url_galerie_popup] = getimagesize($url_galerie_popup);
|
- |
|
534 |
// }
|
- |
|
535 |
// $image_size = $imageSizeCache[$url_galerie_popup];
|
- |
|
536 |
// error_log(print_r($imageSizeCache, true));
|
- |
|
537 |
// $item['width'] = $image_size[0];
|
- |
|
538 |
// $item['height'] = $image_size[1];
|
- |
|
539 |
|
- |
|
540 |
// Récupération des votes et tags
|
- |
|
541 |
$item['votes'] = $this->getVotes($item);
|
- |
|
542 |
$item['tags_pf'] = $this->getPfTags($item);
|
- |
|
543 |
|
- |
|
544 |
$_SESSION[$galerie_id]['infos_images'][$url_galerie_popup] = $item;
|
- |
|
545 |
}
|
- |
|
546 |
|
530 |
$widget['squelette'] = 'photo';
|
547 |
if ($fromEflore) {
|
- |
|
548 |
unset($this->parametres['tag']);
|
Line 531... |
Line 549... |
531 |
}
|
549 |
}
|
532 |
}
|
550 |
$widget['squelette'] = 'photo';
|
Line 533... |
Line 551... |
533 |
|
551 |
|