From 32a32dd33f0c9dbfd0e04d6e019b5d7dc950ca9b Mon Sep 17 00:00:00 2001
From: Cerdic <cedric@yterium.com>
Date: Mon, 13 Jun 2011 21:25:53 +0000
Subject: [PATCH] optimisation des inclusions et des appels a find_in_path :
 pour un hit de l'espace prive sur la home, on passe de 1450 appels a
 find_in_path a 550 environs, pour un total de 200 fichiers differents

A noter :
- charger_fonction memorise les fonctions inexistantes,
car sinon il reproduit la recherche a chaque appel de fonction inexistante
- iterateur DATA ne cherche plus de fonction table_to_array
---
 ecrire/base/objets.php           |  3 +-
 ecrire/base/trouver_table.php    |  3 +-
 ecrire/inc/bandeau.php           |  3 +-
 ecrire/inc/filtres.php           | 24 ++++++++-------
 ecrire/inc/pipelines.php         |  4 +--
 ecrire/inc/pipelines_ecrire.php  |  1 -
 ecrire/inc/presenter_enfants.php |  2 +-
 ecrire/inc/rubriques.php         |  6 ++--
 ecrire/inc/urls.php              |  2 +-
 ecrire/inc/utils.php             | 27 ++++++++++-------
 ecrire/iterateur/data.php        | 51 +++++++++++++++++---------------
 ecrire/public/compiler.php       |  1 -
 ecrire/public/iterateur.php      | 15 +++++-----
 ecrire/public/parametrer.php     |  2 +-
 ecrire/public/styliser.php       |  4 ++-
 ecrire/public/styliser_par_z.php |  3 +-
 16 files changed, 83 insertions(+), 68 deletions(-)

