diff --git a/js/includes/input-phone-matrice-min.js b/js/includes/input-phone-matrice-min.js
index 31153be..4c7a31b 100644
--- a/js/includes/input-phone-matrice-min.js
+++ b/js/includes/input-phone-matrice-min.js
@@ -1,5 +1,10 @@
function inputPhoneMatrice(a){this.container=a}inputPhoneMatrice.prototype={container:this.container};
-inputPhoneMatrice.prototype.fieldsToStorage=function(){console.log("MATRICE: FIELDS TO STORAGE");var a=(new FormDeflater(this.container,["input"],["data-name"])).deflate();crc32(JSON.stringify(a));var d={},b;for(b in a)if(a[b]instanceof Array)for(var e in a[b])null==d[b]&&(d[b]=[]),d[b].push(parseInt(a[b][e]));else null!==a[b]&&(null==d[b]&&(d[b]=[]),d[b].push(parseInt(a[b])));lsi.set("p_matrice",0,d)};
-inputPhoneMatrice.prototype.storageToFields=function(){console.log("MATRICE: STORAGE TO FIELDS");var a=lsi["export"]("p_fiches"),d=lsi.get("p_matrice",0),b=lsi["export"]("p_contacts"),e=[],c;for(c in a)-1==e.indexOf(a[c].contact)&&e.push(a[c].contact);a="
"};
-inputPhoneMatrice.prototype.attach=function(){console.log("MATRICE: ATTACH");lsi.createDataset("p_matrice");this.storageToFields();var a=this;this.container.addEventListener("click",function(d){a.fieldsToStorage();a.storageToFields()},!1);this.snake()};inputPhoneMatrice.prototype.snake=function(){this.sVelocity=[0,0];this.sLength=0;this.sStack=[]};
+inputPhoneMatrice.prototype.fieldsToStorage=function(){console.log("MATRICE: FIELDS TO STORAGE");var a=(new FormDeflater(this.container,["input"],["data-name"])).deflate();crc32(JSON.stringify(a));var d={},b;for(b in a)if(a[b]instanceof Array)for(var g in a[b])null==d[b]&&(d[b]=[]),d[b].push(parseInt(a[b][g]));else null!==a[b]&&(null==d[b]&&(d[b]=[]),d[b].push(parseInt(a[b])));lsi.set("p_matrice",0,d)};
+inputPhoneMatrice.prototype.storageToFields=function(){console.log("MATRICE: STORAGE TO FIELDS");var a=lsi["export"]("p_fiches"),d=lsi.get("p_matrice",0),b=lsi["export"]("p_contacts"),g=[],f;for(f in a)-1==g.indexOf(a[f].contact)&&g.push(a[f].contact);a=""};
+inputPhoneMatrice.prototype.attach=function(){console.log("MATRICE: ATTACH");lsi.createDataset("p_matrice");this.storageToFields();var a=this;this.container.addEventListener("click",function(d){a.fieldsToStorage();a.storageToFields()},!1)};inputPhoneMatrice.prototype.parseGrid=function(){var a=$$(".matrice-panel input[data-name][value]"),d;for(d in a)if(a[d]instanceof Element){var b=a[d].getData("name"),g=a[d].value;this.sGrid[b]instanceof Array||(this.sGrid[b]=[]);this.sGrid[b][g]=a[d]}};
+inputPhoneMatrice.prototype.snake=function(){this.sVelocity=[0,0];this.sLength=2;this.sStack=[];this.sKeys=[];this.sGrid=[];this.sRoutine=this.sTarget=null;var a=this;this.parseGrid();var d=parseInt(this.sGrid.length/2),b=parseInt(this.sGrid[d].length/2);this.sStack.push(this.sGrid[d][b]);for(var d=!1,g,f;!d;)g=Math.floor(Math.random()*this.sGrid.length),f=Math.floor(Math.random()*this.sGrid[g].length),d=(d=null!=this.sGrid[g]&&null!=this.sGrid[g][f])&&-1==this.sStack.indexOf(this.sGrid[g][f]);this.sTarget=
+this.sGrid[g][f];document.body.addEventListener("keydown",function(e){-1<[37,38,39,40].indexOf(e.keyCode)&&-1==a.sKeys.indexOf(e.keyCode)&&a.sKeys.push(e.keyCode)},!1);document.body.addEventListener("keyup",function(e){var c=a.sKeys.indexOf(e.keyCode);-1<[37,38,39,40].indexOf(e.keyCode)&&-1e&&(e=a.sGrid[c].length-1);c=(c+a.sVelocity[1])%a.sGrid.length;0>=c&&(c=e+1);if(null==a.sGrid[c]||null==a.sGrid[c][e])c=a.sGrid.length-1;if(null!=a.sGrid[c]&&null!=a.sGrid[c][e]){if(a.sGrid[c][e].checked)if(a.sGrid[c][e].id==a.sTarget.id){a.sLength++;
+for(var d=!1,b,f;!d;)b=Math.floor(Math.random()*a.sGrid.length),f=Math.floor(Math.random()*a.sGrid[b].length),d=(d=null!=a.sGrid[b]&&null!=a.sGrid[b][f])&&-1==a.sStack.indexOf(a.sGrid[b][f]);a.sTarget=a.sGrid[b][f]}else a.sStack[a.sStack.length-1].id!=a.sGrid[c][e].id&&(console.log(a.sStack[a.sStack.length-1].id,a.sGrid[c][e].id),alert("vous avez perdu! Score: "+(a.sLength-2)),clearInterval(a.sRoutine));a.sStack.push(a.sGrid[c][e])}var c=[],g;for(g in a.sStack)b=a.sStack[g].getData("name"),f=a.sStack[g].value,
+null==c[b]&&(c[b]=[]),c[b].push(parseInt(f));null!=a.sTarget&&(b=a.sTarget.getData("name"),f=a.sTarget.value,null==c[b]&&(c[b]=[]),c[b].push(parseInt(f)));lsi.set("p_matrice",0,c);a.storageToFields();a.parseGrid();g=a.sStack.length;g>=a.sLength&&(a.sStack=a.sStack.slice(1+g-a.sLength));document.location="#snake"},200)};
diff --git a/js/includes/input-phone-matrice.js b/js/includes/input-phone-matrice.js
index 6352ee0..a101d0f 100644
--- a/js/includes/input-phone-matrice.js
+++ b/js/includes/input-phone-matrice.js
@@ -83,10 +83,10 @@ inputPhoneMatrice.prototype.storageToFields = function(){
// On récupère les données de la matrice
var matriceData = lsi.get('p_matrice', 0);
- // On récupère les contacts pour afficher les noms/prénoms
+ // On récupère les contacts pour afficher les noms/prénoms
var contactData = lsi.export('p_contacts');
- // Contiendra les UID des contacts à mettre dans la matrice
+ // Contiendra les UID des contacts à mettre dans la matrice
var contacts = [];
// Pour chaque fiche, on ajoute l'uid du contact s'il n'est pas déja ajouté
@@ -170,8 +170,6 @@ inputPhoneMatrice.prototype.attach = function(){
ptr.fieldsToStorage();
ptr.storageToFields();
}, false);
-
- this.snake();
};
@@ -182,14 +180,178 @@ inputPhoneMatrice.prototype.attach = function(){
+inputPhoneMatrice.prototype.parseGrid = function(){
+ /* (1) On récupère la matrice des éléments de la grille */
+ var gridElements = $$('.matrice-panel input[data-name][value]');
+ for( var i in gridElements ){
+ if( !(gridElements[i] instanceof Element) )
+ continue;
+
+ var col = gridElements[i].getData('name');
+ var row = gridElements[i].value;
+
+ if( !(this.sGrid[col] instanceof Array) )
+ this.sGrid[col] = [];
+
+ this.sGrid[col][row] = gridElements[i];
+
+ }
+
+};
inputPhoneMatrice.prototype.snake = function(){
/* [0] On écrit les fonctions principales
=========================================================*/
+ /* (1) ATTRIBUTS */
this.sVelocity = [0, 0];
- this.sLength = 0;
+ this.sLength = 2;
this.sStack = [];
+ this.sKeys = [];
+ this.sGrid = [];
+ this.sTarget = null;
+ this.sRoutine = null;
+ var ptr = this;
+
+ /* (2) ON RECUPERE LA MATRICE D'ELEMENTS */
+ this.parseGrid();
+
+ /* (2) On positionne le joueur au milieu */
+ var midcol = parseInt( this.sGrid.length / 2 );
+ var midrow = parseInt( this.sGrid[midcol].length / 2 );
+ this.sStack.push( this.sGrid[midcol][midrow] );
+
+ /* (3) On positionne la cible */
+ var tool = { correct: false }
+ while( !tool.correct ){
+ tool.col = Math.floor( Math.random()*this.sGrid.length );
+ tool.row = Math.floor( Math.random()*this.sGrid[tool.col].length );
+ tool.correct = this.sGrid[tool.col] != null && this.sGrid[tool.col][tool.row] != null;
+ tool.correct = tool.correct && this.sStack.indexOf(this.sGrid[tool.col][tool.row]) == -1;
+ }
+ this.sTarget = this.sGrid[tool.col][tool.row];
+
+ /* [1] Gestion des handlers
+ =========================================================*/
+ /* (1) Pression sur touche */
+ document.body.addEventListener('keydown', function(e){
+ // Si une fleche, on l'enregistre si elle ne l'est pas déja
+ if( [37, 38, 39, 40].indexOf(e.keyCode) > -1 && ptr.sKeys.indexOf(e.keyCode) == -1 )
+ ptr.sKeys.push(e.keyCode);
+ }, false);
+
+ /* (2) Relachement touche */
+ document.body.addEventListener('keyup', function(e){
+ var index = ptr.sKeys.indexOf(e.keyCode);
+ // Si une fleche, on la retire si elle ne l'est pas déja
+ if( [37, 38, 39, 40].indexOf(e.keyCode) > -1 && index > -1 )
+ ptr.sKeys.splice(index);
+ }, false);
+
+ /* [2] Lancement de la boucle de jeu
+ =========================================================*/
+ this.sRoutine = setInterval(function(){
+ /* (1) Gestion de la vélocité en fonction des touches */
+ if( ptr.sKeys.indexOf(37) > -1 ) // Vers la gauche
+ ptr.sVelocity[0] = -1;
+ else if( ptr.sKeys.indexOf(39) > -1 ) // Vers la droite
+ ptr.sVelocity[0] = 1;
+
+ if( ptr.sKeys.indexOf(38) > -1 ) // Vers le haut
+ ptr.sVelocity[1] = -1;
+ else if( ptr.sKeys.indexOf(40) > -1 ) // Vers le bas
+ ptr.sVelocity[1] = 1;
+ else if( ptr.sVelocity[0] != 0 )
+ ptr.sVelocity[1] = 0;
+
+ if( ptr.sKeys.indexOf(37)+ptr.sKeys.indexOf(39) == -2 && ptr.sVelocity[1] != 0 )
+ ptr.sVelocity[0] = 0;
+
+ // Dernier element de la pile
+ var lastStack = ptr.sStack[ ptr.sStack.length-1 ];
+ var lastcol = parseInt( lastStack.getData('name') );
+ var lastrow = parseInt( lastStack.value );
+
+ /* (2) Gestion du mouvement */
+ lastrow = (lastrow + ptr.sVelocity[0]) % ptr.sGrid[lastcol].length;
+ if( lastrow < 0 ) lastrow = ptr.sGrid[lastcol].length - 1;
+
+ lastcol = (lastcol + ptr.sVelocity[1]) % ptr.sGrid.length;
+ if( lastcol <= 0 ) lastcol = lastrow+1;
+ if( ptr.sGrid[lastcol] == null || ptr.sGrid[lastcol][lastrow] == null )
+ lastcol = ptr.sGrid.length-1;
+
+
+
+ if( ptr.sGrid[lastcol] != null && ptr.sGrid[lastcol][lastrow] != null ){
+
+ /* (1) Si la case est déja prisse */
+ if( ptr.sGrid[lastcol][lastrow].checked ){
+ /* (2) Si on c'est la cible */
+ if( ptr.sGrid[lastcol][lastrow].id == ptr.sTarget.id ){
+ ptr.sLength++;
+
+ // On repositionne la cible
+ var tool = { correct: false }
+ while( !tool.correct ){
+ tool.col = Math.floor( Math.random()*ptr.sGrid.length );
+ tool.row = Math.floor( Math.random()*ptr.sGrid[tool.col].length );
+ tool.correct = ptr.sGrid[tool.col] != null && ptr.sGrid[tool.col][tool.row] != null;
+ tool.correct = tool.correct && ptr.sStack.indexOf(ptr.sGrid[tool.col][tool.row]) == -1;
+ }
+ ptr.sTarget = ptr.sGrid[tool.col][tool.row];
+ }
+
+ /* (3) Si on se mord la queue (mais pas la tete)*/
+ else if( ptr.sStack[ptr.sStack.length-1].id != ptr.sGrid[lastcol][lastrow].id ){
+ console.log(ptr.sStack[ptr.sStack.length-1].id, ptr.sGrid[lastcol][lastrow].id );
+ alert('vous avez perdu! Score: '+(ptr.sLength-2) );
+ clearInterval(ptr.sRoutine);
+ }
+ }
+ ptr.sStack.push( ptr.sGrid[lastcol][lastrow] );
+ }
+
+
+
+ /* (3) On affiche que les cases de la pile */
+ var matrix = [];
+ for( var i in ptr.sStack ){
+ var col = ptr.sStack[i].getData('name');
+ var row = ptr.sStack[i].value;
+
+ if( matrix[col] == null )
+ matrix[col] = [];
+
+ matrix[col].push( parseInt(row) );
+ }
+
+ /* (4) On ajoute la cible */
+ if( ptr.sTarget != null ){
+ var col = ptr.sTarget.getData('name');
+ var row = ptr.sTarget.value;
+
+ if( matrix[col] == null )
+ matrix[col] = [];
+
+ matrix[col].push( parseInt(row) );
+ }
+
+
+ /* (5) Enregistrement du modèle */
+ lsi.set('p_matrice', 0, matrix);
+ ptr.storageToFields();
+ ptr.parseGrid();
+
+
+ /* (6) On vide les cases dépassant sLength */
+ var len = ptr.sStack.length;
+
+ if( len >= ptr.sLength )
+ ptr.sStack = ptr.sStack.slice( 1+len-ptr.sLength );
+
+ document.location ='#snake';
+
+ }, 200);
-
};
diff --git a/js/lib/shortcut-manager-min.js b/js/lib/shortcut-manager-min.js
new file mode 100644
index 0000000..f3bdddd
--- /dev/null
+++ b/js/lib/shortcut-manager-min.js
@@ -0,0 +1,3 @@
+function strToKeyCode(a){var b=a.toUpperCase().charCodeAt(0);if(1==a.length&&(65<=b&&90>=b||49<=b&&57>=b))return b;switch(a){case "ctrl":return 17;case "maj":return 16;case "alt":return 18;case "tab":return 9;case "left":return 37;case "up":return 38;case "right":return 39;case "down":return 40}return null}function ShortcutManager(){}
+ShortcutManager.prototype={pressed:[],shortcuts:[],handlers:[],lastKeyCode:[],append:function(a,b){for(var c=a.toLowerCase().split("+"),d=0;da.pressed.indexOf(b.keyCode)&&a.pressed.push(b.keyCode);for(var c=0;c= 65 && keyCode <= 90) || (keyCode >= 49 && keyCode <= 57)) )
+ return keyCode; // on retourne le keyCode associé
+ else
+ switch( keyString ){ // sinon, on récupère l'ascii spécifiquement
+ case 'ctrl': return 17; break;
+ case 'maj': return 16; break;
+ case 'alt': return 18; break;
+ case 'tab': return 9; break;
+ case 'left': return 37; break;
+ case 'up': return 38; break;
+ case 'right': return 39; break;
+ case 'down': return 40; break;
+ }
+
+ return null;
+}
+
+
+
+
+
+
+
+/**********/
+/* CLASSE */
+/**********/
+function ShortcutManager(){};
+
+ShortcutManager.prototype = {
+ pressed: [], // contiendra les touches pressées (en cours)
+ shortcuts: [], // contiendra tous les raccourcis
+ // progress: [], // contiendra l'avancée des raccourcis
+ handlers: [], // contiendra tous les handlers (fonctions à éxécuter)
+ /* tmp */
+ lastKeyCode: [], // contiendra des "reminder" pour les évènements
+
+ /* ajout d'un nouveau raccourcis clavier */
+ append: function(keyRow, handler){
+ /* [1] On découpe la chaîne (en minuscule) par "+"
+ =======================================================*/
+ var keyStore = keyRow.toLowerCase().split('+');
+
+ /* [2] On récupère les keyCodes correspondant aux codes/lettres
+ =======================================================*/
+ for( var i = 0 ; i < keyStore.length ; i++ ){
+ keyStore[i] = strToKeyCode( keyStore[i] );
+
+ // si on a une erreur, on retourne NULL
+ if( keyStore[i] == null ) return null;
+ }
+
+ /* [3] On enregistre dans l'objet (shortcuts, progress, handler)
+ =======================================================*/
+ var index = this.shortcuts.push( keyStore ) - 1;
+ // this.progress[index] = 0; // le progrès est l'index d'avancement
+ this.handlers[index] = handler; // handler (function qui s'éxécutera lors de l'activation)
+ this.lastKeyCode[index] = null; //
+ },
+
+ /* démarre l'écoute (active les évènements) */
+ listen: function(){
+
+ /* [1] On créé l'évènement d'appui de touche pour chaque élément
+ =======================================================*/
+ var pointer = this;
+
+ // on initialise/créer l'évènement
+ window.addEventListener('keydown', function(e){
+
+ // on ajoute la touche si elle n'y est pas
+ if( pointer.pressed.indexOf(e.keyCode) < 0 ) pointer.pressed.push(e.keyCode);
+
+ for( var i = 0 ; i < pointer.shortcuts.length ; i++ ){
+
+ var complete = pointer.shortcuts[i].length; // taille du shortcut en question
+ // on vérifie que l'ensemble des touches pressées remplissent le shortcut
+ for( var k = 0 ; k < pointer.pressed.length ; k++ )
+ if( pointer.shortcuts[i].indexOf( pointer.pressed[k] ) > -1 ) // si la touche est dans le shortcut, on décrémente compteur (complete)
+ complete -= 1;
+
+
+ // si le compteur est à 0, on a terminé la combinaison de touches, on remet le compteur à 0 + on exécute le handler
+ if( complete == 0 )
+ pointer.handlers[i](e);
+ }
+
+ }, false);
+
+
+
+
+ // si on lâche une touche, on l'enlève de "pressed"
+ window.addEventListener('keyup', function(e){
+ var index = pointer.pressed.indexOf(e.keyCode);
+
+ if( index > -1 ) // si c'est une touche définie comme déjà appuyée, on l'enlève
+ pointer.pressed = pointer.pressed.slice(0,index).concat( pointer.pressed.slice(index+1) );
+ else // sinon on supprime tout (car sûrement erreur d'écoute)
+ pointer.pressed = [];
+
+ }, false);
+ }
+};
diff --git a/view.php b/view.php
index de18218..aff0c31 100755
--- a/view.php
+++ b/view.php
@@ -35,10 +35,11 @@
+
-
-
+
+
diff --git a/view/input.php b/view/input.php
index 9f10c0f..83b6e0e 100755
--- a/view/input.php
+++ b/view/input.php
@@ -108,7 +108,7 @@
Saisir les matrices des relations entre les contacts les plus contactés
-
+
diff --git a/view/js/input-min.js b/view/js/input-min.js
index 911f39f..37bee37 100644
--- a/view/js/input-min.js
+++ b/view/js/input-min.js
@@ -1,26 +1,26 @@
var cSubjectManager,cContactManager,cMiniManager,cFicheManager,cMatriceManager;
-function cDynamicUpdate(a){var b=a instanceof Element,c=b&&"INPUT"==a.tagName&&"submit"==a.type,e=b&&"SPAN"==a.tagName&&("p_nav-mini"==a.parentNode.id||"p_nav-fiche"==a.parentNode.id),b=b&&"SPAN"==a.tagName&&"p_nav-contact"==a.parentNode.id;if(!c&&!e&&!b&&!0!==a)return!1;console.log("> dynamic update");pMiniManager.fieldsToStorage();pFicheManager.fieldsToStorage();pContactManager.fieldsToStorage();pMatriceManager.fieldsToStorage();pFicheManager.sync();pMiniManager.sync();pMiniManager.storageToFields();
-pFicheManager.storageToFields();pMatriceManager.storageToFields();(c||b)&&pContactManager.storageToFields()}
-include("/js/includes/input-phone-subject-min.js",function(){include("/js/includes/input-phone-contact-min.js",function(){include("/js/includes/input-phone-mini-min.js",function(){include("/js/includes/input-phone-fiche-min.js",function(){include("/js/includes/input-phone-matrice-min.js",function(){pSubjectManager=new inputPhoneSubject($('[data-sublink="phone"] article.subject-panel [data-name="tmp_id"]'),$('[data-sublink="phone"] article.subject-panel [data-name="number"]'),$('[data-sublink="phone"] article.subject-panel [data-name="username"]'),
+function cDynamicUpdate(b){var a=b instanceof Element,d=a&&"INPUT"==b.tagName&&"submit"==b.type,e=a&&"SPAN"==b.tagName&&("p_nav-mini"==b.parentNode.id||"p_nav-fiche"==b.parentNode.id),a=a&&"SPAN"==b.tagName&&"p_nav-contact"==b.parentNode.id;if(!d&&!e&&!a&&!0!==b)return!1;console.log("> dynamic update");pMiniManager.fieldsToStorage();pFicheManager.fieldsToStorage();pContactManager.fieldsToStorage();pMatriceManager.fieldsToStorage();pFicheManager.sync();pMiniManager.sync();pMiniManager.storageToFields();
+pFicheManager.storageToFields();pMatriceManager.storageToFields();(d||a)&&pContactManager.storageToFields()}
+include("/js/includes/input-phone-subject-min.js",function(){include("/js/includes/input-phone-contact-min.js",function(){include("/js/includes/input-phone-mini-min.js",function(){include("/js/includes/input-phone-fiche-min.js",function(){include("/js/includes/input-phone-matrice.js",function(){pSubjectManager=new inputPhoneSubject($('[data-sublink="phone"] article.subject-panel [data-name="tmp_id"]'),$('[data-sublink="phone"] article.subject-panel [data-name="number"]'),$('[data-sublink="phone"] article.subject-panel [data-name="username"]'),
$('[data-sublink="phone"] article.subject-panel [data-name="submit"]'));pSubjectManager.attach();pContactManager=new inputPhoneContact($('[data-sublink="phone"] article.contact-panel'),$('[data-sublink="phone"] #p_nav-contact'));pContactManager.attach(cDynamicUpdate);pMiniManager=new inputPhoneMini($('[data-sublink="phone"] article.mini-relation-panel'),$('[data-sublink="phone"] #p_nav-mini'));pMiniManager.attach(cDynamicUpdate);pFicheManager=new inputPhoneFiche($('[data-sublink="phone"] article.relation-panel'),
-$('[data-sublink="phone"] #p_nav-fiche'));pFicheManager.attach(cDynamicUpdate);pMatriceManager=new inputPhoneMatrice($('[data-sublink="phone"] article.matrice-panel'));pMatriceManager.attach(cDynamicUpdate);$('[data-sublink="phone"] input#p_call_log-import[type="file"]').addEventListener("click",function(a){a.target.value=null},!1);$('[data-sublink="phone"] input#p_call_log-import[type="file"]').addEventListener("change",function(a){a={path:"upload/call_log",phone_number:$('[data-sublink="phone"] #p_subject_phone_number').value,
-file:a.target.files[0]};api.send(a,function(b){console.log(b);var a=null;if(0!=b.ModuleError)9==b.ModuleError?Notification.error("Erreur","Il est n\u00e9cessaire de saisir les informations du sujet avant d'exporter son journal d'appel"):Notification.error("Erreur",b.ModuleError);else{a=Notification.info("Info","Chargement du journal d'appel");pSubjectManager.tmp_id.value=b.tmp_id;pSubjectManager.fieldsToStorage();pSubjectManager.storageToFields();for(var e=0;e GATHERING ALL DATA");pSubjectManager.fieldsToStorage();pContactManager.fieldsToStorage();pMiniManager.fieldsToStorage();cFicheManager.fieldsToStorage();if(!cSubjectManager.check())return Notification.warning("Attention","Vous devez saisir les informations du sujet"),!1;a=lsi["export"]("p_mini-fiches");var b=0,c;for(c in a)if(!isNaN(c)&&(b++,!a[c].valid))return Notification.warning("Attention",
-"La fiche rapide "+b+" est incompl\u00e8te et/ou incorrecte"),!1;a=lsi["export"]("p_fiches");for(c in a)if(!a[c].valid)return Notification.warning("Attention","La fiche compl\u00e8te "+(parseInt(c)+1)+" est incompl\u00e8te et/ou incorrecte"),!1;c={path:"input/phone",subject:lsi["export"]("p_subject")[0],contacts:lsi["export"]("p_contacts"),mini:lsi["export"]("p_mini-fiches"),fiches:lsi["export"]("p_fiches"),matrice:lsi["export"]("p_matrice")[0]};api.send(c,function(a){console.log(a);
-if(0!=a.ModuleError)return Notification.error("ERREUR",a.ModuleError),!1;Notification.success("OK","L'identifiant du sujet est "+a.subject_id+" ! Tout s'est bien d\u00e9roul\u00e9.",1E4);console.log(a)},!1)},!1)})})})})});var fSubjectManager,fContactManager,fMiniManager,fFicheManager,fMatriceManager;
-function fDynamicUpdate(a){var b=a instanceof Element,c=b&&"INPUT"==a.tagName&&"submit"==a.type,e=b&&"SPAN"==a.tagName&&("f_nav-mini"==a.parentNode.id||"f_nav-fiche"==a.parentNode.id),b=b&&"SPAN"==a.tagName&&"f_nav-contact"==a.parentNode.id;if(!c&&!e&&!b&&!0!==a)return!1;console.log("> dynamic update");fMiniManager.fieldsToStorage();fFicheManager.fieldsToStorage();fContactManager.fieldsToStorage();fMatriceManager.fieldsToStorage();fFicheManager.sync();fMiniManager.sync();fMiniManager.storageToFields();
-fFicheManager.storageToFields();fMatriceManager.storageToFields();(c||b)&&fContactManager.storageToFields()}
+$('[data-sublink="phone"] #p_nav-fiche'));pFicheManager.attach(cDynamicUpdate);pMatriceManager=new inputPhoneMatrice($('[data-sublink="phone"] article.matrice-panel'));pMatriceManager.attach(cDynamicUpdate);var b=new ShortcutManager;b.append("s+n+a+k+e",function(){pMatriceManager.snake()});b.listen();$('[data-sublink="phone"] input#p_call_log-import[type="file"]').addEventListener("click",function(a){a.target.value=null},!1);$('[data-sublink="phone"] input#p_call_log-import[type="file"]').addEventListener("change",
+function(a){a={path:"upload/call_log",phone_number:$('[data-sublink="phone"] #p_subject_phone_number').value,file:a.target.files[0]};api.send(a,function(a){console.log(a);var b=null;if(0!=a.ModuleError)9==a.ModuleError?Notification.error("Erreur","Il est n\u00e9cessaire de saisir les informations du sujet avant d'exporter son journal d'appel"):Notification.error("Erreur",a.ModuleError);else{b=Notification.info("Info","Chargement du journal d'appel");pSubjectManager.tmp_id.value=a.tmp_id;pSubjectManager.fieldsToStorage();
+pSubjectManager.storageToFields();for(var f=0;f GATHERING ALL DATA");pSubjectManager.fieldsToStorage();pContactManager.fieldsToStorage();pMiniManager.fieldsToStorage();cFicheManager.fieldsToStorage();if(!cSubjectManager.check())return Notification.warning("Attention","Vous devez saisir les informations du sujet"),!1;a=lsi["export"]("p_mini-fiches");var b=0,e;for(e in a)if(!isNaN(e)&&(b++,
+!a[e].valid))return Notification.warning("Attention","La fiche rapide "+b+" est incompl\u00e8te et/ou incorrecte"),!1;a=lsi["export"]("p_fiches");for(e in a)if(!a[e].valid)return Notification.warning("Attention","La fiche compl\u00e8te "+(parseInt(e)+1)+" est incompl\u00e8te et/ou incorrecte"),!1;e={path:"input/phone",subject:lsi["export"]("p_subject")[0],contacts:lsi["export"]("p_contacts"),mini:lsi["export"]("p_mini-fiches"),fiches:lsi["export"]("p_fiches"),matrice:lsi["export"]("p_matrice")[0]};
+api.send(e,function(a){console.log(a);if(0!=a.ModuleError)return Notification.error("ERREUR",a.ModuleError),!1;Notification.success("OK","L'identifiant du sujet est "+a.subject_id+" ! Tout s'est bien d\u00e9roul\u00e9.",1E4);console.log(a)},!1)},!1)})})})})});var fSubjectManager,fContactManager,fMiniManager,fFicheManager,fMatriceManager;
+function fDynamicUpdate(b){var a=b instanceof Element,d=a&&"INPUT"==b.tagName&&"submit"==b.type,e=a&&"SPAN"==b.tagName&&("f_nav-mini"==b.parentNode.id||"f_nav-fiche"==b.parentNode.id),a=a&&"SPAN"==b.tagName&&"f_nav-contact"==b.parentNode.id;if(!d&&!e&&!a&&!0!==b)return!1;console.log("> dynamic update");fMiniManager.fieldsToStorage();fFicheManager.fieldsToStorage();fContactManager.fieldsToStorage();fMatriceManager.fieldsToStorage();fFicheManager.sync();fMiniManager.sync();fMiniManager.storageToFields();
+fFicheManager.storageToFields();fMatriceManager.storageToFields();(d||a)&&fContactManager.storageToFields()}
include("/js/includes/input-facebook-subject-min.js",function(){include("/js/includes/input-facebook-contact-min.js",function(){include("/js/includes/input-facebook-mini-min.js",function(){include("/js/includes/input-facebook-fiche-min.js",function(){include("/js/includes/input-facebook-matrice-min.js",function(){fSubjectManager=new inputFacebookSubject($('[data-sublink="facebook"] article.subject-panel [data-name="username"]'),$('[data-sublink="facebook"] article.subject-panel [data-name="submit"]'));
fSubjectManager.attach();fContactManager=new inputFacebookContact($('[data-sublink="facebook"] article.contact-panel'),$('[data-sublink="facebook"] #f_nav-contact'));fContactManager.attach(fDynamicUpdate);fMiniManager=new inputFacebookMini($('[data-sublink="facebook"] article.mini-relation-panel'),$('[data-sublink="facebook"] #f_nav-mini'));fMiniManager.attach(fDynamicUpdate);fFicheManager=new inputFacebookFiche($('[data-sublink="facebook"] article.relation-panel'),$('[data-sublink="facebook"] #f_nav-fiche'));
-fFicheManager.attach(fDynamicUpdate);fMatriceManager=new inputFacebookMatrice($('[data-sublink="facebook"] article.matrice-panel'));fMatriceManager.attach(fDynamicUpdate);$('[data-sublink="facebook"] #f_clear-all').addEventListener("click",function(a){lsi.clear("f_subject");lsi.clear("f_contacts");lsi.clear("f_mini-fiches");lsi.clear("f_fiches");lsi.clear("f_matrice");fSubjectManager.storageToFields();fContactManager.storageToFields();fMiniManager.storageToFields();fFicheManager.storageToFields();
-fMatriceManager.storageToFields();Notification.success("OK","Les donn\u00e9es ont \u00e9t\u00e9 supprim\u00e9es")},!1);$('[data-sublink="facebook"] #f_export-all').addEventListener("click",function(a){Notification.info("INFORMATION","Lancement du t\u00e9l\u00e9chargement de la sauvegarde");a={subject:lsi["export"]("f_subject")[0],contacts:lsi["export"]("f_contacts"),mini:lsi["export"]("f_mini-fiches"),fiches:lsi["export"]("f_fiches"),matrice:lsi["export"]("f_matrice")[0]};var b=$('[data-sublink="facebook"] #f_download-target');
-b.download="local-facebook-data.json";b.href="data:application/octet-stream,"+encodeURIComponent(JSON.stringify(a));b.click()},!1);$('[data-sublink="facebook"] #f_import-all').addEventListener("click",function(a){$('[data-sublink="facebook"] #f_local-upload').click()},!1);$('[data-sublink="facebook"] #f_local-upload').addEventListener("click",function(a){a.target.value=null},!1);$('[data-sublink="facebook"] #f_local-upload').addEventListener("change",function(a){a={path:"upload/local_data",file:$('[data-sublink="facebook"] #f_local-upload').files[0]};
-api.send(a,function(a){console.log(a);if(0!=a.ModuleError)return Notification.error("Erreur",a.ModuleError),!1;lsi.set("f_subject",0,a.local_data.subject);lsi["import"]("f_contacts",a.local_data.contacts);lsi["import"]("f_mini-fiches",a.local_data.mini);lsi["import"]("f_fiches",a.local_data.fiches);lsi.set("f_matrice",0,a.local_data.matrice);fSubjectManager.storageToFields();fContactManager.storageToFields();fMatriceManager.storageToFields();fDynamicUpdate(!0)})},!1);$('[data-sublink="facebook"] #f_submit-all').addEventListener("click",
-function(a){console.log("> GATHERING ALL DATA");fSubjectManager.fieldsToStorage();fContactManager.fieldsToStorage();fMiniManager.fieldsToStorage();fFicheManager.fieldsToStorage();if(!fSubjectManager.check())return Notification.warning("Attention","Vous devez saisir les informations du sujet"),!1;a=lsi["export"]("f_mini-fiches");var b=0,c;for(c in a)if(!isNaN(c)&&(b++,!a[c].valid))return Notification.warning("Attention","La fiche rapide "+b+" est incompl\u00e8te et/ou incorrecte"),
-!1;a=lsi["export"]("f_fiches");for(c in a)if(!a[c].valid)return Notification.warning("Attention","La fiche compl\u00e8te "+(parseInt(c)+1)+" est incompl\u00e8te et/ou incorrecte"),!1;c={path:"input/facebook",subject:lsi["export"]("f_subject")[0],contacts:lsi["export"]("f_contacts"),mini:lsi["export"]("f_mini-fiches"),fiches:lsi["export"]("f_fiches"),matrice:lsi["export"]("f_matrice")[0]};api.send(c,function(a){console.log(a);if(0!=a.ModuleError)return Notification.error("ERREUR",a.ModuleError),
+fFicheManager.attach(fDynamicUpdate);fMatriceManager=new inputFacebookMatrice($('[data-sublink="facebook"] article.matrice-panel'));fMatriceManager.attach(fDynamicUpdate);$('[data-sublink="facebook"] #f_clear-all').addEventListener("click",function(b){lsi.clear("f_subject");lsi.clear("f_contacts");lsi.clear("f_mini-fiches");lsi.clear("f_fiches");lsi.clear("f_matrice");fSubjectManager.storageToFields();fContactManager.storageToFields();fMiniManager.storageToFields();fFicheManager.storageToFields();
+fMatriceManager.storageToFields();Notification.success("OK","Les donn\u00e9es ont \u00e9t\u00e9 supprim\u00e9es")},!1);$('[data-sublink="facebook"] #f_export-all').addEventListener("click",function(b){Notification.info("INFORMATION","Lancement du t\u00e9l\u00e9chargement de la sauvegarde");b={subject:lsi["export"]("f_subject")[0],contacts:lsi["export"]("f_contacts"),mini:lsi["export"]("f_mini-fiches"),fiches:lsi["export"]("f_fiches"),matrice:lsi["export"]("f_matrice")[0]};var a=$('[data-sublink="facebook"] #f_download-target');
+a.download="local-facebook-data.json";a.href="data:application/octet-stream,"+encodeURIComponent(JSON.stringify(b));a.click()},!1);$('[data-sublink="facebook"] #f_import-all').addEventListener("click",function(b){$('[data-sublink="facebook"] #f_local-upload').click()},!1);$('[data-sublink="facebook"] #f_local-upload').addEventListener("click",function(b){b.target.value=null},!1);$('[data-sublink="facebook"] #f_local-upload').addEventListener("change",function(b){b={path:"upload/local_data",file:$('[data-sublink="facebook"] #f_local-upload').files[0]};
+api.send(b,function(a){console.log(a);if(0!=a.ModuleError)return Notification.error("Erreur",a.ModuleError),!1;lsi.set("f_subject",0,a.local_data.subject);lsi["import"]("f_contacts",a.local_data.contacts);lsi["import"]("f_mini-fiches",a.local_data.mini);lsi["import"]("f_fiches",a.local_data.fiches);lsi.set("f_matrice",0,a.local_data.matrice);fSubjectManager.storageToFields();fContactManager.storageToFields();fMatriceManager.storageToFields();fDynamicUpdate(!0)})},!1);$('[data-sublink="facebook"] #f_submit-all').addEventListener("click",
+function(b){console.log("> GATHERING ALL DATA");fSubjectManager.fieldsToStorage();fContactManager.fieldsToStorage();fMiniManager.fieldsToStorage();fFicheManager.fieldsToStorage();if(!fSubjectManager.check())return Notification.warning("Attention","Vous devez saisir les informations du sujet"),!1;b=lsi["export"]("f_mini-fiches");var a=0,d;for(d in b)if(!isNaN(d)&&(a++,!b[d].valid))return Notification.warning("Attention","La fiche rapide "+a+" est incompl\u00e8te et/ou incorrecte"),
+!1;b=lsi["export"]("f_fiches");for(d in b)if(!b[d].valid)return Notification.warning("Attention","La fiche compl\u00e8te "+(parseInt(d)+1)+" est incompl\u00e8te et/ou incorrecte"),!1;d={path:"input/facebook",subject:lsi["export"]("f_subject")[0],contacts:lsi["export"]("f_contacts"),mini:lsi["export"]("f_mini-fiches"),fiches:lsi["export"]("f_fiches"),matrice:lsi["export"]("f_matrice")[0]};api.send(d,function(a){console.log(a);if(0!=a.ModuleError)return Notification.error("ERREUR",a.ModuleError),
!1;console.log(a)},!1)},!1)})})})})});
diff --git a/view/js/input.js b/view/js/input.js
index 983b479..c5c2bd6 100644
--- a/view/js/input.js
+++ b/view/js/input.js
@@ -78,7 +78,8 @@ include('/js/includes/input-phone-subject-min.js', function(){
include('/js/includes/input-phone-contact-min.js', function(){
include('/js/includes/input-phone-mini-min.js', function(){
include('/js/includes/input-phone-fiche-min.js', function(){
-include('/js/includes/input-phone-matrice-min.js', function(){
+ // TODO: Use 'min' version
+include('/js/includes/input-phone-matrice.js', function(){
/* (1) Gestion du formulaire du sujet
@@ -146,6 +147,12 @@ include('/js/includes/input-phone-matrice-min.js', function(){
pMatriceManager.attach(cDynamicUpdate);
+ // Listener pour snake
+ var smgr = new ShortcutManager();
+ smgr.append('s+n+a+k+e', function(){ pMatriceManager.snake(); });
+ smgr.listen();
+
+