Explorar el Código

Atualizando para versão mais recente a partir do site

Lucas de Souza hace 5 años
padre
commit
cc5a8ba4e8
Se han modificado 67 ficheros con 34122 adiciones y 28057 borrados
  1. 95 92
      css/style.css
  2. 19 11
      download.html
  3. 1 1
      ex_pt/exerc/exemplo_4_media_aritmetica.ivph
  4. 1 1
      ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0.ivph
  5. 337 326
      ex_pt/index.html
  6. 418 72
      ex_pt/index.html~
  7. BIN
      img/background-panel.png
  8. 11 2
      index.html
  9. 89 15
      index.html~
  10. 31883 26278
      ivprogh/build/ivprog.bundle.js
  11. 1 1
      ivprogh/build/ivprog.bundle.js.map
  12. 28 16
      ivprogh/css/ivprog-visual-1.0.css
  13. 4 0
      ivprogh/exemplos/exemplo_fatorial.ivph
  14. 0 35
      ivprogh/i18n/en/error.json
  15. 0 9
      ivprogh/i18n/en/index.js
  16. 0 3
      ivprogh/i18n/en/message.json
  17. 0 135
      ivprogh/i18n/en/ui.json
  18. 0 3
      ivprogh/i18n/es/error.json
  19. 0 9
      ivprogh/i18n/es/index.js
  20. 0 3
      ivprogh/i18n/es/message.json
  21. 0 140
      ivprogh/i18n/es/ui.json
  22. 0 117
      ivprogh/i18n/i18n-database.json
  23. 0 9
      ivprogh/i18n/index.js
  24. 0 85
      ivprogh/i18n/pt/error.json
  25. 0 9
      ivprogh/i18n/pt/index.js
  26. 0 3
      ivprogh/i18n/pt/message.json
  27. 0 142
      ivprogh/i18n/pt/ui.json
  28. BIN
      ivprogh/img/background-panel.png
  29. 49 15
      ivprogh/js/assessment/ivprogAssessment.js
  30. 3 1
      ivprogh/js/ast/error/syntaxErrorFactory.js
  31. 1 1
      ivprogh/js/ast/expressions/stringLiteral.js
  32. 12 3
      ivprogh/js/ast/ivprogParser.js
  33. 342 339
      ivprogh/js/iassign-integration-functions.js
  34. 2 1
      ivprogh/js/io/domConsole.js
  35. 9 2
      ivprogh/js/main.js
  36. 8 6
      ivprogh/js/processor/compatibilityTable.js
  37. 38 54
      ivprogh/js/processor/error/processorErrorFactory.js
  38. 9 10
      ivprogh/js/processor/ivprogProcessor.js
  39. 1 1
      ivprogh/js/processor/lib/io.js
  40. 25 14
      ivprogh/js/processor/lib/lang.js
  41. 2 1
      ivprogh/js/processor/lib/math.js
  42. 3 4
      ivprogh/js/processor/semantic/semanticAnalyser.js
  43. 3 3
      ivprogh/js/processor/store/store.js
  44. 43 2
      ivprogh/js/services/localizedStringsService.js
  45. 1 1
      ivprogh/js/typeSystem/parsers.js
  46. 1 1
      ivprogh/js/util/config.js
  47. 2 1
      ivprogh/js/util/inputTest.js
  48. 6 1
      ivprogh/js/visualUI/algorithm.js
  49. 258 30
      ivprogh/js/visualUI/commands.js
  50. 3 1
      ivprogh/js/visualUI/commands/attribution.js
  51. 3 1
      ivprogh/js/visualUI/commands/break.js
  52. 3 1
      ivprogh/js/visualUI/commands/comment.js
  53. 0 5
      ivprogh/js/visualUI/commands/contextualized_menu.js
  54. 6 3
      ivprogh/js/visualUI/commands/dowhiletrue.js
  55. 3 1
      ivprogh/js/visualUI/commands/functioncall.js
  56. 4 1
      ivprogh/js/visualUI/commands/iftrue.js
  57. 3 1
      ivprogh/js/visualUI/commands/reader.js
  58. 6 3
      ivprogh/js/visualUI/commands/repeatNtimes.js
  59. 4 1
      ivprogh/js/visualUI/commands/return.js
  60. 3 1
      ivprogh/js/visualUI/commands/switch.js
  61. 6 3
      ivprogh/js/visualUI/commands/whiletrue.js
  62. 3 1
      ivprogh/js/visualUI/commands/writer.js
  63. 345 25
      ivprogh/js/visualUI/functions.js
  64. 5 0
      ivprogh/js/visualUI/globals.js
  65. 4 0
      ivprogh/js/visualUI/variables.js
  66. 3 0
      legacy/version2/index.html
  67. 13 1
      legacy/version2/index.html~

+ 95 - 92
css/style.css

@@ -1,170 +1,173 @@
 .ivprog-container {
-	-webkit-box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
--moz-box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
-box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
-border-radius: 4px;
-padding-top: 0.3rem;
+  -webkit-box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
+  -moz-box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
+  box-shadow: 0px 0px 31px -5px rgba(0,0,0,0.75);
+  border-radius: 4px; padding-top: 0.3rem;
 }
 footer.container {
-	margin-top: 1%;
+  margin-top: 1%;
 }
 .jumbotron.ivprogh-desc {
-	padding-bottom: 0.5rem;
-	margin-bottom: 1rem;
+  padding-bottom: 0.5rem;
+  margin-bottom: 1rem;
 }
 .text-reduced {
-	font-size: 96%;
-	margin-bottom: 0.5rem;
+  font-size: 96%;
+  margin-bottom: 0.5rem;
 }
 h1 {
-	margin-bottom: 0;
+  margin-bottom: 0;
 }
 .col-md-3.item {
-	padding: 1em;
-    background: #007bff;
-    color: white;
-    margin: 1em;
-    border-radius: .5em;
-    text-align: center;
-    border: 1px groove;
-    cursor: pointer;
+  padding: 1em; background: #007bff; color: white;
+  margin: 1em; border-radius: .5em; text-align: center; 
+  border: 1px groove; cursor: pointer;
 } 
 .col-md-3.item .octicon {
-	font-size: 3em;
+  font-size: 2em;
 }
 .col-md-3.item h4 {
-	font-size: 1.4em;
-	margin-top: 0.6em;
+  font-size: 1.4em;
+  margin-top: 0.6em;
 }
 .row.thumbs-ivprog {
-	margin-top: 1em;
+  margin-top: 1em;
 }
 .row.thumbs-ivprog-download .item {
-	background-color: #5a6570;
-	border: 2px groove;
+  background-color: #5a6570;
+  border: 2px groove;
 }
 .col-md-3.item:hover {
-    background-color: #03396c;
+  background-color: #03396c;
 }
 .col-md-3.item hr {
-    background: white;
+  background: white;
+}
+.col-md-3.item a {
+  color: white;
 }
 .btn.btn-primary .octicon {
-	font-size: 1.5em;
-	margin-right: 0.5em;
+  font-size: 1.5em;
+  margin-right: 0.5em;
 }
 .download-ivprog {
-    font-size: 1.3em;
+  font-size: 1.3em;
 }
 .div-button {
-	text-align: center;
-	padding-top: 2.5em;
+  text-align: center;
+  padding-top: 2.5em;
 }
 .div-button .span-version {
-	display: block;
-	font-size: 98%;
+  display: block;
+  font-size: 98%;
 }
 .my-4 .octicon-history {
-	font-size: 1em;
+  font-size: 1em;
 }
 .row.thumbs-ivprog-download {
-    padding-bottom: 3em;
+  padding-bottom: 3em;
 }
 
 .history-ivprog-version {
-	display: block;
-	font-size: 1em;
-	font-weight: bold;
-	margin-top: -.5em;
-	margin-bottom: .5em;
+  display: block;
+  font-size: 1em;
+  font-weight: bold;
+  margin-top: -.5em;
+  margin-bottom: .5em;
 }
 .history-ivprog-time {
-    background-color: gray;
-    padding: .4em;
-    border-radius: .4em;
+  background-color: gray;
+  padding: .4em;
+  border-radius: .4em;
 }
 footer.container {
-	margin-bottom: 1em;
+  margin-bottom: 1em;
 }
 .example-large-div {
-	background-color: #0bbf4a;
-	border-radius: .8em;
-	margin-top: 0.5em;
+  background-color: #0bbf4a;
+  border-radius: .8em;
+  margin-top: 0.5em;
 }
 
 .example-large-div .container .embed-responsive {
-	border-radius: .5em;
-	margin-top: 1em;
+  border-radius: .5em;
+  margin-top: 1em;
 }
 
 .text-count-example {
-	font-size: 1.5em;
-    color: white;
-    text-shadow: 2px 2px gray;
-    font-weight: 600;
-    margin-bottom: .3em;
-    padding-top: .3em;
-    padding-bottom: .2em;
-    cursor: pointer;
+  font-size: 1.5em;
+  color: white;
+  text-shadow: 2px 2px gray;
+  font-weight: 600;
+  margin-bottom: .3em;
+  padding-top: .3em;
+  padding-bottom: .2em;
+  cursor: pointer;
 }
 .example-large-div .text-reduced {
-	color: #06065a;
-    font-size: 1.1em;
-    text-indent: 1em;
+  color: #06065a;
+  font-size: 1.1em;
+  text-indent: 1em;
 }
 .text-count-example .octicon {
-	text-shadow: none;
-    font-weight: normal;
-    font-size: .9em;
-    margin-right: .1em;
+  text-shadow: none;
+  font-weight: normal;
+  font-size: .9em;
+  margin-right: .1em;
 }
 .container.text-center .btn {
-	margin: .5em;
+  margin: .5em;
 }
 .container.example-large-div.autoeval-descript {
-	background-color: #538564;
-    color: white;
-    padding: .2em;
-    padding-left: 1em;
-    font-size: 1.1em;
-    border-radius: .3em;
+  background-color: #538564;
+  color: white;
+  padding: .2em;
+  padding-left: 1em;
+  font-size: 1.1em;
+  border-radius: .3em;
 }
 .container.example-large-div.autoeval-descript .pointer {
-	cursor:pointer;
+  cursor:pointer;
 }
 .container.example-large-div.autoeval-descript span {
-	font-size: 1.2em;
-	margin-right: .2em;
+  font-size: 1.2em;
+  margin-right: .2em;
 }
 #area-autoeval-descript {
-	padding-left: 2em;
-    padding-top: 1em;
-    padding-right: 2em;
-    padding-bottom: 1em;
+  padding-left: 2em;
+  padding-top: 1em;
+  padding-right: 2em;
+  padding-bottom: 1em;
 }
 button.btn.btn-primary.show-solution {
-    float: right;
-    margin-right: 1em;
+  float: right;
+  margin-right: 1em;
 }
 .ivprogh-title-download {
-	color: #03396c;
+  color: #03396c;
 }
 .ivprogh-title-download .octicon {
-	font-size: 1em;
+  font-size: 1em;
 }
 .table.about-auto-eval {
-	border: 2px solid white;
+  border: 2px solid white;
 }
 .box-download {
-	background: #efefef;
-    border-radius: .5em;
+  background: #efefef;
+  border-radius: .5em;
 }
 .distinct-container {
-	margin-top: 2em;
-	margin-bottom: 2em;
+  margin-top: 2em;
+  margin-bottom: 2em;
 }
 .zoom-images {
-	width: 10em;
-	cursor: zoom-in;
-	height: 5.5em !important;
-}
+  width: 10em;
+  cursor: zoom-in;
+  height: 5.5em !important;
+}
+ul.col_download {
+  margin-left:4px; padding:0; list-style:square;
+  }
+li.col_download {
+  display:inline-block; text-align:left;font-size: 0.9em;
+  }

+ 19 - 11
download.html

@@ -73,24 +73,32 @@
       <div class="row">
 
         <div class="col-md-8">
-          <figure>
+          <div class="fig"><figure>
           <img class="img-fluid" src="./img/img_ivprogh_download_page.png" alt="Imagem da interface do usuário do iVProgH em sua versão mais atual.">
-            <figcaption align="center">iVProgH versão atual</figcaption>
-          </figure>
+            <figcaption align="center">Fig. imagem estática do <i>iVProgH</i> com instruções para entrada e para saída em sua versão atual</figcaption>
+          </figure></div>
         </div>
 
         <div class="col-md-4 box-download">
           <h4 class="my-4 ivprogh-title-download"> <span class="octicon octicon-desktop-download"></span> Descarregar o iVProgH</h4>
           
-          <li>Totalmente gratuito e código livre</li>
-          <li>Inclui avaliador automático</li>
-          <li>Possui recursos para vetores e funções</li>
-          <li>Disponibiliza uma série de funções já desenvolvidas</li>
-          <li>Só precisa de um navegador para funcionar!</li>
-          
+          <ul class="col_download">
+            <li>Ambiente para ensino/aprendizagem gratuito e de código livre;</li>
+            <li>Inclui avaliador automático;</li>
+            <li>Possui recursos para vetores, funções e recursividade;</li>
+            <li>Disponibiliza funções pré-definidas (como as matemáticas para seno e cosseno)</li>
+            <li>Pode descarregar apenas o <i>iVProgH</i> ou ele e todas esse conjunto de páginas;</li>
+            <li>Só precisa de um navegador para funcionar!</li>
+          </ul>
+
           <div class="div-button">
-            <a class="btn btn-primary download-ivprog" href="versions/ivprogh_stable.tar.gz" role="button" title=""> <span class="octicon octicon-desktop-download"></span> Download</a>
-            <span class="span-version">Atualização 2019/01/12</span>
+            <a class="btn btn-primary download-ivprog" href="versions/www-ivprog_2019_03_11.tgz" role="button" title="descarregar o iVProgH e todo esse tutorial">
+	       <span class="octicon octicon-desktop-download"></span>Download tudo</a>
+	    <br/>&nbsp;<br/>
+            <a class="btn btn-primary download-ivprog" href="versions/ivprog_2019_03_11.tgz" role="button" title="descarregar apenas o iVProgH">
+	       <span class="octicon octicon-desktop-download"></span>Apenas iVProgH</a>
+            <!--span class="span-version">Atualização 2019/01/12</span-->
+            <span class="span-version">Atualização 2019/03/11</span>
           </div>
         </div>
       </div>

+ 1 - 1
ex_pt/exerc/exemplo_4_media_aritmetica.ivph