diff --git a/ecrire/base/objets.php b/ecrire/base/objets.php
index 437f8c3ad2..c29403c1d7 100644
--- a/ecrire/base/objets.php
+++ b/ecrire/base/objets.php
@@ -583,7 +583,8 @@ function table_objet($type,$serveur='') {
 function table_objet_sql($type,$serveur='') {
 	global $table_des_tables;
 	$nom = table_objet($type, $serveur);
-	include_spip('public/interfaces');
+	if (!isset($table_des_tables['articles'])) // eviter de multiples inclusions
+		include_spip('public/interfaces');
 	if (isset($table_des_tables[$nom])) {
 		$nom = $table_des_tables[$nom];
 		$nom = "spip_$nom";
diff --git a/ecrire/base/trouver_table.php b/ecrire/base/trouver_table.php
index a633b15347..f5ff7be617 100644
--- a/ecrire/base/trouver_table.php
+++ b/ecrire/base/trouver_table.php
@@ -12,6 +12,7 @@
 
 if (!defined('_ECRIRE_INC_VERSION')) return;
 include_spip('public/interfaces');
+include_spip('base/objets');
 
 // Trouve la description d'une table, en particulier celle d'une boucle
 // Si on ne la trouve pas, on demande au serveur SQL
@@ -67,7 +68,6 @@ function base_trouver_table_dist($nom, $serveur='', $table_spip = true){
 
 	// base sous SPIP: gerer les abreviations explicites des noms de table
 	if ($connexion['spip_connect_version']) {
-		include_spip('public/interfaces');
 		if (isset($table_des_tables[$nom])) {
 			$nom = $table_des_tables[$nom];
 			$nom_sql = 'spip_' . $nom;
@@ -127,7 +127,6 @@ function base_trouver_table_dist($nom, $serveur='', $table_spip = true){
 		// charger les infos declarees pour cette table
 		// en lui passant les infos connues
 		// $desc est prioritaire pour la description de la table
-		include_spip('base/objets');
 		$desc = array_merge(lister_tables_objets_sql($nom_sql,$desc),$desc);
 		
 		$connexion['tables'][$nom] = $desc;
diff --git a/ecrire/inc/bandeau.php b/ecrire/inc/bandeau.php
index 7e76fe5255..a1efea6e95 100644
--- a/ecrire/inc/bandeau.php
+++ b/ecrire/inc/bandeau.php
@@ -20,7 +20,8 @@ function definir_barre_contexte($contexte = null){
 	elseif(is_string($contexte))
 		$contexte = unserialize($contexte);
 	if (!isset($contexte['id_rubrique']) AND isset($contexte['exec'])){
-		include_spip('inc/pipelines_ecrire');
+		if (!function_exists('trouver_objet_exec'))
+			include_spip('inc/pipelines_ecrire');
 		if ($e=trouver_objet_exec($contexte['exec'])){
 			$_id = $e['id_table_objet'];
 			if (isset($contexte[$_id]) AND $id=intval($contexte[$_id])){
diff --git a/ecrire/inc/filtres.php b/ecrire/inc/filtres.php
index fa08ff9b5c..b7e79420ae 100644
--- a/ecrire/inc/filtres.php
+++ b/ecrire/inc/filtres.php
@@ -14,6 +14,8 @@ if (!defined('_ECRIRE_INC_VERSION')) return;
 
 include_spip('inc/charsets');
 include_spip('inc/filtres_mini');
+include_spip('base/objets');
+include_spip('public/parametrer'); // charger les fichiers fonctions
 
 /**
  * Charger un filtre depuis le php :
@@ -114,15 +116,15 @@ function version_svn_courante($dir) {
 
 // La matrice est necessaire pour ne filtrer _que_ des fonctions definies dans filtres_images
 // et laisser passer les fonctions personnelles baptisees image_...
-$GLOBALS['spip_matrice']['image_graver'] = 'inc/filtres_images_mini.php';
-$GLOBALS['spip_matrice']['image_select'] = 'inc/filtres_images_mini.php';
-$GLOBALS['spip_matrice']['image_reduire'] = 'inc/filtres_images_mini.php';
-$GLOBALS['spip_matrice']['image_reduire_par'] = 'inc/filtres_images_mini.php';
-$GLOBALS['spip_matrice']['image_passe_partout'] = 'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['image_graver'] = true;//'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['image_select'] = true;//'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['image_reduire'] = true;//'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['image_reduire_par'] = true;//'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['image_passe_partout'] = true;//'inc/filtres_images_mini.php';
 
-$GLOBALS['spip_matrice']['couleur_html_to_hex'] = 'inc/filtres_images_mini.php';
-$GLOBALS['spip_matrice']['couleur_foncer'] = 'inc/filtres_images_mini.php';
-$GLOBALS['spip_matrice']['couleur_eclaircir'] = 'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['couleur_html_to_hex'] = true;//'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['couleur_foncer'] = true;//'inc/filtres_images_mini.php';
+$GLOBALS['spip_matrice']['couleur_eclaircir'] = true;//'inc/filtres_images_mini.php';
 
 // ou pour inclure un script au moment ou l'on cherche le filtre
 $GLOBALS['spip_matrice']['filtre_image_dist'] = 'inc/filtres_mime.php';
@@ -140,9 +142,10 @@ $GLOBALS['spip_matrice']['filtre_audio_x_pn_realaudio'] = 'inc/filtres_mime.php'
 // charge les fonctions graphiques et applique celle demandee
 // http://doc.spip.org/@filtrer
 function filtrer($filtre) {
-	include_spip('public/parametrer'); // charger les fichiers fonctions
-	if (is_string($f = $GLOBALS['spip_matrice'][$filtre]))
+	if (is_string($f = $GLOBALS['spip_matrice'][$filtre])){
 		find_in_path($f,'', true);
+		$GLOBALS['spip_matrice'][$filtre] = true;
+	}
 	$tous = func_get_args();
 	if (substr($filtre,0,6)=='image_' && $GLOBALS['spip_matrice'][$filtre])
 		return image_filtrer($tous);
@@ -2603,7 +2606,6 @@ function filtre_print_dist($u, $join=', ') {
  * @return string
  */
 function objet_info($objet,$info){
-	include_spip('base/objets');
 	$table = table_objet_sql($objet);
 	$infos = lister_tables_objets_sql($table);
 	return (isset($infos[$info])?$infos[$info]:'');
diff --git a/ecrire/inc/pipelines.php b/ecrire/inc/pipelines.php
index 36a428adba..0fdfbfc981 100644
--- a/ecrire/inc/pipelines.php
+++ b/ecrire/inc/pipelines.php
@@ -11,6 +11,8 @@
 \***************************************************************************/
 
 if (!defined('_ECRIRE_INC_VERSION')) return;
+if (test_espace_prive())
+	include_spip('inc/pipelines_ecrire');
 
 
 // Inserer jQuery
@@ -29,7 +31,6 @@ function f_jQuery ($texte) {
 		'javascript/ajaxCallback.js',
 		'javascript/jquery.cookie.js'
 		));
-	include_spip('inc/pipelines_ecrire');
 	$jqueryui_plugins = jqueryui_dependances(pipeline('jqueryui_plugins',
 		array(
 			'jquery.ui.core',
@@ -108,7 +109,6 @@ function f_admin ($texte) {
 
 function f_recuperer_fond($flux) {
 	if (!test_espace_prive()) return $flux;
-	include_spip('inc/pipelines_ecrire');
 	return f_afficher_blocs_ecrire($flux);
 }
 
diff --git a/ecrire/inc/pipelines_ecrire.php b/ecrire/inc/pipelines_ecrire.php
index 83c80a936b..139ddf5ab9 100644
--- a/ecrire/inc/pipelines_ecrire.php
+++ b/ecrire/inc/pipelines_ecrire.php
@@ -283,7 +283,6 @@ function trouver_objet_exec($exec){
 	if (!$exec) return false;
 	if (!isset($objet_exec[$exec])){
 		$objet_exec[$exec]=false;
-		include_spip('base/objets');
 		$infos = lister_tables_objets_sql();
 		foreach($infos as $t=>$info){
 			if ($exec==$info['url_edit'] AND $info['editable']){
diff --git a/ecrire/inc/presenter_enfants.php b/ecrire/inc/presenter_enfants.php
index 3fe702a86d..50e3b24938 100644
--- a/ecrire/inc/presenter_enfants.php
+++ b/ecrire/inc/presenter_enfants.php
@@ -23,6 +23,7 @@ function enfant_rub($collection){
 
 	if ($voir_logo) {
 		$chercher_logo = charger_fonction('chercher_logo', 'inc');
+		include_spip('inc/filtres_images_mini');
 	}
 
 	$res = array();
@@ -43,7 +44,6 @@ function enfant_rub($collection){
 			if ($voir_logo) {
 				if ($logo = $chercher_logo($id_rubrique, 'id_rubrique', 'on')) {
 					list($fid, $dir, $nom, $format) = $logo;
-					include_spip('inc/filtres_images_mini');
 					$logo = image_reduire("<img src='$fid' alt='' />", 48, 36);
 					if ($logo)
 						$logo =  inserer_attribut($logo,'class','logo');
diff --git a/ecrire/inc/rubriques.php b/ecrire/inc/rubriques.php
index 344ca12fd1..f72b6fe11c 100644
--- a/ecrire/inc/rubriques.php
+++ b/ecrire/inc/rubriques.php
@@ -294,6 +294,9 @@ function calculer_langues_rubriques() {
 // site public
 // http://doc.spip.org/@calculer_langues_utilisees
 function calculer_langues_utilisees ($serveur='') {
+	include_spip('public/interfaces');
+	include_spip('public/compiler');
+	include_spip('public/composer');
 	$langues = array();
 
 	$langues[$GLOBALS['meta']['langue_site']] = 1;
@@ -309,7 +312,6 @@ function calculer_langues_utilisees ($serveur='') {
 		  AND isset($desc['field']['lang'])
 			AND isset($desc['field']['langue_choisie'])){
 
-			include_spip('public/interfaces');
 			$boucle = new Boucle();
 			$boucle->show = $desc;
 			$boucle->nom = 'calculer_langues_utilisees';
@@ -320,8 +322,6 @@ function calculer_langues_utilisees ($serveur='') {
 			$boucle->from[$desc['table_objet']] = $t;
 			if (isset($desc['statut'])
 		    AND $desc['statut']){
-				include_spip('public/compiler');
-				include_spip('public/composer');
 				instituer_boucle($boucle, false);
 				$res = calculer_select($boucle->select,$boucle->from,$boucle->from_type,$boucle->where,$boucle->join,$boucle->group,$boucle->order,$boucle->limit,$boucle->having,$desc['table_objet'],$desc['table_objet'],$serveur);
 			}
diff --git a/ecrire/inc/urls.php b/ecrire/inc/urls.php
index b91020db05..2f33e3004e 100644
--- a/ecrire/inc/urls.php
+++ b/ecrire/inc/urls.php
@@ -11,6 +11,7 @@
 \***************************************************************************/
 
 if (!defined('_ECRIRE_INC_VERSION')) return;
+include_spip('base/objets');
 
 /**
  * Decoder une url en utilisant les fonctions inverse
@@ -121,7 +122,6 @@ function urls_liste_objets($preg = true){
 	if (is_null($url_objets)){
 		$url_objets = array();
 		// recuperer les tables_objets_sql declarees
-		include_spip('base/objets');
 		$tables_objets = lister_tables_objets_sql();
 		foreach($tables_objets as $t=>$infos){
 			if ($infos['page']) {
diff --git a/ecrire/inc/utils.php b/ecrire/inc/utils.php
index 6975e9105f..a57bbaacea 100644
--- a/ecrire/inc/utils.php
+++ b/ecrire/inc/utils.php
@@ -32,10 +32,13 @@ if (!defined('_LOG_DEBUG')) define('_LOG_DEBUG', 7);
 // Peut etre appelee plusieurs fois, donc optimiser
 // http://doc.spip.org/@charger_fonction
 function charger_fonction($nom, $dossier='exec', $continue=false) {
+	static $echecs = array();
 
 	if (strlen($dossier) AND substr($dossier,-1) != '/') $dossier .= '/';
+	$f = str_replace('/','_',$dossier) . $nom;
+	if (isset($echecs[$f])) return $echecs[$f];
 
-	if (function_exists($f = str_replace('/','_',$dossier) . $nom))
+	if (function_exists($f))
 		return $f;
 	if (function_exists($g = $f . '_dist'))
 		return $g;
@@ -55,7 +58,7 @@ function charger_fonction($nom, $dossier='exec', $continue=false) {
 	if (function_exists($f)) return $f;
 	if (function_exists($g)) return $g;
 
-	if ($continue) return false;
+	if ($continue) return $echecs[$f] = false;
 
 	// Echec : message d'erreur
 	spip_log("fonction $nom ($f ou $g) indisponible" .
@@ -1027,7 +1030,8 @@ function generer_url_entite($id='', $entite='', $args='', $ancre='', $public=NUL
 
 	if (!$public) {
 		if (!$entite) return '';
-		include_spip('inc/urls');
+		if (!function_exists('generer_url_ecrire_objet'))
+			include_spip('inc/urls');
 		$res = generer_url_ecrire_objet($entite,$id, $args, $ancre, false);
 	} else {
 		if ($type === NULL) {
@@ -1861,7 +1865,6 @@ function verifier_visiteur() {
 // http://doc.spip.org/@lang_select
 function lang_select ($lang=NULL) {
 	static $pile_langues = array();
-	include_spip('inc/lang');
 	if ($lang === NULL)
 		$lang = array_pop($pile_langues);
 	else {
@@ -1943,7 +1946,8 @@ function erreur_squelette($message='', $lieu='') {
  */
 // http://doc.spip.org/@recuperer_fond
 function recuperer_fond($fond, $contexte=array(), $options = array(), $connect='') {
-	include_spip('public/assembler');
+	if (!function_exists('evaluer_fond'))
+		include_spip('public/assembler');
 	// assurer la compat avec l'ancienne syntaxe
 	// (trim etait le 3eme argument, par defaut a true)
 	if (!is_array($options)) $options = array('trim'=>$options);
@@ -1982,7 +1986,8 @@ function recuperer_fond($fond, $contexte=array(), $options = array(), $connect='
 			'data'=>$page
 		));
 		if (isset($options['ajax']) AND $options['ajax']){
-			include_spip('inc/filtres');
+			if (!function_exists('encoder_contexte_ajax'))
+				include_spip('inc/filtres');
 			$page['texte'] = encoder_contexte_ajax(array_merge($contexte,array('fond'=>$f)),'',$page['texte'], $options['ajax']);
 		}
 
@@ -2037,19 +2042,21 @@ function trouver_fond($nom, $dir='', $pathinfo = false) {
 }
 
 function tester_url_ecrire($nom){
+	static $exec=array();
+	if (isset($exec[$nom])) return $exec[$nom];
 	// tester si c'est une page en squelette
 	if (trouver_fond($nom, 'prive/squelettes/contenu/'))
-		return 'fond';
+		return $exec[$nom] = 'fond';
 	// compat skels orthogonaux version precedente
 	elseif (trouver_fond($nom, 'prive/exec/'))
-		return 'fond_monobloc';
+		return $exec[$nom] = 'fond_monobloc';
 	// echaffaudage d'un fond !
 	elseif(include_spip('public/styliser_par_z') AND z_echaffaudable($nom))
-		return 'fond';
+		return $exec[$nom] = 'fond';
 	// attention, il ne faut pas inclure l'exec ici
 	// car sinon #URL_ECRIRE provoque des inclusions
 	// et des define intrusifs potentiels
-	return (find_in_path("{$nom}.php",'exec/') OR charger_fonction($nom,'exec',true))?$nom:'';
+	return $exec[$nom] = ((find_in_path("{$nom}.php",'exec/') OR charger_fonction($nom,'exec',true))?$nom:'');
 }
 
 // Charger dynamiquement une extension php
diff --git a/ecrire/iterateur/data.php b/ecrire/iterateur/data.php
index b2f7b41904..9d434a23f7 100644
--- a/ecrire/iterateur/data.php
+++ b/ecrire/iterateur/data.php
@@ -159,7 +159,9 @@ class IterateurDATA implements Iterator {
 			# un peu crado : avant de charger le cache il faut charger
 			# les class indispensables, sinon PHP ne saura pas gerer
 			# l'objet en cache ; cf plugins/icalendar
-			if (isset($this->command['sourcemode']))
+			# perf : pas de fonction table_to_array ! (table est deja un array)
+			if (isset($this->command['sourcemode'])
+			  AND !in_array($this->command['sourcemode'],array('table', 'array', 'tableau')))
 				charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true);
 
 			# le premier argument peut etre un array, une URL etc.
@@ -197,29 +199,30 @@ class IterateurDATA implements Iterator {
 					)
 						$this->tableau = $a;
 				}
-				else if (preg_match(',^https?://,', $src)) {
-					include_spip('inc/distant');
-					$u = recuperer_page($src);
-					if (!$u)
-						throw new Exception("404");
-					if (!isset($ttl)) $ttl = 24*3600;
-				} else if (@is_dir($src)) {
-					$u = $src;
-					if (!isset($ttl)) $ttl = 10;
-				} else if (@is_readable($src) && @is_file($src)) {
-					$u = spip_file_get_contents($src);
-					if (!isset($ttl)) $ttl = 10;
-				} else {
-					$u = $src;
-					if (!isset($ttl)) $ttl = 10;
-				}
-
-				if (!$this->err
-				AND $g = charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true)) {
-					$args = $this->command['source'];
-					$args[0] = $u;
-					if (is_array($a = call_user_func_array($g,$args))) {
-						$this->tableau = $a;
+				else {
+					if (preg_match(',^https?://,', $src)) {
+						include_spip('inc/distant');
+						$u = recuperer_page($src);
+						if (!$u)
+							throw new Exception("404");
+						if (!isset($ttl)) $ttl = 24*3600;
+					} else if (@is_dir($src)) {
+						$u = $src;
+						if (!isset($ttl)) $ttl = 10;
+					} else if (@is_readable($src) && @is_file($src)) {
+						$u = spip_file_get_contents($src);
+						if (!isset($ttl)) $ttl = 10;
+					} else {
+						$u = $src;
+						if (!isset($ttl)) $ttl = 10;
+					}
+					if (!$this->err
+					AND $g = charger_fonction($this->command['sourcemode'] . '_to_array', 'inc', true)) {
+						$args = $this->command['source'];
+						$args[0] = $u;
+						if (is_array($a = call_user_func_array($g,$args))) {
+							$this->tableau = $a;
+						}
 					}
 				}
 
diff --git a/ecrire/public/compiler.php b/ecrire/public/compiler.php
index 11c430ce50..45d7c7e566 100644
--- a/ecrire/public/compiler.php
+++ b/ecrire/public/compiler.php
@@ -542,7 +542,6 @@ function memoriser_contexte_compil($p) {
 function reconstruire_contexte_compil($context_compil)
 {
 	if (!is_array($context_compil)) return $context_compil;
-	include_spip('public/interfaces');
 	$p = new Contexte;
 	$p->descr = array('sourcefile' => $context_compil[0],
 				  'nom' => $context_compil[1]);
diff --git a/ecrire/public/iterateur.php b/ecrire/public/iterateur.php
index 07a2745405..fc24f9b0e7 100644
--- a/ecrire/public/iterateur.php
+++ b/ecrire/public/iterateur.php
@@ -66,14 +66,15 @@ class IterFactory{
 			// IterateurXXX
 			// definie dans le fichier iterateurs/xxx.php
 			$class = "Iterateur".$iterateur;
-			if (!include_spip("iterateur/" . strtolower($iterateur))
-			  OR !class_exists($class)) {
-				die("Iterateur $iterateur non trouv&#233;");
-				// si l'iterateur n'existe pas, on se rabat sur le generique
-				$iter = new EmptyIterator();
-			} else {
-				$iter = new $class($command, $info);
+			if (!class_exists($class)){
+				if (!include_spip("iterateur/" . strtolower($iterateur))
+					OR !class_exists($class)) {
+					die("Iterateur $iterateur non trouv&#233;");
+					// si l'iterateur n'existe pas, on se rabat sur le generique
+					# $iter = new EmptyIterator();
+				}
 			}
+			$iter = new $class($command, $info);
 		}
 		return new IterDecorator($iter, $command, $info);
 	}
diff --git a/ecrire/public/parametrer.php b/ecrire/public/parametrer.php
index 7371ab2138..f8c45b84f0 100644
--- a/ecrire/public/parametrer.php
+++ b/ecrire/public/parametrer.php
@@ -13,7 +13,6 @@
 if (!defined('_ECRIRE_INC_VERSION')) return;
 
 include_spip('inc/lang');
-include_spip('public/quete'); // pour quete_virtuel et ses dependances
 
 // NB: mes_fonctions peut initialiser $dossier_squelettes (old-style)
 // donc il faut l'inclure "en globals"
@@ -202,6 +201,7 @@ function tester_redirection($fond, $contexte, $connect)
 {
 	if ($fond == 'article'
 	  AND $id_article = intval($contexte['id_article'])) {
+		include_spip('public/quete'); // pour quete_virtuel et ses dependances
 		$m = quete_virtuel($id_article, $connect);
 		if (strlen($m)) {
 			include_spip('inc/texte');
diff --git a/ecrire/public/styliser.php b/ecrire/public/styliser.php
index 31b80ca511..086da52ad3 100644
--- a/ecrire/public/styliser.php
+++ b/ecrire/public/styliser.php
@@ -117,8 +117,10 @@ function styliser_par_objets($flux){
 function quete_rubrique_fond($contexte) {
 	static $liste_objets = null;
 	static $quete = array();
-	if (!$liste_objets) {
+	if (is_null($liste_objets)) {
+		$liste_objets = array();
 		include_spip('inc/urls');
+		include_spip('public/quete');
 		$l = urls_liste_objets(false);
 		// placer la rubrique en tete des objets
 		$l = array_diff($l,array('rubrique'));
diff --git a/ecrire/public/styliser_par_z.php b/ecrire/public/styliser_par_z.php
index ce40ed4314..4fc2a0c5a3 100644
--- a/ecrire/public/styliser_par_z.php
+++ b/ecrire/public/styliser_par_z.php
@@ -257,7 +257,8 @@ function z_echaffaudable($type){
 		return $echaffaudable[$type] = false;
 
 	if (test_espace_prive()){
-		include_spip('inc/pipelines_ecrire');
+		if (!function_exists('trouver_objet_exec'))
+			include_spip('inc/pipelines_ecrire');
 		if ($e=trouver_objet_exec($type)){
 			return $echaffaudable[$type] = array($e['table'],$e['table_objet_sql'],$e);
 		}
-- 
GitLab