docs: function setUpStates(pages, routeNameParent, parentDirectory) {
              pages.forEach(function (page) {
                  if (!page.isBlock && (!page.isStateRef || page.stateRef)) {
                      var routeName = routeNameParent + '.' + page.name;
                      var dirState = routeName.replace('winlassie.', '').split('.');
                      var templateUrl = null;
                      var pageNameReplace = replaceAll(page.name, '_', '-');
                      var state = {url: '/' + pageNameReplace, data: {haveTemplate: false}};
  
                      // Page cachée ou pas
                      if (typeof page.hidden !== 'undefined') {
                          state.data.hidden = page.hidden;
                      } else {
                          state.data.hidden = false;
                      }
  
                      // C'est une route d'action (view, create, edit...)
                      if (page.niveauAction) {
                          dirState.pop();
                          state.data.action = page.niveauAction;
                      }
  
                      // C'est page contient un paramètre requireLogin pour définir si l'utilisateur doit être authentifié
                      if (page.requireLogin) {
                          state.data.requireLogin = page.requireLogin;
                      } else {
                          state.data.requireLogin = true;
                      }
  
                      // C'est page contient un paramètre requireLogin pour définir si l'utilisateur doit être authentifié
                      if (page.redirectTo) {
                          state.redirectTo = 'winlassie.' + page.redirectTo;
                          state.data.haveTemplate = true;
                      }
  
                      // Construction du répertoire
                      if (!parentDirectory || isEmpty(parentDirectory) || (page.stateRef && !isEmpty(page.stateRef))) {
                          // Soit on fait référence à une route différente, une sorte d'inclusion, soit on a un fonctionnement normal
                          if (page.stateRef && !isEmpty(page.stateRef)) {
                              dirState = page.stateRef;
                          } else {
                              dirState = dirState.join('/');
                          }
                      } else {
                          dirState = parentDirectory;
  
                          // Ce n'est pas un niveau, alors on peut concaténé le nom de la page
                          if (!page.niveauAction) {
                              dirState = dirState + '/' + page.name;
                          }
                      }
  
                      // Titre de la page
                      if (page.title) {
                          state.data.pageTitle = page.title;
                      }
  
                      // Données suplémentaire pour la route
                      if (page.data) {
                          state.data = Object.assign({}, state.data, page.data);
                      }
  
                      // Définition de la vue html
                      if (page.views && typeof page.views === 'object') {
                          // On fait référence à une vue qui est le dossier "common"
                          if (page.views.contentCommon) {
                              templateUrl = {templateUrl: 'views/w17_template/common/' + page.views.contentCommon};
                          } else {
                              if (page.views.content && typeof page.views.content === 'object') {
                                  templateUrl = Object.assign({}, page.views.content);
                              } else if (typeof page.views.content === 'string') {
                                  templateUrl = {templateUrl: 'views/w17_template/' + dirState + '/' + page.views.content};
                              }
                          }
  
                          // Définition de la vue dans la route pour le conteneur "content" de la route "winlassie"
                          state.views = {
                              'content@winlassie': templateUrl
                          };
  
                          state.data.haveTemplate = true;
  
                          // Paramètres de la vue
                          if (page.views.params && Array.isArray(page.views.params) && 0 < page.views.params.length) {
                              var paramsUrl = [];
                              var paramsSearch = [];
  
                              page.views.params.forEach(function (value) {
                                  if (value.startsWith('?')) {
                                      paramsSearch.push(value.substring(1));
                                  } else {
                                      paramsUrl.push(value);
                                  }
                              });
  
                              if (0 < paramsUrl.length) {
                                  state.url += '/:' + paramsUrl.join('/:');
                              }
  
                              if (0 < paramsSearch.length) {
                                  state.url += '?' + paramsSearch.join('?')
                              }
                          }
                      }
  
                      states[routeName] = state;
  
                      if (Array.isArray(page.pages) && 0 < page.pages.length) {
                          setUpStates(page.pages, routeName, dirState);
                      }
                  }
              });
          }