diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts b/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts
index 26bc47f5ac42f9e9f2638ffc14a692629af19143..8149c332baa0e1ff11ba97267684f550fcf56b25 100755
--- a/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts	
@@ -281,26 +281,29 @@ export class MateFunComponent {
     var y = cm.getCursor().ch;
     x = (Number(x) + 1).toString();
     y = (Number(y) + 1).toString();
-    var cursorPositionTranslate = this.translateService.get(
-      "i18n.msg.codemirror.cursorPosition"
-    ).value;
-    this.cursorPanelLabel.textContent =
-      cursorPositionTranslate + ": (" + x + "," + y + ")";
 
     this.cursorPanel = this.codemirror.first.instance.addPanel(node, {
       position: "bottom",
       stable: true,
     });
-    var that = this;
-    //agregamos el evento que setea la posición
-    this.codemirror.first.instance.on("cursorActivity", function (cm) {
-      var x = cm.getCursor().line;
-      var y = cm.getCursor().ch;
-      x = (Number(x) + 1).toString();
-      y = (Number(y) + 1).toString();
-      that.cursorPanel.node.innerText =
-        cursorPositionTranslate + ": (" + x + "," + y + ")";
-    });
+
+    const that = this;
+    this.translateService
+      .get("i18n.msg.codemirror.cursorPosition")
+      .subscribe((res) => {
+        // Se configura la posición inicial del cursor
+        this.cursorPanelLabel.textContent = res + ": (" + x + "," + y + ")";
+
+        // Agregamos el evento que setea la posición
+        this.codemirror.first.instance.on("cursorActivity", (codeMirror) => {
+          let x = codeMirror.getCursor().line;
+          let y = codeMirror.getCursor().ch;
+
+          x = (Number(x) + 1).toString();
+          y = (Number(y) + 1).toString();
+          that.cursorPanel.node.innerText = res + ": (" + x + "," + y + ")";
+        });
+      });
 
     this.codemirror.first.instance.on("keyHandled", function (cm, name, evt) {
       if (name.code === "Digit1" && name.ctrlKey && name.shiftKey) {
diff --git a/Frontend Angular 4/src/app/shared/services/ghci.service.ts b/Frontend Angular 4/src/app/shared/services/ghci.service.ts
index 2e07626375a29fe5312801d6918f18b9c7f726eb..21a7aa298517f7c333c18245b6ce778fe7065402 100755
--- a/Frontend Angular 4/src/app/shared/services/ghci.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/ghci.service.ts	
@@ -23,12 +23,19 @@ export class GHCIService {
   private warnings: any = [];
   private codemirrorRef: any = null;
   private warningStepReaded: number = 0;
+
+  /**
+   * Ante la aparición de un mensaje de error (OUTError), se espera por el
+   * próximo mensaje que deberá ser la descripción del error. Este mensaje
+   * comenzará con "OUT"
+   */
   private waitingForError: boolean = false;
+
   private waitingForWarning: boolean = false;
   private waitingForWarning2: boolean = false;
   private warningText: string = "";
   private errorText: string = "";
-  private lastError: number = -1;
+  private lastErrorLineNumber: number = -1;
   private lastErrorFile: string = "";
   private lastWarning: number = -1;
   private lastWarningFile: string = "";
@@ -152,38 +159,47 @@ export class GHCIService {
       setTimeout(this.checkConsole.bind(this), 100);
     }
   }
-  hayError(text) {
-    var line = -1;
+
+  hayError(text: string) {
+    // Si se está esperando por la descripción del error
     if (this.waitingForError) {
-      var line = this.lastError;
+      // WA para manejar el tema de las traducciones asincronicas. Dado que no,
+      // hay una buena forma de manejar las traducciones asincronicas con los
+      // returns asincronicos, se opta por "hardcodear" las traducciones según
+      // el idioma. Este mecanismo funcionaba previamente, pero desde Angular 5
+      // las traducciones pasaron a ser asincronicas, cosa que no había sido
+      // pensado para la arquitectura actual.
+      const language = this.authService.getLanguage();
+      const traduccionColumna = language == "es" ? "columna" : "column";
+      const traduccionEnColumna = language == "es" ? "En columna" : "In column";
+
       var columna = this.errorText
-        .split(
-          `${
-            this.translateService.get("i18n.codemirror.command.column").value
-          }:`
-        )[1]
+        .split(`${traduccionColumna}:`)[1]
         .split("}")[0];
-      var ErrorTextToShow = JSON.parse(text).resultado.split("OUT")[1].trim();
 
-      var ErrorFinalText =
-        `${
-          this.translateService.get("i18n.codemirror.command.inColumn").value
-        }` +
-        columna +
-        ": " +
-        ErrorTextToShow;
+      var errorTextToShow = JSON.parse(text).resultado.split("OUT")[1].trim();
+
+      var errorFinalText =
+        traduccionEnColumna + columna + ": " + errorTextToShow;
 
       if (
-        this.currentFile.toLowerCase() == this.lastErrorFile.toLowerCase() &&
+        this.currentFile.split(" ").join("").toLowerCase() ==
+          this.lastErrorFile.toLowerCase() &&
         this.codemirrorRef !== null
       ) {
-        var makeMarker = function () {
+        /**
+         * Crea un gutter para mostrar el mensaje de error
+         * @returns Gutter para mostrar el mensaje de error
+         */
+        const makeMarker = () => {
           var marker = document.createElement("div");
-          marker.id = "error_" + line.toString();
+
+          marker.id = "error_" + this.lastErrorLineNumber.toString();
           marker.style.width = "15px";
-          marker.title = ErrorFinalText;
+          marker.title = errorFinalText;
           marker.style.height = "15px";
-          marker.style.marginLeft = "-5px";
+          marker.style.marginLeft = "-15px";
+          marker.style.marginTop = "1px";
           marker.style.cursor = "pointer";
           marker.style["background-image"] =
             "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=')";
@@ -191,52 +207,56 @@ export class GHCIService {
             "<a href='@' title='cuidado , advertencia matefun'></a>";
           return marker;
         };
-        this.codemirrorRef.setGutterMarker(line, "breakpoints", makeMarker());
+
+        this.codemirrorRef.setGutterMarker(
+          this.lastErrorLineNumber,
+          "breakpoints",
+          makeMarker()
+        );
         this.waitingForError = false;
-        this.lastError = -1;
+        this.lastErrorLineNumber = -1;
       }
     } else {
       try {
-        var m = JSON.parse(text);
-        var file = m.resultado
-          .split(
-            `${
-              this.translateService.get("i18n.codemirror.command.outError")
-                .value
-            }:`
-          )[1]
-          .trim()
-          .split(`${this.translateService.get("i18n.object.file").value}:`)[1]
-          .split(" ")[1];
+        const message: { tipo: string; resultado: string } = JSON.parse(text);
 
-        var line =
-          m.resultado
-            .split(
-              `${
-                this.translateService.get("i18n.codemirror.command.outError")
-                  .value
-              }:`
-            )[1]
-            .trim()
-            .split(
-              `${
-                this.translateService.get("i18n.codemirror.command.line").value
-              }:`
-            )[1]
-            .split(" ")[1] - 1;
+        // Se filtran los tipos de mensajes
+        if (
+          message.tipo == "ack" ||
+          !message.resultado.startsWith("OUTError")
+        ) {
+          return;
+        }
 
+        // Se espera ahora la descripción del error
         this.waitingForError = true;
-        this.lastError = line;
-        this.lastErrorFile = file;
-        this.errorText = m.resultado
-          .split(
-            `${
-              this.translateService.get("i18n.codemirror.command.outError")
-                .value
-            }:`
-          )[1]
-          .trim();
+
+        // Se obtiene la traducción de file
+        this.translateService.get("i18n.object.file").subscribe((res) => {
+          const fileNameSeparator = "OUTError: {" + res + ": ";
+
+          const fileNameAndMore = message.resultado.replace(
+            fileNameSeparator,
+            ""
+          );
+
+          const fileName = fileNameAndMore.split(" ")[0];
+
+          // Se obtiene la traducción de line
+          this.translateService
+            .get("i18n.codemirror.command.line")
+            .subscribe((line) => {
+              const lineNumber =
+                Number(fileNameAndMore.split(` ${line}: `)[1].split(" ")[0]) -
+                1;
+
+              this.lastErrorLineNumber = lineNumber;
+              this.lastErrorFile = fileName;
+              this.errorText = fileNameAndMore.trim();
+            });
+        });
       } catch (err) {}
+
       return false;
     }
   }
@@ -251,6 +271,16 @@ export class GHCIService {
     var line = -1;
     var m = JSON.parse(text);
 
+    // WA para manejar el tema de las traducciones asincronicas. Dado que no,
+    // hay una buena forma de manejar las traducciones asincronicas con los
+    // returns asincronicos, se opta por "hardcodear" las traducciones según
+    // el idioma. Este mecanismo funcionaba previamente, pero desde Angular 5
+    // las traducciones pasaron a ser asincronicas, cosa que no había sido
+    // pensado para la arquitectura actual.
+    const language = this.authService.getLanguage();
+    const traduccionColumna = language == "es" ? "columna" : "column";
+    const traduccionEnColumna = language == "es" ? "En columna" : "In column";
+
     if (this.warningStepReaded === 1) {
       try {
         var warningText2 = m.resultado.split("OUT")[1].trim();
@@ -260,22 +290,11 @@ export class GHCIService {
         var line = this.lastWarning;
         var title = this.warningText;
 
-        var columna = title
-          .split(
-            `${
-              this.translateService.get("i18n.codemirror.command.column").value
-            }:`
-          )[1]
-          .split("}")[0];
+        var columna = title.split(`${traduccionColumna}:`)[1].split("}")[0];
         var warningTextToShow = title.split("}")[1];
 
         var warningFinalText =
-          `${
-            this.translateService.get("i18n.codemirror.command.inColumn").value
-          }` +
-          columna +
-          ": " +
-          warningTextToShow;
+          traduccionEnColumna + columna + ": " + warningTextToShow;
 
         if (
           this.currentFile.toLowerCase() ==
@@ -286,7 +305,8 @@ export class GHCIService {
             var marker = document.createElement("div");
             marker.style.width = "15px";
             marker.style.height = "15px";
-            marker.style.marginLeft = "-5px";
+            marker.style.marginLeft = "-15px";
+            marker.style.marginTop = "1px";
             marker.style.cursor = "pointer";
             marker.innerHTML =
               "<a href='@' title='cuidado , advertencia matefun'></a>";
@@ -364,7 +384,7 @@ export class GHCIService {
     if (this.clear) {
       this.clearConsole();
     }
-    var server_message = e.data;
+    const server_message = e.data;
 
     if (this.hayError(server_message)) {
       this.error = "Error";