@@ -1,4 +1,4 @@
- {  
+{  
  "testcases" : [ 
 { 
  "input": ["10", "20"], 

+ 1 - 1
ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0.ivph

@@ -1,4 +1,4 @@
- {  
+{  
  "testcases" : [ 
 { 
  "input": ["3", "4", "0"], 

+ 337 - 326
ex_pt/index.html

@@ -20,47 +20,50 @@
   var evaluationResult = '';
   var comment = '';
 
-  function submit_iMA_Answer () {
+  function submit_iMA_Answer (index) {
     // alert('./ex_pt/index.html: window.frames=' + window.frames);
     // alert('./ex_pt/index.html: window.frames.iLM=' + window.frames.iLM);
-    /* DEBUG
-    var strFrames = "";
-    var arrFrames = parent.document.getElementsByTagName("IFRAME");
-    for (var i=0; i<arrFrames.length; i++) {
-      strFrames += ', ' + arrFrames[i].name; // if (arrFrames[i].contentWindow === window) alert("yay!");
-      } // acho 'window.frames' de nome 'iLM'!!!
-    alert('./ex_pt/index.html: window.frames=' + strFrames);
-    */
-    window.frames.iLM.getEvaluation(); // ../ivprogh/js/iassign-integration-functions.js
-    // window.frames.iLM.runCodeAssessment();
-    var strAnswer = window.frames.iLM.getAnswer();
-    alert('./ex_pt/index.html: getAnswer()=' + strAnswer);
-
-    /*
-    var docForm = document.formEnvio;
-    // Prepared to be used with more than 1 "applet'
-    var exercise_answer = new Array(3); // answer: to get the learner answer
-    var exercise_value = new Array(3);  // value from the iLM automatic evaluator
-    // var doc = document.formEnvio; // ----------------------------------------------------------
-    // var doc = javascript:window.jsAnalyseAnswer();
-    try {
-      alert('submit_iMA_Answer(): evaluationResult=' + evaluationResult);
-      exercise_answer[0] = doc.getAnswer();    // answer: it must be first (usually the iLM first get the answer to compute the evaluation grade)
-      exercise_value[0] = doc.getEvaluation(); // value from the iLM automatic evaluator
-    } catch (Exception) { alert("Error!"); }
-    docForm.iLM_POST_Archive_0.value = exercise_answer[0]; // Content coming from the iLM
-    docForm.iLM_POST_Value_0.value = exercise_value[0];    // The activity evaluation coming from the iLM
-    // This is used to help the developer to debug his iLM
-    // It presents the file content that will be registered. 
-    alert('The file activity value is: ' + exercise_value[0] + '\nThe activity content is:\n' + exercise_answer[0]);
-    //uncomment_this docForm.submit(); // envia de fato o formulario
-    //uncomment_this return true;
-    */
+
+    var name = 'iLM[' + index + ']'; // alert('name='+name);
+    window.frames[name].getEvaluation();
+    var strAnswer = window.frames[name].getAnswer();
+    alert('Copie o código ivph a seguir (para usá-lo com o iVProgH): ' + strAnswer);
+
+    //DEBUG
+    //D var strFrames = "";
+    //D var arrFrames = parent.document.getElementsByTagName("IFRAME");
+    //D for (var i=0; i<arrFrames.length; i++) {
+    //D   strFrames += ', ' + arrFrames[i].name; // if (arrFrames[i].contentWindow === window) alert("yay!");
+    //D   } // acho 'window.frames' de nome 'iLM'!!!
+    //D if (index<10)
+    //D alert('./ex_pt/index.html: window.frames=' + strFrames);
+
+    // alert('window.frames.iLM=' + window.frames.iLM); // undefined
+
+    //D var docForm = document.formEnvio;
+    //D // Prepared to be used with more than 1 "applet'
+    //D var exercise_answer = new Array(3); // answer: to get the learner answer
+    //D var exercise_value = new Array(3);  // value from the iLM automatic evaluator
+    //D // var doc = document.formEnvio; // ----------------------------------------------------------
+    //D // var doc = javascript:window.jsAnalyseAnswer();
+    //D try {
+    //D   alert('submit_iMA_Answer(): evaluationResult=' + evaluationResult);
+    //D   exercise_answer[0] = doc.getAnswer();    // answer: it must be first (usually the iLM first get the answer to compute the evaluation grade)
+    //D   exercise_value[0] = doc.getEvaluation(); // value from the iLM automatic evaluator
+    //D } catch (Exception) { alert("Error!"); }
+    //D docForm.iLM_POST_Archive_0.value = exercise_answer[0]; // Content coming from the iLM
+    //D docForm.iLM_POST_Value_0.value = exercise_value[0];    // The activity evaluation coming from the iLM
+    //D // This is used to help the developer to debug his iLM
+    //D // It presents the file content that will be registered. 
+    //D alert('The file activity value is: ' + exercise_value[0] + '\nThe activity content is:\n' + exercise_answer[0]);
+    //D //uncomment_this docForm.submit(); // envia de fato o formulario
+    //D //uncomment_this return true;
+
     }
 
   function getEvaluationCallback (evaluation) {
     evaluationResult = evaluation;
-    strAnswer = window.frames.iLM.getAnswer();
+    strAnswer = window.frames.iLM[index].getAnswer();
     alert('getEvaluationCallback(...)' + evaluation + ', strAnswer=' + strAnswer);
     comment = document.formEnvio.submission_comment.value;
     //leo
@@ -147,343 +150,351 @@
       </div>
 
       <div class="container example-large-div autoeval-descript">
-          <div data-toggle="collapse" class="pointer" href="#area-autoeval-descript" aria-expanded="false" aria-controls="area-autoeval-descript"><span class="octicon octicon-info"></span> Entenda o funcionamento do avaliador automático</div>
-          <div id="area-autoeval-descript" class="collapse">
-            <p>O iVProg permite a disponibilização de exercícios com avaliação automática diretamente em páginas Web.
-            Se o professor dispuser de uma instalação do gerenciador Moodle com o pacote <a href="www.matematica.br/ia">iTarefa</a>, então a atividade realizada pelo aluno será registrada, assim como a nota atribuida à solução do aluno.</p>
-
-            <p>A avaliação automática no iVProg é feita a partir de um modelo (gabarito), que deve ter sido preparado pelo professor,
-            prevendo entradas de dados e suas respectivas saídas. Quando o aluno "clicar" no botão para avaliar sua solução,
-            o iVProg usa a primeira lista como entradas para o problema do aluno, comparando cada saída gerada com aquelas da
-            lista de saídas.</p>
-
-            <p>Para compreender melhor o processo, vamos usar um exemplo de algoritmo que deve somar separadamente todos os números
-            positivos e negativos digitados pelo usuário.</p>
-
-            <p><span class="octicon octicon-pin"></span><b>Problema:</b></p>
-            
-            <p>Fazer um algoritmo que solicite que o usuário digite valores inteiros, finalizando sua execução quando for digitado
-            o valor zero. Ao final, seu programa deve imprimir a soma de todos os inteiros positivos que foram digitados e a seguir,  imprimir a soma de todos os inteiros negativos.</p>
-
-            <p><span class="octicon octicon-light-bulb"></span> <b> Como posso preparar um gabarito para exercício com avaliação automática no iVProg</b></p>
-
-            <p>O professor pode preparar um número qualquer de listas de entradas e de saídas, para o problema acima, usaremos apenas 3 listas,
-            ilustradas na tabela abaixo. A primeira coluna tem o numero do par "entradas/saidas", a segunda apresenta a lista de entradas
-            (separadas por espaço em branco), no terceira coluna estão as saídas esperadas (para aquelas entradas) e na última coluna uma
-            explicação curta sobre o par.
-
-            <table class="table about-auto-eval">
-              <thead class="thead-light">
-                <tr>
-                  <th scope="col">#</th>
-                  <th scope="col">Entradas</th>
-                  <th scope="col">Saídas</th>
-                  <th scope="col">Comentários</th>
-                </tr>
-              </thead>
-              <tbody>
-                <tr>
-                  <th scope="row">1</th>
-                  <td>0</td>
-                  <td>0 0</td>
-                  <td>Esse é um teste capcioso, pois se a primeira entrada for zero, nada será somado (daí deve-se imprimir 0 e 0)</td>
-                </tr>
-                <tr>
-                  <th scope="row">2</th>
-                  <td>1 -1 1 0</td>
-                  <td> 2 -1 </td>
-                  <td>Apresenta 2 valores positivos e 1 negativo, com somas respectivamente 2 e -1</td>
-                </tr>
-                <tr>
-                  <th scope="row">3</th>
-                  <td>-1 -1 3 1 0</td>
-                  <td>4 -2</td>
-                  <td>Apresenta 2 valores positivos e 2 negativo, com somas respectivamente 4 e -2</td>
-                </tr>
-              </tbody>
-            </table>
-
-            <p>O iVProg dispõe de uma interface especial para que o professor digite cada lista de entrada e sua respectiva lista de saídas.</p>
-
-            <p><span class="octicon octicon-light-bulb"></span> <b> Como o iVProg avalia automaticamente uma solução do aluno?</b></p>
-
-            <p>Supondo que o aluno tenha construído um algoritmo, quando ele "clicar" no botão para avaliar
-            sua solução, o iVProg:</p>
-
-            <ol>
-              <li>Pega a primeira entrada da primeira lista e submete ao primeiro de leitura presente no código do aluno (se não existir, erro), depois a segunda entrada e assim por diante até a última.</li>
-              <li>A primeira saída (comando de impressão) gerada pelo código do aluno é comparada com a primeira saída esperada, se coincidir
-                 é registrado um acerto, senão um erro.</li>
-              <li>Repete-se os passos 1 e 2 para cada uma das demais listas de entradas/saídas e ao final é gerada uma média de acertos e erros.
-                 <p>Por exemplo, se o algoritmo do aluno errar em 2 das 6 saídas, sua nota será 1/3.</p></li>
-            </ol>
-          </div>
+        <div data-toggle="collapse" class="pointer" href="#area-autoeval-descript" aria-expanded="false" aria-controls="area-autoeval-descript"><span class="octicon octicon-info"></span>
+	     Entenda o funcionamento do avaliador automático</div>
+        <div id="area-autoeval-descript" class="collapse">
+          <p>O iVProg permite a disponibilização de exercícios com avaliação automática diretamente em páginas Web.
+          Se o professor dispuser de uma instalação do gerenciador Moodle com o pacote <a href="www.matematica.br/ia">iTarefa</a>, então a atividade realizada pelo aluno será registrada, assim como a nota atribuida à solução do aluno.</p>
+
+          <p>A avaliação automática no iVProg é feita a partir de um modelo (gabarito), que deve ter sido preparado pelo professor,
+          prevendo entradas de dados e suas respectivas saídas. Quando o aluno "clicar" no botão para avaliar sua solução,
+          o iVProg usa a primeira lista como entradas para o problema do aluno, comparando cada saída gerada com aquelas da
+          lista de saídas.</p>
+
+          <p>Para compreender melhor o processo, vamos usar um exemplo de algoritmo que deve somar separadamente todos os números
+          positivos e negativos digitados pelo usuário.</p>
+
+          <p><span class="octicon octicon-pin"></span><b>Problema:</b></p>
+          
+          <p>Fazer um algoritmo que solicite que o usuário digite valores inteiros, finalizando sua execução quando for digitado
+          o valor zero. Ao final, seu programa deve imprimir a soma de todos os inteiros positivos que foram digitados e a seguir,  imprimir a soma de todos os inteiros negativos.</p>
+
+          <p><span class="octicon octicon-light-bulb"></span> <b> Como posso preparar um gabarito para exercício com avaliação automática no iVProg</b></p>
+
+          <p>O professor pode preparar um número qualquer de listas de entradas e de saídas, para o problema acima, usaremos apenas 3 listas,
+          ilustradas na tabela abaixo. A primeira coluna tem o numero do par "entradas/saidas", a segunda apresenta a lista de entradas
+          (separadas por espaço em branco), no terceira coluna estão as saídas esperadas (para aquelas entradas) e na última coluna uma
+          explicação curta sobre o par.
+
+          <table class="table about-auto-eval">
+            <thead class="thead-light">
+              <tr>
+                <th scope="col">#</th>
+                <th scope="col">Entradas</th>
+                <th scope="col">Saídas</th>
+                <th scope="col">Comentários</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr>
+                <th scope="row">1</th>
+                <td>0</td>
+                <td>0 0</td>
+                <td>Esse é um teste capcioso, pois se a primeira entrada for zero, nada será somado (daí deve-se imprimir 0 e 0)</td>
+              </tr>
+              <tr>
+                <th scope="row">2</th>
+                <td>1 -1 1 0</td>
+                <td> 2 -1 </td>
+                <td>Apresenta 2 valores positivos e 1 negativo, com somas respectivamente 2 e -1</td>
+              </tr>
+              <tr>
+                <th scope="row">3</th>
+                <td>-1 -1 3 1 0</td>
+                <td>4 -2</td>
+                <td>Apresenta 2 valores positivos e 2 negativo, com somas respectivamente 4 e -2</td>
+              </tr>
+            </tbody>
+          </table>
+
+          <p>O iVProg dispõe de uma interface especial para que o professor digite cada lista de entrada e sua respectiva lista de saídas.</p>
+
+          <p><span class="octicon octicon-light-bulb"></span> <b> Como o iVProg avalia automaticamente uma solução do aluno?</b></p>
+
+          <p>Supondo que o aluno tenha construído um algoritmo, quando ele "clicar" no botão para avaliar
+          sua solução, o iVProg:</p>
+
+          <ol>
+            <li>Pega a primeira entrada da primeira lista e submete ao primeiro de leitura presente no código do aluno (se não existir, erro), depois a segunda entrada e assim por diante até a última.</li>
+            <li>A primeira saída (comando de impressão) gerada pelo código do aluno é comparada com a primeira saída esperada, se coincidir
+               é registrado um acerto, senão um erro.</li>
+            <li>Repete-se os passos 1 e 2 para cada uma das demais listas de entradas/saídas e ao final é gerada uma média de acertos e erros.
+               <p>Por exemplo, se o algoritmo do aluno errar em 2 das 6 saídas, sua nota será 1/3.</p></li>
+          </ol>
+        </div>
+      </div>
+
+      <div class="container example-large-div autoeval-descript">
+        <div aria-expanded="false" aria-controls="area-autoeval-descript">
+             Experimente os exercícios listados abaixo, de exemplo 1 até exemplo 8.
+             O exemplo 9 ilustra como construir um gabarito para um exercício com avaliação automática no <i>iVProgH</i>.<br/>
+             Para abrir o exemplo, "clique" sobre seu título. Você pode ocultá-lo novamente "clicando" sobre o mesmo título.
+        </div>
       </div>
 
       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-1" aria-expanded="false" aria-controls="area-exemplo-1"><span class="octicon octicon-rocket"></span> Exemplo 1: Entrada e Saída</div>
-          <div class="example-content collapse" id="area-exemplo-1">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_1_ler_e_imprimir_inteiro_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Faça um programa que solicite do usuário um valor inteiro, depois imprima o valor por ele digitado.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_1_ler_e_imprimir_inteiro.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-1" aria-expanded="false" aria-controls="area-exemplo-1"><span class="octicon octicon-rocket"></span>
+            Exemplo 1: Entrada e Saída</div>
+        <div class="example-content collapse" id="area-exemplo-1">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_1_ler_e_imprimir_inteiro_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Faça um programa que solicite do usuário um valor inteiro, depois imprima o valor por ele digitado.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[1]" id="iLM[1]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_1_ler_e_imprimir_inteiro.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(1);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-2" aria-expanded="false" aria-controls="area-exemplo-2"><span class="octicon octicon-rocket"></span> Exemplo 2: Quadrado de um número</div>
-          <div class="example-content collapse" id="area-exemplo-2">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_2_imprimir_quadrado_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Construa um algoritmo que recebe um número inteiro e imprime o quadrado desse valor.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_2_imprimir_quadrado.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-2" aria-expanded="false" aria-controls="area-exemplo-2"><span class="octicon octicon-rocket"></span>
+            Exemplo 2: Imprimir o quadrado de um número (inteiro)</div>
+        <div class="example-content collapse" id="area-exemplo-2">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_2_imprimir_quadrado_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que solicite que o usuário digite um número (inteiro) e imprime o quadrado desse valor.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[2]" id="iLM[2]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_2_imprimir_quadrado.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(2);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
 
        <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-3" aria-expanded="false" aria-controls="area-exemplo-3"><span class="octicon octicon-rocket"></span> Exemplo 3: Soma de dois valores</div>
-          <div class="example-content collapse" id="area-exemplo-3">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_3_soma_dois_valores_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Construa um algoritmo que recebe dois números inteiros e imprime a soma desses valores.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_3_soma_dois_valores.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-3" aria-expanded="false" aria-controls="area-exemplo-3"><span class="octicon octicon-rocket"></span>
+            Exemplo 3: Soma de dois valores</div>
+        <div class="example-content collapse" id="area-exemplo-3">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_3_soma_dois_valores_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que recebe dois números inteiros e imprime a soma desses valores.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[3]" id="iLM[3]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_3_soma_dois_valores.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(3);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-4" aria-expanded="false" aria-controls="area-exemplo-4"><span class="octicon octicon-rocket"></span> Exemplo 4: Média aritmética</div>
-          <div class="example-content collapse" id="area-exemplo-4">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_4_media_aritmetica_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Construa um algoritmo que recebe dois números inteiros da entrada, calcula a média aritmética desses números e a imprima.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_4_media_aritmetica.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-4" aria-expanded="false" aria-controls="area-exemplo-4"><span class="octicon octicon-rocket"></span>
+            Exemplo 4: Média aritmética</div>
+        <div class="example-content collapse" id="area-exemplo-4">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_4_media_aritmetica_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que recebe dois números inteiros da entrada, calcula a média aritmética desses números e a imprima.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[4]" id="iLM[4]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_4_media_aritmetica.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(4);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
        <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-5" aria-expanded="false" aria-controls="area-exemplo-5"><span class="octicon octicon-rocket"></span> Exemplo 5: Maior valor</div>
-          <div class="example-content collapse" id="area-exemplo-5">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_5_maior_valor_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Construa um algoritmo que recebe dois números inteiros da entrada e imprime o maior dentre os dois números.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_5_maior_valor.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-5" aria-expanded="false" aria-controls="area-exemplo-5"><span class="octicon octicon-rocket"></span>
+            Exemplo 5: Maior valor</div>
+        <div class="example-content collapse" id="area-exemplo-5">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_5_maior_valor_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que recebe dois números inteiros da entrada e imprime o maior dentre os dois números.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[5]" id="iLM[5]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_5_maior_valor.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(5);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-6" aria-expanded="false" aria-controls="area-exemplo-6"><span class="octicon octicon-rocket"></span> Exemplo 6: Sequência</div>
-          <div class="example-content collapse" id="area-exemplo-6">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_6_imprimir_de_1_a_10_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Construa um algoritmo que imprima a sequência de números inteiros de 1 a 10.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_6_imprimir_de_1_a_10.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-6" aria-expanded="false" aria-controls="area-exemplo-6"><span class="octicon octicon-rocket"></span>
+            Exemplo 6: Sequência</div>
+        <div class="example-content collapse" id="area-exemplo-6">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_6_imprimir_de_1_a_10_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que imprima a sequência de números inteiros de 1 a 10.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[6]" id="iLM[6]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_6_imprimir_de_1_a_10.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(6);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-7" aria-expanded="false" aria-controls="area-exemplo-7"><span class="octicon octicon-rocket"></span> Exemplo 7: Imprimir texto</div>
-          <div class="example-content collapse" id="area-exemplo-7">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_7_imprimir_ivprogh_10_vezes_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Construa um algoritmo que imprima a palavra iVProgH 10 vezes.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_7_imprimir_ivprogh_10_vezes.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-7" aria-expanded="false" aria-controls="area-exemplo-7"><span class="octicon octicon-rocket"></span>
+            Exemplo 7: Imprimir texto</div>
+        <div class="example-content collapse" id="area-exemplo-7">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_7_imprimir_ivprogh_10_vezes_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que imprima a palavra iVProgH 10 vezes.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[7]" id="iLM[7]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_7_imprimir_ivprogh_10_vezes.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(7);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-8" aria-expanded="false" aria-controls="area-exemplo-8"><span class="octicon octicon-rocket"></span> Exemplo 8: Somar n valores</div>
-          <div class="example-content collapse" id="area-exemplo-8">
-            <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0_solucao.ivph', this)">Ver solução</button>
-            <p class="text-reduced">
-              Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
-            </p>
-            
-            <p class="text-reduced">
-              <b>Fazer um algoritmo que lê uma sequência de números inteiros, somando-os até que um valor 0 seja digitado, nesse momento deve imprimir o valor da soma e parar.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-8" aria-expanded="false" aria-controls="area-exemplo-8"><span class="octicon octicon-rocket"></span>
+            Exemplo 8: Somar n valores</div>
+        <div class="example-content collapse" id="area-exemplo-8">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Fazer um algoritmo que lê uma sequência de números inteiros, somando-os até que um valor 0 seja digitado, nesse momento deve imprimir o valor da soma e parar.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#'\ \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[8]" id="iLM[8]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(8);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
       <div class="container example-large-div">
-          <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-9" aria-expanded="false" aria-controls="area-exemplo-9"><span class="octicon octicon-rocket"></span> Gabarito: Construindo uma atividade</div>
-          <div class="example-content collapse" id="area-exemplo-9">
-            <p class="text-reduced">
-              <b>Nesse exemplo, construa uma atividade, inserindo os casos de teste que serão utilizados para avaliar o algoritmo e configure os recursos que serão disponibilizados para o aluno no iVProgH.</b>
-            </p>
-
-            <div class="container text-center">
-              <form name='formEnvio' id='formEnvio' method='post' \
-                      action='#'\
-                      enctype='multipart/form-data'>
-                <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-                  <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                          src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_SendAnswer=true&lang=pt"
-                          allowfullscreen></iframe><br/>
-                </div>
-                 <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
-                         title='Clique aqui para visualizar seu código.'
-                         onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-              </form>
-            </div>
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-9" aria-expanded="false" aria-controls="area-exemplo-9"><span class="octicon octicon-rocket"></span> Gabarito: Construindo uma atividade</div>
+        <div class="example-content collapse" id="area-exemplo-9">
+          <p class="text-reduced">
+            <b>Nesse exemplo, construa uma atividade, inserindo os casos de teste que serão utilizados para avaliar o algoritmo e configure os recursos que serão disponibilizados para o aluno no iVProgH.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#'\ \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[9]" id="iLM[9]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_SendAnswer=true&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                      title='Clique aqui para visualizar seu código.'
+                      onclick='javascript:window.submit_iMA_Answer(9);' /><!-- chama funcao iMA-->
+            </form>
           </div>
+        </div>
       </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
     </main>

+ 418 - 72
ex_pt/index.html~

@@ -20,47 +20,50 @@
   var evaluationResult = '';
   var comment = '';
 
-  function submit_iMA_Answer () {
+  function submit_iMA_Answer (index) {
     // alert('./ex_pt/index.html: window.frames=' + window.frames);
     // alert('./ex_pt/index.html: window.frames.iLM=' + window.frames.iLM);
-    /* DEBUG
-    var strFrames = "";
-    var arrFrames = parent.document.getElementsByTagName("IFRAME");
-    for (var i=0; i<arrFrames.length; i++) {
-      strFrames += ', ' + arrFrames[i].name; // if (arrFrames[i].contentWindow === window) alert("yay!");
-      } // acho 'window.frames' de nome 'iLM'!!!
-    alert('./ex_pt/index.html: window.frames=' + strFrames);
-    */
-    window.frames.iLM.getEvaluation(); // ../ivprogh/js/iassign-integration-functions.js
-    // window.frames.iLM.runCodeAssessment();
-    var strAnswer = window.frames.iLM.getAnswer();
-    alert('./ex_pt/index.html: getAnswer()=' + strAnswer);
-
-    /*
-    var docForm = document.formEnvio;
-    // Prepared to be used with more than 1 "applet'
-    var exercise_answer = new Array(3); // answer: to get the learner answer
-    var exercise_value = new Array(3);  // value from the iLM automatic evaluator
-    // var doc = document.formEnvio; // ----------------------------------------------------------
-    // var doc = javascript:window.jsAnalyseAnswer();
-    try {
-      alert('submit_iMA_Answer(): evaluationResult=' + evaluationResult);
-      exercise_answer[0] = doc.getAnswer();    // answer: it must be first (usually the iLM first get the answer to compute the evaluation grade)
-      exercise_value[0] = doc.getEvaluation(); // value from the iLM automatic evaluator
-    } catch (Exception) { alert("Error!"); }
-    docForm.iLM_POST_Archive_0.value = exercise_answer[0]; // Content coming from the iLM
-    docForm.iLM_POST_Value_0.value = exercise_value[0];    // The activity evaluation coming from the iLM
-    // This is used to help the developer to debug his iLM
-    // It presents the file content that will be registered. 
-    alert('The file activity value is: ' + exercise_value[0] + '\nThe activity content is:\n' + exercise_answer[0]);
-    //uncomment_this docForm.submit(); // envia de fato o formulario
-    //uncomment_this return true;
-    */
+
+    var name = 'iLM[' + index + ']'; // alert('name='+name);
+    window.frames[name].getEvaluation();
+    var strAnswer = window.frames[name].getAnswer();
+    alert('Copie o código ivph a seguir (para usá-lo com o iVProgH): ' + strAnswer);
+
+    //DEBUG
+    //D var strFrames = "";
+    //D var arrFrames = parent.document.getElementsByTagName("IFRAME");
+    //D for (var i=0; i<arrFrames.length; i++) {
+    //D   strFrames += ', ' + arrFrames[i].name; // if (arrFrames[i].contentWindow === window) alert("yay!");
+    //D   } // acho 'window.frames' de nome 'iLM'!!!
+    //D if (index<10)
+    //D alert('./ex_pt/index.html: window.frames=' + strFrames);
+
+    // alert('window.frames.iLM=' + window.frames.iLM); // undefined
+
+    //D var docForm = document.formEnvio;
+    //D // Prepared to be used with more than 1 "applet'
+    //D var exercise_answer = new Array(3); // answer: to get the learner answer
+    //D var exercise_value = new Array(3);  // value from the iLM automatic evaluator
+    //D // var doc = document.formEnvio; // ----------------------------------------------------------
+    //D // var doc = javascript:window.jsAnalyseAnswer();
+    //D try {
+    //D   alert('submit_iMA_Answer(): evaluationResult=' + evaluationResult);
+    //D   exercise_answer[0] = doc.getAnswer();    // answer: it must be first (usually the iLM first get the answer to compute the evaluation grade)
+    //D   exercise_value[0] = doc.getEvaluation(); // value from the iLM automatic evaluator
+    //D } catch (Exception) { alert("Error!"); }
+    //D docForm.iLM_POST_Archive_0.value = exercise_answer[0]; // Content coming from the iLM
+    //D docForm.iLM_POST_Value_0.value = exercise_value[0];    // The activity evaluation coming from the iLM
+    //D // This is used to help the developer to debug his iLM
+    //D // It presents the file content that will be registered. 
+    //D alert('The file activity value is: ' + exercise_value[0] + '\nThe activity content is:\n' + exercise_answer[0]);
+    //D //uncomment_this docForm.submit(); // envia de fato o formulario
+    //D //uncomment_this return true;
+
     }
 
   function getEvaluationCallback (evaluation) {
     evaluationResult = evaluation;
-    strAnswer = window.frames.iLM.getAnswer();
+    strAnswer = window.frames.iLM[index].getAnswer();
     alert('getEvaluationCallback(...)' + evaluation + ', strAnswer=' + strAnswer);
     comment = document.formEnvio.submission_comment.value;
     //leo
@@ -76,6 +79,10 @@
       return true; // success
       }
     }
+
+    function openSolution (url_file, el_button) {
+        $(el_button).parent().find('iframe').attr('src', '../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=' + url_file + '&iLM_PARAM_SendAnswer=false&lang=pt');
+      }
 //]]>
 </script>
 
@@ -85,34 +92,52 @@
 
   <body>
     <nav class="navbar navbar-expand-md navbar-dark fixed-top" style="background-color: #03396c;">
-      <b><a class="navbar-brand" href="#">iVProgH</a></b>
+      <b><a class="navbar-brand" href="../">iVProgH</a></b>
       <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
         <span class="navbar-toggler-icon"></span>
       </button>
       <div class="collapse navbar-collapse" id="navbarsExampleDefault">
         <ul class="navbar-nav mr-auto">
+          <li class="nav-item">
+            <a class="nav-link" href="../" 
+               title="Navegue para a página inicial do site do iVProgH.">Home</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="../sobre_ivprog.html"
+               title="Conheça resumidamente o que é e para que serve o iVProgH.">Conheça</a>
+          </li>
           <li class="nav-item active">
-            <a class="nav-link" href="#">Home</a>
+            <a class="nav-link" href="../ex_pt/index.html"
+               title="Veja alguns exemplos e teste o iVProgH online.">Exemplos</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="../download.html"
+               title="Faça uma cópia do iVProgH para sua máquina.">Download</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">Conheça</a>
+            <a class="nav-link" href="../manual_pt/index.html" 
+               title="Acesse um manual online do iVProgH e conheça todos os recursos.">Ajuda</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">Exemplos</a>
+            <a class="nav-link" href="../bugs/report.html"
+               title="Envie uma mensagem para a equipe do iVProgH.">Contato</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">Download</a>
+            <a class="nav-link" href="//www.usp.br/line/"
+               title="Conheça o Laboratório de Informática na Educação do Instituto de Matemática e Estatística da USP.">LInE</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">LInE</a>
+            <a class="nav-link" href="../docs/"
+               title="Tenha acesso a toda a documentação do iVProgH.">Desenvolvedores</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">Ajuda</a>
+            <a class="nav-link" href="../publicacoes.html"
+               title="Leia as publicações da equipe a respeito do iVProgH.">Publicações</a>
           </li>
         </ul>
         <div class="form-inline my-2 my-lg-0">
-          <img src="../img/img_flag_brazil.png">
-          <img src="../img/img_flag_usa.png">
+          <img src="../img/img_flag_brazil.png" />
+          <img src="../img/img_flag_usa.png" ;>
         </div>
       </div>
     </nav>
@@ -120,41 +145,356 @@
     <main role="main">
       <div class="jumbotron ivprogh-desc">
         <div class="container">
-          <h1>iVProgH</h1>
+          <h1>Exemplos</h1>
+        </div>
+      </div>
+
+      <div class="container example-large-div autoeval-descript">
+        <div data-toggle="collapse" class="pointer" href="#area-autoeval-descript" aria-expanded="false" aria-controls="area-autoeval-descript"><span class="octicon octicon-info"></span>
+	     Entenda o funcionamento do avaliador automático</div>
+        <div id="area-autoeval-descript" class="collapse">
+          <p>O iVProg permite a disponibilização de exercícios com avaliação automática diretamente em páginas Web.
+          Se o professor dispuser de uma instalação do gerenciador Moodle com o pacote <a href="www.matematica.br/ia">iTarefa</a>, então a atividade realizada pelo aluno será registrada, assim como a nota atribuida à solução do aluno.</p>
+
+          <p>A avaliação automática no iVProg é feita a partir de um modelo (gabarito), que deve ter sido preparado pelo professor,
+          prevendo entradas de dados e suas respectivas saídas. Quando o aluno "clicar" no botão para avaliar sua solução,
+          o iVProg usa a primeira lista como entradas para o problema do aluno, comparando cada saída gerada com aquelas da
+          lista de saídas.</p>
+
+          <p>Para compreender melhor o processo, vamos usar um exemplo de algoritmo que deve somar separadamente todos os números
+          positivos e negativos digitados pelo usuário.</p>
+
+          <p><span class="octicon octicon-pin"></span><b>Problema:</b></p>
+          
+          <p>Fazer um algoritmo que solicite que o usuário digite valores inteiros, finalizando sua execução quando for digitado
+          o valor zero. Ao final, seu programa deve imprimir a soma de todos os inteiros positivos que foram digitados e a seguir,  imprimir a soma de todos os inteiros negativos.</p>
+
+          <p><span class="octicon octicon-light-bulb"></span> <b> Como posso preparar um gabarito para exercício com avaliação automática no iVProg</b></p>
+
+          <p>O professor pode preparar um número qualquer de listas de entradas e de saídas, para o problema acima, usaremos apenas 3 listas,
+          ilustradas na tabela abaixo. A primeira coluna tem o numero do par "entradas/saidas", a segunda apresenta a lista de entradas
+          (separadas por espaço em branco), no terceira coluna estão as saídas esperadas (para aquelas entradas) e na última coluna uma
+          explicação curta sobre o par.
+
+          <table class="table about-auto-eval">
+            <thead class="thead-light">
+              <tr>
+                <th scope="col">#</th>
+                <th scope="col">Entradas</th>
+                <th scope="col">Saídas</th>
+                <th scope="col">Comentários</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr>
+                <th scope="row">1</th>
+                <td>0</td>
+                <td>0 0</td>
+                <td>Esse é um teste capcioso, pois se a primeira entrada for zero, nada será somado (daí deve-se imprimir 0 e 0)</td>
+              </tr>
+              <tr>
+                <th scope="row">2</th>
+                <td>1 -1 1 0</td>
+                <td> 2 -1 </td>
+                <td>Apresenta 2 valores positivos e 1 negativo, com somas respectivamente 2 e -1</td>
+              </tr>
+              <tr>
+                <th scope="row">3</th>
+                <td>-1 -1 3 1 0</td>
+                <td>4 -2</td>
+                <td>Apresenta 2 valores positivos e 2 negativo, com somas respectivamente 4 e -2</td>
+              </tr>
+            </tbody>
+          </table>
+
+          <p>O iVProg dispõe de uma interface especial para que o professor digite cada lista de entrada e sua respectiva lista de saídas.</p>
+
+          <p><span class="octicon octicon-light-bulb"></span> <b> Como o iVProg avalia automaticamente uma solução do aluno?</b></p>
+
+          <p>Supondo que o aluno tenha construído um algoritmo, quando ele "clicar" no botão para avaliar
+          sua solução, o iVProg:</p>
+
+          <ol>
+            <li>Pega a primeira entrada da primeira lista e submete ao primeiro de leitura presente no código do aluno (se não existir, erro), depois a segunda entrada e assim por diante até a última.</li>
+            <li>A primeira saída (comando de impressão) gerada pelo código do aluno é comparada com a primeira saída esperada, se coincidir
+               é registrado um acerto, senão um erro.</li>
+            <li>Repete-se os passos 1 e 2 para cada uma das demais listas de entradas/saídas e ao final é gerada uma média de acertos e erros.
+               <p>Por exemplo, se o algoritmo do aluno errar em 2 das 6 saídas, sua nota será 1/3.</p></li>
+          </ol>
+        </div>
+      </div>
+
+      <div class="container example-large-div autoeval-descript">
+        <div aria-expanded="false" aria-controls="area-autoeval-descript">
+             Experimente os exercícios listados abaixo, de exemplo 1 até exemplo 8.
+             O exemplo 9 ilustra como construir um gabarito para um exercício com avaliação automática no <i>iVProgH</i></div>
+        </div>
+      </div>
+
+      <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-1" aria-expanded="false" aria-controls="area-exemplo-1"><span class="octicon octicon-rocket"></span>
+            Exemplo 1: Entrada e Saída</div>
+        <div class="example-content collapse" id="area-exemplo-1">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_1_ler_e_imprimir_inteiro_solucao.ivph', this)">Ver solução</button>
           <p class="text-reduced">
-          <!--
-          O <b>iVProg</b> (<i>Programação Visual interativa na Internet</i>) é um dos sistemas educacionais de código livre do
-          <a href="http://line.ime.usp.br" title="pagina LInE no IME-USP">LInE</a>, sendo destinado ao ensino e à aprendizagem
-          de <b>algoritmos</b> e <b>programação</b>.
-          -->
-          Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
           </p>
           
           <p class="text-reduced">
-          <b>Fazer um programa que solicite do usuário um valor inteiro, depois imprima o valor por ele digitado.
+            <b>Faça um programa que solicite do usuário um valor inteiro, depois imprima o valor por ele digitado.</b>
           </p>
 
-          <a class="btn btn-primary" href="manual_pt/index.html" role="button" title="manual iVProgH">Saiba mais &raquo;</a>
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[1]" id="iLM[1]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_1_ler_e_imprimir_inteiro.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(1);' /><!-- chama funcao iMA-->
+            </form>
+          </div>
         </div>
-      </div>
-      <div class="container ivprog-container">
-       <form name='formEnvio' id='formEnvio' method='post' \
-                action='#'\
-                enctype='multipart/form-data'>
-          <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
-            <iframe name="iLM" id="iLM" class="embed-responsive-item"
-                    src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=exerc/exerc_1_1_ler_imprimir_novo.ivphiLM_PARAM_SendAnswer=false&lang=en"
-                    allowfullscreen></iframe><br/>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+      <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-2" aria-expanded="false" aria-controls="area-exemplo-2"><span class="octicon octicon-rocket"></span>
+            Exemplo 2: Imprimir o quadrado de um número (inteiro)</div>
+        <div class="example-content collapse" id="area-exemplo-2">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_2_imprimir_quadrado_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que solicite que o usuário digite um número (inteiro) e imprime o quadrado desse valor.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[2]" id="iLM[2]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_2_imprimir_quadrado.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(2);' /><!-- chama funcao iMA-->
+            </form>
           </div>
-          <div class="embed-responsive embed-responsive"> <!-- 4by3 -->
-            <center>
-            <input type='button' name='Submit' value='Enviar resposta' 
-                   title='clique aqui para vesualizar seu codigo'
-                   onclick='javascript:window.submit_iMA_Answer();' /><!-- chama funcao iMA-->
-            </center>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+
+       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-3" aria-expanded="false" aria-controls="area-exemplo-3"><span class="octicon octicon-rocket"></span>
+            Exemplo 3: Soma de dois valores</div>
+        <div class="example-content collapse" id="area-exemplo-3">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_3_soma_dois_valores_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que recebe dois números inteiros e imprime a soma desses valores.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[3]" id="iLM[3]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_3_soma_dois_valores.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(3);' /><!-- chama funcao iMA-->
+            </form>
           </div>
-        </form>
-      </div>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+      <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-4" aria-expanded="false" aria-controls="area-exemplo-4"><span class="octicon octicon-rocket"></span>
+            Exemplo 4: Média aritmética</div>
+        <div class="example-content collapse" id="area-exemplo-4">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_4_media_aritmetica_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que recebe dois números inteiros da entrada, calcula a média aritmética desses números e a imprima.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[4]" id="iLM[4]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_4_media_aritmetica.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(4);' /><!-- chama funcao iMA-->
+            </form>
+          </div>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+       <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-5" aria-expanded="false" aria-controls="area-exemplo-5"><span class="octicon octicon-rocket"></span>
+            Exemplo 5: Maior valor</div>
+        <div class="example-content collapse" id="area-exemplo-5">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_5_maior_valor_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que recebe dois números inteiros da entrada e imprime o maior dentre os dois números.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[5]" id="iLM[5]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_5_maior_valor.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(5);' /><!-- chama funcao iMA-->
+            </form>
+          </div>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+      <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-6" aria-expanded="false" aria-controls="area-exemplo-6"><span class="octicon octicon-rocket"></span>
+            Exemplo 6: Sequência</div>
+        <div class="example-content collapse" id="area-exemplo-6">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_6_imprimir_de_1_a_10_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que imprima a sequência de números inteiros de 1 a 10.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[6]" id="iLM[6]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_6_imprimir_de_1_a_10.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(6);' /><!-- chama funcao iMA-->
+            </form>
+          </div>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+      <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-7" aria-expanded="false" aria-controls="area-exemplo-7"><span class="octicon octicon-rocket"></span>
+            Exemplo 7: Imprimir texto</div>
+        <div class="example-content collapse" id="area-exemplo-7">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_7_imprimir_ivprogh_10_vezes_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Construa um algoritmo que imprima a palavra iVProgH 10 vezes.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#' \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[7]" id="iLM[7]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_7_imprimir_ivprogh_10_vezes.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(7);' /><!-- chama funcao iMA-->
+            </form>
+          </div>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+      <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-8" aria-expanded="false" aria-controls="area-exemplo-8"><span class="octicon octicon-rocket"></span>
+            Exemplo 8: Somar n valores</div>
+        <div class="example-content collapse" id="area-exemplo-8">
+          <button type="button" class="btn btn-primary show-solution" onclick="openSolution('../ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0_solucao.ivph', this)">Ver solução</button>
+          <p class="text-reduced">
+            Exemplo de exercício com <i>avaliação automática</i> no <i>iVProg</i>.
+          </p>
+          
+          <p class="text-reduced">
+            <b>Fazer um algoritmo que lê uma sequência de números inteiros, somando-os até que um valor 0 seja digitado, nesse momento deve imprimir o valor da soma e parar.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#'\ \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[8]" id="iLM[8]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_8_somar_valores_ate_digitar_0.ivph&iLM_PARAM_SendAnswer=false&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                       title='Clique aqui para visualizar seu código.'
+                       onclick='javascript:window.submit_iMA_Answer(8);' /><!-- chama funcao iMA-->
+            </form>
+          </div>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
+
+      <!-- Para cada exemplo, copiar toda a DIV abaixo e não alterar as classes dos elementos :) -->
+      <div class="container example-large-div">
+        <div class="text-count-example" data-toggle="collapse" href="#area-exemplo-9" aria-expanded="false" aria-controls="area-exemplo-9"><span class="octicon octicon-rocket"></span> Gabarito: Construindo uma atividade</div>
+        <div class="example-content collapse" id="area-exemplo-9">
+          <p class="text-reduced">
+            <b>Nesse exemplo, construa uma atividade, inserindo os casos de teste que serão utilizados para avaliar o algoritmo e configure os recursos que serão disponibilizados para o aluno no iVProgH.</b>
+          </p>
+
+          <div class="container text-center">
+            <form name='formEnvio' id='formEnvio' method='post' action='#'\ \
+                  enctype='multipart/form-data'>
+              <div class="embed-responsive embed-responsive-16by9"> <!-- 4by3 -->
+                <iframe name="iLM[9]" id="iLM[9]" class="embed-responsive-item"
+                        src="../ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_SendAnswer=true&lang=pt"
+                        allowfullscreen></iframe><br/>
+              </div>
+               <input type='button' name='Submit' value='Enviar resposta' class="btn btn-warning" 
+                      title='Clique aqui para visualizar seu código.'
+                      onclick='javascript:window.submit_iMA_Answer(9);' /><!-- chama funcao iMA-->
+            </form>
+          </div>
+        </div>
+      </div> <!-- Este é o final da DIV que deve ser copiada para cada exemplo -->
 
     </main>
     <footer class="container text-center">
@@ -163,7 +503,13 @@
       <a href="http://www.matematica.br">iM&aacute;tica</a>
     </footer>
 
-    <script src="js/jquery-min.js"></script>
-    <script src="js/bootstrap.min.js"></script>
+    <script src="../js/jquery.min.js"></script>
+    <script src="../js/bootstrap.bundle.min.js"></script>
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.5.0/octicons.min.css">
+    <script type="text/javascript">
+      $('.example-content').on('shown.bs.collapse', function () {
+        this.parentNode.scrollIntoView();
+      });
+    </script>
   </body>
 </html>

BIN
img/background-panel.png


+ 11 - 2
index.html

@@ -78,18 +78,27 @@
           <a href="autoeval/index.html" title="saiba mais sobre"><b>avaliador automático</b></a>
           para exercícios e pode facilmente ser integrado ao ambiente <i>Moodle</i> a partir do pacote
           <a href="http://www.matematica.br/ia" title="pagina do iTarefa no iMatica"><b>iTarefa</b></a>.
-          A <a href="ivprog1/" title="primeira versao iVProg em Java">primeira versão do <i>iVProg</i></a> foi implementada em <i>Java</i> em 2009.
+          A primeira versão do <i>iVProg</i> foi implementada em <i>Java</i> em 2009,
+          <a href="legacy/index.html" title="primeiras versoes do iVProg">confira aqui as versões anteriores do <i>iVProg</i></a>.
           </p>
 
           <a class="btn btn-primary" href="./sobre_ivprog.html" role="button" title="Conheça resumidamente o que é e para que serve o iVProgH.">Saiba mais &raquo;</a>
         </div>
       </div>
       <div class="container ivprog-container">
+      <p>
+          Abaixo o <i>iVProgH</i> com um código ilustrativo, nesse caso para computar o fatorial de um natural
+          a ser digitado pelo usuãrio. Você rodar o código (digite um natural), mas pode alterá-lo como desejar.
+      </p>
         <div class="embed-responsive embed-responsive-16by9">
-          <iframe class="embed-responsive-item" src="ivprogh/index.html" allowfullscreen></iframe>
+          <iframe class="embed-responsive-item"
+           src="ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=../ex_pt/exerc/exemplo_fatorial.ivph"
+           allowfullscreen>
+          </iframe>
         </div>
       </div>
 
+
       <div class="container">
         <div class="row thumbs-ivprog">
           <div class="col-md-1"></div>

+ 89 - 15
index.html~

@@ -10,35 +10,52 @@
 
   <body>
     <nav class="navbar navbar-expand-md navbar-dark fixed-top" style="background-color: #03396c;">
-      <b><a class="navbar-brand" href="#">iVProgH</a></b>
+      <b><a class="navbar-brand" href="./">iVProgH</a></b>
       <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
         <span class="navbar-toggler-icon"></span>
       </button>
       <div class="collapse navbar-collapse" id="navbarsExampleDefault">
         <ul class="navbar-nav mr-auto">
           <li class="nav-item active">
-            <a class="nav-link" href="#">Home</a>
+            <a class="nav-link" href="./" 
+               title="Navegue para a página inicial do site do iVProgH.">Home</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="sobre_ivprog.html"
-               title="conheca resumidamente o que e' e para que serve o iVProgH">Conheça</a>
+            <a class="nav-link" href="./sobre_ivprog.html"
+               title="Conheça resumidamente o que é e para que serve o iVProgH.">Conheça</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="ex_pt/index.html">Exemplos</a>
+            <a class="nav-link" href="./ex_pt/index.html"
+               title="Veja alguns exemplos e teste o iVProgH online.">Exemplos</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">Download</a>
+            <a class="nav-link" href="./download.html"
+               title="Faça uma cópia do iVProgH para sua máquina.">Download</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="#">LInE</a>
+            <a class="nav-link" href="./manual_pt/index.html" 
+               title="Acesse um manual online do iVProgH e conheça todos os recursos.">Ajuda</a>
           </li>
           <li class="nav-item">
-            <a class="nav-link" href="manual_pt/index.html" title="manual iVProgH">Manual</a>
+            <a class="nav-link" href="./bugs/report.html"
+               title="Envie uma mensagem para a equipe do iVProgH.">Contato</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="//www.usp.br/line/"
+               title="Conheça o Laboratório de Informática na Educação do Instituto de Matemática e Estatística da USP.">LInE</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="./docs/"
+               title="Tenha acesso a toda a documentação do iVProgH.">Desenvolvedores</a>
+          </li>
+          <li class="nav-item">
+            <a class="nav-link" href="./publicacoes.html"
+               title="Leia as publicações da equipe a respeito do iVProgH.">Publicações</a>
           </li>
         </ul>
         <div class="form-inline my-2 my-lg-0">
-          <img src="img/img_flag_brazil.png">
-          <img src="img/img_flag_usa.png">
+          <img src="img/img_flag_brazil.png" />
+          <img src="img/img_flag_usa.png" ;>
         </div>
       </div>
     </nav>
@@ -61,15 +78,69 @@
           <a href="autoeval/index.html" title="saiba mais sobre"><b>avaliador automático</b></a>
           para exercícios e pode facilmente ser integrado ao ambiente <i>Moodle</i> a partir do pacote
           <a href="http://www.matematica.br/ia" title="pagina do iTarefa no iMatica"><b>iTarefa</b></a>.
-          A <a href="ivprog1/" title="primeira versao iVProg em Java">primeira versão do <i>iVProg</i></a> foi implementada em <i>Java</i> em 2009.
+          A <a href="legacy/version1/" title="primeira versao iVProg em Java">primeira versão do <i>iVProg</i></a> foi implementada em <i>Java</i> em 2009.
           </p>
 
-          <a class="btn btn-primary" href="manual_pt/index.html" role="button" title="manual iVProgH">Saiba mais &raquo;</a>
+          <a class="btn btn-primary" href="./sobre_ivprog.html" role="button" title="Conheça resumidamente o que é e para que serve o iVProgH.">Saiba mais &raquo;</a>
         </div>
       </div>
       <div class="container ivprog-container">
+      <p>
+          Abaixo o <i>iVProgH</i> com um código ilustrativo, nesse caso para computar o fatorial de um natural
+          a ser digitado pelo usuãrio. Você rodar o código (digite um natural), mas pode alterá-lo como desejar.
+      </p>
         <div class="embed-responsive embed-responsive-16by9">
-          <iframe class="embed-responsive-item" src="ivprogh/index.html" allowfullscreen></iframe>
+          <iframe class="embed-responsive-item"
+           src="ivprogh/index.html?iLM_PARAM_AssignmentURL=true&iLM_PARAM_Assignment=./exemplos/exemplo_fatorial.ivph"
+           allowfullscreen>
+          </iframe>
+        </div>
+      </div>
+
+
+      <div class="container">
+        <div class="row thumbs-ivprog">
+          <div class="col-md-1"></div>
+          <div class="col-md-3 item">
+            <span class="octicon octicon-light-bulb"></span>
+            <h4>Menos linguagem <br> Mais algoritmo</h4>
+            <hr>
+            <p>No iVProgH, o estudante dedica-se ao aprendizado de algoritmo, não se prendendo a uma linguagem ou IDE.</p>
+          </div>
+          <div class="col-md-3 item">
+            <span class="octicon octicon-clock"></span>
+            <h4>Fácil de implementar</h4>
+            <hr>
+            <p>Com um ambiente interativo, para construir algoritmos basta criar e arrastar os componentes para elaborar um programa.</p>
+          </div>
+          <div class="col-md-3 item">
+            <span class="octicon octicon-checklist"></span>
+            <h4>Avaliador Automático</h4>
+            <hr>
+            <p>Assim que o estudante finaliza o algoritmo, já consegue receber um feedback instantâneo, informando se sua solução resolve ou não o problema proposto.</p>
+          </div>
+        </div>
+
+        <div class="row thumbs-ivprog">
+          <div class="col-md-1"></div>
+          <div class="col-md-3 item">
+            <span class="octicon octicon-mortar-board"></span>
+            <h4>Área de criação de atividades</h4>
+            <hr>
+            <p>O professor conta com uma área, dentro do próprio iVProgH, onde pode preparar as atividades. Estas podem ser reaproveitadas em outros cursos também!</p>
+          </div>
+          <div class="col-md-3 item">
+            <span class="octicon octicon-globe"></span>
+            <h4>Baseado na Web</h4>
+            <hr>
+            <p>O iVProgH foi desenvolvido para ser executado em navegadores, utilizando as tecnologias HTML5, CSS3 e JavaScript. Isso permite sua incorporação a qualquer página/site da Web.</p>
+          </div>
+          <div class="col-md-3 item">
+            <span class="octicon octicon-plug"></span>
+            <h4>Fácil integração com o Moodle</h4>
+            <hr>
+            <p>O iVProgH tem uma integração completa com o Moodle: controle de usuários, registros de atividades, notas nos exercícios, comunicação entre professor/aluno, etc.</p>
+          </div>
         </div>
       </div>
 
@@ -80,7 +151,10 @@
       <a href="http://www.matematica.br">iM&aacute;tica</a>
     </footer>
 
-    <script src="js/jquery-min.js"></script>
-    <script src="js/bootstrap.min.js"></script>
+    <script src="./js/jquery.min.js"></script>
+    <script src="./js/bootstrap.bundle.min.js"></script>
+
+
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.5.0/octicons.min.css">
   </body>
 </html>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 31883 - 26278
ivprogh/build/ivprog.bundle.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 1
ivprogh/build/ivprog.bundle.js.map


+ 28 - 16
ivprogh/css/ivprog-visual-1.0.css

@@ -647,12 +647,12 @@ div.function_name_div_updated:active,
 
 .global_var .circle.add_global_button, .global_var i.back,
 .ui.add_var_context .icon.plus.circle, .ui.add_var_context .icon.circle.back,
-.ui.inline_add_command .icon.plus.circle, .ui.inline_add_command .icon.circle.back {
+.ui.rail .icon.plus.circle, .ui.rail .icon.circle.back {
 	position: absolute;
 }
 .global_var .circle.add_global_button,
 .ui.add_var_context .icon.plus.circle,
-.inline_add_command .icon.plus.circle {
+.ui.rail .icon.plus.circle {
 	z-index: 10;
 	color: #bf80d4!important;
 	cursor: pointer;
@@ -660,14 +660,14 @@ div.function_name_div_updated:active,
 }
 .global_var i.back,
 .ui.add_var_context .icon.circle.back,
-.inline_add_command .icon.circle.back {
+.ui.rail .icon.circle.back {
 	z-index: 9;
 	color: white !important;
 }
 .ui.add_var_context{
 	margin-left: -4px;
 }
-.inline_add_command {
+.ui.rail {
 	color: #ab0054 !important;
 }
 
@@ -713,11 +713,11 @@ div.function_name_div_updated:active,
 	color: yellow;
 	font-size: 125%;
 }
-.inline_add_command .icon.plus.circle {
+.ui.rail .icon.plus.circle {
 	color: #ec9962 !important;
 }
-.inline_add_command .icon.plus.circle, 
-.inline_add_command .icon.circle.back,
+.ui.rail .icon.plus.circle, 
+.ui.rail .icon.circle.back,
 .ui.add_var_context .icon.plus.circle, 
 .ui.add_var_context .icon.circle.back,
 .global_var .icon.plus.circle, 
@@ -725,8 +725,13 @@ div.function_name_div_updated:active,
 	left: 1.8em !important;
 	margin-top: 1.5em !important;
 }
+
+.ui.rail .icon.plus.circle, 
+.ui.rail .icon.circle.back {
+	left: 1.3em !important;
+}
+
 .ui.icon.button.dropdown.menu_commands {
-    float: left;
     color: white;
     margin-left: -4px;
     padding: 8px;
@@ -795,14 +800,6 @@ div.ui.checkbox.transition.visible {
     color: white !important;
     border: 2px solid #3125ee;
 }
-.ui.comment:hover, .ui.reader:hover, .ui.writer:hover, .ui.attribution:hover, .ui.functioncall:hover,
-.ui.return:hover {
-    background: #f2e67f;
-}
-
-.ui.iftrue:hover, .ui.repeatNtimes:hover, .ui.whiletrue:hover, .ui.dowhiletrue:hover, .ui.switch:hover {
-	background: #c6c8f2;
-}
 
 .ui.iftrue, .ui.repeatNtimes, .ui.whiletrue, .ui.dowhiletrue, .ui.switch {
     background: #787fe721;
@@ -855,4 +852,19 @@ div.ui.checkbox.transition.visible {
 
 .div_parent_handler:hover i.handler {
 	opacity: 1;
+}
+
+.ui.block_commands {
+    min-height: 20px !important;
+    padding-top: 5px !important;
+}
+
+.ghost_div {
+
+    height: 20px;
+    background-color: #ffffff;
+    margin: 5px;
+    border: 2px dotted #000000;
+    box-shadow: 1px 1px;
+    height: 28px;
 }

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 4 - 0
ivprogh/exemplos/exemplo_fatorial.ivph


+ 0 - 35
ivprogh/i18n/en/error.json

@@ -1,35 +0,0 @@
-{
-  "token_missing_one": "Erro de sintaxe: Espera-se $0, mas encontrou-se $1 na linha:$2, coluna:$3",
-  "token_missing_two": "Erro de sintaxe: Esperava-se $0 ou $1 mas encontrou-se $2 na liha:$3, coluna: $4",
-  "eos_missing": "Falta uma nova linha ou ; na linha: $0, coluna: $1",
-  "invalid_type": "$0 na linha: $1, coluna: $2 é um tipo inválido. Os tipos válidos são: $3",
-  "invalid_array_dimension": "A dimensão inválida na linha: $0, coluna: $1. Insira um $2 ou identificador válido do mesmo tipo.",
-  "invalid_array_size": "O tamnho do vetor/matriz excede o máximo de 2 na linha $0",
-  "extra_lines": "Nenhum texto é permitido após '}' em 'programa {...}'",
-  "invalid_main_return": "A função $0 deve retornar $1 na linha $2",
-  "invalid_var_declaration": "Erro na linha $0. Variáveis só podem ser declarados no corpo principal da função e de preferência nas primeiras linhas.",
-  "invalid_break_command": "Erro na linha $0. O comando $1 não pode ser usado fora de uma estrutura de repetição ou 'escolha...caso'",
-  "invalid_terminal": "Não é possível utilizar $0 na expressão da linha: $1, coluna: $2. Tente um valor númerico, variável ou chamada de função.",
-  "id_missing": "Esperava-se um identificador, mas encontrou-se $0 na linha: $1, coluna: $2",
-  "main_missing": "A função principal não foi encontrada",
-  "invalid_global_var": "Erro crítico: Chamada inválida da função initGlobal fora do contexto BASE",
-  "not_implemented": "Erro interno crítico: A função definida pelo sistema $0 não foi implementada.",
-  "function_missing": "A função $0 não foi encontrada",
-  "invalid_parameters_size": "A quantidade de parâmetros fornecidos está incorreta. Esperava-se $0, encontrou-se $1",
-  "invalid_ref": "Você deve fornecer apenas um identificador como parâmetro",
-  "invalid_parameter_type": "O valor fornecido como parâmetro é do tipo $0, mas o tipo esperado é $1",
-  "unknown_command": "Erro interno crítico: Comando desconhecido encontrado",
-  "loop_condition_type": "A condição dos laços de repetição deve ser do tipo lógico",
-  "if_condition_type": "A condição de um comando se...senao deve ser do tipo lógico",
-  "invalid_return_type": "A função $0 deve retornar um tipo $1, ao invés de $1",
-  "unexpected_break_command": "Erro interno crítico: Comando pare encontrado fora do contexto de um laço/escolha..caso",
-  "invalid_dimension": "As dimensões de um vetor/matriz devem ser do tipo inteiro",
-  "void_in_expression": "A função $0 não pode ser utilizada aqui pois seu tipo de retorno é vazio",
-  "invalid_array": "Expressão literal de Vetor/Mariz inválida",
-  "invalid_array_access": "Identificador $0 não se refere a um vetor/matriz válido",
-  "column_outbounds": "Número de colunas $0 é inválido para a matriz $1 que possui $2 colunas",
-  "line_outbounds": "Número de linhas $0 é invaálido para a matriz $1 que possui $2 linhas",
-  "invalid_infix_op": "Não é possível aplicar a operação $0 entre os tipos $1 e $2",
-  "invalid_unary_op": "Não é possível aplicar a operação $0 ao tipo $1",
-  "unknown_op": "Erro interno crítico: Operação $0 desconhecida"
-}

+ 0 - 9
ivprogh/i18n/en/index.js

@@ -1,9 +0,0 @@
-import errors from './error.json';
-import messages from './message.json'
-import ui from './ui.json';
-
-export default {
- 'message' : messages,
- 'error': errors,
- 'ui': ui
-}

+ 0 - 3
ivprogh/i18n/en/message.json

@@ -1,3 +0,0 @@
-{
-  
-}

+ 0 - 135
ivprogh/i18n/en/ui.json

@@ -1,135 +0,0 @@
-{
-  "function": "function",
-  "btn_clear": "Clear",
-  "btn_function": "Function",
-  "btn_arithmetic_plus": "Sum",
-  "btn_arithmetic_minus": "Minus",
-  "btn_arithmetic_multiplication": "Multiplication",
-  "btn_arithmetic_division": "Division",
-  "btn_arithmetic_module": "Module",
-  "btn_break":"Break",
-  "btn_case":"Case",
-  "start": "start",
-  "void": "void",
-  "integer": "integer",
-  "real": "real",
-  "program": "program",
-  "text": "string",
-  "text_start": "text",
-  "boolean": "boolean",
-  "true": "true",
-  "false": "false",
-  "variable": "Variable",
-  "command": "Command",
-  "new_parameter": "new_parameter",
-  "new_variable": "new_variable",
-  "new_global": "new_global",
-  "new_function": "new_function",
-  "vector": "vector",
-  "text_comment_start": "Initial comment of function...",
-  "text_comment_main": "This is the main function...",
-  "text_read_var": "Reading data",
-  "text_write_var": "Writing data",
-  "text_command_read":"read",
-  "text_command_write":"write",
-  "text_comment": "Comment",
-  "text_attribution": "Attribution",
-  "text_if":"if",
-  "text_else":"else",
-  "text_break":"break",
-  "text_for":"for",
-  "text_code_while":"while",
-  "text_code_do":"do",
-  "text_command_do":"do",
-  "text_code_switch": "switch",
-  "text_code_case": "case",
-  "text_logic_expression": "Logic Expression",
-  "text_arithmetic_expression": "Relational Expression",
-  "text_iftrue": "If true then",
-  "text_receives": "receives",
-  "text_repeatNtimes": "Repeat N times",
-  "text_return":"return",
-  "text_btn_return":"Return",
-  "text_whiletrue": "While true",
-  "text_dowhiletrue": "Do while true",
-  "text_switch": "Switch",
-  "text_functioncall": "Function call",
-  "text_value": "Value",
-  "text_operator": "Operator",
-  "text_parentheses": "Parentheses",
-  "text_change": "Change",
-  "text_teacher_algorithm": "Algorithm",
-  "text_teacher_algorithm_include": "Include the following algorithm in exercise",
-  "text_teacher_test_case": "Test cases",
-  "text_teacher_config": "Settings",
-  "text_teacher_data_types": "Data types",
-  "text_teacher_commands": "Commands",
-  "text_teacher_functions": "Functions",
-  "text_teacher_create_functions": "Create new functions",
-  "text_teacher_create_movement_functions": "Move functions",
-  "text_teacher_test_case_input": "Input",
-  "text_teacher_test_case_output": "Output",
-  "text_teacher_test_case_actions": "Actions",
-  "text_teacher_test_case_add": "Add test cases",
-  "text_header_ivprog_functions": "iVProg Functions",
-  "text_menu_functions_math":"Mathematic",
-  "text_menu_functions_text":"Text",
-  "text_menu_functions_arrangement":"Arrangement",
-  "text_menu_functions_conversion":"Conversion",
-  "text_none_variable":"There is no declared variable",
-  "text_none_variable_instruction":"Create a new variable to use it",
-  "text_ivprog_description":"Interactive Visual Programming on the Internet",
-  "tooltip_visual": "Visual programming",
-  "tooltip_textual": "Textual programming",
-  "tooltip_upload": "Upload code file",
-  "tooltip_download": "Download code file",
-  "tooltip_undo": "Undo",
-  "tooltip_redo": "Redo",
-  "tooltip_run": "Run program",
-  "tooltip_evaluate": "Evaluate program",
-  "tooltip_help": "Help",
-  "tooltip_add_global": "Add global variable",
-  "tooltip_minimize": "Hidde function elements",
-  "tooltip_console": "Open/Close console",
-  "var_menu_select_var": "Select a var",
-  "var_menu_select_all": "Select",
-  "var_menu_select_function": "Select a function",
-  "expression_menu_select": "Construct any logical condition",
-  "math": "Mathematic",
-  "text_t": "Text",
-  "inform_valid_name": "Inform a valid name!",
-  "inform_valid_content": "Enter some content!",
-  "inform_valid_expression": "Construct the logical condition!",
-  "inform_valid_name_duplicated": "This name is already in use by other function.",
-  "inform_valid_global_duplicated": "A global variable with this name already exists.",
-  "inform_valid_variable_duplicated" : "A local variable with this name already exists.",
-  "arrangement": "Arrangement",
-  "conversion": "Conversion",
-  "$sin": "sin",
-  "$cos": "cos",
-  "$tan": "tan",
-  "$sqrt": "sqrt",
-  "$pow": "pow",
-  "$log": "log",
-  "$abs": "abs",
-  "$negate": "negate",
-  "$invert": "invert",
-  "$max": "maximum",
-  "$min": "minimum",
-  "$substring": "substring",
-  "$length": "length",
-  "$uppercase": "uppercase",
-  "$lowercase": "lowercase",
-  "$charAt": "char_at",
-  "$numElements": "total_of_elements",
-  "$matrixLines": "total_of_lines",
-  "$matrixColumns": "total_of_columns",
-  "$isReal": "is_real",
-  "$isInt": "is_integer",
-  "$isBool": "is_logic",
-  "$castReal": "to_real",
-  "$castInt": "to_integer",
-  "$castBool": "to_logic",
-  "$castString": "to_string",
-  "text_ivprog_version":"Version 2018_12_19 Build 13_18"
-}

+ 0 - 3
ivprogh/i18n/es/error.json

@@ -1,3 +0,0 @@
-{
-  
-}

+ 0 - 9
ivprogh/i18n/es/index.js

@@ -1,9 +0,0 @@
-import errors from './error.json';
-import messages from './message.json'
-import ui from './ui.json';
-
-export default {
- 'message' : messages,
- 'error': errors,
- 'ui': ui
-}

+ 0 - 3
ivprogh/i18n/es/message.json

@@ -1,3 +0,0 @@
-{
-  
-}

+ 0 - 140
ivprogh/i18n/es/ui.json

@@ -1,140 +0,0 @@
-{
-  "function": "function",
-  "btn_clear": "Clear",
-  "btn_function": "Function",
-  "btn_arithmetic_plus": "Sum",
-  "btn_arithmetic_minus": "Minus",
-  "btn_arithmetic_multiplication": "Multiplication",
-  "btn_arithmetic_division": "Division",
-  "btn_arithmetic_module": "Module",
-  "btn_break":"Break",
-  "btn_case":"Case",
-  "start": "start",
-  "void": "void",
-  "integer": "integer",
-  "real": "real",
-  "program": "program",
-  "text": "string",
-  "text_start": "text",
-  "boolean": "boolean",
-  "true": "true",
-  "false": "false",
-  "variable": "Variable",
-  "command": "Command",
-  "new_parameter": "new_parameter",
-  "new_variable": "new_variable",
-  "new_global": "new_global",
-  "new_function": "new_function",
-  "vector": "vector",
-  "text_comment_start": "Initial comment of function...",
-  "text_comment_main": "This is the main function...",
-  "text_read_var": "Reading data",
-  "text_write_var": "Writing data",
-  "text_command_read":"read",
-  "text_command_write":"write",
-  "text_comment": "Comment",
-  "text_attribution": "Attribution",
-  "text_if":"if",
-  "text_break":"break",
-  "text_else":"else",
-  "text_return":"return",
-  "text_btn_return":"Return",
-  "text_for":"for",
-  "text_code_while":"while",
-  "text_code_do":"do",
-  "text_command_do":"do",
-  "text_code_switch": "switch",
-  "text_code_case": "case",
-  "text_logic_expression": "Logic Expression",
-  "text_arithmetic_expression": "Relational Expression",
-  "text_iftrue": "If true then",
-  "text_repeatNtimes": "Repeat N times",
-  "text_receives": "receives",
-  "text_whiletrue": "While true",
-  "text_dowhiletrue": "Do while true",
-  "text_switch": "Switch",
-  "text_functioncall": "Function call",
-  "text_value": "Value",
-  "text_operator": "Operator",
-  "text_parentheses": "Parentheses",
-  "text_change": "Change",
-  "text_teacher_algorithm": "Algorithm",
-  "text_teacher_algorithm_include": "Include the following algorithm in exercise",
-  "text_teacher_test_case": "Test cases",
-  "text_teacher_config": "Settings",
-  "text_teacher_data_types": "Data types",
-  "text_teacher_commands": "Commands",
-  "text_teacher_functions": "Functions",
-  "text_teacher_create_functions": "Create new functions",
-  "text_teacher_create_movement_functions": "Move functions",
-  "text_teacher_test_case_input": "Input",
-  "text_teacher_test_case_output": "Output",
-  "text_teacher_test_case_actions": "Actions",
-  "text_teacher_test_case_add": "Add test cases",
-  "text_header_ivprog_functions": "iVProg Functions",
-  "text_menu_functions_math":"Mathematics",
-  "text_menu_functions_text":"Text",
-  "text_menu_functions_arrangement":"Arrangement",
-  "text_menu_functions_conversion":"Conversion",
-  "text_none_variable":"There is no declared variable",
-  "text_none_variable_instruction":"Create a new variable to use it",
-  "text_ivprog_description":"Interactive Visual Programming on the Internet",
-  "tooltip_visual": "Visual programming",
-  "tooltip_textual": "Textual programming",
-  "tooltip_upload": "Upload code file",
-  "tooltip_download": "Download code file",
-  "tooltip_undo": "Undo",
-  "tooltip_redo": "Redo",
-  "tooltip_run": "Run program",
-  "tooltip_evaluate": "Evaluate program",
-  "tooltip_help": "Help",
-  "tooltip_add_global": "Add global variable",
-  "tooltip_minimize": "Hidde function elements",
-  "tooltip_console": "Open/Close console",
-  "var_menu_select_var": "Select a var",
-  "var_menu_select_all": "Select",
-  "var_menu_select_function": "Select a function",
-  "expression_menu_select": "Construct any logical condition",
-  "$sin": "sen",
-  "math": "Mathematic",
-  "text": "Text",
-  "arrangement": "Arrangement",
-  "conversion": "Conversion",
-  "math": "Mathematic",
-  "inform_valid_name": "Inform a valid name!",
-  "inform_valid_content": "Enter some content!",
-  "inform_valid_expression": "Construct the logical condition!",
-  "inform_valid_name_duplicated": "This name is already in use by other function.",
-  "inform_valid_global_duplicated": "A global variable with this name already exists.",
-  "inform_valid_variable_duplicated" : "A local variable with this name already exists.",
-  "text_t": "Text",
-  "arrangement": "Arrangement",
-  "conversion": "Conversion",
-  "$sin": "sin",
-  "$cos": "cos",
-  "$tan": "tan",
-  "$sqrt": "sqrt",
-  "$pow": "pow",
-  "$log": "log",
-  "$abs": "abs",
-  "$negate": "negate",
-  "$invert": "invert",
-  "$max": "maximum",
-  "$min": "minimum",
-  "$substring": "substring",
-  "$length": "length",
-  "$uppercase": "uppercase",
-  "$lowercase": "lowercase",
-  "$charAt": "char_at",
-  "$numElements": "total_of_elements",
-  "$matrixLines": "total_of_lines",
-  "$matrixColumns": "total_of_columns",
-  "$isReal": "is_real",
-  "$isInt": "is_integer",
-  "$isBool": "is_logic",
-  "$castReal": "to_real",
-  "$castInt": "to_integer",
-  "$castBool": "to_logic",
-  "$castString": "to_string",
-  "text_ivprog_version":"Version 2018_12_19 Build 13_18"
-}

+ 0 - 117
ivprogh/i18n/i18n-database.json

@@ -1,117 +0,0 @@
-{
-	"function": {
-		"en": "function",
-		"es": "función",
-		"pt": "função"
-	},
-	"Function": {
-		"en": "Function",
-		"es": "Función",
-		"pt": "Função"
-	},
-	"start": {
-		"en": "start",
-		"es": "comienzo",
-		"pt": "inicio"
-	},
-	"void": {
-		"en": "void",
-		"es": "vacío",
-		"pt": "vazio"
-	},
-	"integer": {
-		"en": "integer",
-		"es": "entero",
-		"pt": "inteiro"
-	},
-	"real": {
-		"en": "real",
-		"es": "real",
-		"pt": "real"
-	},
-	"program": {
-		"en": "program",
-		"es": "programa",
-		"pt": "programa"
-	},
-	"text": {
-		"en": "text",
-		"es": "texto",
-		"pt": "texto"
-	},
-	"boolean": {
-		"en": "boolean",
-		"es": "booleano",
-		"pt": "booleano"
-	},
-	"true": {
-		"en": "true",
-		"es": "verdadero",
-		"pt": "verdadeiro"
-	},
-	"false": {
-		"en": "false",
-		"es": "falso",
-		"pt": "falso"
-	},
-	"Variable": {
-		"en": "Variable",
-		"es": "Variable",
-		"pt": "Variável"
-	},
-	"Command": {
-		"en": "Command",
-		"es": "Mando",
-		"pt": "Comando"
-	},
-	"new_parameter": {
-		"en": "new_parameter",
-		"es": "nuevo_parámetro",
-		"pt": "novo_parâmetro"
-	},
-	"new_variable": {
-		"en": "new_variable",
-		"es": "nuevo_variable",
-		"pt": "nova_variável"
-	},
-	"new_global": {
-		"en": "new_global",
-		"es": "nuevo_global",
-		"pt": "nova_global"
-	},
-	"new_function": {
-		"en": "new_function",
-		"es": "nueva_función",
-		"pt": "nova_função"
-	},
-	"vector": {
-		"en": "vector",
-		"es": "vector",
-		"pt": "vetor"
-	},
-	"text_comment_start": {
-		"en": "Initial comment of function...",
-		"es": "Comentario inicial de la función...",
-		"pt": "Comentário inicial da função..."
-	},
-	"text_comment_main": {
-		"en": "This is the main function...",
-		"es": "Esta es la función principal...",
-		"pt": "Esta é a função principal..."
-	},
-	"text_read_var": {
-		"en": "Reading data",
-		"es": "Leyendo datos",
-		"pt": "Leitura de dados"
-	},
-	"text_write_var": {
-		"en": "Writing data",
-		"es": "Escribir datos",
-		"pt": "Escrita de dados"
-	},
-	"text_comment": {
-		"en": "Comment",
-		"es": "Comentario",
-		"pt": "Comentário"
-	}
-}

+ 0 - 9
ivprogh/i18n/index.js

@@ -1,9 +0,0 @@
-import EN from './en';
-import PT from './pt';
-import ES from './es';
-
-export default {
-  'en': EN,
-  'pt': PT,
-  'es': ES
-}

+ 0 - 85
ivprogh/i18n/pt/error.json

@@ -1,85 +0,0 @@
-{
-  "token_missing_one": "Erro de sintaxe: Espera-se $0, mas encontrou-se $1 na linha:$2, coluna:$3",
-  "token_missing_two": "Erro de sintaxe: Esperava-se $0 ou $1 mas encontrou-se $2 na liha:$3, coluna: $4",
-  "eos_missing": "Falta uma nova linha ou ; na linha: $0, coluna: $1",
-  "invalid_type": "$0 na linha: $1, coluna: $2 é um tipo inválido. Os tipos válidos são: $3",
-  "invalid_array_dimension": "A dimensão inválida na linha: $0, coluna: $1. Insira um $2 ou identificador válido do mesmo tipo.",
-  "invalid_array_size": "O tamnho do vetor/matriz excede o máximo de 2 na linha $0",
-  "extra_lines": "Nenhum texto é permitido após '}' em 'programa {...}'",
-  "invalid_main_return": "A função $0 deve retornar $1 na linha $2",
-  "invalid_var_declaration": "Erro na linha $0. Variáveis só podem ser declarados no corpo principal da função e de preferência nas primeiras linhas.",
-  "invalid_break_command": "Erro na linha $0. O comando $1 não pode ser usado fora de uma estrutura de repetição ou 'escolha...caso'",
-  "invalid_terminal": "Não é possível utilizar $0 na expressão da linha: $1, coluna: $2. Tente um valor númerico, variável ou chamada de função.",
-  "const_not_init": "Erro na linha: $0, coluna: $1. Uma variável declarada como const deve ser inicializada",
-  "id_missing": "Esperava-se um identificador, mas encontrou-se $0 na linha: $1, coluna: $2",
-  "invalid_id_format": "$0 na linha: $1, coluna: $2 não é um identificador válido. O símbolo '.' não é permitido neste contexto.",
-  "main_missing": "A função principal não foi encontrada",
-  "invalid_global_var": "Erro crítico: Chamada inválida da função initGlobal fora do contexto BASE",
-  "not_implemented": "Erro interno crítico: A função definida pelo sistema $0 não foi implementada.",
-  "function_missing": "A função $0 não foi encontrada",
-  "function_missing_full": "A função $0 na linha: $1, coluna: $2 não foi encontrada",
-  "invalid_parameters_size_full": "Erro na linha $0: a quantidade de parâmetros fornecidos à função $1 está incorreta. Esperava-se $2, encontrou-se $3.",
-  "invalid_parameters_size": "A quantidade de parâmetros fornecidos à função $0 está incorreta. Esperava-se $1, encontrou-se $2",
-  "invalid_ref_full": "A expressão $0 fornecida como parâmetro para a função $1 na linha $2 não é válida para esta função. Use uma variável ou posição de vetor.",
-  "invalid_ref": "A expressão $0 fornecida como parâmetro para a função $1 não é válida para esta função. Use uma variável ou posição de vetor.",
-  "invalid_parameter_type_full": "A expressão $0 fornecida como parâmetro para a função $1 na linha $2 não é compatível com o tipo esperado.",
-  "invalid_parameter_type": "A expressão $0 fornecida como parâmetro para a função $1 não é compatível com o tipo esperado.",
-  "unknown_command_full": "Erro interno crítico: comando desconhecido encontrado na linha $0",
-  "unknown_command": "Erro interno crítico: comando desconhecido encontrado!",
-  "loop_condition_type_full": "Erro na linha: $0, coluna $1: a condição dos laços de repetição deve ser do tipo lógico",
-  "loop_condition_type": "A condição dos laços de repetição deve ser do tipo lógico",
-  "endless_loop_full": "Possível laço infinito detectado no seu código. Verifique a linha $0",
-  "endless_loop": "Possível laço infinito detectado no seu código.",
-  "for_condition_type_full": "Erro na linha: $0, coluna $1: a condição de parada do comando para(...) deve ser do tipo lógico",
-  "for_condition_type": "A condição de parada do comando para(...) deve ser do tipo lógico",
-  "if_condition_type_full": "Erro na linha: $0, coluna $1: a condição de um comando se...senao deve ser do tipo lógico",
-  "if_condition_type": "A condição de um comando se...senao deve ser do tipo lógico",
-  "invalid_return_type_full": "Erro na linha $0: a expressão não produz um tipo compatível com a função $1. Tipo esperado: $2.",
-  "invalid_return_type": "A expressão não produz um tipo compatível com a função $0. Tipo esperado: $1.",
-  "invalid_void_return_full": "Erro na linha $0: a função $1 não pode retornar uma expressão vazia, use uma espressão do tipo $2",
-  "invalid_void_return": "A função $0 não pode retornar uma expressão vazia, use uma espressão do tipo $1",
-  "unexpected_break_command_full": "Erro interno crítico: comando pare encontrado fora do contexto de um laço/escolha..caso na linha $0",
-  "unexpected_break_command": "Erro interno crítico: comando pare encontrado fora do contexto de um laço/escolha..caso",
-  "invalid_dimension": "As dimensões de um vetor/matriz devem ser do tipo inteiro",
-  "void_in_expression_full": "Erro na linha: $0, coluna: $1: a função $2 não pode ser utilizada em uma expressão pois seu tipo de retorno é vazio",
-  "void_in_expression": "A função $0 não pode ser utilizada em uma expressão pois seu tipo de retorno é vazio",
-  "invalid_array_access_full": "Identificador $0 na linha: $1, coluna: $2 não se refere a um vetor/matriz válido",
-  "invalid_array_access": "Identificador $0 não se refere a um vetor/matriz válido",
-  "invalid_matrix_access_full": "Identificador $0 na linha: $1, coluna: $2 não se refere a uma matriz válida",
-  "invalid_matrix_access": "Identificador $0 não se refere a uma matriz válida",
-  "matrix_column_outbounds_full": "Erro na linha $0: número de colunas $1 é inválido para a matriz $2 que possui $3 colunas",
-  "matrix_column_outbounds": "Número de colunas $0 é inválido para a matriz $1 que possui $2 colunas",
-  "matrix_line_outbounds_full": "Erro na linha $0: número de linhas $1 é inválido para a matriz $2 que possui $3 linhas",
-  "matrix_line_outbounds": "Número de linhas $0 é inválido para a matriz $1 que possui $2 linhas",
-  "vector_line_outbounds_full": "Erro na linha $0: número de linhas $1 é inválido para a matriz $2 que possui $3 linhas",
-  "vector_line_outbounds": "Número de linhas $0 é inválido para a matriz $1 que possui $2 linhas",
-  "vector_not_matrix_full": "Erro na linha $0: $1 não é uma matriz",
-  "vector_not_matrix": "$1 não é uma matriz",
-  "invalid_infix_op_full": "Erro na linha $0: não é possível aplicar a operação $1 entre os tipos $2 e $3",
-  "invalid_infix_op": "Não é possível aplicar a operação $0 entre os tipos $1 e $2",
-  "invalid_unary_op_full": "Erro na linha $0: não é possível aplicar a operação $1 ao tipo $2",
-  "invalid_unary_op": "Não é possível aplicar a operação $0 ao tipo $1",
-  "unknown_op": "Erro interno crítico: Operação $0 desconhecida",
-  "duplicate_function": "A função $0 na linha: $1, coluna: $2 já foi definida anteriormente.",
-  "duplicate_variable": "A variável $0 na linha: $1, coluna: $2 já foi declarada anteriormente.",
-  "main_parameters": "A função inicio não pode ter parâmetros.",
-  "symbol_not_found_full": "A variável $0 na linha: $1, coluna: $2 não foi declarada",
-  "symbol_not_found": "A variável $0 não foi declarada",
-  "array_dimension_not_int_full": "As dimensões de um vetor/matriz na linha: $0 devem ser do tipo inteiro.",
-  "array_dimension_not_int": "As dimensões de um vetor/matriz devem ser do tipo inteiro.",
-  "array_dimension_not_positive_full": "As dimensões de um vetor/matriz na linha: $0 devem ser valores positivos.",
-  "array_dimension_not_positive": "As dimensões de um vetor/matriz devem ser valores positivos.",
-  "incompatible_types_full": "O tipo $0 não é compatível com o tipo resultante da expressão na linha $1",
-  "incompatible_types": "O tipo $0 não é compatível com o tipo resultante da expressão fornecida.",
-  "incompatible_types_array_full": "A expressão $0 é incompatível com o tipo $1 na linha: $2, coluna: $3.",
-  "incompatible_types_array": "A expressão $0 é incompatível com o tipo $1.",
-  "invalid_case_type_full": "O caso $0 na linha $1 é incompatível com o tipo $2.",
-  "invalid_case_type": "O caso $0 é incompatível com o tipo $1.",
-  "function_no_return": "A função $0 não possui um retorno acessível. Toda função deve ter ao menos um retorno no seu corpo principal.",
-  "invalid_array_literal_type_full": "Erro na linha $0: a expressão $1 não resulta em um tipo compatível.",
-  "invalid_array_literal_type": "A expressão $0 não resulta em um tipo compatível.",
-  "invalid_array_literal_line_full": "Erro na linha $0: esperava-se $1 linhas mas encontrou $2.",
-  "invalid_array_literal_line": "Esperava-se $0 linhas mas encontrou $1.",
-  "invalid_array_literal_column_full": "Erro na linha $0: esperava-se $1 colunas mas encontrou $2.",
-  "invalid_array_literal_column": "Esperava-se $0 colunas mas encontrou $1."
-}

+ 0 - 9
ivprogh/i18n/pt/index.js

@@ -1,9 +0,0 @@
-import errors from './error.json';
-import messages from './message.json'
-import ui from './ui.json';
-
-export default {
- 'message' : messages,
- 'error': errors,
- 'ui': ui
-}

+ 0 - 3
ivprogh/i18n/pt/message.json

@@ -1,3 +0,0 @@
-{
-  
-}

+ 0 - 142
ivprogh/i18n/pt/ui.json

@@ -1,142 +0,0 @@
-{
-  "function": "funcao",
-  "btn_clear": "Limpar",
-  "btn_function": "Função",
-  "btn_arithmetic_plus": "Adição",
-  "btn_arithmetic_minus": "Subtração",
-  "btn_arithmetic_multiplication": "Multiplicação",
-  "btn_arithmetic_division": "Divisão",
-  "btn_arithmetic_module": "Módulo",
-  "btn_break":"Pare",
-  "btn_case":"Caso",
-  "start": "inicio",
-  "void": "vazio",
-  "integer": "inteiro",
-  "and": "E",
-  "or": "OU",
-  "not": "nao",
-  "real": "real",
-  "program": "programa",
-  "text": "cadeia",
-  "text_start": "texto",
-  "boolean": "logico",
-  "true": "verdadeiro",
-  "false": "falso",
-  "variable": "Variável",
-  "command": "Comando",
-  "new_parameter": "novo_parametro",
-  "new_variable": "nova_variavel",
-  "new_global": "nova_global",
-  "new_function": "nova_funcao",
-  "vector": "vetor",
-  "text_comment_start": "Comentário inicial da função...",
-  "text_comment_main": "Esta é a função principal...",
-  "text_read_var": "Leitura de dados",
-  "text_write_var": "Escrita de dados",
-  "text_command_read":"leia",
-  "text_command_write":"escreva",
-  "text_return":"retorne",
-  "text_btn_return":"Retorno",
-  "text_comment": "Comentário",
-  "join_or": "ou",
-  "matrix_string": "matriz de $0",
-  "vector_string": "vetor de $0",
-  "text_attribution": "Atribuição",
-  "text_if":"se",
-  "text_break":"pare",
-  "text_else":"senao",
-  "text_for":"para",
-  "text_code_while":"enquanto",
-  "text_code_do":"faca",
-  "text_command_do":"faça",
-  "text_code_switch": "escolha",
-  "text_code_case": "caso",
-  "text_logic_expression": "Expressão Lógica",
-  "text_arithmetic_expression": "Expressão Relacional",
-  "text_iftrue": "Se verdadeiro então",
-  "text_repeatNtimes": "Repita N vezes",
-  "text_receives": "recebe",
-  "text_whiletrue": "Enquanto verdadeiro",
-  "text_dowhiletrue": "Faça enquanto verdadeiro",
-  "text_switch": "Escolha",
-  "text_functioncall": "Chamada de função",
-  "text_value": "Valor",
-  "text_operator": "Operador",
-  "text_parentheses": "Parênteses",
-  "text_change": "Alterar",
-  "text_teacher_algorithm": "Algoritmo",
-  "text_teacher_algorithm_include": "Incluir o algoritmo abaixo no exercício",
-  "text_teacher_test_case": "Casos de teste",
-  "text_teacher_config": "Configurações",
-  "text_teacher_data_types": "Tipos de dados",
-  "text_teacher_commands": "Comandos",
-  "text_teacher_functions": "Funções",
-  "text_teacher_create_functions": "Criar novas funções",
-  "text_teacher_create_movement_functions": "Movimentar funções",
-  "text_teacher_test_case_input": "Entrada",
-  "text_teacher_test_case_output": "Saída",
-  "text_teacher_test_case_actions": "Ações",
-  "text_teacher_test_case_add": "Adicionar caso de teste",
-  "text_header_ivprog_functions": "Funções do iVProg",
-  "text_menu_functions_math":"Matemática",
-  "text_menu_functions_text":"Texto",
-  "text_menu_functions_arrangement":"Arranjo",
-  "text_menu_functions_conversion":"Conversão",
-  "text_none_variable":"Nenhuma variável declarada",
-  "text_none_variable_instruction":"Antes de utilizar uma variável, é necessário criá-la",
-  "text_ivprog_description":"Programação Visual interativa na Internet",
-  "tooltip_visual": "Programação visual",
-  "tooltip_textual": "Programação textual",
-  "tooltip_upload": "Upload de código fonte",
-  "tooltip_download": "Download do código fonte",
-  "tooltip_undo": "Desfazer",
-  "tooltip_redo": "Refazer",
-  "tooltip_run": "Executar o programa",
-  "tooltip_evaluate": "Avaliar o programa",
-  "tooltip_help": "Ajuda",
-  "tooltip_add_global": "Adicionar variável global",
-  "tooltip_minimize": "Ocultar os elementos da função",
-  "tooltip_console": "Abrir/fechar o terminal",
-  "var_menu_select_var": "Selecione uma variável",
-  "var_menu_select_all": "Selecione",
-  "var_menu_select_function": "Selecione uma função",
-  "expression_menu_select": "Construir uma expressão lógica",
-  "$sin": "sen",
-  "math": "Matematica",
-  "text_t": "Texto",
-  "inform_valid_name": "Informe um nome válido!",
-  "inform_valid_content": "Informe o conteúdo!",
-  "inform_valid_expression": "Construa uma expressão lógica!",
-  "inform_valid_name_duplicated": "Este nome já está em uso por outra função!",
-  "inform_valid_global_duplicated": "Já existe uma variável global com o nome informado.",
-  "inform_valid_variable_duplicated" : "Já existe uma variável local com o nome informado.",
-  "arrangement": "Arranjo",
-  "conversion": "Conversao",
-  "$sin": "seno",
-  "$cos": "cosseno",
-  "$tan": "tangente",
-  "$sqrt": "raiz_quadrada",
-  "$pow": "potencia",
-  "$log": "logaritmo",
-  "$abs": "modulo",
-  "$negate": "trocar_sinal",
-  "$invert": "inverter_valor",
-  "$max": "maximo",
-  "$min": "minimo",
-  "$substring": "subcadeia",
-  "$length": "comprimento",
-  "$uppercase": "caixa_alta",
-  "$lowercase": "caixa_baixa",
-  "$charAt": "texto_na_posicao",
-  "$numElements": "total_de_elementos",
-  "$matrixLines": "total_de_linhas",
-  "$matrixColumns": "total_de_colunas",
-  "$isReal": "e_real",
-  "$isInt": "e_inteiro",
-  "$isBool": "e_logico",
-  "$castReal": "como_real",
-  "$castInt": "como_inteiro",
-  "$castBool": "como_logico",
-  "$castString": "como_cadeia",
-  "text_ivprog_version":"Versão 2018_12_19 Build 13_18"
-}

BIN
ivprogh/img/background-panel.png


+ 49 - 15
ivprogh/js/assessment/ivprogAssessment.js

@@ -3,6 +3,11 @@ import { SemanticAnalyser } from "./../processor/semantic/semanticAnalyser";
 import { IVProgProcessor } from "./../processor/ivprogProcessor";
 import { InputTest } from "./../util/inputTest";
 import { OutputTest } from "./../util/outputTest";
+import * as LocalizedStringsService from "../services/localizedStringsService";
+import { Decimal } from 'decimal.js';
+import { Config } from "../util/config";
+
+const LocalizedStrings = LocalizedStringsService.getInstance();
 
 export class IVProgAssessment {
 
@@ -46,45 +51,74 @@ export class IVProgAssessment {
     return prog.interpretAST().then( _ => {
       const millis = Date.now() - startTime;
       if (input.inputList.length !== input.index) {
-        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou, ainda restam entradas!`);
-        outerThis.domConsole.info(`Levou ${millis}ms`);
+        outerThis.showErrorMessage('test_case_few_reads', name+1);
+        outerThis.showMessage('test_case_duration', millis);
         return Promise.resolve(accumulator + 1 * (input.index/inputList.length));
       } else if (output.list.length < outputList.length) {
-        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
-        outerThis.domConsole.info(`Levou ${millis}ms`);
+        outerThis.showErrorMessage('test_case_failed', name + 1, inputList.join(','),
+          outputList.join(','), output.list.join(','));
+        outerThis.showMessage('test_case_duration', millis);
         return Promise.resolve(accumulator + 1 * (output.list.length/outputList.length));
       } else if (output.list.length > outputList.length) {
-        outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
-        outerThis.domConsole.info(`Levou ${millis}ms`);
+        outerThis.showErrorMessage('test_case_failed', name + 1, inputList.join(','),
+          outputList.join(','), output.list.join(','));
+        outerThis.showMessage('test_case_duration', millis);
         return Promise.resolve(accumulator + 1 * (outputList.length/output.list.length));
       } else {
         const isOk = outerThis.checkOutput(output.list, outputList);
         if(!isOk) {
-          outerThis.domConsole.err(`Caso de teste ${name + 1}: Falhou <${inputList.join(", ")};${outputList.join(", ")};${output.list.join(", ")}>`);
-          outerThis.domConsole.info(`Levou ${millis}ms`);
+          outerThis.showErrorMessage('test_case_failed', name + 1, inputList.join(','),
+            outputList.join(','), output.list.join(','));
+          outerThis.showMessage('test_case_duration', millis);
           return Promise.resolve(accumulator);
         } else {
-          outerThis.domConsole.info(`Caso de teste ${name + 1}: OK!`);
-          outerThis.domConsole.info(`Levou ${millis}ms`);
+          outerThis.showMessage('test_case_success', name + 1);
+          outerThis.showMessage('test_case_duration', millis);
           return Promise.resolve(accumulator + 1);
         }
       }
-    }).catch( _ => Promise.resolve(accumulator));
+    }).catch( error => {
+      outerThis.showErrorMessage('test_case_failed_exception', name + 1, error.message);
+      return Promise.resolve(accumulator);
+    });
   }
 
   partialEvaluateTestCase (prog, inputList, outputList, name) {
-    let partial = (accumulator) => this.evaluateTestCase(prog, inputList, outputList, name, accumulator)
-    partial = partial.bind(this);
-    return partial;
+    return this.evaluateTestCase.bind(this, prog, inputList, outputList, name);
   }
 
   checkOutput (aList, bList) {
     for (let i = 0; i < aList.length; i++) {
       const outValue = aList[i];
-      if(outValue != bList[i]) {
+      let castNumberA = parseFloat(outValue);
+      if(!Number.isNaN(castNumberA)) {
+        let castNumberB = parseFloat(bList[i]);
+        if(Number.isNaN(castNumberB)) {
+          return false;
+        }
+        castNumberA = new Decimal(castNumberA);
+        castNumberB = new Decimal(castNumberB);
+        const decimalPlaces = Math.min(castNumberB.dp(), Config.decimalPlaces);
+        Decimal.set({ rounding: Decimal.ROUND_FLOOR});
+        castNumberA = new Decimal(castNumberA.toFixed(decimalPlaces));
+        castNumberB = new Decimal(castNumberB.toFixed(decimalPlaces));
+        const aEqualsB = castNumberA.eq(castNumberB);
+        Decimal.set({ rounding: Decimal.ROUND_HALF_UP});
+        if (!aEqualsB) {
+          return false;
+        }
+      } else if(outValue != bList[i]) {
         return false;
       }
     }
     return true;
   }
+
+  showErrorMessage (errorID, ...args) {
+    this.domConsole.err(LocalizedStrings.getError(errorID, args));
+  }
+
+  showMessage (msgID, ...args) {
+    this.domConsole.info(LocalizedStrings.getMessage(msgID, args));
+  }
 }

+ 3 - 1
ivprogh/js/ast/error/syntaxErrorFactory.js

@@ -1,6 +1,8 @@
-import { LocalizedStrings } from './../../services/localizedStringsService';
+import * as LocalizedStringsService from './../../services/localizedStringsService';
 import { SyntaxError } from './syntaxError';
 
+const LocalizedStrings = LocalizedStringsService.getInstance();
+
 export const SyntaxErrorFactory = Object.freeze({
   extra_lines: () => new SyntaxError(LocalizedStrings.getError("extra_lines")),
   token_missing_one: (expected, token) => {

+ 1 - 1
ivprogh/js/ast/expressions/stringLiteral.js

@@ -9,6 +9,6 @@ export class StringLiteral extends Literal {
   }
 
   toString() {
-    return this.value;
+    return '"' + this.value + '"';
   }
 }

+ 12 - 3
ivprogh/js/ast/ivprogParser.js

@@ -725,6 +725,7 @@ export class IVProgParser {
     } else {
       this.pushScope(IVProgParser.COMMAND);
     }
+    const token = this.getToken();
     this.pos++;
     this.checkOpenParenthesis();
     this.pos++;
@@ -749,11 +750,16 @@ export class IVProgParser {
       } else {
         throw SyntaxErrorFactory.token_missing_list([this.lexer.literalNames[this.lexerClass.RK_IF], '{'], maybeIf);
       }
-      return new Commands.IfThenElse(logicalExpression, cmdBlocks, elseBlock);
+      this.popScope();
+      const cmd = new Commands.IfThenElse(logicalExpression, cmdBlocks, elseBlock);
+      cmd.sourceInfo = SourceInfo.createSourceInfo(token);
+      return cmd;
     }
     this.popScope();
 
-    return new Commands.IfThenElse(logicalExpression, cmdBlocks, null);
+    const cmd = new Commands.IfThenElse(logicalExpression, cmdBlocks, null);
+    cmd.sourceInfo = SourceInfo.createSourceInfo(token);
+    return cmd;
   }
 
   parseFor () {
@@ -777,6 +783,7 @@ export class IVProgParser {
 
   parseWhile () {
     this.pushScope(IVProgParser.BREAKABLE);
+    const token = this.getToken();
     this.pos++;
     this.checkOpenParenthesis();
     this.pos++;
@@ -788,7 +795,9 @@ export class IVProgParser {
     this.consumeNewLines();
     const cmdBlocks = this.parseCommandBlock();
     this.popScope();
-    return new Commands.While(logicalExpression, cmdBlocks);
+    const cmd = new Commands.While(logicalExpression, cmdBlocks);
+    cmd.sourceInfo = SourceInfo.createSourceInfo(token);
+    return cmd;
   }
 
   parseBreak () {

+ 342 - 339
ivprogh/js/iassign-integration-functions.js

@@ -1,18 +1,18 @@
 // Função para ler parâmetros informados pelo iTarefa via URL
 // Apesar de não ser obrigatório, será muito útil para capturar os parâmetros
 function getParameterByName (name, defaultReturn = null) {
-    var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
-    return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defaultReturn;
+  var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
+  return match ? decodeURIComponent(match[1].replace(/\+/g, ' ')) : defaultReturn;
 }
 
 // Criando um object com os parâmetros informados pelo iTarefa
 // Observe que para cada parâmetro, é realizada a chamada do método getParameterByName, implementado acima
 var iLMparameters = {
-    iLM_PARAM_ServerToGetAnswerURL: getParameterByName("iLM_PARAM_ServerToGetAnswerURL"),
-    iLM_PARAM_SendAnswer: getParameterByName("iLM_PARAM_SendAnswer"),
-    iLM_PARAM_AssignmentURL: getParameterByName("iLM_PARAM_AssignmentURL"),
-    iLM_PARAM_Assignment: getParameterByName("iLM_PARAM_Assignment"),
-    lang: getParameterByName("lang", "pt")
+  iLM_PARAM_ServerToGetAnswerURL: getParameterByName("iLM_PARAM_ServerToGetAnswerURL"),
+  iLM_PARAM_SendAnswer: getParameterByName("iLM_PARAM_SendAnswer"),
+  iLM_PARAM_AssignmentURL: getParameterByName("iLM_PARAM_AssignmentURL"),
+  iLM_PARAM_Assignment: getParameterByName("iLM_PARAM_Assignment"),
+  lang: getParameterByName("lang", "pt")
 };
 
 // Set the lang parameter to the localStorage for easy access
@@ -24,93 +24,93 @@ var iLMparameters = {
 // O retorno é um JSON com os dados do exercício ou da resolução
 // Esse retorno será armazenado no banco de dados do Moodle, pelo iTarefa
 function getAnswer () {
-    // Se o parâmetro "iLM_PARAM_SendAnswer" for false,
-    // então trata-se de resolução de atividade
-    if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-        // Montar o retorno com a resposta do aluno
-        var contentToSend = previousContent.split("\n::algorithm::")[0];
-        contentToSend += '\n::algorithm::\n';
-        contentToSend += JSON.stringify(window.program_obj, function(key, value) {
-            if (key == 'dom_object') {
-                return;
-            }
-            return value; 
-        });
+  // Se o parâmetro "iLM_PARAM_SendAnswer" for false,
+  // então trata-se de resolução de atividade
+  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+    // Montar o retorno com a resposta do aluno
+    var contentToSend = previousContent.split("\n::algorithm::")[0];
+    contentToSend += '\n::algorithm::\n';
+    contentToSend += JSON.stringify(window.program_obj, function(key, value) {
+      if (key == 'dom_object') {
+        return;
+      }
+      return value; 
+    });
 
-        contentToSend += '\n::logs::';
-        contentToSend += getTrackingLogs();
+    contentToSend += '\n::logs::';
+    contentToSend += getTrackingLogs();
 
-        return contentToSend;
+    return contentToSend;
 
-    } else {
-        // Montar o retorno com a criação da atividade do professor
-        var ret = ' { ' + prepareTestCases() 
-            + ',\n"settings_data_types": \n' + JSON.stringify($('form[name="settings_data_types"]').serializeArray()) 
-            + ',\n"settings_commands": \n' + JSON.stringify($('form[name="settings_commands"]').serializeArray()) 
-            + ',\n"settings_functions": \n' + JSON.stringify($('form[name="settings_functions"]').serializeArray()) 
-            + ' } ';
-
-        if ($("input[name='include_algo']").is(':checked')) {
-            ret += '\n::algorithm::\n';
-            ret += JSON.stringify(window.program_obj, function(key, value) {
-                
-                if (key == 'dom_object') {
-                    return;
-                }
-                return value; 
-            });
+  } else {
+    // Montar o retorno com a criação da atividade do professor
+    var ret = ' { ' + prepareTestCases() 
+      + ',\n"settings_data_types": \n' + JSON.stringify($('form[name="settings_data_types"]').serializeArray()) 
+      + ',\n"settings_commands": \n' + JSON.stringify($('form[name="settings_commands"]').serializeArray()) 
+      + ',\n"settings_functions": \n' + JSON.stringify($('form[name="settings_functions"]').serializeArray()) 
+      + ' } ';
+
+    if ($("input[name='include_algo']").is(':checked')) {
+      ret += '\n::algorithm::\n';
+      ret += JSON.stringify(window.program_obj, function(key, value) {
+        
+        if (key == 'dom_object') {
+            return;
         }
+        return value; 
+      });
+    }
 
-        return ret;
+    return ret;
 
-    }
+  }
 }
 
 function prepareTestCases () {
-    var ret = ' \n "testcases" : [ '
-    var test_cases_array = $('form[name="test_cases"]').serializeArray();
-    for (var i = 0; i < test_cases_array.length; i = i + 2) {
-        ret += '\n{ ';
-        ret += '\n "input": [';
-        var inps = test_cases_array[i].value.match(/[^\r\n]+/g);
-        if (inps) {
-            for (var j = 0; j < inps.length; j++) {
-                ret += '"' + inps[j] + '"';
-                if ((j + 1) < inps.length) {
-                    ret += ', ';
-                }
-            }
-        }
-        ret += '], \n "output": [';
-        var outs = test_cases_array[i+1].value.match(/[^\r\n]+/g);
-        if (outs) {
-            for (var j = 0; j < outs.length; j++) {
-                ret += '"' + outs[j] + '"';
-                if ((j + 1) < outs.length) {
-                    ret += ', ';
-                }
-            }
+  var ret = ' \n "testcases" : [ '
+  var test_cases_array = $('form[name="test_cases"]').serializeArray();
+  for (var i = 0; i < test_cases_array.length; i = i + 2) {
+    ret += '\n{ ';
+    ret += '\n "input": [';
+    var inps = test_cases_array[i].value.match(/[^\r\n]+/g);
+    if (inps) {
+      for (var j = 0; j < inps.length; j++) {
+        ret += '"' + inps[j] + '"';
+        if ((j + 1) < inps.length) {
+            ret += ', ';
         }
-        ret += ']';
-        ret += '\n}'
-        if ((i + 2) < test_cases_array.length) {
-            ret += ',';
+      }
+    }
+    ret += '], \n "output": [';
+    var outs = test_cases_array[i+1].value.match(/[^\r\n]+/g);
+    if (outs) {
+      for (var j = 0; j < outs.length; j++) {
+        ret += '"' + outs[j] + '"';
+        if ((j + 1) < outs.length) {
+            ret += ', ';
         }
+      }
     }
-    ret += '\n] ';
-    return ret;
+    ret += ']';
+    ret += '\n}'
+    if ((i + 2) < test_cases_array.length) {
+      ret += ',';
+    }
+  }
+  ret += '\n] ';
+  return ret;
 }
 
 // Função chamada pelo iTarefa para receber a nota do aluno na atividade
 // O retorno é um valor entre 0.0 e 1.0
 function getEvaluation () {
-    if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-        // A chamada do método abaixo é obrigatória!
-        // Observe que a chamada parte do iLM para o iTarefa
-        //parent.getEvaluationCallback(window.studentGrade);
+  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+    // A chamada do método abaixo é obrigatória!
+    // Observe que a chamada parte do iLM para o iTarefa
+    //parent.getEvaluationCallback(window.studentGrade);
 
-        runCodeAssessment();
-    }
+    runCodeAssessment();
+  }
 }
 
 
@@ -124,374 +124,377 @@ var previousContent = null;
 // Função para que o iMA leia os dados da atividade fornecidos pelo iTarefa
 function getiLMContent () {
 
-    // O parâmetro "iLM_PARAM_Assignment" fornece o URL do endereço que deve ser
-    // requisitado via AJAX para a captura dos dados da atividade
-    $.get(iLMparameters.iLM_PARAM_Assignment, function (data) {
-        // Aluno está trabalhando em alguma atividade:
-        if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-            previousContent = data;
-            prepareActivityToStudent(data);
-        } else { // Professor está editando uma atividade:
-            previousContent = data;
-            prepareActivityToEdit(data);
-        }
+  // O parâmetro "iLM_PARAM_Assignment" fornece o URL do endereço que deve ser
+  // requisitado via AJAX para a captura dos dados da atividade
+  $.get(iLMparameters.iLM_PARAM_Assignment, function (data) {
+    // Aluno está trabalhando em alguma atividade:
+    if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+      previousContent = data;
+      prepareActivityToStudent(data);
+    } else { // Professor está editando uma atividade:
+      previousContent = data;
+      prepareActivityToEdit(data);
+    }
 
-        window.block_render = false;
-        renderAlgorithm();
-    });
+    window.block_render = false;
+    renderAlgorithm();
+  });
 }
 
 function prepareActivityToEdit (ilm_cont) {
-    var content = JSON.parse(ilm_cont.split('\n::algorithm::')[0]);
-    testCases = content.testcases;
-    settingsDataTypes = content.settings_data_types;
-    settingsCommands = content.settings_commands;
-    settingsFunctions = content.settings_functions;
-
-    for (var i = 0; i < testCases.length; i++) {
-        addTestCase(testCases[i]);
-    }
-
-    if (ilm_cont.split('\n::algorithm::')[1]) {
-        algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
-        $("input[name='include_algo']").prop('checked', true);
-        includePreviousAlgorithm();
-        renderAlgorithm();
-    }
+  var content = JSON.parse(ilm_cont.split('\n::algorithm::')[0]);
+  testCases = content.testcases;
+  settingsDataTypes = content.settings_data_types;
+  settingsCommands = content.settings_commands;
+  settingsFunctions = content.settings_functions;
+
+  for (var i = 0; i < testCases.length; i++) {
+    addTestCase(testCases[i]);
+  }
+
+  if (ilm_cont.split('\n::algorithm::')[1]) {
+    algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
+    $("input[name='include_algo']").prop('checked', true);
+    includePreviousAlgorithm();
+    renderAlgorithm();
+  }
 }
 
 function includePreviousAlgorithm () {
-    window.program_obj.functions = JSON.parse(algorithm_in_ilm).functions;
-    window.program_obj.globals = JSON.parse(algorithm_in_ilm).globals;
+  window.program_obj.functions = JSON.parse(algorithm_in_ilm).functions;
+  window.program_obj.globals = JSON.parse(algorithm_in_ilm).globals;
+
+  window.watchW.watch(window.program_obj.globals, function(){
+    if (window.insertContext) {
+    setTimeout(function(){ renderAlgorithm(); }, 300);
+    window.insertContext = false;
+    } else {
+    renderAlgorithm();
+    }
+  }, 1);
 
-    window.watchW.watch(window.program_obj.globals, function(){
+  for (var i = 0; i < window.program_obj.functions.length; i ++) {
+    window.watchW.watch(window.program_obj.functions[i].parameters_list, function(){
       if (window.insertContext) {
-        setTimeout(function(){ renderAlgorithm(); }, 300);
-        window.insertContext = false;
+      setTimeout(function(){ renderAlgorithm(); }, 300);
+      window.insertContext = false;
       } else {
-        renderAlgorithm();
+      renderAlgorithm();
       }
     }, 1);
 
-    for (var i = 0; i < window.program_obj.functions.length; i ++) {
-        window.watchW.watch(window.program_obj.functions[i].parameters_list, function(){
-          if (window.insertContext) {
-            setTimeout(function(){ renderAlgorithm(); }, 300);
-            window.insertContext = false;
-          } else {
-            renderAlgorithm();
-          }
-        }, 1);
-
-        window.watchW.watch(window.program_obj.functions[i].variables_list, function(){
-          if (window.insertContext) {
-            setTimeout(function(){ renderAlgorithm(); }, 300);
-            window.insertContext = false;
-          } else {
-            renderAlgorithm();
-          }
-        }, 1);
-
-        if (window.program_obj.functions[i].is_main) {
-            window.program_obj.functions[i].name = LocalizedStrings.getUI("start");
-        }
-    }
-    window.watchW.watch(window.program_obj.functions, function(){
+    window.watchW.watch(window.program_obj.functions[i].variables_list, function(){
       if (window.insertContext) {
-        setTimeout(function(){ renderAlgorithm(); }, 300);
-        window.insertContext = false;
+      setTimeout(function(){ renderAlgorithm(); }, 300);
+      window.insertContext = false;
       } else {
-        renderAlgorithm();
+      renderAlgorithm();
       }
     }, 1);
-}
 
-function prepareActivityToStudent (ilm_cont) {
-    var content = JSON.parse(ilm_cont.split('\n::algorithm::')[0]);
-    testCases = content.testcases;
-    settingsDataTypes = content.settings_data_types;
-    settingsCommands = content.settings_commands;
-    settingsFunctions = content.settings_functions;
-
-    if (ilm_cont.split('\n::algorithm::')[1]) {
-        algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
-        includePreviousAlgorithm();
+    if (window.program_obj.functions[i].is_main) {
+      window.program_obj.functions[i].name = LocalizedStrings.getUI("start");
     }
-    $('.assessment_button').removeClass('disabled');
+  }
+  window.watchW.watch(window.program_obj.functions, function(){
+    if (window.insertContext) {
+    setTimeout(function(){ renderAlgorithm(); }, 300);
+    window.insertContext = false;
+    } else {
     renderAlgorithm();
+    }
+  }, 1);
+}
+
+function prepareActivityToStudent (ilm_cont) {
+  var content = JSON.parse(ilm_cont.split('\n::algorithm::')[0]);
+  testCases = content.testcases;
+  settingsDataTypes = content.settings_data_types;
+  settingsCommands = content.settings_commands;
+  settingsFunctions = content.settings_functions;
+
+  if (ilm_cont.split('\n::algorithm::')[1]) {
+    algorithm_in_ilm = ilm_cont.split('\n::algorithm::')[1].split('\n::logs::')[0];
+    includePreviousAlgorithm();
+  }
+  $('.assessment_button').removeClass('disabled');
+  renderAlgorithm();
 }
 
 // Função para organizar se para criação, visualização ou resolução de atividade
 function prepareEnvironment () {
-    if ((iLMparameters.iLM_PARAM_AssignmentURL == "true") && (iLMparameters.iLM_PARAM_SendAnswer == "true")) {
-        prepareActivityCreation();
-    }
+  if ((iLMparameters.iLM_PARAM_AssignmentURL == "true") && (iLMparameters.iLM_PARAM_SendAnswer == "true")) {
+    prepareActivityCreation();
+  }
 }
 
 $(document).ready(function() {
 
-    // Se iLM_PARAM_SendAnswer for false, então trata-se de resolução de atividade,
-    // portanto, a "DIV" de resolução é liberada
-    if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
-        //$('.resolucao').css("display","block");
-        getiLMContent();
+  // Se iLM_PARAM_SendAnswer for false, então trata-se de resolução de atividade,
+  // portanto, a "DIV" de resolução é liberada
+  if (iLMparameters.iLM_PARAM_SendAnswer == 'false') {
+    //$('.resolucao').css("display","block");
+    getiLMContent();
 
+    $( document ).ready(function() {
+    //DEBUG NAO rastrear 'mousemove'
+    //D   $('.div_to_body').mousemove(function(e) {
+    //D     trackingMatrix.push(adCoords(e, 0));
+    //D   });
 
-        $( document ).ready(function() {
-            $('.div_to_body').mousemove(function(e) {
-                trackingMatrix.push(adCoords(e, 0));
-            });
+      $('.div_to_body').click(function(e) {
+        trackingMatrix.push(adCoords(e, 1));                    
+      });
 
-            $('.div_to_body').click(function(e) {
-                trackingMatrix.push(adCoords(e, 1));                    
-            });
+    });
 
-        });
+  } else {
+    // Caso não esteja em modo de resolução de atividade, a visualização no momento
+    // é para a elaboração de atividade:
+    //$('.elaboracao').css("display","block");
 
-    } else {
-        // Caso não esteja em modo de resolução de atividade, a visualização no momento
-        // é para a elaboração de atividade:
-        //$('.elaboracao').css("display","block");
-
-        // Se possuir o parâmetro iLMparameters.iLM_PARAM_Assignment, o professor
-        // está editando uma atividade:
-        if (iLMparameters.iLM_PARAM_Assignment) {
-            getiLMContent();
-        }
+    // Se possuir o parâmetro iLMparameters.iLM_PARAM_Assignment, o professor
+    // está editando uma atividade:
+    if (iLMparameters.iLM_PARAM_Assignment) {
+      getiLMContent();
     }
+  }
 
-    if (!testCases) {
-        $('.assessment_button').addClass('disabled');
-    }
+  if (!testCases) {
+    $('.assessment_button').addClass('disabled');
+  }
 
 });
 
 // Função para preparar a interface para o professor criar atividade:
 function prepareActivityCreation () {
 
-    $('.add_accordion').addClass('accordion');
+  $('.add_accordion').addClass('accordion');
 
-    $('.default_visual_title').toggle();
-    $('.default_visual_title').append('<span>'+LocalizedStrings.getUI('text_teacher_algorithm')+'</span>');
-    $('.height_100').removeClass('height_100');
-    $('.main_title').remove();
-    $('.ui.accordion').addClass('styled');
-    
-    $('<div class="content_margin"></div>').insertBefore($('.add_accordion').find('.content').find('.div_to_body'));
+  $('.default_visual_title').toggle();
+  $('.default_visual_title').append('<span>'+LocalizedStrings.getUI('text_teacher_algorithm')+'</span>');
+  $('.height_100').removeClass('height_100');
+  $('.main_title').remove();
+  $('.ui.accordion').addClass('styled');
+  
+  $('<div class="content_margin"></div>').insertBefore($('.add_accordion').find('.content').find('.div_to_body'));
 
-    $('<div class="ui checkbox"><input type="checkbox" name="include_algo" class="include_algo" tabindex="0" class="hidden"><label>'+LocalizedStrings.getUI('text_teacher_algorithm_include')+'</label></div>').insertAfter('.content_margin');
-    
-    var cases_test_div = $('<div class="ui accordion styled"><div class="active title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case')+'</div><div class="active content"></div></div>');
+  $('<div class="ui checkbox"><input type="checkbox" name="include_algo" class="include_algo" tabindex="0" class="hidden"><label>'+LocalizedStrings.getUI('text_teacher_algorithm_include')+'</label></div>').insertAfter('.content_margin');
+  
+  var cases_test_div = $('<div class="ui accordion styled"><div class="active title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case')+'</div><div class="active content"></div></div>');
 
-    cases_test_div.insertBefore('.accordion');
+  cases_test_div.insertBefore('.accordion');
 
-    var config_div = $('<div class="ui accordion styled"><div class="title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_config')+'</div><div class="content"></div></div>');
+  var config_div = $('<div class="ui accordion styled"><div class="title"><i class="dropdown icon"></i>'+LocalizedStrings.getUI('text_teacher_config')+'</div><div class="content"></div></div>');
 
-    config_div.insertAfter(cases_test_div);
+  config_div.insertAfter(cases_test_div);
 
-    $('.ui.accordion').accordion();
+  $('.ui.accordion').accordion();
 
-    $('.ui.checkbox').checkbox();
+  $('.ui.checkbox').checkbox();
 
-    prepareTableSettings(config_div.find('.content'));
+  prepareTableSettings(config_div.find('.content'));
 
-    prepareTableTestCases(cases_test_div.find('.content'));
+  prepareTableTestCases(cases_test_div.find('.content'));
+
+  if (inIframe()) {
+    $('.ui.styled.accordion').css('width', '96%');
+  }
 }
 
 function prepareTableTestCases (div_el) {
 
-    var table_el = '<form name="test_cases"><table class="ui blue table"><thead><tr><th width="30px">#</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_input')+'</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_output')+'</th><th width="80px">'+LocalizedStrings.getUI('text_teacher_test_case_actions')+'</th></tr></thead>'
-            + '<tbody class="content_cases"></tbody></table></form>';
+  var table_el = '<form name="test_cases"><table class="ui blue table"><thead><tr><th width="30px">#</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_input')+'</th><th>'+LocalizedStrings.getUI('text_teacher_test_case_output')+'</th><th width="80px">'+LocalizedStrings.getUI('text_teacher_test_case_actions')+'</th></tr></thead>'
+      + '<tbody class="content_cases"></tbody></table></form>';
 
-    div_el.append(table_el);
+  div_el.append(table_el);
 
-    div_el.append('<button class="ui teal labeled icon button button_add_case"><i class="plus icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case_add')+'</button>');
+  div_el.append('<button class="ui teal labeled icon button button_add_case"><i class="plus icon"></i>'+LocalizedStrings.getUI('text_teacher_test_case_add')+'</button>');
 
-    $('.button_add_case').on('click', function(e) {
-        addTestCase();
-    });
+  $('.button_add_case').on('click', function(e) {
+    addTestCase();
+  });
 }
 
 var hist = false;
 
 function addTestCase (test_case = null) {
-    var new_row = null;
-    if (test_case) {
-        var text_row = '';
+  var new_row = null;
+  if (test_case) {
+    var text_row = '';
 
-        text_row += '<tr><td class="counter"></td><td class="expandingArea"><textarea rows="'+test_case.input.length+'" name="input" class="text_area_input">';
+    text_row += '<tr><td class="counter"></td><td class="expandingArea"><textarea rows="'+test_case.input.length+'" name="input" class="text_area_input">';
 
-        for (var i = 0; i < test_case.input.length; i ++) {
-            text_row += test_case.input[i];
-            if ((i + 1) < test_case.input.length) {
-                text_row += '\n';
-            }
-        }
-        
-        text_row += '</textarea></td><td class="expandingArea"><textarea rows="'+test_case.output.length+'" name="output" class="text_area_output">';
-
-        for (var i = 0; i < test_case.output.length; i ++) {
-            text_row += test_case.output[i];
-            if ((i + 1) < test_case.output.length) {
-                text_row += '\n';
-            }
-        }
-
-        text_row += '</textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>';
+    for (var i = 0; i < test_case.input.length; i ++) {
+      text_row += test_case.input[i];
+      if ((i + 1) < test_case.input.length) {
+        text_row += '\n';
+      }
+    }
+    
+    text_row += '</textarea></td><td class="expandingArea"><textarea rows="'+test_case.output.length+'" name="output" class="text_area_output">';
 
-        new_row = $(text_row);
-    } else {
-        new_row = $('<tr><td class="counter"></td><td class="expandingArea"><textarea rows="1" name="input" class="text_area_input"></textarea></td><td class="expandingArea"><textarea rows="1" name="output" class="text_area_output"></textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>');
+    for (var i = 0; i < test_case.output.length; i ++) {
+      text_row += test_case.output[i];
+      if ((i + 1) < test_case.output.length) {
+        text_row += '\n';
+      }
     }
-    $('.content_cases').append(new_row);
 
-    new_row.find('.button_remove_case').click(function(e) {
-        new_row.remove();
-        updateTestCaseCounter();
-    });
+    text_row += '</textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>';
 
-    new_row.find('textarea').on('input', function(e) {
-        var lines = $(this).val().split('\n').length;
-        $(this).attr('rows', lines);
-    });
-    
-    updateTestCaseCounter();
+    new_row = $(text_row);
+  } else {
+    new_row = $('<tr><td class="counter"></td><td class="expandingArea"><textarea rows="1" name="input" class="text_area_input"></textarea></td><td class="expandingArea"><textarea rows="1" name="output" class="text_area_output"></textarea></td><td class="btn_actions"><div class="ui button_remove_case"><i class="red icon times large"></i></div></td></tr>');
+  }
+  $('.content_cases').append(new_row);
 
-     $('.text_area_output').keydown(function(e) {
-        var code = e.keyCode || e.which;
-        if (code == 9 && $(this).closest("tr").is(":last-child")) {
-            hist = true;
-            addTestCase();
-        }
-     });
-     if (test_case == null) {
-        if (!hist) {
-            $( ".content_cases tr:last" ).find('.text_area_input').focus();
-         } else {
-            hist = false;
-         }
+  new_row.find('.button_remove_case').click(function(e) {
+    new_row.remove();
+    updateTestCaseCounter();
+  });
+
+  new_row.find('textarea').on('input', function(e) {
+    var lines = $(this).val().split('\n').length;
+    $(this).attr('rows', lines);
+  });
+  
+  updateTestCaseCounter();
+
+   $('.text_area_output').keydown(function(e) {
+    var code = e.keyCode || e.which;
+    if (code == 9 && $(this).closest("tr").is(":last-child")) {
+      hist = true;
+      addTestCase();
+    }
+   });
+   if (test_case == null) {
+    if (!hist) {
+      $( ".content_cases tr:last" ).find('.text_area_input').focus();
+     } else {
+      hist = false;
      }
+   }
 }
 
 function updateTestCaseCounter () {
-    var i = 1;
-    $( ".content_cases" ).find('tr').each(function() {
-      $( this ).find('.counter').text(i);
-      i ++;
-    });
+  var i = 1;
+  $( ".content_cases" ).find('tr').each(function() {
+    $( this ).find('.counter').text(i);
+    i ++;
+  });
 }
 
 function prepareTableSettings (div_el) {
-    div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_data_types')+'</h4>');
-    div_el.append('<form name="settings_data_types"><div class="ui stackable five column grid">'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="integer_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('integer')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="real_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('real')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="text_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="boolean_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('boolean')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="void_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('void')+'</label></div></div>'
-        +'</div></form>');
-
-
-    div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_commands')+'</h4>');
-    div_el.append('<form name="settings_commands"><div class="ui stackable three column grid">'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_read" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_read_var')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_write" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_write_var')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_comment" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_comment')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_attribution" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_attribution')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_functioncall" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_functioncall')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_iftrue" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_iftrue')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_repeatNtimes" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_repeatNtimes')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_while" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_whiletrue')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_dowhile" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_dowhiletrue')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_switch" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_switch')+'</label></div></div>'
-        +'</div></form>');
-
-    div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_functions')+'</h4>');
-    div_el.append('<form name="settings_functions"><div class="ui stackable one column grid">'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_creation" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_functions')+'</label></div></div>'
-        +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_move" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_movement_functions')+'</label></div></div>'
-        +'</div></form>');
-
-    $('.ui.checkbox').checkbox();
+  div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_data_types')+'</h4>');
+  div_el.append('<form name="settings_data_types"><div class="ui stackable five column grid">'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="integer_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('integer')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="real_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('real')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="text_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="boolean_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('boolean')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="void_data_type" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('void')+'</label></div></div>'
+    +'</div></form>');
+
+
+  div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_commands')+'</h4>');
+  div_el.append('<form name="settings_commands"><div class="ui stackable three column grid">'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_read" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_read_var')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_write" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_write_var')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_comment" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_comment')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_attribution" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_attribution')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_functioncall" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_functioncall')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_iftrue" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_iftrue')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_repeatNtimes" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_repeatNtimes')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_while" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_whiletrue')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_dowhile" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_dowhiletrue')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="commands_switch" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_switch')+'</label></div></div>'
+    +'</div></form>');
+
+  div_el.append('<h4 class="ui header">'+LocalizedStrings.getUI('text_teacher_functions')+'</h4>');
+  div_el.append('<form name="settings_functions"><div class="ui stackable one column grid">'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_creation" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_functions')+'</label></div></div>'
+    +'<div class="column"><div class="ui checkbox"><input type="checkbox" name="functions_move" checked tabindex="0" class="hidden small"><label>'+LocalizedStrings.getUI('text_teacher_create_movement_functions')+'</label></div></div>'
+    +'</div></form>');
+
+  $('.ui.checkbox').checkbox();
 
 
 }
 
 function getTrackingLogs () {
-    var ret = "";
-    for (var i = 0; i < trackingMatrix.length; i++) {
-        ret += "\n" + trackingMatrix[i][0] + "," + trackingMatrix[i][1] + "," + trackingMatrix[i][2];
-        if (trackingMatrix[i][2] === 1) {
-            ret += ',"' + trackingMatrix[i][3] + '"';
-        }
+  var ret = "";
+  for (var i = 0; i < trackingMatrix.length; i++) {
+    ret += "\n" + trackingMatrix[i][0] + "," + trackingMatrix[i][1] + "," + trackingMatrix[i][2];
+    if (trackingMatrix[i][3] === 1) {
+      ret += ',' + trackingMatrix[i][3] + ',"' + trackingMatrix[i][4] + '"';
     }
-    return ret;
+  }
+  return ret;
 }
 
 // Tracking mouse movements
 var trackingMatrix = [];
 
 function adCoords(e, code){
-    var x = e.pageX; 
-    var y = e.pageY;
-    if (code === 1) {
-        return [x, y, code, e.target.classList['value']];
-    } else {
-        return [x, y, code];
-    }
+  var x = e.pageX; 
+  var y = e.pageY;
+  if (code === 1) {
+    return [new Date().getTime(), x, y, code, e.target.classList['value']];
+  } else {
+    return [x, y, code];
+  }
 }
 
 $( document ).ready(function() {
 
-    if (inIframe()) {
-        orderIcons();
-        orderWidth();
-    }
-    renderAlgorithm();
+  if (inIframe()) {
+    orderIcons();
+    orderWidth();
+  }
+  renderAlgorithm();
 });
 
 function orderWidth() {
-    $('.ui.raised.container.segment.div_to_body').css('width', '100%');
-    $('.ui.one.column.container.segment.ivprog_visual_panel').css('width', '100%');
+  $('.ui.raised.container.segment.div_to_body').css('width', '100%');
+  $('.ui.one.column.container.segment.ivprog_visual_panel').css('width', '100%');
 }
 
 function orderIcons() {
-    $('.ui.one.column.doubling.stackable.grid.container').css('display', 'none');
-    $('.only_in_frame').css('display', 'block');
-    
+  $('.ui.one.column.doubling.stackable.grid.container').css('display', 'none');
+  $('.only_in_frame').css('display', 'block');
 }
 
 
 function inIframe () {
-    try {
-        return window.self !== window.top;
-    } catch (e) {
-        return true;
-    }
+  try {
+    return window.self !== window.top;
+  } catch (e) {
+    return true;
+  }
 }
 
 
 function full_screen() {
-    // check if user allows full screen of elements. This can be enabled or disabled in browser config. By default its enabled.
-    //its also used to check if browser supports full screen api.
-    if("fullscreenEnabled" in document || "webkitFullscreenEnabled" in document || "mozFullScreenEnabled" in document || "msFullscreenEnabled" in document) {
-        if(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
-            var element = document.getElementById("ui_main_div");
-            //requestFullscreen is used to display an element in full screen mode.
-            if("requestFullscreen" in element) {
-                element.requestFullscreen();
-            } 
-            else if ("webkitRequestFullscreen" in element) {
-                element.webkitRequestFullscreen();
-            } 
-            else if ("mozRequestFullScreen" in element) {
-                element.mozRequestFullScreen();
-            } 
-            else if ("msRequestFullscreen" in element) {
-                element.msRequestFullscreen();
-            }
-        }
-    } else {
-        $('.expand_button').addClass('disabled');
+  // check if user allows full screen of elements. This can be enabled or disabled in browser config. By default its enabled.
+  //its also used to check if browser supports full screen api.
+  if("fullscreenEnabled" in document || "webkitFullscreenEnabled" in document || "mozFullScreenEnabled" in document || "msFullscreenEnabled" in document) {
+    if(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled) {
+      var element = document.getElementById("ui_main_div");
+      //requestFullscreen is used to display an element in full screen mode.
+      if("requestFullscreen" in element) {
+        element.requestFullscreen();
+      } 
+      else if ("webkitRequestFullscreen" in element) {
+        element.webkitRequestFullscreen();
+      } 
+      else if ("mozRequestFullScreen" in element) {
+        element.mozRequestFullScreen();
+      } 
+      else if ("msRequestFullscreen" in element) {
+        element.msRequestFullscreen();
+      }
     }
+  } else {
+    $('.expand_button').addClass('disabled');
+  }
 }

+ 2 - 1
ivprogh/js/io/domConsole.js

@@ -125,7 +125,8 @@ export class DOMConsole {
   }
 
   sendOutput (text) {
-    text.split("\n").forEach(t => {
+    const output = ""+text;
+    output.split("\n").forEach(t => {
       t = t.replace(/\t/g,'&#9;');
       this.write(t)
     });

+ 9 - 2
ivprogh/js/main.js

@@ -1,13 +1,20 @@
 import { runner } from './runner';
-import { initVisualUI } from './visualUI/functions';
-import { LocalizedStrings} from './services/localizedStringsService';
+import { initVisualUI, addFunctionChangeListener,
+  addGlobalChangeListener, removeFunctionListener,
+  removeGlobalListener } from './visualUI/functions';
+import * as LocalizedStringsService from './services/localizedStringsService';
 import { i18nHelper } from "./services/i18nHelper";
 
 const i18n = i18nHelper.i18n
+const LocalizedStrings = LocalizedStringsService.getInstance();
 
 export {
   runner,
   initVisualUI,
+  addFunctionChangeListener,
+  addGlobalChangeListener,
+  removeFunctionListener,
+  removeGlobalListener,
   LocalizedStrings,
   i18n
 }

+ 8 - 6
ivprogh/js/processor/compatibilityTable.js

@@ -127,12 +127,14 @@ export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpre
   try {
     if(leftExpressionType instanceof MultiType && rightExpressionType instanceof MultiType) {
       let newMulti = [];
-      for (let i = 0; i < leftExpressionType.types.length; i++) {
-        const element = leftExpressionType.types[i];
-        if(rightExpressionType.types.indexOf(element) !== -1) {
-          newMulti.push(element);
+      for (let i = 0; i < leftExpressionType.types.length; ++i) {
+        const typeA = leftExpressionType.types[i];
+        for(let j = 0; j < rightExpressionType.types.length; ++i) {
+          const typeB = rightExpressionType.types[j];
+          newMulti.push(resultTypeAfterInfixOp(operator, typeA, typeB));
         }
       }
+      newMulti = newMulti.filter(x => !x.isCompatible(Types.UNDEFINED));
       if(newMulti.length <= 0) {
         if(Config.enable_type_casting) {
           if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
@@ -147,7 +149,7 @@ export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpre
       }
     } else if(leftExpressionType instanceof MultiType) {
       if(leftExpressionType.isCompatible(rightExpressionType)) {
-        return rightExpressionType;
+        return resultTypeAfterInfixOp(operator, rightExpressionType, rightExpressionType);
       } else {
         if(Config.enable_type_casting) {
           if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {
@@ -160,7 +162,7 @@ export function resultTypeAfterInfixOp (operator, leftExpressionType, rightExpre
       }
     } else if(rightExpressionType instanceof MultiType) {
       if(rightExpressionType.isCompatible(leftExpressionType)) {
-        return leftExpressionType;
+        return resultTypeAfterInfixOp(operator, leftExpressionType, leftExpressionType);
       } else {
         if(Config.enable_type_casting) {
           if(leftExpressionType.isCompatible(Types.INTEGER) || leftExpressionType.isCompatible(Types.REAL)) {

+ 38 - 54
ivprogh/js/processor/error/processorErrorFactory.js

@@ -1,31 +1,8 @@
 import { RuntimeError } from './runtimeError';
 import { SemanticError } from './semanticError';
-import { LocalizedStrings } from './../../services/localizedStringsService';
-import { Operators } from '../../ast/operators';
+import * as  LocalizedStringsService from './../../services/localizedStringsService';
 
-function translateType (type, dim) {
-  switch (dim) {
-    case 0:
-      return LocalizedStrings.getUI(type);
-    default:
-      const transType = LocalizedStrings.getUI(type);
-      if(dim === 1)
-        return LocalizedStrings.getUI("vector_string", [transType])
-      else
-        return LocalizedStrings.getUI("matrix_string", [transType])
-  }
-}
-
-function translateOp (op) {
-  switch(op.ord) {
-    case Operators.AND.ord:
-    case Operators.OR.ord:
-    case Operators.NOT.ord:
-      return LocalizedStrings.getUI(op.value);
-    default:
-      return op.value;
-  }
-}
+const LocalizedStrings = LocalizedStringsService.getInstance();
 
 export const ProcessorErrorFactory  = Object.freeze({
   symbol_not_found_full: (id, sourceInfo) => {
@@ -80,38 +57,39 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   incompatible_types_full: (type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      const context = [LocalizedStrings.translateType(type, dim), sourceInfo.line, sourceInfo.column];
       return new SemanticError(LocalizedStrings.getError("incompatible_types_full", context));
     } else {
       return ProcessorErrorFactory.incompatible_types(type, dim);
     }
   },
   incompatible_types: (type, dim) => {
-    const context = [translateType(type, dim)];
+    const context = [LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("incompatible_types", context));
   },
   incompatible_types_array_full: (exp, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [exp, translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      const context = [exp, LocalizedStrings.translateType(type, dim), sourceInfo.line, sourceInfo.column];
       return new SemanticError(LocalizedStrings.getError("incompatible_types_array_full", context));
     } else {
       return ProcessorErrorFactory.incompatible_types_array(exp, type, dim);
     }
   },
   incompatible_types_array: (exp, type, dim) => {
-    const context = [exp, translateType(type, dim)];
+    const context = [exp, LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("incompatible_types_array", context));
   },
-  loop_condition_type_full: (sourceInfo) => {
+  loop_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, sourceInfo.column];
+      const context = [sourceInfo.line, sourceInfo.column, exp];
       return new SemanticError(LocalizedStrings.getError("loop_condition_type_full", context));
     } else {
-      return ProcessorErrorFactory.loop_condition_type();
+      return ProcessorErrorFactory.loop_condition_type(exp);
     }
   },
-  loop_condition_type: () => {
-    return new SemanticError(LocalizedStrings.getError("loop_condition_type"));
+  loop_condition_type: (exp) => {
+    const context = [exp];
+    return new SemanticError(LocalizedStrings.getError("loop_condition_type", context));
   },
   endless_loop_full: (sourceInfo) => {
     if(sourceInfo) {
@@ -124,27 +102,29 @@ export const ProcessorErrorFactory  = Object.freeze({
   endless_loop: () => {
     return new SemanticError(LocalizedStrings.getError("endless_loop"));
   },
-  for_condition_type_full: (sourceInfo) => {
+  for_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, sourceInfo.column];
+      const context = [sourceInfo.line, sourceInfo.column, exp];
       return new SemanticError(LocalizedStrings.getError("for_condition_type_full", context));
     } else {
-      return ProcessorErrorFactory.for_condition_type();
+      return ProcessorErrorFactory.for_condition_type(exp);
     }
   },
-  for_condition_type: () => {
-    return new SemanticError(LocalizedStrings.getError("for_condition_type"));
+  for_condition_type: (exp) => {
+    const context = [exp];
+    return new SemanticError(LocalizedStrings.getError("for_condition_type", context));
   },
-  if_condition_type_full: (sourceInfo) => {
+  if_condition_type_full: (exp, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, sourceInfo.column];
+      const context = [sourceInfo.line, sourceInfo.column, exp];
       return new SemanticError(LocalizedStrings.getError("if_condition_type_full", context));
     } else {
-      return ProcessorErrorFactory.if_condition_type();
+      return ProcessorErrorFactory.if_condition_type(exp);
     }
   },
-  if_condition_type: () => {
-    return new SemanticError(LocalizedStrings.getError("if_condition_type"));
+  if_condition_type: (exp) => {
+    const context = [exp];
+    return new SemanticError(LocalizedStrings.getError("if_condition_type", context));
   },
   invalid_global_var: () => {
     return new RuntimeError(LocalizedStrings.getError("invalid_global_var"))
@@ -155,14 +135,14 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   invalid_case_type_full: (exp, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [exp, translateType(type, dim), sourceInfo.line, sourceInfo.column];
+      const context = [exp, LocalizedStrings.translateType(type, dim), sourceInfo.line, sourceInfo.column];
       return new SemanticError(LocalizedStrings.getError("invalid_case_type_full", context));
     } else {
       return ProcessorErrorFactory.invalid_case_type(exp, type, dim);
     }
   },
   invalid_case_type: (exp, type, dim) => {
-    const context = [exp, translateType(type, dim)];
+    const context = [exp, LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("invalid_case_type", context));
   },
   void_in_expression_full: (id, sourceInfo) => {
@@ -255,26 +235,26 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   invalid_void_return_full: (id, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, id, translateType(type, dim)];
+      const context = [sourceInfo.line, id, LocalizedStrings.translateType(type, dim)];
       return new SemanticError(LocalizedStrings.getError("invalid_void_return_full", context));
     } else {
       return ProcessorErrorFactory.invalid_void_return(id, type, dim);
     }
   },
   invalid_void_return: (id, type, dim) => {
-    const context = [id, translateType(type, dim)];
+    const context = [id, LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("invalid_void_return_full", context));
   },
   invalid_return_type_full: (id, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, id, translateType(type, dim)];
+      const context = [sourceInfo.line, id, LocalizedStrings.translateType(type, dim)];
       return new SemanticError(LocalizedStrings.getError("invalid_return_type_full", context));
     } else {
       return ProcessorErrorFactory.invalid_return_type(id, type, dim);
     }
   },
   invalid_return_type: (id, type, dim) => {
-    const context = [id, translateType(type, dim)];
+    const context = [id, LocalizedStrings.translateType(type, dim)];
     return new SemanticError(LocalizedStrings.getError("invalid_return_type", context));
   },
   invalid_parameters_size_full: (id, expected, actual, sourceInfo) => {
@@ -362,26 +342,26 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   invalid_unary_op_full: (opName, type, dim, sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, translateOp(opName), translateType(type, dim)];
+      const context = [sourceInfo.line, LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(type, dim)];
       return new RuntimeError(LocalizedStrings.getError("invalid_unary_op_full", context));
     } else {
       return ProcessorErrorFactory.invalid_unary_op(opName, type, dim);
     }
   },
   invalid_unary_op: (opName, type, dim) => {
-    const context = [translateOp(opName), translateType(type, dim)];
+    const context = [LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(type, dim)];
     return new RuntimeError(LocalizedStrings.getError("invalid_unary_op", context));
   },
   invalid_infix_op_full: (opName, typeLeft, dimLeft, typeRight, dimRight,  sourceInfo) => {
     if(sourceInfo) {
-      const context = [sourceInfo.line, translateOp(opName), translateType(typeLeft, dimLeft), translateType(typeRight, dimRight)];
+      const context = [sourceInfo.line, LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(typeLeft, dimLeft), LocalizedStrings.translateType(typeRight, dimRight)];
       return new RuntimeError(LocalizedStrings.getError("invalid_infix_op_full", context));
     } else {
       return ProcessorErrorFactory.invalid_infix_op(opName, typeLeft, dimLeft, typeRight, dimRight);
     }
   },
   invalid_infix_op: (opName, typeLeft, dimLeft, typeRight, dimRight) => {
-    const context = [translateOp(opName), translateType(typeLeft, dimLeft), translateType(typeRight, dimRight)];
+    const context = [LocalizedStrings.translateOp(opName), LocalizedStrings.translateType(typeLeft, dimLeft), LocalizedStrings.translateType(typeRight, dimRight)];
     return new RuntimeError(LocalizedStrings.getError("invalid_infix_op", context));
   },
   array_dimension_not_positive_full: (sourceInfo) => {
@@ -394,5 +374,9 @@ export const ProcessorErrorFactory  = Object.freeze({
   },
   array_dimension_not_positive: () => {
     return new SemanticError(LocalizedStrings.getError("array_dimension_not_positive"));
+  },
+  invalid_type_conversion: (value, type, dim) => {
+    const context = [value, LocalizedStrings.translateType(type, dim)];
+    return new RuntimeError(LocalizedStrings.getError("invalid_type_conversion", context));
   }
 });

+ 9 - 10
ivprogh/js/processor/ivprogProcessor.js

@@ -116,7 +116,6 @@ export class IVProgProcessor {
     } else {
       const val = this.ast.functions.find( v => v.name === name);
       if (!!!val) {
-        // TODO: better error message;
         throw ProcessorErrorFactory.function_missing(name);
       }
       return val;
@@ -139,13 +138,14 @@ export class IVProgProcessor {
     }
     funcStore.insertStore('$', returnStoreObject);
     const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
+    const outerRef = this;
     return newFuncStore$.then(sto => {
       this.context.push(Context.FUNCTION);
       this.stores.push(sto);
       return this.executeCommands(sto, func.variablesDeclarations)
-        .then(stoWithVars => this.executeCommands(stoWithVars, func.commands)).then(finalSto => {
-          this.stores.pop();
-          this.context.pop();
+        .then(stoWithVars => outerRef.executeCommands(stoWithVars, func.commands)).then(finalSto => {
+          outerRef.stores.pop();
+          outerRef.context.pop();
           return finalSto;
         });
     });
@@ -209,7 +209,6 @@ export class IVProgProcessor {
   }
 
   executeCommand (store, cmd) {
-
     if(this.forceKill) {
       return Promise.reject("FORCED_KILL!");
     } else if (store.mode === Modes.PAUSE) {
@@ -232,10 +231,10 @@ export class IVProgProcessor {
       return this.executeReturn(store, cmd);
     } else if (cmd instanceof Commands.IfThenElse) {
       return this.executeIfThenElse(store, cmd);
-    } else if (cmd instanceof Commands.While) {
-      return this.executeWhile(store, cmd);
     } else if (cmd instanceof Commands.DoWhile) {
       return this.executeDoWhile(store, cmd);
+    } else if (cmd instanceof Commands.While) {
+      return this.executeWhile(store, cmd);
     } else if (cmd instanceof Commands.For) {
       return this.executeFor(store, cmd);
     } else if (cmd instanceof Commands.Switch) {
@@ -413,7 +412,7 @@ export class IVProgProcessor {
             return store;
           }
         } else {
-          return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo));
+          return Promise.reject(ProcessorErrorFactory.loop_condition_type_full(cmd.expression.toString(), cmd.sourceInfo));
         }
       })
       
@@ -439,7 +438,7 @@ export class IVProgProcessor {
             return Promise.resolve(store);
           }
         } else {
-          return Promise.reject(ProcessorErrorFactory.if_condition_type_full(cmd.sourceInfo));
+          return Promise.reject(ProcessorErrorFactory.if_condition_type_full(cmd.condition.toString(), cmd.sourceInfo));
         }
       });
     } catch (error) {
@@ -456,6 +455,7 @@ export class IVProgProcessor {
       return $value.then(vl => {
 
         if(vl === null && funcType.isCompatible(Types.VOID)) {
+          store.mode = Modes.RETURN;
           return Promise.resolve(store);
         }
 
@@ -694,7 +694,6 @@ export class IVProgProcessor {
     }
     const func = this.findFunction(exp.id);
     if(Types.VOID.isCompatible(func.returnType)) {
-      // TODO: better error message
       return Promise.reject(ProcessorErrorFactory.void_in_expression_full(exp.id, exp.sourceInfo));
     }
     const $newStore = this.runFunction(func, exp.actualParameters, store);

+ 1 - 1
ivprogh/js/processor/lib/io.js

@@ -26,7 +26,7 @@ export function createInputFun () {
       let stoObj = null;
       if (typeToConvert.isCompatible(Types.INTEGER)) {
         const val = toInt(text);
-        stoObj = new StoreObject(Types.INTEGER, val);
+        stoObj = new StoreObject(Types.INTEGER, val.trunc());
       } else if (typeToConvert.isCompatible(Types.REAL)) {
         stoObj = new StoreObject(Types.REAL, toReal(text));
       } else if (typeToConvert.isCompatible(Types.BOOLEAN)) {

+ 25 - 14
ivprogh/js/processor/lib/lang.js

@@ -5,6 +5,8 @@ import { toReal, convertToString } from "./../../typeSystem/parsers";
 import { IVProgParser } from '../../ast/ivprogParser';
 import { RealLiteral, IntLiteral, BoolLiteral } from '../../ast/expressions';
 import { Modes } from '../modes';
+import { MultiType } from '../../typeSystem/multiType';
+import { ProcessorErrorFactory } from '../error/processorErrorFactory';
 
 /**
  * 
@@ -89,14 +91,16 @@ export function createIsBoolFun () {
 export function createCastRealFun () {
   const castRealFun = (sto, _) => {
     const val = sto.applyStore("val");
+    let value = val.value;
     switch (val.type.ord) {
       case Types.INTEGER.ord: {
-        const temp = new StoreObject(Types.REAL, toReal(val.number));
+        value = value.toNumber();
+        const temp = new StoreObject(Types.REAL, toReal(value));
         sto.mode = Modes.RETURN;
         return Promise.resolve(sto.updateStore("$", temp));
       }
       case Types.STRING.ord: {
-        const parser = IVProgParser.createParser(val.value);
+        const parser = IVProgParser.createParser(value);
         try {
           const result = parser.parseTerm();
           if (result instanceof RealLiteral) {
@@ -104,16 +108,17 @@ export function createCastRealFun () {
             sto.mode = Modes.RETURN;
             return Promise.resolve(sto.updateStore("$", temp));
           }
-        } catch (error) { 
-          return Promise.reject("cannot convert string to real");
-        }
+        } catch (error) { }
       }
     }
+    const typeStringInfoArray = Types.REAL.stringInfo();
+    const typeInfo = typeStringInfoArray[0];
+    return Promise.reject(ProcessorErrorFactory.invalid_type_conversion(value, typeInfo.type, typeInfo.dim));
   }
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(castRealFun)]);
   const func = new Commands.Function('$castReal', Types.REAL,
-    [new Commands.FormalParameter(Types.ALL, 'val', false)],
+    [new Commands.FormalParameter(new MultiType([Types.INTEGER, Types.STRING]), 'val', false)],
     block);
   return func;
 }
@@ -121,14 +126,16 @@ export function createCastRealFun () {
 export function createCastIntFun () {
   const castIntFun = (sto, _) => {
     const val = sto.applyStore("val");
+    let value = val.value;
     switch (val.type.ord) {
       case Types.REAL.ord: {
-        const temp = new StoreObject(Types.INTEGER, Math.floor(val.number));
+        value = value.toNumber();
+        const temp = new StoreObject(Types.INTEGER, Math.floor(value));
         sto.mode = Modes.RETURN;
         return Promise.resolve(sto.updateStore("$", temp));
       }
       case Types.STRING.ord: {
-        const parser = IVProgParser.createParser(val.value);
+        const parser = IVProgParser.createParser(value);
         try {
           const result = parser.parseTerm();
           if (result instanceof IntLiteral) {
@@ -136,16 +143,17 @@ export function createCastIntFun () {
             sto.mode = Modes.RETURN;
             return Promise.resolve(sto.updateStore("$", temp));
           }
-        } catch (error) { 
-          return Promise.reject("cannot convert string to real");
-        }
+        } catch (error) { }
       }
     }
+    const typeStringInfoArray = Types.INTEGER.stringInfo();
+    const typeInfo = typeStringInfoArray[0];
+    return Promise.reject(ProcessorErrorFactory.invalid_type_conversion(value, typeInfo.type, typeInfo.dim));
   }
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(castIntFun)]);
   const func = new Commands.Function('$castInt', Types.INTEGER,
-    [new Commands.FormalParameter(Types.ALL, 'val', false)],
+    [new Commands.FormalParameter(new MultiType([Types.REAL, Types.STRING]), 'val', false)],
     block);
   return func;
 }
@@ -153,7 +161,8 @@ export function createCastIntFun () {
 export function createCastBoolFun () {
   const castBoolFun = (sto, _) => {
     const str = sto.applyStore("str");
-    const parser = IVProgParser.createParser(str.value);
+    let value = str.value; 
+    const parser = IVProgParser.createParser(value);
     try {
       const val = parser.parseTerm();
       if (val instanceof BoolLiteral) {
@@ -162,7 +171,9 @@ export function createCastBoolFun () {
         return Promise.resolve(sto.updateStore("$", temp));
       }
     } catch (error) { }
-    return Promise.reject("cannot convert " + str.value + " to boolean");
+    const typeStringInfoArray = Types.BOOLEAN.stringInfo();
+    const typeInfo = typeStringInfoArray[0];
+    return Promise.reject(ProcessorErrorFactory.invalid_type_conversion(value, typeInfo.type, typeInfo.dim));
   }
 
   const block = new Commands.CommandBlock([],  [new Commands.SysCall(castBoolFun)]);

+ 2 - 1
ivprogh/js/processor/lib/math.js

@@ -173,8 +173,9 @@ export function createAbsFun () {
     const x = sto.applyStore('x');
     const result = x.value.abs();
     const temp = new StoreObject(x.type, result);
+    sto.updateStore('$', temp)
     sto.mode = Modes.RETURN;
-    return Promise.resolve(sto.updateStore('$', temp));
+    return Promise.resolve(sto);
   };
 
  const block = new Commands.CommandBlock([],  [new Commands.SysCall(absFun)]);

+ 3 - 4
ivprogh/js/processor/semantic/semanticAnalyser.js

@@ -57,7 +57,6 @@ export class SemanticAnalyser {
   }
 
   findFunction (name) {
-    console.log(name);
     if(name.match(/^\$.+$/)) {
       const fun = LanguageDefinedFunction.getFunction(name);
       if(!!!fun) {
@@ -347,7 +346,7 @@ export class SemanticAnalyser {
     if (cmd instanceof While) {
       const resultType = this.evaluateExpressionType(cmd.expression);
       if (!resultType.isCompatible(Types.BOOLEAN)) {
-        throw ProcessorErrorFactory.loop_condition_type_full(cmd.sourceInfo);
+        throw ProcessorErrorFactory.loop_condition_type_full(cmd.expression.toString(), cmd.sourceInfo);
       }
       this.checkCommands(type, cmd.commands, optional);
       return false;
@@ -355,7 +354,7 @@ export class SemanticAnalyser {
       this.checkCommand(type, cmd.assignment, optional);
       const resultType = this.evaluateExpressionType(cmd.condition);
       if (!resultType.isCompatible(Types.BOOLEAN)) {
-        throw ProcessorErrorFactory.for_condition_type_full(cmd.sourceInfo);
+        throw ProcessorErrorFactory.for_condition_type_full(cmd.condition.toString(), cmd.sourceInfo);
       }
       this.checkCommand(type, cmd.increment, optional);
       this.checkCommands(type, cmd.commands, optional);
@@ -440,7 +439,7 @@ export class SemanticAnalyser {
     } else if (cmd instanceof IfThenElse) {
       const resultType = this.evaluateExpressionType(cmd.condition);
       if (!resultType.isCompatible(Types.BOOLEAN)) {
-        throw ProcessorErrorFactory.if_condition_type_full(cmd.sourceInfo);
+        throw ProcessorErrorFactory.if_condition_type_full(cmd.condition.toString(), cmd.sourceInfo);
       }
       if(cmd.ifFalse instanceof IfThenElse) {
         return this.checkCommands(type, cmd.ifTrue.commands, optional) && this.checkCommand(type, cmd.ifFalse, optional);

+ 3 - 3
ivprogh/js/processor/store/store.js

@@ -17,10 +17,10 @@ export class Store {
     if(!Store.canImplicitTypeCast(castType, stoObj.type)) {
       throw new Error("!!!Critical error: attempted to type cast invalid types");
     }
-    if(Types.INTEGER.isCompatible(castType)) {
-      return new StoreObject(castType, stoObj.value.trunc());
+    if(castType.isCompatible(Types.INTEGER)) {
+      return new StoreObject(Types.INTEGER, stoObj.value.trunc());
     } else {
-      return new StoreObject(castType, stoObj.value);
+      return new StoreObject(Types.REAL, stoObj.value);
     }
   }
 

+ 43 - 2
ivprogh/js/services/localizedStringsService.js

@@ -1,4 +1,45 @@
 import { LanguageService } from "./languageService";
-import line_i18n from 'line-i18n'
+import line_i18n from 'line-i18n';
 import Langs from './../../i18n';
-export const LocalizedStrings = Object.freeze(new line_i18n.LocalizedStrings(LanguageService, Langs, true));
+
+class IVProgLocalizedStrings extends line_i18n.LocalizedStrings {
+
+  constructor(langService, langsJsons, shouldListenToChange =  false) {
+    super(langService, langsJsons, shouldListenToChange);
+  }
+
+  translateType (type, dim) {
+    switch (dim) {
+      case 0:
+        return this.getUI(type);
+      default:
+        const transType = this.getUI(type);
+        if(dim === 1)
+          return this.getUI("vector_string", [transType])
+        else
+          return this.getUI("matrix_string", [transType])
+    }
+  }
+  
+  translateOp (op) {
+    switch(op.ord) {
+      case Operators.AND.ord:
+      case Operators.OR.ord:
+      case Operators.NOT.ord:
+        return this.getUI(op.value);
+      default:
+        return op.value;
+    }
+  }
+}
+
+export const LocalizedStrings = Object.freeze(new IVProgLocalizedStrings(LanguageService, Langs, true));
+
+let _instance = null;
+
+export function getInstance () {
+  if(_instance == null) {
+    _instance = new IVProgLocalizedStrings(LanguageService, Langs);
+  }
+  return _instance;
+}

+ 1 - 1
ivprogh/js/typeSystem/parsers.js

@@ -37,7 +37,7 @@ export function toBool (str) {
   }
 }
 
-function convertBoolToString (bool) {
+export function convertBoolToString (bool) {
   const lexer = LanguageService.getCurrentLexer();
   const instance = new lexer(null);
   if (bool) {

+ 1 - 1
ivprogh/js/util/config.js

@@ -2,7 +2,7 @@ class ConfigObject {
 
   constructor () {
     this.loopTimeout = 5000;
-    this.decimalPlaces = 5;
+    this.decimalPlaces = 8;
     this.intConvertRoundMode = 2;
     this.default_lang = 'pt';
     this.enable_type_casting = true;

+ 2 - 1
ivprogh/js/util/inputTest.js

@@ -1,4 +1,5 @@
 import { Input } from './../io/input';
+import { LocalizedStrings } from '../services/localizedStringsService';
 
 export class InputTest extends Input {
 
@@ -13,7 +14,7 @@ export class InputTest extends Input {
       callback(this.inputList[this.index]);
       this.index++;
     } else {
-      throw new Error('The amount of requests exceeded the amount of available inputs');
+      throw new Error(LocalizedStrings.getError("exceeded_input_request"));
     }
   }
 }

+ 6 - 1
ivprogh/js/visualUI/algorithm.js

@@ -19,7 +19,11 @@ export function renderAlgorithm () {
 	if (window.block_render) {
 		return;
 	}
+	if (window.draging) {
+		return;
+	}
 	window.block_render = true;
+	console.log('rendering algorithm');
 
  	$('.all_functions').children().off();
 	$('.all_functions').empty();
@@ -35,5 +39,6 @@ export function renderAlgorithm () {
 		GlobalsManagement.renderGlobal(window.program_obj.globals[i]);
 	}	
 
-	setTimeout(function(){ window.block_render = false; }, 500);
+	setTimeout(function(){ window.block_render = false; }, 100);
+	console.log('fim do render');
 }

+ 258 - 30
ivprogh/js/visualUI/commands.js

@@ -56,7 +56,10 @@ export function removeCommand (command, function_obj, dom_obj) {
 	return false;
 }
 
+window.function_container_active = null;
+
 export function createFloatingCommand (function_obj, function_container, command_type, mouse_event) {
+
 	var floatingObject;
 
 	switch (command_type) {
@@ -109,29 +112,247 @@ export function createFloatingCommand (function_obj, function_container, command
 			break;
 	}
 
-	floatingObject.draggable({
-		drag: function(evt) {
-	        borderMouseDragCommand(function_obj, function_container, evt);
-	    },
-	    stop: function(evt) {
-	    	function_container.find('.over_command_drag').each(function( index ) {
-				$(this).removeClass('over_command_drag');
-			});
-	    }
-	}).appendTo("body");
+	floatingObject.draggable().appendTo("body");
 
-	floatingObject.mouseup(function(evt) {
+	$('body').mouseup(function(evt) {
 	  manageCommand(function_obj, function_container, evt, command_type);
+	  $('body').off('mouseup');
+	  $('body').off('mouseover');
+	});
+
+	if (!function_container.hasClass('function_div') || function_container.length < 1) {
+		window.mouse_event = mouse_event;
+		function_container = $(mouse_event.originalEvent.srcElement.closest('.function_div'));
+	}
+
+	console.log('function_container', function_container);
+
+	function_container_active = function_container;
+
+	function_container.find('.commands_list_div').on('mousemove', function(evt) {
+	  addGhostDiv(evt);
+	});
+	function_container.find('.commands_list_div').find("*").on('mousemove', function(evt) {
+	  addGhostDiv(evt);
+	});
+
+	function_container.on('mouseout', function(event) {
+		var el = $(document.elementFromPoint(event.clientX, event.clientY));
+		if (el.closest('.commands_list_div').length < 1) {
+			window.ghostDiv.remove();
+		}
 	});
 	
 	floatingObject.css("position", "absolute");
 	mouse_event.type = "mousedown.draggable";
 	mouse_event.target = floatingObject[0];
-	floatingObject.css("left", mouse_event.pageX - 15);
-	floatingObject.css("top", mouse_event.pageY - 15);
+	floatingObject.css("left", mouse_event.pageX - window.divx);
+	floatingObject.css("top", mouse_event.pageY);
 	floatingObject.trigger(mouse_event);
 }
 
+window.divx = 100;
+window.ghostDiv = $('<div class="ghost_div">');
+window.active_container = null;
+
+function addGhostToEmptyBlock (element, evt) {
+
+	$('.ghost_div').remove();
+
+	var container = element.closest('.command_container');
+
+	if (container.hasClass('switch')) {
+		container = $(evt.target).closest('.case_div');		
+	}
+
+	if (!container.hasClass('dowhiletrue') && !container.hasClass('iftrue') && !container.hasClass('repeatNtimes') 
+				&& !container.hasClass('case_div') && !container.hasClass('whiletrue')) {
+		addGhostToNotEmptyBlock(element, evt);
+		return;
+	}
+
+	if (window.active_container != null) {
+		if (window.active_container.is(container)) {
+			console.log('é o mesmo, não mudou!');
+		} else {
+			if (container.length < 1) {
+				container = element.closest('.commands_list_div');
+				if (window.active_container.is(container)) {
+					console.log('é o mesmo command list');
+				} else {
+					console.log('mudou para um command list');
+					window.active_container = container;
+				}
+			} else {
+				console.log('mudou para um outro container?');
+			}
+		}
+	}
+
+	window.active_container = container;
+	if (container.hasClass('iftrue')) {
+		var containerIf = container.find('.commands_if').get(0);
+		var containerElse = container.find('.commands_else').get(0);
+		var topIfDistance = Math.abs(evt.clientY - containerIf.getBoundingClientRect().top);
+		var bottomIfDistance = Math.abs(containerIf.getBoundingClientRect().top + containerIf.getBoundingClientRect().height - evt.clientY);
+		var topElseDistance = Math.abs(evt.clientY - containerElse.getBoundingClientRect().top);
+		var bottomElseDistance = Math.abs(containerElse.getBoundingClientRect().top + containerElse.getBoundingClientRect().height - evt.clientY);
+
+		if (topIfDistance < topElseDistance && topIfDistance < bottomElseDistance) {
+			$(containerIf).append(window.ghostDiv);
+		} else {
+			$(containerElse).append(window.ghostDiv);
+		}
+	} else if (container.hasClass('case_div')) {
+		container.find('.case_commands_block').append(window.ghostDiv);
+	} else {
+		container.find('.block_commands').append(window.ghostDiv);
+	}
+	
+}
+
+function addGhostToNotEmptyBlock (element, evt) {
+
+	$('.ghost_div').remove();
+
+	var container = element.closest('.dowhiletrue, .iftrue, .repeatNtimes, .case_div, .whiletrue');
+
+	//console.log("\n\nNOT EMPTY: ", container);
+
+	//if (window.active_container != null) {
+		
+		
+	//}
+
+	if (container.length < 1) {
+		container = element.closest('.commands_list_div');
+		window.active_container = container;
+		addGhostToFunctionArea(element, evt);
+	} else {
+		//console.log('mudou para um outro container?');
+	}
+
+	window.active_container = container;
+
+	// quem está mais próximo? // Essa regra se aplica somente quando o over está sobre um comando
+	var allfilhos;
+	console.log('olha o container: ', container);
+	if (container.hasClass('iftrue')) {
+		
+		if ($(evt.target).closest('.data_block_if').length > 0) {
+			allfilhos = container.find('.commands_if').children('.command_container');
+		} else if ($(evt.target).closest('.data_block_else').length > 0) {
+			allfilhos = container.find('.commands_else').children('.command_container');
+		} else {
+
+			var containerIf = container.find('.commands_if').get(0);
+			var containerElse = container.find('.commands_else').get(0);
+			var topIfDistance = Math.abs(evt.clientY - containerIf.getBoundingClientRect().top);
+			var bottomIfDistance = Math.abs(containerIf.getBoundingClientRect().top + containerIf.getBoundingClientRect().height - evt.clientY);
+			var topElseDistance = Math.abs(evt.clientY - containerElse.getBoundingClientRect().top);
+			var bottomElseDistance = Math.abs(containerElse.getBoundingClientRect().top + containerElse.getBoundingClientRect().height - evt.clientY);
+
+			if (topIfDistance < topElseDistance && topIfDistance < bottomElseDistance) {
+				allfilhos = $(containerIf).children('.command_container');
+			} else {
+				allfilhos = $(containerElse).children('.command_container');
+			}
+		}
+	} else if (container.hasClass('case_div')) {
+		allfilhos = container.children('.case_commands_block').children('.command_container');
+	} else if (container.hasClass('commands_list_div')) {
+		allfilhos = container.children('.command_container');
+	} else {
+		allfilhos = container.children('.block_commands').children('.command_container');
+	}
+
+	var topDistances = [];
+	var bottomDistances = [];
+
+	for (var i = 0; i < allfilhos.length; i++) {
+		var topD = Math.abs(evt.clientY - allfilhos.get(i).getBoundingClientRect().top);
+		topDistances.push(topD);
+		var botD = Math.abs(allfilhos.get(i).getBoundingClientRect().top + allfilhos.get(i).getBoundingClientRect().height - evt.clientY);
+		bottomDistances.push(botD);
+	}
+
+	console.log('topDistances\n', topDistances, '\nbottomDistances\n', bottomDistances)
+
+	var menorTop = Math.min.apply(null, topDistances);
+	var indiceTop = topDistances.indexOf(menorTop);
+
+	var menorBot = Math.min.apply(null, bottomDistances);
+	var indiceBot = bottomDistances.indexOf(menorBot);
+
+	if (menorTop < menorBot) {
+		window.ghostDiv.insertBefore($(allfilhos.get(indiceTop)));
+	} else {
+		window.ghostDiv.insertAfter($(allfilhos.get(indiceBot)));
+	}
+
+	console.log('distancias: menorTop ', menorTop, ' menorBot ', menorBot);
+}
+
+function addGhostToFunctionArea (undermouse, evt) {
+	$('.ghost_div').remove();
+	var allfilhos = undermouse.closest('.commands_list_div').children('.command_container');
+
+	var topDistances = [];
+	var bottomDistances = [];
+
+	for (var i = 0; i < allfilhos.length; i++) {
+		var topD = Math.abs(evt.clientY - allfilhos.get(i).getBoundingClientRect().top);
+		topDistances.push(topD);
+		var botD = Math.abs(allfilhos.get(i).getBoundingClientRect().top + allfilhos.get(i).getBoundingClientRect().height - evt.clientY);
+		bottomDistances.push(botD);
+	}
+
+	var menorTop = Math.min.apply(null, topDistances);
+	var indiceTop = topDistances.indexOf(menorTop);
+
+	var menorBot = Math.min.apply(null, bottomDistances);
+	var indiceBot = bottomDistances.indexOf(menorBot);
+
+	if (menorTop < menorBot) {
+		window.ghostDiv.insertBefore($(allfilhos.get(indiceTop)));
+	} else {
+		window.ghostDiv.insertAfter($(allfilhos.get(indiceBot)));
+	}
+
+}
+
+function addGhostDiv (evt) {
+
+	console.log('a');
+
+	var undermouse = $(evt.target);
+
+	console.log('undermouse', undermouse);
+
+	if (undermouse.hasClass('ghost_div')) {
+		return;
+	} else if (undermouse.hasClass('commands_list_div')) {
+		addGhostToFunctionArea(undermouse, evt);
+		return;
+	} else if (undermouse.hasClass('block_commands')) {
+		if (undermouse.find('.command_container').length > 0) {
+			addGhostToNotEmptyBlock(undermouse, evt);
+		} else {
+			addGhostToEmptyBlock(undermouse, evt);
+		}
+	} else if (undermouse.hasClass('case_div')) {
+		if (undermouse.find('.case_commands_block').find('.command_container').length > 0) {
+			addGhostToNotEmptyBlock(undermouse, evt);
+		} else {
+			addGhostToEmptyBlock(undermouse, evt);
+		}
+	} else {
+		
+		addGhostToNotEmptyBlock(undermouse, evt);
+		
+	} 
+}
+
 function borderMouseDragCommand (function_obj, function_container, evt) {
 
 	function_container.find('.over_command_drag').each(function( index ) {
@@ -220,9 +441,7 @@ export function renderCommand (command, element_reference, before_after_inside,
 		case Models.COMMAND_TYPES.return:
 			createdElement = ReturnsManagement.renderCommand(command, function_obj);
 			break;
-
 	}
-
 	switch (before_after_inside) {
 		case 1:
 			createdElement.insertBefore(element_reference);
@@ -237,13 +456,6 @@ export function renderCommand (command, element_reference, before_after_inside,
 			break;
 	}
 
-	createdElement.find('.button_remove_command').mouseover(function() {
-    	createdElement.css({'opacity':'.8'});
-	});
-	createdElement.find('.button_remove_command').mouseout(function() { 
-    	createdElement.css({'opacity':'1'});
-	});
-
 }
 
 export function genericCreateCommand (command_type) {
@@ -296,6 +508,8 @@ export function genericCreateCommand (command_type) {
 
 function dragTrash (event) {
 
+	$('.ghost_div').remove();
+
 	var trash = $('<i class="ui icon trash alternate outline"></i>');
 	$('body').append(trash);
 	trash.css('position', 'absolute');
@@ -304,6 +518,9 @@ function dragTrash (event) {
 	trash.css('font-size', '3em');
 	trash.css('display', 'none');
 
+	function_container_active.find('.commands_list_div').off('mousemove');
+	function_container_active.find('.commands_list_div').find("*").off('mousemove');
+
 	trash.fadeIn( 200, function() {
 		trash.fadeOut( 200, function() {
 			trash.remove();
@@ -318,11 +535,27 @@ function manageCommand (function_obj, function_container, event, command_type) {
 	});
 
 	var el = $(document.elementFromPoint(event.clientX, event.clientY));
+
+	if (el.hasClass('ghost_div')) {
+		if (el.closest('.command_container').length < 1) {
+			
+
+			console.log('\n\nvou tentar!!!!');
+
+			console.log(el.closest('.commands_list_div'), '\n\n');
+
+			el.closest('.commands_list_div').css('height', el.closest('.commands_list_div').css('height') + 30);
+			
+			//$('.ghost_div').remove();
+
+			el = el.closest('.commands_list_div');
+		}
+	}
+
 	console.log('soltou no: ');
 	console.log(el);
 	console.log(el.data('fun'));
 
-
 	// Primeiro verificar se ele soltou no espaço da função correta:
 	var hier = el.parentsUntil(".all_functions");
 	var esta_correto = false;
@@ -408,7 +641,6 @@ function manageCommand (function_obj, function_container, event, command_type) {
 
 					is_correct_context = true;
 					break;
-
 				}
 			}
 
@@ -418,8 +650,6 @@ function manageCommand (function_obj, function_container, event, command_type) {
 			}
 		}
 
-		
-
 		// se a hierarquia possuir apenas um elemento, então está na raiz dos comandos: 
 		if (hierarquia_bottom_up.length == 1) {
 			console.log('QQ1');
@@ -461,6 +691,8 @@ function manageCommand (function_obj, function_container, event, command_type) {
 	
 	has_element_created_draged = false;
 	which_element_is_draged = null;
+
+	renderAlgorithm();
 }
 
 function insertCommandInBlockHierar (el, event, function_obj, command_type, hier_dom, hier_obj) {
@@ -504,8 +736,6 @@ function insertCommandInBlockHierar (el, event, function_obj, command_type, hier
 	}
 }
 
-
-
 function findNearbyCommandToAddInBlockScope (el, event, node_list_commands, function_obj, command_type, command_parent) {
 
 	var all_sub = $(node_list_commands).find('div.command_container');
@@ -553,8 +783,6 @@ function findNearbyCommandToAddInBlockScope (el, event, node_list_commands, func
 	}
 }
 
-
-
 function findBeforeOrAfterCommandToAddInsertBlock (el, event, function_obj, command_type) {
 
 	var el_jq = $(el);

+ 3 - 1
ivprogh/js/visualUI/commands/attribution.js

@@ -419,7 +419,9 @@ function addHandlers (command, function_obj, attribution_dom) {
 
 	attribution_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, attribution_dom)) {
-			attribution_dom.fadeOut();
+			attribution_dom.fadeOut(400, function() {
+				attribution_dom.remove();
+			});
 		}
 	});
 

+ 3 - 1
ivprogh/js/visualUI/commands/break.js

@@ -21,7 +21,9 @@ function addHandlers (command, function_obj, break_dom) {
 
 	break_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, break_dom)) {
-			break_dom.fadeOut();
+			break_dom.fadeOut(400, function() {
+				break_dom.remove();
+			});
 		}
 	});
 }

+ 3 - 1
ivprogh/js/visualUI/commands/comment.js

@@ -30,7 +30,9 @@ function addHandlers (command, function_obj, comment_dom) {
 
 	comment_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, comment_dom)) {
-			comment_dom.fadeOut();
+			comment_dom.fadeOut(400, function() {
+				comment_dom.remove();
+			});
 		}
 	});
 }

+ 0 - 5
ivprogh/js/visualUI/commands/contextualized_menu.js

@@ -36,11 +36,6 @@ export function renderMenu (command, dom_where_render, function_obj, dom_command
 
 function addHandlers (command, dom_where_render, function_obj, dom_command) {
 
-	console.log('command, dom_where_render, function_obj, dom_command');
-	console.log(command, dom_where_render, function_obj, dom_command);
-
-	console.log(dom_where_render.parents());
-
 	dom_where_render.find('.menu_commands').dropdown({
       on: 'hover'
     });

+ 6 - 3
ivprogh/js/visualUI/commands/dowhiletrue.js

@@ -9,12 +9,12 @@ import * as ConditionalExpressionManagement from './conditional_expression';
 import * as ContextualizedMenu from './contextualized_menu';
 
 export function createFloatingCommand () {
-	return $('<div class="ui dowhiletrue created_element"> <i class="ui icon small sync"></i> <span> '+ LocalizedStrings.getUI('text_command_do') +' {<br>} ' + LocalizedStrings.getUI('text_code_while') +'(x < 10) </span></div>');
+	return $('<div class="ui dowhiletrue created_element"> <i class="ui icon small sync"></i> <span> '+ LocalizedStrings.getUI('text_command_do') +' <br> ' + LocalizedStrings.getUI('text_code_while') +'(x < 10) </span></div>');
 }
 
 export function renderCommand (command, function_obj) {
 	var ret = '';
-	ret += '<div class="ui dowhiletrue command_container"> <i class="ui icon small random command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="ui context_menu"></div>  <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_command_do') + ' </span>';
+	ret += '<div class="ui dowhiletrue command_container"> <i class="ui icon small sync command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="ui context_menu"></div>  <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_command_do') + ' </span>';
 	ret += '<div class="ui block_commands" data-subblock="" data-idcommand="">';
 	ret += '</div>';
 	ret += ' <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_code_while') + ' </span> <span class="span_command_spec"> ( </span> <div class="conditional_expression"></div> <span class="span_command_spec"> ) </span>';
@@ -22,6 +22,7 @@ export function renderCommand (command, function_obj) {
 
 	var el = $(ret);
 	el.data('command', command);
+	el.find('.block_commands').data('command', command);
 
 	addHandlers(command, function_obj, el);
 
@@ -43,7 +44,9 @@ function addHandlers (command, function_obj, dowhiletrue_dom) {
 
 	dowhiletrue_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, dowhiletrue_dom)) {
-			dowhiletrue_dom.fadeOut();
+			dowhiletrue_dom.fadeOut(400, function() {
+				dowhiletrue_dom.remove();
+			});
 		}
 	});
 }

+ 3 - 1
ivprogh/js/visualUI/commands/functioncall.js

@@ -26,7 +26,9 @@ function addHandlers (command, function_obj, functioncall_dom) {
 
 	functioncall_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, functioncall_dom)) {
-			functioncall_dom.fadeOut();
+			functioncall_dom.fadeOut(400, function() {
+				functioncall_dom.remove();
+			});
 		}
 	});
 }

+ 4 - 1
ivprogh/js/visualUI/commands/iftrue.js

@@ -30,6 +30,7 @@ export function renderCommand (command, function_obj) {
 	el.find('.block_commands').data('command', command);
 	el.find('.data_block_if').data('command', command);
 	el.find('.data_block_else').data('command', command);
+	el.find('.commands_if').data('command', command);
 
 	addHandlers(command, function_obj, el);
 
@@ -54,7 +55,9 @@ function addHandlers (command, function_obj, iftrue_dom) {
 
 	iftrue_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, iftrue_dom)) {
-			iftrue_dom.fadeOut();
+			iftrue_dom.fadeOut(400, function() {
+				iftrue_dom.remove();
+			});
 		}
 	});
 }

+ 3 - 1
ivprogh/js/visualUI/commands/reader.js

@@ -27,7 +27,9 @@ export function renderCommand (command, function_obj) {
 function addHandlers (command, function_obj, reader_dom) {
 	reader_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, reader_dom)) {
-			reader_dom.fadeOut();
+			reader_dom.fadeOut(400, function() {
+				reader_dom.remove();
+			});
 		}
 	});
 }

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 6 - 3
ivprogh/js/visualUI/commands/repeatNtimes.js


+ 4 - 1
ivprogh/js/visualUI/commands/return.js

@@ -21,6 +21,7 @@ export function renderCommand (command, function_obj) {
 		VariableValueMenu.renderMenu(command, command.variable_value_menu, el.find('.var_value_menu_div'), function_obj);
 	} else {
 		el.find('.var_value_menu_div').remove();
+		command.variable_value_menu = null;
 	}
 
 
@@ -31,7 +32,9 @@ function addHandlers (command, function_obj, return_dom) {
 
 	return_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, return_dom)) {
-			return_dom.fadeOut();
+			return_dom.fadeOut(400, function() {
+				return_dom.remove();
+			});
 		}
 	});
 }

+ 3 - 1
ivprogh/js/visualUI/commands/switch.js

@@ -69,7 +69,9 @@ function addHandlers (command, function_obj, switch_dom) {
 
 	switch_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, switch_dom)) {
-			switch_dom.fadeOut();
+			switch_dom.fadeOut(400, function() {
+				switch_dom.remove();
+			});
 		}
 	});
 }

+ 6 - 3
ivprogh/js/visualUI/commands/whiletrue.js

@@ -9,12 +9,12 @@ import * as ConditionalExpressionManagement from './conditional_expression';
 import * as ContextualizedMenu from './contextualized_menu';
 
 export function createFloatingCommand () {
-	return $('<div class="ui whiletrue created_element"> <i class="ui icon small sync"></i> <span> ' + LocalizedStrings.getUI('text_code_while') + ' ( x < 10 ) { } </span></div>');
+	return $('<div class="ui whiletrue created_element"> <i class="ui icon small sync"></i> <span> ' + LocalizedStrings.getUI('text_code_while') + ' ( x < 10 ) <br> </span></div>');
 }
 
 export function renderCommand (command, function_obj) {
 	var ret = '';
-	ret += '<div class="ui whiletrue command_container"> <i class="ui icon small random command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="ui context_menu"></div>  <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_code_while') + ' </span>';
+	ret += '<div class="ui whiletrue command_container"> <i class="ui icon small sync command_drag"></i> <i class="ui icon times red button_remove_command"></i> <div class="ui context_menu"></div>  <span class="span_command_spec"> ' + LocalizedStrings.getUI('text_code_while') + ' </span>';
 	ret += '<span class="span_command_spec"> ( </span> <div class="conditional_expression"></div> <span class="span_command_spec"> ) </span>';
 	ret += ' </span>';
 	ret += '<div class="ui block_commands">';
@@ -24,6 +24,7 @@ export function renderCommand (command, function_obj) {
 
 	var el = $(ret);
 	el.data('command', command);
+	el.find('.block_commands').data('command', command);
 
 	addHandlers(command, function_obj, el);
 
@@ -44,7 +45,9 @@ function addHandlers (command, function_obj, whiletrue_dom) {
 
 	whiletrue_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, whiletrue_dom)) {
-			whiletrue_dom.fadeOut();
+			whiletrue_dom.fadeOut(400, function() {
+				whiletrue_dom.remove();
+			});
 		}
 	});
 }

+ 3 - 1
ivprogh/js/visualUI/commands/writer.js

@@ -69,7 +69,9 @@ function addHandlers (command, function_obj, writer_dom) {
 
 	writer_dom.find('.button_remove_command').on('click', function() {
 		if (CommandsManagement.removeCommand(command, function_obj, writer_dom)) {
-			writer_dom.fadeOut();
+			writer_dom.fadeOut(400, function() {
+				writer_dom.remove();
+			});
 		}
 	});
 

+ 345 - 25
ivprogh/js/visualUI/functions.js

@@ -15,13 +15,16 @@ import { SemanticAnalyser } from '../processor/semantic/semanticAnalyser';
 import { IVProgAssessment } from '../assessment/ivprogAssessment';
 import * as AlgorithmManagement from './algorithm';
 import * as Utils from './utils';
+import VersionInfo from './../../.ima_version.json';
 
-import '../Sortable.js';
+import '../Sortable.js'; 
 
 var counter_new_functions = 0;
 var counter_new_parameters = 0;
+var ivprog_version = VersionInfo.version;
 
-let studentTemp = null;
+const globalChangeListeners = [];
+const functionsChangeListeners = [];
 let domConsole = null;
 window.studentGrade = null;
 window.LocalizedStrings = LocalizedStrings;
@@ -102,21 +105,29 @@ window.watchW = WatchJS;
 
 WatchJS.watch(window.program_obj.globals, function(){
   if (window.insertContext) {
-    setTimeout(function(){ AlgorithmManagement.renderAlgorithm(); }, 300);
+    setTimeout(function() {
+      AlgorithmManagement.renderAlgorithm();
+      globalChangeListeners.forEach(x => x());
+    }, 300);
     window.insertContext = false;
   } else {
     AlgorithmManagement.renderAlgorithm();
+    globalChangeListeners.forEach(x => x());
   }
 }, 1);
 
 WatchJS.watch(window.program_obj.functions, function(){
   if (window.insertContext) {
-    setTimeout(function(){ AlgorithmManagement.renderAlgorithm(); }, 300);
+    setTimeout(function(){
+      AlgorithmManagement.renderAlgorithm();
+      functionsChangeListeners.forEach( x => x());
+    }, 300);
     window.insertContext = false;
   } else {
     AlgorithmManagement.renderAlgorithm();
+    functionsChangeListeners.forEach( x => x());
   }
-}, 0);
+}, 1);
 
 function addFunctionHandler () {
 
@@ -129,8 +140,8 @@ function addFunctionHandler () {
 
   var newe = renderFunction(new_function);
 
-  newe.css('display', 'none');
-  newe.fadeIn();
+  /*newe.css('display', 'none');
+  newe.fadeIn();*/
 }
 
 function addParameter (function_obj, function_container, is_from_click = false) {
@@ -144,8 +155,8 @@ function addParameter (function_obj, function_container, is_from_click = false)
   var newe = renderParameter(function_obj, new_parameter, function_container);
 
   if (is_from_click) {
-    newe.css('display', 'none');
-    newe.fadeIn();
+    /*newe.css('display', 'none');
+    newe.fadeIn();*/
   }
 }
 
@@ -275,10 +286,11 @@ function renderFunctionReturn (function_obj, function_element) {
     function_element.find('.function_return').append(ret);
 }
 
+var cont = 0;
 
 export function renderFunction (function_obj) {
   
-  var appender = '<div class="ui secondary segment function_div list-group-item">';
+  var appender = '<div class="ui secondary segment function_div list-group-item function_cont_'+cont+'">';
 
   if (function_obj.function_comment) {
     //appender += renderComment(function_obj.function_comment, sequence, true, -1);
@@ -308,7 +320,13 @@ export function renderFunction (function_obj) {
 
   appender += '<div class="ui top attached segment variables_list_div"></div>';
 
-  appender += '<div class="ui inline_add_command"><i class="icon plus circle purple"></i><i class="icon circle white back"></i><div class="ui icon button dropdown menu_commands orange" style="float: left;" ><i class="icon code"></i> <div class="menu"> ';
+  
+
+  appender += '<div class="ui bottom attached segment commands_list_div commands_cont_'+cont+'">'
+        + '<div class="ui rail" style="width: 35px; margin-left: -36px;"><div class="ui sticky sticky_cont_'+cont+'" style="top: 50px !important;">';
+
+
+  appender += '<i class="icon plus circle purple"></i><i class="icon circle white back"></i><div class="ui icon button dropdown menu_commands orange" ><i class="icon code"></i> <div class="menu"> ';
   appender += '<a class="item" data-command="'+Models.COMMAND_TYPES.reader+'"><i class="download icon"></i> ' +LocalizedStrings.getUI('text_read_var')+ '</a>'
         + '<a class="item" data-command="'+Models.COMMAND_TYPES.writer+'"><i class="upload icon"></i> '+LocalizedStrings.getUI('text_write_var')+'</a>'
         + '<a class="item" data-command="'+Models.COMMAND_TYPES.comment+'"><i class="quote left icon"></i> '+LocalizedStrings.getUI('text_comment')+'</a>'
@@ -320,9 +338,11 @@ export function renderFunction (function_obj) {
         + '<a class="item" data-command="'+Models.COMMAND_TYPES.dowhiletrue+'"><i class="sync icon"></i> '+LocalizedStrings.getUI('text_dowhiletrue')+'</a>'
         + '<a class="item" data-command="'+Models.COMMAND_TYPES.switch+'"><i class="list icon"></i> '+LocalizedStrings.getUI('text_switch')+'</a>'
         + '<a class="item" data-command="'+Models.COMMAND_TYPES.return+'"><i class="reply icon"></i> '+LocalizedStrings.getUI('text_btn_return')+'</a>'
-        + '</div></div></div>';
+        + '</div></div>';
+
 
-  appender += '<div class="ui bottom attached segment commands_list_div"></div>';
+  appender += '</div></div>'
+        +'</div>';
 
   appender += '</div></div>';
 
@@ -358,25 +378,19 @@ export function renderFunction (function_obj) {
     }
   });
 
+  var function_index = program.functions.indexOf(function_obj);
+
   Sortable.create(appender.find(".variables_list_div")[0], {
     handle: '.ellipsis',
     animation: 100,
     ghostClass: 'ghost',
-    group: 'local_vars_drag_' + program.functions.indexOf(function_obj),
+    group: 'local_vars_drag_' + function_index,
     onEnd: function (evt) {
        updateSequenceLocals(evt.oldIndex, evt.newIndex, function_obj);
     }
   });
 
-  Sortable.create(appender.find(".commands_list_div")[0], {
-    handle: '.command_drag',
-    animation: 100,
-    ghostClass: 'ghost',
-    group: 'commands_drag_' + program.functions.indexOf(function_obj),
-    onEnd: function (evt) {
-       //updateSequenceLocals(evt.oldIndex, evt.newIndex, function_obj);
-    }
-  });
+  addSortableHandler(appender.find(".commands_list_div")[0], function_index);
 
   if (!function_obj.is_main) {
     Sortable.create(appender.find(".container_parameters_list")[0], {
@@ -389,9 +403,285 @@ export function renderFunction (function_obj) {
       }
     });
   }
+
+  var teste  = '.ui.sticky.sticky_cont_'+cont;
+  $(teste).sticky({
+    context: '.ui.bottom.attached.segment.commands_list_div.commands_cont_'+cont,
+    scrollContext: '.ivprog_visual_panel',
+    observeChanges: true,
+    offset: 40,
+    onStick: function (evt) {
+      $(teste).css('top', '20px', 'important');
+    }, 
+    onBottom: function (evt) {
+      $(teste).css('top', '20px', 'important');
+    },
+    onUnstick: function (evt) {
+      $(teste).css('top', '20px', 'important');
+    },
+    onReposition: function (evt) {
+      $(teste).css('top', '20px', 'important');
+    },
+    onScroll: function (evt) {
+      $(teste).css('top', '20px', 'important');
+      if (!isVisible($(teste), $(teste).parent())) {
+        $(teste).removeClass('fixed');
+      }
+    },
+    onTop: function (evt) {
+      $(teste).css('top', '20px', 'important');
+    }
+  });
+  cont ++;
+
   return appender;
 }
 
+function isVisible (element, container) {
+
+  var elementTop = $(element).offset().top,
+      elementHeight = $(element).height(),
+      containerTop = $(container).offset().top,
+      containerHeight = $(container).height() - 30;
+
+  return ((((elementTop - containerTop) + elementHeight) > 0)
+         && ((elementTop - containerTop) < containerHeight));
+}
+
+
+window.evento_drag;
+
+function updateProgramObjDrag () {
+  var nodes = Array.prototype.slice.call( $('.all_functions').children() );
+  var function_index;
+  var start_index;
+  var function_obj;
+  $(evento_drag.item).parentsUntil(".all_functions").each(function (index) {
+    if ($(this).hasClass('function_div')) {
+      function_index = nodes.indexOf(this);
+      start_index = index;
+      function_obj = $(this);
+    }
+  });
+
+  console.log(function_index);
+
+  var path_target = [];
+  $(evento_drag.item).parentsUntil(".all_functions").each(function (index) {
+    if ($(this).hasClass('command_container')) {
+      path_target.push(this);
+    }
+  });
+  if (path_target.length == 0) {
+    //console.log('soltou na raiz, na posição: ' + evento_drag.newIndex + ' mas ainda não sei de onde saiu ');
+  } else {
+    //console.log('soltou dentro de algum bloco, sequência vem logo abaixo (de baixo pra cima): ');
+    //console.log(path_target);
+  }
+
+  var index_each = [];
+  var path_relative = [];
+  for (var i = path_target.length - 1; i >= 0; i --) {
+    console.log('da vez', $(path_target[i + 1]));
+    if (i == (path_target.length - 1)) { // está na raiz
+      var indice_na_raiz = function_obj.find('.command_container').index(path_target[i]);
+      console.log('índice na raiz: ', indice_na_raiz);
+    } else {
+      if ($(path_target[i + 1]).hasClass('iftrue')) {
+        if ($(path_target[i]).parent().hasClass('commands_if')) {
+          path_relative.push('if');
+          index_each.push($(path_target[i]).parent().find('.command_container').index(path_target[i]));
+        } else {
+          path_relative.push('else');
+          index_each.push($(path_target[i]).parent().find('.command_container').index(path_target[i]));
+        }
+      } else if ($(path_target[i + 1]).hasClass('dowhiletrue')) {
+        path_relative.push('dowhiletrue');
+        index_each.push($(path_target[i + 1]).find('.command_container').index(path_target[i]));
+      } else if ($(path_target[i + 1]).hasClass('repeatNtimes')) {
+        path_relative.push('repeatNtimes');
+        index_each.push($(path_target[i + 1]).find('.command_container').index(path_target[i]));
+      } else if ($(path_target[i + 1]).hasClass('whiletrue')) {
+        path_relative.push('whiletrue');
+        index_each.push($(path_target[i + 1]).find('.command_container').index(path_target[i]));
+      } else if ($(path_target[i + 1]).hasClass('switch')) {
+        path_relative.push('switch');
+        //index_each.push($(path_target[i + 1]).find('.command_container').index(path_target[i]));
+      }
+    }
+  }
+  var index_in_block = -1;
+  var is_in_else = $(evento_drag.item).parent().hasClass('commands_else');
+
+  index_in_block = $(evento_drag.item).parent().find('.command_container').index(evento_drag.item);
+
+  var is_in_case_switch = $(evento_drag.item).parent().hasClass('case_commands_block');
+  var index_case_of_switch = -1;
+  if (is_in_case_switch) {
+    index_case_of_switch = $(evento_drag.item).parent().parent().parent().find('.case_div').index($(evento_drag.item).parent().parent());
+  }
+
+  /*console.log('path_relative:');
+  console.log(path_relative);
+  console.log('index_each:');
+  console.log(index_each);
+  console.log('index_in_block:');
+  console.log(index_in_block);
+  console.log('ele está em algum bloco de senão? ');
+  console.log(is_in_else);
+  console.log('ele está dentro de um case de switch?');
+  console.log(is_in_case_switch);
+  console.log('qual é o índice do case: ');
+  console.log(index_case_of_switch);*/
+
+  // encontrar o elemento na árvore:
+  var command_start_point = window.program_obj.functions[function_index].commands[indice_na_raiz];
+  var block_to_insert = command_start_point;
+  for (var i = 0; i < index_each.length; i++) {
+    if (path_relative[i] == "else") {
+      block_to_insert = block_to_insert.commands_else[index_each[i]];
+    } else if (path_relative[i] == "switch") {
+
+    } else {
+      block_to_insert = block_to_insert.commands_block[index_each[i]]
+    }
+  }
+
+  //console.log('command_start_point', command_start_point);
+  //console.log('block_to_insert', block_to_insert);
+
+  // agora tem que alocar o comando na árvore, mas considerar as quatro situações:
+  // (1) se está em um else ou (2) se está em switch ou (3) será um caso padrão ou (4) se será na raiz.
+  
+  if (path_target.length == 0) { // soltou na raiz:
+    window.program_obj.functions[function_index].commands.splice(evento_drag.newIndex, 0, command_in_drag);
+  } else if (is_in_else)  {
+    if (block_to_insert.commands_else) {
+      block_to_insert.commands_else.splice(evento_drag.newIndex, 0, command_in_drag);
+    } else {
+      block_to_insert.commands_else = [];
+      block_to_insert.commands_else.push(command_in_drag);
+    }
+  } else if (is_in_case_switch) {
+
+  } else {
+    // verificar se tem alguma coisa no bloco:
+    if (block_to_insert.commands_block) {
+      block_to_insert.commands_block.splice(evento_drag.newIndex, 0, command_in_drag);
+    } else {
+      block_to_insert.commands_block = [];
+      block_to_insert.commands_block.push(command_in_drag);
+    }
+  }
+
+  window.draging = false;
+  renderAlgorithm();
+  
+
+}
+
+function prepareDragHandler (evt) {
+  window.draging = true;
+
+  var nodes = Array.prototype.slice.call( $('.all_functions').children() );
+  var function_index;
+  var function_obj;
+  $(evt.item).parentsUntil(".all_functions").each(function (index) {
+    if ($(this).hasClass('function_div')) {
+      function_index = nodes.indexOf(this);
+      function_obj = window.program_obj.functions[function_index];
+    }
+  });
+
+  command_in_drag = $(evt.item).data("command");
+
+  //console.log('$(evt.item).parent(): ');
+  //console.log($(evt.item).parent());
+
+  // descobrir qual das quatro situações:
+  if ($(evt.item).parent().hasClass('commands_list_div')) { // está na raiz:
+    if (function_obj.commands.indexOf(command_in_drag) > -1) {
+      function_obj.commands.splice(function_obj.commands.indexOf(command_in_drag), 1);
+    }
+  } else if ($(evt.item).parent().hasClass('commands_else')) { // está no else:
+    if ($(evt.item).parent().data('command').commands_else.indexOf(command_in_drag) > -1) {
+      $(evt.item).parent().data('command').commands_else.splice($(evt.item).parent().data('command').commands_else.indexOf(command_in_drag), 1);
+    }
+  } else if ($(evt.item).parent().hasClass('case_commands_block')) { // está em um switch:
+
+  } else { // caso padrão:
+    if ($(evt.item).parent().data('command').commands_block.indexOf(command_in_drag) > -1) {
+      $(evt.item).parent().data('command').commands_block.splice($(evt.item).parent().data('command').commands_block.indexOf(command_in_drag), 1);
+    }
+  }
+
+}
+
+var command_in_drag;
+
+function addSortableHandler (element, id_function) {
+  var n_group = 'commands_drag_' + id_function;
+  Sortable.create(element, {
+    handle: '.command_drag',
+    ghostClass: 'ghost',
+    animation: 300,
+    group: {name: n_group},
+    onEnd: function (evt) {
+       //updateSequenceLocals(evt.oldIndex, evt.newIndex, function_obj);
+       var itemEl = evt.item;  // dragged HTMLElement
+       evt.to;    // target list
+       evt.from;  // previous list
+       evt.oldIndex;  // element's old index within old parent
+       evt.newIndex;  // element's new index within new parent
+       //console.log('::EVT::');
+       //console.log(evt);
+
+       window.evento_drag = evt;
+
+       try {
+        updateProgramObjDrag();
+       } catch (e) {
+        window.draging = false;
+       }
+    },
+    onStart: function (evt) {
+      //console.log("START::EVT::");
+      //console.log(evt);
+      //console.log("\n\ncommand_in_drag");
+      try {
+        prepareDragHandler(evt);
+      } catch (e) {
+        window.draging = false;
+      }
+    }
+  });
+  element = $(element);
+  element.find(".iftrue").each(function( index ) {
+    addSortableHandler($(this).find(".block_commands")[0], id_function);
+    addSortableHandler($(this).find(".block_commands")[1], id_function);
+  });
+
+  element.find(".repeatNtimes").each(function( index ) {
+    addSortableHandler($(this).find(".block_commands")[0], id_function);
+  });
+
+  element.find(".dowhiletrue").each(function( index ) {
+    addSortableHandler($(this).find(".block_commands")[0], id_function);
+  });
+
+  element.find(".whiletrue").each(function( index ) {
+    addSortableHandler($(this).find(".block_commands")[0], id_function);
+  });
+
+  element.find(".switch").each(function( index ) {
+
+    $(this).find(".case_div").each(function( index ) {
+      addSortableHandler($(this).find(".case_commands_block")[0], id_function);
+    });
+
+  });  
+}
+
 export function initVisualUI () {
   // MUST USE CONST, LET, OR VAR !!!!!!
   const mainDiv = $('#visual-main-div');
@@ -428,6 +718,9 @@ export function initVisualUI () {
   $('.expand_button').on('click', () => {
     full_screen();
   });
+  $('.help_button').on('click', () => {
+    window.open('https://www.usp.br/line/ivprog/', '_blank');
+  });
   $('.main_title h2').prop('title', LocalizedStrings.getUI('text_ivprog_description'));
 }
 
@@ -493,7 +786,7 @@ $( document ).ready(function() {
     }
   });
   $('.help_button').popup({
-    content : LocalizedStrings.getUI("tooltip_help") + ' - ' + LocalizedStrings.getUI("text_ivprog_version"),
+    content : LocalizedStrings.getUI("tooltip_help") + ' - ' + LocalizedStrings.getUI("text_ivprog_version") + ' ' + ivprog_version,
     delay: {
       show: time_show,
       hide: 0
@@ -556,7 +849,6 @@ function updateSequenceFunction (oldIndex, newIndex) {
 function runCodeAssessment () {
   
   window.studentGrade = null;
-  studentTemp = null;
   const strCode = CodeManagement.generate();
   if (strCode == null) {
     return;
@@ -770,6 +1062,11 @@ function renderParameter (function_obj, parameter_obj, function_container) {
 }
 
 function updateParameterName (parameter_var, new_name, parameter_obj_dom, function_obj) {
+  
+  if (parameter_var.name == new_name) {
+    return;
+  }
+
   if (isValidIdentifier(new_name)) {
     if (variableNameAlreadyExists(new_name, function_obj)) {
       Utils.renderErrorMessage(parameter_obj_dom.find('.parameter_div_edit'), LocalizedStrings.getUI('inform_valid_variable_duplicated'));
@@ -803,6 +1100,11 @@ function variableNameAlreadyExists (name_var, function_obj) {
 }
 
 function updateFunctionName (function_var, new_name, function_obj_dom) {
+  
+  if (function_var.name == new_name) {
+    return;
+  }
+  
   if (isValidIdentifier(new_name)) {
     if (functionNameAlreadyExists(new_name)) {
       Utils.renderErrorMessage(function_obj_dom.find('.function_name_div'), LocalizedStrings.getUI('inform_valid_name_duplicated'));
@@ -980,4 +1282,22 @@ function enableNameFunctionUpdate (function_obj, parent_node) {
   });
   input_field.select();
   
+}
+
+export function addFunctionChangeListener (callback) {
+  functionsChangeListeners.push(callback);
+  return functionsChangeListeners.length - 1;
+}
+
+export function addGlobalChangeListener (callback) {
+  globalChangeListeners.push(callback);
+  return globalChangeListeners.length - 1;
+}
+
+export function removeGlobalListener (index) {
+  globalChangeListeners.splice(index, 1);
+}
+
+export function removeFunctionListener (index) {
+  functionsChangeListeners.splice(index);
 }

+ 5 - 0
ivprogh/js/visualUI/globals.js

@@ -33,6 +33,11 @@ function toggleConstant (global_var) {
 }
 
 function updateName (global_var, new_name, global_obj_dom) {
+
+	if (global_var.name == new_name) {
+		return;
+	}
+
 	if (isValidIdentifier(new_name)) {
 		if (globalNameAlreadyExists(new_name)) {
 			Utils.renderErrorMessage(global_obj_dom.find('.editing_name_var'), LocalizedStrings.getUI('inform_valid_global_duplicated'));

+ 4 - 0
ivprogh/js/visualUI/variables.js

@@ -30,6 +30,10 @@ export function addVariable (function_obj, function_container, is_in_click = fal
 
 function updateName (variable_obj, new_name, variable_obj_dom, function_obj) {
 
+	if (variable_obj.name == new_name) {
+		return;
+	}
+
 	if (isValidIdentifier(new_name)) {
 		if (variableNameAlreadyExists(new_name, function_obj)) {
 			Utils.renderErrorMessage(variable_obj_dom.find('.editing_name_var'), LocalizedStrings.getUI('inform_valid_variable_duplicated'));

+ 3 - 0
legacy/version2/index.html

@@ -60,6 +60,9 @@
     <span ng-controller="CommCtrl" id="commCtrl"><center>
      <applet name="iLM" codebase="." archive="iVProg2.jar" code="usp.ime.line.ivprog.Ilm.class"
              width="800" height="650" vspace=10 hspace=10>
+         <img src="img/ivprog_fatorial.png" title="imagem estatica do iVProg2 com algoritmo para fatorial"/>
+         <br/>
+         Se estiver vendo uma imagem estática é porque seu navegador não consegue interpretar "applet" Java.
          <param name="iLM_PARAM_Assignment" value="content_repository/activity_ivprog2_simula_form_recursiva_hanoi.ivp2">
          <param name="lang" value="pt"/>
          <param name="MA_PARAM_PropositionURL" value="true"/>

+ 13 - 1
legacy/version2/index.html~

@@ -22,7 +22,17 @@
 
     <div class="bloco">
     <p>
-    O <i>iVProg</i> &eacute; um sistema para 
+      O <i>iVProg</i> &eacute; um sistema para ensino-aprendizagem de algoritmos e programa&ccedil;&atilde;o, que
+      pode ser usado desde o ensino fundamental II at&eacute; o ensino superior. Para isso, ele implementa o paradigma de
+      <b>Programa&ccedil;&atilde;o Visual</b> e permitir a avalia&ccedil;&atilde;o autom&aacute;tica de exerc&iacute;cios
+      (a partir de casos-de-teste).
+      <br/>
+      Nós tamb&eacute;m disponibilizamos uma vers&atilde;o em <i>HTML5</i>, que pode ser examinada a partir
+      <a href="http://www.matematica.br/ivprogh5" title="iVProg em HTML5">desse endere&ccedil;o</a>).
+      <br/>
+      Ambos os sistema s&atilde;o livres e seus códigos fonte podem ser examinados a partir dos seguintes endere&ccedil;os:
+      <a href="https://github.com/LInE-IME-USP/ivp2java" title="iVProg2 em Java">iVProg2 no GitHub</a> e
+      <a href="https://github.com/LInE-IME-USP/ivprog-html" title="iVProg em HTML5">iVProgH no GitHub</a>.
     </p>
     </div> <!-- class="bloco" -->
     
@@ -50,6 +60,8 @@
     <span ng-controller="CommCtrl" id="commCtrl"><center>
      <applet name="iLM" codebase="." archive="iVProg2.jar" code="usp.ime.line.ivprog.Ilm.class"
              width="800" height="650" vspace=10 hspace=10>
+	 <img src="img/ivprog_fatorial.png" title="imagem estatica do iVProg2 com algoritmo para fatorial"/>
+	 Se estiver vendo uma imagem estática é porque seu navegador não consegue interpretar "applet" Java.
          <param name="iLM_PARAM_Assignment" value="content_repository/activity_ivprog2_simula_form_recursiva_hanoi.ivp2">
          <param name="lang" value="pt"/>
          <param name="MA_PARAM_PropositionURL" value="true"/>