From d9af8afc748915d0e950b30ee72a040e2150fa51 Mon Sep 17 00:00:00 2001
From: Nicolas Camera <nicolas.camera.lopez@fing.edu.uy>
Date: Thu, 29 Sep 2022 00:48:13 -0300
Subject: [PATCH] =?UTF-8?q?Primera=20versi=C3=B3n=20de=20actualizar=20a=20?=
 =?UTF-8?q?Angular=205?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Hay que ajustar algunas cosas de Bootstrap, el consumo de la API con el Back-end en el response y que siga funcionando el codemirror que dejó de tener soporte a partir de Angular 4.
---
 Frontend Angular 4/e2e/app.e2e-spec.ts        |    8 +-
 Frontend Angular 4/e2e/app.po.ts              |    6 +-
 Frontend Angular 4/e2e/tsconfig.e2e.json      |    5 +-
 Frontend Angular 4/package-lock.json          |  671 +---
 Frontend Angular 4/package.json               |   36 +-
 .../src/app/app-routing.module.ts             |   50 +-
 .../src/app/app.component.spec.ts             |   24 +-
 Frontend Angular 4/src/app/app.component.ts   |   36 +-
 Frontend Angular 4/src/app/app.module.ts      |   70 +-
 .../archivos/archivos-routing.module.ts       |   16 +-
 .../app/layout/archivos/archivos.component.ts | 1150 +++---
 .../app/layout/archivos/archivos.module.ts    |   90 +-
 .../archivos/compartirArchivo.component.ts    |  147 +-
 .../archivos/confirmarEliminar.component.ts   |  128 +-
 .../src/app/layout/archivos/index.ts          |    2 +-
 .../layout/archivos/nuevoArchivo.component.ts |  159 +-
 .../seleccionarDirectorio.component.ts        |  182 +-
 .../archivos/verCalificacion.component.ts     |   76 +-
 .../src/app/layout/canvas/canvas.component.ts | 2129 +++++-----
 .../src/app/layout/canvas/canvas.module.ts    |   21 +-
 .../src/app/layout/canvas/canvas.routes.ts    |   12 +-
 .../src/app/layout/canvas/index.ts            |    4 +-
 .../grupos/calificarEntrega.component.ts      |  178 +-
 .../layout/grupos/grupos-routing.module.ts    |   16 +-
 .../app/layout/grupos/grupos.component.html   |  356 +-
 .../src/app/layout/grupos/grupos.component.ts |  365 +-
 .../src/app/layout/grupos/grupos.module.ts    |   57 +-
 .../src/app/layout/layout-routing.module.ts   |   35 +-
 .../src/app/layout/layout.component.spec.ts   |   13 +-
 .../src/app/layout/layout.component.ts        |   36 +-
 .../src/app/layout/layout.module.ts           |   56 +-
 .../app/layout/matefun/confirm.component.ts   |   59 +-
 .../src/app/layout/matefun/index.ts           |    4 +-
 .../layout/matefun/matefun-routing.module.ts  |   16 +-
 .../app/layout/matefun/matefun.component.html |  587 ++-
 .../app/layout/matefun/matefun.component.ts   | 1501 +++----
 .../src/app/layout/matefun/matefun.module.ts  |   76 +-
 .../src/app/layout/matefun/matefun.routes.ts  |   12 +-
 .../seleccionarDirectorio.component.ts        |  267 +-
 .../animation-control.component.ts            |   15 +-
 .../plotter/graph2D/graph2D.component.ts      | 3528 +++++++++--------
 .../layout/plotter/graph2D/graph2D.helper.ts  |   68 +-
 .../layout/plotter/graph2D/graph2D.module.ts  |   43 +-
 .../layout/plotter/graph2D/graph2D.routes.ts  |   12 +-
 .../src/app/layout/plotter/graph2D/index.ts   |    4 +-
 .../plotter/graph3D/graph3D.component.spec.ts |   13 +-
 .../plotter/graph3D/graph3D.component.ts      |  179 +-
 .../layout/plotter/graph3D/graph3D.helper.ts  |   94 +-
 .../layout/plotter/graph3D/graph3D.module.ts  |   52 +-
 .../src/app/login/login-routing.module.ts     |   14 +-
 .../src/app/login/login.component.spec.ts     |   13 +-
 .../src/app/login/login.component.ts          |  209 +-
 .../src/app/login/login.module.ts             |   26 +-
 .../app/not-found/not-found-routing.module.ts |   19 +-
 .../src/app/not-found/not-found.component.ts  |   25 +-
 .../src/app/not-found/not-found.module.ts     |   18 +-
 .../notificacion/notificacion.component.ts    |   60 +-
 .../app/notificacion/notificacion.module.ts   |   20 +-
 .../header/header.component.spec.ts           |   13 +-
 .../components/header/header.component.ts     |   75 +-
 .../src/app/shared/components/index.ts        |    4 +-
 .../sidebar/sidebar.component.spec.ts         |   13 +-
 .../components/sidebar/sidebar.component.ts   |   97 +-
 .../directives/closePopover.directive.ts      |   30 +-
 .../shared/directives/directives.module.ts    |   12 +-
 .../src/app/shared/guards/auth.guard.spec.ts  |   10 +-
 .../src/app/shared/guards/auth.guard.ts       |   33 +-
 Frontend Angular 4/src/app/shared/index.ts    |    6 +-
 .../src/app/shared/modal/confirm.component.ts |   59 +-
 .../src/app/shared/modules/index.ts           |    6 +-
 .../page-header/page-header.component.spec.ts |   13 +-
 .../page-header/page-header.component.ts      |   12 +-
 .../modules/page-header/page-header.module.ts |   19 +-
 .../modules/stat/stat.component.spec.ts       |   13 +-
 .../app/shared/modules/stat/stat.component.ts |   24 +-
 .../app/shared/modules/stat/stat.module.ts    |   16 +-
 .../app/shared/modules/titlecase.module.ts    |   12 +-
 .../src/app/shared/objects/archivo.ts         |   13 +-
 .../src/app/shared/objects/grupo.ts           |   20 +-
 .../src/app/shared/objects/usuario.ts         |   26 +-
 .../src/app/shared/pipes/filter.pipe.ts       |   18 +-
 .../app/shared/pipes/shared-pipes.module.ts   |   12 +-
 .../src/app/shared/pipes/titlecase.pipe.ts    |   21 +-
 .../shared/services/authentication.service.ts |  104 +-
 .../src/app/shared/services/ghci.service.ts   | 1156 +++---
 .../app/shared/services/haskell.service.ts    |  306 +-
 .../shared/services/notificacion.service.ts   |  100 +-
 .../app/shared/services/session.service.ts    |  349 +-
 .../app/shared/services/usuario.service.ts    |   87 +-
 .../app/shared/services/websocket.service.ts  |   65 +-
 .../src/app/shared/utils/sha1.ts              |  292 +-
 Frontend Angular 4/src/index.html             |   58 +-
 Frontend Angular 4/src/main.ts                |    8 +-
 Frontend Angular 4/src/polyfills.ts           |   40 +-
 Frontend Angular 4/src/test.ts                |   20 +-
 Frontend Angular 4/tsconfig.json              |   10 +-
 Frontend Angular 4/tslint.json                |   51 +-
 97 files changed, 8616 insertions(+), 7675 deletions(-)

diff --git a/Frontend Angular 4/e2e/app.e2e-spec.ts b/Frontend Angular 4/e2e/app.e2e-spec.ts
index 0bcefd88..c10a8a03 100755
--- a/Frontend Angular 4/e2e/app.e2e-spec.ts	
+++ b/Frontend Angular 4/e2e/app.e2e-spec.ts	
@@ -1,14 +1,14 @@
-import { CliStablePage } from './app.po';
+import { CliStablePage } from "./app.po";
 
-describe('cli-stable App', () => {
+describe("cli-stable App", () => {
   let page: CliStablePage;
 
   beforeEach(() => {
     page = new CliStablePage();
   });
 
-  it('should display message saying app works', () => {
+  it("should display message saying app works", () => {
     page.navigateTo();
-    expect(page.getParagraphText()).toEqual('app works!');
+    expect(page.getParagraphText()).toEqual("app works!");
   });
 });
diff --git a/Frontend Angular 4/e2e/app.po.ts b/Frontend Angular 4/e2e/app.po.ts
index 11ce66a9..80d5a639 100755
--- a/Frontend Angular 4/e2e/app.po.ts	
+++ b/Frontend Angular 4/e2e/app.po.ts	
@@ -1,11 +1,11 @@
-import { browser, element, by } from 'protractor';
+import { browser, element, by } from "protractor";
 
 export class CliStablePage {
   navigateTo() {
-    return browser.get('/');
+    return browser.get("/");
   }
 
   getParagraphText() {
-    return element(by.css('app-root h1')).getText();
+    return element(by.css("app-root h1")).getText();
   }
 }
diff --git a/Frontend Angular 4/e2e/tsconfig.e2e.json b/Frontend Angular 4/e2e/tsconfig.e2e.json
index ac7a3732..e7549236 100755
--- a/Frontend Angular 4/e2e/tsconfig.e2e.json	
+++ b/Frontend Angular 4/e2e/tsconfig.e2e.json	
@@ -4,9 +4,6 @@
     "outDir": "../out-tsc/e2e",
     "module": "commonjs",
     "target": "es5",
-    "types":[
-      "jasmine",
-      "node"
-    ]
+    "types": ["jasmine", "node"]
   }
 }
diff --git a/Frontend Angular 4/package-lock.json b/Frontend Angular 4/package-lock.json
index d39e055f..3b65043a 100644
--- a/Frontend Angular 4/package-lock.json	
+++ b/Frontend Angular 4/package-lock.json	
@@ -303,89 +303,81 @@
       }
     },
     "@angular/common": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/common/-/common-4.4.7.tgz",
-      "integrity": "sha512-5R0POjbT4CR+8vXS7P33SiozJpTEKDsHq07EMm90OCwoofU5DIKDLNyEqr362zsbpzGUTmhGbSiLZib5Qt4djA==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.11.tgz",
+      "integrity": "sha512-LniJjGAeftUJDJh+2+LEjltcGen08C/VMxQ/eUYmesytKy1sN+MWzh3GbpKfEWtWmyUsYTG9lAAJNo3L3jPwsw==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
     "@angular/compiler": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-4.4.7.tgz",
-      "integrity": "sha512-aiRh86RqHMTgJ7xckQWzG2UTnq23+WuDVhYh/QL19R43areZLglqgtKSkfezg9aatO5CGzxDA3qL5WGhccQ5EQ==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.11.tgz",
+      "integrity": "sha512-ICvB1ud1mxaXUYLb8vhJqiLhGBVocAZGxoHTglv6hMkbrRYcnlB3FZJFOzBvtj+krkd1jamoYLI43UAmesqQ6Q==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
     "@angular/compiler-cli": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-4.4.7.tgz",
-      "integrity": "sha512-vzphs9galtMV29CW+ihp6v0HwSQrjAFqs04swqt9o0jEJET6/mPi1EFjJRNZiFn6ghh6lxUPr3vThy7CrSNxHg==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.11.tgz",
+      "integrity": "sha512-dwrQ0yxoCM/XzKzlm7pTsyg4/6ECjT9emZufGj8t12bLMO8NDn1IJOsqXJA1+onEgQKhlr0Ziwi+96TvDTb1Cg==",
       "dev": true,
       "requires": {
-        "@angular/tsc-wrapped": "4.4.7",
+        "chokidar": "^1.4.2",
         "minimist": "^1.2.0",
-        "reflect-metadata": "^0.1.2"
+        "reflect-metadata": "^0.1.2",
+        "tsickle": "^0.27.2"
       }
     },
     "@angular/core": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/core/-/core-4.4.7.tgz",
-      "integrity": "sha512-Jxs6gNTl5KjXflg5vi5rlnokq1johFccN94qSOgDv+Mg1iuGF2i9p7EHkw3Y8jBCVaSLw1qgHE+wMb6KTlJDLA==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.11.tgz",
+      "integrity": "sha512-h2vpvXNAdOqKzbVaZcHnHGMT5A8uDnizk6FgGq6SPyw9s3d+/VxZ9LJaPjUk3g2lICA7og1tUel+2YfF971MlQ==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
     "@angular/forms": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-4.4.7.tgz",
-      "integrity": "sha512-EXGutI4GNBptpwkCQdCTxWAlJll8aCV7m3cA1FHZgFP7VNSgYF0pD+PscM5jSeajG30cRjaKxgL4cqj6yMMtww==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.11.tgz",
+      "integrity": "sha512-wBllFlIubPclAFRXUc84Kc7TMeKOftzrQraVZ7ooTNeFLLa/FZLN2K8HGyRde8X/XDsMu1XAmjNfkz++spwTzA==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
     "@angular/http": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/http/-/http-4.4.7.tgz",
-      "integrity": "sha512-9XrvXFVuHsAfVlIbM6Em2EouKiRyV2y4nPA+dAUd/9uB9i/i+FzZlmmeSIvP7ePnm6QyAC6nlvy9FMQYwvrtNA==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.11.tgz",
+      "integrity": "sha512-eR7wNXh1+6MpcQNb3sq4bJVX03dx50Wl3kpPG+Q7N1VSL0oPQSobaTrR17ac3oFCEfSJn6kkUCqtUXha6wcNHg==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
     "@angular/platform-browser": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-4.4.7.tgz",
-      "integrity": "sha512-5WGMhUbaepmNoE597N/6R4jDdSqe4wwJblfi6bOJI34QStmD6QRnmg3H7ujr8lLhRBo9P3zH+hn7bM3RxUIEJg==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.11.tgz",
+      "integrity": "sha512-6YZ4IpBFqXx88vEzBZG2WWnaSYXbFWDgG0iT+bZPHAfwsbmqbcMcs7Ogu+XZ4VmK02dTqbrFh7U4P2W+sqrzow==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
     "@angular/platform-browser-dynamic": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.4.7.tgz",
-      "integrity": "sha512-or6CB+LzK8zYn7K4rif32UvVadnbdrqBiT+5Yai1szNUUKuseqx2h1dsEgJQamkajsOUM7zjLYq4LrKJEEcm8A==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.11.tgz",
+      "integrity": "sha512-5kKPNULcXNwkyBjpHfF+pq+Yxi8Zl866YSOK9t8txoiQ9Ctw97kMkEJcTetk6MJgBp/NP3YyjtoTAm8oXLerug==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
     "@angular/router": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/router/-/router-4.4.7.tgz",
-      "integrity": "sha512-WaVnBP41UdrUwReSUgB5YE6C37PrYFSaiFAoPRTx4RC0jeRE+ncFWwessVIh0kvfEK4ROkO3QK2BtLzMUY5GNg==",
+      "version": "5.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/router/-/router-5.2.11.tgz",
+      "integrity": "sha512-NT8xYl7Vr3qPygisek3PlXqNROEjg48GXOEsDEc7c8lDBo3EB9Tf328fWJD0GbLtXZNhmmNNxwIe+qqPFFhFAA==",
       "requires": {
         "tslib": "^1.7.1"
       }
     },
-    "@angular/tsc-wrapped": {
-      "version": "4.4.7",
-      "resolved": "https://registry.npmjs.org/@angular/tsc-wrapped/-/tsc-wrapped-4.4.7.tgz",
-      "integrity": "sha512-R9w7sTU+HSTMPOa4NgvPL753qB6aqnPc1AVh2rwSl5FOpLS/AeeyzIhRnBsVXGrZrTcBQVLp/Cxg1oUSXE2k4Q==",
-      "dev": true,
-      "requires": {
-        "tsickle": "^0.21.0"
-      }
-    },
     "@babel/code-frame": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
@@ -427,9 +419,9 @@
       "dev": true
     },
     "@ng-bootstrap/ng-bootstrap": {
-      "version": "1.0.0-alpha.26",
-      "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0-alpha.26.tgz",
-      "integrity": "sha512-IyuzetcloF82ctEHu8k8Rwq1RUPJvqV0AeI/g8mBIU98T8sToA/2v6DWPK4xGi5lmc5nXlChN2ja6qiuJqApCw=="
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-1.0.0.tgz",
+      "integrity": "sha512-70QRgrqVYNhlop9iDTTY+++BGRTf3xgx3SmVDVYm5A9H4B/XOIv9XOu2UnD/7VGXZxefS+xizShJPMsjn8xNAg=="
     },
     "@ngtools/json-schema": {
       "version": "1.2.0",
@@ -454,14 +446,14 @@
       }
     },
     "@ngx-translate/core": {
-      "version": "7.2.2",
-      "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-7.2.2.tgz",
-      "integrity": "sha512-KCX433VoID0B19z8JV6epdnMpPTRl1zGQp8wbCgSm3kVLaSBwnhGfa9IP9M2ch+f+9jyyh1okez3QHW49P2YiQ=="
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-8.0.0.tgz",
+      "integrity": "sha512-ko8UY/A7GziOukG+Is0VBwtUM4HGFy4UGpPlGXC0NXj0qxYNIsA/Ymx7YVpqSMkzFf3c9lxhnFloSq79fAaECQ=="
     },
     "@ngx-translate/http-loader": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-0.1.0.tgz",
-      "integrity": "sha512-YarxppsMRcH7oB7rHKcOndMQxvL798wUO9GooRuchGhmqJmC0trtpW6rCY7J8ju/2dour3rr5yDvXM1HXYohlg=="
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-1.1.0.tgz",
+      "integrity": "sha512-UvlSPSEurIeCWa6+Nws0BFzoCjFX1L6zcDdf2xkH3k8vcoPop3arxR/oXHKsHp6w5Gi3yqZKnv1TdjI4gsoEIQ=="
     },
     "@npmcli/fs": {
       "version": "1.1.1",
@@ -781,48 +773,6 @@
       "dev": true,
       "optional": true
     },
-    "ansi-align": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
-      "integrity": "sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA==",
-      "dev": true,
-      "requires": {
-        "string-width": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
-          "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-          "dev": true
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^3.0.0"
-          }
-        }
-      }
-    },
     "ansi-html": {
       "version": "0.0.7",
       "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
@@ -1490,60 +1440,6 @@
         "hoek": "2.x.x"
       }
     },
-    "boxen": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
-      "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
-      "dev": true,
-      "requires": {
-        "ansi-align": "^2.0.0",
-        "camelcase": "^4.0.0",
-        "chalk": "^2.0.1",
-        "cli-boxes": "^1.0.0",
-        "string-width": "^2.0.0",
-        "term-size": "^1.2.0",
-        "widest-line": "^2.0.0"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
-          "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
-          "dev": true
-        },
-        "camelcase": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
-          "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-          "dev": true
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^3.0.0"
-          }
-        }
-      }
-    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -1724,6 +1620,12 @@
       "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==",
       "dev": true
     },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==",
+      "dev": true
+    },
     "builtin-status-codes": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
@@ -1866,12 +1768,6 @@
       "integrity": "sha512-znVbq4OUjqgLxMxoNX2ZeeLR0d7lcDiE5uJ4eUiWdml1J1EkxbnQq6opT9jb9SMfJxB0XA16/ziHwni4u1I3GQ==",
       "dev": true
     },
-    "capture-stack-trace": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
-      "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
-      "dev": true
-    },
     "caseless": {
       "version": "0.12.0",
       "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -1922,12 +1818,6 @@
       "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
       "dev": true
     },
-    "ci-info": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
-      "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
-      "dev": true
-    },
     "cipher-base": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
@@ -1996,12 +1886,6 @@
       "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
       "dev": true
     },
-    "cli-boxes": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
-      "integrity": "sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==",
-      "dev": true
-    },
     "cliui": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
@@ -2100,17 +1984,25 @@
       "dev": true
     },
     "codelyzer": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-2.0.1.tgz",
-      "integrity": "sha512-9223/J6RXYWU+DTsVdQBtiHYMl8ae2rLsytCIK3flPj4oxNcy6AafDR5KA0PRbIyhRMa/icut9Ak3n16lE5Jtw==",
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.5.0.tgz",
+      "integrity": "sha512-oO6vCkjqsVrEsmh58oNlnJkRXuA30hF8cdNAQV9DytEalDwyOFRvHMnlKFzmOStNerOmPGZU9GAHnBo4tGvtiQ==",
       "dev": true,
       "requires": {
-        "app-root-path": "^2.0.1",
+        "app-root-path": "^2.1.0",
         "css-selector-tokenizer": "^0.7.0",
         "cssauron": "^1.4.0",
         "semver-dsl": "^1.0.1",
-        "source-map": "^0.5.6",
-        "sprintf-js": "^1.0.3"
+        "source-map": "^0.5.7",
+        "sprintf-js": "^1.1.1"
+      },
+      "dependencies": {
+        "sprintf-js": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+          "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+          "dev": true
+        }
       }
     },
     "codemirror": {
@@ -2250,20 +2142,6 @@
         "typedarray": "^0.0.6"
       }
     },
-    "configstore": {
-      "version": "3.1.5",
-      "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.5.tgz",
-      "integrity": "sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==",
-      "dev": true,
-      "requires": {
-        "dot-prop": "^4.2.1",
-        "graceful-fs": "^4.1.2",
-        "make-dir": "^1.0.0",
-        "unique-string": "^1.0.0",
-        "write-file-atomic": "^2.0.0",
-        "xdg-basedir": "^3.0.0"
-      }
-    },
     "connect": {
       "version": "3.7.0",
       "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
@@ -2491,15 +2369,6 @@
         }
       }
     },
-    "create-error-class": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
-      "integrity": "sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==",
-      "dev": true,
-      "requires": {
-        "capture-stack-trace": "^1.0.0"
-      }
-    },
     "create-hash": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
@@ -2567,12 +2436,6 @@
         "randomfill": "^1.0.3"
       }
     },
-    "crypto-random-string": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
-      "integrity": "sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==",
-      "dev": true
-    },
     "css": {
       "version": "2.2.4",
       "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
@@ -3005,12 +2868,6 @@
         "regexp.prototype.flags": "^1.2.0"
       }
     },
-    "deep-extend": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
-      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
-      "dev": true
-    },
     "default-require-extensions": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz",
@@ -3304,21 +3161,6 @@
         "domhandler": "^4.2.0"
       }
     },
-    "dot-prop": {
-      "version": "4.2.1",
-      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.1.tgz",
-      "integrity": "sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==",
-      "dev": true,
-      "requires": {
-        "is-obj": "^1.0.0"
-      }
-    },
-    "duplexer3": {
-      "version": "0.1.5",
-      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
-      "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==",
-      "dev": true
-    },
     "duplexify": {
       "version": "3.7.1",
       "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -4196,30 +4038,6 @@
         "locate-path": "^2.0.0"
       }
     },
-    "findup-sync": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
-      "integrity": "sha512-z8Nrwhi6wzxNMIbxlrTzuUW6KWuKkogZ/7OdDVq+0+kxn77KUH1nipx8iU6suqkHqc4y6n7a9A8IpmxY/pTjWg==",
-      "dev": true,
-      "requires": {
-        "glob": "~5.0.0"
-      },
-      "dependencies": {
-        "glob": {
-          "version": "5.0.15",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
-          "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==",
-          "dev": true,
-          "requires": {
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "2 || 3",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        }
-      }
-    },
     "flag-icon-css": {
       "version": "3.5.0",
       "resolved": "https://registry.npmjs.org/flag-icon-css/-/flag-icon-css-3.5.0.tgz",
@@ -4688,15 +4506,6 @@
         "is-glob": "^2.0.0"
       }
     },
-    "global-dirs": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
-      "integrity": "sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==",
-      "dev": true,
-      "requires": {
-        "ini": "^1.3.4"
-      }
-    },
     "globals": {
       "version": "9.18.0",
       "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
@@ -4753,25 +4562,6 @@
         }
       }
     },
-    "got": {
-      "version": "6.7.1",
-      "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
-      "integrity": "sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==",
-      "dev": true,
-      "requires": {
-        "create-error-class": "^3.0.0",
-        "duplexer3": "^0.1.4",
-        "get-stream": "^3.0.0",
-        "is-redirect": "^1.0.0",
-        "is-retry-allowed": "^1.0.0",
-        "is-stream": "^1.0.0",
-        "lowercase-keys": "^1.0.0",
-        "safe-buffer": "^5.0.1",
-        "timed-out": "^4.0.0",
-        "unzip-response": "^2.0.1",
-        "url-parse-lax": "^1.0.0"
-      }
-    },
     "graceful-fs": {
       "version": "4.2.10",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
@@ -6596,12 +6386,6 @@
         "resolve-from": "^3.0.0"
       }
     },
-    "import-lazy": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
-      "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==",
-      "dev": true
-    },
     "import-local": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
@@ -6791,15 +6575,6 @@
       "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==",
       "dev": true
     },
-    "is-ci": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
-      "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
-      "dev": true,
-      "requires": {
-        "ci-info": "^1.5.0"
-      }
-    },
     "is-core-module": {
       "version": "2.10.0",
       "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
@@ -6903,16 +6678,6 @@
         "is-extglob": "^1.0.0"
       }
     },
-    "is-installed-globally": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
-      "integrity": "sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw==",
-      "dev": true,
-      "requires": {
-        "global-dirs": "^0.1.0",
-        "is-path-inside": "^1.0.0"
-      }
-    },
     "is-lambda": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
@@ -6925,12 +6690,6 @@
       "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
       "dev": true
     },
-    "is-npm": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
-      "integrity": "sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==",
-      "dev": true
-    },
     "is-number": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
@@ -6949,12 +6708,6 @@
         "has-tostringtag": "^1.0.0"
       }
     },
-    "is-obj": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
-      "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==",
-      "dev": true
-    },
     "is-path-cwd": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
@@ -7014,12 +6767,6 @@
       "integrity": "sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==",
       "dev": true
     },
-    "is-redirect": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
-      "integrity": "sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==",
-      "dev": true
-    },
     "is-regex": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -7030,12 +6777,6 @@
         "has-tostringtag": "^1.0.0"
       }
     },
-    "is-retry-allowed": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
-      "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
-      "dev": true
-    },
     "is-shared-array-buffer": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
@@ -7596,15 +7337,6 @@
         "is-buffer": "^1.1.5"
       }
     },
-    "latest-version": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
-      "integrity": "sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==",
-      "dev": true,
-      "requires": {
-        "package-json": "^4.0.0"
-      }
-    },
     "lazy-cache": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
@@ -7807,12 +7539,6 @@
       "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==",
       "dev": true
     },
-    "lowercase-keys": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
-      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
-      "dev": true
-    },
     "lru-cache": {
       "version": "4.1.5",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
@@ -9779,18 +9505,6 @@
       "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
       "dev": true
     },
-    "package-json": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
-      "integrity": "sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA==",
-      "dev": true,
-      "requires": {
-        "got": "^6.7.1",
-        "registry-auth-token": "^3.0.1",
-        "registry-url": "^3.0.3",
-        "semver": "^5.1.0"
-      }
-    },
     "pako": {
       "version": "1.0.11",
       "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
@@ -10141,12 +9855,6 @@
       "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
       "dev": true
     },
-    "prepend-http": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-      "integrity": "sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==",
-      "dev": true
-    },
     "preserve": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
@@ -10607,18 +10315,6 @@
       "integrity": "sha512-sf7oGoLuaYAScB4VGr0tzetsYlS8EJH6qnTCfQ/WVEa89hALQ4RQfCKt5xCyPQKPDUbVUAIP1QsxAwfAjlDp7Q==",
       "dev": true
     },
-    "rc": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
-      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
-      "dev": true,
-      "requires": {
-        "deep-extend": "^0.6.0",
-        "ini": "~1.3.0",
-        "minimist": "^1.2.0",
-        "strip-json-comments": "~2.0.1"
-      }
-    },
     "read-cache": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -11051,25 +10747,6 @@
         "functions-have-names": "^1.2.2"
       }
     },
-    "registry-auth-token": {
-      "version": "3.4.0",
-      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
-      "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
-      "dev": true,
-      "requires": {
-        "rc": "^1.1.6",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "registry-url": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
-      "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==",
-      "dev": true,
-      "requires": {
-        "rc": "^1.0.1"
-      }
-    },
     "relateurl": {
       "version": "0.2.7",
       "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
@@ -11427,15 +11104,6 @@
       "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
       "dev": true
     },
-    "semver-diff": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
-      "integrity": "sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==",
-      "dev": true,
-      "requires": {
-        "semver": "^5.0.3"
-      }
-    },
     "semver-dsl": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
@@ -12513,15 +12181,6 @@
         "inherits": "2"
       }
     },
-    "term-size": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
-      "integrity": "sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ==",
-      "dev": true,
-      "requires": {
-        "execa": "^0.7.0"
-      }
-    },
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -12550,12 +12209,6 @@
       "integrity": "sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA==",
       "dev": true
     },
-    "timed-out": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
-      "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==",
-      "dev": true
-    },
     "timers-browserify": {
       "version": "2.0.12",
       "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
@@ -12760,15 +12413,33 @@
       }
     },
     "tsickle": {
-      "version": "0.21.6",
-      "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.21.6.tgz",
-      "integrity": "sha512-S0WhNQvuO7zbTDeOrNJ1LGKPVLUE0kjSdpMxMiyeZE0c0MtpvB93p787iOnjKqUOFl1+x2v1CN/DDMFOX6WKdA==",
+      "version": "0.27.5",
+      "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.27.5.tgz",
+      "integrity": "sha512-NP+CjM1EXza/M8mOXBLH3vkFEJiu1zfEAlC5WdJxHPn8l96QPz5eooP6uAgYtw1CcKfuSyIiheNUdKxtDWCNeg==",
       "dev": true,
       "requires": {
         "minimist": "^1.2.0",
         "mkdirp": "^0.5.1",
-        "source-map": "^0.5.6",
-        "source-map-support": "^0.4.2"
+        "source-map": "^0.6.0",
+        "source-map-support": "^0.5.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "source-map-support": {
+          "version": "0.5.21",
+          "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+          "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+          "dev": true,
+          "requires": {
+            "buffer-from": "^1.0.0",
+            "source-map": "^0.6.0"
+          }
+        }
       }
     },
     "tslib": {
@@ -12777,27 +12448,68 @@
       "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
     },
     "tslint": {
-      "version": "4.5.1",
-      "resolved": "https://registry.npmjs.org/tslint/-/tslint-4.5.1.tgz",
-      "integrity": "sha512-7Pt7EcdupEPtx74vCBC9dqfNftYFP+TiXgxp8GFbgdEnlEdmycbhjOrJNAMChchqh32zUryENbd66gaJ95OEqQ==",
+      "version": "5.20.1",
+      "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz",
+      "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==",
       "dev": true,
       "requires": {
-        "babel-code-frame": "^6.20.0",
-        "colors": "^1.1.2",
-        "diff": "^3.0.1",
-        "findup-sync": "~0.3.0",
+        "@babel/code-frame": "^7.0.0",
+        "builtin-modules": "^1.1.1",
+        "chalk": "^2.3.0",
+        "commander": "^2.12.1",
+        "diff": "^4.0.1",
         "glob": "^7.1.1",
-        "optimist": "~0.6.0",
-        "resolve": "^1.1.7",
-        "tsutils": "^1.1.0",
-        "update-notifier": "^2.0.0"
+        "js-yaml": "^3.13.1",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "resolve": "^1.3.2",
+        "semver": "^5.3.0",
+        "tslib": "^1.8.0",
+        "tsutils": "^2.29.0"
+      },
+      "dependencies": {
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "diff": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+          "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+          "dev": true
+        },
+        "has-flag": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
       }
     },
     "tsutils": {
-      "version": "1.9.1",
-      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-1.9.1.tgz",
-      "integrity": "sha512-Z4MMpdLvxER0Wz+l9TM71URBKGoHKBzArEraOFmTp44jxzdqiG8oTCtpjiZ9YtFXNwWQfMv+g8VAxTlBEVS6yw==",
-      "dev": true
+      "version": "2.29.0",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+      "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.8.1"
+      }
     },
     "tty-browserify": {
       "version": "0.0.0",
@@ -12849,9 +12561,9 @@
       "dev": true
     },
     "typescript": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.2.2.tgz",
-      "integrity": "sha512-ZQXTJ7IcU5Yg8Mz8VzVFDrguzIDpRxNlD8yjowh1F0cbruhWnd92YJ/c6gHjopRINwhgpe5bDx7fOD6nAagwmQ==",
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.2.tgz",
+      "integrity": "sha512-a6qhFjx88CqXM92QX6e5zwbYavxaknEdFhh/ZrBmuHEP+r2ye102uvhCkWdian4u5Ee17W+8fAN7xtdM8KeQ7A==",
       "dev": true
     },
     "uglify-js": {
@@ -12973,15 +12685,6 @@
         "imurmurhash": "^0.1.4"
       }
     },
-    "unique-string": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
-      "integrity": "sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==",
-      "dev": true,
-      "requires": {
-        "crypto-random-string": "^1.0.0"
-      }
-    },
     "universalify": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
@@ -13040,36 +12743,12 @@
         }
       }
     },
-    "unzip-response": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
-      "integrity": "sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==",
-      "dev": true
-    },
     "upath": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
       "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
       "dev": true
     },
-    "update-notifier": {
-      "version": "2.5.0",
-      "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
-      "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
-      "dev": true,
-      "requires": {
-        "boxen": "^1.2.1",
-        "chalk": "^2.0.1",
-        "configstore": "^3.0.0",
-        "import-lazy": "^2.1.0",
-        "is-ci": "^1.0.10",
-        "is-installed-globally": "^0.1.0",
-        "is-npm": "^1.0.0",
-        "latest-version": "^3.0.0",
-        "semver-diff": "^2.0.0",
-        "xdg-basedir": "^3.0.0"
-      }
-    },
     "upper-case": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
@@ -13153,15 +12832,6 @@
         "requires-port": "^1.0.0"
       }
     },
-    "url-parse-lax": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
-      "integrity": "sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==",
-      "dev": true,
-      "requires": {
-        "prepend-http": "^1.0.1"
-      }
-    },
     "use": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
@@ -14827,48 +14497,6 @@
         "string-width": "^1.0.2 || 2 || 3 || 4"
       }
     },
-    "widest-line": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
-      "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
-      "dev": true,
-      "requires": {
-        "string-width": "^2.1.1"
-      },
-      "dependencies": {
-        "ansi-regex": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
-          "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
-          "dev": true
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
-          "dev": true
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^4.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^3.0.0"
-          }
-        }
-      }
-    },
     "window-size": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
@@ -14946,17 +14574,6 @@
       "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
-    "write-file-atomic": {
-      "version": "2.4.3",
-      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
-      "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
-      "dev": true,
-      "requires": {
-        "graceful-fs": "^4.1.11",
-        "imurmurhash": "^0.1.4",
-        "signal-exit": "^3.0.2"
-      }
-    },
     "ws": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.1.tgz",
@@ -14973,12 +14590,6 @@
       "integrity": "sha512-qfR6ovmRRMxNHgUNYI9LRdVofApe/eYrv4ggNOvvCP+pPdEo9Ym93QN4jUceGD6PignBbp2zAzgoE7GibAdq2A==",
       "dev": true
     },
-    "xdg-basedir": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
-      "integrity": "sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==",
-      "dev": true
-    },
     "xml2js": {
       "version": "0.4.23",
       "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
diff --git a/Frontend Angular 4/package.json b/Frontend Angular 4/package.json
index ab3786bf..048faa36 100755
--- a/Frontend Angular 4/package.json	
+++ b/Frontend Angular 4/package.json	
@@ -12,23 +12,23 @@
   },
   "private": true,
   "dependencies": {
-    "@angular/common": "^4.0.0",
-    "@angular/compiler": "^4.0.0",
-    "@angular/core": "^4.1.3",
-    "@angular/forms": "^4.0.0",
-    "@angular/http": "^4.0.0",
-    "@angular/platform-browser": "^4.0.0",
-    "@angular/platform-browser-dynamic": "^4.0.0",
-    "@angular/router": "^4.0.0",
-    "@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.26",
-    "@ngx-translate/core": "^7.2.2",
-    "@ngx-translate/http-loader": "^0.1.0",
-    "function-plot": "file:////home/ncamera/Escritorio/function-plot-2/",
-    "graph3D": "file:////home/ncamera/Escritorio/graph3d/",
+    "@angular/common": "^5.2.11",
+    "@angular/compiler": "^5.2.11",
+    "@angular/core": "^5.2.11",
+    "@angular/forms": "^5.2.11",
+    "@angular/http": "^5.2.11",
+    "@angular/platform-browser": "^5.2.11",
+    "@angular/platform-browser-dynamic": "^5.2.11",
+    "@angular/router": "^5.2.11",
+    "@ng-bootstrap/ng-bootstrap": "1.0.0",
+    "@ngx-translate/core": "^8.0.0",
+    "@ngx-translate/http-loader": "^1.0.0",
     "core-js": "^2.4.1",
     "d3": "^4.12.2",
     "flag-icon-css": "^3.2.1",
     "font-awesome": "^4.7.0",
+    "function-plot": "file:////home/ncamera/Escritorio/function-plot-2/",
+    "graph3D": "file:////home/ncamera/Escritorio/graph3d/",
     "ionicons": "^3.0.0",
     "jq-console": "^2.13.2",
     "jquery": "^3.2.1",
@@ -36,18 +36,18 @@
     "ng2-bootstrap-modal": "^1.0.1",
     "ng2-codemirror": "^1.1.1",
     "ng2-slider-component": "^1.0.9",
-    "rxjs": "^5.1.0",
+    "rxjs": "^5.5.12",
     "tippy.js": "^1.2.0",
     "web-animations-js": "^2.3.1",
     "zone.js": "^0.8.4"
   },
   "devDependencies": {
     "@angular/cli": "^1.6.4",
-    "@angular/compiler-cli": "^4.0.0",
+    "@angular/compiler-cli": "^5.2.11",
     "@types/jasmine": "2.5.38",
     "@types/jquery": "^2.0.45",
     "@types/node": "~6.0.60",
-    "codelyzer": "~2.0.0",
+    "codelyzer": "^4.0.0",
     "jasmine-core": "~2.5.2",
     "jasmine-spec-reporter": "~3.2.0",
     "karma": "~1.4.1",
@@ -59,7 +59,7 @@
     "node-sass": "^7.0.1",
     "protractor": "~5.1.0",
     "ts-node": "~2.0.0",
-    "tslint": "~4.5.0",
-    "typescript": "~2.2.0"
+    "tslint": "^5.0.0",
+    "typescript": "2.4.2"
   }
 }
diff --git a/Frontend Angular 4/src/app/app-routing.module.ts b/Frontend Angular 4/src/app/app-routing.module.ts
index 8ab640f1..f53b0072 100755
--- a/Frontend Angular 4/src/app/app-routing.module.ts	
+++ b/Frontend Angular 4/src/app/app-routing.module.ts	
@@ -1,19 +1,45 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
 
-import { AuthGuard } from './shared/guards/auth.guard';
+import { AuthGuard } from "./shared/guards/auth.guard";
 
 const routes: Routes = [
-    { path: '', loadChildren: './layout/layout.module#LayoutModule', canActivate: [AuthGuard] },
-    { path: 'login', loadChildren: './login/login.module#LoginModule', data: { language: navigator.language && (navigator.language.split('-')[0] == 'es' || navigator.language.split('-')[0] == 'en') ? navigator.language.split('-')[0] : 'es' }},
-    { path: 'es/login', loadChildren: './login/login.module#LoginModule', data: { language: 'es' }},
-    { path: 'en/login', loadChildren: './login/login.module#LoginModule', data: { language: 'en' }},
-    { path: 'not-found', loadChildren: './not-found/not-found.module#NotFoundModule' },
-    { path: '**', redirectTo: 'not-found' }
+  {
+    path: "",
+    loadChildren: "./layout/layout.module#LayoutModule",
+    canActivate: [AuthGuard],
+  },
+  {
+    path: "login",
+    loadChildren: "./login/login.module#LoginModule",
+    data: {
+      language:
+        navigator.language &&
+        (navigator.language.split("-")[0] == "es" ||
+          navigator.language.split("-")[0] == "en")
+          ? navigator.language.split("-")[0]
+          : "es",
+    },
+  },
+  {
+    path: "es/login",
+    loadChildren: "./login/login.module#LoginModule",
+    data: { language: "es" },
+  },
+  {
+    path: "en/login",
+    loadChildren: "./login/login.module#LoginModule",
+    data: { language: "en" },
+  },
+  {
+    path: "not-found",
+    loadChildren: "./not-found/not-found.module#NotFoundModule",
+  },
+  { path: "**", redirectTo: "not-found" },
 ];
 
 @NgModule({
-    imports: [RouterModule.forRoot(routes, { useHash: true })],
-    exports: [RouterModule]
+  imports: [RouterModule.forRoot(routes, { useHash: true })],
+  exports: [RouterModule],
 })
-export class AppRoutingModule { }
+export class AppRoutingModule {}
diff --git a/Frontend Angular 4/src/app/app.component.spec.ts b/Frontend Angular 4/src/app/app.component.spec.ts
index 2fee2a80..dd332074 100755
--- a/Frontend Angular 4/src/app/app.component.spec.ts	
+++ b/Frontend Angular 4/src/app/app.component.spec.ts	
@@ -1,21 +1,17 @@
-import { TestBed, async } from '@angular/core/testing';
-import { RouterTestingModule } from '@angular/router/testing';
+import { TestBed, async } from "@angular/core/testing";
+import { RouterTestingModule } from "@angular/router/testing";
 
-import { AppComponent } from './app.component';
+import { AppComponent } from "./app.component";
 
-describe('AppComponent', () => {
+describe("AppComponent", () => {
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      imports: [
-        RouterTestingModule
-      ],
-      declarations: [
-        AppComponent
-      ],
+      imports: [RouterTestingModule],
+      declarations: [AppComponent],
     }).compileComponents();
   }));
 
-  it('should create the app', async(() => {
+  it("should create the app", async(() => {
     const fixture = TestBed.createComponent(AppComponent);
     const app = fixture.debugElement.componentInstance;
     expect(app).toBeTruthy();
@@ -24,13 +20,13 @@ describe('AppComponent', () => {
   it(`should have as title 'app works!'`, async(() => {
     const fixture = TestBed.createComponent(AppComponent);
     const app = fixture.debugElement.componentInstance;
-    expect(app.title).toEqual('app works!');
+    expect(app.title).toEqual("app works!");
   }));
 
-  it('should render title in a h1 tag', async(() => {
+  it("should render title in a h1 tag", async(() => {
     const fixture = TestBed.createComponent(AppComponent);
     fixture.detectChanges();
     const compiled = fixture.debugElement.nativeElement;
-    expect(compiled.querySelector('h1').textContent).toContain('app works!');
+    expect(compiled.querySelector("h1").textContent).toContain("app works!");
   }));
 });
diff --git a/Frontend Angular 4/src/app/app.component.ts b/Frontend Angular 4/src/app/app.component.ts
index 4f1d4c09..7d49c521 100755
--- a/Frontend Angular 4/src/app/app.component.ts	
+++ b/Frontend Angular 4/src/app/app.component.ts	
@@ -1,24 +1,24 @@
-import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router';
-import { TranslateService } from '../../node_modules/@ngx-translate/core';
+import { Component, OnInit } from "@angular/core";
+import { Router } from "@angular/router";
+import { TranslateService } from "../../node_modules/@ngx-translate/core";
 
 @Component({
-    selector: 'app-root',
-    templateUrl: './app.component.html',
-    styleUrls: ['./app.component.scss']
+  selector: "app-root",
+  templateUrl: "./app.component.html",
+  styleUrls: ["./app.component.scss"],
 })
 export class AppComponent implements OnInit {
-    constructor(public router: Router, public translate: TranslateService) {
-        this.translate.addLangs(['es', 'en']);
-        let currentSession = sessionStorage.getItem("currentUser"); 
-        let language = currentSession ? JSON.parse(currentSession).language : 'es';
-        if (language) {
-            this.translate.setDefaultLang(language);
-        } else {
-            this.translate.setDefaultLang('es');
-        }
-    }
-    ngOnInit() {
-        //this.router.navigate(['/login']);
+  constructor(public router: Router, public translate: TranslateService) {
+    this.translate.addLangs(["es", "en"]);
+    let currentSession = sessionStorage.getItem("currentUser");
+    let language = currentSession ? JSON.parse(currentSession).language : "es";
+    if (language) {
+      this.translate.setDefaultLang(language);
+    } else {
+      this.translate.setDefaultLang("es");
     }
+  }
+  ngOnInit() {
+    //this.router.navigate(['/login']);
+  }
 }
diff --git a/Frontend Angular 4/src/app/app.module.ts b/Frontend Angular 4/src/app/app.module.ts
index e6dac183..be803c92 100755
--- a/Frontend Angular 4/src/app/app.module.ts	
+++ b/Frontend Angular 4/src/app/app.module.ts	
@@ -1,40 +1,42 @@
-import { BrowserModule } from '@angular/platform-browser';
-import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
-import { HttpModule, Http } from '@angular/http';
-import { AppRoutingModule } from './app-routing.module';
-import { AppComponent } from './app.component';
-import { AuthGuard } from './shared/guards/auth.guard';
-import { SessionService } from './shared/services/session.service';
-import { NotificacionService } from './shared/services/notificacion.service';
-import { NotificacionModule } from './notificacion/notificacion.module';
+import { BrowserModule } from "@angular/platform-browser";
+import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { HttpClient, HttpClientModule } from "@angular/common/http";
+import { AppRoutingModule } from "./app-routing.module";
+import { AppComponent } from "./app.component";
+import { AuthGuard } from "./shared/guards/auth.guard";
+import { SessionService } from "./shared/services/session.service";
+import { NotificacionService } from "./shared/services/notificacion.service";
+import { NotificacionModule } from "./notificacion/notificacion.module";
 
-import { TranslateHttpLoader } from '@ngx-translate/http-loader';
-import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
+import { TranslateHttpLoader } from "@ngx-translate/http-loader";
+import { TranslateModule, TranslateLoader } from "@ngx-translate/core";
 
-export function HttpLoaderFactory(http: Http) {
-    return new TranslateHttpLoader(http, './assets/i18n/', '.json?cb=' + new Date().getTime());
+export function HttpLoaderFactory(http: HttpClient) {
+  return new TranslateHttpLoader(
+    http,
+    "./assets/i18n/",
+    ".json?cb=" + new Date().getTime()
+  );
 }
 
 @NgModule({
-    declarations: [
-        AppComponent
-    ],
-    imports: [
-        NotificacionModule,
-        BrowserModule,
-        FormsModule,
-        HttpModule,
-        AppRoutingModule,
-        TranslateModule.forRoot({
-            loader: {
-                provide: TranslateLoader,
-                useFactory: HttpLoaderFactory,
-                deps: [Http]
-            }
-        })
-    ],
-    providers: [AuthGuard, SessionService, NotificacionService],
-    bootstrap: [AppComponent]
+  declarations: [AppComponent],
+  imports: [
+    NotificacionModule,
+    BrowserModule,
+    FormsModule,
+    HttpClientModule,
+    AppRoutingModule,
+    TranslateModule.forRoot({
+      loader: {
+        provide: TranslateLoader,
+        useFactory: HttpLoaderFactory,
+        deps: [HttpClient],
+      },
+    }),
+  ],
+  providers: [AuthGuard, SessionService, NotificacionService],
+  bootstrap: [AppComponent],
 })
-export class AppModule { }
+export class AppModule {}
diff --git a/Frontend Angular 4/src/app/layout/archivos/archivos-routing.module.ts b/Frontend Angular 4/src/app/layout/archivos/archivos-routing.module.ts
index 47cc7eab..1f9d0da6 100755
--- a/Frontend Angular 4/src/app/layout/archivos/archivos-routing.module.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/archivos-routing.module.ts	
@@ -1,14 +1,12 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
 
-import { ArchivosComponent } from './archivos.component';
+import { ArchivosComponent } from "./archivos.component";
 
-const routes: Routes = [
-    { path: '', component: ArchivosComponent }
-];
+const routes: Routes = [{ path: "", component: ArchivosComponent }];
 
 @NgModule({
-    imports: [RouterModule.forChild(routes)],
-    exports: [RouterModule]
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
 })
-export class ArchivosRoutingModule { }
\ No newline at end of file
+export class ArchivosRoutingModule {}
diff --git a/Frontend Angular 4/src/app/layout/archivos/archivos.component.ts b/Frontend Angular 4/src/app/layout/archivos/archivos.component.ts
index a6e6392e..96cd2a8a 100755
--- a/Frontend Angular 4/src/app/layout/archivos/archivos.component.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/archivos.component.ts	
@@ -1,549 +1,613 @@
-import { Component,ViewChild } from '@angular/core';
-import { Archivo } from '../../shared/objects/archivo';
-import { AuthenticationService } from '../../shared/services/authentication.service';
-import { HaskellService } from '../../shared/services/haskell.service';
-import { SessionService } from '../../shared/services/session.service';
-import { NotificacionService } from '../../shared/services/notificacion.service';
-import { Router, ActivatedRoute } from '@angular/router';
-import { NuevoArchivo } from './nuevoArchivo.component';
-import { VerCalificacionComponent } from './verCalificacion.component';
-import { CompartirArchivoComponent } from './compartirArchivo.component';
-import { ConfirmarEliminar } from './confirmarEliminar.component';
+import { Component, ViewChild } from "@angular/core";
+import { Archivo } from "../../shared/objects/archivo";
+import { AuthenticationService } from "../../shared/services/authentication.service";
+import { HaskellService } from "../../shared/services/haskell.service";
+import { SessionService } from "../../shared/services/session.service";
+import { NotificacionService } from "../../shared/services/notificacion.service";
+import { Router, ActivatedRoute } from "@angular/router";
+import { NuevoArchivo } from "./nuevoArchivo.component";
+import { VerCalificacionComponent } from "./verCalificacion.component";
+import { CompartirArchivoComponent } from "./compartirArchivo.component";
+import { ConfirmarEliminar } from "./confirmarEliminar.component";
 import { DialogService } from "ng2-bootstrap-modal";
-import { ConfirmComponent } from '../../shared/modal/confirm.component';
-import { SeleccionarDirectorioMove } from './seleccionarDirectorio.component';
-import { CodemirrorComponent } from 'ng2-codemirror';
-import { NgbPopoverConfig, NgbPopover} from '@ng-bootstrap/ng-bootstrap';
-import { TranslateService } from '@ngx-translate/core';
-import { TitleCasePipe } from '../../shared/pipes/titlecase.pipe';
-import { map }                from 'rxjs/operators';
-
-import 'codemirror/mode/haskell/haskell';
-import 'codemirror/addon/display/panel';
-import 'codemirror/addon/hint/show-hint';
-import 'codemirror/addon/hint/anyword-hint';
-import 'codemirror/mode/markdown/markdown';
+import { ConfirmComponent } from "../../shared/modal/confirm.component";
+import { SeleccionarDirectorioMove } from "./seleccionarDirectorio.component";
+import { CodemirrorComponent } from "ng2-codemirror";
+import { NgbPopoverConfig, NgbPopover } from "@ng-bootstrap/ng-bootstrap";
+import { TranslateService } from "@ngx-translate/core";
+import { TitleCasePipe } from "../../shared/pipes/titlecase.pipe";
+import { map } from "rxjs/operators";
+
+import "codemirror/mode/haskell/haskell";
+import "codemirror/addon/display/panel";
+import "codemirror/addon/hint/show-hint";
+import "codemirror/addon/hint/anyword-hint";
+import "codemirror/mode/markdown/markdown";
 
 @Component({
-	moduleId: module.id,
-	selector: 'archivos',
-	templateUrl: './archivos.component.html'
+  moduleId: module.id,
+  selector: "archivos",
+  templateUrl: "./archivos.component.html",
 })
-
 export class ArchivosComponent {
-	translateService : any;
-	titlecasePipe: any;
-	archivos : Archivo[] = [];
-	archivosCompartidos: Archivo[] = [];
-	archivosCompartidosSinDuplicados: Archivo [] = [];
-	archivoSeleccionado: Archivo;
-	loading: boolean = false;
-	loadingCompartidos:boolean = false;
-	filtroNombre: string = '';
-	idRecorridos :any = [];
-	esAlumno :boolean;
-	tree: any;
-	preview: string = '';
-	directorioActual:any;
-	sortFunction:any;
-	configCodeMirror = JSON.parse(sessionStorage.getItem('codeMirrorConfig')) ;
-
-	constructor(
-		private router: Router,
-		private notifService: NotificacionService,
-		private authService: AuthenticationService,
-		private haskellService: HaskellService,
-		private sessionService: SessionService,
-		private dialogService:DialogService,
-		public translate: TranslateService,
-		private route: ActivatedRoute
-		){
-		this.translateService = translate;
-		this.titlecasePipe = new TitleCasePipe();
-
-		this.esAlumno = JSON.parse(sessionStorage.getItem("currentUser")).tipo ==="alumno";
-		this.directorioActual = {};
-		this.directorioActual.archivos = [];
-		this.configCodeMirror.readOnly = true;
-	}
-	@ViewChild(CodemirrorComponent) codemirror: CodemirrorComponent;
-
-	ngOnInit(){
-		this.sortFunction = 'tipo'
-		let cedula = this.authService.getUser().cedula;
-		this.loading = true;
-		this.haskellService.getArchivos(cedula)
-		.subscribe(
-			archivos => {
-				this.archivos = archivos;
-				this.loading = false;
-				this.buildTreeFromList();
-			}, 
-			error => console.log(error) 
-			);
-
-		if(this.esAlumno){
-			this.loadingCompartidos = true;
-			this.haskellService.getArchivosCompartidosAlumno(cedula)
-			.subscribe(
-				archivos => {
-					this.archivosCompartidos = archivos;
-					this.archivosCompartidosSinDuplicados = archivos.filter(arch => arch.archivoOrigenId != -1 || !archivos.some(a => a.archivoOrigenId == arch.id));
-					this.loadingCompartidos = false;
-				}, 
-				error => console.log(error) 
-				);
-
-		}
-		this.ordenarArchivos();
-	}
-	ordenarMixto(){
-		//1. primero las carpetas.
-		this.archivosCompartidosSinDuplicados = this.archivosCompartidosSinDuplicados.sort(this.ordenarTipo);
-		this.directorioActual.archivos= this.directorioActual.archivos.sort(this.ordenarTipo);
-
-		var archs1 = this.directorioActual.archivos;
-		var archs2 = this.archivosCompartidosSinDuplicados;
-
-		var archs1_directorios = archs1.filter(
-			function (a) {
-				return a.directorio;
-			}
-		);
-
-		var archs1_archivos =archs1.filter(
-			function(a){
-				return !a.directorio;
-			}
-
-		);
-
-		var archs2_directorios = archs2.filter(
-			function (a) {
-				return a.directorio;
-			}
-		);
-
-		var archs2_archivos =archs2.filter(
-			function(a){
-				return !a.directorio;
-			}
-
-		);
-		//2. dentro de cada categoría ordeno alfabéticamente.
-
-		archs1_archivos = archs1_archivos.sort(this.ordenarAlph);
-		archs1_directorios = archs1_directorios.sort(this.ordenarAlph);
-		archs2_archivos = archs2_archivos.sort(this.ordenarAlph);
-		archs2_directorios = archs2_directorios.sort(this.ordenarAlph);
-
-		for(var i in archs1_archivos){
-			archs1_directorios.push(archs1_archivos[i])
-		}
-		for(var i in archs2_archivos){
-			archs2_directorios.push(archs2_archivos[i])
-		}
-
-		this.directorioActual.archivos = archs1_directorios;
-		this.archivosCompartidosSinDuplicados = archs2_directorios;
-	}
-
-	ordenarAlph(a,b){
-		if(a.nombre.toLowerCase() < b.nombre.toLowerCase()) return -1;
-		if(a.nombre.toLowerCase() > b.nombre.toLowerCase()) return 1;
-		return 0;
-	}
-	ordenarFecha(a, b){
-		if(a.fechaCreacion < b.fechaCreacion) return -1;
-		if(a.fechaCreacion > b.fechaCreacion) return 1;
-		return 0;
-	}
-	ordenarTipo(a,b){
-		if(a.directorio && !b.directorio) return -1;
-		if(!a.directorio && b.directorio) return 1;
-		return 0;	
-	}
-	ordenarPorTipo(){
-		this.sortFunction='tipo';
-		this.ordenarArchivos();
-	}
-	ordenarPorFecha(){
-		this.sortFunction='fecha';
-		this.ordenarArchivos();
-	}
-	ordenarFechaCreacion(){
-		this.archivosCompartidosSinDuplicados = this.archivosCompartidosSinDuplicados.sort(this.ordenarFecha);
-		this.directorioActual.archivos= this.directorioActual.archivos.sort(this.ordenarFecha);
-	}
-
-	ordenarArchivos(){
-		var tipo = this.sortFunction;
-		if(tipo==='tipo'){
-			this.ordenarMixto();	
-		} else if(tipo==='fecha'){
-			this.ordenarFechaCreacion();
-		}
-	}
-
-	mostrarEliminarDialogo(){
-		if(this.archivoSeleccionado){
-			//Si el archivo es del alumno lo puedo eliminar. 
-			//(No se controla por creador dado que los compartidos mantienen este atributo)
-			if(this.archivos.some(arch => arch.id == this.archivoSeleccionado.id)){
-				var that = this;
-				let disposable = this.dialogService.addDialog(ConfirmarEliminar, {
-					nombreArchivo : {fileName: that.archivoSeleccionado.nombre}, 
-					esDirectorio : that.archivoSeleccionado.directorio,
-					parentContext : that})
-				.subscribe((isConfirmed)=>{
-					if(isConfirmed) {
-						//codeMirrorRef.options.readOnly = false;
-						//componentRef.editDialogFired = true;
-					}
-				});
-				console.log(disposable);
-			}else{
-				this.notifService.warning(this.translateService.get('i18n.warning.file.noPermissionDelete').value);
-			}
-		}else{
-			this.notifService.warning(this.translateService.get('i18n.warning.file.noSelected').value);
-		}
-	}
-	seleccionarDirectorioAMover(){
-		if(this.archivoSeleccionado){
-			//Si el archivo es del alumno lo puedo eliminar. 
-			//(No se controla por creador dado que los compartidos mantienen este atributo)
-			if(this.archivos.some(arch => arch.id == this.archivoSeleccionado.id)){
-				var that = this;
-				let disposable = this.dialogService.addDialog(SeleccionarDirectorioMove, {
-					archivos:that.tree,
-					directorioActual:that.directorioActual,
-					nombre:that.archivoSeleccionado.nombre, 
-					directorio:that.archivoSeleccionado.directorio,
-					parent :that})
-				.subscribe((isConfirmed)=>{
-
-					if(isConfirmed) {
-
-
-					}
-				});
-			}else{
-				this.notifService.warning(this.translateService.get('i18n.warning.file.noPermissionMove').value);
-			}
-		}else{
-			this.notifService.warning(this.translateService.get('i18n.warning.file.noSelected').value);
-		}
-	}
-
-	recargarArchivos(idDirectorioActual){
-		let cedula = this.authService.getUser().cedula;
-		this.loading = true;
-		this.haskellService.getArchivos(cedula)
-		.subscribe(
-			archivos => {
-				this.archivos = archivos;
-				this.loading = false;
-				this.buildTreeFromList_setearDirectorioActual(idDirectorioActual);
-
-			}, 
-			error => console.log(error) 
-			);
-	}
-
-
-	navBack(){
-		var that =this;
-		if(this.directorioActual.padreId!==-1){
-			var padre = this.archivos.filter(function(a){return a.id===that.directorioActual.padreId})[0];
-			this.directorioActual = padre;	
-		}
-		
-	}
-	
-	setSoloLectura = function(arch: Archivo){
-
-		this.archivoSeleccionado.editable = !this.archivoSeleccionado.editable;
-		this.haskellService.editarArchivo(this.archivoSeleccionado.id,this.archivoSeleccionado)
-		.subscribe(
-			archivo => {
-				console.log(this.translateService.get('i18n.msg.file.modified').value);
-
-			}, 
-			error => {
-				this.notifService.error(error);
-			});
-		
-	}
-	
-	cargarArchivo(){
-		if(this.archivoSeleccionado){
-			if(this.archivoSeleccionado.directorio){
-				this.notifService.warning(this.translateService.get('i18n.warning.file.noSelected').value, false);
-			}else{
-				//Si el archivo es compartido con el grupo, editabe y no lo he editado, lo voy a buscar al servidor. 
-				if(this.archivosCompartidos.some(arch => arch.id == this.archivoSeleccionado.id) && this.archivoSeleccionado.editable && this.archivoSeleccionado.archivoOrigenId == -1){
-					if(this.hayArchivoMio()){
-						this.seleccionarArchivoMio();
-						this.sessionService.setArchivo(this.archivoSeleccionado);
-						this.router.navigate(['/matefun']);
-					}else{
-						let cedula = this.authService.getUser().cedula;
-						this.haskellService.getCopiaArchivoCompartidoGrupo(cedula,this.archivoSeleccionado.id).subscribe(
-							archivo => {
-								this.sessionService.setArchivo(archivo);
-								this.router.navigate(['/matefun']);
-							},
-							error =>{
-								console.log(error);
-							});
-					}
-				}else{
-					this.sessionService.setArchivo(this.archivoSeleccionado);
-					this.router.navigate(['/matefun']);
-				}
-			}
-		}else{
-			this.notifService.warning(this.translateService.get('i18n.warning.file.noSelected').value);
-		}
-	}
-
-	confirmarEntrega(){
-		var title = this.titlecasePipe.transform(this.translateService.get('i18n.action.send').value) + " " +
-					this.titlecasePipe.transform(this.translateService.get('i18n.object.file').value);
-		var msg = '';
-		this.translateService.get('i18n.msg.file.toSend', {fileName: this.archivoSeleccionado.nombre}).subscribe((res: string) => {
-			msg = res + '\n' + this.translateService.get('i18n.msg.file.toSendInfo').value;
-		});
-		
-		let disposable = this.dialogService.addDialog(ConfirmComponent, {
-			title: title,
-			message: msg,
-			confirmText: this.titlecasePipe.transform(this.translateService.get('i18n.action.send')),
-			cancelText: this.titlecasePipe.transform(this.translateService.get('i18n.action.cancel')),
-		})
-		.subscribe((isConfirmed)=>{
-			if(isConfirmed) {
-				this.entregarArchivo();
-			}
-		});
-	}
-
-	entregarArchivo(){
-		this.archivoSeleccionado.estado = "Entregado"; //this.titlecasePipe.transform(this.translateService.get('i18n.action.sent'));
-		this.haskellService.editarArchivo(this.archivoSeleccionado.id, this.archivoSeleccionado)
-		.subscribe(
-			archivo => {
-				this.archivoSeleccionado = archivo;                                
-			}, 
-			error => {
-				this.notifService.error(error);
-			});
-	}
-
-	buildTreeFromList_setearDirectorioActual(idDirectorioActual){
-		var archivos = this.archivos;
-		this.sessionService.setArchivosList(archivos);
-		var root :Archivo;
-		
-		for(var a in archivos){
-			var arch = archivos[a];
-			if(arch.padreId===-1){
-				root = arch;
-			} 
-		}
-		this.idRecorridos = [root.id];
-		var archivos2 = archivos.filter(
-			function(a){
-				return a.id!==root.id;
-			}
-			);
-		var directorioActual = this.archivos.filter(function(a){return a.id===idDirectorioActual})[0];
-		var tree = this.buildTree(archivos2,root);
-		this.tree = tree;
-		this.directorioActual = directorioActual;
-		this.ordenarArchivos();
-		this.sessionService.setArchivosTree(tree);
-	}
-
-	buildTreeFromList (){
-		
-		var archivos = this.archivos;
-		this.sessionService.setArchivosList(archivos);
-		var root :Archivo;
-		
-		for(var a in archivos){
-			var arch = archivos[a];
-			if(arch.padreId===-1){
-				root = arch;
-			} 
-		}
-		this.idRecorridos = [root.id];
-		var archivos2 = archivos.filter(
-			function(a){
-				return a.id!==root.id;
-			}
-			);
-		var tree = this.buildTree(archivos2,root);
-		this.tree = tree;
-		this.directorioActual = tree;
-		this.ordenarArchivos();
-		this.sessionService.setArchivosTree(tree);
-	}
-
-
-	buildTree(archivos, root){
-		root.archivos = this.getArchivos(root.id,archivos);
-		for(var a in root.archivos){
-			if(root.archivos[a].directorio && this.idRecorridos[root.archivos[a].id] === undefined){
-				var id = root.archivos[a].id;
-				var archivos2 = archivos.filter(function(a){return a.id!==id});
-				root.archivos[a] = this.buildTree(archivos2 ,root.archivos[a]);
-			}
-		}
-		return root;
-	}
-
-	getArchivos(id,archivos){
-		return archivos.filter(
-			function(a){
-				return a.padreId === id;
-			}
-			);
-	}
-
-	cantArchivos(idPadre,archivos){
-		return archivos.filter(function(a){a.padreId ===idPadre;}).length;
-	}
-
-	elem(id,archivos){
-		if(archivos===[]){
-			return false;
-		}else {
-			return archivos.filter(
-				function(a){
-					a.id ===id;
-				}).length>0;
-		}
-	}
-
-	mkdir(){
-		var that = this;
-		let disposable = this.dialogService.addDialog(NuevoArchivo, {
-			nombre:'', 
-			descripcion:'',
-			esDirectorio:true,
-			parentContext :that})
-		.subscribe((isConfirmed)=>{
-
-			if(isConfirmed) {
-
-
-				//codeMirrorRef.options.readOnly = false;
-				//componentRef.editDialogFired = true;
-			}
-		});
-	}
-	mkFile(){
-		var that = this;
-		let disposable = this.dialogService.addDialog(NuevoArchivo, {
-			nombre:'', 
-			descripcion:'',
-			esDirectorio:false,
-			parentContext :that})
-		.subscribe((isConfirmed)=>{
-
-			if(isConfirmed) {
-
-
-				//codeMirrorRef.options.readOnly = false;
-				//componentRef.editDialogFired = true;
-			}
-		});
-	}
-
-	seleccionarArchivo = function(arch: Archivo){
-		if(arch.directorio){
-			this.directorioActual=arch;
-		}else {
-			this.sessionService.setDirectorioActual(this.directorioActual);
-			this.sessionService.setArchivosCompartidos(this.archivosCompartidos);
-			this.sessionService.cargarDependencias(arch);
-		}
-		this.archivoSeleccionado = arch;	
-		this.preview = arch.contenido;
-		//this.ordenarArchivos();
-	}
-
-	compartirArchivo(){
-		if(this.archivoSeleccionado){
-			var grupos = this.sessionService.getGrupos();
-			if(grupos == undefined){
-				this.haskellService.getGrupos(this.authService.getUser().cedula)
-				.subscribe(
-					gruposRest => {
-						this.sessionService.setGrupos(grupos);
-						this.dialogService.addDialog(CompartirArchivoComponent, {
-							grupos:gruposRest, 
-							archivo:this.archivoSeleccionado,
-							nombreArchivo: {'fileName': this.archivoSeleccionado.nombre },
-							parent:this
-						})
-						.subscribe((isConfirmed)=>{
-							if(isConfirmed) {
-								this.notifService.success("confirmado?");
-							}
-						});
-
-
-					},
-					error => {
-
-					})
-			}else{
-				this.dialogService.addDialog(CompartirArchivoComponent, {
-					grupos:grupos, 
-					archivo:this.archivoSeleccionado,
-					nombreArchivo: {'fileName': this.archivoSeleccionado.nombre },
-					parent:this
-				})
-				.subscribe((isConfirmed)=>{
-					if(isConfirmed) {
-						this.notifService.success("confirmado?");
-					}
-				});
-			}
-		}else{
-			this.notifService.warning(this.translateService.get('i18n.warning.file.noSelected').value);
-		}
-
-	}
-
-	hayArchivoOriginal(){
-		return !this.archivoSeleccionado.directorio && this.archivosCompartidos.some(a => a.id == this.archivoSeleccionado.archivoOrigenId);
-	}
-
-	seleccionarArchivoOriginal(){
-		this.archivoSeleccionado = this.archivosCompartidos.find(arch => arch.id == this.archivoSeleccionado.archivoOrigenId);
-		this.preview = this.archivoSeleccionado.contenido;
-	}
-
-	hayArchivoMio(){
-		return !this.archivoSeleccionado.directorio && this.archivosCompartidos.some(a => a.archivoOrigenId == this.archivoSeleccionado.id);	
-	}
-
-	seleccionarArchivoMio(){
-		this.archivoSeleccionado = this.archivosCompartidos.find(a => a.archivoOrigenId == this.archivoSeleccionado.id);
-		this.preview = this.archivoSeleccionado.contenido;
-	}
-
-	verCalificacion(){
-		this.dialogService.addDialog(VerCalificacionComponent, {
-			archivo:this.archivoSeleccionado
-		}).subscribe((isConfirmed)=>{
-			if(isConfirmed) {
-				this.notifService.success("confirmado?");
-			}
-		});
-	}
+  translateService: any;
+  titlecasePipe: any;
+  archivos: Archivo[] = [];
+  archivosCompartidos: Archivo[] = [];
+  archivosCompartidosSinDuplicados: Archivo[] = [];
+  archivoSeleccionado: Archivo;
+  loading: boolean = false;
+  loadingCompartidos: boolean = false;
+  filtroNombre: string = "";
+  idRecorridos: any = [];
+  esAlumno: boolean;
+  tree: any;
+  preview: string = "";
+  directorioActual: any;
+  sortFunction: any;
+  configCodeMirror = JSON.parse(sessionStorage.getItem("codeMirrorConfig"));
+
+  constructor(
+    private router: Router,
+    private notifService: NotificacionService,
+    private authService: AuthenticationService,
+    private haskellService: HaskellService,
+    private sessionService: SessionService,
+    private dialogService: DialogService,
+    public translate: TranslateService,
+    private route: ActivatedRoute
+  ) {
+    this.translateService = translate;
+    this.titlecasePipe = new TitleCasePipe();
+
+    this.esAlumno =
+      JSON.parse(sessionStorage.getItem("currentUser")).tipo === "alumno";
+    this.directorioActual = {};
+    this.directorioActual.archivos = [];
+    this.configCodeMirror.readOnly = true;
+  }
+  @ViewChild(CodemirrorComponent) codemirror: CodemirrorComponent;
+
+  ngOnInit() {
+    this.sortFunction = "tipo";
+    let cedula = this.authService.getUser().cedula;
+    this.loading = true;
+    this.haskellService.getArchivos(cedula).subscribe(
+      (archivos) => {
+        this.archivos = archivos;
+        this.loading = false;
+        this.buildTreeFromList();
+      },
+      (error) => console.log(error)
+    );
+
+    if (this.esAlumno) {
+      this.loadingCompartidos = true;
+      this.haskellService.getArchivosCompartidosAlumno(cedula).subscribe(
+        (archivos) => {
+          this.archivosCompartidos = archivos;
+          this.archivosCompartidosSinDuplicados = archivos.filter(
+            (arch) =>
+              arch.archivoOrigenId != -1 ||
+              !archivos.some((a) => a.archivoOrigenId == arch.id)
+          );
+          this.loadingCompartidos = false;
+        },
+        (error) => console.log(error)
+      );
+    }
+    this.ordenarArchivos();
+  }
+  ordenarMixto() {
+    //1. primero las carpetas.
+    this.archivosCompartidosSinDuplicados =
+      this.archivosCompartidosSinDuplicados.sort(this.ordenarTipo);
+    this.directorioActual.archivos = this.directorioActual.archivos.sort(
+      this.ordenarTipo
+    );
+
+    var archs1 = this.directorioActual.archivos;
+    var archs2 = this.archivosCompartidosSinDuplicados;
+
+    var archs1_directorios = archs1.filter(function (a) {
+      return a.directorio;
+    });
+
+    var archs1_archivos = archs1.filter(function (a) {
+      return !a.directorio;
+    });
+
+    var archs2_directorios = archs2.filter(function (a) {
+      return a.directorio;
+    });
+
+    var archs2_archivos = archs2.filter(function (a) {
+      return !a.directorio;
+    });
+    //2. dentro de cada categoría ordeno alfabéticamente.
+
+    archs1_archivos = archs1_archivos.sort(this.ordenarAlph);
+    archs1_directorios = archs1_directorios.sort(this.ordenarAlph);
+    archs2_archivos = archs2_archivos.sort(this.ordenarAlph);
+    archs2_directorios = archs2_directorios.sort(this.ordenarAlph);
+
+    for (var i in archs1_archivos) {
+      archs1_directorios.push(archs1_archivos[i]);
+    }
+    for (var i in archs2_archivos) {
+      archs2_directorios.push(archs2_archivos[i]);
+    }
+
+    this.directorioActual.archivos = archs1_directorios;
+    this.archivosCompartidosSinDuplicados = archs2_directorios;
+  }
+
+  ordenarAlph(a, b) {
+    if (a.nombre.toLowerCase() < b.nombre.toLowerCase()) return -1;
+    if (a.nombre.toLowerCase() > b.nombre.toLowerCase()) return 1;
+    return 0;
+  }
+  ordenarFecha(a, b) {
+    if (a.fechaCreacion < b.fechaCreacion) return -1;
+    if (a.fechaCreacion > b.fechaCreacion) return 1;
+    return 0;
+  }
+  ordenarTipo(a, b) {
+    if (a.directorio && !b.directorio) return -1;
+    if (!a.directorio && b.directorio) return 1;
+    return 0;
+  }
+  ordenarPorTipo() {
+    this.sortFunction = "tipo";
+    this.ordenarArchivos();
+  }
+  ordenarPorFecha() {
+    this.sortFunction = "fecha";
+    this.ordenarArchivos();
+  }
+  ordenarFechaCreacion() {
+    this.archivosCompartidosSinDuplicados =
+      this.archivosCompartidosSinDuplicados.sort(this.ordenarFecha);
+    this.directorioActual.archivos = this.directorioActual.archivos.sort(
+      this.ordenarFecha
+    );
+  }
+
+  ordenarArchivos() {
+    var tipo = this.sortFunction;
+    if (tipo === "tipo") {
+      this.ordenarMixto();
+    } else if (tipo === "fecha") {
+      this.ordenarFechaCreacion();
+    }
+  }
+
+  mostrarEliminarDialogo() {
+    if (this.archivoSeleccionado) {
+      //Si el archivo es del alumno lo puedo eliminar.
+      //(No se controla por creador dado que los compartidos mantienen este atributo)
+      if (
+        this.archivos.some((arch) => arch.id == this.archivoSeleccionado.id)
+      ) {
+        var that = this;
+        let disposable = this.dialogService
+          .addDialog(ConfirmarEliminar, {
+            nombreArchivo: { fileName: that.archivoSeleccionado.nombre },
+            esDirectorio: that.archivoSeleccionado.directorio,
+            parentContext: that,
+          })
+          .subscribe((isConfirmed) => {
+            if (isConfirmed) {
+              //codeMirrorRef.options.readOnly = false;
+              //componentRef.editDialogFired = true;
+            }
+          });
+        console.log(disposable);
+      } else {
+        this.notifService.warning(
+          this.translateService.get("i18n.warning.file.noPermissionDelete")
+            .value
+        );
+      }
+    } else {
+      this.notifService.warning(
+        this.translateService.get("i18n.warning.file.noSelected").value
+      );
+    }
+  }
+  seleccionarDirectorioAMover() {
+    if (this.archivoSeleccionado) {
+      //Si el archivo es del alumno lo puedo eliminar.
+      //(No se controla por creador dado que los compartidos mantienen este atributo)
+      if (
+        this.archivos.some((arch) => arch.id == this.archivoSeleccionado.id)
+      ) {
+        var that = this;
+        let disposable = this.dialogService
+          .addDialog(SeleccionarDirectorioMove, {
+            archivos: that.tree,
+            directorioActual: that.directorioActual,
+            nombre: that.archivoSeleccionado.nombre,
+            directorio: that.archivoSeleccionado.directorio,
+            parent: that,
+          })
+          .subscribe((isConfirmed) => {
+            if (isConfirmed) {
+            }
+          });
+      } else {
+        this.notifService.warning(
+          this.translateService.get("i18n.warning.file.noPermissionMove").value
+        );
+      }
+    } else {
+      this.notifService.warning(
+        this.translateService.get("i18n.warning.file.noSelected").value
+      );
+    }
+  }
+
+  recargarArchivos(idDirectorioActual) {
+    let cedula = this.authService.getUser().cedula;
+    this.loading = true;
+    this.haskellService.getArchivos(cedula).subscribe(
+      (archivos) => {
+        this.archivos = archivos;
+        this.loading = false;
+        this.buildTreeFromList_setearDirectorioActual(idDirectorioActual);
+      },
+      (error) => console.log(error)
+    );
+  }
+
+  navBack() {
+    var that = this;
+    if (this.directorioActual.padreId !== -1) {
+      var padre = this.archivos.filter(function (a) {
+        return a.id === that.directorioActual.padreId;
+      })[0];
+      this.directorioActual = padre;
+    }
+  }
+
+  setSoloLectura = function (arch: Archivo) {
+    this.archivoSeleccionado.editable = !this.archivoSeleccionado.editable;
+    this.haskellService
+      .editarArchivo(this.archivoSeleccionado.id, this.archivoSeleccionado)
+      .subscribe(
+        (archivo) => {
+          console.log(
+            this.translateService.get("i18n.msg.file.modified").value
+          );
+        },
+        (error) => {
+          this.notifService.error(error);
+        }
+      );
+  };
+
+  cargarArchivo() {
+    if (this.archivoSeleccionado) {
+      if (this.archivoSeleccionado.directorio) {
+        this.notifService.warning(
+          this.translateService.get("i18n.warning.file.noSelected").value,
+          false
+        );
+      } else {
+        //Si el archivo es compartido con el grupo, editabe y no lo he editado, lo voy a buscar al servidor.
+        if (
+          this.archivosCompartidos.some(
+            (arch) => arch.id == this.archivoSeleccionado.id
+          ) &&
+          this.archivoSeleccionado.editable &&
+          this.archivoSeleccionado.archivoOrigenId == -1
+        ) {
+          if (this.hayArchivoMio()) {
+            this.seleccionarArchivoMio();
+            this.sessionService.setArchivo(this.archivoSeleccionado);
+            this.router.navigate(["/matefun"]);
+          } else {
+            let cedula = this.authService.getUser().cedula;
+            this.haskellService
+              .getCopiaArchivoCompartidoGrupo(
+                cedula,
+                this.archivoSeleccionado.id
+              )
+              .subscribe(
+                (archivo) => {
+                  this.sessionService.setArchivo(archivo);
+                  this.router.navigate(["/matefun"]);
+                },
+                (error) => {
+                  console.log(error);
+                }
+              );
+          }
+        } else {
+          this.sessionService.setArchivo(this.archivoSeleccionado);
+          this.router.navigate(["/matefun"]);
+        }
+      }
+    } else {
+      this.notifService.warning(
+        this.translateService.get("i18n.warning.file.noSelected").value
+      );
+    }
+  }
+
+  confirmarEntrega() {
+    var title =
+      this.titlecasePipe.transform(
+        this.translateService.get("i18n.action.send").value
+      ) +
+      " " +
+      this.titlecasePipe.transform(
+        this.translateService.get("i18n.object.file").value
+      );
+    var msg = "";
+    this.translateService
+      .get("i18n.msg.file.toSend", {
+        fileName: this.archivoSeleccionado.nombre,
+      })
+      .subscribe((res: string) => {
+        msg =
+          res +
+          "\n" +
+          this.translateService.get("i18n.msg.file.toSendInfo").value;
+      });
+
+    let disposable = this.dialogService
+      .addDialog(ConfirmComponent, {
+        title: title,
+        message: msg,
+        confirmText: this.titlecasePipe.transform(
+          this.translateService.get("i18n.action.send")
+        ),
+        cancelText: this.titlecasePipe.transform(
+          this.translateService.get("i18n.action.cancel")
+        ),
+      })
+      .subscribe((isConfirmed) => {
+        if (isConfirmed) {
+          this.entregarArchivo();
+        }
+      });
+  }
+
+  entregarArchivo() {
+    this.archivoSeleccionado.estado = "Entregado"; //this.titlecasePipe.transform(this.translateService.get('i18n.action.sent'));
+    this.haskellService
+      .editarArchivo(this.archivoSeleccionado.id, this.archivoSeleccionado)
+      .subscribe(
+        (archivo) => {
+          this.archivoSeleccionado = archivo;
+        },
+        (error) => {
+          this.notifService.error(error);
+        }
+      );
+  }
+
+  buildTreeFromList_setearDirectorioActual(idDirectorioActual) {
+    var archivos = this.archivos;
+    this.sessionService.setArchivosList(archivos);
+    var root: Archivo;
+
+    for (var a in archivos) {
+      var arch = archivos[a];
+      if (arch.padreId === -1) {
+        root = arch;
+      }
+    }
+    this.idRecorridos = [root.id];
+    var archivos2 = archivos.filter(function (a) {
+      return a.id !== root.id;
+    });
+    var directorioActual = this.archivos.filter(function (a) {
+      return a.id === idDirectorioActual;
+    })[0];
+    var tree = this.buildTree(archivos2, root);
+    this.tree = tree;
+    this.directorioActual = directorioActual;
+    this.ordenarArchivos();
+    this.sessionService.setArchivosTree(tree);
+  }
+
+  buildTreeFromList() {
+    var archivos = this.archivos;
+    this.sessionService.setArchivosList(archivos);
+    var root: Archivo;
+
+    for (var a in archivos) {
+      var arch = archivos[a];
+      if (arch.padreId === -1) {
+        root = arch;
+      }
+    }
+    this.idRecorridos = [root.id];
+    var archivos2 = archivos.filter(function (a) {
+      return a.id !== root.id;
+    });
+    var tree = this.buildTree(archivos2, root);
+    this.tree = tree;
+    this.directorioActual = tree;
+    this.ordenarArchivos();
+    this.sessionService.setArchivosTree(tree);
+  }
+
+  buildTree(archivos, root) {
+    root.archivos = this.getArchivos(root.id, archivos);
+    for (var a in root.archivos) {
+      if (
+        root.archivos[a].directorio &&
+        this.idRecorridos[root.archivos[a].id] === undefined
+      ) {
+        var id = root.archivos[a].id;
+        var archivos2 = archivos.filter(function (a) {
+          return a.id !== id;
+        });
+        root.archivos[a] = this.buildTree(archivos2, root.archivos[a]);
+      }
+    }
+    return root;
+  }
+
+  getArchivos(id, archivos) {
+    return archivos.filter(function (a) {
+      return a.padreId === id;
+    });
+  }
+
+  cantArchivos(idPadre, archivos) {
+    return archivos.filter(function (a) {
+      a.padreId === idPadre;
+    }).length;
+  }
+
+  elem(id, archivos) {
+    if (archivos === []) {
+      return false;
+    } else {
+      return (
+        archivos.filter(function (a) {
+          a.id === id;
+        }).length > 0
+      );
+    }
+  }
+
+  mkdir() {
+    var that = this;
+    let disposable = this.dialogService
+      .addDialog(NuevoArchivo, {
+        nombre: "",
+        descripcion: "",
+        esDirectorio: true,
+        parentContext: that,
+      })
+      .subscribe((isConfirmed) => {
+        if (isConfirmed) {
+          //codeMirrorRef.options.readOnly = false;
+          //componentRef.editDialogFired = true;
+        }
+      });
+  }
+  mkFile() {
+    var that = this;
+    let disposable = this.dialogService
+      .addDialog(NuevoArchivo, {
+        nombre: "",
+        descripcion: "",
+        esDirectorio: false,
+        parentContext: that,
+      })
+      .subscribe((isConfirmed) => {
+        if (isConfirmed) {
+          //codeMirrorRef.options.readOnly = false;
+          //componentRef.editDialogFired = true;
+        }
+      });
+  }
+
+  seleccionarArchivo = function (arch: Archivo) {
+    if (arch.directorio) {
+      this.directorioActual = arch;
+    } else {
+      this.sessionService.setDirectorioActual(this.directorioActual);
+      this.sessionService.setArchivosCompartidos(this.archivosCompartidos);
+      this.sessionService.cargarDependencias(arch);
+    }
+    this.archivoSeleccionado = arch;
+    this.preview = arch.contenido;
+    //this.ordenarArchivos();
+  };
+
+  compartirArchivo() {
+    if (this.archivoSeleccionado) {
+      var grupos = this.sessionService.getGrupos();
+      if (grupos == undefined) {
+        this.haskellService
+          .getGrupos(this.authService.getUser().cedula)
+          .subscribe(
+            (gruposRest) => {
+              this.sessionService.setGrupos(grupos);
+              this.dialogService
+                .addDialog(CompartirArchivoComponent, {
+                  grupos: gruposRest,
+                  archivo: this.archivoSeleccionado,
+                  nombreArchivo: { fileName: this.archivoSeleccionado.nombre },
+                  parent: this,
+                })
+                .subscribe((isConfirmed) => {
+                  if (isConfirmed) {
+                    this.notifService.success("confirmado?");
+                  }
+                });
+            },
+            (error) => {}
+          );
+      } else {
+        this.dialogService
+          .addDialog(CompartirArchivoComponent, {
+            grupos: grupos,
+            archivo: this.archivoSeleccionado,
+            nombreArchivo: { fileName: this.archivoSeleccionado.nombre },
+            parent: this,
+          })
+          .subscribe((isConfirmed) => {
+            if (isConfirmed) {
+              this.notifService.success("confirmado?");
+            }
+          });
+      }
+    } else {
+      this.notifService.warning(
+        this.translateService.get("i18n.warning.file.noSelected").value
+      );
+    }
+  }
+
+  hayArchivoOriginal() {
+    return (
+      !this.archivoSeleccionado.directorio &&
+      this.archivosCompartidos.some(
+        (a) => a.id == this.archivoSeleccionado.archivoOrigenId
+      )
+    );
+  }
+
+  seleccionarArchivoOriginal() {
+    this.archivoSeleccionado = this.archivosCompartidos.find(
+      (arch) => arch.id == this.archivoSeleccionado.archivoOrigenId
+    );
+    this.preview = this.archivoSeleccionado.contenido;
+  }
+
+  hayArchivoMio() {
+    return (
+      !this.archivoSeleccionado.directorio &&
+      this.archivosCompartidos.some(
+        (a) => a.archivoOrigenId == this.archivoSeleccionado.id
+      )
+    );
+  }
+
+  seleccionarArchivoMio() {
+    this.archivoSeleccionado = this.archivosCompartidos.find(
+      (a) => a.archivoOrigenId == this.archivoSeleccionado.id
+    );
+    this.preview = this.archivoSeleccionado.contenido;
+  }
+
+  verCalificacion() {
+    this.dialogService
+      .addDialog(VerCalificacionComponent, {
+        archivo: this.archivoSeleccionado,
+      })
+      .subscribe((isConfirmed) => {
+        if (isConfirmed) {
+          this.notifService.success("confirmado?");
+        }
+      });
+  }
 }
diff --git a/Frontend Angular 4/src/app/layout/archivos/archivos.module.ts b/Frontend Angular 4/src/app/layout/archivos/archivos.module.ts
index b8750352..72be5886 100755
--- a/Frontend Angular 4/src/app/layout/archivos/archivos.module.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/archivos.module.ts	
@@ -1,45 +1,53 @@
-import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
-import { ArchivosComponent } from './archivos.component';
-import { CommonModule } from '@angular/common';
-import { ArchivosRoutingModule } from './archivos-routing.module';
-import { FilterPipe } from '../../shared/pipes/filter.pipe';
-import { ConfirmComponent } from '../../shared/modal/confirm.component'; 
-import { NuevoArchivo } from './nuevoArchivo.component';
-import { VerCalificacionComponent } from './verCalificacion.component';
-import { CompartirArchivoComponent } from './compartirArchivo.component';
-import { SeleccionarDirectorioMove } from './seleccionarDirectorio.component';
-import { ConfirmarEliminar } from './confirmarEliminar.component';
+import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { ArchivosComponent } from "./archivos.component";
+import { CommonModule } from "@angular/common";
+import { ArchivosRoutingModule } from "./archivos-routing.module";
+import { FilterPipe } from "../../shared/pipes/filter.pipe";
+import { ConfirmComponent } from "../../shared/modal/confirm.component";
+import { NuevoArchivo } from "./nuevoArchivo.component";
+import { VerCalificacionComponent } from "./verCalificacion.component";
+import { CompartirArchivoComponent } from "./compartirArchivo.component";
+import { SeleccionarDirectorioMove } from "./seleccionarDirectorio.component";
+import { ConfirmarEliminar } from "./confirmarEliminar.component";
 import { DialogService } from "ng2-bootstrap-modal";
-import { BootstrapModalModule } from 'ng2-bootstrap-modal';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { CodemirrorModule } from 'ng2-codemirror';
-import { NotificacionModule } from '../../notificacion/notificacion.module';
-import { I18nModule } from '../../shared/modules/translate/i18n.module';
-import { TitleCaseModule } from '../../shared/modules/titlecase.module';
+import { BootstrapModalModule } from "ng2-bootstrap-modal";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { CodemirrorModule } from "ng2-codemirror";
+import { NotificacionModule } from "../../notificacion/notificacion.module";
+import { I18nModule } from "../../shared/modules/translate/i18n.module";
+import { TitleCaseModule } from "../../shared/modules/titlecase.module";
 
 @NgModule({
-    imports: [
-        CommonModule,
-        ArchivosRoutingModule,
-        FormsModule,
-        BootstrapModalModule,
-        NgbModule,
-        CodemirrorModule,
-        NotificacionModule,
-        I18nModule,
-        TitleCaseModule
-    ],
-    declarations: [ArchivosComponent, FilterPipe,NuevoArchivo, VerCalificacionComponent, ConfirmComponent, CompartirArchivoComponent,ConfirmarEliminar, SeleccionarDirectorioMove],
-    entryComponents: [
-        NuevoArchivo, 
-        VerCalificacionComponent,
-        ConfirmComponent,
-        CompartirArchivoComponent,
-        ConfirmarEliminar,
-        SeleccionarDirectorioMove
-    ],
-    exports: [ArchivosComponent]
+  imports: [
+    CommonModule,
+    ArchivosRoutingModule,
+    FormsModule,
+    BootstrapModalModule,
+    NgbModule,
+    CodemirrorModule,
+    NotificacionModule,
+    I18nModule,
+    TitleCaseModule,
+  ],
+  declarations: [
+    ArchivosComponent,
+    FilterPipe,
+    NuevoArchivo,
+    VerCalificacionComponent,
+    ConfirmComponent,
+    CompartirArchivoComponent,
+    ConfirmarEliminar,
+    SeleccionarDirectorioMove,
+  ],
+  entryComponents: [
+    NuevoArchivo,
+    VerCalificacionComponent,
+    ConfirmComponent,
+    CompartirArchivoComponent,
+    ConfirmarEliminar,
+    SeleccionarDirectorioMove,
+  ],
+  exports: [ArchivosComponent],
 })
-
-export class ArchivosModule { }
+export class ArchivosModule {}
diff --git a/Frontend Angular 4/src/app/layout/archivos/compartirArchivo.component.ts b/Frontend Angular 4/src/app/layout/archivos/compartirArchivo.component.ts
index 9b9c97a0..be9ee07f 100755
--- a/Frontend Angular 4/src/app/layout/archivos/compartirArchivo.component.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/compartirArchivo.component.ts	
@@ -1,74 +1,111 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
-import { Archivo } from '../../shared/objects/archivo';
-import { Grupo } from '../../shared/objects/grupo';
-import { TranslateService } from '@ngx-translate/core';
+import { Archivo } from "../../shared/objects/archivo";
+import { Grupo } from "../../shared/objects/grupo";
+import { TranslateService } from "@ngx-translate/core";
 
 export interface ConfirmModel {
   archivo: Archivo;
-  grupos:any;
-  parent:any;
-  nombreArchivo: { 'fileName' : string };
+  grupos: any;
+  parent: any;
+  nombreArchivo: { fileName: string };
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-                   <div class="modal-header">
-                      <h6 class="modal-title pull-lefth">
-                        {{ "i18n.msg.file.share" | translate:nombreArchivo }}
-                      </h6>
-                     <button type="button" class="close" (click)="close()" style="margin-rigth:8px;">&times;</button>
-                   </div>
-                   <div class="modal-body" style="height:350px;overflow-y: scroll;">
-                       <div>
-                         <div class="list-group">
-                            <button *ngFor="let g of grupos" type="button" (click)="seleccionarGrupo(g)" style="cursor:pointer" class="list-group-item list-group-item-action" [ngClass]="{'active':grupo!=undefined && g.grado == grupo.grado && g.grupo == grupo.grupo && g.anio == grupo.anio && g.liceoId == grupo.liceoId}">
-                                  <i class="fa fa-group" style="margin-right:10px; font-size: 3em; cursor: pointer;" aria-hidden="true" ></i>
-                                 {{g.grado+"°"+g.grupo+" - "+g.anio}}
-                            </button>
-                          </div>
-                        </div>
-                     </div>
-                   <div class="modal-footer">
-                     <button type="button" class="btn btn-primary" (click)="compartir()">
-                      {{ "i18n.action.share" | translate | titleCase }}
-                     </button>
-                   </div>
-                 </div>
-              </div>`
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h6 class="modal-title pull-lefth">
+          {{ "i18n.msg.file.share" | translate: nombreArchivo }}
+        </h6>
+        <button
+          type="button"
+          class="close"
+          (click)="close()"
+          style="margin-rigth:8px;"
+        >
+          &times;
+        </button>
+      </div>
+      <div class="modal-body" style="height:350px;overflow-y: scroll;">
+        <div>
+          <div class="list-group">
+            <button
+              *ngFor="let g of grupos"
+              type="button"
+              (click)="seleccionarGrupo(g)"
+              style="cursor:pointer"
+              class="list-group-item list-group-item-action"
+              [ngClass]="{
+                active:
+                  grupo != undefined &&
+                  g.grado == grupo.grado &&
+                  g.grupo == grupo.grupo &&
+                  g.anio == grupo.anio &&
+                  g.liceoId == grupo.liceoId
+              }"
+            >
+              <i
+                class="fa fa-group"
+                style="margin-right:10px; font-size: 3em; cursor: pointer;"
+                aria-hidden="true"
+              ></i>
+              {{ g.grado + "°" + g.grupo + " - " + g.anio }}
+            </button>
+          </div>
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-primary" (click)="compartir()">
+          {{ "i18n.action.share" | translate | titleCase }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class CompartirArchivoComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class CompartirArchivoComponent
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   archivo: Archivo;
-  grupos:any;
+  grupos: any;
   grupo: Grupo;
   parent: any;
-  nombreArchivo: { 'fileName' : string };
+  nombreArchivo: { fileName: string };
   translateService: any;
-  
-  constructor(dialogService: DialogService, public translate: TranslateService) {
+
+  constructor(
+    dialogService: DialogService,
+    public translate: TranslateService
+  ) {
     super(dialogService);
     this.translateService = translate;
   }
 
-  seleccionarGrupo(grupo){
+  seleccionarGrupo(grupo) {
     this.grupo = grupo;
   }
 
-  compartir(){
-    this.nombreArchivo = {'fileName' : this.archivo.nombre};
-    if(this.grupo){
-      this.parent.haskellService.compartirArchivoGrupo(this.grupo, this.archivo.id)
-                .subscribe(
-                    success => {
-                        this.parent.notifService.success(this.translateService.get('i18n.msg.file.shared').value);
-                        this.close();
-                    }, 
-                    error => {
-                        this.parent.notifService.error(error);
-                    });
-    }else{
-      this.parent.notifService.error(this.translateService.get('i18n.warning.group.select').value);
+  compartir() {
+    this.nombreArchivo = { fileName: this.archivo.nombre };
+    if (this.grupo) {
+      this.parent.haskellService
+        .compartirArchivoGrupo(this.grupo, this.archivo.id)
+        .subscribe(
+          (success) => {
+            this.parent.notifService.success(
+              this.translateService.get("i18n.msg.file.shared").value
+            );
+            this.close();
+          },
+          (error) => {
+            this.parent.notifService.error(error);
+          }
+        );
+    } else {
+      this.parent.notifService.error(
+        this.translateService.get("i18n.warning.group.select").value
+      );
     }
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/layout/archivos/confirmarEliminar.component.ts b/Frontend Angular 4/src/app/layout/archivos/confirmarEliminar.component.ts
index d7de4a51..81834a81 100755
--- a/Frontend Angular 4/src/app/layout/archivos/confirmarEliminar.component.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/confirmarEliminar.component.ts	
@@ -1,47 +1,61 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
-import { Archivo } from '../../shared/objects/archivo';
+import { Archivo } from "../../shared/objects/archivo";
 
 export interface ConfirmModel {
   nombreArchivo: { fileName: string };
-  esDirectorio:boolean;
+  esDirectorio: boolean;
   parentContext: any;
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-                   <div class="modal-header">
-                      <h6 class="modal-title" *ngIf="!esDirectorio">
-                        {{ "i18n.action.delete" | translate | titleCase }}
-                        {{ "i18n.object.file" | translate | titleCase }}
-                      </h6> 
-                      <h6 class="modal-title" *ngIf="esDirectorio">
-                        {{ "i18n.action.delete" | translate | titleCase }}
-                        {{ "i18n.object.folder" | translate | titleCase }}
-                      </h6> 
-                      <button type="button" class="close" (click)="close()" style="margin-left:8px;">&times;</button>
-                   </div>
-                   <div class="modal-body">
-                        <p *ngIf="!esDirectorio">
-                            {{ "i18n.msg.file.delete" | translate:nombreArchivo }}
-                        </p>
-                        <p *ngIf="esDirectorio">
-                            {{ "i18n.msg.file.delete" | translate:nombreArchivo }}
-                        </p>
-                  </div>
-                  <div class="modal-footer">
-                    <button type="button" class="btn btn-default" (click)="close()">
-                        {{ "i18n.action.cancel" | translate | titleCase }}
-                    </button>
-                    <button type="button" class="btn btn-success" (click)="confirmarEliminar()">
-                        {{ "i18n.action.delete" | translate | titleCase }}
-                    </button>
-                  </div>
-                 </div>
-              </div>`
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h6 class="modal-title" *ngIf="!esDirectorio">
+          {{ "i18n.action.delete" | translate | titleCase }}
+          {{ "i18n.object.file" | translate | titleCase }}
+        </h6>
+        <h6 class="modal-title" *ngIf="esDirectorio">
+          {{ "i18n.action.delete" | translate | titleCase }}
+          {{ "i18n.object.folder" | translate | titleCase }}
+        </h6>
+        <button
+          type="button"
+          class="close"
+          (click)="close()"
+          style="margin-left:8px;"
+        >
+          &times;
+        </button>
+      </div>
+      <div class="modal-body">
+        <p *ngIf="!esDirectorio">
+          {{ "i18n.msg.file.delete" | translate: nombreArchivo }}
+        </p>
+        <p *ngIf="esDirectorio">
+          {{ "i18n.msg.file.delete" | translate: nombreArchivo }}
+        </p>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" (click)="close()">
+          {{ "i18n.action.cancel" | translate | titleCase }}
+        </button>
+        <button
+          type="button"
+          class="btn btn-success"
+          (click)="confirmarEliminar()"
+        >
+          {{ "i18n.action.delete" | translate | titleCase }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class ConfirmarEliminar extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class ConfirmarEliminar
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   nombreArchivo: { fileName: string };
   esDirectorio: boolean;
   parentContext: any;
@@ -49,29 +63,29 @@ export class ConfirmarEliminar extends DialogComponent<ConfirmModel, boolean> im
   constructor(dialogService: DialogService) {
     super(dialogService);
   }
-   confirmarEliminar(){
-      var that = this.parentContext;
-      var directorio = this.parentContext.archivoSeleccionado.directorio;
-      this.parentContext.archivoSeleccionado.eliminado = true;
-      if(directorio){
-        delete this.parentContext.archivoSeleccionado['archivos'];
-      }
-      this.parentContext.haskellService.eliminarArchivo(this.parentContext.archivoSeleccionado.id)
+  confirmarEliminar() {
+    var that = this.parentContext;
+    var directorio = this.parentContext.archivoSeleccionado.directorio;
+    this.parentContext.archivoSeleccionado.eliminado = true;
+    if (directorio) {
+      delete this.parentContext.archivoSeleccionado["archivos"];
+    }
+    this.parentContext.haskellService
+      .eliminarArchivo(this.parentContext.archivoSeleccionado.id)
       .subscribe(
-        archivo => {
-          if(directorio){
+        (archivo) => {
+          if (directorio) {
             var idDirActual = that.directorioActual.padreId;
-          }else {
+          } else {
             var idDirActual = that.directorioActual.id;
           }
           that.recargarArchivos(idDirActual);
-          that.archivoSeleccionado = null;          
-        }, 
-        error => {
+          that.archivoSeleccionado = null;
+        },
+        (error) => {
           this.parentContext.notifService.error(error);
-        });
-      this.close();
-      
-    }
-  
-}
\ No newline at end of file
+        }
+      );
+    this.close();
+  }
+}
diff --git a/Frontend Angular 4/src/app/layout/archivos/index.ts b/Frontend Angular 4/src/app/layout/archivos/index.ts
index ca9d5018..907ba758 100755
--- a/Frontend Angular 4/src/app/layout/archivos/index.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/index.ts	
@@ -1,4 +1,4 @@
 /**
  * This barrel file provides the export for the lazy loaded BlankpageComponent.
  */
-export * from './archivos.component';
\ No newline at end of file
+export * from "./archivos.component";
diff --git a/Frontend Angular 4/src/app/layout/archivos/nuevoArchivo.component.ts b/Frontend Angular 4/src/app/layout/archivos/nuevoArchivo.component.ts
index fc67e03f..b4f8ebdf 100755
--- a/Frontend Angular 4/src/app/layout/archivos/nuevoArchivo.component.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/nuevoArchivo.component.ts	
@@ -1,99 +1,126 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
-import { Archivo } from '../../shared/objects/archivo';
-import { TranslateService } from '@ngx-translate/core';
+import { Archivo } from "../../shared/objects/archivo";
+import { TranslateService } from "@ngx-translate/core";
 
 export interface ConfirmModel {
-  nombre:string;
-  descripcion:string;
+  nombre: string;
+  descripcion: string;
   parentContext: any;
-  esDirectorio:boolean;
+  esDirectorio: boolean;
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h6 class="modal-title" *ngIf="esDirectorio">
+          {{ "i18n.action.new" | translate | titleCase }}
+          {{ "i18n.object.folder" | translate | titleCase }}
+        </h6>
+        <h6 class="modal-title" *ngIf="!esDirectorio">
+          {{ "i18n.action.new" | translate | titleCase }}
+          {{ "i18n.object.file" | translate | titleCase }}
+        </h6>
+        <button
+          type="button"
+          class="close"
+          (click)="close()"
+          style="margin-left:8px;"
+        >
+          &times;
+        </button>
+      </div>
 
-                   <div class="modal-header">
-                      <h6 class="modal-title" *ngIf="esDirectorio">
-                        {{ "i18n.action.new" | translate | titleCase }}
-                        {{ "i18n.object.folder" | translate | titleCase }}
-                      </h6> 
-                      <h6 class="modal-title" *ngIf="!esDirectorio">
-                        {{ "i18n.action.new" | translate | titleCase }}
-                        {{ "i18n.object.file" | translate | titleCase }}
-                      </h6> 
-                      <button type="button" class="close" (click)="close()" style="margin-left:8px;">&times;</button>
-                   </div>
-                   
-                   <div class="modal-body">
-                    <form>
-                      <div class="form-group">
-                        <label for="recipient-name" class="form-control-label">
-                          {{ "i18n.object.name" | translate | titleCase }}:
-                        </label>
-                        <input type="text" class="form-control" id="recipient-name" [(ngModel)]="nombre" [ngModelOptions]="{standalone: true}" >
-                      </div>
-                      <div class="form-group" *ngIf="esDirectorio">
-                        <label for="message-text" class="form-control-label">
-                          {{ "i18n.object.descr" | translate | titleCase }}:
-                        </label>
-                        <textarea class="form-control" id="message-text" [(ngModel)]="descripcion" [ngModelOptions]="{standalone: true}" ></textarea>
-                      </div>
-                    </form>
-                  </div>
+      <div class="modal-body">
+        <form>
+          <div class="form-group">
+            <label for="recipient-name" class="form-control-label">
+              {{ "i18n.object.name" | translate | titleCase }}:
+            </label>
+            <input
+              type="text"
+              class="form-control"
+              id="recipient-name"
+              [(ngModel)]="nombre"
+              [ngModelOptions]="{ standalone: true }"
+            />
+          </div>
+          <div class="form-group" *ngIf="esDirectorio">
+            <label for="message-text" class="form-control-label">
+              {{ "i18n.object.descr" | translate | titleCase }}:
+            </label>
+            <textarea
+              class="form-control"
+              id="message-text"
+              [(ngModel)]="descripcion"
+              [ngModelOptions]="{ standalone: true }"
+            ></textarea>
+          </div>
+        </form>
+      </div>
 
-                  <div class="modal-footer">
-                    <button [disabled]="this.nombre==''" type="button" class="btn btn-success" (click)="confirm()">
-                      {{ "i18n.action.create" | translate | titleCase }}
-                    </button>
-                  </div>
-
-                 </div>
-              </div>`
+      <div class="modal-footer">
+        <button
+          [disabled]="this.nombre == ''"
+          type="button"
+          class="btn btn-success"
+          (click)="confirm()"
+        >
+          {{ "i18n.action.create" | translate | titleCase }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class NuevoArchivo extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class NuevoArchivo
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   nombre: string;
   esDirectorio: boolean;
   descripcion: string;
   parentContext: any;
   translateService: any;
 
-  constructor(dialogService: DialogService, public translate: TranslateService) {
+  constructor(
+    dialogService: DialogService,
+    public translate: TranslateService
+  ) {
     super(dialogService);
     this.translateService = translate;
   }
   confirm() {
     var nombre = this.nombre;
     var desc = this.descripcion;
-    var archivo : Archivo;
+    var archivo: Archivo;
     archivo = new Archivo();
     archivo.cedulaCreador = this.parentContext.directorioActual.cedulaCreador;
-    if(this.esDirectorio){
+    if (this.esDirectorio) {
       archivo.contenido = desc;
     } else {
-      archivo.contenido = '';
+      archivo.contenido = "";
     }
     archivo.directorio = this.esDirectorio;
     archivo.editable = true;
-    archivo.fechaCreacion  = new Date();
+    archivo.fechaCreacion = new Date();
     archivo.nombre = nombre;
-    archivo.padreId =  this.parentContext.directorioActual.id;
+    archivo.padreId = this.parentContext.directorioActual.id;
     var that = this.parentContext;
-    var regex = /^[A-Z]/
-    if(regex.test(nombre)){
+    var regex = /^[A-Z]/;
+    if (regex.test(nombre)) {
       this.parentContext.haskellService.crearArchivo(archivo).subscribe(
-          archivo => {
-            var id = that.directorioActual.id;
-            that.recargarArchivos(id);        
-          }, 
-          error => {
-              this.parentContext.notifService.error(error.text());
-          });
+        (archivo) => {
+          var id = that.directorioActual.id;
+          that.recargarArchivos(id);
+        },
+        (error) => {
+          this.parentContext.notifService.error(error.text());
+        }
+      );
       this.close();
-    }else{
-        alert(this.translateService.get('i18n.warning.file.capitalLetter').value);
+    } else {
+      alert(this.translateService.get("i18n.warning.file.capitalLetter").value);
     }
   }
-  
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/layout/archivos/seleccionarDirectorio.component.ts b/Frontend Angular 4/src/app/layout/archivos/seleccionarDirectorio.component.ts
index 0ab182f6..45f3f79a 100755
--- a/Frontend Angular 4/src/app/layout/archivos/seleccionarDirectorio.component.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/seleccionarDirectorio.component.ts	
@@ -1,97 +1,133 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
-import { Archivo } from '../../shared/objects/archivo';
+import { Archivo } from "../../shared/objects/archivo";
 export interface ConfirmModel {
   directorio: boolean;
-  archivos:any;
-  directorioActual:any;
-  parent:any;
-  nombre:string;
-
+  archivos: any;
+  directorioActual: any;
+  parent: any;
+  nombre: string;
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-                   <div class="modal-header">
-                     <h6 class="modal-title pull-lefth">
-                      {{ "i18n.msg.file.move" | translate }}
-                     </h6> 
-                     <button type="button" class="close" (click)="close()" style="margin-rigth:8px;">&times;</button>
-                   </div>
-                   <div class="modal-body" style="height:350px;overflow-y: scroll;">
-                       <div>
-                         <div class="list-group" >
-                            <button *ngFor="let arch of directorioActual.archivos.filter(esDirectorio)" type="button" (click)="navToDir(arch)" style="cursor:pointer" class="list-group-item list-group-item-action">
-                                  <i *ngIf="arch.directorio" class="fa fa-folder" style="margin-right:10px; font-size: 3em; cursor: pointer;" aria-hidden="true" ></i>
-                                  <i *ngIf="!arch.directorio" class="fa fa-file-text" style="margin-right:10px;font-size: 3em; cursor: pointer;" aria-hidden="true"></i>
-                                 {{arch.nombre}}
-                             </button>
-                          </div>
-                        </div>
-                     </div>
-                   <div class="modal-footer">
-                     <button [disabled]="this.directorioActual.padreId == -1" type="button" class="btn btn-default" (click)="navBack()">
-                      {{ "i18n.action.goBack" | translate | titleCase }}
-                     </button>
-                     <button type="button" class="btn btn-primary" (click)="move()">
-                      {{ "i18n.action.move" | translate | titleCase }}
-                      {{ "i18n.object.here" | translate }}
-                     </button>
-                   </div>
-                 </div>
-              </div>`
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h6 class="modal-title pull-lefth">
+          {{ "i18n.msg.file.move" | translate }}
+        </h6>
+        <button
+          type="button"
+          class="close"
+          (click)="close()"
+          style="margin-rigth:8px;"
+        >
+          &times;
+        </button>
+      </div>
+      <div class="modal-body" style="height:350px;overflow-y: scroll;">
+        <div>
+          <div class="list-group">
+            <button
+              *ngFor="
+                let arch of directorioActual.archivos.filter(esDirectorio)
+              "
+              type="button"
+              (click)="navToDir(arch)"
+              style="cursor:pointer"
+              class="list-group-item list-group-item-action"
+            >
+              <i
+                *ngIf="arch.directorio"
+                class="fa fa-folder"
+                style="margin-right:10px; font-size: 3em; cursor: pointer;"
+                aria-hidden="true"
+              ></i>
+              <i
+                *ngIf="!arch.directorio"
+                class="fa fa-file-text"
+                style="margin-right:10px;font-size: 3em; cursor: pointer;"
+                aria-hidden="true"
+              ></i>
+              {{ arch.nombre }}
+            </button>
+          </div>
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button
+          [disabled]="this.directorioActual.padreId == -1"
+          type="button"
+          class="btn btn-default"
+          (click)="navBack()"
+        >
+          {{ "i18n.action.goBack" | translate | titleCase }}
+        </button>
+        <button type="button" class="btn btn-primary" (click)="move()">
+          {{ "i18n.action.move" | translate | titleCase }}
+          {{ "i18n.object.here" | translate }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class SeleccionarDirectorioMove extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class SeleccionarDirectorioMove
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   directorio: boolean;
-  archivos:any;
-  directorioActual:any;
-  parent:any;
-  nombre:string;
+  archivos: any;
+  directorioActual: any;
+  parent: any;
+  nombre: string;
 
   constructor(dialogService: DialogService) {
     super(dialogService);
   }
 
-
-  esDirectorio(archivo){return archivo.directorio;}
-
+  esDirectorio(archivo) {
+    return archivo.directorio;
+  }
 
   move() {
-    // we set dialog result as true on click on confirm button, 
-    // then we can get dialog result from caller code 
+    // we set dialog result as true on click on confirm button,
+    // then we can get dialog result from caller code
     var that = this;
-    if(this.nombre!==undefined && this.nombre!==""){
-       this.parent.archivoSeleccionado.padreId = this.directorioActual.id;
-       if(this.parent.archivoSeleccionado.directorio){
-         delete this.parent.archivoSeleccionado['archivos'];
-       }
-       this.parent.haskellService.editarArchivo(this.parent.archivoSeleccionado.id,this.parent.archivoSeleccionado)
-      .subscribe(
-        archivo => {
-          
-          that.parent.recargarArchivos(this.directorioActual.id);
-          that.parent.archivoSeleccionado = null;  
-          
-        }, 
-        error => {
-          this.parent.notifService.error(error.text());
-        });
-      
+    if (this.nombre !== undefined && this.nombre !== "") {
+      this.parent.archivoSeleccionado.padreId = this.directorioActual.id;
+      if (this.parent.archivoSeleccionado.directorio) {
+        delete this.parent.archivoSeleccionado["archivos"];
+      }
+      this.parent.haskellService
+        .editarArchivo(
+          this.parent.archivoSeleccionado.id,
+          this.parent.archivoSeleccionado
+        )
+        .subscribe(
+          (archivo) => {
+            that.parent.recargarArchivos(this.directorioActual.id);
+            that.parent.archivoSeleccionado = null;
+          },
+          (error) => {
+            this.parent.notifService.error(error.text());
+          }
+        );
     }
     this.close();
   }
 
-  navToDir(arch){
-    if(arch.directorio){
-      this.directorioActual = arch;  
+  navToDir(arch) {
+    if (arch.directorio) {
+      this.directorioActual = arch;
     }
   }
 
-  navBack(){
+  navBack() {
     var idPadre = this.directorioActual.padreId;
     var archivosList = this.parent.sessionService.getArchivosList();
-    var nuevoDirectorioActual = archivosList.filter(function(a){return a.id===idPadre})[0];
-    this.directorioActual=nuevoDirectorioActual;
+    var nuevoDirectorioActual = archivosList.filter(function (a) {
+      return a.id === idPadre;
+    })[0];
+    this.directorioActual = nuevoDirectorioActual;
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/layout/archivos/verCalificacion.component.ts b/Frontend Angular 4/src/app/layout/archivos/verCalificacion.component.ts
index 18cf3125..844cc7e5 100755
--- a/Frontend Angular 4/src/app/layout/archivos/verCalificacion.component.ts	
+++ b/Frontend Angular 4/src/app/layout/archivos/verCalificacion.component.ts	
@@ -1,39 +1,59 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
-import { Archivo, Evaluacion } from '../../shared/objects/archivo';
+import { Archivo, Evaluacion } from "../../shared/objects/archivo";
 
 export interface ConfirmModel {
   archivo: Archivo;
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-                   <div class="modal-header">
-                     <h6 class="modal-title pull-lefth">
-                      {{ "i18n.object.qualification" | translate | titleCase }} &quot;{{archivo.nombre}}&quot;:
-                     </h6> 
-                     <button type="button" class="close" (click)="close()" style="margin-rigth:8px;">&times;</button>
-                   </div>
-                   <div class="modal-body">
-                       <div>
-                         <label><b>{{ "i18n.object.date" | translate | titleCase }}: </b></label>&nbsp; {{archivo.evaluacion.fecha | date}}<br>
-                         <label><b>{{ "i18n.object.score" | translate | titleCase }} (0-100): </b></label>&nbsp; {{archivo.evaluacion.nota}}<br>
-                         <label><b>{{ "i18n.object.detail" | translate | titleCase }}: </b></label>&nbsp; {{archivo.evaluacion.descripcion}}
-                       </div>
-                   </div>
-                   <div class="modal-footer">
-                     <button type="button" class="btn btn-primary" (click)="close()">
-                      {{ "i18n.action.close" | translate | titleCase }}
-                     </button>
-                   </div>
-                 </div>
-              </div>`
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h6 class="modal-title pull-lefth">
+          {{ "i18n.object.qualification" | translate | titleCase }} &quot;{{
+            archivo.nombre
+          }}&quot;:
+        </h6>
+        <button
+          type="button"
+          class="close"
+          (click)="close()"
+          style="margin-rigth:8px;"
+        >
+          &times;
+        </button>
+      </div>
+      <div class="modal-body">
+        <div>
+          <label
+            ><b>{{ "i18n.object.date" | translate | titleCase }}: </b></label
+          >&nbsp; {{ archivo.evaluacion.fecha | date }}<br />
+          <label
+            ><b
+              >{{ "i18n.object.score" | translate | titleCase }} (0-100):
+            </b></label
+          >&nbsp; {{ archivo.evaluacion.nota }}<br />
+          <label
+            ><b>{{ "i18n.object.detail" | translate | titleCase }}: </b></label
+          >&nbsp; {{ archivo.evaluacion.descripcion }}
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-primary" (click)="close()">
+          {{ "i18n.action.close" | translate | titleCase }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class VerCalificacionComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class VerCalificacionComponent
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   archivo: Archivo;
 
   constructor(dialogService: DialogService) {
     super(dialogService);
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/layout/canvas/canvas.component.ts b/Frontend Angular 4/src/app/layout/canvas/canvas.component.ts
index fa3d9b23..b36bffff 100755
--- a/Frontend Angular 4/src/app/layout/canvas/canvas.component.ts	
+++ b/Frontend Angular 4/src/app/layout/canvas/canvas.component.ts	
@@ -1,1017 +1,1240 @@
-import { Component, ViewChild, HostListener, ComponentRef, ElementRef, Input, Output} from '@angular/core';
-import { NgbPopoverConfig, NgbPopover} from '@ng-bootstrap/ng-bootstrap';
-import { NgbPopoverWindow } from '@ng-bootstrap/ng-bootstrap/popover/popover';
-import { GHCIService } from '../../shared/services/ghci.service'; 
+import {
+  Component,
+  ViewChild,
+  HostListener,
+  ComponentRef,
+  ElementRef,
+  Input,
+  Output,
+} from "@angular/core";
+import { NgbPopoverConfig, NgbPopover } from "@ng-bootstrap/ng-bootstrap";
+import { NgbPopoverWindow } from "@ng-bootstrap/ng-bootstrap/popover/popover";
+import { GHCIService } from "../../shared/services/ghci.service";
 @Component({
-    moduleId: module.id,
-    selector: 'canvas-component',
-    templateUrl: './canvas.component.html',
-    host: {
-        '(window:resize)': 'onResize($event)'
-    }
+  moduleId: module.id,
+  selector: "canvas-component",
+  templateUrl: "./canvas.component.html",
+  host: {
+    "(window:resize)": "onResize($event)",
+  },
 })
-
 export class CanvasComponent {
-    //addEventListener('mousemove', tellPos, false);
-    public constructor(private ghciService: GHCIService) {
-        ghciService.messages.subscribe(
-            canvas=>{
-                this.limpiarCanvas();
-                if(canvas.tipo == 'canvas'){
-                    this.objetos = JSON.parse(canvas.resultado);
-                    this.elementosAnimacion = [];
-                    this.frameAnimacion = 0;
-
-                    this.dibujarObjetos();
-                }else if (canvas.tipo == 'animacion'){
-                    this.elementosAnimacion = canvas.resultado.map(res => JSON.parse(res));
-                    this.frameAnimacion = 0;
-                    this.animando = true;
-                    this.animar();
-                }else if (canvas.tipo == 'graph'){
-                    var jsonCanvas = JSON.parse(canvas.resultado);
-                    var fun = this.generarFuncion(jsonCanvas);
-                    this.objetos = [{tipo:'grafica',ecuacion: eval(fun), color:'black',thickness: 2}]
-                    this.dibujarObjetos();
-                }
-            }
-            ,
-            error=>{
-                this.objetos = [];
-            })
-    }
-    animar_:boolean = true;
-    objetos:any = [];
-    evaluacionVertical:boolean = true;
-    elementosAnimacion:any = [];
-    frameAnimacion:number = 0;
-    animando: boolean = true;
-    mostrarEjes: boolean = true;
-    mostrarGrilla: boolean = true;
-    //Todo, abscisa y ordenada
-    tipoZoom = "Todo";
-    tipoZoomDesc = "Zoom en ambos ejes";
-    timeOutRef:number;
-    timer: number = 1000;
-    public setTimer(t){
-        if(t>40 && t < 1500){
-            this.timer = t;
+  //addEventListener('mousemove', tellPos, false);
+  public constructor(private ghciService: GHCIService) {
+    ghciService.messages.subscribe(
+      (canvas) => {
+        this.limpiarCanvas();
+        if (canvas.tipo == "canvas") {
+          this.objetos = JSON.parse(canvas.resultado);
+          this.elementosAnimacion = [];
+          this.frameAnimacion = 0;
+
+          this.dibujarObjetos();
+        } else if (canvas.tipo == "animacion") {
+          this.elementosAnimacion = canvas.resultado.map((res) =>
+            JSON.parse(res)
+          );
+          this.frameAnimacion = 0;
+          this.animando = true;
+          this.animar();
+        } else if (canvas.tipo == "graph") {
+          var jsonCanvas = JSON.parse(canvas.resultado);
+          var fun = this.generarFuncion(jsonCanvas);
+          this.objetos = [
+            {
+              tipo: "grafica",
+              ecuacion: eval(fun),
+              color: "black",
+              thickness: 2,
+            },
+          ];
+          this.dibujarObjetos();
         }
+      },
+      (error) => {
+        this.objetos = [];
+      }
+    );
+  }
+  animar_: boolean = true;
+  objetos: any = [];
+  evaluacionVertical: boolean = true;
+  elementosAnimacion: any = [];
+  frameAnimacion: number = 0;
+  animando: boolean = true;
+  mostrarEjes: boolean = true;
+  mostrarGrilla: boolean = true;
+  //Todo, abscisa y ordenada
+  tipoZoom = "Todo";
+  tipoZoomDesc = "Zoom en ambos ejes";
+  timeOutRef: number;
+  timer: number = 1000;
+  public setTimer(t) {
+    if (t > 40 && t < 1500) {
+      this.timer = t;
     }
-
-    @ViewChild('canvasElement') canvasRef: ElementRef;
-
-    @ViewChild('popover') popover: NgbPopover;
-
-    onResize(event){
-        if(this.canvasRef.nativeElement.offsetParent){
-            var pixelRatio = window.devicePixelRatio || 1;
-            if(pixelRatio > 2){
-                pixelRatio = 2;
-            }else if (pixelRatio < 1){
-                pixelRatio = 1;
-            }
-            
-            this.canvasRef.nativeElement.width = this.canvasRef.nativeElement.offsetParent.offsetWidth * pixelRatio * 0.94;
-            this.canvasRef.nativeElement.height = this.canvasRef.nativeElement.offsetParent.offsetHeight * pixelRatio * 0.94;
-            var relacionAspecto = this.canvasRef.nativeElement.width/this.canvasRef.nativeElement.height;
-            this.Graph(relacionAspecto);
-            this.dibujarObjetos();
+  }
+
+  @ViewChild("canvasElement") canvasRef: ElementRef;
+
+  @ViewChild("popover") popover: NgbPopover;
+
+  onResize(event) {
+    if (this.canvasRef.nativeElement.offsetParent) {
+      var pixelRatio = window.devicePixelRatio || 1;
+      if (pixelRatio > 2) {
+        pixelRatio = 2;
+      } else if (pixelRatio < 1) {
+        pixelRatio = 1;
+      }
+
+      this.canvasRef.nativeElement.width =
+        this.canvasRef.nativeElement.offsetParent.offsetWidth *
+        pixelRatio *
+        0.94;
+      this.canvasRef.nativeElement.height =
+        this.canvasRef.nativeElement.offsetParent.offsetHeight *
+        pixelRatio *
+        0.94;
+      var relacionAspecto =
+        this.canvasRef.nativeElement.width /
+        this.canvasRef.nativeElement.height;
+      this.Graph(relacionAspecto);
+      this.dibujarObjetos();
+    }
+  }
+
+  exportImg() {
+    function dlCanvas() {
+      var canvas: any;
+      canvas = document.getElementById("myCanvas");
+      var dt = canvas.toDataURL("image/png");
+      /* Change MIME type to trick the browser to downlaod the file instead of displaying it */
+      dt = dt.replace(/^data:image\/[^;]*/, "data:application/octet-stream");
+
+      /* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
+      dt = dt.replace(
+        /^data:application\/octet-stream/,
+        "data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Canvas.png"
+      );
+
+      this.href = dt;
+    }
+    document.getElementById("dl").addEventListener("click", dlCanvas, false);
+    document.getElementById("dl").click();
+  }
+  ngAfterViewInit() {
+    // Make it visually fill the positioned parent
+    this.canvasRef.nativeElement.width =
+      this.canvasRef.nativeElement.offsetParent.offsetWidth * 0.94;
+    this.canvasRef.nativeElement.height =
+      this.canvasRef.nativeElement.offsetParent.offsetHeight * 0.94;
+    var relacionAspecto =
+      this.canvasRef.nativeElement.width / this.canvasRef.nativeElement.height;
+    this.Graph(relacionAspecto);
+
+    this.dibujarObjetos();
+  }
+
+  @HostListener("document:click", ["$event"])
+  private documentClicked(event: MouseEvent): void {
+    // Popover is open
+    if (this.popover && this.popover.isOpen()) {
+      // Not clicked on self element
+      if (
+        !(this.popover as any)._elementRef.nativeElement.contains(event.target)
+      ) {
+        // Hacking typescript to access private member
+        const popoverWindowRef: ComponentRef<NgbPopoverWindow> = (
+          this.popover as any
+        )._windowRef;
+
+        // If clicked outside popover window
+        if (!popoverWindowRef.location.nativeElement.contains(event.target)) {
+          this.popover.close();
         }
+      }
     }
-
-    exportImg(){
-        function dlCanvas() {
-            var canvas :any;
-            canvas = document.getElementById('myCanvas');
-            var dt = canvas.toDataURL('image/png');
-            /* Change MIME type to trick the browser to downlaod the file instead of displaying it */
-            dt = dt.replace(/^data:image\/[^;]*/, 'data:application/octet-stream');
-
-            /* In addition to <a>'s "download" attribute, you can define HTTP-style headers */
-            dt = dt.replace(/^data:application\/octet-stream/, 'data:application/octet-stream;headers=Content-Disposition%3A%20attachment%3B%20filename=Canvas.png');
-
-            this.href = dt;
-        };
-        document.getElementById("dl").addEventListener('click', dlCanvas, false);
-        document.getElementById("dl").click();
+  }
+
+  play() {
+    this.animando = true;
+    this.animar();
+  }
+
+  pause() {
+    this.animando = false;
+  }
+
+  private mostrarOcultarEjes = function () {
+    this.mostrarEjes = !this.mostrarEjes;
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    this.dibujarObjetos();
+  };
+
+  private mostrarOcultarGrilla = function () {
+    this.mostrarGrilla = !this.mostrarGrilla;
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    this.dibujarObjetos();
+  };
+
+  private mostrarEvaluacionVertical = function () {
+    this.evaluacionVertical = !this.evaluacionVertical;
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    this.dibujarObjetos();
+  };
+
+  public limpiarCanvas = function () {
+    this.animar_ = false;
+    clearTimeout(this.timeOutRef);
+    this.objetos = [];
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    if (this.mostrarEjes || this.mostrarGrilla) {
+      this.drawXAxis(this.context);
+      this.drawYAxis(this.context);
     }
-    ngAfterViewInit() {
-
-        // Make it visually fill the positioned parent
-        this.canvasRef.nativeElement.width = this.canvasRef.nativeElement.offsetParent.offsetWidth * 0.94;
-        this.canvasRef.nativeElement.height = this.canvasRef.nativeElement.offsetParent.offsetHeight * 0.94;
-        var relacionAspecto = this.canvasRef.nativeElement.width/this.canvasRef.nativeElement.height;
-        this.Graph(relacionAspecto);
-
-        this.dibujarObjetos();
+  };
+
+  public centrarCanvas = function () {
+    this.maxX = 10;
+    this.maxY = 10 / this.aspectRatio;
+    this.minX = -10;
+    this.minY = -10 / this.aspectRatio;
+
+    this.rangeX = this.maxX - this.minX;
+    this.rangeY = this.maxY - this.minY;
+
+    this.unitsPerTickX = 1;
+    this.unitsPerTickY = 1;
+
+    this.unitX = this.canvasRef.nativeElement.width / this.rangeX;
+    this.unitY = this.canvasRef.nativeElement.height / this.rangeY;
+    this.centerY =
+      (-this.minY / this.rangeY) * this.canvasRef.nativeElement.height;
+    this.centerX =
+      (-this.minX / this.rangeX) * this.canvasRef.nativeElement.width;
+    this.iteration = (this.maxX - this.minX) / this.precision;
+    this.scaleX = this.canvasRef.nativeElement.width / this.rangeX;
+    this.scaleY = this.canvasRef.nativeElement.height / this.rangeY;
+
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    this.dibujarObjetos();
+  };
+
+  public cambiarTipoZoom = function () {
+    //Todo, Abscisa y Ordenada
+    if (this.tipoZoom == "Todo") {
+      this.tipoZoom = "Abscisa";
+      this.tipoZoomDesc = "Zoom en abscisa";
+    } else if (this.tipoZoom == "Abscisa") {
+      this.tipoZoom = "Ordenada";
+      this.tipoZoomDesc = "Zoom en ordenada";
+    } else {
+      this.tipoZoom = "Todo";
+      this.tipoZoomDesc = "Zoom en ambos ejes";
+    }
+  };
+
+  private generarFuncion = function (graph: any) {
+    var funcionString = "";
+    var grafica;
+    for (var fun of graph.funs) {
+      funcionString =
+        "var " +
+        fun.fun +
+        " = function(" +
+        fun.args.join() +
+        "){\n return " +
+        this.generarExpresion(fun.bdy) +
+        "}\n" +
+        funcionString;
+
+      if (fun.fun == graph.graph) {
+        funcionString += "return " + fun.fun + "(" + fun.args.join() + ");\n";
+        grafica = fun;
+      }
+    }
+    funcionString =
+      "(" + grafica.args.join() + ",delta,hayPunto)=>{\n" + funcionString + "}";
+    return funcionString;
+  };
+
+  private generarExpresion = function (exp: any) {
+    var expresion = "";
+    if (exp.kind == "cnd") {
+      expresion =
+        " (" +
+        this.generarExpresion(exp.cond) +
+        "?" +
+        this.generarExpresion(exp.exp1) +
+        ":" +
+        this.generarExpresion(exp.exp2) +
+        ") ";
+    } else if (exp.kind == "bop") {
+      if (exp.op == "==") {
+        expresion =
+          " Math.abs((" +
+          this.generarExpresion(exp.exp1) +
+          ") - (" +
+          this.generarExpresion(exp.exp2) +
+          ")) < delta && hayPunto() ";
+      } else if (exp.op == "/=") {
+        expresion =
+          " Math.abs((" +
+          this.generarExpresion(exp.exp1) +
+          ") - (" +
+          this.generarExpresion(exp.exp2) +
+          ")) > delta ||  Math.abs((" +
+          this.generarExpresion(exp.exp1) +
+          ") - (" +
+          this.generarExpresion(exp.exp2) +
+          ")) < delta && !hayPunto()  ";
+      } else if (exp.op == "^") {
+        expresion =
+          " Math.pow(" +
+          this.generarExpresion(exp.exp1) +
+          "," +
+          this.generarExpresion(exp.exp2) +
+          ") ";
+      } else {
+        expresion =
+          " (" +
+          this.generarExpresion(exp.exp1) +
+          ")" +
+          exp.op +
+          "(" +
+          this.generarExpresion(exp.exp2) +
+          ") ";
+      }
+    } else if (exp.kind == "uop") {
+      expresion = " " + exp.op + " " + this.generarExpresion(exp.exp) + " ";
+    } else if (exp.kind == "app") {
+      if (exp.fun == "cos") {
+        exp.fun = "Math.cos";
+      } else if (exp.fun == "sen") {
+        exp.fun = "Math.sin";
+      } else if (exp.fun == "red") {
+        exp.fun = "Math.round";
+      }
+      expresion =
+        " " +
+        exp.fun +
+        "(" +
+        exp.args.map((e) => this.generarExpresion(e)).join() +
+        ") ";
+    } else if (exp.kind == "tup") {
+      expresion =
+        " (" + exp.exps.map((e) => this.generarExpresion(e)).join() + ") ";
+    } else if (exp.kind == "lit") {
+      expresion = " " + exp.val + " ";
+    } else if (exp.kind == "var") {
+      expresion = " " + exp.var + " ";
+    } else {
+      expresion = " undefined ";
     }
 
-    @HostListener('document:click', ['$event'])
-    private documentClicked(event: MouseEvent): void {
-
-        // Popover is open
-        if (this.popover && this.popover.isOpen()) {
+    return expresion;
+  };
 
-            // Not clicked on self element
-            if (!(this.popover as any)._elementRef.nativeElement.contains(event.target)) {
+  private animar = function () {
+    this.animar_ = true;
+    if (this.mostrarEjes || this.mostrarGrilla) {
+      this.drawXAxis(this.context);
+      this.drawYAxis(this.context);
+    }
 
-                // Hacking typescript to access private member
-                const popoverWindowRef: ComponentRef<NgbPopoverWindow> = (this.popover as any)._windowRef;
+    this.objetos = [];
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    if (this.mostrarEjes || this.mostrarGrilla) {
+      this.drawXAxis(this.context);
+      this.drawYAxis(this.context);
+    }
 
-                // If clicked outside popover window
-                if (!popoverWindowRef.location.nativeElement.contains(event.target)) {
-                    this.popover.close();
-                }
+    this.objetos = this.elementosAnimacion[this.frameAnimacion];
+    this.dibujarObjetos();
+    if (this.animando) {
+      this.timeOutRef = setTimeout(
+        function () {
+          if (this.animando) {
+            this.frameAnimacion++;
+            if (this.frameAnimacion >= this.elementosAnimacion.length) {
+              this.frameAnimacion = 0;
             }
-        }
+            if (this.animar_) {
+              this.animar();
+            }
+          }
+        }.bind(this),
+        this.timer
+      );
     }
+  };
 
-    play(){
-        this.animando = true;
-        this.animar();
+  private dibujarObjetos = function () {
+    if (this.mostrarEjes || this.mostrarGrilla) {
+      this.drawXAxis(this.context);
+      this.drawYAxis(this.context);
     }
-
-    pause(){
-        this.animando = false;
+    for (let obj of this.objetos) {
+      if (obj.tipo == "circulo") {
+        this.drawCircle(obj.x, obj.y, obj.r, obj.color, obj.rotacion);
+      } else if (obj.tipo == "grafica") {
+        this.drawEquation(obj.ecuacion, obj.color, obj.thickness);
+      } else if (obj.tipo == "rectangulo") {
+        this.drawRect(obj.x, obj.y, obj.w, obj.h, obj.color, obj.rotacion);
+      } else if (obj.tipo == "texto") {
+        this.drawText(
+          obj.x,
+          obj.y,
+          obj.text,
+          obj.size,
+          obj.color,
+          obj.rotacion
+        );
+      } else if (obj.tipo == "poligono") {
+        this.drawPolyline(true, obj.puntos, obj.color, obj.rotacion);
+      } else if (obj.tipo == "lineas") {
+        this.drawPolyline(false, obj.puntos, obj.color, obj.rotacion);
+      }
     }
-
-    private mostrarOcultarEjes = function(){
-        this.mostrarEjes = !this.mostrarEjes;
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        this.dibujarObjetos();
+  };
+
+  public Graph = function (relacionAspecto) {
+    this.config = {
+      canvasId: "myCanvas",
+      minX: -10,
+      minY: -10 / relacionAspecto,
+      maxX: 10,
+      maxY: 10 / relacionAspecto,
+      unitsPerTickX: 1,
+      unitsPerTickY: 1,
+    };
+    this.aspectRatio = relacionAspecto;
+    this.canvas = this.canvasRef;
+    this.minX = this.config.minX;
+    this.minY = this.config.minY;
+    this.maxX = this.config.maxX;
+    this.maxY = this.config.maxY;
+    this.unitsPerTickX = this.config.unitsPerTickX;
+    this.unitsPerTickY = this.config.unitsPerTickY;
+    // constants
+    this.axisColor = "#aaa";
+    this.font = "8pt Calibri";
+    this.tickSize = 10;
+
+    // relationships
+    this.context = this.canvasRef.nativeElement.getContext("2d");
+
+    this.rangeX = this.maxX - this.minX;
+    this.rangeY = this.maxY - this.minY;
+
+    this.unitX = this.canvasRef.nativeElement.width / this.rangeX;
+    this.unitY = this.canvasRef.nativeElement.height / this.rangeY;
+    this.centerY = Math.round(
+      Math.abs(this.minY / this.rangeY) * this.canvasRef.nativeElement.height
+    );
+    this.centerX = Math.round(
+      Math.abs(this.minX / this.rangeX) * this.canvasRef.nativeElement.width
+    );
+    this.precision = 1000;
+    this.iteration = (this.maxX - this.minX) / this.precision;
+    this.scaleX = this.canvasRef.nativeElement.width / this.rangeX;
+    this.scaleY = this.canvasRef.nativeElement.height / this.rangeY;
+  };
+
+  private drawXAxis = function (context: any) {
+    context.save();
+
+    // draw tick marks
+    let xPosIncrement = this.unitsPerTickX * this.unitX;
+    //let xPos, unit;
+    context.font = this.font;
+    context.textAlign = "center";
+    context.textBaseline = "top";
+
+    // draw left tick marks
+    let xPos = this.centerX - xPosIncrement;
+    let unit = -1 * this.unitsPerTickX;
+    if (this.mostrarGrilla) {
+      context.beginPath();
+      context.strokeStyle = "#EEEEEE";
+      context.lineWidth = 1;
+      context.moveTo(this.centerX, 0);
+      context.lineTo(this.centerX, this.canvasRef.nativeElement.height);
+      context.stroke();
     }
 
-    private mostrarOcultarGrilla = function(){
-        this.mostrarGrilla = !this.mostrarGrilla;
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        this.dibujarObjetos();
+    while (xPos > 0) {
+      if (this.mostrarGrilla) {
+        context.beginPath();
+        context.strokeStyle = "#EEEEEE";
+        context.lineWidth = 1;
+        context.moveTo(xPos, 0);
+        context.lineTo(xPos, this.canvasRef.nativeElement.height);
+        context.stroke();
+      }
+      if (this.mostrarEjes) {
+        context.beginPath();
+        context.strokeStyle = this.axisColor;
+        context.lineWidth = 2;
+        context.moveTo(xPos, this.centerY - this.tickSize / 2);
+        context.lineTo(xPos, this.centerY + this.tickSize / 2);
+        context.stroke();
+        context.fillText(unit + "", xPos, this.centerY + this.tickSize / 2 + 3);
+      }
+      unit = parseFloat((unit - this.unitsPerTickX).toFixed(2));
+      xPos = Math.round(xPos - xPosIncrement);
     }
 
-    private mostrarEvaluacionVertical = function(){
-        this.evaluacionVertical = !this.evaluacionVertical;
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        this.dibujarObjetos();
+    // draw right tick marks
+    xPos = this.centerX + xPosIncrement;
+    unit = this.unitsPerTickX;
+    while (xPos < this.canvas.nativeElement.width) {
+      if (this.mostrarGrilla) {
+        context.beginPath();
+        context.strokeStyle = "#EEEEEE";
+        context.lineWidth = 1;
+        context.moveTo(xPos, 0);
+        context.lineTo(xPos, this.canvasRef.nativeElement.height);
+        context.stroke();
+      }
+      if (this.mostrarEjes) {
+        context.beginPath();
+        context.strokeStyle = this.axisColor;
+        context.lineWidth = 2;
+        context.moveTo(xPos, this.centerY - this.tickSize / 2);
+        context.lineTo(xPos, this.centerY + this.tickSize / 2);
+        context.stroke();
+        context.fillText(unit + "", xPos, this.centerY + this.tickSize / 2 + 3);
+      }
+      unit = parseFloat((unit + this.unitsPerTickX).toFixed(2));
+      xPos = Math.round(xPos + xPosIncrement);
     }
-
-    public limpiarCanvas = function(){
-        this.animar_ = false; 
-        clearTimeout(this.timeOutRef);
-        this.objetos = [];
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        if(this.mostrarEjes || this.mostrarGrilla){
-            this.drawXAxis(this.context);
-            this.drawYAxis(this.context);
-        }
+    if (this.mostrarEjes) {
+      context.beginPath();
+      context.strokeStyle = this.axisColor;
+      context.lineWidth = 2;
+      context.moveTo(0, this.centerY);
+      context.lineTo(this.canvasRef.nativeElement.width, this.centerY);
+      context.stroke();
+      context.moveTo(this.canvasRef.nativeElement.width, this.centerY);
+      context.lineTo(this.canvasRef.nativeElement.width - 12, this.centerY - 5);
+      context.stroke();
+      context.moveTo(this.canvasRef.nativeElement.width, this.centerY);
+      context.lineTo(this.canvasRef.nativeElement.width - 12, this.centerY + 5);
+      context.stroke();
     }
-
-    public centrarCanvas = function(){
-        this.maxX = 10;
-        this.maxY = 10/this.aspectRatio;
-        this.minX = -10;
-        this.minY = -10/this.aspectRatio;
-
-        this.rangeX = this.maxX - this.minX;
-        this.rangeY = this.maxY - this.minY;
-
-        this.unitsPerTickX = 1;
-        this.unitsPerTickY = 1;
-
-        this.unitX = this.canvasRef.nativeElement.width / this.rangeX;
-        this.unitY = this.canvasRef.nativeElement.height / this.rangeY;
-        this.centerY = (-this.minY / this.rangeY) * this.canvasRef.nativeElement.height;
-        this.centerX = (-this.minX / this.rangeX) * this.canvasRef.nativeElement.width;
-        this.iteration = (this.maxX - this.minX) / this.precision;
-        this.scaleX = this.canvasRef.nativeElement.width / this.rangeX;
-        this.scaleY = this.canvasRef.nativeElement.height / this.rangeY;
-
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        this.dibujarObjetos();
+    context.restore();
+  };
+
+  private drawYAxis = function (context: any) {
+    context.save();
+
+    // draw tick marks
+    let yPosIncrement = this.unitsPerTickY * this.unitY;
+    //var yPos, unit;
+    context.font = this.font;
+    context.textAlign = "right";
+    context.textBaseline = "middle";
+
+    // draw top tick marks
+    let yPos = this.centerY - yPosIncrement;
+    let unit = this.unitsPerTickY;
+    if (this.mostrarGrilla) {
+      context.beginPath();
+      context.strokeStyle = "#EEEEEE";
+      context.lineWidth = 1;
+      context.moveTo(0, this.centerY);
+      context.lineTo(this.canvasRef.nativeElement.width, this.centerY);
+      context.stroke();
     }
-
-    public cambiarTipoZoom = function(){
-        //Todo, Abscisa y Ordenada
-        if(this.tipoZoom == "Todo"){
-            this.tipoZoom = "Abscisa";
-            this.tipoZoomDesc = "Zoom en abscisa";
-        }else if (this.tipoZoom == "Abscisa"){
-            this.tipoZoom = "Ordenada";
-            this.tipoZoomDesc = "Zoom en ordenada";
-        }else{
-            this.tipoZoom = "Todo";
-            this.tipoZoomDesc = "Zoom en ambos ejes";
-        }
+    while (yPos > 0) {
+      if (this.mostrarGrilla) {
+        context.beginPath();
+        context.strokeStyle = "#EEEEEE";
+        context.lineWidth = 1;
+        context.moveTo(0, yPos);
+        context.lineTo(this.canvasRef.nativeElement.width, yPos);
+        context.stroke();
+      }
+      if (this.mostrarEjes) {
+        context.beginPath();
+        context.strokeStyle = this.axisColor;
+        context.lineWidth = 2;
+        context.moveTo(this.centerX - this.tickSize / 2, yPos);
+        context.lineTo(this.centerX + this.tickSize / 2, yPos);
+        context.stroke();
+        context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos);
+      }
+      unit = parseFloat((unit + this.unitsPerTickY).toFixed(2));
+      yPos = Math.round(yPos - yPosIncrement);
     }
-    
 
-    private generarFuncion = function(graph:any){
-        var funcionString="";
-        var grafica;
-        for(var fun of graph.funs){
-            funcionString = "var "+fun.fun + " = function("+fun.args.join()+"){\n return "+this.generarExpresion(fun.bdy)+"}\n"+funcionString;
-
-            if(fun.fun == graph.graph){
-                funcionString += "return "+fun.fun+"("+fun.args.join()+");\n"
-                grafica = fun;
-            }
-        }
-        funcionString = "("+grafica.args.join()+",delta,hayPunto)=>{\n"+funcionString+"}";
-        return funcionString;
-    }
-
-    private generarExpresion = function(exp:any){
-        var expresion = "";
-        if(exp.kind == "cnd"){
-            expresion = " ("+this.generarExpresion(exp.cond)+"?"+this.generarExpresion(exp.exp1)+":"+this.generarExpresion(exp.exp2)+") ";
-        }else if(exp.kind == "bop"){
-            if(exp.op == "=="){
-                expresion = " Math.abs(("+this.generarExpresion(exp.exp1)+") - ("+this.generarExpresion(exp.exp2)+")) < delta && hayPunto() ";
-            }else if (exp.op == "/="){
-                expresion = " Math.abs(("+this.generarExpresion(exp.exp1)+") - ("+this.generarExpresion(exp.exp2)+")) > delta ||  Math.abs(("+this.generarExpresion(exp.exp1)+") - ("+this.generarExpresion(exp.exp2)+")) < delta && !hayPunto()  ";
-            }else if (exp.op == "^"){
-                expresion = " Math.pow("+this.generarExpresion(exp.exp1)+","+this.generarExpresion(exp.exp2)+") ";
-            }else{
-                expresion = " ("+this.generarExpresion(exp.exp1)+")"+exp.op+"("+this.generarExpresion(exp.exp2)+") ";
-            }
-        }else if(exp.kind == "uop"){
-            expresion = " "+exp.op+" "+this.generarExpresion(exp.exp)+" ";
-        }else if(exp.kind == "app"){
-            if(exp.fun == 'cos'){
-                exp.fun = 'Math.cos'
-            }else if(exp.fun == 'sen'){
-                exp.fun = 'Math.sin'
-            }else if(exp.fun == 'red'){
-                exp.fun = 'Math.round'
-            }
-            expresion = " "+exp.fun+"("+exp.args.map(e => this.generarExpresion(e)).join()+") ";
-        }else if(exp.kind == "tup"){
-            expresion = " ("+exp.exps.map(e => this.generarExpresion(e)).join()+") ";
-        }else if(exp.kind == "lit"){
-            expresion = " "+exp.val+" ";
-        }else if(exp.kind == "var"){
-            expresion = " "+exp.var+" ";
-        }else{
-            expresion = " undefined ";
-        }
-
-        return expresion;
+    // draw bottom tick marks
+    yPos = this.centerY + yPosIncrement;
+    unit = -1 * this.unitsPerTickY;
+    while (yPos < this.canvasRef.nativeElement.height) {
+      if (this.mostrarGrilla) {
+        context.beginPath();
+        context.strokeStyle = "#EEEEEE";
+        context.lineWidth = 1;
+        context.moveTo(0, yPos);
+        context.lineTo(this.canvasRef.nativeElement.width, yPos);
+        context.stroke();
+      }
+      if (this.mostrarEjes) {
+        context.beginPath();
+        context.strokeStyle = this.axisColor;
+        context.lineWidth = 2;
+        context.moveTo(this.centerX - this.tickSize / 2, yPos);
+        context.lineTo(this.centerX + this.tickSize / 2, yPos);
+        context.stroke();
+        context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos);
+      }
+      unit = parseFloat((unit - this.unitsPerTickY).toFixed(2));
+      yPos = Math.round(yPos + yPosIncrement);
     }
-
-    private animar = function(){
-        this.animar_ =  true;
-        if(this.mostrarEjes || this.mostrarGrilla){
-            this.drawXAxis(this.context);
-            this.drawYAxis(this.context);
-        }
-
-        this.objetos = [];
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        if(this.mostrarEjes || this.mostrarGrilla){
-            this.drawXAxis(this.context);
-            this.drawYAxis(this.context);
-        }
-
-        this.objetos = this.elementosAnimacion[this.frameAnimacion];        
-        this.dibujarObjetos();
-        if(this.animando){
-            this.timeOutRef =  setTimeout(function(){
-                if(this.animando){
-                    this.frameAnimacion ++;
-                    if(this.frameAnimacion>=this.elementosAnimacion.length){
-                        this.frameAnimacion = 0;
-                    }
-                    if(this.animar_){
-                        this.animar();    
-                    }
-                }
-            }.bind(this),this.timer);
-        }
+    if (this.mostrarEjes) {
+      context.beginPath();
+      context.strokeStyle = this.axisColor;
+      context.lineWidth = 2;
+      context.moveTo(this.centerX, 0);
+      context.lineTo(this.centerX, this.canvasRef.nativeElement.height);
+      context.stroke();
+      context.moveTo(this.centerX, 0);
+      context.lineTo(this.centerX + 5, 12);
+      context.stroke();
+      context.moveTo(this.centerX, 0);
+      context.lineTo(this.centerX - 5, 12);
+      context.stroke();
     }
-
-    private dibujarObjetos = function(){
-        if(this.mostrarEjes || this.mostrarGrilla){
-            this.drawXAxis(this.context);
-            this.drawYAxis(this.context);
-        }
-        for(let obj of this.objetos){
-            if(obj.tipo == 'circulo'){
-                this.drawCircle(obj.x, obj.y, obj.r, obj.color,obj.rotacion);
-            }else if(obj.tipo == 'grafica'){
-                this.drawEquation(obj.ecuacion, obj.color,obj.thickness)
-            }else if (obj.tipo == 'rectangulo'){
-                this.drawRect(obj.x,obj.y,obj.w,obj.h,obj.color,obj.rotacion);
-            }else if (obj.tipo == 'texto'){
-                this.drawText(obj.x, obj.y, obj.text, obj.size, obj.color,obj.rotacion);
-            }else if (obj.tipo == 'poligono'){
-                this.drawPolyline(true,obj.puntos,obj.color, obj.rotacion);
-            }else if (obj.tipo == 'lineas'){
-                this.drawPolyline(false,obj.puntos,obj.color, obj.rotacion);
-            }
-        }
+    context.restore();
+  };
+
+  private transformContext = function (context: any) {
+    context.translate(this.centerX, this.centerY);
+    // stretch grid to fit the canvas window, and
+    //  invert the y scale so that that increments
+    //  as you move upwards
+
+    context.scale(this.scaleX, -this.scaleY);
+  };
+
+  public hayGraficas = function () {
+    for (let obj of this.objetos) {
+      if (obj.tipo == "grafica") {
+        return true;
+      }
     }
-
-    public Graph = function(relacionAspecto) {
-        this.config = {
-            canvasId: 'myCanvas',
-            minX: -10,
-            minY: -10/relacionAspecto,
-            maxX: 10,
-            maxY: 10/relacionAspecto,
-            unitsPerTickX: 1,
-            unitsPerTickY: 1
-        }
-        this.aspectRatio = relacionAspecto;
-        this.canvas = this.canvasRef;
-        this.minX = this.config.minX;
-        this.minY = this.config.minY;
-        this.maxX = this.config.maxX;
-        this.maxY = this.config.maxY;
-        this.unitsPerTickX = this.config.unitsPerTickX;
-        this.unitsPerTickY = this.config.unitsPerTickY;
-        // constants
-        this.axisColor = '#aaa';
-        this.font = '8pt Calibri';
-        this.tickSize = 10;
-
-        // relationships
-        this.context = this.canvasRef.nativeElement.getContext('2d');
-
-        this.rangeX = this.maxX - this.minX;
-        this.rangeY = this.maxY - this.minY;
-
-
-        this.unitX = this.canvasRef.nativeElement.width / this.rangeX;
-        this.unitY = this.canvasRef.nativeElement.height / this.rangeY;
-        this.centerY = Math.round(Math.abs(this.minY / this.rangeY) * this.canvasRef.nativeElement.height);
-        this.centerX = Math.round(Math.abs(this.minX / this.rangeX) * this.canvasRef.nativeElement.width);
-        this.precision = 1000;
-        this.iteration = (this.maxX - this.minX) / this.precision;
-        this.scaleX = this.canvasRef.nativeElement.width / this.rangeX;
-        this.scaleY = this.canvasRef.nativeElement.height / this.rangeY;
-    };
-
-
-
-    private drawXAxis = function(context: any) {
-        context.save();
-
-        // draw tick marks
-        let xPosIncrement = this.unitsPerTickX * this.unitX;
-        //let xPos, unit;
-        context.font = this.font;
-        context.textAlign = 'center';
-        context.textBaseline = 'top';
-
-        // draw left tick marks
-        let xPos = this.centerX - xPosIncrement;
-        let unit = -1 * this.unitsPerTickX;
-        if(this.mostrarGrilla){
-            context.beginPath();
-            context.strokeStyle = "#EEEEEE";;
-            context.lineWidth = 1;
-            context.moveTo(this.centerX, 0);
-            context.lineTo(this.centerX, this.canvasRef.nativeElement.height);
-            context.stroke();
-        }
-
-        while (xPos > 0) {
-            if(this.mostrarGrilla){
-                context.beginPath();
-                context.strokeStyle = "#EEEEEE";;
-                context.lineWidth = 1;
-                context.moveTo(xPos, 0);
-                context.lineTo(xPos, this.canvasRef.nativeElement.height);
-                context.stroke();
-
-            }
-            if(this.mostrarEjes){
-                context.beginPath();
-                context.strokeStyle = this.axisColor;
-                context.lineWidth = 2;
-                context.moveTo(xPos, this.centerY - this.tickSize / 2);
-                context.lineTo(xPos, this.centerY + this.tickSize / 2);
-                context.stroke();
-                context.fillText(unit + '', xPos, this.centerY + this.tickSize / 2 + 3);
-            }
-            unit = parseFloat((unit-this.unitsPerTickX).toFixed(2));
-            xPos = Math.round(xPos - xPosIncrement);
-        }
-
-        // draw right tick marks
-        xPos = this.centerX + xPosIncrement;
-        unit = this.unitsPerTickX;
-        while (xPos < this.canvas.nativeElement.width) {
-            if(this.mostrarGrilla){
-                context.beginPath();
-                context.strokeStyle = "#EEEEEE";;
-                context.lineWidth = 1;
-                context.moveTo(xPos, 0);
-                context.lineTo(xPos, this.canvasRef.nativeElement.height);
-                context.stroke();
-
-            }
-            if(this.mostrarEjes){
-                context.beginPath();
-                context.strokeStyle = this.axisColor;
-                context.lineWidth = 2;
-                context.moveTo(xPos, this.centerY - this.tickSize / 2);
-                context.lineTo(xPos, this.centerY + this.tickSize / 2);
-                context.stroke();
-                context.fillText(unit + '', xPos, this.centerY + this.tickSize / 2 + 3);
-            }
-            unit = parseFloat((unit+this.unitsPerTickX).toFixed(2));
-            xPos = Math.round(xPos + xPosIncrement);
+    return false;
+  };
+
+  public verticalLine = function (x: number, y: number) {
+    if (this.hayGraficas()) {
+      this.context.clearRect(
+        0,
+        0,
+        this.canvasRef.nativeElement.width,
+        this.canvasRef.nativeElement.height
+      );
+      this.dibujarObjetos();
+      var context = this.context;
+
+      this.context.moveTo(x, 0);
+      this.context.lineTo(x, this.canvasRef.nativeElement.height);
+
+      var minimoX = -(this.centerX / this.scaleX);
+      var minimoY = -(this.centerY / this.scaleY);
+
+      var relativeX =
+        (x / this.canvasRef.nativeElement.width) * this.rangeX + minimoX;
+
+      for (let obj of this.objetos) {
+        if (obj.tipo == "grafica") {
+          var relativeX = Math.trunc(relativeX * 100) / 100;
+          var interseccion = obj.ecuacion(relativeX, this.rangeX / 500, () => {
+            return true;
+          });
+          var realY =
+            -((interseccion + minimoY) / this.rangeY) *
+            this.canvasRef.nativeElement.height;
+          if (obj.color) {
+            this.context.fillStyle = obj.color;
+          }
+          this.context.fillText(
+            "(" + relativeX.toFixed(2) + "," + interseccion.toFixed(2) + ")",
+            x + 10,
+            realY
+          );
+          this.context.fillStyle = "black";
+          this.context.fillRect(x - 2.5, realY - 2.5, 5, 5);
         }
-        if(this.mostrarEjes){
-            context.beginPath();
-            context.strokeStyle = this.axisColor;
-            context.lineWidth = 2;
-            context.moveTo(0, this.centerY);
-            context.lineTo(this.canvasRef.nativeElement.width, this.centerY);
-            context.stroke();
-            context.moveTo(this.canvasRef.nativeElement.width, this.centerY);
-            context.lineTo(this.canvasRef.nativeElement.width-12, this.centerY-5);
-            context.stroke();
-            context.moveTo(this.canvasRef.nativeElement.width, this.centerY);
-            context.lineTo(this.canvasRef.nativeElement.width-12, this.centerY+5);
-            context.stroke();
-        }
-        context.restore();
-    };
+      }
 
-    private drawYAxis = function(context: any) {
-        context.save();
-
-        // draw tick marks
-        let yPosIncrement = this.unitsPerTickY * this.unitY;
-        //var yPos, unit;
-        context.font = this.font;
-        context.textAlign = 'right';
-        context.textBaseline = 'middle';
-
-        // draw top tick marks
-        let yPos = this.centerY - yPosIncrement;
-        let unit = this.unitsPerTickY;
-        if(this.mostrarGrilla){
-            context.beginPath();
-            context.strokeStyle = "#EEEEEE";;
-            context.lineWidth = 1;
-            context.moveTo(0, this.centerY);
-            context.lineTo(this.canvasRef.nativeElement.width, this.centerY);
-            context.stroke();
-        }
-        while (yPos > 0) {
-            if(this.mostrarGrilla){
-                context.beginPath();
-                context.strokeStyle = "#EEEEEE";;
-                context.lineWidth = 1;
-                context.moveTo(0, yPos);
-                context.lineTo(this.canvasRef.nativeElement.width, yPos);
-                context.stroke();
-            }
-            if(this.mostrarEjes){
-                context.beginPath();
-                context.strokeStyle = this.axisColor;
-                context.lineWidth = 2;
-                context.moveTo(this.centerX - this.tickSize / 2, yPos);
-                context.lineTo(this.centerX + this.tickSize / 2, yPos);
-                context.stroke();
-                context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos);
-            }
-            unit = parseFloat((unit+this.unitsPerTickY).toFixed(2));
-            yPos = Math.round(yPos - yPosIncrement);
-        }
-
-        // draw bottom tick marks
-        yPos = this.centerY + yPosIncrement;
-        unit = -1 * this.unitsPerTickY;
-        while (yPos < this.canvasRef.nativeElement.height) {
-            if(this.mostrarGrilla){
-
-                context.beginPath();
-                context.strokeStyle = "#EEEEEE";;
-                context.lineWidth = 1;
-                context.moveTo(0, yPos);
-                context.lineTo(this.canvasRef.nativeElement.width, yPos);
-                context.stroke();
-            }
-            if(this.mostrarEjes){
-                context.beginPath();
-                context.strokeStyle = this.axisColor;
-                context.lineWidth = 2;
-                context.moveTo(this.centerX - this.tickSize / 2, yPos);
-                context.lineTo(this.centerX + this.tickSize / 2, yPos);
-                context.stroke();
-                context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos);
-            }
-            unit = parseFloat((unit-this.unitsPerTickY).toFixed(2));
-            yPos = Math.round(yPos + yPosIncrement);
-        }
-        if(this.mostrarEjes){
-            context.beginPath();
-            context.strokeStyle = this.axisColor;
-            context.lineWidth = 2;
-            context.moveTo(this.centerX, 0);
-            context.lineTo(this.centerX, this.canvasRef.nativeElement.height);
-            context.stroke();
-            context.moveTo(this.centerX, 0);
-            context.lineTo(this.centerX+5, 12);
-            context.stroke();
-            context.moveTo(this.centerX, 0);
-            context.lineTo(this.centerX-5, 12);
-            context.stroke();
-        }
-        context.restore();
-    };
-
-    private transformContext = function(context: any) {
-
-        context.translate(this.centerX, this.centerY);
-        // stretch grid to fit the canvas window, and
-        //  invert the y scale so that that increments
-        //  as you move upwards
-
-        context.scale(this.scaleX, -this.scaleY);
+      this.context.stroke();
     }
-
-    public hayGraficas = function(){
-        for(let obj of this.objetos){
-            if(obj.tipo == 'grafica'){
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public verticalLine = function(x:number, y:number){
-        if(this.hayGraficas()){
-            this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-            this.dibujarObjetos();
-            var context = this.context;
-
-            this.context.moveTo(x, 0);
-            this.context.lineTo(x, this.canvasRef.nativeElement.height);
-
-            var minimoX = -(this.centerX / this.scaleX);
-            var minimoY = -(this.centerY / this.scaleY);
-
-            var relativeX = (x/this.canvasRef.nativeElement.width)*this.rangeX + minimoX;
-
-            for(let obj of this.objetos){
-                if(obj.tipo == 'grafica'){
-                    var relativeX = Math.trunc(relativeX*100)/100;
-                    var interseccion = obj.ecuacion(relativeX,this.rangeX/500, ()=>{return true;});
-                    var realY = - ((interseccion+minimoY)/this.rangeY)*this.canvasRef.nativeElement.height;
-                    if(obj.color){
-                        this.context.fillStyle = obj.color;
-                    }
-                    this.context.fillText("("+relativeX.toFixed(2)+","+interseccion.toFixed(2)+")",x+10,realY);
-                    this.context.fillStyle = 'black';
-                    this.context.fillRect(x-2.5,realY-2.5,5,5);
-                }
-            }
-
-            this.context.stroke();
+  };
+
+  public leaveCanvas = function (e: any) {
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    this.dibujarObjetos();
+  };
+
+  public moveGraph = function (e: any) {
+    if (e.buttons === 1 && e.type == "mousemove") {
+      this.centerX += e.offsetX - this.lastPositionX;
+      this.centerY += e.offsetY - this.lastPositionY;
+      this.minX = -(this.centerX / this.scaleX);
+      this.maxY = this.centerY / this.scaleY;
+      this.maxX =
+        this.canvasRef.nativeElement.width / this.scaleX -
+        this.centerX / this.scaleX;
+      this.minY = -(
+        this.canvasRef.nativeElement.height / this.scaleY -
+        this.centerY / this.scaleY
+      );
+      this.lastPositionX = e.offsetX;
+      this.lastPositionY = e.offsetY;
+      this.context.clearRect(
+        0,
+        0,
+        this.canvasRef.nativeElement.width,
+        this.canvasRef.nativeElement.height
+      );
+      this.dibujarObjetos();
+    } else if (e.type == "touchend") {
+      if (e.touches.length == 1) {
+        this.lastPositionX = e.touches[0].clientX;
+        this.lastPositionY = e.touches[0].clientY;
+      }
+    } else if (e.type == "touchmove") {
+      if (e.touches.length == 1) {
+        this.centerX += e.touches[0].clientX - this.lastPositionX;
+        this.centerY += e.touches[0].clientY - this.lastPositionY;
+        this.minX = -(this.centerX / this.scaleX);
+        this.maxY = this.centerY / this.scaleY;
+        this.maxX =
+          this.canvasRef.nativeElement.width / this.scaleX -
+          this.centerX / this.scaleX;
+        this.minY = -(
+          this.canvasRef.nativeElement.height / this.scaleY -
+          this.centerY / this.scaleY
+        );
+        this.lastPositionX = e.touches[0].clientX;
+        this.lastPositionY = e.touches[0].clientY;
+        this.context.clearRect(
+          0,
+          0,
+          this.canvasRef.nativeElement.width,
+          this.canvasRef.nativeElement.height
+        );
+        this.dibujarObjetos();
+      } else if (this.lastZoom && e.touches.length > 1) {
+        this.lastPositionX = e.touches[0].clientX;
+        this.lastPositionY = e.touches[0].clientY;
+        var x = e.touches[1].clientX;
+        var y = e.touches[1].clientY;
+        var newZoom = Math.sqrt(
+          Math.pow(this.lastPositionX - x, 2) +
+            Math.pow(this.lastPositionY - y, 2)
+        );
+        if (Math.abs(newZoom - this.lastZoom) > 2) {
+          //15 es un factor para que el zoom en el dispositivo sea natural.
+          this.zoom((newZoom - this.lastZoom) / 15);
         }
+        this.lastZoom = newZoom;
+      }
+    } else if (e.type == "touchstart") {
+      this.lastPositionX = e.touches[0].clientX;
+      this.lastPositionY = e.touches[0].clientY;
+      if (e.touches.length > 1) {
+        var x = e.touches[1].clientX;
+        var y = e.touches[1].clientY;
+        this.lastZoom = Math.sqrt(
+          Math.pow(this.lastPositionX - x, 2) +
+            Math.pow(this.lastPositionY - y, 2)
+        );
+      } else {
+        this.lastZoom = undefined;
+      }
+    } else {
+      this.lastPositionX = e.offsetX;
+      this.lastPositionY = e.offsetY;
     }
 
-    public leaveCanvas = function(e:any){
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        this.dibujarObjetos();
+    if (this.evaluacionVertical) {
+      var rect = this.canvasRef.nativeElement.getBoundingClientRect();
+      var x, y;
+      if (e instanceof MouseEvent) {
+        x = e.clientX - rect.left;
+        y = e.clientY - rect.top;
+      } else if (e instanceof TouchEvent) {
+        x = e.touches[0].clientX - rect.left;
+        y = e.touches[0].clientY - rect.top;
+      }
+      this.verticalLine(x, y);
     }
 
-    public moveGraph = function(e: any) {
-
-
-        if (e.buttons === 1 && e.type == 'mousemove') {
-            this.centerX += e.offsetX - this.lastPositionX;
-            this.centerY += e.offsetY - this.lastPositionY;
-            this.minX = -(this.centerX / this.scaleX);
-            this.maxY = (this.centerY / this.scaleY);
-            this.maxX = (this.canvasRef.nativeElement.width / this.scaleX) - (this.centerX / this.scaleX);
-            this.minY = -((this.canvasRef.nativeElement.height / this.scaleY) - (this.centerY / this.scaleY));
-            this.lastPositionX = e.offsetX;
-            this.lastPositionY = e.offsetY;
-            this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-            this.dibujarObjetos();
-        } else if(e.type == 'touchend'){
-            if(e.touches.length==1){
-                this.lastPositionX = e.touches[0].clientX;
-                this.lastPositionY = e.touches[0].clientY;
-            }
-        } else if(e.type == 'touchmove') {
-            if(e.touches.length==1){
-                this.centerX += e.touches[0].clientX - this.lastPositionX;
-                this.centerY += e.touches[0].clientY - this.lastPositionY;
-                this.minX = -(this.centerX / this.scaleX);
-                this.maxY = (this.centerY / this.scaleY);
-                this.maxX = (this.canvasRef.nativeElement.width / this.scaleX) - (this.centerX / this.scaleX);
-                this.minY = -((this.canvasRef.nativeElement.height / this.scaleY) - (this.centerY / this.scaleY));
-                this.lastPositionX = e.touches[0].clientX;
-                this.lastPositionY = e.touches[0].clientY;
-                this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-                this.dibujarObjetos();
-            } else if(this.lastZoom && e.touches.length>1){
-                this.lastPositionX = e.touches[0].clientX;
-                this.lastPositionY = e.touches[0].clientY;
-                var x = e.touches[1].clientX;
-                var y = e.touches[1].clientY;
-                var newZoom = Math.sqrt(Math.pow(this.lastPositionX - x,2)+Math.pow(this.lastPositionY - y,2));
-                if(Math.abs(newZoom - this.lastZoom)>2){
-                    //15 es un factor para que el zoom en el dispositivo sea natural. 
-                    this.zoom((newZoom-this.lastZoom)/15);
-                }
-                this.lastZoom = newZoom;
-            }
-        } else if(e.type == 'touchstart'){
-            this.lastPositionX = e.touches[0].clientX;
-            this.lastPositionY = e.touches[0].clientY;
-            if(e.touches.length>1){
-                var x = e.touches[1].clientX;
-                var y = e.touches[1].clientY;
-                this.lastZoom = Math.sqrt(Math.pow(this.lastPositionX - x,2)+Math.pow(this.lastPositionY - y,2));
-            }else{
-                this.lastZoom = undefined;
-            }
-        } else {
-            this.lastPositionX = e.offsetX;
-            this.lastPositionY = e.offsetY;
-        }
-
-        if(this.evaluacionVertical){
-            var rect = this.canvasRef.nativeElement.getBoundingClientRect();
-            var x,y;
-            if(e instanceof MouseEvent){
-                x = e.clientX - rect.left;
-                y = e.clientY - rect.top;
-            }else if(e instanceof TouchEvent){
-                x = e.touches[0].clientX - rect.left;
-                y = e.touches[0].clientY - rect.top;
-            }
-            this.verticalLine(x,y);        
-        }
-
-        if(e instanceof TouchEvent){
-            e.preventDefault();
-        }
-
+    if (e instanceof TouchEvent) {
+      e.preventDefault();
     }
-
-    public zoomGraph = function(e: any) {
-        // cross-browser wheel delta
-        var e = window.event || e; // old IE support
-        var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
-        this.zoom(delta, e.clientX, e.clientY);
-        return false;
+  };
+
+  public zoomGraph = function (e: any) {
+    // cross-browser wheel delta
+    var e = window.event || e; // old IE support
+    var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
+    this.zoom(delta, e.clientX, e.clientY);
+    return false;
+  };
+
+  public zoomMas = function () {
+    this.zoom(1);
+  };
+
+  public zoomMenos = function () {
+    this.zoom(-1);
+  };
+
+  private zoom = function (delta: number, clientX?: number, clientY?: number) {
+    var deltaX = (delta * this.rangeX) / 20;
+    var deltaY = (delta * this.rangeY) / 20;
+
+    if (
+      (this.tipoZoom == "Todo" &&
+        ((this.rangeX < 0.1 && deltaX > 0) ||
+          (this.rangeX > 10000 && deltaX < 0) ||
+          (this.rangeY < 0.1 && deltaY > 0) ||
+          (this.rangeY > 10000 && deltaY < 0))) ||
+      (this.tipoZoom == "Abscisa" &&
+        ((this.rangeX < 0.1 && deltaX > 0) ||
+          (this.rangeX > 10000 && deltaX < 0))) ||
+      (this.tipoZoom == "Ordenada" &&
+        ((this.rangeY < 0.1 && deltaY > 0) ||
+          (this.rangeY > 10000 && deltaY < 0)))
+    ) {
+      return;
     }
 
-    public zoomMas = function(){
-        this.zoom(1);
+    if (clientX && clientY) {
+      var rect = this.canvasRef.nativeElement.getBoundingClientRect();
+      var x = clientX - rect.left;
+      var y = clientY - rect.top;
+      var minimoX = -(this.centerX / this.scaleX);
+      var minimoY = -(
+        this.canvasRef.nativeElement.height / this.scaleY -
+        this.centerY / this.scaleY
+      );
+      var relativeX =
+        (x / this.canvasRef.nativeElement.width) * this.rangeX + minimoX;
+      var relativeY =
+        (1 - y / this.canvasRef.nativeElement.height) * this.rangeY + minimoY;
+      var distRelX =
+        Math.abs(relativeX - this.minX) / Math.abs(this.maxX - this.minX);
+      var distRelY =
+        Math.abs(relativeY - this.minY) / Math.abs(this.maxY - this.minY);
+
+      if (this.tipoZoom == "Todo") {
+        this.maxX -= deltaX * (1 - distRelX);
+        this.maxY -= deltaY * (1 - distRelY);
+        this.minX += deltaX * distRelX;
+        this.minY += deltaY * distRelY;
+      } else if (this.tipoZoom == "Abscisa") {
+        this.maxX -= deltaX * (1 - distRelX);
+        this.minX += deltaX * distRelX;
+      } else {
+        this.maxY -= deltaY * (1 - distRelY);
+        this.minY += deltaY * distRelY;
+      }
+    } else {
+      if (this.tipoZoom == "Todo") {
+        this.maxX -= deltaX;
+        this.maxY -= deltaY;
+        this.minX += deltaX;
+        this.minY += deltaY;
+      } else if (this.tipoZoom == "Abscisa") {
+        this.maxX -= deltaX;
+        this.minX += deltaX;
+      } else {
+        this.maxY -= deltaY;
+        this.minY += deltaY;
+      }
     }
 
-    public zoomMenos = function(){
-        this.zoom(-1);
+    this.rangeX = this.maxX - this.minX;
+    this.rangeY = this.maxY - this.minY;
+
+    if (this.rangeX > 15) {
+      this.unitsPerTickX = Math.round(this.rangeX / 15);
+    } else if (this.rangeX > 4) {
+      this.unitsPerTickX = 1;
+    } else if (this.rangeX > 1.5) {
+      this.unitsPerTickX = Math.round((this.rangeX / 15) * 10) / 10;
+    } else if (this.rangeX > 0.4) {
+      this.unitsPerTickX = 0.1;
+    } else if (this.rangeX > 0.15) {
+      this.unitsPerTickX = Math.round((this.rangeX / 15) * 100) / 100;
+    } else {
+      this.unitsPerTickX = 0.01;
     }
 
-    private zoom = function(delta:number, clientX?:number, clientY?:number){
-        var deltaX = delta*this.rangeX / 20;
-        var deltaY = delta*this.rangeY / 20;
-
-        if ((this.tipoZoom == "Todo" 
-            && ((this.rangeX < 0.1 && deltaX > 0 || this.rangeX > 10000 && deltaX < 0) 
-                || (this.rangeY < 0.1 && deltaY > 0 || this.rangeY > 10000 && deltaY < 0)))
-            || this.tipoZoom == "Abscisa" 
-            && (this.rangeX < 0.1 && deltaX > 0 || this.rangeX > 10000 && deltaX < 0)
-            || this.tipoZoom == "Ordenada" 
-            && (this.rangeY < 0.1 && deltaY > 0 || this.rangeY > 10000 && deltaY < 0)) {
-            return;
-        }
-
-        if(clientX && clientY){
-            var rect = this.canvasRef.nativeElement.getBoundingClientRect();
-            var x = clientX - rect.left;
-            var y = clientY - rect.top;
-            var minimoX = -(this.centerX / this.scaleX);
-            var minimoY = -((this.canvasRef.nativeElement.height / this.scaleY) - (this.centerY / this.scaleY));
-            var relativeX = (x/this.canvasRef.nativeElement.width)*this.rangeX + minimoX;
-            var relativeY = (1-y/this.canvasRef.nativeElement.height)*this.rangeY + minimoY;
-            var distRelX = (Math.abs(relativeX-this.minX)/Math.abs(this.maxX-this.minX));
-            var distRelY = (Math.abs(relativeY-this.minY)/Math.abs(this.maxY-this.minY));
-
-            if(this.tipoZoom == "Todo"){
-                this.maxX -= deltaX*(1-distRelX);
-                this.maxY -= deltaY*(1-distRelY);
-                this.minX += deltaX*distRelX;
-                this.minY += deltaY*distRelY;
-            }else if(this.tipoZoom == "Abscisa"){
-                this.maxX -= deltaX*(1-distRelX);
-                this.minX += deltaX*distRelX;
-            }else{
-                this.maxY -= deltaY*(1-distRelY);
-                this.minY += deltaY*distRelY;
-            }
-        }else{
-            if(this.tipoZoom == "Todo"){
-                this.maxX -= deltaX;
-                this.maxY -= deltaY;
-                this.minX += deltaX;
-                this.minY += deltaY;
-            }else if(this.tipoZoom == "Abscisa"){
-                this.maxX -= deltaX;
-                this.minX += deltaX;
-            }else{
-                this.maxY -= deltaY;
-                this.minY += deltaY;
-            }
-        }
-
-        this.rangeX = this.maxX - this.minX;
-        this.rangeY = this.maxY - this.minY;
-
-        if(this.rangeX >15){
-            this.unitsPerTickX = Math.round(this.rangeX/15);
-        }else if (this.rangeX > 4){
-            this.unitsPerTickX = 1;
-        }else if (this.rangeX > 1.5){
-            this.unitsPerTickX = Math.round((this.rangeX/15)*10)/10;
-        }else if (this.rangeX > 0.4){
-            this.unitsPerTickX = 0.1;
-        }else if (this.rangeX > 0.15){
-            this.unitsPerTickX = Math.round((this.rangeX/15)*100)/100;
-        }else{
-            this.unitsPerTickX = 0.01;
-        }
-
-
-        if(this.rangeY >15){
-            this.unitsPerTickY = Math.round(this.rangeY/15);
-        }else if(this.rangeY > 4){
-            this.unitsPerTickY = 1;
-        }else if (this.rangeY > 1.5){
-            this.unitsPerTickY = Math.round((this.rangeY/15)*10)/10;
-        }else if (this.rangeY > 0.4){
-            this.unitsPerTickY = 0.1;
-        }else if (this.rangeY > 0.15){
-            this.unitsPerTickY = Math.round((this.rangeY/15)*100)/100;
-        }else {
-            this.unitsPerTickY = 0.01;
-        }
-
-        this.unitX = this.canvasRef.nativeElement.width / this.rangeX;
-        this.unitY = this.canvasRef.nativeElement.height / this.rangeY;
-        this.centerY = (this.maxY / this.rangeY) * this.canvasRef.nativeElement.height;
-        this.centerX = (-this.minX / this.rangeX) * this.canvasRef.nativeElement.width;
-        this.iteration = (this.maxX - this.minX) / this.precision;
-        this.scaleX = this.canvasRef.nativeElement.width / this.rangeX;
-        this.scaleY = this.canvasRef.nativeElement.height / this.rangeY;
-
-        this.context.clearRect(0, 0, this.canvasRef.nativeElement.width, this.canvasRef.nativeElement.height);
-        this.dibujarObjetos();
-
+    if (this.rangeY > 15) {
+      this.unitsPerTickY = Math.round(this.rangeY / 15);
+    } else if (this.rangeY > 4) {
+      this.unitsPerTickY = 1;
+    } else if (this.rangeY > 1.5) {
+      this.unitsPerTickY = Math.round((this.rangeY / 15) * 10) / 10;
+    } else if (this.rangeY > 0.4) {
+      this.unitsPerTickY = 0.1;
+    } else if (this.rangeY > 0.15) {
+      this.unitsPerTickY = Math.round((this.rangeY / 15) * 100) / 100;
+    } else {
+      this.unitsPerTickY = 0.01;
     }
 
-    private drawCircle: any = function(x: number, y: number, radius: number, color:string, rotation: number) {
-
-        let context = this.context;
-        context.save();
-        context.save();
-        this.transformContext(context);
-
-        context.beginPath();
-        try {
-            context.translate(0, 0);
-            var degree = rotation * Math.PI / 180;
-            var nuevoX = Math.cos(degree)*x-Math.sin(degree)*y;
-            var nuevoY = Math.sin(degree)*x+Math.cos(degree)*y;
-
-            context.rotate(-degree);
-
-            this.context.arc(nuevoX, nuevoY, radius, 0, 2 * Math.PI, false);
-            if(color){
-                context.fillStyle = color;
-                context.fill();
-            }    
-
-        } catch (e) {
-            this.limpiarCanvas();
-        }
-
-        context.restore();
-        context.lineJoin = 'round';
-        context.lineWidth = this.thickness;
-        context.strokeStyle = this.color;
-        context.stroke();
-        context.restore();
-
+    this.unitX = this.canvasRef.nativeElement.width / this.rangeX;
+    this.unitY = this.canvasRef.nativeElement.height / this.rangeY;
+    this.centerY =
+      (this.maxY / this.rangeY) * this.canvasRef.nativeElement.height;
+    this.centerX =
+      (-this.minX / this.rangeX) * this.canvasRef.nativeElement.width;
+    this.iteration = (this.maxX - this.minX) / this.precision;
+    this.scaleX = this.canvasRef.nativeElement.width / this.rangeX;
+    this.scaleY = this.canvasRef.nativeElement.height / this.rangeY;
+
+    this.context.clearRect(
+      0,
+      0,
+      this.canvasRef.nativeElement.width,
+      this.canvasRef.nativeElement.height
+    );
+    this.dibujarObjetos();
+  };
+
+  private drawCircle: any = function (
+    x: number,
+    y: number,
+    radius: number,
+    color: string,
+    rotation: number
+  ) {
+    let context = this.context;
+    context.save();
+    context.save();
+    this.transformContext(context);
+
+    context.beginPath();
+    try {
+      context.translate(0, 0);
+      var degree = (rotation * Math.PI) / 180;
+      var nuevoX = Math.cos(degree) * x - Math.sin(degree) * y;
+      var nuevoY = Math.sin(degree) * x + Math.cos(degree) * y;
+
+      context.rotate(-degree);
+
+      this.context.arc(nuevoX, nuevoY, radius, 0, 2 * Math.PI, false);
+      if (color) {
+        context.fillStyle = color;
+        context.fill();
+      }
+    } catch (e) {
+      this.limpiarCanvas();
     }
 
-    private drawText: any = function(x: number, y: number, text: string, size:number, color:string, rotation: number) {
-
-        this.context.save();
-        var minimoX = -(this.centerX / this.scaleX);
-        var minimoY = -(this.centerY / this.scaleY);
-
-        var realY = - ((y+minimoY)/this.rangeY)*this.canvasRef.nativeElement.height;
-        var realX = ((x-minimoX)/this.rangeX)*this.canvasRef.nativeElement.width;
-        if(color){
-            this.context.fillStyle = color;
-        }
-
-        this.context.translate(realX, realY);
-        var degree = rotation * Math.PI / 180;
-
-        this.context.rotate(degree);
-
-        this.context.font = (size*100)/this.rangeX+"pt Arial";
-        this.context.textBaseline="middle";
-        this.context.textAlign="center";
-        this.context.fillText(text,0,0);
-        this.context.restore();
+    context.restore();
+    context.lineJoin = "round";
+    context.lineWidth = this.thickness;
+    context.strokeStyle = this.color;
+    context.stroke();
+    context.restore();
+  };
+
+  private drawText: any = function (
+    x: number,
+    y: number,
+    text: string,
+    size: number,
+    color: string,
+    rotation: number
+  ) {
+    this.context.save();
+    var minimoX = -(this.centerX / this.scaleX);
+    var minimoY = -(this.centerY / this.scaleY);
+
+    var realY =
+      -((y + minimoY) / this.rangeY) * this.canvasRef.nativeElement.height;
+    var realX =
+      ((x - minimoX) / this.rangeX) * this.canvasRef.nativeElement.width;
+    if (color) {
+      this.context.fillStyle = color;
     }
 
-    private drawRect: any = function(x: number, y: number, width: number, height:number,color:string, rotation:number) {
-
-        let context = this.context;
-        context.save();
-        context.save();
-        this.transformContext(context);
-
-        context.beginPath();
-        try {
-            context.translate(0, 0);
-            var degree = rotation * Math.PI / 180;
-            var nuevoX = Math.cos(degree)*x-Math.sin(degree)*y;
-            var nuevoY = Math.sin(degree)*x+Math.cos(degree)*y;
-
-            context.rotate(-degree);
-
-            context.rect(nuevoX-width/2,nuevoY-height/2,width,height);
-            if(color){
-                context.fillStyle = color;
-                context.fill();
-            } 
-
-            context.translate(this.centerX, this.centerY);
-        } catch (e) {
-            this.limpiarCanvas();
-        }
-
-        context.restore();
-        context.lineJoin = 'round';
-        context.lineWidth = this.thickness;
-        context.strokeStyle = this.color;
-        context.stroke();
-        context.restore();
+    this.context.translate(realX, realY);
+    var degree = (rotation * Math.PI) / 180;
+
+    this.context.rotate(degree);
+
+    this.context.font = (size * 100) / this.rangeX + "pt Arial";
+    this.context.textBaseline = "middle";
+    this.context.textAlign = "center";
+    this.context.fillText(text, 0, 0);
+    this.context.restore();
+  };
+
+  private drawRect: any = function (
+    x: number,
+    y: number,
+    width: number,
+    height: number,
+    color: string,
+    rotation: number
+  ) {
+    let context = this.context;
+    context.save();
+    context.save();
+    this.transformContext(context);
+
+    context.beginPath();
+    try {
+      context.translate(0, 0);
+      var degree = (rotation * Math.PI) / 180;
+      var nuevoX = Math.cos(degree) * x - Math.sin(degree) * y;
+      var nuevoY = Math.sin(degree) * x + Math.cos(degree) * y;
+
+      context.rotate(-degree);
+
+      context.rect(nuevoX - width / 2, nuevoY - height / 2, width, height);
+      if (color) {
+        context.fillStyle = color;
+        context.fill();
+      }
+
+      context.translate(this.centerX, this.centerY);
+    } catch (e) {
+      this.limpiarCanvas();
     }
 
-    private drawElipse: any = function(x: number, y: number, radiusX: number, radiusY: number, rotation: number) {
-
-        let context = this.context;
-        this.color = 'green';
-        this.thickness = 3;
-
-        context.save();
-        context.save();
-        this.transformContext(context);
-
-        context.beginPath();
-        try {
-            this.context.ellipse(x, y, radiusX, radiusY, rotation * Math.PI / 180, 0, 2 * Math.PI);
-        } catch (e) {
-            this.limpiarCanvas();
-        }
-        context.restore();
-        context.lineJoin = 'round';
-        context.lineWidth = this.thickness;
-        context.strokeStyle = this.color;
-        context.stroke();
-        context.restore();
+    context.restore();
+    context.lineJoin = "round";
+    context.lineWidth = this.thickness;
+    context.strokeStyle = this.color;
+    context.stroke();
+    context.restore();
+  };
+
+  private drawElipse: any = function (
+    x: number,
+    y: number,
+    radiusX: number,
+    radiusY: number,
+    rotation: number
+  ) {
+    let context = this.context;
+    this.color = "green";
+    this.thickness = 3;
+
+    context.save();
+    context.save();
+    this.transformContext(context);
+
+    context.beginPath();
+    try {
+      this.context.ellipse(
+        x,
+        y,
+        radiusX,
+        radiusY,
+        (rotation * Math.PI) / 180,
+        0,
+        2 * Math.PI
+      );
+    } catch (e) {
+      this.limpiarCanvas();
     }
-
-    private drawEquation: any = function(equation: any, color: string, thickness: number) {
-        let context = this.context;
-        context.save();
-        context.save();
-        this.transformContext(context);
-
-        context.beginPath();
-        context.lineWidth = thickness;
+    context.restore();
+    context.lineJoin = "round";
+    context.lineWidth = this.thickness;
+    context.strokeStyle = this.color;
+    context.stroke();
+    context.restore();
+  };
+
+  private drawEquation: any = function (
+    equation: any,
+    color: string,
+    thickness: number
+  ) {
+    let context = this.context;
+    context.save();
+    context.save();
+    this.transformContext(context);
+
+    context.beginPath();
+    context.lineWidth = thickness;
+    try {
+      var firstPoint = equation(this.minX);
+      if (firstPoint > 10e6) {
+        firstPoint = 10e6;
+      } else if (firstPoint < -10e6) {
+        firstPoint = -10e6;
+      }
+      context.moveTo(this.minX, firstPoint);
+      var move = true;
+      var _x = undefined;
+      var _y = undefined;
+      var pendiente = undefined;
+      var h = 1 / this.precision;
+      var delta = this.rangeX / this.precision;
+      var anchoPunto = this.rangeX / 200;
+      for (
+        var x = this.minX + this.iteration;
+        x <= this.maxX;
+        x += this.iteration
+      ) {
         try {
-            var firstPoint = equation(this.minX);
-            if(firstPoint>10e6){
-                firstPoint = 10e6;
-            }else if (firstPoint<-10e6){
-                firstPoint = -10e6;
+          var punto = false;
+          var hayPunto = function () {
+            punto = true;
+            return true;
+          };
+          var y = equation(x, delta, hayPunto);
+          if (punto) {
+            this.context.fillRect(
+              x - anchoPunto / 2,
+              y - anchoPunto / 2,
+              anchoPunto,
+              anchoPunto
+            );
+            move = true;
+            punto = false;
+          } else {
+            if (pendiente != undefined) {
+              var pendienteMas1 = Math.tan(Math.atan(pendiente) + Math.PI / 8);
+              var pendienteMenos1 = Math.tan(
+                Math.atan(pendiente) - Math.PI / 8
+              );
+
+              if (pendiente > 0 && pendienteMas1 < 0) {
+                pendienteMas1 = 1e20; //Number.MAX_VALUE;//1000000;
+              }
+
+              if (pendiente < 0 && pendienteMenos1 > 0) {
+                pendienteMenos1 = -1e20; //Number.MIN_VALUE;//-1000000;
+              }
+
+              var max = (x - _x) * pendienteMas1 - (y - _y);
+              var min = (x - _x) * pendienteMenos1 - (y - _y);
+
+              if (max < 0 || min > 0) {
+                move = true;
+              }
             }
-            context.moveTo(this.minX, firstPoint);
-            var move = true;
-            var _x = undefined;
-            var _y = undefined;
-            var pendiente = undefined;
-            var h = 1/this.precision;
-            var delta = this.rangeX/this.precision;
-            var anchoPunto = this.rangeX/200;
-            for (var x = this.minX + this.iteration; x <= this.maxX; x += this.iteration) {
-                try{
-
-                    var punto = false;
-                    var hayPunto = function(){
-                        punto = true;
-                        return true;
-                    }
-                    var y = equation(x,delta,hayPunto);
-                    if(punto){
-                        this.context.fillRect(x-anchoPunto/2,y-anchoPunto/2,anchoPunto,anchoPunto);
-                        move = true;
-                        punto = false;
-                    }else{
-
-                        if(pendiente != undefined){
-                            var pendienteMas1 = Math.tan(Math.atan(pendiente)+Math.PI/8);
-                            var pendienteMenos1 = Math.tan(Math.atan(pendiente)-Math.PI/8);
-
-                            if(pendiente > 0 && pendienteMas1 < 0){
-                                pendienteMas1 = 1e20;//Number.MAX_VALUE;//1000000;
-                            }
-
-                            if(pendiente < 0 && pendienteMenos1 > 0){
-                                pendienteMenos1 = -1e20;//Number.MIN_VALUE;//-1000000;
-                            }
-
-                            var max = (x - _x)*pendienteMas1 - (y-_y);
-                            var min = (x - _x)*pendienteMenos1 -(y-_y);
-
-                            if(max < 0 || min > 0){ 
-                                move = true;
-                            }
-                        }
-                        if(_x){
-                            pendiente = (y -_y)/(x-_x);
-                        }
-
-                        var copiaY = y;
-                        if(y>10e6){
-                            copiaY = 10e6;
-                        }else if (y<-10e6){
-                            copiaY = -10e6;
-                        }
-                        if(move){
-                            context.moveTo(x,copiaY);
-                            move = false;
-                        }else{
-                            context.lineTo(x, copiaY);
-                        }
-                    }
-                    _x = x;
-                    _y = y;
-                }catch(e){
-                    move = true;
-                }
+            if (_x) {
+              pendiente = (y - _y) / (x - _x);
             }
-        } catch (e) {
-            this.limpiarCanvas();
-        }
-
-        context.restore();
-        context.lineJoin = 'bevel';
-        context.lineWidth = thickness;
-        context.strokeStyle = color;
-        context.stroke();
-        context.restore();
-    };
-
-    private drawPolyline: any = function(polygon:boolean, puntos: any, color: string, rotation:number) {
-        let context = this.context;
-        context.save();
-        context.save();
-        this.transformContext(context);
 
-        context.beginPath();
-        try {
-            if (puntos.length > 1){
-                var inicio = puntos[0];
-                context.moveTo(inicio[0], inicio[1]);
-                for (let punto of puntos) {
-                    context.lineTo(punto[0], punto[1]);
-                }
-                if(polygon){
-                    context.lineTo(inicio[0], inicio[1]);
-                }
+            var copiaY = y;
+            if (y > 10e6) {
+              copiaY = 10e6;
+            } else if (y < -10e6) {
+              copiaY = -10e6;
+            }
+            if (move) {
+              context.moveTo(x, copiaY);
+              move = false;
+            } else {
+              context.lineTo(x, copiaY);
             }
+          }
+          _x = x;
+          _y = y;
         } catch (e) {
-            this.limpiarCanvas();
+          move = true;
         }
+      }
+    } catch (e) {
+      this.limpiarCanvas();
+    }
 
-        context.restore();
-        context.lineJoin = 'round';
-        context.strokeStyle = color;
-        if(color){
-            context.fillStyle = color;
-            context.fill();
-        } 
-        context.strokeStyle = 'black';
-        context.stroke();
-        context.restore();
-    };
+    context.restore();
+    context.lineJoin = "bevel";
+    context.lineWidth = thickness;
+    context.strokeStyle = color;
+    context.stroke();
+    context.restore();
+  };
+
+  private drawPolyline: any = function (
+    polygon: boolean,
+    puntos: any,
+    color: string,
+    rotation: number
+  ) {
+    let context = this.context;
+    context.save();
+    context.save();
+    this.transformContext(context);
+
+    context.beginPath();
+    try {
+      if (puntos.length > 1) {
+        var inicio = puntos[0];
+        context.moveTo(inicio[0], inicio[1]);
+        for (let punto of puntos) {
+          context.lineTo(punto[0], punto[1]);
+        }
+        if (polygon) {
+          context.lineTo(inicio[0], inicio[1]);
+        }
+      }
+    } catch (e) {
+      this.limpiarCanvas();
+    }
 
+    context.restore();
+    context.lineJoin = "round";
+    context.strokeStyle = color;
+    if (color) {
+      context.fillStyle = color;
+      context.fill();
+    }
+    context.strokeStyle = "black";
+    context.stroke();
+    context.restore();
+  };
 }
diff --git a/Frontend Angular 4/src/app/layout/canvas/canvas.module.ts b/Frontend Angular 4/src/app/layout/canvas/canvas.module.ts
index 931d67ff..eaf5106f 100755
--- a/Frontend Angular 4/src/app/layout/canvas/canvas.module.ts	
+++ b/Frontend Angular 4/src/app/layout/canvas/canvas.module.ts	
@@ -1,14 +1,13 @@
-import { NgModule} from '@angular/core';
-import { CommonModule } from '@angular/common'
-import { RouterModule } from '@angular/router';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { FormsModule } from '@angular/forms';
-import { CanvasComponent } from './canvas.component';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { RouterModule } from "@angular/router";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { FormsModule } from "@angular/forms";
+import { CanvasComponent } from "./canvas.component";
 
 @NgModule({
-    imports: [FormsModule, RouterModule, CommonModule, NgbModule],
-    declarations: [CanvasComponent],
-    exports: [CanvasComponent]
+  imports: [FormsModule, RouterModule, CommonModule, NgbModule],
+  declarations: [CanvasComponent],
+  exports: [CanvasComponent],
 })
-
-export class CanvasModule { }
+export class CanvasModule {}
diff --git a/Frontend Angular 4/src/app/layout/canvas/canvas.routes.ts b/Frontend Angular 4/src/app/layout/canvas/canvas.routes.ts
index 38e1ce58..111cb61b 100755
--- a/Frontend Angular 4/src/app/layout/canvas/canvas.routes.ts	
+++ b/Frontend Angular 4/src/app/layout/canvas/canvas.routes.ts	
@@ -1,9 +1,9 @@
-import { Route } from '@angular/router';
-import { CanvasComponent } from './index';
+import { Route } from "@angular/router";
+import { CanvasComponent } from "./index";
 
 export const CanvasRoutes: Route[] = [
-	{
-		path: 'canvas',
-		component: CanvasComponent
-	}
+  {
+    path: "canvas",
+    component: CanvasComponent,
+  },
 ];
diff --git a/Frontend Angular 4/src/app/layout/canvas/index.ts b/Frontend Angular 4/src/app/layout/canvas/index.ts
index ec27135c..cf77b0a9 100755
--- a/Frontend Angular 4/src/app/layout/canvas/index.ts	
+++ b/Frontend Angular 4/src/app/layout/canvas/index.ts	
@@ -1,6 +1,6 @@
 /**
  * This barrel file provides the export for the lazy loaded BlankpageComponent.
  */
-export * from './canvas.component';
+export * from "./canvas.component";
 
-export * from './canvas.routes';
+export * from "./canvas.routes";
diff --git a/Frontend Angular 4/src/app/layout/grupos/calificarEntrega.component.ts b/Frontend Angular 4/src/app/layout/grupos/calificarEntrega.component.ts
index 0d627e95..924070d2 100755
--- a/Frontend Angular 4/src/app/layout/grupos/calificarEntrega.component.ts	
+++ b/Frontend Angular 4/src/app/layout/grupos/calificarEntrega.component.ts	
@@ -1,72 +1,117 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
-import { Archivo, Evaluacion } from '../../shared/objects/archivo';
-import { TranslateService } from '@ngx-translate/core';
+import { Archivo, Evaluacion } from "../../shared/objects/archivo";
+import { TranslateService } from "@ngx-translate/core";
 
 export interface ConfirmModel {
-  cedula:string;
+  cedula: string;
   archivo: Archivo;
   parentContext: any;
-
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-
-                   <div class="modal-header">
-                      <h5 class="modal-title">{{ "i18n.msg.file.qualify" | translate }}</h5> 
-                      <button type="button" class="close" (click)="close()" style="margin-left:8px;">&times;</button>
-                   </div>
-                   
-                   <div class="modal-body">
-                    <form>                      
-                      <div class="form-group">
-                        <label for="message-text" class="form-control-label">{{ "i18n.object.score" | translate | titleCase }} (0-100):</label>
-                        <input type="number" class="form-control" [(ngModel)]="nota" min=1 max=100 [ngModelOptions]="{standalone: true}" >                        
-                      </div>
-                      <div class="form-group">
-                        <label for="message-text" class="form-control-label">{{ "i18n.object.detail" | translate | titleCase }}:</label>
-                        <textarea class="form-control" id="message-text" [(ngModel)]="descripcion" [ngModelOptions]="{standalone: true}" ></textarea>
-                      </div>
-                      <div class="form-group">
-                        <label for="message-text" class="form-control-label">{{ "i18n.object.state" | translate | titleCase }}:</label>
- 			<select name="estado" id="estado" class="form-control"
-        		[(ngModel)]="estado">
-        		<option *ngFor="let st of estados" [value]="st.value">{{ st.label }}</option>
-    			</select>
-                      </div>
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h5 class="modal-title">{{ "i18n.msg.file.qualify" | translate }}</h5>
+        <button
+          type="button"
+          class="close"
+          (click)="close()"
+          style="margin-left:8px;"
+        >
+          &times;
+        </button>
+      </div>
 
-                    </form>
-                  </div>
+      <div class="modal-body">
+        <form>
+          <div class="form-group">
+            <label for="message-text" class="form-control-label"
+              >{{ "i18n.object.score" | translate | titleCase }} (0-100):</label
+            >
+            <input
+              type="number"
+              class="form-control"
+              [(ngModel)]="nota"
+              min="1"
+              max="100"
+              [ngModelOptions]="{ standalone: true }"
+            />
+          </div>
+          <div class="form-group">
+            <label for="message-text" class="form-control-label"
+              >{{ "i18n.object.detail" | translate | titleCase }}:</label
+            >
+            <textarea
+              class="form-control"
+              id="message-text"
+              [(ngModel)]="descripcion"
+              [ngModelOptions]="{ standalone: true }"
+            ></textarea>
+          </div>
+          <div class="form-group">
+            <label for="message-text" class="form-control-label"
+              >{{ "i18n.object.state" | translate | titleCase }}:</label
+            >
+            <select
+              name="estado"
+              id="estado"
+              class="form-control"
+              [(ngModel)]="estado"
+            >
+              <option *ngFor="let st of estados" [value]="st.value">
+                {{ st.label }}
+              </option>
+            </select>
+          </div>
+        </form>
+      </div>
 
-                  <div class="modal-footer">
-                    <button type="button" class="btn btn-secondary" (click)="cancel()">{{ "i18n.action.cancel" | translate | titleCase }}</button>
-                    <button type="button" class="btn btn-success" (click)="confirm()">{{ "i18n.action.qualify" | translate | titleCase }}</button>
-                  </div>
-
-                 </div>
-              </div>`
+      <div class="modal-footer">
+        <button type="button" class="btn btn-secondary" (click)="cancel()">
+          {{ "i18n.action.cancel" | translate | titleCase }}
+        </button>
+        <button type="button" class="btn btn-success" (click)="confirm()">
+          {{ "i18n.action.qualify" | translate | titleCase }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class CalificarEntrega extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class CalificarEntrega
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   descripcion: string = "";
   cedula: string;
   archivo: Archivo;
   nota: number = 0;
-  estado : string = "Corregido";
-  estados : any ;
+  estado: string = "Corregido";
+  estados: any;
   translateService: any;
   parentContext: any;
 
-  constructor(dialogService: DialogService, public translate: TranslateService) {
+  constructor(
+    dialogService: DialogService,
+    public translate: TranslateService
+  ) {
     super(dialogService);
     this.translateService = translate;
-    this.estados = [ {value : "Corregido", label : this.translateService.get('i18n.msg.file.evaluated').value }
-                   , {value : "Devuelto", label : this.translateService.get('i18n.msg.file.returned').value }];
+    this.estados = [
+      {
+        value: "Corregido",
+        label: this.translateService.get("i18n.msg.file.evaluated").value,
+      },
+      {
+        value: "Devuelto",
+        label: this.translateService.get("i18n.msg.file.returned").value,
+      },
+    ];
   }
 
   ngOnInit() {
-    if(this.archivo.evaluacion){
+    if (this.archivo.evaluacion) {
       this.descripcion = this.archivo.evaluacion.descripcion;
       this.nota = this.archivo.evaluacion.nota;
     }
@@ -77,24 +122,29 @@ export class CalificarEntrega extends DialogComponent<ConfirmModel, boolean> imp
     evaluacion.cedulaDocente = this.cedula;
     evaluacion.descripcion = this.descripcion;
     evaluacion.nota = this.nota;
-    if(this.nota>=0 && this.nota<=100){
-      this.parentContext.haskellService.calificarArchivo(this.archivo.id,this.estado,evaluacion )
-       .subscribe(
-        evaluacion => {
-          this.parentContext.notifService.success(this.translateService.get('i18n.msg.file.evaluated').value);
-          this.archivo.evaluacion = evaluacion;
-          this.close();
-        }, 
-        error => {
-          this.parentContext.notifService.error(error);
-        });
-    }else{
-      this.parentContext.notifService.error(this.translateService.get('i18n.warning.file.qualifyOutRange').value);
+    if (this.nota >= 0 && this.nota <= 100) {
+      this.parentContext.haskellService
+        .calificarArchivo(this.archivo.id, this.estado, evaluacion)
+        .subscribe(
+          (evaluacion) => {
+            this.parentContext.notifService.success(
+              this.translateService.get("i18n.msg.file.evaluated").value
+            );
+            this.archivo.evaluacion = evaluacion;
+            this.close();
+          },
+          (error) => {
+            this.parentContext.notifService.error(error);
+          }
+        );
+    } else {
+      this.parentContext.notifService.error(
+        this.translateService.get("i18n.warning.file.qualifyOutRange").value
+      );
     }
   }
 
-  cancel(){
+  cancel() {
     this.close();
   }
-  
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/layout/grupos/grupos-routing.module.ts b/Frontend Angular 4/src/app/layout/grupos/grupos-routing.module.ts
index 6b7c8a8b..282f8937 100755
--- a/Frontend Angular 4/src/app/layout/grupos/grupos-routing.module.ts	
+++ b/Frontend Angular 4/src/app/layout/grupos/grupos-routing.module.ts	
@@ -1,14 +1,12 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
 
-import { GruposComponent } from './grupos.component';
+import { GruposComponent } from "./grupos.component";
 
-const routes: Routes = [
-    { path: '', component: GruposComponent }
-];
+const routes: Routes = [{ path: "", component: GruposComponent }];
 
 @NgModule({
-    imports: [RouterModule.forChild(routes)],
-    exports: [RouterModule]
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
 })
-export class GruposRoutingModule { }
\ No newline at end of file
+export class GruposRoutingModule {}
diff --git a/Frontend Angular 4/src/app/layout/grupos/grupos.component.html b/Frontend Angular 4/src/app/layout/grupos/grupos.component.html
index f264162c..50d865f7 100755
--- a/Frontend Angular 4/src/app/layout/grupos/grupos.component.html	
+++ b/Frontend Angular 4/src/app/layout/grupos/grupos.component.html	
@@ -1,121 +1,259 @@
-<notificacion></notificacion> 
+<notificacion></notificacion>
 <div class="container-fluid">
-    <div class="row">
-        <div class="col-lg-5">
-            <label for="search">Nombre del archivo:</label>
-            <div class="input-group">
-            <!--[(ngModel)]=filtroNombre-->
-                <input type="text" class="form-control" id="search" >
-                <span class="input-group-addon fa fa-search">
-                </span>
-            </div>
-        </div>
+  <div class="row">
+    <div class="col-lg-5">
+      <label for="search">Nombre del archivo:</label>
+      <div class="input-group">
+        <!--[(ngModel)]=filtroNombre-->
+        <input type="text" class="form-control" id="search" />
+        <span class="input-group-addon fa fa-search"> </span>
+      </div>
     </div>
-    <div class="row" style="margin-top: 20px">
-        <div class="col-lg-5">
-            <div class="card" *ngIf="grupoSeleccionado == undefined">
-                <div class="card-header">
-                    <div *ngIf="grupoSeleccionado==undefined">Grupos</div>
-                </div>
-                <div class="card-block" *ngIf="grupoSeleccionado == undefined">
-                    <div class="row listado-grupos" style="min-height: 100px; overflow-y: scroll;">
-                        <div class="loading" *ngIf="loading">
-                            <div class="loading-bar"></div>
-                            <div class="loading-bar"></div>
-                            <div class="loading-bar"></div>
-                            <div class="loading-bar"></div>
-                        </div>
-                        <div *ngFor="let grupo of grupos" (click)="seleccionarGrupo(grupo)" class="col-sm-3 col-4 " style="text-align: center;">
-                            <i class="fa fa-users" style="font-size: 3em; cursor: pointer;color: #f95e5e;" aria-hidden="true"></i>
-                            <p style="cursor: pointer;">{{grupo.grado + '°' + grupo.grupo+" - "+grupo.anio}}</p>
-                        </div>
-                    </div>
-                </div>
+  </div>
+  <div class="row" style="margin-top: 20px">
+    <div class="col-lg-5">
+      <div class="card" *ngIf="grupoSeleccionado == undefined">
+        <div class="card-header">
+          <div *ngIf="grupoSeleccionado == undefined">Grupos</div>
+        </div>
+        <div class="card-block" *ngIf="grupoSeleccionado == undefined">
+          <div
+            class="row listado-grupos"
+            style="min-height: 100px; overflow-y: scroll"
+          >
+            <div class="loading" *ngIf="loading">
+              <div class="loading-bar"></div>
+              <div class="loading-bar"></div>
+              <div class="loading-bar"></div>
+              <div class="loading-bar"></div>
+            </div>
+            <div
+              *ngFor="let grupo of grupos"
+              (click)="seleccionarGrupo(grupo)"
+              class="col-sm-3 col-4"
+              style="text-align: center"
+            >
+              <i
+                class="fa fa-users"
+                style="font-size: 3em; cursor: pointer; color: #f95e5e"
+                aria-hidden="true"
+              ></i>
+              <p style="cursor: pointer">
+                {{ grupo.grado + "°" + grupo.grupo + " - " + grupo.anio }}
+              </p>
             </div>
-            <ngb-tabset *ngIf="grupoSeleccionado" [destroyOnHide]=false>
-                <ngb-tab title="Alumnos">
-                    <ng-template ngbTabContent>
-                        <div class="card">
-                            <div>
-                                <button class="btn btn-sm btn-secondary pull-right" style="cursor: pointer; margin-top: -35px; margin-right: 1px;" (click)="desseleccionarGrupo()" ngbPopover='{{ "i18n.action.goBack" | translate | titleCase }}' data-placement="bottom" triggers="mouseenter:mouseleave">
-                                    <i class="fa fa-arrow-up"></i>
-                                </button>
-                                <p class="pull-right" style="margin-top: -34px; margin-right: 60px;">{{grupoSeleccionado.grado+ '°' + grupoSeleccionado.grupo+" - "+grupoSeleccionado.anio}}</p>
-                            </div>
-                            <div class="card-block">
-                                <div class="row listado-grupos" style="min-height: 100px; overflow-y: scroll;">
-                                    <div *ngFor="let alumno of grupoSeleccionado.alumnos" (click)="seleccionarAlumno(alumno)" class="col-sm-3 " style="text-align: center;">
-                                        <i class="fa fa-user" style="font-size: 3em; cursor: pointer;color: #f95e5e;" aria-hidden="true"></i>
-                                        <p style="cursor: pointer;">{{alumno.apellido +', ' + alumno.nombre}}</p>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </ng-template>
-                </ngb-tab>
-                <ngb-tab title="Archivos">
-                    <ng-template ngbTabContent>
-                        <div class="card">
-                            <div>
-                                <button class="btn btn-sm btn-secondary pull-right" style="cursor: pointer; margin-top: -35px; margin-right: 1px;" (click)="desseleccionarGrupo()"  ngbPopover='{{ "i18n.action.goBack" | translate | titleCase }}' data-placement="bottom" triggers="mouseenter:mouseleave">
-                                    <i class="fa fa-arrow-up"></i>
-                                </button>
-                                <p class="pull-right" style="margin-top: -34px; margin-right: 60px;">{{grupoSeleccionado.grado+ '°' + grupoSeleccionado.grupo+" - "+grupoSeleccionado.anio}}</p>
-                            </div>
-                            <div class="card-block">
-                                <div class="row listado-grupos" style="min-height: 100px; overflow-y: scroll;">
-                                    <div *ngFor="let archivo of grupoSeleccionado.archivos " (click)="seleccionarArchivo(archivo)" class="col-sm-3 col-4" style="text-align: center;">
-                                        <i class="fa fa-file-text" style="font-size: 3em; cursor: pointer;color: #ff8383" aria-hidden="true"></i>
-                                        <p style="cursor: pointer;">{{archivo.nombre}}</p>
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </ng-template>
-                </ngb-tab>
-            </ngb-tabset>
+          </div>
         </div>
-        <div class="col-lg-7">
-            <div class="card" *ngIf="alumnoSeleccionado">
-                <div class="card-block">
-                    <div class="row listadoEntregasAlumnoGrupos" style="min-height: 100px; overflow-y: scroll;" >
-                        <div *ngFor="let entrega of alumnoSeleccionado.archivos" (click)="seleccionarEntrega(entrega)" class="col-sm-3 col-4" style="text-align: center;">
-                            <i [ngStyle]="" class="fa fa-file-text" style="font-size: 3em; cursor: pointer;" aria-hidden="true"></i>
-                            <p style="cursor: pointer;">{{entrega.nombre}}</p>
-                        </div>
-                        <div *ngIf="alumnoSeleccionado.archivos.length == 0" style="width: 100%; text-align: center;">
-                            <i style="color: rgb(220,220,220); font-size: 10em; padding: 0.1em" class="fa fa-file-text"></i>
-                            <p>No hay entregas del alumno: {{alumnoSeleccionado.nombre +' '+alumnoSeleccionado.apellido }}</p>
-                        </div>
-                    </div>
-                   
+      </div>
+      <ngb-tabset *ngIf="grupoSeleccionado" [destroyOnHide]="false">
+        <ngb-tab title="Alumnos">
+          <ng-template ngbTabContent>
+            <div class="card">
+              <div>
+                <button
+                  class="btn btn-sm btn-secondary pull-right"
+                  style="cursor: pointer; margin-top: -35px; margin-right: 1px"
+                  (click)="desseleccionarGrupo()"
+                  ngbPopover="{{
+                    'i18n.action.goBack' | translate | titleCase
+                  }}"
+                  data-placement="bottom"
+                  triggers="mouseenter:mouseleave"
+                >
+                  <i class="fa fa-arrow-up"></i>
+                </button>
+                <p
+                  class="pull-right"
+                  style="margin-top: -34px; margin-right: 60px"
+                >
+                  {{
+                    grupoSeleccionado.grado +
+                      "°" +
+                      grupoSeleccionado.grupo +
+                      " - " +
+                      grupoSeleccionado.anio
+                  }}
+                </p>
+              </div>
+              <div class="card-block">
+                <div
+                  class="row listado-grupos"
+                  style="min-height: 100px; overflow-y: scroll"
+                >
+                  <div
+                    *ngFor="let alumno of grupoSeleccionado.alumnos"
+                    (click)="seleccionarAlumno(alumno)"
+                    class="col-sm-3"
+                    style="text-align: center"
+                  >
+                    <i
+                      class="fa fa-user"
+                      style="font-size: 3em; cursor: pointer; color: #f95e5e"
+                      aria-hidden="true"
+                    ></i>
+                    <p style="cursor: pointer">
+                      {{ alumno.apellido + ", " + alumno.nombre }}
+                    </p>
+                  </div>
                 </div>
+              </div>
             </div>
-            <div class="card" *ngIf="alumnoSeleccionado == undefined && archivoSeleccionado == undefined">
-                <div class="card-block">
-                     <div class="row previewArchivoNoSeleccionadoGrupos" style="min-height: 100px" >
-                        <div style="width: 100%; text-align: center;">
-                            <i style="color: rgb(220,220,220); font-size: 10em; padding: 0.1em" class="fa fa-file-text"></i>
-                        </div>
-                    </div>
+          </ng-template>
+        </ngb-tab>
+        <ngb-tab title="Archivos">
+          <ng-template ngbTabContent>
+            <div class="card">
+              <div>
+                <button
+                  class="btn btn-sm btn-secondary pull-right"
+                  style="cursor: pointer; margin-top: -35px; margin-right: 1px"
+                  (click)="desseleccionarGrupo()"
+                  ngbPopover="{{
+                    'i18n.action.goBack' | translate | titleCase
+                  }}"
+                  data-placement="bottom"
+                  triggers="mouseenter:mouseleave"
+                >
+                  <i class="fa fa-arrow-up"></i>
+                </button>
+                <p
+                  class="pull-right"
+                  style="margin-top: -34px; margin-right: 60px"
+                >
+                  {{
+                    grupoSeleccionado.grado +
+                      "°" +
+                      grupoSeleccionado.grupo +
+                      " - " +
+                      grupoSeleccionado.anio
+                  }}
+                </p>
+              </div>
+              <div class="card-block">
+                <div
+                  class="row listado-grupos"
+                  style="min-height: 100px; overflow-y: scroll"
+                >
+                  <div
+                    *ngFor="let archivo of grupoSeleccionado.archivos"
+                    (click)="seleccionarArchivo(archivo)"
+                    class="col-sm-3 col-4"
+                    style="text-align: center"
+                  >
+                    <i
+                      class="fa fa-file-text"
+                      style="font-size: 3em; cursor: pointer; color: #ff8383"
+                      aria-hidden="true"
+                    ></i>
+                    <p style="cursor: pointer">{{ archivo.nombre }}</p>
+                  </div>
                 </div>
+              </div>
             </div>
-
-            <div class="card" *ngIf="archivoSeleccionado" >
-                <div class="card-header">
-                    <button *ngIf="tipoArchivo == 'entrega'" class="btn btn-sm btn-secondary pull-left mr-2" (click)="calificarEntrega()">
-                        Calificar
-                    </button>
-                    <button *ngIf="esArchivoGrupo()"  ngbPopover="Cargar/Editar" data-placement="bottom" triggers="mouseenter:mouseleave" class="btn btn-sm btn-secondary pull-left mr-2" (click)="cargarArchivoCompartido()">
-                        <i class="fa fa-pencil"></i>
-                    </button>
-                    <div class="pull-left" >
-                        Nombre: {{archivoSeleccionado?.nombre}} - Creado: {{archivoSeleccionado?.fechaCreacion | date}}
-                    </div>
-                </div>
-                <codemirror class="codemirrorGrupos" [(ngModel)]="archivoSeleccionado.contenido" [config]="configCodeMirror" [ngStyle]="{'font-size': configCodeMirror.fontSize+'px'}">
-                </codemirror>
+          </ng-template>
+        </ngb-tab>
+      </ngb-tabset>
+    </div>
+    <div class="col-lg-7">
+      <div class="card" *ngIf="alumnoSeleccionado">
+        <div class="card-block">
+          <div
+            class="row listadoEntregasAlumnoGrupos"
+            style="min-height: 100px; overflow-y: scroll"
+          >
+            <div
+              *ngFor="let entrega of alumnoSeleccionado.archivos"
+              (click)="seleccionarEntrega(entrega)"
+              class="col-sm-3 col-4"
+              style="text-align: center"
+            >
+              <i
+                [ngStyle]=""
+                class="fa fa-file-text"
+                style="font-size: 3em; cursor: pointer"
+                aria-hidden="true"
+              ></i>
+              <p style="cursor: pointer">{{ entrega.nombre }}</p>
             </div>
+            <div
+              *ngIf="alumnoSeleccionado.archivos.length == 0"
+              style="width: 100%; text-align: center"
+            >
+              <i
+                style="
+                  color: rgb(220, 220, 220);
+                  font-size: 10em;
+                  padding: 0.1em;
+                "
+                class="fa fa-file-text"
+              ></i>
+              <p>
+                No hay entregas del alumno:
+                {{
+                  alumnoSeleccionado.nombre + " " + alumnoSeleccionado.apellido
+                }}
+              </p>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div
+        class="card"
+        *ngIf="
+          alumnoSeleccionado == undefined && archivoSeleccionado == undefined
+        "
+      >
+        <div class="card-block">
+          <div
+            class="row previewArchivoNoSeleccionadoGrupos"
+            style="min-height: 100px"
+          >
+            <div style="width: 100%; text-align: center">
+              <i
+                style="
+                  color: rgb(220, 220, 220);
+                  font-size: 10em;
+                  padding: 0.1em;
+                "
+                class="fa fa-file-text"
+              ></i>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="card" *ngIf="archivoSeleccionado">
+        <div class="card-header">
+          <button
+            *ngIf="tipoArchivo == 'entrega'"
+            class="btn btn-sm btn-secondary pull-left mr-2"
+            (click)="calificarEntrega()"
+          >
+            Calificar
+          </button>
+          <button
+            *ngIf="esArchivoGrupo()"
+            ngbPopover="Cargar/Editar"
+            data-placement="bottom"
+            triggers="mouseenter:mouseleave"
+            class="btn btn-sm btn-secondary pull-left mr-2"
+            (click)="cargarArchivoCompartido()"
+          >
+            <i class="fa fa-pencil"></i>
+          </button>
+          <div class="pull-left">
+            Nombre: {{ archivoSeleccionado?.nombre }} - Creado:
+            {{ archivoSeleccionado?.fechaCreacion | date }}
+          </div>
         </div>
+        <codemirror
+          class="codemirrorGrupos"
+          [(ngModel)]="archivoSeleccionado.contenido"
+          [config]="configCodeMirror"
+          [ngStyle]="{ 'font-size': configCodeMirror.fontSize + 'px' }"
+        >
+        </codemirror>
+      </div>
     </div>
+  </div>
 </div>
diff --git a/Frontend Angular 4/src/app/layout/grupos/grupos.component.ts b/Frontend Angular 4/src/app/layout/grupos/grupos.component.ts
index 50adcf9e..cec5374c 100755
--- a/Frontend Angular 4/src/app/layout/grupos/grupos.component.ts	
+++ b/Frontend Angular 4/src/app/layout/grupos/grupos.component.ts	
@@ -1,181 +1,194 @@
-import { Component } from '@angular/core';
-import { Router } from '@angular/router';
-
-import { Archivo } from '../../shared/objects/archivo';
-import { Grupo } from '../../shared/objects/grupo';
-import { Usuario } from '../../shared/objects/usuario';
-import { AuthenticationService } from '../../shared/services/authentication.service';
-import { HaskellService } from '../../shared/services/haskell.service';
-import { SessionService } from '../../shared/services/session.service';
+import { Component } from "@angular/core";
+import { Router } from "@angular/router";
+
+import { Archivo } from "../../shared/objects/archivo";
+import { Grupo } from "../../shared/objects/grupo";
+import { Usuario } from "../../shared/objects/usuario";
+import { AuthenticationService } from "../../shared/services/authentication.service";
+import { HaskellService } from "../../shared/services/haskell.service";
+import { SessionService } from "../../shared/services/session.service";
 import { DialogService } from "ng2-bootstrap-modal";
-import { CalificarEntrega } from './calificarEntrega.component';
-import { NgbPopoverConfig, NgbPopover} from '@ng-bootstrap/ng-bootstrap';
-import { NotificacionService } from '../../shared/services/notificacion.service';
-import { TranslateService } from '@ngx-translate/core';
+import { CalificarEntrega } from "./calificarEntrega.component";
+import { NgbPopoverConfig, NgbPopover } from "@ng-bootstrap/ng-bootstrap";
+import { NotificacionService } from "../../shared/services/notificacion.service";
+import { TranslateService } from "@ngx-translate/core";
 
 @Component({
-	moduleId: module.id,
-	selector: 'grupos',
-	templateUrl: './grupos.component.html'
+  moduleId: module.id,
+  selector: "grupos",
+  templateUrl: "./grupos.component.html",
 })
-
 export class GruposComponent {
-	archivos : Archivo[] = [];
-	grupos : Grupo [] = [];
-	grupoSeleccionado: Grupo = undefined;
-	
-	alumnoSeleccionado: Usuario = undefined;
-
-	archivoSeleccionado: Archivo = undefined;
-
-	tipoArchivo: string = undefined;
-
-	loading: boolean = false;
-	idRecorridos :any = [];
-	tree: any;
-	directorioActual:any;
-	configCodeMirror = JSON.parse(sessionStorage.getItem('codeMirrorConfig'));
-	translateService: any;
-
-	constructor(
-		private router: Router,
-		private authService: AuthenticationService,
-		private haskellService: HaskellService,
-		private notifService: NotificacionService,
-		private sessionService: SessionService,
-		private dialogService:DialogService,
-		public translate: TranslateService
-		){
-		this.translateService = translate;
-		this.directorioActual = {};
-		this.directorioActual.archivos = [];
-		this.configCodeMirror.readOnly = true;
-	}
-
-	ngOnInit(){
-		let cedula = this.authService.getUser().cedula;
-		this.loading = true;
-		this.haskellService.getGrupos(cedula)
-		.subscribe(
-			grupos => {
-				this.grupos = grupos;
-				this.ordenarGrupos();
-				this.loading = false;
-			}, 
-			error => console.log(error) 
-			);
-	}
-
-	//ordenar archivos del grupo seleccionado.
-	ordenarAlph(a, b){
-   		if(a.nombre.toLowerCase() < b.nombre.toLowerCase()) return -1;
-     	if(a.nombre.toLowerCase() > b.nombre.toLowerCase()) return 1;
-     	return 0;
-	}
-
-	ordenarArchivos(){
-		this.grupoSeleccionado.archivos = this.grupoSeleccionado.archivos.sort(this.ordenarAlph);
-	}
-
-	//ordeno los archivos del alumno (los archivos entregados.)
-	ordenarArchivosAlumno(){
-		if(this.archivoSeleccionado && this.archivoSeleccionado.archivos){
-			this.archivoSeleccionado.archivos = this.archivoSeleccionado.archivos.sort(this.ordenarAlph);
-		}
-	}
-
-	//ordenar grupos
-	ordenarGrupoF(a,b){
-		if(a.grado>b.grado) return 1;
-		if(a.grado<b.grado) return -1;
-		if(a.grupo.toLowerCase()>b.grupo.toLowerCase()) return 1;
-		if(a.grupo.toLowerCase()<b.grupo.toLowerCase()) return -1;
-		return 0;
-	}
-
-	ordenarGrupos(){
-		this.grupos = this.grupos.sort(this.ordenarGrupoF);
-	}
-
-	//ordenar alumnos
-	ordenarAlumnosF(a,b){
-		if(a.apellido.toLowerCase()>b.apellido.toLowerCase()) return  1;
-		if(a.apellido.toLowerCase()<b.apellido.toLowerCase()) return -1;
-		return 0;
-	}
-
-	ordenarAlumnos(){
-		this.grupoSeleccionado.alumnos = this.grupoSeleccionado.alumnos.sort(this.ordenarAlumnosF);
-	}
-
-	seleccionarGrupo(grupo){
-		this.grupoSeleccionado = grupo;
-		this.ordenarAlumnos();
-		this.ordenarArchivos();
-		this.archivoSeleccionado = undefined;
-		this.alumnoSeleccionado = undefined;
-	}
-
-	desseleccionarGrupo(){
-		this.grupoSeleccionado = undefined;
-		this.archivoSeleccionado = undefined;
-		this.alumnoSeleccionado = undefined;
-	}
-
-	seleccionarAlumno(alumno){
-	  if (!(typeof alumno === 'undefined')){
-		this.alumnoSeleccionado = alumno;
-		this.ordenarArchivosAlumno();
-		this.archivoSeleccionado = undefined;
-	}
-	}
-
-	seleccionarArchivo(archivo){
-		this.archivoSeleccionado = archivo;
-		this.alumnoSeleccionado = undefined;
-		this.tipoArchivo = "compartido";
-	}
-
-	seleccionarEntrega(entrega){
-		this.archivoSeleccionado = entrega;
-		this.alumnoSeleccionado = undefined;
-		this.tipoArchivo = "entrega";
-	}
-
-	calificarEntrega(){
-		let disposable = this.dialogService.addDialog(CalificarEntrega,
-			{
-				cedula: JSON.parse(sessionStorage.currentUser).cedula+'',  
-				archivo: this.archivoSeleccionado,
-  				parentContext: this
-  			})
-		.subscribe((isConfirmed)=>{
-			if(isConfirmed) { 
-				//codeMirrorRef.options.readOnly = false;
-				//componentRef.editDialogFired = true;
-			}
-		});
-	}
-
-	esArchivoGrupo(){
-		if(this.archivoSeleccionado && this.grupoSeleccionado && this.grupoSeleccionado.archivos.some(arch => arch.id == this.archivoSeleccionado.id)){
-			return true;
-		}else{
-			return false;
-		}
-	}
-
-	cargarArchivoCompartido(){
-		if(this.archivoSeleccionado){
-			if(this.archivoSeleccionado.directorio){
-				this.notifService.warning(this.translateService.get('i18n.warning.file.noSelected').value,false);
-			}else{
-				this.sessionService.setArchivo(this.archivoSeleccionado);
-				this.router.navigate(['/matefun']);
-			}
-		}else{
-			this.notifService.warning(this.translateService.get('i18n.warning.file.noSelected').value);
-		}
-	}
-
-}
\ No newline at end of file
+  archivos: Archivo[] = [];
+  grupos: Grupo[] = [];
+  grupoSeleccionado: Grupo = undefined;
+
+  alumnoSeleccionado: Usuario = undefined;
+
+  archivoSeleccionado: Archivo = undefined;
+
+  tipoArchivo: string = undefined;
+
+  loading: boolean = false;
+  idRecorridos: any = [];
+  tree: any;
+  directorioActual: any;
+  configCodeMirror = JSON.parse(sessionStorage.getItem("codeMirrorConfig"));
+  translateService: any;
+
+  constructor(
+    private router: Router,
+    private authService: AuthenticationService,
+    private haskellService: HaskellService,
+    private notifService: NotificacionService,
+    private sessionService: SessionService,
+    private dialogService: DialogService,
+    public translate: TranslateService
+  ) {
+    this.translateService = translate;
+    this.directorioActual = {};
+    this.directorioActual.archivos = [];
+    this.configCodeMirror.readOnly = true;
+  }
+
+  ngOnInit() {
+    let cedula = this.authService.getUser().cedula;
+    this.loading = true;
+    this.haskellService.getGrupos(cedula).subscribe(
+      (grupos) => {
+        this.grupos = grupos;
+        this.ordenarGrupos();
+        this.loading = false;
+      },
+      (error) => console.log(error)
+    );
+  }
+
+  //ordenar archivos del grupo seleccionado.
+  ordenarAlph(a, b) {
+    if (a.nombre.toLowerCase() < b.nombre.toLowerCase()) return -1;
+    if (a.nombre.toLowerCase() > b.nombre.toLowerCase()) return 1;
+    return 0;
+  }
+
+  ordenarArchivos() {
+    this.grupoSeleccionado.archivos = this.grupoSeleccionado.archivos.sort(
+      this.ordenarAlph
+    );
+  }
+
+  //ordeno los archivos del alumno (los archivos entregados.)
+  ordenarArchivosAlumno() {
+    if (this.archivoSeleccionado && this.archivoSeleccionado.archivos) {
+      this.archivoSeleccionado.archivos =
+        this.archivoSeleccionado.archivos.sort(this.ordenarAlph);
+    }
+  }
+
+  //ordenar grupos
+  ordenarGrupoF(a, b) {
+    if (a.grado > b.grado) return 1;
+    if (a.grado < b.grado) return -1;
+    if (a.grupo.toLowerCase() > b.grupo.toLowerCase()) return 1;
+    if (a.grupo.toLowerCase() < b.grupo.toLowerCase()) return -1;
+    return 0;
+  }
+
+  ordenarGrupos() {
+    this.grupos = this.grupos.sort(this.ordenarGrupoF);
+  }
+
+  //ordenar alumnos
+  ordenarAlumnosF(a, b) {
+    if (a.apellido.toLowerCase() > b.apellido.toLowerCase()) return 1;
+    if (a.apellido.toLowerCase() < b.apellido.toLowerCase()) return -1;
+    return 0;
+  }
+
+  ordenarAlumnos() {
+    this.grupoSeleccionado.alumnos = this.grupoSeleccionado.alumnos.sort(
+      this.ordenarAlumnosF
+    );
+  }
+
+  seleccionarGrupo(grupo) {
+    this.grupoSeleccionado = grupo;
+    this.ordenarAlumnos();
+    this.ordenarArchivos();
+    this.archivoSeleccionado = undefined;
+    this.alumnoSeleccionado = undefined;
+  }
+
+  desseleccionarGrupo() {
+    this.grupoSeleccionado = undefined;
+    this.archivoSeleccionado = undefined;
+    this.alumnoSeleccionado = undefined;
+  }
+
+  seleccionarAlumno(alumno) {
+    if (!(typeof alumno === "undefined")) {
+      this.alumnoSeleccionado = alumno;
+      this.ordenarArchivosAlumno();
+      this.archivoSeleccionado = undefined;
+    }
+  }
+
+  seleccionarArchivo(archivo) {
+    this.archivoSeleccionado = archivo;
+    this.alumnoSeleccionado = undefined;
+    this.tipoArchivo = "compartido";
+  }
+
+  seleccionarEntrega(entrega) {
+    this.archivoSeleccionado = entrega;
+    this.alumnoSeleccionado = undefined;
+    this.tipoArchivo = "entrega";
+  }
+
+  calificarEntrega() {
+    let disposable = this.dialogService
+      .addDialog(CalificarEntrega, {
+        cedula: JSON.parse(sessionStorage.currentUser).cedula + "",
+        archivo: this.archivoSeleccionado,
+        parentContext: this,
+      })
+      .subscribe((isConfirmed) => {
+        if (isConfirmed) {
+          //codeMirrorRef.options.readOnly = false;
+          //componentRef.editDialogFired = true;
+        }
+      });
+  }
+
+  esArchivoGrupo() {
+    if (
+      this.archivoSeleccionado &&
+      this.grupoSeleccionado &&
+      this.grupoSeleccionado.archivos.some(
+        (arch) => arch.id == this.archivoSeleccionado.id
+      )
+    ) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  cargarArchivoCompartido() {
+    if (this.archivoSeleccionado) {
+      if (this.archivoSeleccionado.directorio) {
+        this.notifService.warning(
+          this.translateService.get("i18n.warning.file.noSelected").value,
+          false
+        );
+      } else {
+        this.sessionService.setArchivo(this.archivoSeleccionado);
+        this.router.navigate(["/matefun"]);
+      }
+    } else {
+      this.notifService.warning(
+        this.translateService.get("i18n.warning.file.noSelected").value
+      );
+    }
+  }
+}
diff --git a/Frontend Angular 4/src/app/layout/grupos/grupos.module.ts b/Frontend Angular 4/src/app/layout/grupos/grupos.module.ts
index abcb8ebb..a06751a5 100755
--- a/Frontend Angular 4/src/app/layout/grupos/grupos.module.ts	
+++ b/Frontend Angular 4/src/app/layout/grupos/grupos.module.ts	
@@ -1,33 +1,32 @@
-import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
-import { GruposComponent } from './grupos.component';
-import { CommonModule } from '@angular/common';
-import { GruposRoutingModule } from './grupos-routing.module';
+import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { GruposComponent } from "./grupos.component";
+import { CommonModule } from "@angular/common";
+import { GruposRoutingModule } from "./grupos-routing.module";
 import { DialogService } from "ng2-bootstrap-modal";
-import { NotificacionService } from '../../shared/services/notificacion.service';
-import { BootstrapModalModule } from 'ng2-bootstrap-modal';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { CodemirrorModule } from 'ng2-codemirror';
-import { CalificarEntrega } from './calificarEntrega.component';
-import { NotificacionModule } from '../../notificacion/notificacion.module';
-import { I18nModule } from '../../shared/modules/translate/i18n.module';
-import { TitleCaseModule } from '../../shared/modules/titlecase.module';
+import { NotificacionService } from "../../shared/services/notificacion.service";
+import { BootstrapModalModule } from "ng2-bootstrap-modal";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { CodemirrorModule } from "ng2-codemirror";
+import { CalificarEntrega } from "./calificarEntrega.component";
+import { NotificacionModule } from "../../notificacion/notificacion.module";
+import { I18nModule } from "../../shared/modules/translate/i18n.module";
+import { TitleCaseModule } from "../../shared/modules/titlecase.module";
 
 @NgModule({
-    imports: [
-        CommonModule, 
-        GruposRoutingModule,
-        FormsModule,
-        BootstrapModalModule,
-        NgbModule,
-        CodemirrorModule,
-        NotificacionModule,
-        I18nModule,
-        TitleCaseModule
-    ],
-    declarations: [GruposComponent, CalificarEntrega],
-    exports: [GruposComponent],
-    entryComponents: [CalificarEntrega]
+  imports: [
+    CommonModule,
+    GruposRoutingModule,
+    FormsModule,
+    BootstrapModalModule,
+    NgbModule,
+    CodemirrorModule,
+    NotificacionModule,
+    I18nModule,
+    TitleCaseModule,
+  ],
+  declarations: [GruposComponent, CalificarEntrega],
+  exports: [GruposComponent],
+  entryComponents: [CalificarEntrega],
 })
-
-export class GruposModule { }
+export class GruposModule {}
diff --git a/Frontend Angular 4/src/app/layout/layout-routing.module.ts b/Frontend Angular 4/src/app/layout/layout-routing.module.ts
index 0a40b067..0541eeca 100755
--- a/Frontend Angular 4/src/app/layout/layout-routing.module.ts	
+++ b/Frontend Angular 4/src/app/layout/layout-routing.module.ts	
@@ -1,20 +1,27 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-import { LayoutComponent } from './layout.component';
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
+import { LayoutComponent } from "./layout.component";
 
 const routes: Routes = [
-    {
-        path: '', component: LayoutComponent,
-        children: [
-            { path: 'matefun', loadChildren: './matefun/matefun.module#MateFunModule' },
-            { path: 'archivos', loadChildren: './archivos/archivos.module#ArchivosModule' },
-            { path: 'grupos', loadChildren: './grupos/grupos.module#GruposModule' }            
-        ]
-    }
+  {
+    path: "",
+    component: LayoutComponent,
+    children: [
+      {
+        path: "matefun",
+        loadChildren: "./matefun/matefun.module#MateFunModule",
+      },
+      {
+        path: "archivos",
+        loadChildren: "./archivos/archivos.module#ArchivosModule",
+      },
+      { path: "grupos", loadChildren: "./grupos/grupos.module#GruposModule" },
+    ],
+  },
 ];
 
 @NgModule({
-    imports: [RouterModule.forChild(routes)],
-    exports: [RouterModule]
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
 })
-export class LayoutRoutingModule { }
+export class LayoutRoutingModule {}
diff --git a/Frontend Angular 4/src/app/layout/layout.component.spec.ts b/Frontend Angular 4/src/app/layout/layout.component.spec.ts
index c4d6365d..33ad4cb7 100755
--- a/Frontend Angular 4/src/app/layout/layout.component.spec.ts	
+++ b/Frontend Angular 4/src/app/layout/layout.component.spec.ts	
@@ -1,16 +1,15 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
 
-import { LayoutComponent } from './layout.component';
+import { LayoutComponent } from "./layout.component";
 
-describe('LayoutComponent', () => {
+describe("LayoutComponent", () => {
   let component: LayoutComponent;
   let fixture: ComponentFixture<LayoutComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ LayoutComponent ]
-    })
-    .compileComponents();
+      declarations: [LayoutComponent],
+    }).compileComponents();
   }));
 
   beforeEach(() => {
@@ -19,7 +18,7 @@ describe('LayoutComponent', () => {
     fixture.detectChanges();
   });
 
-  it('should create', () => {
+  it("should create", () => {
     expect(component).toBeTruthy();
   });
 });
diff --git a/Frontend Angular 4/src/app/layout/layout.component.ts b/Frontend Angular 4/src/app/layout/layout.component.ts
index 48be054b..2cd5a978 100755
--- a/Frontend Angular 4/src/app/layout/layout.component.ts	
+++ b/Frontend Angular 4/src/app/layout/layout.component.ts	
@@ -1,24 +1,26 @@
-import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router';
-import { GHCIService } from '../shared/services/ghci.service';
-import { NotificacionService } from '../shared/services/notificacion.service';
-import { TranslateService } from '@ngx-translate/core';
+import { Component, OnInit } from "@angular/core";
+import { Router } from "@angular/router";
+import { GHCIService } from "../shared/services/ghci.service";
+import { NotificacionService } from "../shared/services/notificacion.service";
+import { TranslateService } from "@ngx-translate/core";
 
 @Component({
-    selector: 'app-layout',
-    templateUrl: './layout.component.html',
-    styleUrls: ['./layout.component.scss'],
-    providers: [GHCIService]
+  selector: "app-layout",
+  templateUrl: "./layout.component.html",
+  styleUrls: ["./layout.component.scss"],
+  providers: [GHCIService],
 })
 export class LayoutComponent implements OnInit {
-    translateService: any;
+  translateService: any;
 
-    constructor(public router: Router, public translate: TranslateService) {
-        this.translateService = translate;
-    }
-    ngOnInit() {
-        if (this.router.url === '/') {
-            this.router.navigate(['/'+this.translateService.get('i18n.code').value+'/login']);
-        }
+  constructor(public router: Router, public translate: TranslateService) {
+    this.translateService = translate;
+  }
+  ngOnInit() {
+    if (this.router.url === "/") {
+      this.router.navigate([
+        "/" + this.translateService.get("i18n.code").value + "/login",
+      ]);
     }
+  }
 }
diff --git a/Frontend Angular 4/src/app/layout/layout.module.ts b/Frontend Angular 4/src/app/layout/layout.module.ts
index e3c702ba..bcbb2774 100755
--- a/Frontend Angular 4/src/app/layout/layout.module.ts	
+++ b/Frontend Angular 4/src/app/layout/layout.module.ts	
@@ -1,34 +1,30 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { FormsModule } from '@angular/forms';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { FormsModule } from "@angular/forms";
 
-import { LayoutRoutingModule } from './layout-routing.module';
-import { LayoutComponent } from './layout.component';
-import { HeaderComponent, SidebarComponent } from '../shared';
-import { AuthenticationService } from '../shared/services/authentication.service';
-import { HaskellService } from '../shared/services/haskell.service';
-import { CodemirrorModule } from 'ng2-codemirror';
-import { NotificacionModule } from '../notificacion/notificacion.module';
-import { I18nModule } from '../shared/modules/translate/i18n.module';
-import { TitleCaseModule } from '../shared/modules/titlecase.module';
+import { LayoutRoutingModule } from "./layout-routing.module";
+import { LayoutComponent } from "./layout.component";
+import { HeaderComponent, SidebarComponent } from "../shared";
+import { AuthenticationService } from "../shared/services/authentication.service";
+import { HaskellService } from "../shared/services/haskell.service";
+import { CodemirrorModule } from "ng2-codemirror";
+import { NotificacionModule } from "../notificacion/notificacion.module";
+import { I18nModule } from "../shared/modules/translate/i18n.module";
+import { TitleCaseModule } from "../shared/modules/titlecase.module";
 
 @NgModule({
-    imports: [
-        CommonModule,
-        FormsModule,
-        NgbModule.forRoot(),
-        LayoutRoutingModule,
-        CodemirrorModule,
-        NotificacionModule,
-        I18nModule,
-        TitleCaseModule
-    ],
-    declarations: [
-        LayoutComponent,
-        HeaderComponent,
-        SidebarComponent
-    ],
-    providers: [AuthenticationService, HaskellService]
+  imports: [
+    CommonModule,
+    FormsModule,
+    NgbModule.forRoot(),
+    LayoutRoutingModule,
+    CodemirrorModule,
+    NotificacionModule,
+    I18nModule,
+    TitleCaseModule,
+  ],
+  declarations: [LayoutComponent, HeaderComponent, SidebarComponent],
+  providers: [AuthenticationService, HaskellService],
 })
-export class LayoutModule { }
+export class LayoutModule {}
diff --git a/Frontend Angular 4/src/app/layout/matefun/confirm.component.ts b/Frontend Angular 4/src/app/layout/matefun/confirm.component.ts
index 28a84174..2f893f43 100755
--- a/Frontend Angular 4/src/app/layout/matefun/confirm.component.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/confirm.component.ts	
@@ -1,41 +1,44 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
 export interface ConfirmModel {
-  title:string;
-  message:string;
+  title: string;
+  message: string;
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-                   <div class="modal-header">
-                     <button type="button" class="close" (click)="close()" >&times;</button>
-                     <!-- <h4 class="modal-title">{{title || 'Confirm'}}</h4> -->
-                   </div>
-                   <div class="modal-body">
-                     <p>{{message || ''}}</p>
-                   </div>
-                   <div class="modal-footer">
-                     <button type="button" class="btn btn-primary" (click)="confirm()">
-                      {{ "i18n.action.edit" | translate }}
-                     </button>
-                     <button type="button" class="btn btn-default" (click)="close()" >
-                      {{ "i18n.action.cancel" | translate }}
-                     </button>
-                   </div>
-                 </div>
-              </div>`
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" (click)="close()">&times;</button>
+        <!-- <h4 class="modal-title">{{title || 'Confirm'}}</h4> -->
+      </div>
+      <div class="modal-body">
+        <p>{{ message || "" }}</p>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-primary" (click)="confirm()">
+          {{ "i18n.action.edit" | translate }}
+        </button>
+        <button type="button" class="btn btn-default" (click)="close()">
+          {{ "i18n.action.cancel" | translate }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class ConfirmComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class ConfirmComponent
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   title: string;
   message: string;
   constructor(dialogService: DialogService) {
     super(dialogService);
   }
   confirm() {
-    // we set dialog result as true on click on confirm button, 
-    // then we can get dialog result from caller code 
+    // we set dialog result as true on click on confirm button,
+    // then we can get dialog result from caller code
     this.result = true;
     this.close();
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/layout/matefun/index.ts b/Frontend Angular 4/src/app/layout/matefun/index.ts
index 4676de0b..f4618928 100755
--- a/Frontend Angular 4/src/app/layout/matefun/index.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/index.ts	
@@ -1,5 +1,5 @@
 /**
  * This barrel file provides the export for the lazy loaded BlankpageComponent.
  */
-export * from './matefun.component';
-export * from './matefun.routes';
+export * from "./matefun.component";
+export * from "./matefun.routes";
diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun-routing.module.ts b/Frontend Angular 4/src/app/layout/matefun/matefun-routing.module.ts
index 4ff3fac0..40e20235 100755
--- a/Frontend Angular 4/src/app/layout/matefun/matefun-routing.module.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/matefun-routing.module.ts	
@@ -1,14 +1,12 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
 
-import { MateFunComponent } from './matefun.component';
+import { MateFunComponent } from "./matefun.component";
 
-const routes: Routes = [
-    { path: '', component: MateFunComponent }
-];
+const routes: Routes = [{ path: "", component: MateFunComponent }];
 
 @NgModule({
-    imports: [RouterModule.forChild(routes)],
-    exports: [RouterModule]
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
 })
-export class MateFunRoutingModule { }
\ No newline at end of file
+export class MateFunRoutingModule {}
diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.component.html b/Frontend Angular 4/src/app/layout/matefun/matefun.component.html
index 8715bb57..07e9ba70 100755
--- a/Frontend Angular 4/src/app/layout/matefun/matefun.component.html	
+++ b/Frontend Angular 4/src/app/layout/matefun/matefun.component.html	
@@ -1,188 +1,365 @@
-<notificacion></notificacion> 
-<div class="container-fluid" style=" padding-left: 0px; padding-right: 0px; margin-top: -13px; margin-left: -6px; margin-right: -6px;">
-    <div class="row">
-        <div class="col-md-6">
-            <ngb-tabset [destroyOnHide]=false (tabChange)="onChangeTab($event)">
-                <ngb-tab id="ProgramBtn" title='{{ "i18n.object.program" | translate | titlecase }}'>
-                    <ng-template ngbTabContent>
-
+<notificacion></notificacion>
+<div
+  class="container-fluid"
+  style="
+    padding-left: 0px;
+    padding-right: 0px;
+    margin-top: -13px;
+    margin-left: -6px;
+    margin-right: -6px;
+  "
+>
+  <div class="row">
+    <div class="col-md-6">
+      <ngb-tabset [destroyOnHide]="false" (tabChange)="onChangeTab($event)">
+        <ngb-tab
+          id="ProgramBtn"
+          title="{{ 'i18n.object.program' | translate | titlecase }}"
+        >
+          <ng-template ngbTabContent>
             <div class="card">
-                <div class="card-header">
-                    <form>
-                        <input type="text" name="archivo" class="nomArchivoInp form-control form-control-sm" 
-                        [disabled]="!archivo.editable || archivo.estado=='Corregido' || archivo.estado == 'Entregado'"
-                        *ngIf="archivo" [(ngModel)]="archivo.nombre" (keyup)="archivoModificado()" placeholder='{{ "i18n.msg.file.fileName" | translate }}' />
+              <div class="card-header">
+                <form>
+                  <input
+                    type="text"
+                    name="archivo"
+                    class="nomArchivoInp form-control form-control-sm"
+                    [disabled]="
+                      !archivo.editable ||
+                      archivo.estado == 'Corregido' ||
+                      archivo.estado == 'Entregado'
+                    "
+                    *ngIf="archivo"
+                    [(ngModel)]="archivo.nombre"
+                    (keyup)="archivoModificado()"
+                    placeholder="{{ 'i18n.msg.file.fileName' | translate }}"
+                  />
 
-                        <button 
-                            style="margin-left: 5px; float: right;"
-                            id="shortcutsPopover"
+                  <button
+                    style="margin-left: 5px; float: right"
+                    id="shortcutsPopover"
+                    class="btn btn-sm btn-secondary"
+                    placement="bottom"
+                    [ngbPopover]="shortcutsPopoverContent"
+                    #popover="ngbPopover"
+                    popoverTitle="{{
+                      'i18n.object.shortcuts' | translate | titleCase
+                    }}"
+                    tiggers="click"
+                  >
+                    <i class="fa fa-keyboard-o"></i>
+                  </button>
+                  <button
+                    id="downloadFileButton"
+                    (click)="downloadFile()"
+                    style="margin-left: 5px; float: right"
+                    class="btn btn-sm btn-secondary"
+                    placement="bottom"
+                    ngbPopover="{{
+                      'i18n.action.export' | translate | titleCase
+                    }} (Ctrl+E)"
+                    triggers="mouseenter:mouseleave"
+                    tiggers="click"
+                  >
+                    <i class="fa fa-download"></i>
+                  </button>
+                  <button
+                    id="uploadFileButton"
+                    (click)="seleccionarDirectorio(true)"
+                    style="margin-left: 5px; float: right"
+                    class="btn btn-sm btn-secondary"
+                    placement="bottom"
+                    ngbPopover="{{
+                      'i18n.action.import' | translate | titleCase
+                    }} (Ctrl+I)"
+                    triggers="mouseenter:mouseleave"
+                    tiggers="click"
+                  >
+                    <i class="fa fa-upload"></i>
+                  </button>
+                  <button
+                    style="margin-left: 5px; float: right"
+                    id="popover"
+                    class="btn btn-sm btn-secondary"
+                    placement="bottom"
+                    [ngbPopover]="popoverContent"
+                    #popover="ngbPopover"
+                    popoverTitle="{{
+                      'i18n.object.settings' | translate | titleCase
+                    }}"
+                    tiggers="click"
+                  >
+                    <i class="fa fa-gear"></i>
+                  </button>
+                  <div
+                    style="margin-left: 5px; float: right"
+                    ngbPopover="{{
+                      'i18n.action.save' | translate | titleCase
+                    }} {{
+                      'i18n.object.file' | translate | titleCase
+                    }} (Ctrl+G)"
+                    triggers="mouseenter:mouseleave"
+                    placement="bottom"
+                  >
+                    <button
+                      [disabled]="!modificado"
+                      (click)="guardarArchivo()"
+                      class="btn btn-sm btn-secondary"
+                    >
+                      <i class="fa fa-save"></i>
+                    </button>
+                  </div>
+                  <button
+                    style="margin-left: 5px; float: right"
+                    (click)="mostrandoDefinicion = false; reiniciarInterprete()"
+                    class="btn btn-sm btn-secondary"
+                    ngbPopover="{{
+                      'i18n.action.restart' | translate | titleCase
+                    }} {{
+                      'i18n.object.interpreter' | translate | titleCase
+                    }} (Ctrl+R)"
+                    triggers="mouseenter:mouseleave"
+                    placement="bottom"
+                  >
+                    <i class="fa fa-refresh"></i>
+                  </button>
+                  <button
+                    style="margin-left: 5px; float: right"
+                    (click)="mostrandoDefinicion = false; runCode()"
+                    class="btn btn-sm btn-secondary"
+                    ngbPopover="{{
+                      'i18n.action.load' | translate | titleCase
+                    }} {{
+                      'i18n.object.program' | translate | titleCase
+                    }} (Ctrl+P)"
+                    triggers="mouseenter:mouseleave"
+                    placement="bottom"
+                  >
+                    <i class="fa fa-play"></i>
+                  </button>
+                  <button
+                    style="float: right"
+                    (click)="seleccionarDirectorio(false)"
+                    class="btn btn-sm btn-secondary"
+                    ngbPopover="{{
+                      'i18n.action.new' | translate | titleCase
+                    }} {{
+                      'i18n.object.file' | translate | titleCase
+                    }} (Ctrl+A)"
+                    triggers="mouseenter:mouseleave"
+                    placement="bottom"
+                  >
+                    <i class="fa fa-plus"></i>
+                  </button>
+                  <ng-template #popoverContent style="width: 15em">
+                    <div style="width: 12em">
+                      <div class="form-group">
+                        <label
+                          >{{
+                            "i18n.object.theme" | translate | titleCase
+                          }}:</label
+                        >
+                        <select
+                          name="theme"
+                          class="form-control form-control-sm"
+                          #selectTheme
+                          (change)="updateConfig(selectTheme.value)"
+                        >
+                          <option
+                            *ngFor="let theme of themes"
+                            [selected]="theme == configCodeMirror.theme"
+                            value="{{ theme }}"
+                          >
+                            {{ theme }}
+                          </option>
+                        </select>
+                      </div>
+                      <div class="form-group">
+                        <label
+                          >{{
+                            "i18n.msg.codemirror.fontSize" | translate
+                          }}:</label
+                        >
+                        <div>
+                          <button
                             class="btn btn-sm btn-secondary"
-                            placement="bottom"
-                            [ngbPopover]=shortcutsPopoverContent
-                            #popover="ngbPopover"
-                            popoverTitle='{{ "i18n.object.shortcuts" | translate | titleCase }}'
-                            tiggers="click">
-                            <i class="fa fa-keyboard-o"></i>
-                        </button>
-                        <button
-                            id="downloadFileButton"
-                            (click)="downloadFile()"
-                            style="margin-left: 5px; float: right;"
+                            (click)="aumentarFuente()"
+                          >
+                            A⁺
+                          </button>
+                          <button
                             class="btn btn-sm btn-secondary"
-                            placement="bottom"
-                            ngbPopover='{{ "i18n.action.export" | translate | titleCase }} (Ctrl+E)'
-                            triggers="mouseenter:mouseleave"
-                            tiggers="click">
-                            <i class="fa fa-download "></i>
-                        </button>
-                        <button
-                            id="uploadFileButton"
-                            (click)="seleccionarDirectorio(true)"
-                            style="margin-left: 5px; float: right;"
-                            class="btn btn-sm btn-secondary"
-                            placement="bottom"
-                            ngbPopover='{{ "i18n.action.import" | translate | titleCase }} (Ctrl+I)'
-                            triggers="mouseenter:mouseleave"
-                            tiggers="click">
-                            <i class="fa fa-upload "></i>
-                        </button>
-                        <button
-                            style="margin-left: 5px; float: right;"
-                            id="popover" class="btn btn-sm btn-secondary"
-                            placement="bottom"
-                            [ngbPopover]=popoverContent
-                            #popover="ngbPopover"
-                            popoverTitle='{{ "i18n.object.settings" | translate | titleCase }}'
-                            tiggers="click">
-                            <i class="fa fa-gear"></i>
-                        </button>
-                        <div
-                            style="margin-left: 5px; float: right;"
-                            ngbPopover='{{ "i18n.action.save" | translate | titleCase }} {{ "i18n.object.file" | translate | titleCase }} (Ctrl+G)'
-                            triggers="mouseenter:mouseleave"
-                            placement="bottom" >
-                            <button [disabled]="!modificado" (click)="guardarArchivo()" class="btn btn-sm btn-secondary" >
-                                <i class="fa fa-save"></i>
-                            </button>
+                            (click)="disminuirFuente()"
+                          >
+                            A⁻
+                          </button>
+                          {{ configCodeMirror.fontSize }}px
                         </div>
+                      </div>
+                      <div class="form-group">
+                        <label>
+                          <input
+                            type="checkbox"
+                            style="width: 15px; display: inline-block"
+                            name="argumentoF"
+                            class="form-control form-control-sm"
+                            [(ngModel)]="argumentoF"
+                          />
+                          {{
+                            "i18n.msg.codemirror.functionWarnings" | translate
+                          }}
+                        </label>
+                        <br />
+                        <label>
+                          <input
+                            type="checkbox"
+                            style="width: 15px; display: inline-block"
+                            name="argumentoI"
+                            class="form-control form-control-sm"
+                            [(ngModel)]="argumentoI"
+                          />
+                          {{
+                            "i18n.msg.codemirror.infixOperatorsWarnings"
+                              | translate
+                          }}
+                        </label>
+                        <br />
+                        <label>
+                          <input
+                            type="checkbox"
+                            style="width: 15px; display: inline-block"
+                            name="hintsCheck"
+                            class="form-control form-control-sm"
+                            [(ngModel)]="hintsCheck"
+                          />
+                          {{ "i18n.msg.codemirror.showHints" | translate }}
+                        </label>
+                        <br />
+                        <label>
+                          <input
+                            type="checkbox"
+                            style="width: 15px; display: inline-block"
+                            name="typingCheck"
+                            class="form-control form-control-sm"
+                            [(ngModel)]="typingCheck"
+                          />
+                          {{ "i18n.msg.codemirror.functionTyping" | translate }}
+                        </label>
+                      </div>
+                      <div class="form-group">
                         <button
-                            style="margin-left: 5px; float: right;"
-                            (click)="mostrandoDefinicion = false; reiniciarInterprete()"
-                            class="btn btn-sm btn-secondary"
-                            ngbPopover='{{ "i18n.action.restart" | translate | titleCase }} {{ "i18n.object.interpreter" | translate | titleCase }} (Ctrl+R)'
-                            triggers="mouseenter:mouseleave"
-                            placement="bottom">
-                            <i class="fa fa-refresh"></i>
-                        </button>
-                        <button
-                            style="margin-left: 5px; float: right;"
-                            (click)="mostrandoDefinicion = false; runCode()"
-                            class="btn btn-sm btn-secondary"
-                            ngbPopover='{{ "i18n.action.load" | translate | titleCase }} {{ "i18n.object.program" | translate | titleCase }} (Ctrl+P)'
-                            triggers="mouseenter:mouseleave"
-                            placement="bottom">
-                            <i class="fa fa-play"></i>
-                        </button>
-                        <button
-                            style="float: right;"
-                            (click)="seleccionarDirectorio(false)"
-                            class="btn btn-sm btn-secondary"
-                            ngbPopover='{{ "i18n.action.new" | translate | titleCase }} {{ "i18n.object.file" | translate | titleCase }} (Ctrl+A)'
-                            triggers="mouseenter:mouseleave"
-                            placement="bottom">
-                            <i class="fa fa-plus"></i>
+                          class="btn btn-secondary"
+                          (click)="saveConfig(); popover.close()"
+                        >
+                          {{ "i18n.action.save" | translate | titleCase }}
                         </button>
-                        <ng-template #popoverContent style="width: 15em">
-                            <div style="width: 12em">
-                                <div class="form-group">
-                                    <label>{{ "i18n.object.theme" | translate | titleCase }}:</label>
-                                    <select name="theme" class="form-control form-control-sm" #selectTheme (change)=updateConfig(selectTheme.value)>
-                                        <option *ngFor="let theme of themes" [selected]="theme==configCodeMirror.theme" value='{{theme}}'>{{theme}}</option>
-                                    </select>
-                                </div>
-                                <div class="form-group">
-                                    <label>{{ "i18n.msg.codemirror.fontSize" | translate }}:</label>
-                                    <div>
-                                        <button class="btn btn-sm btn-secondary" (click)="aumentarFuente()">A⁺</button>
-                                        <button class="btn btn-sm btn-secondary" (click)="disminuirFuente()">A⁻</button>
-                                        {{configCodeMirror.fontSize}}px                                    
-                                    </div>
-                                </div>
-                                <div class="form-group">
-                                    <label>
-                                        <input type="checkbox" style="width: 15px; display: inline-block;" name="argumentoF" class="form-control form-control-sm" [(ngModel)]=argumentoF>
-                                        {{ "i18n.msg.codemirror.functionWarnings" | translate }}
-                                    </label>
-                                    <br>
-                                    <label>
-                                        <input type="checkbox" style="width: 15px; display: inline-block;" name="argumentoI" class="form-control form-control-sm" [(ngModel)]=argumentoI>
-                                        {{ "i18n.msg.codemirror.infixOperatorsWarnings" | translate }}
-                                        
-                                    </label>
-                                    <br>
-                                    <label>
-                                        <input type="checkbox" style="width: 15px; display: inline-block;" name="hintsCheck" class="form-control form-control-sm" [(ngModel)]=hintsCheck>
-                                        {{ "i18n.msg.codemirror.showHints" | translate }}
-                                    </label>
-                                    <br>
-                                    <label>
-                                        <input type="checkbox" style="width: 15px; display: inline-block;" name="typingCheck" class="form-control form-control-sm" [(ngModel)]=typingCheck>
-                                        {{ "i18n.msg.codemirror.functionTyping" | translate }}
-                                    </label>
-                                </div>
-                                <div class="form-group">
-                                    <button class="btn btn-secondary" (click)="saveConfig(); popover.close();">{{ "i18n.action.save" | translate | titleCase }}</button>
-                                </div>
-                            </div>
-                        </ng-template>
-                        <ng-template #shortcutsPopoverContent style="width: 18em">
-                            <div style="width: 18em">
-                                <div class="form-group">
-                                    <label><b>Ctrl+P</b> {{ "i18n.shortcuts.runCode" | translate }}</label>
-                                    <label><b>Ctrl+A</b> {{ "i18n.shortcuts.newFile" | translate }}</label>
-                                    <label><b>Ctrl+O</b> {{ "i18n.shortcuts.openMenu" | translate }}</label>
-                                    <label><b>Ctrl+E</b> {{ "i18n.shortcuts.exportFile" | translate }}</label>
-                                    <label><b>Ctrl+I</b> {{ "i18n.shortcuts.importFile" | translate }}</label>
-                                    <label><b>Ctrl+R</b> {{ "i18n.shortcuts.restartInterpreter" | translate }}</label>
-                                    <label><b>Ctrl+G</b> {{ "i18n.shortcuts.saveFile" | translate }}</label>
-                                    <label><b>Ctrl+{{ "i18n.shortcuts.space" | translate }}</b> {{ "i18n.shortcuts.autocomplete" | translate }}</label>
-                                    <label><b>Ctrl+Shift+K</b> {{ "i18n.shortcuts.comment" | translate }}</label>
-                                    <label><b>Ctrl+Alt+p</b> {{ "i18n.shortcuts.focusProgram" | translate }}</label>
-                                    <label><b>Ctrl+Alt+c</b> {{ "i18n.shortcuts.focusInterpreter" | translate }}</label>				    
-                                    <label><b>Alt+.</b> {{ "i18n.shortcuts.functionNavigation" | translate }}</label>
-                                </div>
-                            </div>
-                        </ng-template>
-                    </form>
-                </div>
-                <codemirror class="codemirrorPrograma" [(ngModel)]="archivo.contenido" (keyup)="archivoModificado($event)" (click)="clickEnEditor($event)" [config]="configCodeMirror" [ngStyle]="{'font-size': configCodeMirror.fontSize+'px'}">
-                </codemirror>
+                      </div>
+                    </div>
+                  </ng-template>
+                  <ng-template #shortcutsPopoverContent style="width: 18em">
+                    <div style="width: 18em">
+                      <div class="form-group">
+                        <label
+                          ><b>Ctrl+P</b>
+                          {{ "i18n.shortcuts.runCode" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+A</b>
+                          {{ "i18n.shortcuts.newFile" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+O</b>
+                          {{ "i18n.shortcuts.openMenu" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+E</b>
+                          {{ "i18n.shortcuts.exportFile" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+I</b>
+                          {{ "i18n.shortcuts.importFile" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+R</b>
+                          {{
+                            "i18n.shortcuts.restartInterpreter" | translate
+                          }}</label
+                        >
+                        <label
+                          ><b>Ctrl+G</b>
+                          {{ "i18n.shortcuts.saveFile" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+{{ "i18n.shortcuts.space" | translate }}</b>
+                          {{ "i18n.shortcuts.autocomplete" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+Shift+K</b>
+                          {{ "i18n.shortcuts.comment" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+Alt+p</b>
+                          {{ "i18n.shortcuts.focusProgram" | translate }}</label
+                        >
+                        <label
+                          ><b>Ctrl+Alt+c</b>
+                          {{
+                            "i18n.shortcuts.focusInterpreter" | translate
+                          }}</label
+                        >
+                        <label
+                          ><b>Alt+.</b>
+                          {{
+                            "i18n.shortcuts.functionNavigation" | translate
+                          }}</label
+                        >
+                      </div>
+                    </div>
+                  </ng-template>
+                </form>
+              </div>
+              <codemirror
+                class="codemirrorPrograma"
+                [(ngModel)]="archivo.contenido"
+                (keyup)="archivoModificado($event)"
+                (click)="clickEnEditor($event)"
+                [config]="configCodeMirror"
+                [ngStyle]="{ 'font-size': configCodeMirror.fontSize + 'px' }"
+              >
+              </codemirror>
             </div>
-
-            </ng-template>
-                </ngb-tab>
-                <!-- <ngb-tab id="FigurasBtn" title="Figuras OLD">
+          </ng-template>
+        </ngb-tab>
+        <!-- <ngb-tab id="FigurasBtn" title="Figuras OLD">
                     <ng-template ngbTabContent>
                         <canvas-component (canvasComp)=canvasC></canvas-component>
                     </ng-template>
                 </ngb-tab> -->
-                <ngb-tab id="FigurasBtn2D" title='{{ "i18n.object.figures" | translate | titleCase }} 2D'>
-                    <ng-template ngbTabContent>
-                        <graph2D-component (graph2DComp)=graph2DComp></graph2D-component>
-                    </ng-template>
-                </ngb-tab>
-                <ngb-tab id="FigurasBtn3D" title='{{ "i18n.object.figures" | translate | titleCase }} 3D'>
-                    <ng-template ngbTabContent>
-                        <graph3d-component (graph3DComp)=graph3DComp></graph3d-component>
-                    </ng-template>
-                </ngb-tab>
-
-            </ngb-tabset> 
-
-        </div>
+        <ngb-tab
+          id="FigurasBtn2D"
+          title="{{ 'i18n.object.figures' | translate | titleCase }} 2D"
+        >
+          <ng-template ngbTabContent>
+            <graph2D-component
+              (graph2DComp)="(graph2DComp)"
+            ></graph2D-component>
+          </ng-template>
+        </ngb-tab>
+        <ngb-tab
+          id="FigurasBtn3D"
+          title="{{ 'i18n.object.figures' | translate | titleCase }} 3D"
+        >
+          <ng-template ngbTabContent>
+            <graph3d-component
+              (graph3DComp)="(graph3DComp)"
+            ></graph3d-component>
+          </ng-template>
+        </ngb-tab>
+      </ngb-tabset>
+    </div>
 
-        <div class="col-md-6" [hidden]="mostrandoDefinicion">
-            <!--  
+    <div class="col-md-6" [hidden]="mostrandoDefinicion">
+      <!--  
             <ngb-tabset [destroyOnHide]=false>
                 <ngb-tab title="Programa">
                     <ng-template ngbTabContent>
@@ -200,47 +377,49 @@
                 </ngb-tab>
             </ngb-tabset> 
             -->
-            
-
 
-            <div class="card">
-                <div id="console"> </div>
-            </div>
-           <!--
+      <div class="card">
+        <div id="console"></div>
+      </div>
+      <!--
             <canvas-component (canvasComp)=canvasC></canvas-component>
             
              <div class="card">
                 <div id="svgHaskell">
                 </div>
             </div> -->
+    </div>
 
-        </div>
-
-        <div class="col-md-6" [hidden]="!mostrandoDefinicion" style="top: 42px">
-            <div class="card">
-                <div class="card-header" style="height: 52.22px">
-                    <form>
-                        <div class="pull-left" *ngIf="archivoDefinicion">
-                            {{ "i18n.object.name" | translate | titleCase }}:
-                            {{archivoDefinicion?.nombre}}
-                            &nbsp;-&nbsp;
-                            {{ "i18n.action.created" | translate | titleCase }}:
-                            {{archivoDefinicion?.fechaCreacion | date}}
-                        </div>
-                        <button style="float: right;" (click)="mostrandoDefinicion = !mostrandoDefinicion">
-                            <i class="fa fa-times"></i>
-                        </button>
-                    </form>
-                </div>
-                <codemirror
-                    class="codemirrorPrograma"
-                    [(ngModel)]="archivoDefinicion.contenido"
-                    [config]="configCodeMirrorDefinicion"
-                    [ngStyle]="{'font-size': configCodeMirrorDefinicion.fontSize+'px'}">
-                </codemirror>
+    <div class="col-md-6" [hidden]="!mostrandoDefinicion" style="top: 42px">
+      <div class="card">
+        <div class="card-header" style="height: 52.22px">
+          <form>
+            <div class="pull-left" *ngIf="archivoDefinicion">
+              {{ "i18n.object.name" | translate | titleCase }}:
+              {{ archivoDefinicion?.nombre }}
+              &nbsp;-&nbsp;
+              {{ "i18n.action.created" | translate | titleCase }}:
+              {{ archivoDefinicion?.fechaCreacion | date }}
             </div>
+            <button
+              style="float: right"
+              (click)="mostrandoDefinicion = !mostrandoDefinicion"
+            >
+              <i class="fa fa-times"></i>
+            </button>
+          </form>
         </div>
+        <codemirror
+          class="codemirrorPrograma"
+          [(ngModel)]="archivoDefinicion.contenido"
+          [config]="configCodeMirrorDefinicion"
+          [ngStyle]="{
+            'font-size': configCodeMirrorDefinicion.fontSize + 'px'
+          }"
+        >
+        </codemirror>
+      </div>
     </div>
-    <span class="version">v{{version}}</span>
+  </div>
+  <span class="version">v{{ version }}</span>
 </div>
-
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 bd70c7ff..a7ae73ef 100755
--- a/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts	
@@ -1,713 +1,846 @@
-import { Component, NgModule, ViewChild, HostListener, ElementRef, ComponentRef, TemplateRef, QueryList, ViewChildren } from '@angular/core';
-import { CanvasModule} from '../canvas/canvas.module';
-import { CanvasComponent } from '../canvas/canvas.component';
-import { Http, JsonpModule } from '@angular/http';
-import { Headers, RequestOptions } from '@angular/http';
-import { HaskellService } from '../../shared/services/haskell.service';
-import { WebsocketService } from '../../shared/services/websocket.service';
-import { UsuarioService } from '../../shared/services/usuario.service';
-import { SessionService } from '../../shared/services/session.service';
-import { GHCIService } from '../../shared/services/ghci.service';
-import { AuthenticationService } from '../../shared/services/authentication.service';
-import { GHCI_URL } from '../../shared/config';
-import { Archivo } from '../../shared/objects/archivo';
-import { Configuracion } from '../../shared/objects/usuario';
-import { ConfirmComponent } from './confirm.component';
-import { SeleccionarDirectorioComp } from './seleccionarDirectorio.component';
+import {
+  Component,
+  NgModule,
+  ViewChild,
+  HostListener,
+  ElementRef,
+  ComponentRef,
+  TemplateRef,
+  QueryList,
+  ViewChildren,
+} from "@angular/core";
+import { CanvasModule } from "../canvas/canvas.module";
+import { CanvasComponent } from "../canvas/canvas.component";
+import { HaskellService } from "../../shared/services/haskell.service";
+import { WebsocketService } from "../../shared/services/websocket.service";
+import { UsuarioService } from "../../shared/services/usuario.service";
+import { SessionService } from "../../shared/services/session.service";
+import { GHCIService } from "../../shared/services/ghci.service";
+import { AuthenticationService } from "../../shared/services/authentication.service";
+import { GHCI_URL } from "../../shared/config";
+import { Archivo } from "../../shared/objects/archivo";
+import { Configuracion } from "../../shared/objects/usuario";
+import { ConfirmComponent } from "./confirm.component";
+import { SeleccionarDirectorioComp } from "./seleccionarDirectorio.component";
 import { DialogService } from "ng2-bootstrap-modal";
-import { CodemirrorComponent } from 'ng2-codemirror';
-import { NgbPopoverConfig, NgbPopover} from '@ng-bootstrap/ng-bootstrap';
-import { NgbPopoverWindow } from '@ng-bootstrap/ng-bootstrap/popover/popover';
-import { NotificacionService } from '../../shared/services/notificacion.service';
-import { Graph2DModule } from '../plotter/graph2D/graph2D.module';
-import { Graph2DComponent } from '../plotter/graph2D/graph2D.component';
-import { Graph3DComponent } from '../plotter/graph3D/graph3D.component';
-import { TranslateService } from '@ngx-translate/core';
-import { TitleCasePipe } from '../../shared/pipes/titlecase.pipe';
-import { Router, NavigationExtras } from '@angular/router';
-
-import 'rxjs/add/operator/catch';
-import 'rxjs/add/operator/map';
+import { CodemirrorComponent } from "ng2-codemirror";
+import { NgbPopoverConfig, NgbPopover } from "@ng-bootstrap/ng-bootstrap";
+import { NgbPopoverWindow } from "@ng-bootstrap/ng-bootstrap/popover/popover";
+import { NotificacionService } from "../../shared/services/notificacion.service";
+import { Graph2DModule } from "../plotter/graph2D/graph2D.module";
+import { Graph2DComponent } from "../plotter/graph2D/graph2D.component";
+import { Graph3DComponent } from "../plotter/graph3D/graph3D.component";
+import { TranslateService } from "@ngx-translate/core";
+import { TitleCasePipe } from "../../shared/pipes/titlecase.pipe";
+import { Router, NavigationExtras } from "@angular/router";
+
+import "rxjs/add/operator/catch";
+import "rxjs/add/operator/map";
 // import 'codemirror/mode/haskell/haskell';
-import 'codemirror/addon/display/panel';
-import 'codemirror/addon/hint/show-hint';
-import 'codemirror/addon/hint/anyword-hint';
-import 'codemirror/mode/markdown/markdown';
-import 'codemirror/lib/codemirror';
-import 'codemirror/addon/search/search';
-
-
-import 'codemirror/addon/dialog/dialog';
-import 'codemirror/addon/search/search';
-import 'codemirror/addon/search/matchesonscrollbar';
-import 'codemirror/addon/search/jump-to-line';
-import 'codemirror/addon/edit/matchbrackets';
-import 'codemirror/addon/selection/active-line';
-import 'codemirror/addon/comment/comment.js';
-
-import './codemirror/matefun-mode-ES.js';
-import './codemirror/matefun-mode-EN.js';
-import './codemirror/addons/functions_definition_EN.js';
-import './codemirror/addons/functions_definition_ES.js';
-
-import * as npm from './../../../../package.json'
-
-var codeMirrorRef:any;
-var componentRef : any;
+import "codemirror/addon/display/panel";
+import "codemirror/addon/hint/show-hint";
+import "codemirror/addon/hint/anyword-hint";
+import "codemirror/mode/markdown/markdown";
+import "codemirror/lib/codemirror";
+import "codemirror/addon/search/search";
+
+import "codemirror/addon/dialog/dialog";
+import "codemirror/addon/search/search";
+import "codemirror/addon/search/matchesonscrollbar";
+import "codemirror/addon/search/jump-to-line";
+import "codemirror/addon/edit/matchbrackets";
+import "codemirror/addon/selection/active-line";
+import "codemirror/addon/comment/comment.js";
+
+import "./codemirror/matefun-mode-ES.js";
+import "./codemirror/matefun-mode-EN.js";
+import "./codemirror/addons/functions_definition_EN.js";
+import "./codemirror/addons/functions_definition_ES.js";
+
+import * as npm from "./../../../../package.json";
+
+var codeMirrorRef: any;
+var componentRef: any;
 var focus: any;
 
 @Component({
-    moduleId: module.id,
-    selector: 'matefun',     
-    templateUrl: './matefun.component.html',   
-    styleUrls: ['./matefun.component.scss'],  
-    providers: [ WebsocketService, NgbPopoverConfig, UsuarioService ]
+  moduleId: module.id,
+  selector: "matefun",
+  templateUrl: "./matefun.component.html",
+  styleUrls: ["./matefun.component.scss"],
+  providers: [WebsocketService, NgbPopoverConfig, UsuarioService],
 })
-
-
 export class MateFunComponent {
-    titlecasePipe: any;
-    translateService: any;
-    consoleDisable: boolean = false;
-    consolaVisible: boolean = true;
-    cursorPanel: any;
-    cursorPanelLabel: any;
-    cursorLabelInit : boolean = false;
-    entrada : string = '';
-    archivo : Archivo;
-    copiaNombreArchivo:string;
-    copiaContenidoArchivo:string;
-    modificado = false;
-    argumentoI = false;
-    argumentoF = false;
-    hintsCheck = true;
-    typingCheck = true;
-    editableLoaded = false;
-    editDialogFired = false;
-    archivosTree :any;
-    idRecorridos: any;
-    code: string ='';
-    mostrandoDefinicion = false;
-    archivoDefinicion: any = {};
-    jump = false;
-    jump_word = "";
-    configCodeMirror = {
-        readOnly: false,
-        lineNumbers: true,
-        lineWrapping : true,
-        matchBrackets: true,
-        styleActiveLine: true,
-        extraKeys: {"Ctrl-Space": "autocomplete"},
-        mode: {
-            name: "matefun-EN", 
-            globalVars: true
-        },
-        gutters: ["CodeMirror-linenumbers", "breakpoints"],
-        theme: 'dracula',
-        fontSize: 12,
-        hintOptions: {
-            completeSingle: false,
-            closeCharacters: /[^\d\w\_]/
-        },
-        files: null
-    };
-    configCodeMirrorDefinicion: any = {};
-    themes = ['3024-day', '3024-night', 'abcdef', 'ambiance-mobile', 'ambiance', 'base16-dark', 'base16-light', 'bespin', 'blackboard', 'cobalt', 'colorforth', 'dracula', 'duotone-dark', 'duotone-light', 'eclipse', 'elegant', 'erlang-dark', 'hopscotch', 'icecoder', 'isotope', 'lesser-dark', 'liquibyte', 'material', 'mbo', 'mdn-like', 'midnight', 'monokai', 'neat', 'neo', 'night', 'panda-syntax', 'paraiso-dark', 'paraiso-light', 'pastel-on-dark', 'railscasts', 'rubyblue', 'seti', 'solarized', 'the-matrix', 'tomorrow-night-bright', 'tomorrow-night-eighties', 'ttcn', 'twilight', 'vibrant-ink', 'xq-dark', 'xq-light', 'yeti', 'zenburn']
-    version: string = "3.1.3";//npm.version;
-
-    constructor(
-        private haskellService: HaskellService,
-        private authService: AuthenticationService, 
-        private ghciService: GHCIService, 
-        private elRef: ElementRef, 
-        private notifService: NotificacionService,
-        private sessionService: SessionService,
-        private dialogService:DialogService,
-        private usuarioService: UsuarioService,
-        public translate: TranslateService,
-        private router: Router) {
-
-        // i18n
-        this.translateService = translate;
-        this.titlecasePipe = new TitleCasePipe();
-
-        //si el archivo fue seteado en la session. 
-        this.archivo = sessionService.getArchivo();
-        if(!this.archivo || !this.archivo.id){
-            this.newFile();
+  titlecasePipe: any;
+  translateService: any;
+  consoleDisable: boolean = false;
+  consolaVisible: boolean = true;
+  cursorPanel: any;
+  cursorPanelLabel: any;
+  cursorLabelInit: boolean = false;
+  entrada: string = "";
+  archivo: Archivo;
+  copiaNombreArchivo: string;
+  copiaContenidoArchivo: string;
+  modificado = false;
+  argumentoI = false;
+  argumentoF = false;
+  hintsCheck = true;
+  typingCheck = true;
+  editableLoaded = false;
+  editDialogFired = false;
+  archivosTree: any;
+  idRecorridos: any;
+  code: string = "";
+  mostrandoDefinicion = false;
+  archivoDefinicion: any = {};
+  jump = false;
+  jump_word = "";
+  configCodeMirror = {
+    readOnly: false,
+    lineNumbers: true,
+    lineWrapping: true,
+    matchBrackets: true,
+    styleActiveLine: true,
+    extraKeys: { "Ctrl-Space": "autocomplete" },
+    mode: {
+      name: "matefun-EN",
+      globalVars: true,
+    },
+    gutters: ["CodeMirror-linenumbers", "breakpoints"],
+    theme: "dracula",
+    fontSize: 12,
+    hintOptions: {
+      completeSingle: false,
+      closeCharacters: /[^\d\w\_]/,
+    },
+    files: null,
+  };
+  configCodeMirrorDefinicion: any = {};
+  themes = [
+    "3024-day",
+    "3024-night",
+    "abcdef",
+    "ambiance-mobile",
+    "ambiance",
+    "base16-dark",
+    "base16-light",
+    "bespin",
+    "blackboard",
+    "cobalt",
+    "colorforth",
+    "dracula",
+    "duotone-dark",
+    "duotone-light",
+    "eclipse",
+    "elegant",
+    "erlang-dark",
+    "hopscotch",
+    "icecoder",
+    "isotope",
+    "lesser-dark",
+    "liquibyte",
+    "material",
+    "mbo",
+    "mdn-like",
+    "midnight",
+    "monokai",
+    "neat",
+    "neo",
+    "night",
+    "panda-syntax",
+    "paraiso-dark",
+    "paraiso-light",
+    "pastel-on-dark",
+    "railscasts",
+    "rubyblue",
+    "seti",
+    "solarized",
+    "the-matrix",
+    "tomorrow-night-bright",
+    "tomorrow-night-eighties",
+    "ttcn",
+    "twilight",
+    "vibrant-ink",
+    "xq-dark",
+    "xq-light",
+    "yeti",
+    "zenburn",
+  ];
+  version: string = "3.1.3"; //npm.version;
+
+  constructor(
+    private haskellService: HaskellService,
+    private authService: AuthenticationService,
+    private ghciService: GHCIService,
+    private elRef: ElementRef,
+    private notifService: NotificacionService,
+    private sessionService: SessionService,
+    private dialogService: DialogService,
+    private usuarioService: UsuarioService,
+    public translate: TranslateService,
+    private router: Router
+  ) {
+    // i18n
+    this.translateService = translate;
+    this.titlecasePipe = new TitleCasePipe();
+
+    //si el archivo fue seteado en la session.
+    this.archivo = sessionService.getArchivo();
+    if (!this.archivo || !this.archivo.id) {
+      this.newFile();
+    }
+    this.copiaContenidoArchivo = this.archivo.contenido;
+    this.copiaNombreArchivo = this.archivo.nombre;
+    if (authService.getUser().configuracion) {
+      var config: Configuracion = authService.getUser().configuracion;
+      if (config.fontSizeEditor <= 30 && config.fontSizeEditor >= 8) {
+        this.configCodeMirror.fontSize = config.fontSizeEditor;
+      }
+      if (this.themes.some((theme) => theme == config.themeEditor)) {
+        this.configCodeMirror.theme = config.themeEditor;
+      }
+      sessionStorage.setItem(
+        "codeMirrorConfig",
+        JSON.stringify(this.configCodeMirror)
+      );
+      this.argumentoI = config.argumentoI;
+      this.argumentoF = config.argumentoF;
+    }
+    this.code = "my code";
+    let svg: string = "";
+
+    for (var key in this.configCodeMirror) {
+      this.configCodeMirrorDefinicion[key] = this.configCodeMirror[key];
+    }
+    this.configCodeMirrorDefinicion["readOnly"] = true;
+  }
+
+  @ViewChildren(CodemirrorComponent) codemirror: QueryList<CodemirrorComponent>;
+  // @ViewChild(NgbPopover) popover: NgbPopover;
+  @ViewChild("popover") popover: NgbPopover;
+
+  updateConfig(theme) {
+    this.configCodeMirror.theme = theme;
+    this.codemirror.first.instance.setOption("theme", theme);
+    sessionStorage.setItem(
+      "codeMirrorConfig",
+      JSON.stringify(this.configCodeMirror)
+    );
+  }
+
+  lockSaveButton() {
+    this.copiaNombreArchivo = this.archivo.nombre;
+    this.copiaContenidoArchivo = this.archivo.contenido;
+    this.modificado = false;
+  }
+
+  showConfirm() {
+    let disposable = this.dialogService
+      .addDialog(ConfirmComponent, {
+        title: "Está intentando editar un archivo de solo lectura",
+        message: "Está editando un archivo de solo lectura, desea continuar?",
+      })
+      .subscribe((isConfirmed) => {
+        if (isConfirmed) {
+          codeMirrorRef.options.readOnly = false;
+          componentRef.editDialogFired = true;
         }
-        this.copiaContenidoArchivo = this.archivo.contenido;
-        this.copiaNombreArchivo = this.archivo.nombre;
-        if(authService.getUser().configuracion){
-            var config: Configuracion = authService.getUser().configuracion;
-            if(config.fontSizeEditor<=30 && config.fontSizeEditor>=8){
-                this.configCodeMirror.fontSize = config.fontSizeEditor;
-            }
-            if(this.themes.some(theme => theme==config.themeEditor)){
-                this.configCodeMirror.theme = config.themeEditor;                
-            }
-            sessionStorage.setItem('codeMirrorConfig',JSON.stringify(this.configCodeMirror));
-            this.argumentoI = config.argumentoI;
-            this.argumentoF = config.argumentoF;
-
+      });
+  }
+
+  /* Panel para la posición del cursor */
+  makePanel() {
+    var node = document.createElement("div");
+    node.id = "cursorpos-panel";
+    node.className = "panel bottom";
+    this.cursorPanelLabel = node.appendChild(document.createElement("span"));
+    var cm = this.codemirror.first.instance;
+    var x = cm.getCursor().line;
+    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 + ")";
+    });
+
+    this.codemirror.first.instance.on("keyHandled", function (cm, name, evt) {
+      if (name.code === "Digit1" && name.ctrlKey && name.shiftKey) {
+        that.seleccionarDirectorio(false);
+      } else if (name.code === "Digit2" && name.ctrlKey && name.shiftKey) {
+        that.saveConfig();
+      }
+    });
+
+    this.codemirror.first.instance.on("keypress", function (cm, name, evt) {
+      if (
+        !that.editDialogFired &&
+        JSON.parse(sessionStorage.currentUser).tipo === "docente" &&
+        cm.options.readOnly
+      ) {
+        codeMirrorRef = that.codemirror.first.instance;
+        componentRef = that;
+        that.showConfirm();
+      }
+    });
+  }
+
+  saveConfig() {
+    var config = new Configuracion();
+    config.themeEditor = this.configCodeMirror.theme;
+    config.fontSizeEditor = this.configCodeMirror.fontSize;
+    var confUser = this.authService.getUserConfig();
+    var reiniciar =
+      confUser.argumentoF != this.argumentoF ||
+      confUser.argumentoI != this.argumentoI;
+    config.argumentoF = this.argumentoF;
+    config.argumentoI = this.argumentoI;
+    this.usuarioService
+      .actualizarConfiguracion(this.authService.getUser().cedula, config)
+      .subscribe(
+        (success) => {
+          //this.ghciService.consoleRef.Write("Configuración guardada"  + "\n");
+          this.popover.close();
+          this.authService.setUserConfig(success);
+          if (reiniciar) {
+            this.reiniciarInterprete();
+          }
+        },
+        (error) => {
+          this.notifService.error(error);
+          this.popover.close();
         }
-        this.code = "my code";
-        let svg : string = '';
-
-        for (var key in this.configCodeMirror){
-            this.configCodeMirrorDefinicion[key] = this.configCodeMirror[key];
+      );
+    if (!this.hintsCheck) {
+      delete this.configCodeMirror.extraKeys["Ctrl-Space"];
+    } else {
+      this.configCodeMirror.extraKeys["Ctrl-Space"] = "autocomplete";
+    }
+  }
+
+  aumentarFuente() {
+    if (this.configCodeMirror.fontSize < 30) {
+      this.configCodeMirror.fontSize++;
+    }
+  }
+
+  disminuirFuente() {
+    if (this.configCodeMirror.fontSize > 8) {
+      this.configCodeMirror.fontSize--;
+    }
+  }
+
+  @HostListener("document:click", ["$event"])
+  private documentClicked(event: MouseEvent): void {
+    // Popover is open
+    if (this.popover && this.popover.isOpen()) {
+      // Not clicked on self element
+      if (
+        !(this.popover as any)._elementRef.nativeElement.contains(event.target)
+      ) {
+        // Hacking typescript to access private member
+        const popoverWindowRef: ComponentRef<NgbPopoverWindow> = (
+          this.popover as any
+        )._windowRef;
+
+        // If clicked outside popover window
+        if (!popoverWindowRef.location.nativeElement.contains(event.target)) {
+          this.popover.close();
         }
-        this.configCodeMirrorDefinicion['readOnly'] = true;
+      }
     }
+  }
 
+  ngOnInit() {
+    window["matefunComponent"] = { component: this };
 
-    @ViewChildren(CodemirrorComponent) codemirror: QueryList<CodemirrorComponent>;
-    // @ViewChild(NgbPopover) popover: NgbPopover;
-    @ViewChild('popover') popover: NgbPopover;
+    this.ghciService.rendered();
 
-    updateConfig(theme){
-        this.configCodeMirror.theme = theme;
-        this.codemirror.first.instance.setOption('theme', theme); 
-        sessionStorage.setItem('codeMirrorConfig',JSON.stringify(this.configCodeMirror));
-    }
-
-    lockSaveButton (){
-        this.copiaNombreArchivo = this.archivo.nombre;
-        this.copiaContenidoArchivo = this.archivo.contenido;
+    this.haskellService
+      .getArchivos(this.authService.getUser().cedula)
+      .subscribe(
+        (archivos) => {
+          //.filter(function(a){return !a.eliminado})
+          this.buildTreeFromList(archivos);
+        },
+        (error) => console.log("Error al obtener los archivos del alumno")
+      );
+
+    function KeyPress(e) {
+      var evtobj = window.event ? event : e;
+      if (evtobj.keyCode == 90 && evtobj.ctrlKey) {
+        //alert("Ctrl+z")
+      }
+      if (evtobj != null && evtobj.key != null) {
+        if (evtobj.key.toLowerCase() === "a" && evtobj.ctrlKey) {
+          componentRef.seleccionarDirectorio();
+          return false;
+        } else if (evtobj.key.toLowerCase() === "e" && evtobj.ctrlKey) {
+          componentRef.downloadFile();
+          return false;
+        } else if (evtobj.key.toLowerCase() === "r" && evtobj.ctrlKey) {
+          componentRef.reiniciarInterprete();
+          return false;
+        } else if (evtobj.key.toLowerCase() === "g" && evtobj.ctrlKey) {
+          componentRef.guardarArchivo();
+          return false;
+        } else if (evtobj.key.toLowerCase() === "o" && evtobj.ctrlKey) {
+          document.getElementById("popover").click();
+          return false;
+        } else if (
+          evtobj.ctrlKey &&
+          evtobj.altKey &&
+          evtobj.key.toLowerCase() === "p"
+        ) {
+          document.getElementById("ProgramBtn").click();
+          var that = componentRef;
+          setTimeout(function () {
+            that.codemirror.first.instance.focus();
+          }, 250);
+          componentRef.codemirror.first.instance.focus();
+          focus = "program";
+          return false;
+        } else if (
+          evtobj.ctrlKey &&
+          evtobj.altKey &&
+          evtobj.key.toLowerCase() === "c"
+        ) {
+          componentRef.ghciService.focusConsole();
+          focus = "consola";
+          return false;
+        } else if (
+          evtobj.ctrlKey &&
+          evtobj.altKey &&
+          evtobj.key.toLowerCase() === "f"
+        ) {
+          document.getElementById("FigurasBtn").click();
+          componentRef.ghciService.focusConsole();
+          focus = "graficas";
+          return false;
+        } else if (
+          evtobj.key.toLowerCase() === "p" &&
+          evtobj.ctrlKey &&
+          !evtobj.altKey
+        ) {
+          componentRef.runCode();
+          return false;
+        }
+      }
+    }
+    document.onkeydown = KeyPress;
+
+    let currentSession = sessionStorage.getItem("currentUser");
+    let langCode = currentSession ? JSON.parse(currentSession).language : "es";
+    if (langCode == "es") {
+      this.configCodeMirror.mode.name = "matefun-ES";
+    } else if (langCode == "en") {
+      this.configCodeMirror.mode.name = "matefun-EN";
+    }
+  }
+
+  ngAfterViewInit() {
+    this.codemirror.last.instance.on("change", () => {
+      this.makeAJump();
+    });
+
+    componentRef = this;
+    if (this.codemirror.first.instance != null && !this.cursorLabelInit) {
+      this.cursorLabelInit = true;
+      this.codemirror.first.instance.setOption(
+        "theme",
+        this.configCodeMirror.theme
+      );
+      this.makePanel();
+    }
+    if (
+      !this.editableLoaded &&
+      this.codemirror.first.instance != null &&
+      this.sessionService.archivo.editable !== undefined
+    ) {
+      try {
+        var editable =
+          this.sessionService.archivo.editable &&
+          (this.sessionService.archivo.estado == "Edicion" ||
+            this.sessionService.archivo.estado == "Devuelto");
+        this.codemirror.first.instance.options.readOnly = !editable;
+        this.editableLoaded = true;
+      } catch (err) {
+        return;
+      }
+    }
+  }
+
+  makeAJump() {
+    if (this.jump) {
+      this.jump = false;
+      this.jumpExternalFile(this.jump_word);
+    }
+  }
+
+  htmlEncode(value: string) {
+    return value
+      .replace("Prelude> ", "")
+      .replace(/&/g, "&amp;")
+      .replace(/\s/g, "&nbsp;")
+      .replace(/"/g, "&quot;")
+      .replace(/'/g, "&#39;")
+      .replace(/</g, "&lt;")
+      .replace(/>/g, "&gt;");
+  }
+
+  // @ViewChild(CanvasComponent) canvasC: CanvasComponent;
+  @ViewChild(Graph3DComponent) graph3DComp: Graph3DComponent;
+
+  @ViewChild(Graph2DComponent) graph2DComp: Graph2DComponent;
+
+  funcionSTR: string = "Math.sin(x)*x*x-20";
+  consola: string = "";
+  command: string = "";
+  tipo: number = 1;
+
+  private onKey = function (value: string) {
+    this.funcionSTR = value;
+    this.archivo.contenido = value;
+  };
+
+  private writeCommand = function (value: string) {
+    this.command = value.split("\n")[value.split("\n").length - 1];
+  };
+
+  private selectFunction = function () {
+    this.tipo = 1;
+    this.funcionSTR = "Math.sin(x)*x*x-20";
+  };
+
+  private selectElipse = function () {
+    this.tipo = 2;
+    this.funcionSTR = "elipse(x,y,radioX, radioY, rotacion_en_grados)";
+  };
+
+  private selectCircle = function () {
+    this.tipo = 3;
+    this.funcionSTR = "circulo(x,y,radio)";
+  };
+
+  private elipse = function (
+    x: number,
+    y: number,
+    radiusX: number,
+    radiusY: number,
+    rotation: number
+  ) {
+    return [x, y, radiusX, radiusY, rotation];
+  };
+
+  private circulo = function (x: number, y: number, radius: number) {
+    return [x, y, radius];
+  };
+
+  inputConsola(text: any) {
+    this.entrada = text;
+  }
+
+  newFile() {
+    this.archivo = new Archivo();
+    this.archivo.cedulaCreador = this.authService.getUser().cedula;
+    this.archivo.contenido = "";
+    this.archivo.nombre = "";
+    this.copiaNombreArchivo = "";
+    this.copiaContenidoArchivo = "";
+  }
+
+  archivoModificado(event) {
+    if (this.hintsCheck && !event.ctrlKey && !event.altKey) {
+      if (/^[\w\_\d]$/.test(event.key) || event.key == "Enter") {
+        this.codemirror.first.instance.options.files = this.archivosTree;
+        this.codemirror.first.instance.showHint(event);
+      }
+      if (
+        this.copiaNombreArchivo != this.archivo.nombre ||
+        this.copiaContenidoArchivo != this.archivo.contenido
+      ) {
+        this.modificado = true;
+      } else {
         this.modificado = false;
+      }
+    } else if (event.ctrlKey && event.shiftKey && event.key == "K")
+      this.codemirror.first.instance.toggleComment();
+    else if (event.altKey && event.key == ".")
+      this.codemirror.first.instance.jumpToDefinition(
+        this.archivosTree,
+        this.codemirror.first.instance.doc,
+        event
+      );
+  }
+
+  goToFilesPreview(file_found, word) {
+    this.mostrandoDefinicion = true;
+    for (var key in this.configCodeMirror) {
+      this.configCodeMirrorDefinicion[key] = this.configCodeMirror[key];
+    }
+    this.configCodeMirrorDefinicion["readOnly"] = true;
+    this.archivoDefinicion = this.archivosTree.archivos.filter(
+      (a) => a.id == parseInt(file_found.id)
+    )[0];
+    this.jump = true;
+    this.jump_word = word;
+    this.jumpExternalFile(word);
+  }
+
+  jumpExternalFile(word) {
+    this.codemirror.last.instance.jumpToDefinitionByWord(
+      this.codemirror.last.instance.doc,
+      word
+    );
+  }
+
+  clickEnEditor(event) {
+    if (this.typingCheck) {
+      let currentSession = sessionStorage.getItem("currentUser");
+      let langCode = currentSession
+        ? JSON.parse(currentSession).language
+        : "es";
+      if (langCode == "en")
+        this.codemirror.first.instance.functionDefinitionEN(
+          this.archivo.nombre,
+          this.archivosTree.archivos,
+          this.codemirror.first.instance.doc,
+          event
+        );
+      else if (langCode == "es")
+        this.codemirror.first.instance.functionDefinitionES(
+          this.archivo.nombre,
+          this.archivosTree.archivos,
+          this.codemirror.first.instance.doc,
+          event
+        );
     }
-    
-
-    showConfirm() {
-        let disposable = this.dialogService.addDialog(ConfirmComponent, {
-            title:'Está intentando editar un archivo de solo lectura', 
-            message:'Está editando un archivo de solo lectura, desea continuar?'})
-        .subscribe((isConfirmed)=>{
-
-            if(isConfirmed) {
-                codeMirrorRef.options.readOnly = false;
-                componentRef.editDialogFired = true;
-            }
-        });        
-    }
-
-    /* Panel para la posición del cursor */
-    makePanel() {
-
-        var node = document.createElement("div");
-        node.id = "cursorpos-panel";
-        node.className = "panel bottom";
-        this.cursorPanelLabel = node.appendChild(document.createElement("span"));
-        var cm = this.codemirror.first.instance;
-        var x = cm.getCursor().line;
-        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 + ")";    
-        });
-
-        this.codemirror.first.instance.on("keyHandled",function(cm,name,evt){
-            if(name.code==="Digit1" && name.ctrlKey && name.shiftKey){
-                that.seleccionarDirectorio(false);
-            } else if(name.code==="Digit2" && name.ctrlKey && name.shiftKey){
-                that.saveConfig();
-            }
-        });
-
-        this.codemirror.first.instance.on("keypress",function(cm,name,evt){
-
-            if(!that.editDialogFired && JSON.parse(sessionStorage.currentUser).tipo === "docente" && cm.options.readOnly){
-                codeMirrorRef = that.codemirror.first.instance;
-                componentRef = that;
-                that.showConfirm(); 
-            }
-
-        });
-    } 
-
-    saveConfig(){
-        var config = new Configuracion();
-        config.themeEditor = this.configCodeMirror.theme;
-        config.fontSizeEditor = this.configCodeMirror.fontSize;
-        var confUser = this.authService.getUserConfig();
-        var reiniciar = confUser.argumentoF != this.argumentoF || confUser.argumentoI != this.argumentoI;
-        config.argumentoF = this.argumentoF;
-        config.argumentoI = this.argumentoI;
-        this.usuarioService.actualizarConfiguracion(this.authService.getUser().cedula,config)
-        .subscribe(
-            success=> {
-                //this.ghciService.consoleRef.Write("Configuración guardada"  + "\n");
-                this.popover.close();
-                this.authService.setUserConfig(success);
-                if(reiniciar){
-                    this.reiniciarInterprete();
-                }
-
+  }
+
+  guardarArchivo() {
+    var regex = /^[A-Z]/;
+    if (this.archivo.nombre.trim() == "") {
+      this.notifService.error("Nombre de archivo sin especificar");
+    } else if (!regex.test(this.archivo.nombre)) {
+      this.notifService.error("Nombre de archivo debe iniciar con mayusula.");
+    } else {
+      if (this.archivo.id) {
+        this.haskellService
+          .editarArchivo(this.archivo.id, this.archivo)
+          .subscribe(
+            (archivo) => {
+              //this.ghciService.consoleRef.Write("Editar archivo: " + this.archivo.nombre + "\n");
+              this.archivo = archivo;
+              this.lockSaveButton();
             },
-            error=> {
-                this.notifService.error(error);
-                this.popover.close();
+            (error) => {
+              this.notifService.error(error);
             }
+          );
+      } else {
+        this.haskellService.crearArchivo(this.archivo).subscribe(
+          (archivo) => {
+            //this.ghciService.consoleRef.Write("Archivo creado: " + this.archivo.nombre + "\n");
+            this.archivo = archivo;
+            this.lockSaveButton();
+          },
+          (error) => {
+            this.notifService.error(error);
+          }
         );
-        if (!this.hintsCheck){
-            delete this.configCodeMirror.extraKeys["Ctrl-Space"];
-        }else{
-            this.configCodeMirror.extraKeys["Ctrl-Space"] = "autocomplete";
-        }
-    }
-
-    aumentarFuente(){
-        if(this.configCodeMirror.fontSize<30){
-            this.configCodeMirror.fontSize++;
-        }
-    }
-
-    disminuirFuente(){
-        if(this.configCodeMirror.fontSize>8){
-            this.configCodeMirror.fontSize--;
-        }
-    }
-
-    @HostListener('document:click', ['$event'])
-    private documentClicked(event: MouseEvent): void {
-
-        // Popover is open
-        if (this.popover && this.popover.isOpen()) {
-
-            // Not clicked on self element
-            if (!(this.popover as any)._elementRef.nativeElement.contains(event.target)) {
-
-                // Hacking typescript to access private member
-                const popoverWindowRef: ComponentRef<NgbPopoverWindow> = (this.popover as any)._windowRef;
-
-                // If clicked outside popover window
-                if (!popoverWindowRef.location.nativeElement.contains(event.target)) {
-                    this.popover.close();
+      }
+    }
+  }
+  runCode() {
+    this.ghciService.setCodemirrorRef(this.codemirror.first.instance);
+    this.ghciService.resetGutters();
+    var regex = /^[A-Z]/;
+    if (this.archivo.nombre.trim() == "") {
+      this.notifService.error("Nombre de archivo sin especificar");
+    } else if (!regex.test(this.archivo.nombre)) {
+      this.notifService.error("Nombre de archivo debe iniciar con mayusula.");
+    } else {
+      var resultado = this.sessionService.cargarDependencias(this.archivo);
+      if (resultado["status"] === "miss") {
+        this.ghciService.outputConsole(
+          "Error: No se encuentra el archivo " + resultado["nombre"] + "\n"
+        );
+        return;
+      }
+      if (this.archivo.id) {
+        if (
+          this.archivo.editable ||
+          this.authService.getUser().tipo == "docente"
+        ) {
+          this.haskellService
+            .editarArchivo(this.archivo.id, this.archivo)
+            .subscribe(
+              (archivo) => {
+                this.archivo = archivo;
+                var list = this.sessionService.getDependencias(),
+                  idList = [];
+                for (var l in list) {
+                  idList.push(list[l].id);
                 }
-            }
-        }
-    }
-
-    ngOnInit() {
-        window['matefunComponent'] = { component: this };
-
-        this.ghciService.rendered(); 
-
-
-        this.haskellService.getArchivos(this.authService.getUser().cedula)
-        .subscribe(
-            archivos => {
-                //.filter(function(a){return !a.eliminado})
-                this.buildTreeFromList(archivos);
-
-            }, 
-            error => console.log("Error al obtener los archivos del alumno") 
-            );
-
-        function KeyPress(e) {
-
-            var evtobj = window.event? event : e
-            if (evtobj.keyCode == 90 && evtobj.ctrlKey){
-                //alert("Ctrl+z")
-            };
-	    if (evtobj != null && evtobj.key != null){
-            if( evtobj.key.toLowerCase() ==="a" && evtobj.ctrlKey){
-                componentRef.seleccionarDirectorio();
-                return false;
-            }else if(evtobj.key.toLowerCase() ==="e" && evtobj.ctrlKey){
-                componentRef.downloadFile();
-                return false;
-            } else if(evtobj.key.toLowerCase() ==="r" && evtobj.ctrlKey){
-                componentRef.reiniciarInterprete();
-                return false;
-            } else if(evtobj.key.toLowerCase() ==="g" && evtobj.ctrlKey){
-                componentRef.guardarArchivo();
-                return false;
-            } else if(evtobj.key.toLowerCase() ==="o" && evtobj.ctrlKey){
-                document.getElementById("popover").click();
-                return false;
-            } else if(evtobj.ctrlKey && evtobj.altKey && evtobj.key.toLowerCase() ==="p"){
-                document.getElementById("ProgramBtn").click();
-                var that  = componentRef;
-                setTimeout(function() {
-                    that.codemirror.first.instance.focus();
-                },250);
-                componentRef.codemirror.first.instance.focus();
-                focus ="program";
-                return false;
-            }  else if(evtobj.ctrlKey && evtobj.altKey && evtobj.key.toLowerCase() ==="c"){
-                componentRef.ghciService.focusConsole();
-                focus = "consola";
-                return false;
-            }  else if(evtobj.ctrlKey && evtobj.altKey && evtobj.key.toLowerCase() ==="f"){
-                document.getElementById("FigurasBtn").click()
-                componentRef.ghciService.focusConsole();
-                focus = "graficas";
-                return false;
-            }  else if(evtobj.key.toLowerCase() ==="p" && evtobj.ctrlKey && !evtobj.altKey){
-                componentRef.runCode();
-                return false;
-            }
-	    }
-        }
-        document.onkeydown = KeyPress;
-
-        let currentSession = sessionStorage.getItem("currentUser"); 
-        let langCode = currentSession ? JSON.parse(currentSession).language : 'es';
-        if (langCode == 'es'){
-            this.configCodeMirror.mode.name = "matefun-ES";
-        }else if (langCode == 'en'){
-            this.configCodeMirror.mode.name = "matefun-EN";
-        }
-    }
-
-    ngAfterViewInit() {
-        this.codemirror.last.instance.on('change', () => {
-            this.makeAJump();
-        });
-
-        componentRef = this;
-        if(this.codemirror.first.instance!=null && !this.cursorLabelInit){
-            this.cursorLabelInit = true;
-            this.codemirror.first.instance.setOption('theme', this.configCodeMirror.theme);
-            this.makePanel();    
-        }
-        if(!this.editableLoaded && this.codemirror.first.instance!=null &&(this.sessionService.archivo.editable!==undefined)){
-            try{
-                var editable = this.sessionService.archivo.editable && (this.sessionService.archivo.estado == 'Edicion' || this.sessionService.archivo.estado == 'Devuelto');
-                this.codemirror.first.instance.options.readOnly = !editable;
-                this.editableLoaded = true;
-
-
-            } catch(err) {
-                return;
-
-            }
-        }
-
-    }
-    
-    makeAJump(){
-        if (this.jump){
-            this.jump = false;
-            this.jumpExternalFile(this.jump_word);
-        }
-    }
-    
-    htmlEncode(value:string){
-        return value
-        .replace('Prelude> ','')
-        .replace(/&/g, '&amp;')
-        .replace(/\s/g, '&nbsp;')
-        .replace(/"/g, '&quot;')
-        .replace(/'/g, '&#39;')
-        .replace(/</g, '&lt;')
-        .replace(/>/g, '&gt;');
-    }
-
-    // @ViewChild(CanvasComponent) canvasC: CanvasComponent;
-    @ViewChild(Graph3DComponent) graph3DComp: Graph3DComponent;
-
-    @ViewChild(Graph2DComponent) graph2DComp: Graph2DComponent;
-
-    funcionSTR: string = 'Math.sin(x)*x*x-20';
-    consola: string = '';
-    command: string = '';
-    tipo: number = 1;
-
-    private onKey = function (value: string) {
-        this.funcionSTR = value;
-        this.archivo.contenido = value;
-    }
-
-    private writeCommand = function (value: string){
-        this.command = value.split("\n")[value.split("\n").length - 1];
-    }
-
-    private selectFunction = function() {
-        this.tipo = 1;
-        this.funcionSTR = "Math.sin(x)*x*x-20";
-    }
-
-    private selectElipse = function() {
-        this.tipo = 2;
-        this.funcionSTR = "elipse(x,y,radioX, radioY, rotacion_en_grados)";
-    }
-
-    private selectCircle = function() {
-        this.tipo = 3;
-        this.funcionSTR = "circulo(x,y,radio)";
-    }
-
-    private elipse = function(x: number, y: number, radiusX: number, radiusY: number, rotation: number) {
-        return [x, y, radiusX, radiusY, rotation];
-    }
-
-    private circulo = function(x: number, y: number, radius: number) {
-        return [x, y, radius];
-    }
-
-    inputConsola(text:any){
-        this.entrada = text;            
-    }
-
-    newFile(){
-        this.archivo = new Archivo();
-        this.archivo.cedulaCreador = this.authService.getUser().cedula;
-        this.archivo.contenido = "";
-        this.archivo.nombre = "";
-        this.copiaNombreArchivo = '';
-        this.copiaContenidoArchivo = '';
-    }
-
-    archivoModificado(event){
-        if (this.hintsCheck && !event.ctrlKey && !event.altKey){
-            if (/^[\w\_\d]$/.test(event.key) || event.key == 'Enter'){
-                this.codemirror.first.instance.options.files = this.archivosTree;
-                this.codemirror.first.instance.showHint(event);
-            }
-            if(this.copiaNombreArchivo!=this.archivo.nombre || this.copiaContenidoArchivo != this.archivo.contenido){
-                this.modificado = true;
-            }else{
-                this.modificado = false;
-            }
-        }else if (event.ctrlKey && event.shiftKey && event.key == 'K') this.codemirror.first.instance.toggleComment();
-        else if (event.altKey && event.key == '.') this.codemirror.first.instance.jumpToDefinition(this.archivosTree, this.codemirror.first.instance.doc, event);
-    }
-
-    goToFilesPreview(file_found, word){
-        this.mostrandoDefinicion = true;
-        for (var key in this.configCodeMirror){
-            this.configCodeMirrorDefinicion[key] = this.configCodeMirror[key];
-        }
-        this.configCodeMirrorDefinicion['readOnly'] = true;
-        this.archivoDefinicion = this.archivosTree.archivos.filter(a => a.id == parseInt(file_found.id))[0];
-        this.jump = true;  
-        this.jump_word = word;
-        this.jumpExternalFile(word);
-    }
-
-    jumpExternalFile(word){
-        this.codemirror.last.instance.jumpToDefinitionByWord(this.codemirror.last.instance.doc, word);
-    }
-
-    clickEnEditor(event){
-        if (this.typingCheck){
-            let currentSession = sessionStorage.getItem("currentUser"); 
-            let langCode = currentSession ? JSON.parse(currentSession).language : 'es';
-            if (langCode == 'en')
-                this.codemirror.first.instance.functionDefinitionEN(this.archivo.nombre, this.archivosTree.archivos, this.codemirror.first.instance.doc, event);
-            else if (langCode == 'es')
-                this.codemirror.first.instance.functionDefinitionES(this.archivo.nombre, this.archivosTree.archivos, this.codemirror.first.instance.doc, event);
-    }
-    }
-
-    guardarArchivo(){
-        var regex = /^[A-Z]/
-        if(this.archivo.nombre.trim() == ""){
-            this.notifService.error("Nombre de archivo sin especificar");
-        }else if (!regex.test(this.archivo.nombre)){
-            this.notifService.error("Nombre de archivo debe iniciar con mayusula.")
-        }else{
-            if(this.archivo.id){
-                this.haskellService.editarArchivo(this.archivo.id, this.archivo)
-                .subscribe(
-                    archivo => {
-                        //this.ghciService.consoleRef.Write("Editar archivo: " + this.archivo.nombre + "\n");
-                        this.archivo = archivo;
-                        this.lockSaveButton();
-                    }, 
-                    error => {
-                        this.notifService.error(error);
-                    });
-            }else{
-                this.haskellService.crearArchivo(this.archivo)
-                .subscribe(
-                    archivo => {
-                        //this.ghciService.consoleRef.Write("Archivo creado: " + this.archivo.nombre + "\n");
-                        this.archivo = archivo;
-                        this.lockSaveButton();
-                    }, 
-                    error => {
-                        this.notifService.error(error);
-                    });
-
-            }
-        }
-    }
-    runCode(){
-        this.ghciService.setCodemirrorRef(this.codemirror.first.instance);
-        this.ghciService.resetGutters();
-        var regex = /^[A-Z]/
-        if(this.archivo.nombre.trim() == ""){
-            this.notifService.error("Nombre de archivo sin especificar");
-        }else if (!regex.test(this.archivo.nombre)){
-            this.notifService.error("Nombre de archivo debe iniciar con mayusula.")
-        }else{
-            var resultado = this.sessionService.cargarDependencias(this.archivo);
-            if(resultado["status"]==="miss"){
-                this.ghciService.outputConsole("Error: No se encuentra el archivo " + resultado["nombre"] + "\n");
-                return;
-            }
-            if(this.archivo.id){
-                if(this.archivo.editable || this.authService.getUser().tipo == 'docente'){
-                    this.haskellService.editarArchivo(this.archivo.id, this.archivo)
-                    .subscribe(
-                        archivo => {
-                            this.archivo = archivo;
-                            var list = this.sessionService.getDependencias(),
-                            idList = [];
-                            for(var l in list){
-                                idList.push(list[l].id);
-                            }
-                            if(!idList.some(id => id ==archivo.id)){
-                                idList.push(archivo.id);
-                            }
-                            this.lockSaveButton();
-                            this.ghciService.loadFile(archivo.id,archivo.nombre,idList);
-                        }, 
-                        error => {
-                            this.notifService.error(error);
-                        });
-                }else{
-                    var list = this.sessionService.getDependencias(),
-                    idList = [];
-                    for(var l in list){
-                        idList.push(list[l].id);
-                    }
-                    if(!idList.some(id => id ==this.archivo.id)){
-                        idList.push(this.archivo.id);
-                    }
-                    this.ghciService.loadFile(this.archivo.id,this.archivo.nombre,idList);
+                if (!idList.some((id) => id == archivo.id)) {
+                  idList.push(archivo.id);
                 }
-            }else{
-                this.haskellService.crearArchivo(this.archivo)
-                .subscribe(
-                    archivo => {
-                        this.archivo = archivo;
-                        this.lockSaveButton();
-                        this.ghciService.loadFile(archivo.id,archivo.nombre,[]);
-                    }, 
-                    error => {
-                        this.notifService.error(error);
-                    });
-            }
+                this.lockSaveButton();
+                this.ghciService.loadFile(archivo.id, archivo.nombre, idList);
+              },
+              (error) => {
+                this.notifService.error(error);
+              }
+            );
+        } else {
+          var list = this.sessionService.getDependencias(),
+            idList = [];
+          for (var l in list) {
+            idList.push(list[l].id);
+          }
+          if (!idList.some((id) => id == this.archivo.id)) {
+            idList.push(this.archivo.id);
+          }
+          this.ghciService.loadFile(
+            this.archivo.id,
+            this.archivo.nombre,
+            idList
+          );
         }
-        this.ghciService.focusConsole();
-
-    }
-
-
-
-    download(filename, text) {
-        var element = document.createElement('a');
-        element.setAttribute('href', 'data:application/octet-stream,' + encodeURIComponent(text));
-        element.setAttribute('download', filename+ ".mf");
-
-        element.style.display = 'none';
-        document.body.appendChild(element);
-
-        element.click();
-
-        document.body.removeChild(element);
-    }
-    downloadFile(){
-        var nom = this.archivo.nombre;
-        var content = this.archivo.contenido;
-        if(nom!= undefined && nom!="" && content!= undefined && content !=""){
-            this.download(nom , content);
+      } else {
+        this.haskellService.crearArchivo(this.archivo).subscribe(
+          (archivo) => {
+            this.archivo = archivo;
+            this.lockSaveButton();
+            this.ghciService.loadFile(archivo.id, archivo.nombre, []);
+          },
+          (error) => {
+            this.notifService.error(error);
+          }
+        );
+      }
+    }
+    this.ghciService.focusConsole();
+  }
+
+  download(filename, text) {
+    var element = document.createElement("a");
+    element.setAttribute(
+      "href",
+      "data:application/octet-stream," + encodeURIComponent(text)
+    );
+    element.setAttribute("download", filename + ".mf");
+
+    element.style.display = "none";
+    document.body.appendChild(element);
+
+    element.click();
+
+    document.body.removeChild(element);
+  }
+  downloadFile() {
+    var nom = this.archivo.nombre;
+    var content = this.archivo.contenido;
+    if (
+      nom != undefined &&
+      nom != "" &&
+      content != undefined &&
+      content != ""
+    ) {
+      this.download(nom, content);
+    }
+  }
+  reiniciarInterprete() {
+    this.ghciService.reiniciarInterprete();
+  }
+
+  toggleConsole() {
+    this.consolaVisible = !this.consolaVisible;
+  }
+
+  seleccionarDirectorio(toImport: boolean) {
+    this.archivosTree = this.sessionService.getArchivos(undefined);
+    var that = this;
+    let disposable = this.dialogService
+      .addDialog(SeleccionarDirectorioComp, {
+        title: "",
+        import: toImport,
+        message: "",
+        archivos: this.archivosTree,
+        directorioActual: this.archivosTree,
+        nombre: "",
+        parent: this,
+      })
+      .subscribe((isConfirmed) => {
+        if (isConfirmed) {
+          //codeMirrorRef.options.readOnly = false;
+          //componentRef.editDialogFired = true;
         }
-
-    }
-    reiniciarInterprete(){
-        this.ghciService.reiniciarInterprete();
-    }
-
-    toggleConsole(){
-        this.consolaVisible = !this.consolaVisible;
-    }
-
-    seleccionarDirectorio(toImport:boolean){
-        this.archivosTree = this.sessionService.getArchivos(undefined);
-        var that = this;
-        let disposable = this.dialogService.addDialog(SeleccionarDirectorioComp, {
-            title:'',
- 	    import: toImport,
-            message:'',
-            archivos:this.archivosTree,
-            directorioActual:this.archivosTree,
-            nombre:'',
-            parent:this})
-        .subscribe((isConfirmed)=>{
-
-            if(isConfirmed) {
-
-
-                //codeMirrorRef.options.readOnly = false;
-                //componentRef.editDialogFired = true;
-            }
+      });
+  }
+
+  buildTreeFromList(archivos) {
+    this.sessionService.setArchivosList(archivos);
+    var root: Archivo;
+
+    for (var a in archivos) {
+      var arch = archivos[a];
+      if (arch.padreId === -1) {
+        root = arch;
+      }
+    }
+    this.idRecorridos = [root.id];
+    var archivos2 = archivos.filter(function (a) {
+      return a.id !== root.id;
+    });
+    var tree = this.buildTree(archivos2, root);
+    this.archivosTree = tree;
+    this.sessionService.setArchivosTree(tree);
+  }
+
+  buildTree(archivos, root) {
+    root.archivos = this.getArchivos(root.id, archivos);
+    for (var a in root.archivos) {
+      if (
+        root.archivos[a].directorio &&
+        this.idRecorridos[root.archivos[a].id] === undefined
+      ) {
+        var id = root.archivos[a].id;
+        var archivos2 = archivos.filter(function (a) {
+          return a.id !== id;
         });
+        root.archivos[a] = this.buildTree(archivos2, root.archivos[a]);
+      }
     }
+    return root;
+  }
 
+  getArchivos(id, archivos) {
+    return archivos.filter(function (a) {
+      return a.padreId === id;
+    });
+  }
 
-    buildTreeFromList (archivos){
-
-
-        this.sessionService.setArchivosList(archivos);
-        var root :Archivo;
-
-        for(var a in archivos){
-            var arch = archivos[a];
-            if(arch.padreId===-1){
-                root = arch;
-            } 
-        }
-        this.idRecorridos = [root.id];
-        var archivos2 = archivos.filter(
-            function(a){
-                return a.id!==root.id;
-            }
-            );
-        var tree = this.buildTree(archivos2,root);
-        this.archivosTree = tree;
-        this.sessionService.setArchivosTree(tree);
-    }
-
-
-    buildTree(archivos, root){
-        root.archivos = this.getArchivos(root.id,archivos);
-        for(var a in root.archivos){
-            if(root.archivos[a].directorio && this.idRecorridos[root.archivos[a].id] === undefined){
-                var id = root.archivos[a].id;
-                var archivos2 = archivos.filter(function(a){return a.id!==id});
-                root.archivos[a] = this.buildTree(archivos2 ,root.archivos[a]);
-            }
-        }
-        return root;
-    }
-
-    getArchivos(id,archivos){
-        return archivos.filter(
-            function(a){
-                return a.padreId === id;
-            });
-    }
-
-    onChangeTab(event) {
-        if (event.nextId == 'FigurasBtn3D') {
-            this.graph3DComp.onActivate();
-        }
+  onChangeTab(event) {
+    if (event.nextId == "FigurasBtn3D") {
+      this.graph3DComp.onActivate();
     }
+  }
 }
diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts b/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts
index 80eba443..bc415fcb 100755
--- a/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts	
@@ -1,45 +1,37 @@
-import { NgModule } from '@angular/core';
-import { FormsModule } from '@angular/forms';
-import { CanvasModule } from '../canvas/canvas.module'
-import { MateFunComponent } from './matefun.component';
-import { BootstrapModalModule } from 'ng2-bootstrap-modal';
-import { ConfirmComponent } from './confirm.component';
-import { SeleccionarDirectorioComp } from './seleccionarDirectorio.component';
-import { CommonModule } from '@angular/common';
-import { MateFunRoutingModule } from './matefun-routing.module';
-import { CodemirrorModule } from 'ng2-codemirror';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { NotificacionModule } from '../../notificacion/notificacion.module';
-import { Graph2DModule } from '../plotter/graph2D/graph2D.module';
-import { Graph3DModule } from '../plotter/graph3D/graph3D.module';
-import { I18nModule } from '../../shared/modules/translate/i18n.module';
-import { TitleCaseModule } from '../../shared/modules/titlecase.module';
+import { NgModule } from "@angular/core";
+import { FormsModule } from "@angular/forms";
+import { CanvasModule } from "../canvas/canvas.module";
+import { MateFunComponent } from "./matefun.component";
+import { BootstrapModalModule } from "ng2-bootstrap-modal";
+import { ConfirmComponent } from "./confirm.component";
+import { SeleccionarDirectorioComp } from "./seleccionarDirectorio.component";
+import { CommonModule } from "@angular/common";
+import { MateFunRoutingModule } from "./matefun-routing.module";
+import { CodemirrorModule } from "ng2-codemirror";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { NotificacionModule } from "../../notificacion/notificacion.module";
+import { Graph2DModule } from "../plotter/graph2D/graph2D.module";
+import { Graph3DModule } from "../plotter/graph3D/graph3D.module";
+import { I18nModule } from "../../shared/modules/translate/i18n.module";
+import { TitleCaseModule } from "../../shared/modules/titlecase.module";
 
 @NgModule({
-    imports: [
-        CommonModule, 
-        FormsModule, 
-        CanvasModule, 
-        Graph2DModule,
-        Graph3DModule,
-        NotificacionModule,
-        MateFunRoutingModule,
-        CodemirrorModule,
-        NgbModule,    
-        BootstrapModalModule,
-        I18nModule,
-        TitleCaseModule
-    ],      
-    entryComponents: [
-        ConfirmComponent,
-        SeleccionarDirectorioComp
-    ],
-    declarations: [
-        MateFunComponent,
-        ConfirmComponent,
-        SeleccionarDirectorioComp
-    ],
-    exports: [MateFunComponent]
+  imports: [
+    CommonModule,
+    FormsModule,
+    CanvasModule,
+    Graph2DModule,
+    Graph3DModule,
+    NotificacionModule,
+    MateFunRoutingModule,
+    CodemirrorModule,
+    NgbModule,
+    BootstrapModalModule,
+    I18nModule,
+    TitleCaseModule,
+  ],
+  entryComponents: [ConfirmComponent, SeleccionarDirectorioComp],
+  declarations: [MateFunComponent, ConfirmComponent, SeleccionarDirectorioComp],
+  exports: [MateFunComponent],
 })
-
-export class MateFunModule { }
+export class MateFunModule {}
diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.routes.ts b/Frontend Angular 4/src/app/layout/matefun/matefun.routes.ts
index 222b5fda..cad1de5c 100755
--- a/Frontend Angular 4/src/app/layout/matefun/matefun.routes.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/matefun.routes.ts	
@@ -1,8 +1,8 @@
-import { Route } from '@angular/router';
-import { MateFunComponent } from './index';
+import { Route } from "@angular/router";
+import { MateFunComponent } from "./index";
 export const MateFunRoutes: Route[] = [
-	{
-		path: 'funciones',
-		component: MateFunComponent
-	}
+  {
+    path: "funciones",
+    component: MateFunComponent,
+  },
 ];
diff --git a/Frontend Angular 4/src/app/layout/matefun/seleccionarDirectorio.component.ts b/Frontend Angular 4/src/app/layout/matefun/seleccionarDirectorio.component.ts
index 2f851786..aa00cb39 100755
--- a/Frontend Angular 4/src/app/layout/matefun/seleccionarDirectorio.component.ts	
+++ b/Frontend Angular 4/src/app/layout/matefun/seleccionarDirectorio.component.ts	
@@ -1,104 +1,162 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
-import { Archivo } from '../../shared/objects/archivo';
-import { TranslateService } from '@ngx-translate/core';
+import { Archivo } from "../../shared/objects/archivo";
+import { TranslateService } from "@ngx-translate/core";
 
 export interface ConfirmModel {
-  title:string;
-  message:string;
-  archivos:any;
-  directorioActual:any;
-  import:boolean;
-  parent:any;
-  nombre:string;
+  title: string;
+  message: string;
+  archivos: any;
+  directorioActual: any;
+  import: boolean;
+  parent: any;
+  nombre: string;
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-                   <div class="modal-header">
-                     <h6 class="modal-title pull-lefth">
-                      {{ "i18n.msg.file.create" | translate }}
-                     </h6> 
-                     <button type="button" class="close" (click)="close()" style="margin-rigth:8px;">&times;</button>
-                   </div>
-                   <div class="modal-body" style="height:350px;overflow-y: scroll;">
-                       <div>
-                         <div class="form-group">
-                            <label for="file-name" class="form-control-label">{{ "i18n.object.name" | translate | titleCase }}:</label>
-                            <input type="text" class="form-control" id="file-name" [(ngModel)]="nombre" >
-                         </div>
-                         <div class="list-group" >
-                            <button *ngFor="let arch of directorioActual.archivos.filter(esDirectorio)" type="button" (click)="navToDir(arch)" style="cursor:pointer" class="list-group-item list-group-item-action">
-                                  <i *ngIf="arch.directorio" class="fa fa-folder" style="margin-right:10px; font-size: 3em; cursor: pointer;" aria-hidden="true" ></i>
-                                  <i *ngIf="!arch.directorio" class="fa fa-file-text" style="margin-right:10px;font-size: 3em; cursor: pointer;" aria-hidden="true"></i>
-                                 {{arch.nombre}}
-                             </button>
-                          </div>
-			  <div *ngIf="import" class="form-group">
-			  <br>
-			    <label for="file-name" class="form-control-label">{{ "i18n.object.file" | translate | titleCase }}:</label><br>
-			    <input id='fileid' type='file' (change)="changeListener($event)" #input />
-			  </div>
-                        </div>
-                     </div>
-                   <div class="modal-footer">
-                      <button [disabled]="this.directorioActual.padreId == -1" type="button" class="btn btn-default" (click)="navBack()">
-                        {{ "i18n.action.goBack" | translate | titleCase }}
-                      </button>
-                      <button [disabled]="this.nombre=='' || (import && filecontent=='')" type="button" class="btn btn-primary" (click)="confirm()">
-                      {{ "i18n.action.create" | translate | titleCase }}
-                      </button>
-                   </div>
-                 </div>
-              </div>`
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h6 class="modal-title pull-lefth">
+          {{ "i18n.msg.file.create" | translate }}
+        </h6>
+        <button
+          type="button"
+          class="close"
+          (click)="close()"
+          style="margin-rigth:8px;"
+        >
+          &times;
+        </button>
+      </div>
+      <div class="modal-body" style="height:350px;overflow-y: scroll;">
+        <div>
+          <div class="form-group">
+            <label for="file-name" class="form-control-label"
+              >{{ "i18n.object.name" | translate | titleCase }}:</label
+            >
+            <input
+              type="text"
+              class="form-control"
+              id="file-name"
+              [(ngModel)]="nombre"
+            />
+          </div>
+          <div class="list-group">
+            <button
+              *ngFor="
+                let arch of directorioActual.archivos.filter(esDirectorio)
+              "
+              type="button"
+              (click)="navToDir(arch)"
+              style="cursor:pointer"
+              class="list-group-item list-group-item-action"
+            >
+              <i
+                *ngIf="arch.directorio"
+                class="fa fa-folder"
+                style="margin-right:10px; font-size: 3em; cursor: pointer;"
+                aria-hidden="true"
+              ></i>
+              <i
+                *ngIf="!arch.directorio"
+                class="fa fa-file-text"
+                style="margin-right:10px;font-size: 3em; cursor: pointer;"
+                aria-hidden="true"
+              ></i>
+              {{ arch.nombre }}
+            </button>
+          </div>
+          <div *ngIf="import" class="form-group">
+            <br />
+            <label for="file-name" class="form-control-label"
+              >{{ "i18n.object.file" | translate | titleCase }}:</label
+            ><br />
+            <input
+              id="fileid"
+              type="file"
+              (change)="changeListener($event)"
+              #input
+            />
+          </div>
+        </div>
+      </div>
+      <div class="modal-footer">
+        <button
+          [disabled]="this.directorioActual.padreId == -1"
+          type="button"
+          class="btn btn-default"
+          (click)="navBack()"
+        >
+          {{ "i18n.action.goBack" | translate | titleCase }}
+        </button>
+        <button
+          [disabled]="this.nombre == '' || (import && filecontent == '')"
+          type="button"
+          class="btn btn-primary"
+          (click)="confirm()"
+        >
+          {{ "i18n.action.create" | translate | titleCase }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class SeleccionarDirectorioComp extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class SeleccionarDirectorioComp
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   title: string;
   message: string;
-  archivos:any;
-  directorioActual:any;
-  parent:any;
-  nombre:string;
+  archivos: any;
+  directorioActual: any;
+  parent: any;
+  nombre: string;
   translateService: any;
-  import:boolean;
+  import: boolean;
   filecontent: string = "";
 
-  constructor(dialogService: DialogService, public translate: TranslateService) {
+  constructor(
+    dialogService: DialogService,
+    public translate: TranslateService
+  ) {
     super(dialogService);
     this.translateService = translate;
   }
-  esDirectorio(archivo){return archivo.directorio;}
-
-    changeListener($event): void {
-            this.readThis($event.target);
-     }
-
+  esDirectorio(archivo) {
+    return archivo.directorio;
+  }
 
-    readThis(inputValue: any): void {
-        var file: File = inputValue.files[0];
-        var myReader: FileReader = new FileReader();
-        var fileType = inputValue.parentElement.id;
-	
-        myReader.onloadend = (e) => {    
-	    this.filecontent = myReader.result as string;
-        }
+  changeListener($event): void {
+    this.readThis($event.target);
+  }
 
-        myReader.readAsText(file);
-    }
+  readThis(inputValue: any): void {
+    var file: File = inputValue.files[0];
+    var myReader: FileReader = new FileReader();
+    var fileType = inputValue.parentElement.id;
 
+    myReader.onloadend = (e) => {
+      this.filecontent = myReader.result as string;
+    };
 
+    myReader.readAsText(file);
+  }
 
   confirm() {
-    // we set dialog result as true on click on confirm button, 
-    // then we can get dialog result from caller code 
-    var regex = /^[A-Z]/
-    if(this.nombre==undefined || this.nombre==""){
-        this.parent.notifService.error(this.translateService.get('i18n.warning.file.invalidName').value);
-    }else if (!regex.test(this.nombre)){
-        this.parent.notifService.error(this.translateService.get('i18n.warning.file.capitalLetter').value);
-    }else{
-      var archivo:Archivo = new Archivo();
+    // we set dialog result as true on click on confirm button,
+    // then we can get dialog result from caller code
+    var regex = /^[A-Z]/;
+    if (this.nombre == undefined || this.nombre == "") {
+      this.parent.notifService.error(
+        this.translateService.get("i18n.warning.file.invalidName").value
+      );
+    } else if (!regex.test(this.nombre)) {
+      this.parent.notifService.error(
+        this.translateService.get("i18n.warning.file.capitalLetter").value
+      );
+    } else {
+      var archivo: Archivo = new Archivo();
       archivo.cedulaCreador = this.parent.authService.getUser().cedula;
       archivo.contenido = this.filecontent;
       archivo.nombre = this.nombre;
@@ -106,35 +164,36 @@ export class SeleccionarDirectorioComp extends DialogComponent<ConfirmModel, boo
       archivo.padreId = this.directorioActual.id;
       archivo.editable = true;
 
-      this.parent.haskellService.crearArchivo(archivo)
-                .subscribe(
-                    archivo => {
-                        this.parent.archivo = archivo;
-                        //this.parent.ghciService.loadFile(archivo.id);
-                        this.parent.sessionService.setArchivo(archivo);
-                       
-                    }, 
-                    error => {
-                        this.parent.notifService.error(error.text());
-                    });
-    
+      this.parent.haskellService.crearArchivo(archivo).subscribe(
+        (archivo) => {
+          this.parent.archivo = archivo;
+          //this.parent.ghciService.loadFile(archivo.id);
+          this.parent.sessionService.setArchivo(archivo);
+        },
+        (error) => {
+          this.parent.notifService.error(error.text());
+        }
+      );
+
       this.result = true;
       this.close();
     }
   }
 
-  navToDir(arch){
-    if(arch.directorio){
-      this.directorioActual = arch;  
+  navToDir(arch) {
+    if (arch.directorio) {
+      this.directorioActual = arch;
     }
   }
 
-  navBack(){
-    if (this.directorioActual.padreId != -1){
-       var idPadre = this.directorioActual.padreId;
-       var archivosList = this.parent.sessionService.getArchivosList();
-       var nuevoDirectorioActual = archivosList.filter(function(a){return a.id===idPadre})[0];
-       this.directorioActual=nuevoDirectorioActual;
+  navBack() {
+    if (this.directorioActual.padreId != -1) {
+      var idPadre = this.directorioActual.padreId;
+      var archivosList = this.parent.sessionService.getArchivosList();
+      var nuevoDirectorioActual = archivosList.filter(function (a) {
+        return a.id === idPadre;
+      })[0];
+      this.directorioActual = nuevoDirectorioActual;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts
index 085382cc..0356417e 100755
--- a/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts	
@@ -1,12 +1,11 @@
-import { Component, OnInit, Input } from '@angular/core';
+import { Component, OnInit, Input } from "@angular/core";
 
 @Component({
-  selector: 'animation-control',
-  templateUrl: './animation-control.component.html',
-  styleUrls: ['./animation-control.component.scss']
+  selector: "animation-control",
+  templateUrl: "./animation-control.component.html",
+  styleUrls: ["./animation-control.component.scss"],
 })
 export class AnimationControlComponent implements OnInit {
-  
   @Input() visible: boolean;
   @Input() playing: boolean;
 
@@ -18,9 +17,7 @@ export class AnimationControlComponent implements OnInit {
   @Input() onTogglePlay: Function;
   @Input() onChangeSpeed: Function;
 
-  constructor() { }
-
-  ngOnInit() {
-  }
+  constructor() {}
 
+  ngOnInit() {}
 }
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts
index f37335e6..523bf8fb 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts	
@@ -1,1214 +1,1316 @@
-import { Component, ViewChild, ElementRef } from '@angular/core';
-import { GHCIService } from '../../../shared/services/ghci.service';
-import * as functionPlot from 'function-plot';
-import { Animation, Setting, toJSON, triggerDownload } from './graph2D.helper';
-import { TranslateService } from '@ngx-translate/core';
+import { Component, ViewChild, ElementRef } from "@angular/core";
+import { GHCIService } from "../../../shared/services/ghci.service";
+import * as functionPlot from "function-plot";
+import { Animation, Setting, toJSON, triggerDownload } from "./graph2D.helper";
+import { TranslateService } from "@ngx-translate/core";
 
 @Component({
-    moduleId: module.id,
-    selector: 'graph2D-component',
-    templateUrl: './graph2D.component.html',
-    styleUrls: ['./graph2D.component.scss'],
-    host: {
-        '(window:resize)': 'onResize($event)'
-    }
+  moduleId: module.id,
+  selector: "graph2D-component",
+  templateUrl: "./graph2D.component.html",
+  styleUrls: ["./graph2D.component.scss"],
+  host: {
+    "(window:resize)": "onResize($event)",
+  },
 })
 export class Graph2DComponent {
+  // Ghci Service
+  private ghciServiceSub: any;
+
+  // Chart Container - DOM Element
+  @ViewChild("graph2DContainer")
+  private graph2DRef: ElementRef;
+
+  // Chart Instance
+  private instance: any;
+
+  // Settings
+  settings: Setting = {
+    axis: true,
+    grid: true,
+    tip: true,
+  };
+
+  private funciones = [];
+
+  private id = 0;
+
+  private valores = [];
+
+  private conjunto = [];
+
+  // Animation state
+  animation: Animation = {
+    data: [],
+    init: false,
+    currentFrame: 0,
+    fps: 10,
+    playing: false,
+    timeout: null,
+    animationFrame: null,
+    speedX: 10,
+    boton: true,
+    zoo: 2000,
+  };
+  //Nuevo
+
+  public easeInOutCubic = function (fps) {
+    var t = fps < 6 ? 6 : fps;
+    var k = t / 60;
+    var animation =
+      k < 0.5
+        ? 60 * (4 * k * k * k)
+        : 60 * ((k - 1) * (2 * k - 2) * (2 * k - 2) + 1);
+    console.log(animation);
+    return animation;
+  };
+
+  public setZoom = () => {
+    this.animation.zoo = this.animation.zoo;
+  };
+  public multiGraf = () => {
+    this.animation.boton = !this.animation.boton;
+  };
+  public constructor(
+    private ghciService: GHCIService,
+    public translate: TranslateService
+  ) {
+    this.ghciServiceSub = ghciService.messages.subscribe(
+      (canvas) => {
+        // Stop Animation
+        if (this.animation.init) {
+          this.stopAnimation();
+        }
+        switch (canvas.tipo) {
+          case "graph": {
+            console.log(canvas.resultado);
+            // var jsonCanvas = JSON.parse(JSONRepair(canvas.resultado));
 
-    // Ghci Service
-    private ghciServiceSub: any;
-
-    // Chart Container - DOM Element
-    @ViewChild('graph2DContainer')
-    private graph2DRef: ElementRef;
-
-    // Chart Instance
-    private instance: any;
-
-    // Settings
-    settings: Setting = {
-        axis: true,
-        grid: true,
-        tip: true
-    }
-
-    private funciones= [];
-
-    private id = 0;
-
-    private valores = [];
-
-    private conjunto= [];
-
-    // Animation state
-    animation: Animation = {
-        data: [],
-        init: false,
-        currentFrame: 0,
-        fps: 10,
-        playing: false,
-        timeout: null,
-        animationFrame: null,
-        speedX: 10,
-        boton: true,
-        zoo: 2000
-    };
-    //Nuevo
-
-    public easeInOutCubic = function(fps) {
-        var t = fps < 6 ? 6 : fps;
-        var k = t/60;
-        var animation = k<.5 ? 60*(4*k*k*k) : 60*((k-1)*(2*k-2)*(2*k-2)+1);
-        console.log(animation);
-        return animation;
-    }
-
-    public setZoom = () => {
-        this.animation.zoo = this.animation.zoo ;  
-    }
-    public multiGraf = () => { 
-        this.animation.boton = !this.animation.boton;
-    }
-    public constructor(private ghciService: GHCIService, public translate: TranslateService) {
-        this.ghciServiceSub = ghciService.messages.subscribe(
-            canvas => {
-                // Stop Animation
-                if (this.animation.init) {
-                    this.stopAnimation();
-                }
-                switch(canvas.tipo) { 
-                    case 'graph': {
-                        console.log(canvas.resultado)
-                        // var jsonCanvas = JSON.parse(JSONRepair(canvas.resultado));
-
-                        var jsonCanvas = JSON.parse(canvas.resultado);
-                        var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
-    
-                        var d = conjs + "}"; //Leo
-			
-                        var obj = JSON.parse(d);
-
-                        if ((obj.conj.baseDom == "Error") || (obj.conj.baseCod == "Error")) { break; }
-
-                        //Para las funciones 
-                        if (obj.conj.sets.fdom == "function(x)") {
-                            var nom = jsonCanvas.funs[0].dom;
-                            var elemento1 = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
-
-                            var funcionString = '';
-                            funcionString ="var "+nom+" = function(x){\nreturn "+elemento1+"}\n"
-
-                            funcionString += 'return ' + nom + '(x);\n'
-                            
-                            for (var funs of jsonCanvas.funs) {
-                                funcionString = 'var ' + funs.fun + ' = function('+funs.args+'){\n return ' + this.generarExpresion(funs.bdy) + '}\n' + funcionString;
-                            }
-                            funcionString = '(x)=>{\n' + funcionString + '}';
-			    console.log(funcionString);
-                            obj.conj.sets.fdom = eval(funcionString);
-
-
-
-
-
-
-
-
-                        }
-                        if (obj.conj.sets.fcod == "function(x)") {
-                           
-                            var nom = jsonCanvas.funs[0].cod;
-                            var elemento2 = this.recursionfuncionCod(jsonCanvas.funs[0].sets, nom);
-                            console.log(elemento2)
-
-                            obj.conj.sets.fcod = function (x) { return (eval(elemento2)) }
-
-                            var funcionString = '';
-                            funcionString ="var "+nom+" = function(x){\nreturn "+elemento2+"}\n"
-
-                            funcionString += 'return ' + nom + '(x);\n'
-                            
-                            for (var funs of jsonCanvas.funs) {
-                                funcionString = 'var ' + funs.fun + ' = function('+funs.args+'){\n return ' + this.generarExpresion(funs.bdy) + '}\n' + funcionString;
-                            }
-                            funcionString = '(x)=>{\n' + funcionString + '}';
-
-                            obj.conj.sets.fdom = eval(funcionString);
-
-                            
+            var jsonCanvas = JSON.parse(canvas.resultado);
+            var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
 
+            var d = conjs + "}"; //Leo
 
-                        }
+            var obj = JSON.parse(d);
 
-                        var funcionGenerada = this.generarFuncion(jsonCanvas);
-                        
- 
+            if (obj.conj.baseDom == "Error" || obj.conj.baseCod == "Error") {
+              break;
+            }
 
+            //Para las funciones
+            if (obj.conj.sets.fdom == "function(x)") {
+              var nom = jsonCanvas.funs[0].dom;
+              var elemento1 = this.recursionfuncion(
+                jsonCanvas.funs[0].sets,
+                nom
+              );
+
+              var funcionString = "";
+              funcionString =
+                "var " + nom + " = function(x){\nreturn " + elemento1 + "}\n";
+
+              funcionString += "return " + nom + "(x);\n";
+
+              for (var funs of jsonCanvas.funs) {
+                funcionString =
+                  "var " +
+                  funs.fun +
+                  " = function(" +
+                  funs.args +
+                  "){\n return " +
+                  this.generarExpresion(funs.bdy) +
+                  "}\n" +
+                  funcionString;
+              }
+              funcionString = "(x)=>{\n" + funcionString + "}";
+              console.log(funcionString);
+              obj.conj.sets.fdom = eval(funcionString);
+            }
+            if (obj.conj.sets.fcod == "function(x)") {
+              var nom = jsonCanvas.funs[0].cod;
+              var elemento2 = this.recursionfuncionCod(
+                jsonCanvas.funs[0].sets,
+                nom
+              );
+              console.log(elemento2);
+
+              obj.conj.sets.fcod = function (x) {
+                return eval(elemento2);
+              };
+
+              var funcionString = "";
+              funcionString =
+                "var " + nom + " = function(x){\nreturn " + elemento2 + "}\n";
+
+              funcionString += "return " + nom + "(x);\n";
+
+              for (var funs of jsonCanvas.funs) {
+                funcionString =
+                  "var " +
+                  funs.fun +
+                  " = function(" +
+                  funs.args +
+                  "){\n return " +
+                  this.generarExpresion(funs.bdy) +
+                  "}\n" +
+                  funcionString;
+              }
+              funcionString = "(x)=>{\n" + funcionString + "}";
+
+              obj.conj.sets.fdom = eval(funcionString);
+            }
 
-                        //para Enumerados
-                        if (obj.conj.dom == 'Numer') {
-                            var j = 0;
-                            for (var f of obj.conj.sets.fdom) {
-                                var expresionDom = new RegExp('( '+f+' )', 'g'); 
-                                funcionGenerada = funcionGenerada.replace(expresionDom, j.toString()); 
-                                j += 1;
-                            }
-                        }
-                        if (obj.conj.cod == 'Numer') {
-                            var j2 = 0;
-                            for (var f2 of obj.conj.sets.fcod) {
-                                var expresionCod = new RegExp(f2, 'g'); 
-                                funcionGenerada = funcionGenerada.replace(expresionCod, j2.toString()); 
-                                j2 += 1;
-                            }
+            var funcionGenerada = this.generarFuncion(jsonCanvas);
+
+            //para Enumerados
+            if (obj.conj.dom == "Numer") {
+              var j = 0;
+              for (var f of obj.conj.sets.fdom) {
+                var expresionDom = new RegExp("( " + f + " )", "g");
+                funcionGenerada = funcionGenerada.replace(
+                  expresionDom,
+                  j.toString()
+                );
+                j += 1;
+              }
+            }
+            if (obj.conj.cod == "Numer") {
+              var j2 = 0;
+              for (var f2 of obj.conj.sets.fcod) {
+                var expresionCod = new RegExp(f2, "g");
+                funcionGenerada = funcionGenerada.replace(
+                  expresionCod,
+                  j2.toString()
+                );
+                j2 += 1;
+              }
+            }
 
-                        }
+            if (obj.conj.baseDom == "R") {
+              obj.conj.baseCod = "R";
+              if (obj.conj.cod != "Func") {
+                obj.conj.cod = "R";
+                obj.conj.fcod = "R";
+              }
+            }
 
-                        if (obj.conj.baseDom == 'R'){
-                            obj.conj.baseCod = 'R';
-                            if (obj.conj.cod != 'Func'){
-                                obj.conj.cod = 'R';
-                                obj.conj.fcod = 'R'; 
-                            }
-             
+            let fun = eval(funcionGenerada);
 
-                        }
+            var colores = ["violet", "red", "blue", "orange", "green", "black"];
+            var num = this.getRandomArbitrary(0, 5);
+            var color = colores[num];
 
-                        
-                        let fun = eval(funcionGenerada);
-                   
-
-                        var colores = ['violet', 'red', 'blue', 'orange', 'green','black']
-                        var num = this.getRandomArbitrary(0, 5);
-                        var color = colores[num];
-    
-                        var tipoGraf;
-                        if (obj.conj.baseDom != 'R'){
-                            tipoGraf = 'scatter';
-                        }else{
-                            tipoGraf = 'polyline';
-                        }
-                        if(this.animation.boton && obj.conj.cod != 'Numer' && obj.conj.dom != 'Numer'){
-                            if(this.conjunto.length == 1 && (this.conjunto[0].cod == 'Numer' || this.conjunto[0].dom == 'Numer')){
-                                this.conjunto = [];
-                                this.conjunto.push(obj.conj);
-                                this.id = 0;
-                                this.funciones = [];
-                                if(obj.conj.baseDom == 'R'){
-                                    this.valores = [];
-                                    var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
-                                    
-                                    var funcionesVer2019 =  this.createListFunction(jsonCanvas);
-                                    var listValores = [];
-                                    for (var k of this.valores){
-                                    listValores.push(parseInt(k))
-                                    }   
-                                    for (var i of this.valores){
-                                    for(var t of this.valores){
-                                        var aux = parseInt(t);
-                                        var aux2 = parseInt(i);
-                                        var mul = aux * aux2;
-                                        listValores.push(mul)
-                                        }
-                                    }
-                                    for (i = -999; i < 1000; i++) {                                      
-                                        listValores.push(i)
-                                    }
-                                    let sinRepetidos = listValores.filter((valor, indiceActual, arreglo) => arreglo.indexOf(valor) === indiceActual);
-
-                                    for (var fun2 of funcionesVer2019){
-                                        let fun3 = eval(fun2);
-                                        var insertar = false;
-                                        var punto1 = [];
-
-                                        if (sinRepetidos.length){
-                                            for (var p of sinRepetidos){
-                                                var pn= parseInt(p) - 0.001
-                                                var pp= parseInt(p) + 0.001
-                                                insertar = (((fun3(pp) != undefined) ) || ((fun3(pn) != undefined)) || insertar)
-                                                if((fun3(pp) != undefined)){
-                                                    punto1.push(pp);
-                                                }else if ((fun3(pn) != undefined)){
-                                                    punto1.push(p);
-                                                }
-                                            }
-                                        }else{
-                                            insertar = true;
-                                        }
-                                        if (insertar){
-                                            console.log("A")
-                                            this.funciones.push({
-                                                id: 0,
-                                                sampler: 'builtIn',
-                                                fn: function(scope) {
-                                                return fun3(scope.x)
-                                                },
-                                                graphType: tipoGraf,
-                                                point:punto1[0],
-                                                color: color,
-                                                
-                                            });
-                                        }
-                                    } 
-                                }else{
-                                    console.log("B")
-                                        this.funciones.push({
-
-                                            id: this.funciones.length,
-                                            sampler: 'builtIn',
-                                            fn: function(scope) {
-                                            return fun(scope.x)
-                                            },
-                                            graphType: tipoGraf,
-                                            color: color
-                                        })
-                                } 
-                                     
-                            }else{
-                                if(this.conjunto.length == 1){
-                                    this.id = 1;
-                              
-                                    this.conjunto.unshift({radio: 2, dom:this.conjunto[0].baseDom, cod:this.conjunto[0].baseCod, baseCod:this.conjunto[0].baseCod, baseDom:this.conjunto[0].baseDom, sets:{fdom:this.conjunto[0].baseDom,fcod:this.conjunto[0].baseCod}});
-                                    this.funciones[0].id = this.id;
-                                    
-                                }
-                                if (this.conjunto.length != 0){ 
-                                    if (obj.conj.baseDom == 'R'){
-                                        this.conjunto[0].baseDom = 'R';
-                                        this.conjunto[0].dom = 'R';
-                                        this.conjunto[0].sets.fdom = 'R';
-                                    }
-                                    if (obj.conj.baseCod == 'R'){
-                                        this.conjunto[0].baseCod = 'R';
-                                        this.conjunto[0].cod = 'R';
-                                        this.conjunto[0].sets.fcod = 'R';
-                                    }
-                                }    
-                                this.conjunto.push(obj.conj);
-                                var identificador=0;
-                                    if (this.conjunto.length > 1){
-                                        identificador=this.conjunto.length - 2 + this.id;
-                                    }
-                                if(obj.conj.baseDom == 'R'){
-                                   this.valores = [];
-                                   var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
-
-                                   var funcionesVer2019 =  this.createListFunction(jsonCanvas);
-                                   var listValores = [];
-                                   for (var k of this.valores){
-                                      listValores.push(parseInt(k))
-                                   }   
-                                   for (var i of this.valores){
-                                      for(var t of this.valores){
-                                         var aux = parseInt(t);
-                                         var aux2 = parseInt(i);
-                                         var mul = aux * aux2;
-                                         listValores.push(mul)
-                                       }
-                                    }
-                                    for (i = -999; i < 1000; i++) {                                      
-                                        listValores.push(i)
-                                    }
-                                    let sinRepetidos = listValores.filter((valor, indiceActual, arreglo) => arreglo.indexOf(valor) === indiceActual);
-                                    for (var fun2 of funcionesVer2019){
-                                        let fun3 = eval(fun2);
-                                        var insertar = false;
-                                        var punto1 = [];
-
-                                        if (sinRepetidos.length){
-                                            for (var p of sinRepetidos){
-                                                var pn= parseInt(p) - 0.001
-                                                var pp= parseInt(p) + 0.001
-                                                insertar = (((fun3(pp) != undefined) ) || ((fun3(pn) != undefined)) || insertar)
-                                                if((fun3(pp) != undefined)){
-                                                    punto1.push(pp);
-                                                }else if ((fun3(pn) != undefined)){
-                                                    punto1.push(p);
-                                                }
-                                            }
-                                        }else{
-                                            insertar = true;
-                                        }
-                                        if (insertar){
-                                            console.log(fun3)
-                                            this.funciones.push({
-                                                id: identificador,
-                                                sampler: 'builtIn',
-                                                fn: function(scope) {
-                                                return fun3(scope.x)
-                                                },
-                                                graphType: tipoGraf,
-                                                point:punto1[0],
-                                                color: color,
-                                               
-                                            });
-                                        }
-                                    } 
-                                }else{
-                                    console.log("D")
-                                    this.funciones.push({
-                                        id: identificador,
-                                        sampler: 'builtIn',
-                                        fn: function(scope) {
-                                        return fun(scope.x)
-                                        },
-                                        graphType: tipoGraf,
-                                        color: color
-                                    });
-                                }
-                                
-                            }        
-                        }else{ 
-                            
-                            this.conjunto = [];
-                            this.conjunto.push(obj.conj);
-                            this.id = 0;
-                            this.funciones = [];
-                            if(obj.conj.baseDom == 'R'){
-                                this.valores = [];
-                                var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
-                                var funcionesVer2019 =  this.createListFunction(jsonCanvas);
-                                var listValores = [];
-                                for (var k of this.valores){
-                                   listValores.push(parseInt(k))
-                                }
-                                for (var i of this.valores){
-                                   for(var t of this.valores){
-                                      var aux = parseInt(t);
-                                      var aux2 = parseInt(i);
-                                      var mul = aux * aux2;
-                                      listValores.push(mul)
-                                    }
-                                 }
-                                 for (i = -999; i < 1000; i++) {                                      
-                                     listValores.push(i)
-                                 }
-                                 let sinRepetidos = listValores.filter((valor, indiceActual, arreglo) => arreglo.indexOf(valor) === indiceActual);
-
-                                 for (var fun2 of funcionesVer2019){
-                                     let fun3 = eval(fun2);
-                                     var insertar = false;
-                                     var punto1 = [];
-
-                                     if (sinRepetidos.length){
-                                         for (var p of sinRepetidos){
-                                             var pn= parseInt(p) - 0.001
-                                             var pp= parseInt(p) + 0.001
-                                             insertar = (((fun3(pp) != undefined) ) || ((fun3(pn) != undefined)) || insertar)
-                                             if((fun3(pp) != undefined)){
-                                                 punto1.push(pp);
-                                             }else if ((fun3(pn) != undefined)){
-                                                 punto1.push(p);
-                                             }
-                                         }
-                                     }else{
-                                         insertar = true;
-                                     }
-                                     if (insertar){
-                                         this.funciones.push({
-                                             id: 0,
-                                             sampler: 'builtIn',
-                                             fn: function(scope) {
-                                             return fun3(scope.x)
-                                             },
-                                             graphType: tipoGraf,
-                                             point:punto1[0],
-                                             color: color,
-                                            
-                                         });
-
-                                     }
-                                  
-                                 } 
-
-                            }else{
-                                this.funciones.push({
-                                    id: this.funciones.length,
-                                    sampler: 'builtIn',
-                                    fn: function(scope) {
-                                    return fun(scope.x)
-                                    },
-                                    graphType: tipoGraf,
-                                    color: color
-                                });
-
-                            }
+            var tipoGraf;
+            if (obj.conj.baseDom != "R") {
+              tipoGraf = "scatter";
+            } else {
+              tipoGraf = "polyline";
+            }
+            if (
+              this.animation.boton &&
+              obj.conj.cod != "Numer" &&
+              obj.conj.dom != "Numer"
+            ) {
+              if (
+                this.conjunto.length == 1 &&
+                (this.conjunto[0].cod == "Numer" ||
+                  this.conjunto[0].dom == "Numer")
+              ) {
+                this.conjunto = [];
+                this.conjunto.push(obj.conj);
+                this.id = 0;
+                this.funciones = [];
+                if (obj.conj.baseDom == "R") {
+                  this.valores = [];
+                  var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
+
+                  var funcionesVer2019 = this.createListFunction(jsonCanvas);
+                  var listValores = [];
+                  for (var k of this.valores) {
+                    listValores.push(parseInt(k));
+                  }
+                  for (var i of this.valores) {
+                    for (var t of this.valores) {
+                      var aux = parseInt(t);
+                      var aux2 = parseInt(i);
+                      var mul = aux * aux2;
+                      listValores.push(mul);
+                    }
+                  }
+                  for (i = -999; i < 1000; i++) {
+                    listValores.push(i);
+                  }
+                  let sinRepetidos = listValores.filter(
+                    (valor, indiceActual, arreglo) =>
+                      arreglo.indexOf(valor) === indiceActual
+                  );
+
+                  for (var fun2 of funcionesVer2019) {
+                    let fun3 = eval(fun2);
+                    var insertar = false;
+                    var punto1 = [];
+
+                    if (sinRepetidos.length) {
+                      for (var p of sinRepetidos) {
+                        var pn = parseInt(p) - 0.001;
+                        var pp = parseInt(p) + 0.001;
+                        insertar =
+                          fun3(pp) != undefined ||
+                          fun3(pn) != undefined ||
+                          insertar;
+                        if (fun3(pp) != undefined) {
+                          punto1.push(pp);
+                        } else if (fun3(pn) != undefined) {
+                          punto1.push(p);
                         }
-                        let bounding = this.getBounding();
-                        this.instance = functionPlot({
-                            target: '#graph2D-container',
-                            grid: this.settings.grid,
-                            axis:  this.settings.axis,
-                            width: bounding.width,
-                            height: bounding.height,
-                            tip: { 
-                                color: 'green'
-                            },
-                            xAxis: {
-                                scale: 'linear',
-                                domain: { initial: [-4, 4],
-                                        type: 'discrete' },
-                                yAxis: { domain: [-4, 4] }
-                            },
-                            conj:this.conjunto,
-                            data: this.funciones,
-                            zoom:this.animation.zoo,
-                            plugins: [
-                                functionPlot.plugins.zoomBox()
-                            ]
-                        })
-                        break; 
+                      }
+                    } else {
+                      insertar = true;
+                    }
+                    if (insertar) {
+                      console.log("A");
+                      this.funciones.push({
+                        id: 0,
+                        sampler: "builtIn",
+                        fn: function (scope) {
+                          return fun3(scope.x);
+                        },
+                        graphType: tipoGraf,
+                        point: punto1[0],
+                        color: color,
+                      });
                     }
-                    case 'canvas': {
-                        var shapesData = JSON.parse(canvas.resultado);
-                        var shapesDataNormalized = this.normalizeShapesData(shapesData);
-                        let bounding = this.getBounding();
-                        this.cleanPlot(); 
-                        this.instance = functionPlot({
-                            target: '#graph2D-container',
-                            width: bounding.width,
-                            height: bounding.height,
-                            grid: this.settings.grid,
-                            axis:  this.settings.axis,
-                            xAxis: {
-                                scale: 'linear',
-                                domain: {
-                                    initial: [-10, 10],
-                                    type: 'discrete'
-                                }
-                            },
-                            data: shapesDataNormalized,
-                            plugins: [
-                                functionPlot.plugins.zoomBox()
-                            ]
-                        })
-                        break; 
+                  }
+                } else {
+                  console.log("B");
+                  this.funciones.push({
+                    id: this.funciones.length,
+                    sampler: "builtIn",
+                    fn: function (scope) {
+                      return fun(scope.x);
+                    },
+                    graphType: tipoGraf,
+                    color: color,
+                  });
+                }
+              } else {
+                if (this.conjunto.length == 1) {
+                  this.id = 1;
+
+                  this.conjunto.unshift({
+                    radio: 2,
+                    dom: this.conjunto[0].baseDom,
+                    cod: this.conjunto[0].baseCod,
+                    baseCod: this.conjunto[0].baseCod,
+                    baseDom: this.conjunto[0].baseDom,
+                    sets: {
+                      fdom: this.conjunto[0].baseDom,
+                      fcod: this.conjunto[0].baseCod,
+                    },
+                  });
+                  this.funciones[0].id = this.id;
+                }
+                if (this.conjunto.length != 0) {
+                  if (obj.conj.baseDom == "R") {
+                    this.conjunto[0].baseDom = "R";
+                    this.conjunto[0].dom = "R";
+                    this.conjunto[0].sets.fdom = "R";
+                  }
+                  if (obj.conj.baseCod == "R") {
+                    this.conjunto[0].baseCod = "R";
+                    this.conjunto[0].cod = "R";
+                    this.conjunto[0].sets.fcod = "R";
+                  }
+                }
+                this.conjunto.push(obj.conj);
+                var identificador = 0;
+                if (this.conjunto.length > 1) {
+                  identificador = this.conjunto.length - 2 + this.id;
+                }
+                if (obj.conj.baseDom == "R") {
+                  this.valores = [];
+                  var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
+
+                  var funcionesVer2019 = this.createListFunction(jsonCanvas);
+                  var listValores = [];
+                  for (var k of this.valores) {
+                    listValores.push(parseInt(k));
+                  }
+                  for (var i of this.valores) {
+                    for (var t of this.valores) {
+                      var aux = parseInt(t);
+                      var aux2 = parseInt(i);
+                      var mul = aux * aux2;
+                      listValores.push(mul);
                     }
-                    case 'animacion': {
-                        this.cleanPlot(); 
-                        var animationData = canvas.resultado.map(res => JSON.parse(res));
-                        for (var frame of animationData) {
-                            this.animation.data.push(this.normalizeShapesData(frame));
+                  }
+                  for (i = -999; i < 1000; i++) {
+                    listValores.push(i);
+                  }
+                  let sinRepetidos = listValores.filter(
+                    (valor, indiceActual, arreglo) =>
+                      arreglo.indexOf(valor) === indiceActual
+                  );
+                  for (var fun2 of funcionesVer2019) {
+                    let fun3 = eval(fun2);
+                    var insertar = false;
+                    var punto1 = [];
+
+                    if (sinRepetidos.length) {
+                      for (var p of sinRepetidos) {
+                        var pn = parseInt(p) - 0.001;
+                        var pp = parseInt(p) + 0.001;
+                        insertar =
+                          fun3(pp) != undefined ||
+                          fun3(pn) != undefined ||
+                          insertar;
+                        if (fun3(pp) != undefined) {
+                          punto1.push(pp);
+                        } else if (fun3(pn) != undefined) {
+                          punto1.push(p);
                         }
-                        this.runAnimation();
-                        this.animation.init = true;
-                        break; 
+                      }
+                    } else {
+                      insertar = true;
                     }
+                    if (insertar) {
+                      console.log(fun3);
+                      this.funciones.push({
+                        id: identificador,
+                        sampler: "builtIn",
+                        fn: function (scope) {
+                          return fun3(scope.x);
+                        },
+                        graphType: tipoGraf,
+                        point: punto1[0],
+                        color: color,
+                      });
+                    }
+                  }
+                } else {
+                  console.log("D");
+                  this.funciones.push({
+                    id: identificador,
+                    sampler: "builtIn",
+                    fn: function (scope) {
+                      return fun(scope.x);
+                    },
+                    graphType: tipoGraf,
+                    color: color,
+                  });
+                }
+              }
+            } else {
+              this.conjunto = [];
+              this.conjunto.push(obj.conj);
+              this.id = 0;
+              this.funciones = [];
+              if (obj.conj.baseDom == "R") {
+                this.valores = [];
+                var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
+                var funcionesVer2019 = this.createListFunction(jsonCanvas);
+                var listValores = [];
+                for (var k of this.valores) {
+                  listValores.push(parseInt(k));
+                }
+                for (var i of this.valores) {
+                  for (var t of this.valores) {
+                    var aux = parseInt(t);
+                    var aux2 = parseInt(i);
+                    var mul = aux * aux2;
+                    listValores.push(mul);
+                  }
+                }
+                for (i = -999; i < 1000; i++) {
+                  listValores.push(i);
                 }
-            },
-            error => {
+                let sinRepetidos = listValores.filter(
+                  (valor, indiceActual, arreglo) =>
+                    arreglo.indexOf(valor) === indiceActual
+                );
+
+                for (var fun2 of funcionesVer2019) {
+                  let fun3 = eval(fun2);
+                  var insertar = false;
+                  var punto1 = [];
+
+                  if (sinRepetidos.length) {
+                    for (var p of sinRepetidos) {
+                      var pn = parseInt(p) - 0.001;
+                      var pp = parseInt(p) + 0.001;
+                      insertar =
+                        fun3(pp) != undefined ||
+                        fun3(pn) != undefined ||
+                        insertar;
+                      if (fun3(pp) != undefined) {
+                        punto1.push(pp);
+                      } else if (fun3(pn) != undefined) {
+                        punto1.push(p);
+                      }
+                    }
+                  } else {
+                    insertar = true;
+                  }
+                  if (insertar) {
+                    this.funciones.push({
+                      id: 0,
+                      sampler: "builtIn",
+                      fn: function (scope) {
+                        return fun3(scope.x);
+                      },
+                      graphType: tipoGraf,
+                      point: punto1[0],
+                      color: color,
+                    });
+                  }
+                }
+              } else {
+                this.funciones.push({
+                  id: this.funciones.length,
+                  sampler: "builtIn",
+                  fn: function (scope) {
+                    return fun(scope.x);
+                  },
+                  graphType: tipoGraf,
+                  color: color,
+                });
+              }
             }
-        )
-    }
-
-    /**
-     * Angular lifecycle hook.
-     * called after Angular has fully initialized a component's view.
-     */
-    ngAfterViewInit() {
-        if (!this.instance) {
             let bounding = this.getBounding();
             this.instance = functionPlot({
-                target: '#graph2D-container',
-                width: bounding.width,
-                height: bounding.height,
-                grid: this.settings.grid,
-                axis:  this.settings.axis,
-                xAxis: {
-                    scale: 'linear',
-                    domain: {
-                        initial: [-10, 10],
-                        type: 'discrete'
-                    }
-                },
-                data: []
-            })
-        }
-    }
-
-    /**
-     * Angular lifecycle hook.
-     * called when a directive, pipe, or service is destroyed.
-     */
-    ngOnDestroy() {
-        if (this.ghciServiceSub) {
-          this.ghciServiceSub.unsubscribe();
-        }
-    }
-
-    /**
-     * On Resize Event.
-     */
-    onResize(event){
-        let instance = this.instance;
-        let bounding = this.getBounding();
-        if (bounding.width > 0) {
-            instance.options.width = bounding.width;
-            instance.options.height = bounding.height;
-            instance.build();
-        }
-    }
-
-    /**
-     * @name getBounding
-     * @desc get the measures of the container of the graph
-     */
-    private getBounding = function() {
-        var {width, height} = this.graph2DRef.nativeElement.getBoundingClientRect();
-        if (width === 0) {
-            width = document.getElementById('graph2D-container').querySelector('svg').width.baseVal.value;
-            height = document.getElementById('graph2D-container').querySelector('svg').height.baseVal.value;
-        }
-        return {width, height}
-    }
-
-    /**
-     * @name updateFrame
-     * @desc update data for Function Plot and redraw the graph
-     */
-    public updateFrame = function() {
-        var $this = this;
-        var $data = $this.animation.data[$this.animation.currentFrame];
-        if ($this.instance) {
-            $this.instance.options.data = $data;
-            $this.instance.draw();
-        } else {
-            let bounding = $this.getBounding();
-            $this.instance = functionPlot({
-                target: '#graph2D-container',
-                grid: this.settings.grid,
-                axis:  this.settings.axis,
-                width: bounding.width,
-                height: bounding.height,
-                xAxis: {
-                    label: 'x - axis',
-                    scale: 'linear',
-                    domain: {
-                        initial: [-10, 10],
-                        type: 'discrete'
-                    }
+              target: "#graph2D-container",
+              grid: this.settings.grid,
+              axis: this.settings.axis,
+              width: bounding.width,
+              height: bounding.height,
+              tip: {
+                color: "green",
+              },
+              xAxis: {
+                scale: "linear",
+                domain: { initial: [-4, 4], type: "discrete" },
+                yAxis: { domain: [-4, 4] },
+              },
+              conj: this.conjunto,
+              data: this.funciones,
+              zoom: this.animation.zoo,
+              plugins: [functionPlot.plugins.zoomBox()],
+            });
+            break;
+          }
+          case "canvas": {
+            var shapesData = JSON.parse(canvas.resultado);
+            var shapesDataNormalized = this.normalizeShapesData(shapesData);
+            let bounding = this.getBounding();
+            this.cleanPlot();
+            this.instance = functionPlot({
+              target: "#graph2D-container",
+              width: bounding.width,
+              height: bounding.height,
+              grid: this.settings.grid,
+              axis: this.settings.axis,
+              xAxis: {
+                scale: "linear",
+                domain: {
+                  initial: [-10, 10],
+                  type: "discrete",
                 },
-                data: $data
-            })
-        }
-        // Update Frame
-        $this.animation.timeout = setTimeout(function() {
-            $this.animation.currentFrame = ($this.animation.currentFrame + 1) % $this.animation.data.length;
-            $this.animation.animationFrame = requestAnimationFrame($this.updateFrame.bind($this));
-        }, 1000/ this.easeInOutCubic($this.animation.fps));
-    }
-
-    /**
-     * @name runAnimation
-     * @desc Run Shapes Animation
-     */
-    public runAnimation = function() {
-        if (this.animation.playing) return;
-        var $this = this;
-        $this.animation.playing = true;
-        $this.updateFrame();
-    }
-
-    /**
-     * @name pauseAnimation
-     * @desc Pause Shapes Animation
-     */
-    public pauseAnimation = function() {
-        var $this = this;
-        cancelAnimationFrame($this.animation.animationFrame);
-        clearTimeout($this.animation.timeout);
-        $this.animation.timeout = null;
-        $this.animation.playing = false;
-    }
-
-    /**
-     * @name stopAnimation
-     * @desc Stop Shapes Animation
-     */
-    public stopAnimation = function() {
-        var $this = this;
-        $this.pauseAnimation();
-        $this.animation.data = [];
-        $this.animation.currentFrame = 0;
-        $this.animation.init = false;
-        this.instance.removeAllGraphs();
-    }
-
-    /**
-     * @name decreaseSpeed
-     * @desc Decrease Speed Animation
-     */
-    public decreaseSpeed = function() {
-        var decrease = false;
-        if (this.animation.fps > 6) {
-            decrease = true;
-        }
-        if (decrease) {
-            if (this.animation.fps > 10) {
-                this.animation.fps -= 1;
-                this.animation.speedX = this.animation.fps / 10;
-            } else {
-                this.animation.fps -= 1;
-                this.animation.speedX = this.animation.fps / 10;
-            }
-            this.pauseAnimation();
-            this.runAnimation();
-        }
-    }
-    
-    /**
-     * @name restoreSpeed
-     * @desc Increase Speed Animation
-     */
-    public restoreSpeed = function() {
-        this.animation.fps = 10;
-        this.animation.speedX = 1;
-        this.pauseAnimation();
-        this.runAnimation();
-    }
-
-    /**
-     * @name increaseSpeed
-     * @desc Increase Speed Animation
-     */
-    public increaseSpeed = function() {
-        var increase = false;
-        if (this.animation.fps < 60) {
-            increase = true;
-        }
-        if (increase) {
-            if (this.animation.fps >= 10) {
-                this.animation.fps += 1;
-                this.animation.speedX = this.animation.fps / 10;
-            } else {
-                this.animation.fps += 1;
-                this.animation.speedX = this.animation.fps / 10;
+              },
+              data: shapesDataNormalized,
+              plugins: [functionPlot.plugins.zoomBox()],
+            });
+            break;
+          }
+          case "animacion": {
+            this.cleanPlot();
+            var animationData = canvas.resultado.map((res) => JSON.parse(res));
+            for (var frame of animationData) {
+              this.animation.data.push(this.normalizeShapesData(frame));
             }
-            this.pauseAnimation();
             this.runAnimation();
+            this.animation.init = true;
+            break;
+          }
         }
+      },
+      (error) => {}
+    );
+  }
+
+  /**
+   * Angular lifecycle hook.
+   * called after Angular has fully initialized a component's view.
+   */
+  ngAfterViewInit() {
+    if (!this.instance) {
+      let bounding = this.getBounding();
+      this.instance = functionPlot({
+        target: "#graph2D-container",
+        width: bounding.width,
+        height: bounding.height,
+        grid: this.settings.grid,
+        axis: this.settings.axis,
+        xAxis: {
+          scale: "linear",
+          domain: {
+            initial: [-10, 10],
+            type: "discrete",
+          },
+        },
+        data: [],
+      });
     }
-
-
-    /**
-     * @name toggleGrid
-     * @desc Show and Hide Grid
-     */
-    public toggleGrid = function () {
-        this.instance.toggleGrid();
-        this.settings.grid = !this.settings.grid;
+  }
+
+  /**
+   * Angular lifecycle hook.
+   * called when a directive, pipe, or service is destroyed.
+   */
+  ngOnDestroy() {
+    if (this.ghciServiceSub) {
+      this.ghciServiceSub.unsubscribe();
     }
-
-    /**
-     * @name toggleAxis
-     * @desc Show and Hide Axis
-     */
-    public toggleAxis = function () {
-        this.instance.toggleAxis();
-        this.settings.axis = !this.settings.axis;
+  }
+
+  /**
+   * On Resize Event.
+   */
+  onResize(event) {
+    let instance = this.instance;
+    let bounding = this.getBounding();
+    if (bounding.width > 0) {
+      instance.options.width = bounding.width;
+      instance.options.height = bounding.height;
+      instance.build();
     }
-
-    /**
-     * @name toggleTip
-     * @desc Show and Hide Tip
-     */
-    public toggleTip = function () {
-        this.instance.toggleTip();
-        this.settings.tip = !this.settings.tip;
+  }
+
+  /**
+   * @name getBounding
+   * @desc get the measures of the container of the graph
+   */
+  private getBounding = function () {
+    var { width, height } =
+      this.graph2DRef.nativeElement.getBoundingClientRect();
+    if (width === 0) {
+      width = document.getElementById("graph2D-container").querySelector("svg")
+        .width.baseVal.value;
+      height = document.getElementById("graph2D-container").querySelector("svg")
+        .height.baseVal.value;
     }
-
-    /**
-     * @name zoomOut
-     * @desc Zoom Out Button Control
-     */
-    public zoomOut = function () {
-        this.instance.zoomOut();
+    return { width, height };
+  };
+
+  /**
+   * @name updateFrame
+   * @desc update data for Function Plot and redraw the graph
+   */
+  public updateFrame = function () {
+    var $this = this;
+    var $data = $this.animation.data[$this.animation.currentFrame];
+    if ($this.instance) {
+      $this.instance.options.data = $data;
+      $this.instance.draw();
+    } else {
+      let bounding = $this.getBounding();
+      $this.instance = functionPlot({
+        target: "#graph2D-container",
+        grid: this.settings.grid,
+        axis: this.settings.axis,
+        width: bounding.width,
+        height: bounding.height,
+        xAxis: {
+          label: "x - axis",
+          scale: "linear",
+          domain: {
+            initial: [-10, 10],
+            type: "discrete",
+          },
+        },
+        data: $data,
+      });
     }
-    /**
-     * @name zoomIn
-     * @desc Zoom In Button Control 
-     */
-    public zoomIn = function () {
-        this.instance.zoomIn();
+    // Update Frame
+    $this.animation.timeout = setTimeout(function () {
+      $this.animation.currentFrame =
+        ($this.animation.currentFrame + 1) % $this.animation.data.length;
+      $this.animation.animationFrame = requestAnimationFrame(
+        $this.updateFrame.bind($this)
+      );
+    }, 1000 / this.easeInOutCubic($this.animation.fps));
+  };
+
+  /**
+   * @name runAnimation
+   * @desc Run Shapes Animation
+   */
+  public runAnimation = function () {
+    if (this.animation.playing) return;
+    var $this = this;
+    $this.animation.playing = true;
+    $this.updateFrame();
+  };
+
+  /**
+   * @name pauseAnimation
+   * @desc Pause Shapes Animation
+   */
+  public pauseAnimation = function () {
+    var $this = this;
+    cancelAnimationFrame($this.animation.animationFrame);
+    clearTimeout($this.animation.timeout);
+    $this.animation.timeout = null;
+    $this.animation.playing = false;
+  };
+
+  /**
+   * @name stopAnimation
+   * @desc Stop Shapes Animation
+   */
+  public stopAnimation = function () {
+    var $this = this;
+    $this.pauseAnimation();
+    $this.animation.data = [];
+    $this.animation.currentFrame = 0;
+    $this.animation.init = false;
+    this.instance.removeAllGraphs();
+  };
+
+  /**
+   * @name decreaseSpeed
+   * @desc Decrease Speed Animation
+   */
+  public decreaseSpeed = function () {
+    var decrease = false;
+    if (this.animation.fps > 6) {
+      decrease = true;
     }
-    /**
-     * @name recenterPlot
-     * @desc center the plot and it returns to the initial state.
-     */
-    public recenterPlot = function () {
-        this.instance.recenter();
+    if (decrease) {
+      if (this.animation.fps > 10) {
+        this.animation.fps -= 1;
+        this.animation.speedX = this.animation.fps / 10;
+      } else {
+        this.animation.fps -= 1;
+        this.animation.speedX = this.animation.fps / 10;
+      }
+      this.pauseAnimation();
+      this.runAnimation();
     }
-    /**
-     * @name cleanPlot
-     * @desc remove all the graph from the instance.
-     */
-    public cleanPlot = function () {
-        if (this.animation.playing) {
-            this.stopAnimation();
-        } else {
-            this.funciones = [];
-            this.conjunto = [];
-            this.id = 0;
-            this.instance.removeAllGraphs();
-        }
+  };
+
+  /**
+   * @name restoreSpeed
+   * @desc Increase Speed Animation
+   */
+  public restoreSpeed = function () {
+    this.animation.fps = 10;
+    this.animation.speedX = 1;
+    this.pauseAnimation();
+    this.runAnimation();
+  };
+
+  /**
+   * @name increaseSpeed
+   * @desc Increase Speed Animation
+   */
+  public increaseSpeed = function () {
+    var increase = false;
+    if (this.animation.fps < 60) {
+      increase = true;
     }
-
-    /**
-     * @name exportPlot
-     * @desc Download Plot as an SVG image.
-     */
-    public exportPlot = function() {
-        // Objects
-        var svg = document.querySelector('svg');
-        var canvas = document.createElement("canvas");
-
-        // Set dimensions of the image
-        var svgSize = svg.getBoundingClientRect();
-        canvas.width = svgSize.width;
-        canvas.height = svgSize.height;
-
-        // Convert SVG DOM structure to xml
-        var ctx = canvas.getContext('2d');
-        var data = new XMLSerializer().serializeToString(svg);
-
-        // URL Object used to parse, construct, normalise, and encode URLs.
-        var DOMURL = window.URL || (<any>window).webkitURL || window;
-
-        var img = new Image();
-        var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });
-        var url = DOMURL.createObjectURL(svgBlob);
-
-        img.onload = function () {
-            ctx.drawImage(img, 0, 0);
-            DOMURL.revokeObjectURL(url);
-
-            var imgURI = canvas
-                .toDataURL('image/png')
-                .replace('image/png', 'image/octet-stream');
-
-            triggerDownload(imgURI);
-        };
-        img.src = url;
+    if (increase) {
+      if (this.animation.fps >= 10) {
+        this.animation.fps += 1;
+        this.animation.speedX = this.animation.fps / 10;
+      } else {
+        this.animation.fps += 1;
+        this.animation.speedX = this.animation.fps / 10;
+      }
+      this.pauseAnimation();
+      this.runAnimation();
     }
-
-
-    /**
-     * @name normalizeRectData
-     * @desc Normalize Rectangle data for Function Plot Library 
-     * @param {Object} rectData Data of Rectangle to be normalized
-     * @returns {Object}
-     */
-    public normalizeRectData = function ($rectData) {
-        var $rectNormalized:any = {};
-        var $shape:any = {};
-        $shape.w = $rectData.w;
-        $shape.h = $rectData.h;
-        $shape.x = $rectData.x;
-        $shape.y = $rectData.y;
-        $rectData.color && ($shape.fill = $rectData.color);
-        $rectData.rot !== 'undefined' && ($shape.rotation = $rectData.rot);
-
-        $rectNormalized.shape = $shape;
-        $rectNormalized.graphType = 'shape';
-        $rectNormalized.shapeType = 'rect';
-    
-        return $rectNormalized;
+  };
+
+  /**
+   * @name toggleGrid
+   * @desc Show and Hide Grid
+   */
+  public toggleGrid = function () {
+    this.instance.toggleGrid();
+    this.settings.grid = !this.settings.grid;
+  };
+
+  /**
+   * @name toggleAxis
+   * @desc Show and Hide Axis
+   */
+  public toggleAxis = function () {
+    this.instance.toggleAxis();
+    this.settings.axis = !this.settings.axis;
+  };
+
+  /**
+   * @name toggleTip
+   * @desc Show and Hide Tip
+   */
+  public toggleTip = function () {
+    this.instance.toggleTip();
+    this.settings.tip = !this.settings.tip;
+  };
+
+  /**
+   * @name zoomOut
+   * @desc Zoom Out Button Control
+   */
+  public zoomOut = function () {
+    this.instance.zoomOut();
+  };
+  /**
+   * @name zoomIn
+   * @desc Zoom In Button Control
+   */
+  public zoomIn = function () {
+    this.instance.zoomIn();
+  };
+  /**
+   * @name recenterPlot
+   * @desc center the plot and it returns to the initial state.
+   */
+  public recenterPlot = function () {
+    this.instance.recenter();
+  };
+  /**
+   * @name cleanPlot
+   * @desc remove all the graph from the instance.
+   */
+  public cleanPlot = function () {
+    if (this.animation.playing) {
+      this.stopAnimation();
+    } else {
+      this.funciones = [];
+      this.conjunto = [];
+      this.id = 0;
+      this.instance.removeAllGraphs();
     }
-    /**
-     * @name normalizeCircleData
-     * @desc Normalize Circle data for Function Plot Library 
-     * @param {Object} circleData Data of Circle to be normalized
-     * @returns {Object}
-     */
-    public normalizeCircleData = function ($circleData) {
-        var $circleNormalized:any = {};
-        var $shape:any = {};
-        $shape.r = $circleData.r;
-        $shape.x = $circleData.x;
-        $shape.y = $circleData.y;
-        $circleData.color && ($shape.fill = $circleData.color);
-        $circleData.rot !== 'undefined' && ($shape.rotation = $circleData.rot);
-
-        $circleNormalized.shape = $shape;
-        $circleNormalized.graphType = 'shape';
-        $circleNormalized.shapeType = 'circle';
-    
-        return $circleNormalized;
+  };
+
+  /**
+   * @name exportPlot
+   * @desc Download Plot as an SVG image.
+   */
+  public exportPlot = function () {
+    // Objects
+    var svg = document.querySelector("svg");
+    var canvas = document.createElement("canvas");
+
+    // Set dimensions of the image
+    var svgSize = svg.getBoundingClientRect();
+    canvas.width = svgSize.width;
+    canvas.height = svgSize.height;
+
+    // Convert SVG DOM structure to xml
+    var ctx = canvas.getContext("2d");
+    var data = new XMLSerializer().serializeToString(svg);
+
+    // URL Object used to parse, construct, normalise, and encode URLs.
+    var DOMURL = window.URL || (<any>window).webkitURL || window;
+
+    var img = new Image();
+    var svgBlob = new Blob([data], { type: "image/svg+xml;charset=utf-8" });
+    var url = DOMURL.createObjectURL(svgBlob);
+
+    img.onload = function () {
+      ctx.drawImage(img, 0, 0);
+      DOMURL.revokeObjectURL(url);
+
+      var imgURI = canvas
+        .toDataURL("image/png")
+        .replace("image/png", "image/octet-stream");
+
+      triggerDownload(imgURI);
+    };
+    img.src = url;
+  };
+
+  /**
+   * @name normalizeRectData
+   * @desc Normalize Rectangle data for Function Plot Library
+   * @param {Object} rectData Data of Rectangle to be normalized
+   * @returns {Object}
+   */
+  public normalizeRectData = function ($rectData) {
+    var $rectNormalized: any = {};
+    var $shape: any = {};
+    $shape.w = $rectData.w;
+    $shape.h = $rectData.h;
+    $shape.x = $rectData.x;
+    $shape.y = $rectData.y;
+    $rectData.color && ($shape.fill = $rectData.color);
+    $rectData.rot !== "undefined" && ($shape.rotation = $rectData.rot);
+
+    $rectNormalized.shape = $shape;
+    $rectNormalized.graphType = "shape";
+    $rectNormalized.shapeType = "rect";
+
+    return $rectNormalized;
+  };
+  /**
+   * @name normalizeCircleData
+   * @desc Normalize Circle data for Function Plot Library
+   * @param {Object} circleData Data of Circle to be normalized
+   * @returns {Object}
+   */
+  public normalizeCircleData = function ($circleData) {
+    var $circleNormalized: any = {};
+    var $shape: any = {};
+    $shape.r = $circleData.r;
+    $shape.x = $circleData.x;
+    $shape.y = $circleData.y;
+    $circleData.color && ($shape.fill = $circleData.color);
+    $circleData.rot !== "undefined" && ($shape.rotation = $circleData.rot);
+
+    $circleNormalized.shape = $shape;
+    $circleNormalized.graphType = "shape";
+    $circleNormalized.shapeType = "circle";
+
+    return $circleNormalized;
+  };
+  /**
+   * @name normalizeTextData
+   * @desc Normalize Text data for Function Plot Library
+   * @param {Object} textData Data of Text to be normalized
+   * @returns {Object}
+   */
+  public normalizeTextData = function ($textData) {
+    var $textNormalized: any = {};
+    var $shape: any = {};
+    $shape.text = $textData.text;
+    $shape.size = $textData.size;
+    $shape.x = $textData.x;
+    $shape.y = $textData.y;
+    $textData.color && ($shape.fill = $textData.color);
+    $textData.rot !== "undefined" && ($shape.rotation = $textData.rot);
+
+    $textNormalized.shape = $shape;
+    $textNormalized.graphType = "shape";
+    $textNormalized.shapeType = "text";
+
+    return $textNormalized;
+  };
+  /**
+   * @name normalizeLineData
+   * @desc Normalize Line data for Function Plot Library
+   * @param {Object} lineData Data of Line to be normalized
+   * @returns {Object}
+   */
+  public normalizeLineData = function ($lineData) {
+    var $lineNormalized: any = {};
+    var $points = [];
+    for (var p of $lineData.pts) {
+      $points.push([p[0], p[1]]);
     }
-    /**
-     * @name normalizeTextData
-     * @desc Normalize Text data for Function Plot Library 
-     * @param {Object} textData Data of Text to be normalized
-     * @returns {Object}
-     */
-    public normalizeTextData = function ($textData) {
-        var $textNormalized:any = {};
-        var $shape:any = {};
-        $shape.text = $textData.text;
-        $shape.size = $textData.size;
-        $shape.x = $textData.x;
-        $shape.y = $textData.y;
-        $textData.color && ($shape.fill = $textData.color);
-        $textData.rot !== 'undefined' && ($shape.rotation = $textData.rot);
-
-        $textNormalized.shape = $shape;
-        $textNormalized.graphType = 'shape';
-        $textNormalized.shapeType = 'text';
-    
-        return $textNormalized;
+    $lineNormalized.points = $points;
+    $lineNormalized.stroke = $lineData.color;
+    $lineNormalized.rotation = $lineData.rot;
+    $lineNormalized.fnType = "points";
+    $lineNormalized.polylineType = "line";
+    $lineNormalized.graphType = "polyline";
+
+    return $lineNormalized;
+  };
+  /**
+   * @name normalizePolygonData
+   * @desc Normalize Polygon data for Function Plot Library
+   * @param {Object} textData Data of Polygon to be normalized
+   * @returns {Object}
+   */
+  public normalizePolygonData = function ($polygonData) {
+    var $polygonNormalized: any = {};
+    var $points = [];
+    for (var p of $polygonData.pts) {
+      $points.push([p[0], p[1]]);
     }
-    /**
-     * @name normalizeLineData
-     * @desc Normalize Line data for Function Plot Library 
-     * @param {Object} lineData Data of Line to be normalized
-     * @returns {Object}
-     */
-    public normalizeLineData = function ($lineData) {
-        var $lineNormalized:any = {};
-        var $points = []
-        for (var p of $lineData.pts) {
-            $points.push([p[0],p[1]]);
+    $polygonNormalized.points = $points;
+    $polygonNormalized.fill = $polygonData.color;
+    $polygonNormalized.rotation = $polygonData.rot;
+    $polygonNormalized.fnType = "points";
+    $polygonNormalized.polylineType = "polygon";
+    $polygonNormalized.graphType = "polyline";
+
+    return $polygonNormalized;
+  };
+
+  /**
+   * @name normalizeShapesData
+   * @desc Normalize Shapes data for Function Plot Library
+   * @param {Array} shapesData Data of Shapes to be normalized
+   * @returns {Array}
+   */
+  public normalizeShapesData = function (shapesData) {
+    var normalized: Array<Object> = [];
+    for (var shape of shapesData) {
+      switch (shape.kind) {
+        case "rect": {
+          normalized.push(this.normalizeRectData(shape));
+          break;
         }
-        $lineNormalized.points = $points;
-        $lineNormalized.stroke = $lineData.color;
-        $lineNormalized.rotation = $lineData.rot;
-        $lineNormalized.fnType = 'points';
-        $lineNormalized.polylineType = 'line';
-        $lineNormalized.graphType = 'polyline';
-    
-        return $lineNormalized;
-    }
-    /**
-     * @name normalizePolygonData
-     * @desc Normalize Polygon data for Function Plot Library 
-     * @param {Object} textData Data of Polygon to be normalized
-     * @returns {Object}
-     */
-    public normalizePolygonData = function ($polygonData) {
-        var $polygonNormalized:any = {};
-        var $points = []
-        for (var p of $polygonData.pts) {
-            $points.push([p[0],p[1]]);
+        case "circle": {
+          normalized.push(this.normalizeCircleData(shape));
+          break;
         }
-        $polygonNormalized.points = $points;
-        $polygonNormalized.fill = $polygonData.color;
-        $polygonNormalized.rotation = $polygonData.rot;
-        $polygonNormalized.fnType = 'points';
-        $polygonNormalized.polylineType = 'polygon';
-        $polygonNormalized.graphType = 'polyline';
-    
-        return $polygonNormalized;
-    }
-
-    /**
-     * @name normalizeShapesData
-     * @desc Normalize Shapes data for Function Plot Library 
-     * @param {Array} shapesData Data of Shapes to be normalized 
-     * @returns {Array}
-     */
-    public normalizeShapesData = function (shapesData) {
-        var normalized:Array<Object> = [];
-        for (var shape of shapesData) {
-            switch(shape.kind) { 
-                case 'rect': { 
-                    normalized.push(this.normalizeRectData(shape)); 
-                    break; 
-                } 
-                case 'circle': { 
-                    normalized.push(this.normalizeCircleData(shape)); 
-                    break; 
-                } 
-                case 'text': { 
-                    normalized.push(this.normalizeTextData(shape)); 
-                    break; 
-                }
-                case 'line': { 
-                    normalized.push(this.normalizeLineData(shape)); 
-                    break; 
-                }
-                case 'poly': { 
-                    normalized.push(this.normalizePolygonData(shape)); 
-                    break; 
-                } 
-            } 
+        case "text": {
+          normalized.push(this.normalizeTextData(shape));
+          break;
         }
-        return normalized;
-    }
-
-
-
-    getRandomArbitrary = function (min, max) {
-        return Math.round(Math.random() * (max - min) + min);
-    }
-
-    generarFuncion = function (graph) {
-        var funcionString = '';
-        var grafica;
-        for (var fun of graph.funs) {
-            funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + this.generarExpresion(fun.bdy) + '}\n' + funcionString;
-
-            if (fun.fun == graph.graph) {
-                funcionString += 'return ' + fun.fun + '(' + fun.args.join() + ');\n'
-                grafica = fun;
-            }
+        case "line": {
+          normalized.push(this.normalizeLineData(shape));
+          break;
         }
-        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
-
-        return funcionString;
+        case "poly": {
+          normalized.push(this.normalizePolygonData(shape));
+          break;
+        }
+      }
     }
+    return normalized;
+  };
 
-    generarExpresion = function (exp) {
-
-        var expresion = '';
-        if (exp.kind == 'cnd') {
-            expresion = ' (' + this.generarExpresion(exp.cond) + '?' + this.generarExpresion(exp.exp1) + ':' + this.generarExpresion(exp.exp2) + ') ';
-        } else if (exp.kind == 'bop') {
-            if (exp.op == '==') {
-                expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 ';
-            } else if (exp.op == '/=') {
-                expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) != 0';
-            } else if (exp.op == '^') {
-                expresion = ' Math.pow(' + this.generarExpresion(exp.exp1) + ',' + this.generarExpresion(exp.exp2) + ') ';
-            } else {
-                expresion = ' (' + this.generarExpresion(exp.exp1) + ')' + exp.op + '(' + this.generarExpresion(exp.exp2) + ') ';
-            }
-        } else if (exp.kind == 'uop') {
-            expresion = ' ' + exp.op + ' ' + this.generarExpresion(exp.exp) + ' ';
-        } else if (exp.kind == 'app') {
-	       	  	var mul = '';
-		
-			if (exp.fun == 'Math.tan' || exp.fun == 'tan') {
-				exp.fun = 'Math.tan'
-				mul = '*Math.PI/180'
-			} else if (exp.fun == 'Math.cos' || exp.fun == 'cos') {
-				exp.fun = 'Math.cos'
-				mul = '*Math.PI/180'
-			} else if (exp.fun == 'Math.sin' || exp.fun == 'sin') {
-				exp.fun = 'Math.sin'
-				mul = '*Math.PI/180'
-			} else if (exp.fun == 'red') {
-				exp.fun = 'Math.round'
-			}else if (exp.fun == 'sqrt'){
-                	        exp.fun = 'Math.sqrt'
-            		}
-			
-			expresion = ' ' + exp.fun + '((' + exp.args.map(e => this.generarExpresion(e)).join() + ')'+ mul +') ';
-            
-
-        } else if (exp.kind == 'tup') {
-            expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
-        } else if (exp.kind == 'lit') {
-            expresion = ' ' + exp.val + ' ';
-        } else if (exp.kind == 'var') {
-            expresion = ' ' + exp.var + ' ';
-        } else {
-            expresion = ' undefined ';
-        }
+  getRandomArbitrary = function (min, max) {
+    return Math.round(Math.random() * (max - min) + min);
+  };
 
-        return expresion;
+  generarFuncion = function (graph) {
+    var funcionString = "";
+    var grafica;
+    for (var fun of graph.funs) {
+      funcionString =
+        "var " +
+        fun.fun +
+        " = function(" +
+        fun.args.join() +
+        "){\n return " +
+        this.generarExpresion(fun.bdy) +
+        "}\n" +
+        funcionString;
+
+      if (fun.fun == graph.graph) {
+        funcionString += "return " + fun.fun + "(" + fun.args.join() + ");\n";
+        grafica = fun;
+      }
+    }
+    funcionString = "(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
+
+    return funcionString;
+  };
+
+  generarExpresion = function (exp) {
+    var expresion = "";
+    if (exp.kind == "cnd") {
+      expresion =
+        " (" +
+        this.generarExpresion(exp.cond) +
+        "?" +
+        this.generarExpresion(exp.exp1) +
+        ":" +
+        this.generarExpresion(exp.exp2) +
+        ") ";
+    } else if (exp.kind == "bop") {
+      if (exp.op == "==") {
+        expresion =
+          " Math.abs((" +
+          this.generarExpresion(exp.exp1) +
+          ") - (" +
+          this.generarExpresion(exp.exp2) +
+          ")) == 0 ";
+      } else if (exp.op == "/=") {
+        expresion =
+          " Math.abs((" +
+          this.generarExpresion(exp.exp1) +
+          ") - (" +
+          this.generarExpresion(exp.exp2) +
+          ")) != 0";
+      } else if (exp.op == "^") {
+        expresion =
+          " Math.pow(" +
+          this.generarExpresion(exp.exp1) +
+          "," +
+          this.generarExpresion(exp.exp2) +
+          ") ";
+      } else {
+        expresion =
+          " (" +
+          this.generarExpresion(exp.exp1) +
+          ")" +
+          exp.op +
+          "(" +
+          this.generarExpresion(exp.exp2) +
+          ") ";
+      }
+    } else if (exp.kind == "uop") {
+      expresion = " " + exp.op + " " + this.generarExpresion(exp.exp) + " ";
+    } else if (exp.kind == "app") {
+      var mul = "";
+
+      if (exp.fun == "Math.tan" || exp.fun == "tan") {
+        exp.fun = "Math.tan";
+        mul = "*Math.PI/180";
+      } else if (exp.fun == "Math.cos" || exp.fun == "cos") {
+        exp.fun = "Math.cos";
+        mul = "*Math.PI/180";
+      } else if (exp.fun == "Math.sin" || exp.fun == "sin") {
+        exp.fun = "Math.sin";
+        mul = "*Math.PI/180";
+      } else if (exp.fun == "red") {
+        exp.fun = "Math.round";
+      } else if (exp.fun == "sqrt") {
+        exp.fun = "Math.sqrt";
+      }
+
+      expresion =
+        " " +
+        exp.fun +
+        "((" +
+        exp.args.map((e) => this.generarExpresion(e)).join() +
+        ")" +
+        mul +
+        ") ";
+    } else if (exp.kind == "tup") {
+      expresion =
+        " (" + exp.exps.map((e) => this.generarExpresion(e)).join() + ") ";
+    } else if (exp.kind == "lit") {
+      expresion = " " + exp.val + " ";
+    } else if (exp.kind == "var") {
+      expresion = " " + exp.var + " ";
+    } else {
+      expresion = " undefined ";
     }
 
+    return expresion;
+  };
 
-
-// nueva
-createListFunction = function (graph) {
-    var funcionString = '';
+  // nueva
+  createListFunction = function (graph) {
+    var funcionString = "";
     var grafica;
     var funciones = [];
     var j = 0;
     while (graph.funs[j].fun != graph.graph) {
-        j += 1;
+      j += 1;
     }
 
     var fun1 = graph.funs[j];
     var arrayFunction = [];
     var nameFun = [];
     nameFun.push(fun1.fun);
-    funciones = this.armarFuncion(fun1.bdy,graph,nameFun);
-    for (var funs of funciones){
-        for (var fun of graph.funs){
-            if (fun.fun != fun1.fun){
-                funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + this.generarExpresion(fun.bdy) + '}\n' + funcionString;
-            }
+    funciones = this.armarFuncion(fun1.bdy, graph, nameFun);
+    for (var funs of funciones) {
+      for (var fun of graph.funs) {
+        if (fun.fun != fun1.fun) {
+          funcionString =
+            "var " +
+            fun.fun +
+            " = function(" +
+            fun.args.join() +
+            "){\n return " +
+            this.generarExpresion(fun.bdy) +
+            "}\n" +
+            funcionString;
         }
-
-        funcionString = 'var ' + fun1.fun + ' = function(' + fun1.args.join() + '){\n return ' + funs + '}\n' + funcionString;
-        funcionString += ';return ' + fun1.fun + '(' + fun1.args.join() + ');\n'
-        grafica = fun1;
-        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
-        
-        arrayFunction.push(funcionString);   
-        var funcionString = '';
+      }
+
+      funcionString =
+        "var " +
+        fun1.fun +
+        " = function(" +
+        fun1.args.join() +
+        "){\n return " +
+        funs +
+        "}\n" +
+        funcionString;
+      funcionString += ";return " + fun1.fun + "(" + fun1.args.join() + ");\n";
+      grafica = fun1;
+      funcionString =
+        "(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
+
+      arrayFunction.push(funcionString);
+      var funcionString = "";
     }
     return arrayFunction;
-}
+  };
 
-armarFuncion = function (exp,graph,nameFun){
-    var lisArm = this.generateFunctionAndExp(exp,graph,nameFun);
+  armarFuncion = function (exp, graph, nameFun) {
+    var lisArm = this.generateFunctionAndExp(exp, graph, nameFun);
     var lisFun = [];
-    for(var lis of lisArm){
-        var aux = '';
-        if(lis[0] == 'N'){
-            aux = lis[1];
-        }else{
-            aux = '('+lis[0]+' ? '+lis[1]+' : undefined )';
-        }
-        lisFun.push(aux);
+    for (var lis of lisArm) {
+      var aux = "";
+      if (lis[0] == "N") {
+        aux = lis[1];
+      } else {
+        aux = "(" + lis[0] + " ? " + lis[1] + " : undefined )";
+      }
+      lisFun.push(aux);
     }
-    return lisFun
-}
+    return lisFun;
+  };
 
-
-generateFunctionAndExp = function (exp,graph,namefun6) {
+  generateFunctionAndExp = function (exp, graph, namefun6) {
     var myList = [];
     // devuelvo lista con tupla (cond,funcion)
-    if (exp.kind == 'cnd') {
-        var lisA = this.generateFunctionAndExp(exp.exp1,graph,namefun6);
-        var lisB = this.generateFunctionAndExp(exp.exp2,graph,namefun6);
-        var cond = this.createListExp(exp.cond);
-        var g = this.createListExp(exp.cond);
-        
-        var cond2 = g.splice(1);
-        var union = g[0]
-
-
-        for(var a of cond2){
-            union = '('+union+' && '+a+')';
+    if (exp.kind == "cnd") {
+      var lisA = this.generateFunctionAndExp(exp.exp1, graph, namefun6);
+      var lisB = this.generateFunctionAndExp(exp.exp2, graph, namefun6);
+      var cond = this.createListExp(exp.cond);
+      var g = this.createListExp(exp.cond);
+
+      var cond2 = g.splice(1);
+      var union = g[0];
+
+      for (var a of cond2) {
+        union = "(" + union + " && " + a + ")";
+      }
+      for (var fun1 of lisA) {
+        var aux121 = [];
+        if (fun1[0] == "N") {
+          if (cond.length == 0) {
+            aux121[0] = "N";
+          } else {
+            aux121[0] = union;
+          }
+        } else {
+          aux121[0] = "(" + fun1[0] + " && " + union + ")";
         }
-        for (var fun1 of lisA){
-            var aux121 = [];
-            if(fun1[0] == 'N'){
-                if(cond.length == 0){
-                    aux121[0]='N';
-                }else{
-                    aux121[0]=union;
-                }
-            }else{ 
-                aux121[0]= '('+fun1[0]+' && '+union+ ')';
+        aux121[1] = fun1[1];
+        myList.push(aux121);
+      }
+      for (var fun2 of lisB) {
+        if (cond.length != 0) {
+          for (var condi of cond) {
+            var aux123 = [];
+            aux123[1] = fun2[1];
+            if (fun2[0] == "N") {
+              aux123[0] = "!(" + condi + ")";
+            } else {
+              aux123[0] = "(" + fun2[0] + " && !(" + condi + "))";
             }
-            aux121[1] = fun1[1];
-            myList.push(aux121);
+            myList.push(aux123);
+          }
+        } else {
+          myList.push(fun2);
         }
-        for (var fun2 of lisB){
-            if(cond.length != 0){
-                for (var condi of cond){
-                    var aux123 = [];
-                    aux123[1]=fun2[1];
-                    if(fun2[0] == 'N'){
-                            aux123[0]='!('+condi+')';
-                    }else{
-                        aux123[0] = '('+fun2[0]+' && !('+condi+'))';
-                    }
-                    myList.push(aux123);
-                }
-            }else{
-                myList.push(fun2);
+      }
+    } else if (exp.kind == "bop") {
+      if (exp.op == "^") {
+        var lisA1 = this.generateFunctionAndExp(exp.exp1, graph, namefun6);
+        var lisB1 = this.generateFunctionAndExp(exp.exp2, graph, namefun6);
+        var aux1 = [];
+        for (var f1 of lisA1) {
+          for (var f2 of lisB1) {
+            var aux11 = "Math.pow(" + f1[1] + " , " + f2[1] + ")";
+            var aux21;
+            if (f2[0] == "N" && f1[0] == "N") {
+              aux21 = "N";
+            } else if (f2[0] == "N") {
+              aux21 = f1[0];
+            } else if (f1[0] == "N") {
+              aux21 = f2[0];
+            } else {
+              aux21 = "(" + f1[0] + " && " + f2[0] + ")";
             }
+            aux1[0] = aux21;
+            aux1[1] = aux11;
+            myList.push(aux1);
+          }
         }
-        
-    } else if (exp.kind == 'bop') {
-        
-        if (exp.op == '^') {
-            var lisA1 = this.generateFunctionAndExp(exp.exp1,graph,namefun6);
-            var lisB1 = this.generateFunctionAndExp(exp.exp2,graph,namefun6);
-            var aux1 = [];
-            for (var f1 of lisA1){
-                for (var f2 of lisB1){
-                    var aux11 = 'Math.pow('+f1[1]+' , '+f2[1]+')';
-                    var aux21;
-                    if ((f2[0] == 'N') && (f1[0] == 'N')){
-                        aux21 = 'N'
-                    }else if(f2[0] == 'N'){
-                        aux21=f1[0]
-                    }else if(f1[0] == 'N'){
-                        aux21=f2[0]
-                    }else{
-                        aux21= '('+f1[0]+' && '+f2[0]+')';
-                    }
-                    aux1[0]= aux21;
-                    aux1[1] = aux11;
-                    myList.push(aux1);
-                }
-            }
-        
-
-        }else {
-
-            var lisA2 = this.generateFunctionAndExp(exp.exp1,graph,namefun6);
-            var lisB2 = this.generateFunctionAndExp(exp.exp2,graph,namefun6);
-            var aux2 = [];
-            for (var f1 of lisA2){
-                for (var f2 of lisB2){
-                    var aux12 = '(('+f1[1]+')'+exp.op+'('+f2[1]+'))';
-                    var aux22
-                    if ((f2[0] == 'N') && (f1[0] == 'N')){
-                        aux22 = 'N'
-                    }else if (f2[0] == 'N'){
-                        aux22 =f1[0]
-                    }else if (f1[0] == 'N'){
-                        aux22 =f2[0]
-                    }else{ 
-                        aux22= '('+f1[0]+' && '+f2[0]+')';
-                    }
-                    aux2[0]= aux22;
-                    aux2[1] = aux12;
-                    myList.push(aux2);
-
-                }
+      } else {
+        var lisA2 = this.generateFunctionAndExp(exp.exp1, graph, namefun6);
+        var lisB2 = this.generateFunctionAndExp(exp.exp2, graph, namefun6);
+        var aux2 = [];
+        for (var f1 of lisA2) {
+          for (var f2 of lisB2) {
+            var aux12 = "((" + f1[1] + ")" + exp.op + "(" + f2[1] + "))";
+            var aux22;
+            if (f2[0] == "N" && f1[0] == "N") {
+              aux22 = "N";
+            } else if (f2[0] == "N") {
+              aux22 = f1[0];
+            } else if (f1[0] == "N") {
+              aux22 = f2[0];
+            } else {
+              aux22 = "(" + f1[0] + " && " + f2[0] + ")";
             }
+            aux2[0] = aux22;
+            aux2[1] = aux12;
+            myList.push(aux2);
+          }
         }
-    } else if (exp.kind == 'uop') {
-        var lisA3 = this.generateFunctionAndExp(exp.exp,graph,namefun6);
-        var aux3 = [];
-        for (var f1 of lisA3){
-                var aux13 = ' '+exp.op+' '+f1[1]+' ';               
-                aux3[0]= f1[0];
-                aux3[1] = aux13;
-                myList.push(aux3);   
-        }
-    } else if (exp.kind == 'app') {       
-        if ((exp.fun == 'Math.cos') || (exp.fun == 'cos')) {
-            var aux4 = [];
-            var aux14 = 'Math.cos(('+ exp.args.map(e => this.generarExpresion(e)).join() +')*Math.PI/180)';
-            var aux24 = 'N'
-            aux4[0]= aux24;
-            aux4[1] = aux14;
-            myList.push(aux4);           
-        } else if ((exp.fun == 'Math.sin') || (exp.fun == 'sin')) {
-            var aux5 = [];
-            var aux15 = 'Math.sin(('+ exp.args.map(e => this.generarExpresion(e)).join() +')*Math.PI/180)';
-            var aux25 = 'N'
-            aux5[0]= aux25;
-            aux5[1] = aux15;
-            myList.push(aux5);
-        } else if ((exp.fun == 'Math.tan') || (exp.fun == 'tan')) {
-            var aux5 = [];
-            var aux15 = 'Math.tan(('+ exp.args.map(e => this.generarExpresion(e)).join() +')*Math.PI/180)';
-            var aux25 = 'N'
-            aux5[0]= aux25;
-            aux5[1] = aux15;
-            myList.push(aux5);
-        } else if ((exp.fun == 'Math.PI') || (exp.fun == 'pi')) {
-            var aux5 = [];
-            var aux15 = 'Math.PI';
-            var aux25 = 'N'
-            aux5[0]= aux25;
-            aux5[1] = aux15;
-            myList.push(aux5);
-        } else if ((exp.fun == 'Math.round') || (exp.fun == 'red')){
-            var aux6 = [];
-            var aux16 = 'Math.round('+ exp.args.map(e => this.generarExpresion(e)).join() +')';
-            var aux26 = 'N'
-            aux6[0]= aux26;
-            aux6[1] = aux16;
-            myList.push(aux6);
-        }else if ((exp.fun == 'Math.sqrt') || (exp.fun == 'sqrt')){
-            var aux7 = [];
-            var aux17 = 'Math.sqrt('+ exp.args.map(e => this.generarExpresion(e)).join() +')';
-            var aux27 = 'N'
-            aux7[0]= aux27;
-            aux7[1] = aux17;
-            myList.push(aux7);
+      }
+    } else if (exp.kind == "uop") {
+      var lisA3 = this.generateFunctionAndExp(exp.exp, graph, namefun6);
+      var aux3 = [];
+      for (var f1 of lisA3) {
+        var aux13 = " " + exp.op + " " + f1[1] + " ";
+        aux3[0] = f1[0];
+        aux3[1] = aux13;
+        myList.push(aux3);
+      }
+    } else if (exp.kind == "app") {
+      if (exp.fun == "Math.cos" || exp.fun == "cos") {
+        var aux4 = [];
+        var aux14 =
+          "Math.cos((" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")*Math.PI/180)";
+        var aux24 = "N";
+        aux4[0] = aux24;
+        aux4[1] = aux14;
+        myList.push(aux4);
+      } else if (exp.fun == "Math.sin" || exp.fun == "sin") {
+        var aux5 = [];
+        var aux15 =
+          "Math.sin((" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")*Math.PI/180)";
+        var aux25 = "N";
+        aux5[0] = aux25;
+        aux5[1] = aux15;
+        myList.push(aux5);
+      } else if (exp.fun == "Math.tan" || exp.fun == "tan") {
+        var aux5 = [];
+        var aux15 =
+          "Math.tan((" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")*Math.PI/180)";
+        var aux25 = "N";
+        aux5[0] = aux25;
+        aux5[1] = aux15;
+        myList.push(aux5);
+      } else if (exp.fun == "Math.PI" || exp.fun == "pi") {
+        var aux5 = [];
+        var aux15 = "Math.PI";
+        var aux25 = "N";
+        aux5[0] = aux25;
+        aux5[1] = aux15;
+        myList.push(aux5);
+      } else if (exp.fun == "Math.round" || exp.fun == "red") {
+        var aux6 = [];
+        var aux16 =
+          "Math.round(" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")";
+        var aux26 = "N";
+        aux6[0] = aux26;
+        aux6[1] = aux16;
+        myList.push(aux6);
+      } else if (exp.fun == "Math.sqrt" || exp.fun == "sqrt") {
+        var aux7 = [];
+        var aux17 =
+          "Math.sqrt(" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")";
+        var aux27 = "N";
+        aux7[0] = aux27;
+        aux7[1] = aux17;
+        myList.push(aux7);
         // }else if (exp.args[0].kind == 'app'){
         //     var aux101 = [];
         //     var aux1101 = exp.fun+'('+ exp.args.map(e => this.generarExpresion(e)).join() +')';
@@ -1216,7 +1318,6 @@ generateFunctionAndExp = function (exp,graph,namefun6) {
         //     aux101[0]= aux2101;
         //     aux101[1] = aux1101;
         //     myList.push(aux101);
-        
 
         // }else if(((exp.args[0].kind == 'cnd' || exp.args[0].kind == 'bop') && (exp.args[0].exp1.kind == 'app' || exp.args[0].exp2.kind == 'app' )) || (exp.args[0].kind == 'uop' && exp.args[0].exp.kind == 'app') ){
         //     var aux102 = [];
@@ -1225,574 +1326,669 @@ generateFunctionAndExp = function (exp,graph,namefun6) {
         //     aux102[0]= aux2102;
         //     aux102[1] = aux1102;
         //     myList.push(aux102);
-        } else if(JSON.stringify(exp.args[0]).indexOf("app") != -1){ 
-            exp.args[0] = this.recorrerArgumentos(exp.args[0]);
-            var aux102 = [];
-            var aux1102 = exp.fun+'('+ exp.args.map(e => this.generarExpresion(e)).join() +')';
-            var aux2102 = 'N'
-            aux102[0]= aux2102;
-            aux102[1] = aux1102;
-            myList.push(aux102);        
-        }else{ 
-
-               
-
-            var nomFun = exp.fun+exp.args.map(e => this.generarExpresion(e)).join()
-            if(!namefun6.includes(nomFun)){
-                var ListnameFNew = namefun6;
-
-                ListnameFNew.push(nomFun);
-                for (var fun5 of graph.funs){
-                    if(fun5.fun == exp.fun){
-
-                        myList = this.generateFunctionAndExp(fun5.bdy,graph,ListnameFNew);
-                        for(var iter of myList){
-                            iter[1] = iter[1].replace(/x/g,exp.args.map(e => this.generarExpresion(e)).join())
-                        }
-
-
-                    }
-                }
-            }else{
-
-                var aux76 = [];
-                aux76[0] = 'N';
-                aux76[1] = exp.fun+'('+exp.args.map(e => this.generarExpresion(e)).join()+')';
-                myList.push(aux76);
+      } else if (JSON.stringify(exp.args[0]).indexOf("app") != -1) {
+        exp.args[0] = this.recorrerArgumentos(exp.args[0]);
+        var aux102 = [];
+        var aux1102 =
+          exp.fun +
+          "(" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")";
+        var aux2102 = "N";
+        aux102[0] = aux2102;
+        aux102[1] = aux1102;
+        myList.push(aux102);
+      } else {
+        var nomFun =
+          exp.fun + exp.args.map((e) => this.generarExpresion(e)).join();
+        if (!namefun6.includes(nomFun)) {
+          var ListnameFNew = namefun6;
+
+          ListnameFNew.push(nomFun);
+          for (var fun5 of graph.funs) {
+            if (fun5.fun == exp.fun) {
+              myList = this.generateFunctionAndExp(
+                fun5.bdy,
+                graph,
+                ListnameFNew
+              );
+              for (var iter of myList) {
+                iter[1] = iter[1].replace(
+                  /x/g,
+                  exp.args.map((e) => this.generarExpresion(e)).join()
+                );
+              }
             }
+          }
+        } else {
+          var aux76 = [];
+          aux76[0] = "N";
+          aux76[1] =
+            exp.fun +
+            "(" +
+            exp.args.map((e) => this.generarExpresion(e)).join() +
+            ")";
+          myList.push(aux76);
         }
-        
-    } else if (exp.kind == 'tup') {
-        var lisA7 = this.generateFunctionAndExp(exp.exps,graph,namefun6);
-        for (var f of lisA7){
-            var aux65 = [];
-            aux65[1] = '('+f[1]+')';
-            aux65[0] = f[0];
-            myList.push(aux65);
-        }
-       //Es esto o las combinaciones
-       // expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
-    } else if (exp.kind == 'lit') {
-        var aux8 = [];
-        aux8[0] = 'N';
-        aux8[1] = ' ' + exp.val + ' ';
-        myList.push(aux8);
-    } else if (exp.kind == 'var') {
-
-        var aux9 = [];
-        aux9[0] = 'N';
-        aux9[1] = ' ' + exp.var + ' ';
-        myList.push(aux9);
+      }
+    } else if (exp.kind == "tup") {
+      var lisA7 = this.generateFunctionAndExp(exp.exps, graph, namefun6);
+      for (var f of lisA7) {
+        var aux65 = [];
+        aux65[1] = "(" + f[1] + ")";
+        aux65[0] = f[0];
+        myList.push(aux65);
+      }
+      //Es esto o las combinaciones
+      // expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
+    } else if (exp.kind == "lit") {
+      var aux8 = [];
+      aux8[0] = "N";
+      aux8[1] = " " + exp.val + " ";
+      myList.push(aux8);
+    } else if (exp.kind == "var") {
+      var aux9 = [];
+      aux9[0] = "N";
+      aux9[1] = " " + exp.var + " ";
+      myList.push(aux9);
     } else {
-        var aux54 = [];
-        aux54[0]= 'N';
-        aux54[1]='undefined';
-        myList.push(aux54);
+      var aux54 = [];
+      aux54[0] = "N";
+      aux54[1] = "undefined";
+      myList.push(aux54);
     }
 
     return myList;
-}
-
-recorrerArgumentos = function(argumento){
-    if(argumento.kind == 'app'){
-        if ((argumento.fun == 'Math.cos') || (argumento.fun == 'cos')){
-            argumento.fun = 'Math.cos';
-        }else if((argumento.fun == 'Math.sin') || (argumento.fun == 'sin')){
-            argumento.fun = 'Math.sin';
-        }else if((argumento.fun == 'Math.tan') || (argumento.fun == 'tan')){
-            argumento.fun = 'Math.tan';	    
-        }else if((argumento.fun == 'Math.round') || (argumento.fun == 'red')){
-            argumento.fun = 'Math.round';
-        }else if((argumento.fun == 'Math.sqrt') || (argumento.fun == 'sqrt')){
-            argumento.fun = 'Math.sqrt';
-        }
-
-    }else if(argumento.kind == 'cnd'){
-        this.recorrerArgumentos(argumento.exp1)
-        this.recorrerArgumentos(argumento.exp2)
-    }else if(argumento.kind == 'bop'){
-        this.recorrerArgumentos(argumento.exp1)
-        this.recorrerArgumentos(argumento.exp2)
-    }else if(argumento.kind == 'uop'){
-        this.recorrerArgumentos(argumento.exp1)
+  };
+
+  recorrerArgumentos = function (argumento) {
+    if (argumento.kind == "app") {
+      if (argumento.fun == "Math.cos" || argumento.fun == "cos") {
+        argumento.fun = "Math.cos";
+      } else if (argumento.fun == "Math.sin" || argumento.fun == "sin") {
+        argumento.fun = "Math.sin";
+      } else if (argumento.fun == "Math.tan" || argumento.fun == "tan") {
+        argumento.fun = "Math.tan";
+      } else if (argumento.fun == "Math.round" || argumento.fun == "red") {
+        argumento.fun = "Math.round";
+      } else if (argumento.fun == "Math.sqrt" || argumento.fun == "sqrt") {
+        argumento.fun = "Math.sqrt";
+      }
+    } else if (argumento.kind == "cnd") {
+      this.recorrerArgumentos(argumento.exp1);
+      this.recorrerArgumentos(argumento.exp2);
+    } else if (argumento.kind == "bop") {
+      this.recorrerArgumentos(argumento.exp1);
+      this.recorrerArgumentos(argumento.exp2);
+    } else if (argumento.kind == "uop") {
+      this.recorrerArgumentos(argumento.exp1);
     }
     return argumento;
-}
-/////////////////////
+  };
+  /////////////////////
 
-createListExp = function (exp) {
-    var expresion = '';
+  createListExp = function (exp) {
+    var expresion = "";
     var funcione = [];
-    if (exp.kind == 'cnd') {
-            funcione = this.createListExp(exp.cond);
-    } else if (exp.kind == 'bop') {
-        if (exp.op == '==') {
-            expresion = ' Math.abs((' + this.createListExp(exp.exp1)[0] + ') - (' + this.createListExp(exp.exp2)[0] + ')) == 0 ';
-            if(exp.exp1.kind == 'lit'){
-                this.valores.push(exp.exp1.val)
-            }
-            if(exp.exp2.kind == 'lit'){
-                this.valores.push(exp.exp2.val)
-            }
-            funcione.push(expresion)
-
-        } else if (exp.op == '/=') {
-            expresion = ' Math.abs((' + this.createListExp(exp.exp1) + ') - (' + this.createListExp(exp.exp2) + ')) != 0';
-            funcione.push(expresion)
-
-        } else if (exp.op == '^') {
-            expresion = ' Math.pow(' + this.createListExp(exp.exp1) + ',' + this.createListExp(exp.exp2) + ') ';
-            funcione.push(expresion)
-
-        } else if (exp.op == '&&'){
-            
-            for (var atr of this.createListExp(exp.exp1)){
-                funcione.push(atr)
-            }
-            for (var atr2 of this.createListExp(exp.exp2)){
-                funcione.push(atr2)
-            }
-        }else if (exp.op == 'or'){
-            funcione.push('!'+this.createListExp(exp.exp1))
-            funcione.push('!'+this.createListExp(exp.exp2))
-        }else{
-            var lis1 = this.createListExp(exp.exp1)
-            var lis2 = this.createListExp(exp.exp2)
-            for(var expes1 of lis1){
-                for (var expes2 of lis2){
-                    expresion = ' ((' + expes1 + ')' + exp.op + '(' + expes2 + ') )';
-                    funcione.push(expresion)
-                }
-            }
+    if (exp.kind == "cnd") {
+      funcione = this.createListExp(exp.cond);
+    } else if (exp.kind == "bop") {
+      if (exp.op == "==") {
+        expresion =
+          " Math.abs((" +
+          this.createListExp(exp.exp1)[0] +
+          ") - (" +
+          this.createListExp(exp.exp2)[0] +
+          ")) == 0 ";
+        if (exp.exp1.kind == "lit") {
+          this.valores.push(exp.exp1.val);
         }
-    } else if (exp.kind == 'uop') {
-        expresion = ' ' + exp.op + ' ' + this.createListExp(exp.exp) + ' ';
-        funcione.push(expresion)
-
-    } else if (exp.kind == 'app') {
-
-        if (exp.fun == 'Math.cos') {
-            exp.fun = 'Math.cos'
-            expresion = ' ' + exp.fun + '((' + exp.args.map(e => this.generarExpresion(e)).join() + ')*Math.PI/180) ';
-            funcione.push(expresion)
-
-        } else if (exp.fun == 'Math.sin') {
-            exp.fun = 'Math.sin'
-            expresion = ' ' + exp.fun + '((' + exp.args.map(e => this.generarExpresion(e)).join() + ')*Math.PI/180) ';
-            funcione.push(expresion)
-        } else if (exp.fun == 'Math.tan') {
-            exp.fun = 'Math.tan'
-            expresion = ' ' + exp.fun + '((' + exp.args.map(e => this.generarExpresion(e)).join() + ')*Math.PI/180) ';
-            funcione.push(expresion)
-        } else if ((exp.fun == 'Math.PI') || (exp.fun == 'pi')) {
-            exp.fun = 'Math.PI'
-            funcione.push(exp.fun)
-
-        } else if (exp.fun == 'Math.round') {
-            exp.fun = 'Math.round'
-            expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresion(e)).join() + ') ';
-            funcione.push(expresion)
-
-        } else if (exp.fun == 'Math.sqrt') {
-            exp.fun = 'Math.sqrt'
-            expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresion(e)).join() + ') ';
-            funcione.push(expresion)
-
-        }else{
-            expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresion(e)).join() + ') ';
-            funcione.push(expresion)
+        if (exp.exp2.kind == "lit") {
+          this.valores.push(exp.exp2.val);
         }
-
-    } else if (exp.kind == 'tup') {
-        expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
-        funcione.push(expresion)
-
-    } else if (exp.kind == 'lit') {
-        expresion = ' ' + exp.val + ' ';
-        this.valores.push(exp.val)
-        funcione.push(expresion)
-
-    } else if (exp.kind == 'var') {
-
-        expresion = ' ' + exp.var + ' ';
-        funcione.push(expresion)
-
+        funcione.push(expresion);
+      } else if (exp.op == "/=") {
+        expresion =
+          " Math.abs((" +
+          this.createListExp(exp.exp1) +
+          ") - (" +
+          this.createListExp(exp.exp2) +
+          ")) != 0";
+        funcione.push(expresion);
+      } else if (exp.op == "^") {
+        expresion =
+          " Math.pow(" +
+          this.createListExp(exp.exp1) +
+          "," +
+          this.createListExp(exp.exp2) +
+          ") ";
+        funcione.push(expresion);
+      } else if (exp.op == "&&") {
+        for (var atr of this.createListExp(exp.exp1)) {
+          funcione.push(atr);
+        }
+        for (var atr2 of this.createListExp(exp.exp2)) {
+          funcione.push(atr2);
+        }
+      } else if (exp.op == "or") {
+        funcione.push("!" + this.createListExp(exp.exp1));
+        funcione.push("!" + this.createListExp(exp.exp2));
+      } else {
+        var lis1 = this.createListExp(exp.exp1);
+        var lis2 = this.createListExp(exp.exp2);
+        for (var expes1 of lis1) {
+          for (var expes2 of lis2) {
+            expresion = " ((" + expes1 + ")" + exp.op + "(" + expes2 + ") )";
+            funcione.push(expresion);
+          }
+        }
+      }
+    } else if (exp.kind == "uop") {
+      expresion = " " + exp.op + " " + this.createListExp(exp.exp) + " ";
+      funcione.push(expresion);
+    } else if (exp.kind == "app") {
+      if (exp.fun == "Math.cos") {
+        exp.fun = "Math.cos";
+        expresion =
+          " " +
+          exp.fun +
+          "((" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")*Math.PI/180) ";
+        funcione.push(expresion);
+      } else if (exp.fun == "Math.sin") {
+        exp.fun = "Math.sin";
+        expresion =
+          " " +
+          exp.fun +
+          "((" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")*Math.PI/180) ";
+        funcione.push(expresion);
+      } else if (exp.fun == "Math.tan") {
+        exp.fun = "Math.tan";
+        expresion =
+          " " +
+          exp.fun +
+          "((" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ")*Math.PI/180) ";
+        funcione.push(expresion);
+      } else if (exp.fun == "Math.PI" || exp.fun == "pi") {
+        exp.fun = "Math.PI";
+        funcione.push(exp.fun);
+      } else if (exp.fun == "Math.round") {
+        exp.fun = "Math.round";
+        expresion =
+          " " +
+          exp.fun +
+          "(" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ") ";
+        funcione.push(expresion);
+      } else if (exp.fun == "Math.sqrt") {
+        exp.fun = "Math.sqrt";
+        expresion =
+          " " +
+          exp.fun +
+          "(" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ") ";
+        funcione.push(expresion);
+      } else {
+        expresion =
+          " " +
+          exp.fun +
+          "(" +
+          exp.args.map((e) => this.generarExpresion(e)).join() +
+          ") ";
+        funcione.push(expresion);
+      }
+    } else if (exp.kind == "tup") {
+      expresion =
+        " (" + exp.exps.map((e) => this.generarExpresion(e)).join() + ") ";
+      funcione.push(expresion);
+    } else if (exp.kind == "lit") {
+      expresion = " " + exp.val + " ";
+      this.valores.push(exp.val);
+      funcione.push(expresion);
+    } else if (exp.kind == "var") {
+      expresion = " " + exp.var + " ";
+      funcione.push(expresion);
     } else {
-        expresion = 'undefined ';
-        funcione.push(expresion)
-
+      expresion = "undefined ";
+      funcione.push(expresion);
     }
     return funcione;
-}
-///////////////////// fin de nuevo
-
-
-     // Prueba 2019
-     generarFuncionDisc = function (graph) {
-        var funcionString = '';
-        var grafica;
-        var arrayFunction = [];
-        var fun = graph.funs[0];
-        var ListnameF = [];
-        ListnameF.push(fun.fun);
-        var funciones = this.generarExpresionDisc(fun.bdy,graph,ListnameF)
-        for (var funs of funciones){
-            funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + funs + '}\n' + funcionString;
-
-            if (fun.fun == graph.graph) {
-                funcionString += ';return ' + fun.fun + '(' + fun.args.join() + ');\n'
-                grafica = fun;
-            }
-            funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
-            arrayFunction.push(funcionString);
-            var funcionString = '';
-        }
-
+  };
+  ///////////////////// fin de nuevo
 
-        var arrayFunction1 = [arrayFunction[0]]
-        return arrayFunction;
+  // Prueba 2019
+  generarFuncionDisc = function (graph) {
+    var funcionString = "";
+    var grafica;
+    var arrayFunction = [];
+    var fun = graph.funs[0];
+    var ListnameF = [];
+    ListnameF.push(fun.fun);
+    var funciones = this.generarExpresionDisc(fun.bdy, graph, ListnameF);
+    for (var funs of funciones) {
+      funcionString =
+        "var " +
+        fun.fun +
+        " = function(" +
+        fun.args.join() +
+        "){\n return " +
+        funs +
+        "}\n" +
+        funcionString;
+
+      if (fun.fun == graph.graph) {
+        funcionString += ";return " + fun.fun + "(" + fun.args.join() + ");\n";
+        grafica = fun;
+      }
+      funcionString =
+        "(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
+      arrayFunction.push(funcionString);
+      var funcionString = "";
     }
 
-    generarExpresionDisc = function (exp,grap,ListnameF) {
-        var expresion = '';
-        var funcione = [];
-        if (exp.kind == 'cnd') {
-
-                var con1 = this.generarExpresionDisc(exp.cond,grap,ListnameF);
-                var con11 = '';
-                
-                for (var condi of con1){
-                    if (con11 == ''){
-                        con11 = condi;
-                    }else{
-                        con11 = '('+con11 +' && '+ condi +')';
-                    }
-                    
-                }
-                for (var funs of this.generarExpresionDisc(exp.exp1,grap,ListnameF)){ 
-                    funcione.push('('+con11+' ? '+ funs +' : undefined)');      
-                }
-                for (var funs2 of this.generarExpresionDisc(exp.exp2,grap,ListnameF)){ 
-                    for (var condi2 of con1){
-                        funcione.push('(!('+condi2+') ? '+ funs2 +' : undefined)');
-
-                    }   
-                }
-            
-            
-           
-        } else if (exp.kind == 'bop') {
-            if (exp.op == '==') {
-                expresion = ' Math.abs((' + this.generarExpresionDisc(exp.exp1,grap,ListnameF) + ') - (' + this.generarExpresionDisc(exp.exp2,grap,ListnameF) + ')) == 0 ';
-                if(exp.exp1.kind == 'lit'){
-                    this.valores.push(exp.exp1.val)
-                }
-                if(exp.exp2.kind == 'lit'){
-                    this.valores.push(exp.exp2.val)
-                }
-                funcione.push(expresion)
-
-            } else if (exp.op == '/=') {
-                expresion = ' Math.abs((' + this.generarExpresionDisc(exp.exp1,grap,ListnameF) + ') - (' + this.generarExpresionDisc(exp.exp2,grap,ListnameF) + ')) != 0';
-                funcione.push(expresion)
-
-            } else if (exp.op == '^') {
-                expresion = ' Math.pow(' + this.generarExpresionDisc(exp.exp1,grap,ListnameF) + ',' + this.generarExpresionDisc(exp.exp2,grap,ListnameF) + ') ';
-                funcione.push(expresion)
-
-            } else if (exp.op == '&&'){
-                
-                for (var atr of this.generarExpresionDisc(exp.exp1,grap,ListnameF)){
-                    funcione.push(atr)
-                }
-                for (var atr2 of this.generarExpresionDisc(exp.exp2,grap,ListnameF)){
-                    funcione.push(atr2)
-                }
-            }else if (exp.op == 'or'){
-                funcione.push('!'+this.generarExpresionDisc(exp.exp1,grap,ListnameF))
-                funcione.push('!'+this.generarExpresionDisc(exp.exp2,grap,ListnameF))
-            }else{
-                var lis1 = this.generarExpresionDisc(exp.exp1,grap,ListnameF)
-                var lis2 = this.generarExpresionDisc(exp.exp2,grap,ListnameF)
-                for(var expes1 of lis1){
-                    for (var expes2 of lis2){
-                        expresion = ' ((' + expes1 + ')' + exp.op + '(' + expes2 + ') )';
-                        funcione.push(expresion)
-                    }
-                }
+    var arrayFunction1 = [arrayFunction[0]];
+    return arrayFunction;
+  };
 
+  generarExpresionDisc = function (exp, grap, ListnameF) {
+    var expresion = "";
+    var funcione = [];
+    if (exp.kind == "cnd") {
+      var con1 = this.generarExpresionDisc(exp.cond, grap, ListnameF);
+      var con11 = "";
 
+      for (var condi of con1) {
+        if (con11 == "") {
+          con11 = condi;
+        } else {
+          con11 = "(" + con11 + " && " + condi + ")";
+        }
+      }
+      for (var funs of this.generarExpresionDisc(exp.exp1, grap, ListnameF)) {
+        funcione.push("(" + con11 + " ? " + funs + " : undefined)");
+      }
+      for (var funs2 of this.generarExpresionDisc(exp.exp2, grap, ListnameF)) {
+        for (var condi2 of con1) {
+          funcione.push("(!(" + condi2 + ") ? " + funs2 + " : undefined)");
+        }
+      }
+    } else if (exp.kind == "bop") {
+      if (exp.op == "==") {
+        expresion =
+          " Math.abs((" +
+          this.generarExpresionDisc(exp.exp1, grap, ListnameF) +
+          ") - (" +
+          this.generarExpresionDisc(exp.exp2, grap, ListnameF) +
+          ")) == 0 ";
+        if (exp.exp1.kind == "lit") {
+          this.valores.push(exp.exp1.val);
+        }
+        if (exp.exp2.kind == "lit") {
+          this.valores.push(exp.exp2.val);
+        }
+        funcione.push(expresion);
+      } else if (exp.op == "/=") {
+        expresion =
+          " Math.abs((" +
+          this.generarExpresionDisc(exp.exp1, grap, ListnameF) +
+          ") - (" +
+          this.generarExpresionDisc(exp.exp2, grap, ListnameF) +
+          ")) != 0";
+        funcione.push(expresion);
+      } else if (exp.op == "^") {
+        expresion =
+          " Math.pow(" +
+          this.generarExpresionDisc(exp.exp1, grap, ListnameF) +
+          "," +
+          this.generarExpresionDisc(exp.exp2, grap, ListnameF) +
+          ") ";
+        funcione.push(expresion);
+      } else if (exp.op == "&&") {
+        for (var atr of this.generarExpresionDisc(exp.exp1, grap, ListnameF)) {
+          funcione.push(atr);
+        }
+        for (var atr2 of this.generarExpresionDisc(exp.exp2, grap, ListnameF)) {
+          funcione.push(atr2);
+        }
+      } else if (exp.op == "or") {
+        funcione.push(
+          "!" + this.generarExpresionDisc(exp.exp1, grap, ListnameF)
+        );
+        funcione.push(
+          "!" + this.generarExpresionDisc(exp.exp2, grap, ListnameF)
+        );
+      } else {
+        var lis1 = this.generarExpresionDisc(exp.exp1, grap, ListnameF);
+        var lis2 = this.generarExpresionDisc(exp.exp2, grap, ListnameF);
+        for (var expes1 of lis1) {
+          for (var expes2 of lis2) {
+            expresion = " ((" + expes1 + ")" + exp.op + "(" + expes2 + ") )";
+            funcione.push(expresion);
+          }
+        }
+      }
+    } else if (exp.kind == "uop") {
+      expresion =
+        " " +
+        exp.op +
+        " " +
+        this.generarExpresionDisc(exp.exp, grap, ListnameF) +
+        " ";
+      funcione.push(expresion);
+    } else if (exp.kind == "app") {
+      if (exp.fun == "Math.cos") {
+        exp.fun = "Math.cos";
+        expresion =
+          " " +
+          exp.fun +
+          "(" +
+          exp.args
+            .map((e) => this.generarExpresionDisc(e, grap, ListnameF))
+            .join() +
+          ") ";
+        funcione.push(expresion);
+      } else if (exp.fun == "Math.sin") {
+        exp.fun = "Math.sin";
+        expresion =
+          " " +
+          exp.fun +
+          "(" +
+          exp.args
+            .map((e) => this.generarExpresionDisc(e, grap, ListnameF))
+            .join() +
+          ") ";
+        funcione.push(expresion);
+      } else if (exp.fun == "Math.round") {
+        exp.fun = "Math.round";
+        expresion =
+          " " +
+          exp.fun +
+          "(" +
+          exp.args
+            .map((e) => this.generarExpresionDisc(e, grap, ListnameF))
+            .join() +
+          ") ";
+        funcione.push(expresion);
+      } else if (exp.fun == "Math.sqrt") {
+        exp.fun = "Math.sqrt";
+        expresion =
+          " " +
+          exp.fun +
+          "(" +
+          exp.args
+            .map((e) => this.generarExpresionDisc(e, grap, ListnameF))
+            .join() +
+          ") ";
+        funcione.push(expresion);
+      } else {
+        if (!ListnameF.includes(exp.fun)) {
+          var ListnameFNew = ListnameF;
+          ListnameFNew.push(exp.fun);
+          for (var fun5 of grap.funs) {
+            if (fun5.fun == exp.fun) {
+              var funresul = this.generarExpresionDisc(
+                fun5.bdy,
+                grap,
+                ListnameFNew
+              );
+              for (var subfunciones of funresul) {
+                funcione.push(subfunciones);
+              }
             }
-        } else if (exp.kind == 'uop') {
-            expresion = ' ' + exp.op + ' ' + this.generarExpresionDisc(exp.exp,grap,ListnameF) + ' ';
-            funcione.push(expresion)
-
-        } else if (exp.kind == 'app') {
-
-			if (exp.fun == 'Math.cos') {
-                exp.fun = 'Math.cos'
-                expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresionDisc(e,grap,ListnameF)).join() + ') ';
-                funcione.push(expresion)
-
-			} else if (exp.fun == 'Math.sin') {
-                exp.fun = 'Math.sin'
-                expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresionDisc(e,grap,ListnameF)).join() + ') ';
-                funcione.push(expresion)
-
-			} else if (exp.fun == 'Math.round') {
-                exp.fun = 'Math.round'
-                expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresionDisc(e,grap,ListnameF)).join() + ') ';
-                funcione.push(expresion)
-
-            } else if (exp.fun == 'Math.sqrt') {
-                exp.fun = 'Math.sqrt'
-                expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresionDisc(e,grap,ListnameF)).join() + ') ';
-                funcione.push(expresion)
-    
-            }else{
-
-                if(!ListnameF.includes(exp.fun)){
-
-                    var ListnameFNew = ListnameF;
-                    ListnameFNew.push(exp.fun);
-                    for (var fun5 of grap.funs){
-
-                        if(fun5.fun == exp.fun){
-
-                            var funresul = this.generarExpresionDisc(fun5.bdy,grap,ListnameFNew);
-                            for (var subfunciones of funresul){
-                                funcione.push(subfunciones);
-                            }
-                            
-                        }
-                    }
-                }else{
-                    funcione.push(exp.fun);
-                }
-                
-            }
-
-        } else if (exp.kind == 'tup') {
-            expresion = ' (' + exp.exps.map(e => this.generarExpresionDisc(e,grap,ListnameF)).join() + ') ';
-            funcione.push(expresion)
-
-        } else if (exp.kind == 'lit') {
-            expresion = ' ' + exp.val + ' ';
-            this.valores.push(exp.val)
-            funcione.push(expresion)
-
-        } else if (exp.kind == 'var') {
-
-            expresion = ' ' + exp.var + ' ';
-            funcione.push(expresion)
-
+          }
         } else {
-            expresion = ' undefined ';
-            funcione.push(expresion)
-
+          funcione.push(exp.fun);
         }
-        return funcione;
+      }
+    } else if (exp.kind == "tup") {
+      expresion =
+        " (" +
+        exp.exps
+          .map((e) => this.generarExpresionDisc(e, grap, ListnameF))
+          .join() +
+        ") ";
+      funcione.push(expresion);
+    } else if (exp.kind == "lit") {
+      expresion = " " + exp.val + " ";
+      this.valores.push(exp.val);
+      funcione.push(expresion);
+    } else if (exp.kind == "var") {
+      expresion = " " + exp.var + " ";
+      funcione.push(expresion);
+    } else {
+      expresion = " undefined ";
+      funcione.push(expresion);
     }
-
-
-     //Prueba 2019 fin
-
-
-
-
-
-
-    //Nuevo 20-07-2018
-    
-
-    obtenerConjunto = function (grf) {
-
-        var setf = '\"sets\": {';
-        var dominio = '{\"conj\": {';
-        if (grf.dom == 'R') {
-            dominio += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"R\"";
-            setf += "\"fdom\": \"R\",";
-        } else if (grf.dom == 'Z') {
-            dominio += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Z\"";
-            setf += "\"fdom\": \"Z\",";
-        }/* else if (grf.dom == 'N') {
+    return funcione;
+  };
+
+  //Prueba 2019 fin
+
+  //Nuevo 20-07-2018
+
+  obtenerConjunto = function (grf) {
+    var setf = '"sets": {';
+    var dominio = '{"conj": {';
+    if (grf.dom == "R") {
+      dominio += '"radio": 0.3, "baseDom": "R", "dom": "R"';
+      setf += '"fdom": "R",';
+    } else if (grf.dom == "Z") {
+      dominio += '"radio": 2, "baseDom": "Z", "dom": "Z"';
+      setf += '"fdom": "Z",';
+    } /* else if (grf.dom == 'N') {
             dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"N\"";
             setf += "\"fdom\": \"N\",";
         }*/ else {
-            var nom = grf.dom;
-            if (Array.isArray(grf.sets[0][nom])) {
-                var arreglo = grf.sets[0][nom];
-                var arreglo2 = [];
-                for (var item of arreglo) {
-                    arreglo2.push("\"" + item + "\"");
-                }
-                dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"Numer\"";
-                setf += "\"fdom\": [" + arreglo2 + "], ";
-            } else {
-
-                dominio += this.recursivoDom(grf.sets, nom);
-                setf += "\"fdom\":\"function(x)\",";
-            }
+      var nom = grf.dom;
+      if (Array.isArray(grf.sets[0][nom])) {
+        var arreglo = grf.sets[0][nom];
+        var arreglo2 = [];
+        for (var item of arreglo) {
+          arreglo2.push('"' + item + '"');
         }
-        dominio += ", ";
-        if (grf.cod == 'R') {
-            dominio += "\"baseCod\": \"R\", \"cod\": \"R\" ,";
-            setf += "\"fcod\": \"R\"";
-        } else if (grf.cod == 'Z') {
-            dominio += "\"baseCod\": \"Z\", \"cod\": \"Z\" ,";
-            setf += "\"fcod\": \"Z\"";
-        } /*else if (grf.cod == 'N') {
+        dominio += '"radio":2, "baseDom": "N", "dom": "Numer"';
+        setf += '"fdom": [' + arreglo2 + "], ";
+      } else {
+        dominio += this.recursivoDom(grf.sets, nom);
+        setf += '"fdom":"function(x)",';
+      }
+    }
+    dominio += ", ";
+    if (grf.cod == "R") {
+      dominio += '"baseCod": "R", "cod": "R" ,';
+      setf += '"fcod": "R"';
+    } else if (grf.cod == "Z") {
+      dominio += '"baseCod": "Z", "cod": "Z" ,';
+      setf += '"fcod": "Z"';
+    } /*else if (grf.cod == 'N') {
             dominio += "\"baseCod\": \"N\", \"cod\": \"N\" ,";
             setf += "\"fcod\": \"N\"";
-        } */else {
-            var nom1 = grf.cod;
-
-            if (Array.isArray(grf.sets[0][nom1])) {
-                var arreglo3 = grf.sets[0][nom1];
-                var arreglo4 = [];
-                for (var item of arreglo3) {
-                    arreglo4.push("\"" + item + "\"");
-                }
-                dominio += "\"baseCod\": \"N\", \"cod\": \"Numer\" ,";
-                setf += '\"fcod\":[' + arreglo4 + ']';
-            } else {
-
-                dominio += this.recursivoCod(grf.sets, nom1);
-                setf += "\"fcod\": \"function(x)\"";
-            }
+        } */ else {
+      var nom1 = grf.cod;
+
+      if (Array.isArray(grf.sets[0][nom1])) {
+        var arreglo3 = grf.sets[0][nom1];
+        var arreglo4 = [];
+        for (var item of arreglo3) {
+          arreglo4.push('"' + item + '"');
         }
-        return dominio + setf + "}}";
+        dominio += '"baseCod": "N", "cod": "Numer" ,';
+        setf += '"fcod":[' + arreglo4 + "]";
+      } else {
+        dominio += this.recursivoCod(grf.sets, nom1);
+        setf += '"fcod": "function(x)"';
+      }
     }
-
-
-
-
-
-    recursionfuncion = function (func, nombre) {
-        var fun = func[0][nombre].set;
-        var resul = ""; // "var z = 2;"; // PRUEBA
-        if (fun == 'R' || fun == 'Z' || fun == 'N') {
-
-            resul += this.generarF(func[0][nombre].cond);
-
-        } else {
-
-            resul += this.generarF(func[0][nombre].cond) + " && " + this.recursionfuncion(func, fun);
-
-        }
-        return resul;
+    return dominio + setf + "}}";
+  };
+
+  recursionfuncion = function (func, nombre) {
+    var fun = func[0][nombre].set;
+    var resul = ""; // "var z = 2;"; // PRUEBA
+    if (fun == "R" || fun == "Z" || fun == "N") {
+      resul += this.generarF(func[0][nombre].cond);
+    } else {
+      resul +=
+        this.generarF(func[0][nombre].cond) +
+        " && " +
+        this.recursionfuncion(func, fun);
     }
-
-
-    recursionfuncionCod = function (func, nombre) {
-        //ACA CAMBIE
-        var fun = func[0][nombre].set;
-        var resul = "";
-        if (fun == 'R' || fun == 'Z' || fun == 'N') {
-            //ACA TAMBIEN
-            resul += this.generarF(func[0][nombre].cond);
-
-        } else {
-
-            //ACA TAMBIEN
-            resul += this.generarF(func[0][nombre].cond) + " && " + this.recursionfuncionCod(func, fun);
-
-        }
-        return resul;
+    return resul;
+  };
+
+  recursionfuncionCod = function (func, nombre) {
+    //ACA CAMBIE
+    var fun = func[0][nombre].set;
+    var resul = "";
+    if (fun == "R" || fun == "Z" || fun == "N") {
+      //ACA TAMBIEN
+      resul += this.generarF(func[0][nombre].cond);
+    } else {
+      //ACA TAMBIEN
+      resul +=
+        this.generarF(func[0][nombre].cond) +
+        " && " +
+        this.recursionfuncionCod(func, fun);
     }
-
-    recursivoDom = function (sets, nom) {
-        var domin = "";
-	if (sets[0][nom] == undefined) {
-	    domin += "\"baseDom\": \"Error\"";
-        } else if (sets[0][nom].set == 'R') {
-            domin += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"Func\"";
-        } else if (sets[0][nom].set == 'Z') {
-            domin += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Func\"";
-        } else if (sets[0][nom].set == 'N') {
-            domin += "\"radio\": 2, \"baseDom\": \"N\", \"dom\": \"Func\"";
-        } else {
-            var nombre = sets[0][nom].set;
-            domin = this.recursivoDom(sets, nombre);
-        }
-        return domin;
+    return resul;
+  };
+
+  recursivoDom = function (sets, nom) {
+    var domin = "";
+    if (sets[0][nom] == undefined) {
+      domin += '"baseDom": "Error"';
+    } else if (sets[0][nom].set == "R") {
+      domin += '"radio": 0.3, "baseDom": "R", "dom": "Func"';
+    } else if (sets[0][nom].set == "Z") {
+      domin += '"radio": 2, "baseDom": "Z", "dom": "Func"';
+    } else if (sets[0][nom].set == "N") {
+      domin += '"radio": 2, "baseDom": "N", "dom": "Func"';
+    } else {
+      var nombre = sets[0][nom].set;
+      domin = this.recursivoDom(sets, nombre);
     }
-
-
-    recursivoCod = function (sets, nom) {
-        var coodo = "";
-	if (sets[0][nom] == undefined) {
-	    coodo += "\"baseCod\": \"Error\"";
-        } else  if (sets[0][nom].set == 'R') {
-            coodo += "\"baseCod\": \"R\", \"cod\": \"Func\",";
-        } else if (sets[0][nom].set == 'Z') {
-            coodo += "\"baseCod\": \"Z\", \"cod\": \"Func\",";
-        } else if (sets[0][nom].set == 'N') {
-            coodo += "\"baseCod\": \"N\", \"cod\": \"Func\",";
-        } else {
-            var nombre = sets[0][nom].set;
-            coodo += this.recursivoDom(sets, nombre);
-        }
-        return coodo;
+    return domin;
+  };
+
+  recursivoCod = function (sets, nom) {
+    var coodo = "";
+    if (sets[0][nom] == undefined) {
+      coodo += '"baseCod": "Error"';
+    } else if (sets[0][nom].set == "R") {
+      coodo += '"baseCod": "R", "cod": "Func",';
+    } else if (sets[0][nom].set == "Z") {
+      coodo += '"baseCod": "Z", "cod": "Func",';
+    } else if (sets[0][nom].set == "N") {
+      coodo += '"baseCod": "N", "cod": "Func",';
+    } else {
+      var nombre = sets[0][nom].set;
+      coodo += this.recursivoDom(sets, nombre);
     }
-
-    generarF = function (exp) {
-        var expresion = '';
-        if (exp.kind == 'cond') {
-            expresion = ' (' + this.generarF(exp.cond) + '?' + this.generarF(exp.exp1) + ':' + this.generarF(exp.exp2) + ') ';
-        } else if (exp.kind == 'bop') {
-            if (exp.op == '==') {
-                expresion = ' Math.abs((' + this.generarF(exp.exp1) + ') - (' + this.generarF(exp.exp2) + ')) == 0 ';
-            } else if (exp.op == '/=') {
-                expresion = ' Math.abs((' + this.generarF(exp.exp1) + ') - (' + this.generarF(exp.exp2) + ')) != 0 ';
-            } else if (exp.op == '^') {
-                expresion = ' Math.pow(' + this.generarF(exp.exp1) + ',' + this.generarF(exp.exp2) + ') ';
-            } else {
-                expresion = ' (' + this.generarF(exp.exp1) + ')' + exp.op + '(' + this.generarF(exp.exp2) + ') ';
-            }
-        } else if (exp.kind == 'uop') {
-            expresion = ' ' + exp.op + ' ' + this.generarF(exp.exp) + ' ';
-        } else if (exp.kind == 'app') {
-            if (exp.fun == 'cos') {
-                exp.fun = 'Math.cos'
-            } else if (exp.fun == 'sin') {
-                exp.fun = 'Math.sin'
-            } else if (exp.fun == 'round') {
-                exp.fun = 'Math.round'
-            }else if (exp.fun == 'sqrt'){
-                exp.fun = 'Math.sqrt'
-            }
-            expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarF(e)).join() + ') ';
-        } else if (exp.kind == 'tup') {
-            expresion = ' (' + exp.exps.map(e => this.generarF(e)).join() + ') ';
-        } else if (exp.kind == 'lit') {
-            expresion = ' ' + exp.val + ' ';
-        } else if (exp.kind == 'var') {
-            expresion = ' ' + exp.var + ' ';
-        } else {
-            expresion = ' undefined ';
-        }
-
-        return expresion;
+    return coodo;
+  };
+
+  generarF = function (exp) {
+    var expresion = "";
+    if (exp.kind == "cond") {
+      expresion =
+        " (" +
+        this.generarF(exp.cond) +
+        "?" +
+        this.generarF(exp.exp1) +
+        ":" +
+        this.generarF(exp.exp2) +
+        ") ";
+    } else if (exp.kind == "bop") {
+      if (exp.op == "==") {
+        expresion =
+          " Math.abs((" +
+          this.generarF(exp.exp1) +
+          ") - (" +
+          this.generarF(exp.exp2) +
+          ")) == 0 ";
+      } else if (exp.op == "/=") {
+        expresion =
+          " Math.abs((" +
+          this.generarF(exp.exp1) +
+          ") - (" +
+          this.generarF(exp.exp2) +
+          ")) != 0 ";
+      } else if (exp.op == "^") {
+        expresion =
+          " Math.pow(" +
+          this.generarF(exp.exp1) +
+          "," +
+          this.generarF(exp.exp2) +
+          ") ";
+      } else {
+        expresion =
+          " (" +
+          this.generarF(exp.exp1) +
+          ")" +
+          exp.op +
+          "(" +
+          this.generarF(exp.exp2) +
+          ") ";
+      }
+    } else if (exp.kind == "uop") {
+      expresion = " " + exp.op + " " + this.generarF(exp.exp) + " ";
+    } else if (exp.kind == "app") {
+      if (exp.fun == "cos") {
+        exp.fun = "Math.cos";
+      } else if (exp.fun == "sin") {
+        exp.fun = "Math.sin";
+      } else if (exp.fun == "round") {
+        exp.fun = "Math.round";
+      } else if (exp.fun == "sqrt") {
+        exp.fun = "Math.sqrt";
+      }
+      expresion =
+        " " +
+        exp.fun +
+        "(" +
+        exp.args.map((e) => this.generarF(e)).join() +
+        ") ";
+    } else if (exp.kind == "tup") {
+      expresion = " (" + exp.exps.map((e) => this.generarF(e)).join() + ") ";
+    } else if (exp.kind == "lit") {
+      expresion = " " + exp.val + " ";
+    } else if (exp.kind == "var") {
+      expresion = " " + exp.var + " ";
+    } else {
+      expresion = " undefined ";
     }
 
-    generarFun = function (graph) {
-        var funcionString = '';
-        var grafica;
-        for (var fun of graph.funs) {
-            funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + this.generarF(fun.bdy) + '}\n' + funcionString;
-
-            if (fun.fun == graph.graph) {
-                funcionString += 'return ' + fun.fun + '(' + fun.args.join() + ');\n'
-                grafica = fun;
-            }
-        }
-        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
+    return expresion;
+  };
 
-        return funcionString;
+  generarFun = function (graph) {
+    var funcionString = "";
+    var grafica;
+    for (var fun of graph.funs) {
+      funcionString =
+        "var " +
+        fun.fun +
+        " = function(" +
+        fun.args.join() +
+        "){\n return " +
+        this.generarF(fun.bdy) +
+        "}\n" +
+        funcionString;
+
+      if (fun.fun == graph.graph) {
+        funcionString += "return " + fun.fun + "(" + fun.args.join() + ");\n";
+        grafica = fun;
+      }
     }
+    funcionString = "(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
 
-
-
+    return funcionString;
+  };
 }
-
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts
index 480e9dfb..e8477cdb 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts	
@@ -1,52 +1,52 @@
 export interface Animation {
-	data?: any,
-	init: boolean,
-	currentFrame: number,
-	fps: number,
-	playing: boolean,
-	timeout?: any,
-	animationFrame?: any,
-	speedX: number,
-	boton: boolean,
-	zoo: number,
+  data?: any;
+  init: boolean;
+  currentFrame: number;
+  fps: number;
+  playing: boolean;
+  timeout?: any;
+  animationFrame?: any;
+  speedX: number;
+  boton: boolean;
+  zoo: number;
 }
 
 export interface Setting {
-	axis: boolean,
-	grid: boolean,
-	tip: boolean
+  axis: boolean;
+  grid: boolean;
+  tip: boolean;
 }
 
-export function toJSON(data: string) : string {
-	console.log('data',data);
-	const regexPts = /(?:\"pts\"\:\[(?:\((x),(y)\))+,?\])/g;
-	var dataJSON = data.replace(regexPts, (match, x, y) => {
-		return `"points": [[${x},${y}]]`
-	})
-	console.log('dataJSON', dataJSON);
-	return dataJSON;
+export function toJSON(data: string): string {
+  console.log("data", data);
+  const regexPts = /(?:\"pts\"\:\[(?:\((x),(y)\))+,?\])/g;
+  var dataJSON = data.replace(regexPts, (match, x, y) => {
+    return `"points": [[${x},${y}]]`;
+  });
+  console.log("dataJSON", dataJSON);
+  return dataJSON;
 }
 /**************para borrar***************** */
 // export function JSONRepair(data: string): string {
 // 	const regex = /\"sets\"\ : \[(\"+.*)\]\, \"bdy\"/g;
-  
+
 // 	return data.replace(regex, (match, content) => {
 // 	  return `"sets": [{ ${content} }], "bdy"`
 // 	})
 //   }
-  /**************fin para borrar***************** */
+/**************fin para borrar***************** */
 
 export function triggerDownload(imgURI: string) {
-	var evt = new MouseEvent('click', {
-		view: window,
-		bubbles: false,
-		cancelable: true
-	});
+  var evt = new MouseEvent("click", {
+    view: window,
+    bubbles: false,
+    cancelable: true,
+  });
 
-	var a = document.createElement('a');
-	a.setAttribute('download', 'Matefun_2D_plot.png');
-	a.setAttribute('href', imgURI);
-	a.setAttribute('target', '_blank');
+  var a = document.createElement("a");
+  a.setAttribute("download", "Matefun_2D_plot.png");
+  a.setAttribute("href", imgURI);
+  a.setAttribute("target", "_blank");
 
-	a.dispatchEvent(evt);
-}
\ No newline at end of file
+  a.dispatchEvent(evt);
+}
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts
index f29f0b5a..e7b7b4a2 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts	
@@ -1,25 +1,24 @@
-import { NgModule} from '@angular/core';
-import { CommonModule } from '@angular/common'
-import { RouterModule } from '@angular/router';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { FormsModule } from '@angular/forms';
-import { Graph2DComponent } from './graph2D.component';
-import { DirectivesModule } from '../../../shared/directives/directives.module';
-import { I18nModule } from '../../../shared/modules/translate/i18n.module';
-import { TitleCaseModule } from '../../../shared/modules/titlecase.module';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { RouterModule } from "@angular/router";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { FormsModule } from "@angular/forms";
+import { Graph2DComponent } from "./graph2D.component";
+import { DirectivesModule } from "../../../shared/directives/directives.module";
+import { I18nModule } from "../../../shared/modules/translate/i18n.module";
+import { TitleCaseModule } from "../../../shared/modules/titlecase.module";
 
 @NgModule({
-    imports: [
-        FormsModule,
-        RouterModule,
-        CommonModule, 
-        NgbModule,
-        DirectivesModule,
-        I18nModule,
-        TitleCaseModule
-    ],
-    declarations: [Graph2DComponent],
-    exports: [Graph2DComponent],
+  imports: [
+    FormsModule,
+    RouterModule,
+    CommonModule,
+    NgbModule,
+    DirectivesModule,
+    I18nModule,
+    TitleCaseModule,
+  ],
+  declarations: [Graph2DComponent],
+  exports: [Graph2DComponent],
 })
-
-export class Graph2DModule { }
\ No newline at end of file
+export class Graph2DModule {}
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.routes.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.routes.ts
index 4edd5275..1ef3b326 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.routes.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.routes.ts	
@@ -1,9 +1,9 @@
-import { Route } from '@angular/router';
-import { Graph2DComponent } from '.';
+import { Route } from "@angular/router";
+import { Graph2DComponent } from ".";
 
 export const Graph2DRoutes: Route[] = [
-	{
-		path: 'graph2D',
-		component: Graph2DComponent
-	}
+  {
+    path: "graph2D",
+    component: Graph2DComponent,
+  },
 ];
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/index.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/index.ts
index d4fa2919..719a6aaa 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph2D/index.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/index.ts	
@@ -1,6 +1,6 @@
 /**
  * This barrel file provides the export for the lazy loaded BlankpageComponent.
  */
-export * from './graph2D.component';
+export * from "./graph2D.component";
 
-export * from './graph2D.routes';
+export * from "./graph2D.routes";
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts
index 513c2458..3c310189 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts	
@@ -1,16 +1,15 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
 
-import { Graph3DComponent } from './graph3D.component';
+import { Graph3DComponent } from "./graph3D.component";
 
-describe('Graph3DComponent', () => {
+describe("Graph3DComponent", () => {
   let component: Graph3DComponent;
   let fixture: ComponentFixture<Graph3DComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ Graph3DComponent ]
-    })
-    .compileComponents();
+      declarations: [Graph3DComponent],
+    }).compileComponents();
   }));
 
   beforeEach(() => {
@@ -19,7 +18,7 @@ describe('Graph3DComponent', () => {
     fixture.detectChanges();
   });
 
-  it('should be created', () => {
+  it("should be created", () => {
     expect(component).toBeTruthy();
   });
 });
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts
index 3ea6aabb..e47613af 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts	
@@ -1,73 +1,90 @@
-import { Component, OnInit, ViewChild, ElementRef, NgZone, AfterViewInit } from '@angular/core';
-import * as graph3DLib from 'graph3D';
-import { GHCIService } from '../../../shared/services/ghci.service';
-import { formatJSON, AnimationProps, Zoom3DType, GraphProps, Default_GraphProps, debounce } from './graph3D.helper';
-import { TranslateService } from '@ngx-translate/core';
-import { TitleCasePipe } from '../../../shared/pipes/titlecase.pipe';
+import {
+  Component,
+  OnInit,
+  ViewChild,
+  ElementRef,
+  NgZone,
+  AfterViewInit,
+} from "@angular/core";
+import * as graph3DLib from "graph3D";
+import { GHCIService } from "../../../shared/services/ghci.service";
+import {
+  formatJSON,
+  AnimationProps,
+  Zoom3DType,
+  GraphProps,
+  Default_GraphProps,
+  debounce,
+} from "./graph3D.helper";
+import { TranslateService } from "@ngx-translate/core";
+import { TitleCasePipe } from "../../../shared/pipes/titlecase.pipe";
 
 @Component({
-  selector: 'graph3d-component',
-  templateUrl: './graph3D.component.html',
-  styleUrls: ['./graph3D.component.scss'],
+  selector: "graph3d-component",
+  templateUrl: "./graph3D.component.html",
+  styleUrls: ["./graph3D.component.scss"],
   host: {
-    '(window:resize)': 'onResize($event)'
-  }
+    "(window:resize)": "onResize($event)",
+  },
 })
 export class Graph3DComponent implements AfterViewInit {
-
   private ghciServiceSub: any;
 
   private translateService: any;
   private titlecasePipe: any;
 
-  @ViewChild('graph3DElement') 
+  @ViewChild("graph3DElement")
   private graph3DRef: ElementRef;
 
-  graphProps : GraphProps = Default_GraphProps;
-  
-  animationProps : AnimationProps = {
+  graphProps: GraphProps = Default_GraphProps;
+
+  animationProps: AnimationProps = {
     visible: false,
     playing: false,
     value: 0,
-    speed: 1000
+    speed: 1000,
   };
-  
-  constructor(ghciService: GHCIService, private zone: NgZone, public translate: TranslateService) {
+
+  constructor(
+    ghciService: GHCIService,
+    private zone: NgZone,
+    public translate: TranslateService
+  ) {
     const self = this;
 
     // i18n
     this.translateService = translate;
     this.titlecasePipe = new TitleCasePipe();
 
-    this.ghciServiceSub = ghciService.messages.subscribe(
-      message => {
-        if (message.tipo == "canvas3D") {
-          const figures = JSON.parse(formatJSON(message.resultado));
-          self.clear();
-          graph3DLib.drawFigures(figures);
-        } 
-        else if (message.tipo == "animacion3D") {
-          const frames = message.resultado.map((frame) => JSON.parse(formatJSON(frame)));
+    this.ghciServiceSub = ghciService.messages.subscribe((message) => {
+      if (message.tipo == "canvas3D") {
+        const figures = JSON.parse(formatJSON(message.resultado));
+        self.clear();
+        graph3DLib.drawFigures(figures);
+      } else if (message.tipo == "animacion3D") {
+        const frames = message.resultado.map((frame) =>
+          JSON.parse(formatJSON(frame))
+        );
 
-          self.clear();
+        self.clear();
 
-          this.animationProps.visible = true;
-          this.animationProps.playing = true;
-          this.animationProps.value = 0;
+        this.animationProps.visible = true;
+        this.animationProps.playing = true;
+        this.animationProps.value = 0;
 
-          graph3DLib.initializeAnimation(frames, 
-            (value) => this.animationProps.value = value
-          );
+        graph3DLib.initializeAnimation(
+          frames,
+          (value) => (this.animationProps.value = value)
+        );
 
-          graph3DLib.playAnimation();
-        }
+        graph3DLib.playAnimation();
       }
-    )
+    });
   }
 
   ngAfterViewInit() {
     //this.zone.runOutsideAngular(() => {
-      graph3DLib.initialize(this.graph3DRef.nativeElement);
+    graph3DLib.initialize(this.graph3DRef.nativeElement);
     //})
   }
 
@@ -80,55 +97,52 @@ export class Graph3DComponent implements AfterViewInit {
   onActivate() {
     setTimeout(() => {
       this.onResize(null);
-    })
+    });
   }
 
-  onResize(event){
-    const {width, height} = this.graph3DRef.nativeElement.getBoundingClientRect();
-      
+  onResize(event) {
+    const { width, height } =
+      this.graph3DRef.nativeElement.getBoundingClientRect();
+
     if (width > 0 && height > 0) {
-      graph3DLib.changeSize({width, height});
+      graph3DLib.changeSize({ width, height });
     }
   }
 
   onAnimationChangeSpeed = (value) => {
     this.animationProps.speed = parseInt(value);
     graph3DLib.changeSpeedAnimation(parseInt(value));
-  }
+  };
 
   onAnimationTogglePlay = () => {
     if (this.animationProps.playing) {
       graph3DLib.pauseAnimation();
-    }
-    else {
+    } else {
       graph3DLib.playAnimation();
     }
-    
+
     this.animationProps.playing = !this.animationProps.playing;
-  }
+  };
 
   public changeZoomType = (type: Zoom3DType = null) => {
     if (type != null) {
       this.graphProps.zoomType = type;
-    } 
-    else {
+    } else {
       this.graphProps.zoomType = (this.graphProps.zoomType % 4) + 1;
     }
 
     graph3DLib.changeZoomType(this.graphProps.zoomType);
-  }
+  };
 
   public changeAxesVisibility = () => {
     this.graphProps.showAxes = !this.graphProps.showAxes;
     graph3DLib.showAxes(this.graphProps.showAxes);
-  }
+  };
 
   handleAxesRangeDebounced = debounce(function () {
-    setTimeout(() =>
-      graph3DLib.changeAxesSize(this.graphProps.range)
-    );
+    setTimeout(() => graph3DLib.changeAxesSize(this.graphProps.range));
   }, 500);
-  
+
   public onChangeAxesSize = (v, event) => {
     let value = this.graphProps.range[v];
 
@@ -136,64 +150,77 @@ export class Graph3DComponent implements AfterViewInit {
     const max = parseInt(event.target.max);
 
     if (value == null) {
-      value = v.search('Min') ? min : max;
+      value = v.search("Min") ? min : max;
       this.graphProps.range[v] = value;
     }
 
     if (value < min) {
       this.graphProps.range[v] = min;
-    } 
-    
+    }
+
     if (value > max) {
       this.graphProps.range[v] = max;
     }
     this.handleAxesRangeDebounced();
     //graph3DLib.changeAxesSize(this.graphProps.range)
-  }
+  };
 
   public onChangeQuality = () => {
     const value = this.graphProps.quality;
 
     if (value == null || value <= 1) {
       this.graphProps.quality = 30;
-    } 
-    else {
+    } else {
       this.graphProps.quality = value;
     }
 
-    graph3DLib.changeOptions({quality: value});
-  }
+    graph3DLib.changeOptions({ quality: value });
+  };
 
   public zoomIn = () => {
     graph3DLib.changeZoom(true);
-  }
+  };
 
   public zoomOut = () => {
     graph3DLib.changeZoom(false);
-  }
-  
+  };
+
   public clear = () => {
     this.animationProps.visible = false;
 
     graph3DLib.clear();
-  }
-  
+  };
+
   public center = () => {
     this.graphProps = Default_GraphProps;
 
     graph3DLib.reset();
-  }
+  };
 
   public getZoom3DTypeName = (type: Zoom3DType) => {
     switch (type) {
       case Zoom3DType.Normal:
-        return this.titlecasePipe.transform(this.translateService.get('i18n.object.normal').value);
+        return this.titlecasePipe.transform(
+          this.translateService.get("i18n.object.normal").value
+        );
       case Zoom3DType.XAxis:
-        return this.titlecasePipe.transform(this.translateService.get('i18n.object.axis').value) + ' x';
+        return (
+          this.titlecasePipe.transform(
+            this.translateService.get("i18n.object.axis").value
+          ) + " x"
+        );
       case Zoom3DType.YAxis:
-        return this.titlecasePipe.transform(this.translateService.get('i18n.object.axis').value) + ' y';
+        return (
+          this.titlecasePipe.transform(
+            this.translateService.get("i18n.object.axis").value
+          ) + " y"
+        );
       case Zoom3DType.ZAxis:
-        return this.titlecasePipe.transform(this.translateService.get('i18n.object.axis').value) + ' z';
+        return (
+          this.titlecasePipe.transform(
+            this.translateService.get("i18n.object.axis").value
+          ) + " z"
+        );
     }
-  }
+  };
 }
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts
index 9a9673a0..662e9c48 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts	
@@ -1,71 +1,67 @@
-export function formatJSON(jsonString: string) : string {
-	const regexRot = /\"rot\"\:\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\)/g;
-	const regexPts = /\"pts\"\:\[\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\),\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\)\]/g;
+export function formatJSON(jsonString: string): string {
+  const regexRot = /\"rot\"\:\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\)/g;
+  const regexPts =
+    /\"pts\"\:\[\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\),\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\)\]/g;
 
-	return jsonString
-		.replace(
-			regexRot, (match, x, y, z) => {
-				return `"rot": { "x": ${x}, "y": ${y}, "z": ${z} }`
-			}
-		)
-		.replace(
-			regexPts, (match, x1, y1, z1, x2, y2, z2) => {
-				return `"pts": [{ "x": ${x1}, "y": ${y1}, "z": ${z1} },{ "x": ${x2}, "y": ${y2}, "z": ${z2} }]`
-			}
-		)
+  return jsonString
+    .replace(regexRot, (match, x, y, z) => {
+      return `"rot": { "x": ${x}, "y": ${y}, "z": ${z} }`;
+    })
+    .replace(regexPts, (match, x1, y1, z1, x2, y2, z2) => {
+      return `"pts": [{ "x": ${x1}, "y": ${y1}, "z": ${z1} },{ "x": ${x2}, "y": ${y2}, "z": ${z2} }]`;
+    });
 }
 
-
 export interface AnimationProps {
-	visible?: boolean,
-	playing?: boolean,
-	value?: number,
-	speed?: number
+  visible?: boolean;
+  playing?: boolean;
+  value?: number;
+  speed?: number;
 }
 
 export enum Zoom3DType {
-	Normal = 1,
-	XAxis,
-	YAxis,
-	ZAxis,
+  Normal = 1,
+  XAxis,
+  YAxis,
+  ZAxis,
 }
 
 export interface GraphProps {
-	zoomType?: Zoom3DType,
-	showAxes?: boolean,
-	quality?: number,
-	range: {
-		xMin?: number,
-		xMax?: number,
-		yMin?: number,
-		yMax?: number,
-		zMin?: number,
-		zMax?: number
-	}
+  zoomType?: Zoom3DType;
+  showAxes?: boolean;
+  quality?: number;
+  range: {
+    xMin?: number;
+    xMax?: number;
+    yMin?: number;
+    yMax?: number;
+    zMin?: number;
+    zMax?: number;
+  };
 }
 
-export const Default_GraphProps : GraphProps = {
-	zoomType: Zoom3DType.Normal,
-	showAxes: true,
-	quality: 30,
-	range: {
-		xMin: -10,
-		xMax: 10,
-		yMin: -10,
-		yMax: 10,
-		zMin: -10,
-		zMax: 10
-	}
-}
+export const Default_GraphProps: GraphProps = {
+  zoomType: Zoom3DType.Normal,
+  showAxes: true,
+  quality: 30,
+  range: {
+    xMin: -10,
+    xMax: 10,
+    yMin: -10,
+    yMax: 10,
+    zMin: -10,
+    zMax: 10,
+  },
+};
 
 export function debounce(fn, delay) {
   var timer = null;
   return function () {
-    var context = this, args = arguments;
+    var context = this,
+      args = arguments;
     clearTimeout(timer);
     timer = setTimeout(function () {
       fn.apply(context, args);
     }, delay);
   };
 }
-
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts
index d39268b5..1fa698c4 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts	
@@ -1,32 +1,26 @@
-import { NgModule} from '@angular/core';
-import { CommonModule } from '@angular/common'
-import { RouterModule } from '@angular/router';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
-import { FormsModule } from '@angular/forms';
-import { Graph3DComponent } from './graph3D.component';
-import { AnimationControlComponent } from '../animation-control/animation-control.component';
-import { DirectivesModule } from '../../../shared/directives/directives.module';
-import { I18nModule } from '../../../shared/modules/translate/i18n.module';
-import { TitleCaseModule } from '../../../shared/modules/titlecase.module';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { RouterModule } from "@angular/router";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
+import { FormsModule } from "@angular/forms";
+import { Graph3DComponent } from "./graph3D.component";
+import { AnimationControlComponent } from "../animation-control/animation-control.component";
+import { DirectivesModule } from "../../../shared/directives/directives.module";
+import { I18nModule } from "../../../shared/modules/translate/i18n.module";
+import { TitleCaseModule } from "../../../shared/modules/titlecase.module";
 
 @NgModule({
-    imports: [
-        FormsModule,
-        RouterModule,
-        CommonModule,
-        NgbModule,
-        DirectivesModule,
-        I18nModule,
-        TitleCaseModule
-    ],
-    declarations: [
-        AnimationControlComponent, 
-        Graph3DComponent
-    ],
-    entryComponents: [
-        AnimationControlComponent
-    ],
-    exports: [Graph3DComponent]
+  imports: [
+    FormsModule,
+    RouterModule,
+    CommonModule,
+    NgbModule,
+    DirectivesModule,
+    I18nModule,
+    TitleCaseModule,
+  ],
+  declarations: [AnimationControlComponent, Graph3DComponent],
+  entryComponents: [AnimationControlComponent],
+  exports: [Graph3DComponent],
 })
-
-export class Graph3DModule { }
+export class Graph3DModule {}
diff --git a/Frontend Angular 4/src/app/login/login-routing.module.ts b/Frontend Angular 4/src/app/login/login-routing.module.ts
index 0235f700..3d5e871f 100755
--- a/Frontend Angular 4/src/app/login/login-routing.module.ts	
+++ b/Frontend Angular 4/src/app/login/login-routing.module.ts	
@@ -1,13 +1,11 @@
-import { NgModule } from '@angular/core';
-import { Routes, RouterModule } from '@angular/router';
-import { LoginComponent } from './login.component';
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
+import { LoginComponent } from "./login.component";
 
-const routes: Routes = [
-    { path: '', component: LoginComponent }
-];
+const routes: Routes = [{ path: "", component: LoginComponent }];
 
 @NgModule({
   imports: [RouterModule.forChild(routes)],
-  exports: [RouterModule]
+  exports: [RouterModule],
 })
-export class LoginRoutingModule { }
+export class LoginRoutingModule {}
diff --git a/Frontend Angular 4/src/app/login/login.component.spec.ts b/Frontend Angular 4/src/app/login/login.component.spec.ts
index d6d85a84..e08691e6 100755
--- a/Frontend Angular 4/src/app/login/login.component.spec.ts	
+++ b/Frontend Angular 4/src/app/login/login.component.spec.ts	
@@ -1,16 +1,15 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
 
-import { LoginComponent } from './login.component';
+import { LoginComponent } from "./login.component";
 
-describe('LoginComponent', () => {
+describe("LoginComponent", () => {
   let component: LoginComponent;
   let fixture: ComponentFixture<LoginComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ LoginComponent ]
-    })
-    .compileComponents();
+      declarations: [LoginComponent],
+    }).compileComponents();
   }));
 
   beforeEach(() => {
@@ -19,7 +18,7 @@ describe('LoginComponent', () => {
     fixture.detectChanges();
   });
 
-  it('should create', () => {
+  it("should create", () => {
     expect(component).toBeTruthy();
   });
 });
diff --git a/Frontend Angular 4/src/app/login/login.component.ts b/Frontend Angular 4/src/app/login/login.component.ts
index c641ebe0..e0b2e0f6 100755
--- a/Frontend Angular 4/src/app/login/login.component.ts	
+++ b/Frontend Angular 4/src/app/login/login.component.ts	
@@ -1,110 +1,111 @@
-import { Component, OnInit } from '@angular/core';
-import { Router, ActivatedRoute } from '@angular/router';
-import { SessionService } from '../shared/services/session.service';
-import { AuthenticationService } from '../shared/services/authentication.service';
-import { TranslateService } from '@ngx-translate/core';
-
+import { Component, OnInit } from "@angular/core";
+import { Router, ActivatedRoute } from "@angular/router";
+import { SessionService } from "../shared/services/session.service";
+import { AuthenticationService } from "../shared/services/authentication.service";
+import { TranslateService } from "@ngx-translate/core";
 
 @Component({
-    selector: 'app-login',
-    templateUrl: './login.component.html',
-    styleUrls: ['./login.component.scss']
-
+  selector: "app-login",
+  templateUrl: "./login.component.html",
+  styleUrls: ["./login.component.scss"],
 })
-
 export class LoginComponent implements OnInit {
-    languages = [
-        {id: 0, name: "Español", code: 'es', flagCode: 'es'},
-        {id: 1, name: "English", code: 'en', flagCode: 'us'}
-    ];
-
-	model: any = {
-        language: this.languages[0]
-    };
-
-    loading = false;
-    error = false;
-    errorText = "";
-    returnUrl: string;
-
-  
-    constructor(
-        private route: ActivatedRoute,
-        private router: Router,
-        private sessionService: SessionService,
-        private authenticationService: AuthenticationService,
-        public translate: TranslateService,
-        ) { }
-
-    ngOnInit() {
-        console.log('this.route', this.route.snapshot.data['language']);
-        console.log('return', this.route.snapshot.queryParams['returnUrl']);
-        
-        // let currentSession = sessionStorage.getItem("currentUser"); 
-        // let langCode = currentSession ? JSON.parse(currentSession).language : 'es';
-        // if (langCode) {
-        //     this.model.language = this.getLanguageElementByCode(langCode);
-        // }
-
-        this.model.language = this.getLanguageElementByCode(this.route.snapshot.data['language']);
-        this.translate.use(this.model.language.code);
-
-        // reset login status
-        this.authenticationService.logout();
-
-        // get return url from route parameters or default to '/'
-        this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/matefun';
-    }
-
-    login() {
-    	// this.router.navigate([this.returnUrl]);
-        this.loading = true;
-
-        var that = this;
-
-        this.translate.use(this.model.language.code);
-        this.authenticationService.login(this.model.cedula, this.model.password, this.model.language.code)
-            .subscribe(
-                data => {
-                    //resetSession = true;
-                    this.router.navigate([this.returnUrl]);
-                    that.sessionService.reset();
-                },
-                error => {
-                    this.loading = false;
-                    this.error = true;
-                    this.errorText = error.text();
-                });
-    }
-
-    invitado(){
-        this.loading = true;
-
-        this.authenticationService.login("invitado", "invitado", this.model.language.code)
-            .subscribe(
-                data => {
-                    this.router.navigate([this.returnUrl]);
-                    this.sessionService.reset();
-                },
-                error => {
-                    this.loading = false;
-                });
-    }
-
-    onChangeLanguage(lang) {
-        this.model.language = lang;
-        this.translate.use(this.model.language.code);
+  languages = [
+    { id: 0, name: "Español", code: "es", flagCode: "es" },
+    { id: 1, name: "English", code: "en", flagCode: "us" },
+  ];
+
+  model: any = {
+    language: this.languages[0],
+  };
+
+  loading = false;
+  error = false;
+  errorText = "";
+  returnUrl: string;
+
+  constructor(
+    private route: ActivatedRoute,
+    private router: Router,
+    private sessionService: SessionService,
+    private authenticationService: AuthenticationService,
+    public translate: TranslateService
+  ) {}
+
+  ngOnInit() {
+    console.log("this.route", this.route.snapshot.data["language"]);
+    console.log("return", this.route.snapshot.queryParams["returnUrl"]);
+
+    // let currentSession = sessionStorage.getItem("currentUser");
+    // let langCode = currentSession ? JSON.parse(currentSession).language : 'es';
+    // if (langCode) {
+    //     this.model.language = this.getLanguageElementByCode(langCode);
+    // }
+
+    this.model.language = this.getLanguageElementByCode(
+      this.route.snapshot.data["language"]
+    );
+    this.translate.use(this.model.language.code);
+
+    // reset login status
+    this.authenticationService.logout();
+
+    // get return url from route parameters or default to '/'
+    this.returnUrl = this.route.snapshot.queryParams["returnUrl"] || "/matefun";
+  }
+
+  login() {
+    // this.router.navigate([this.returnUrl]);
+    this.loading = true;
+
+    var that = this;
+
+    this.translate.use(this.model.language.code);
+    this.authenticationService
+      .login(this.model.cedula, this.model.password, this.model.language.code)
+      .subscribe(
+        (data) => {
+          //resetSession = true;
+          this.router.navigate([this.returnUrl]);
+          that.sessionService.reset();
+        },
+        (error) => {
+          this.loading = false;
+          this.error = true;
+          this.errorText = error.text();
+        }
+      );
+  }
+
+  invitado() {
+    this.loading = true;
+
+    this.authenticationService
+      .login("invitado", "invitado", this.model.language.code)
+      .subscribe(
+        (data) => {
+          this.router.navigate([this.returnUrl]);
+          this.sessionService.reset();
+        },
+        (error) => {
+          this.loading = false;
+        }
+      );
+  }
+
+  onChangeLanguage(lang) {
+    this.model.language = lang;
+    this.translate.use(this.model.language.code);
+  }
+
+  getLanguageElementByCode(code) {
+    let langElement = null;
+    for (let lang of this.languages) {
+      if (lang.code === code) {
+        langElement = lang;
+        break;
+      }
     }
-
-    getLanguageElementByCode(code) {
-        let langElement = null;
-        for(let lang of this.languages) {
-            if (lang.code === code) {
-                langElement = lang;
-                break;
-            }
-        };
-        return langElement;
-    }
-
+    return langElement;
+  }
 }
diff --git a/Frontend Angular 4/src/app/login/login.module.ts b/Frontend Angular 4/src/app/login/login.module.ts
index 48e2edf2..b44838f2 100755
--- a/Frontend Angular 4/src/app/login/login.module.ts	
+++ b/Frontend Angular 4/src/app/login/login.module.ts	
@@ -1,18 +1,18 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { RouterModule } from '@angular/router';
-import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { RouterModule } from "@angular/router";
+import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
 
-import { LoginRoutingModule } from './login-routing.module';
-import { LoginComponent } from './login.component';
-import { FormsModule } from '@angular/forms';
-import { AuthenticationService } from '../shared/services/authentication.service';
-import { I18nModule } from '../shared/modules/translate/i18n.module';
-import { TitleCaseModule } from '../shared/modules/titlecase.module';
+import { LoginRoutingModule } from "./login-routing.module";
+import { LoginComponent } from "./login.component";
+import { FormsModule } from "@angular/forms";
+import { AuthenticationService } from "../shared/services/authentication.service";
+import { I18nModule } from "../shared/modules/translate/i18n.module";
+import { TitleCaseModule } from "../shared/modules/titlecase.module";
 
 @NgModule({
   imports: [
-  	FormsModule,
+    FormsModule,
     CommonModule,
     LoginRoutingModule,
     I18nModule,
@@ -20,6 +20,6 @@ import { TitleCaseModule } from '../shared/modules/titlecase.module';
     NgbModule.forRoot(),
   ],
   declarations: [LoginComponent],
-  providers: [AuthenticationService]
+  providers: [AuthenticationService],
 })
-export class LoginModule { }
+export class LoginModule {}
diff --git a/Frontend Angular 4/src/app/not-found/not-found-routing.module.ts b/Frontend Angular 4/src/app/not-found/not-found-routing.module.ts
index 13304137..af5f8cf0 100755
--- a/Frontend Angular 4/src/app/not-found/not-found-routing.module.ts	
+++ b/Frontend Angular 4/src/app/not-found/not-found-routing.module.ts	
@@ -1,16 +1,11 @@
-import {NgModule} from "@angular/core";
-import {Routes, RouterModule} from "@angular/router";
-import {NotFoundComponent} from "./not-found.component";
+import { NgModule } from "@angular/core";
+import { Routes, RouterModule } from "@angular/router";
+import { NotFoundComponent } from "./not-found.component";
 
-const routes: Routes = [
-  {path: '', component: NotFoundComponent}
-];
+const routes: Routes = [{ path: "", component: NotFoundComponent }];
 
 @NgModule({
-  imports: [
-    RouterModule.forChild(routes)
-  ],
-  exports: [RouterModule]
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule],
 })
-export class NotFoundRoutingModule {
-}
+export class NotFoundRoutingModule {}
diff --git a/Frontend Angular 4/src/app/not-found/not-found.component.ts b/Frontend Angular 4/src/app/not-found/not-found.component.ts
index 54cced5d..cf853e6a 100755
--- a/Frontend Angular 4/src/app/not-found/not-found.component.ts	
+++ b/Frontend Angular 4/src/app/not-found/not-found.component.ts	
@@ -1,17 +1,18 @@
-import { Component } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
+import { Component } from "@angular/core";
+import { TranslateService } from "@ngx-translate/core";
 
 @Component({
-    selector: 'app-not-found',
-    templateUrl: './not-found.component.html',
-    styleUrls: ['not-found.component.scss']
+  selector: "app-not-found",
+  templateUrl: "./not-found.component.html",
+  styleUrls: ["not-found.component.scss"],
 })
-export class NotFoundComponent { 
-    translateService: any;
-    urlLogin: string;
+export class NotFoundComponent {
+  translateService: any;
+  urlLogin: string;
 
-    constructor(public translate: TranslateService) {
-        this.translateService = translate;
-        this.urlLogin = '/'+this.translateService.get('i18n.code').value+'/login';
-    }
+  constructor(public translate: TranslateService) {
+    this.translateService = translate;
+    this.urlLogin =
+      "/" + this.translateService.get("i18n.code").value + "/login";
+  }
 }
diff --git a/Frontend Angular 4/src/app/not-found/not-found.module.ts b/Frontend Angular 4/src/app/not-found/not-found.module.ts
index 61813330..0027f248 100755
--- a/Frontend Angular 4/src/app/not-found/not-found.module.ts	
+++ b/Frontend Angular 4/src/app/not-found/not-found.module.ts	
@@ -1,15 +1,11 @@
-import { NgModule } from '@angular/core';
-import { RouterModule } from '@angular/router';
-import { I18nModule } from '../shared/modules/translate/i18n.module';
-import { NotFoundComponent } from './not-found.component';
-import { NotFoundRoutingModule } from './not-found-routing.module';
+import { NgModule } from "@angular/core";
+import { RouterModule } from "@angular/router";
+import { I18nModule } from "../shared/modules/translate/i18n.module";
+import { NotFoundComponent } from "./not-found.component";
+import { NotFoundRoutingModule } from "./not-found-routing.module";
 
 @NgModule({
-    imports: [
-        I18nModule,
-        NotFoundRoutingModule,
-        RouterModule
-    ],
-    declarations: [NotFoundComponent]
+  imports: [I18nModule, NotFoundRoutingModule, RouterModule],
+  declarations: [NotFoundComponent],
 })
 export class NotFoundModule {}
diff --git a/Frontend Angular 4/src/app/notificacion/notificacion.component.ts b/Frontend Angular 4/src/app/notificacion/notificacion.component.ts
index 5a311f83..4790b7cd 100755
--- a/Frontend Angular 4/src/app/notificacion/notificacion.component.ts	
+++ b/Frontend Angular 4/src/app/notificacion/notificacion.component.ts	
@@ -1,38 +1,34 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit } from "@angular/core";
 
-import { NotificacionService } from '../shared/services/notificacion.service';
+import { NotificacionService } from "../shared/services/notificacion.service";
 
-import 'rxjs/add/operator/debounceTime';
+import "rxjs/add/operator/debounceTime";
 
 @Component({
-    moduleId: module.id,
-    selector: 'notificacion',
-    templateUrl: 'notificacion.component.html'
+  moduleId: module.id,
+  selector: "notificacion",
+  templateUrl: "notificacion.component.html",
 })
-
 export class NotificacionComponent {
-    message: any;
-
-    constructor(private notifService: NotificacionService) {
-    }
-
-    ngOnInit() {
-    	this.notifService.getMessageSubject().subscribe(message => { 
-            this.alerts.push(message);
-            setTimeout(()=>{
-                this.closeAlert(0);//siempre elimino la 0 dado que es la mas antigua que se agrego. 
-            }, 5000);
-        });
-        //Esto es otra forma que lugo de 5 segundos del ultimo mensaje vacia todo el arreglo. 
-        // this.notifService.getMessageSubject().debounceTime(5000).subscribe(() => this.alerts = []);
-
-    }
-
-   	public alerts: Array<Object> = [];
-
-	// Alert
-	public closeAlert(i:number):void {
-		this.alerts.splice(i, 1);
-	}
-
-}
\ No newline at end of file
+  message: any;
+
+  constructor(private notifService: NotificacionService) {}
+
+  ngOnInit() {
+    this.notifService.getMessageSubject().subscribe((message) => {
+      this.alerts.push(message);
+      setTimeout(() => {
+        this.closeAlert(0); // siempre elimino la 0 dado que es la mas antigua que se agrego.
+      }, 5000);
+    });
+    // Esto es otra forma que lugo de 5 segundos del ultimo mensaje vacia todo el arreglo.
+    // this.notifService.getMessageSubject().debounceTime(5000).subscribe(() => this.alerts = []);
+  }
+
+  public alerts: Array<Object> = [];
+
+  // Alert
+  public closeAlert(i: number): void {
+    this.alerts.splice(i, 1);
+  }
+}
diff --git a/Frontend Angular 4/src/app/notificacion/notificacion.module.ts b/Frontend Angular 4/src/app/notificacion/notificacion.module.ts
index c385f9f6..d38fbec0 100755
--- a/Frontend Angular 4/src/app/notificacion/notificacion.module.ts	
+++ b/Frontend Angular 4/src/app/notificacion/notificacion.module.ts	
@@ -1,15 +1,13 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { RouterModule } from '@angular/router';
-import { NotificacionComponent } from './notificacion.component';
-
-import { NgbAlertModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { RouterModule } from "@angular/router";
+import { NotificacionComponent } from "./notificacion.component";
 
+import { NgbAlertModule } from "@ng-bootstrap/ng-bootstrap";
 
 @NgModule({
-    imports: [CommonModule, RouterModule, NgbAlertModule],
-    declarations: [NotificacionComponent],
-    exports: [NotificacionComponent]
+  imports: [CommonModule, RouterModule, NgbAlertModule],
+  declarations: [NotificacionComponent],
+  exports: [NotificacionComponent],
 })
-
-export class NotificacionModule { }
+export class NotificacionModule {}
diff --git a/Frontend Angular 4/src/app/shared/components/header/header.component.spec.ts b/Frontend Angular 4/src/app/shared/components/header/header.component.spec.ts
index 2d0479d7..bddd3676 100755
--- a/Frontend Angular 4/src/app/shared/components/header/header.component.spec.ts	
+++ b/Frontend Angular 4/src/app/shared/components/header/header.component.spec.ts	
@@ -1,16 +1,15 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
 
-import { HeaderComponent } from './header.component';
+import { HeaderComponent } from "./header.component";
 
-describe('HeaderComponent', () => {
+describe("HeaderComponent", () => {
   let component: HeaderComponent;
   let fixture: ComponentFixture<HeaderComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ HeaderComponent ]
-    })
-    .compileComponents();
+      declarations: [HeaderComponent],
+    }).compileComponents();
   }));
 
   beforeEach(() => {
@@ -19,7 +18,7 @@ describe('HeaderComponent', () => {
     fixture.detectChanges();
   });
 
-  it('should create', () => {
+  it("should create", () => {
     expect(component).toBeTruthy();
   });
 });
diff --git a/Frontend Angular 4/src/app/shared/components/header/header.component.ts b/Frontend Angular 4/src/app/shared/components/header/header.component.ts
index 5479ed5a..7eefc9c5 100755
--- a/Frontend Angular 4/src/app/shared/components/header/header.component.ts	
+++ b/Frontend Angular 4/src/app/shared/components/header/header.component.ts	
@@ -1,43 +1,46 @@
-import { Component, OnInit } from '@angular/core';
-import { Router } from '@angular/router';
-import { AuthenticationService } from '../../services/authentication.service';
-import { SessionService } from '../../services/session.service';
-import { GHCIService } from '../../services/ghci.service';
-import { Usuario } from '../../objects/usuario';
-import { TranslateService } from '@ngx-translate/core';
+import { Component, OnInit } from "@angular/core";
+import { Router } from "@angular/router";
+import { AuthenticationService } from "../../services/authentication.service";
+import { SessionService } from "../../services/session.service";
+import { GHCIService } from "../../services/ghci.service";
+import { Usuario } from "../../objects/usuario";
+import { TranslateService } from "@ngx-translate/core";
 
 @Component({
-    selector: 'app-header',
-    templateUrl: './header.component.html',
-    styleUrls: ['./header.component.scss']
+  selector: "app-header",
+  templateUrl: "./header.component.html",
+  styleUrls: ["./header.component.scss"],
 })
 export class HeaderComponent implements OnInit {
-    usuario: Usuario;
-    translateService: any;
-    constructor(
-        private authService: AuthenticationService, 
-        private router : Router, 
-        private sessionService : SessionService,
-        private ghciService : GHCIService,
-        public translate: TranslateService) {
-        this.translateService = translate;
-        this.usuario = authService.getUser();
-    }
-    ngOnInit() {}
+  usuario: Usuario;
+  translateService: any;
+  constructor(
+    private authService: AuthenticationService,
+    private router: Router,
+    private sessionService: SessionService,
+    private ghciService: GHCIService,
+    public translate: TranslateService
+  ) {
+    this.translateService = translate;
+    this.usuario = authService.getUser();
+  }
+  ngOnInit() {}
 
-    toggleSidebar(event) {
-        event.stopPropagation();
-        const dom: any = document.querySelector('body');
-        dom.classList.toggle('push-right');
-    }
-    rltAndLtr() {
-        const dom: any = document.querySelector('body');
-        dom.classList.toggle('rtl');
-    }
+  toggleSidebar(event) {
+    event.stopPropagation();
+    const dom: any = document.querySelector("body");
+    dom.classList.toggle("push-right");
+  }
+  rltAndLtr() {
+    const dom: any = document.querySelector("body");
+    dom.classList.toggle("rtl");
+  }
 
-    logout(){
-        this.sessionService.reset();
-        this.ghciService.desconectarWS();
-        this.router.navigate(['/'+this.translateService.get('i18n.code').value+'/login']);
-    }
+  logout() {
+    this.sessionService.reset();
+    this.ghciService.desconectarWS();
+    this.router.navigate([
+      "/" + this.translateService.get("i18n.code").value + "/login",
+    ]);
+  }
 }
diff --git a/Frontend Angular 4/src/app/shared/components/index.ts b/Frontend Angular 4/src/app/shared/components/index.ts
index 85f05120..70e2ed00 100755
--- a/Frontend Angular 4/src/app/shared/components/index.ts	
+++ b/Frontend Angular 4/src/app/shared/components/index.ts	
@@ -1,2 +1,2 @@
-export * from './header/header.component';
-export * from './sidebar/sidebar.component';
+export * from "./header/header.component";
+export * from "./sidebar/sidebar.component";
diff --git a/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.spec.ts b/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.spec.ts
index f29709fd..8999833a 100755
--- a/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.spec.ts	
+++ b/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.spec.ts	
@@ -1,16 +1,15 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
 
-import { SidebarComponent } from './sidebar.component';
+import { SidebarComponent } from "./sidebar.component";
 
-describe('SidebarComponent', () => {
+describe("SidebarComponent", () => {
   let component: SidebarComponent;
   let fixture: ComponentFixture<SidebarComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ SidebarComponent ]
-    })
-    .compileComponents();
+      declarations: [SidebarComponent],
+    }).compileComponents();
   }));
 
   beforeEach(() => {
@@ -19,7 +18,7 @@ describe('SidebarComponent', () => {
     fixture.detectChanges();
   });
 
-  it('should create', () => {
+  it("should create", () => {
     expect(component).toBeTruthy();
   });
 });
diff --git a/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.ts b/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.ts
index fa8516b9..b5d68430 100755
--- a/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.ts	
+++ b/Frontend Angular 4/src/app/shared/components/sidebar/sidebar.component.ts	
@@ -1,62 +1,59 @@
-import { Component, HostListener, ViewChild, ElementRef } from '@angular/core';
+import { Component, HostListener, ViewChild, ElementRef } from "@angular/core";
 
-import { AuthenticationService } from '../../services/authentication.service';
-import { Usuario } from '../../objects/usuario';
+import { AuthenticationService } from "../../services/authentication.service";
+import { Usuario } from "../../objects/usuario";
 
 @Component({
-    selector: 'app-sidebar',
-    templateUrl: './sidebar.component.html',
-    styleUrls: ['./sidebar.component.scss']
+  selector: "app-sidebar",
+  templateUrl: "./sidebar.component.html",
+  styleUrls: ["./sidebar.component.scss"],
 })
 export class SidebarComponent {
-    isActive = false;
-    showMenu = '';
+  isActive = false;
+  showMenu = "";
 
-    usuario: Usuario;
+  usuario: Usuario;
 
-    constructor(private authService: AuthenticationService) {
-        this.usuario = authService.getUser();
-    }
-
-    eventCalled() {
-        this.isActive = !this.isActive;
-    }
-
-    addExpandClass(element: any) {
-        if (element === this.showMenu) {
-            this.showMenu = '0';
-        } else {
-            this.showMenu = element;
-        }
-    }
-
-    toggleSidebar() {
-        const dom: any = document.querySelector('body');
-        dom.classList.toggle('push-right');
-    }
+  constructor(private authService: AuthenticationService) {
+    this.usuario = authService.getUser();
+  }
 
-    esAlumno(){
-        return this.usuario.tipo == "alumno";
-    }
+  eventCalled() {
+    this.isActive = !this.isActive;
+  }
 
-    esDocente(){
-        return this.usuario.tipo == "docente";
+  addExpandClass(element: any) {
+    if (element === this.showMenu) {
+      this.showMenu = "0";
+    } else {
+      this.showMenu = element;
     }
-
-    @ViewChild('sidebarNav') sidebarNav: ElementRef;
-
-    @HostListener('document:click', ['$event'])
-    private documentClicked(event: MouseEvent): void {
-
-        // Nav is open
-        const dom: any = document.querySelector('body');
-        if(dom.classList.contains('push-right')){
-            // Not clicked on self element
-            if (!this.sidebarNav.nativeElement.contains(event.target)) {
-                
-                dom.classList.remove('push-right');
-            }
-        }
+  }
+
+  toggleSidebar() {
+    const dom: any = document.querySelector("body");
+    dom.classList.toggle("push-right");
+  }
+
+  esAlumno() {
+    return this.usuario.tipo == "alumno";
+  }
+
+  esDocente() {
+    return this.usuario.tipo == "docente";
+  }
+
+  @ViewChild("sidebarNav") sidebarNav: ElementRef;
+
+  @HostListener("document:click", ["$event"])
+  private documentClicked(event: MouseEvent): void {
+    // Nav is open
+    const dom: any = document.querySelector("body");
+    if (dom.classList.contains("push-right")) {
+      // Not clicked on self element
+      if (!this.sidebarNav.nativeElement.contains(event.target)) {
+        dom.classList.remove("push-right");
+      }
     }
-
+  }
 }
diff --git a/Frontend Angular 4/src/app/shared/directives/closePopover.directive.ts b/Frontend Angular 4/src/app/shared/directives/closePopover.directive.ts
index dfdf151f..89aa27f0 100755
--- a/Frontend Angular 4/src/app/shared/directives/closePopover.directive.ts	
+++ b/Frontend Angular 4/src/app/shared/directives/closePopover.directive.ts	
@@ -1,28 +1,28 @@
-import { Directive, HostListener, ElementRef, ComponentRef } from '@angular/core';
-import { NgbPopover } from '@ng-bootstrap/ng-bootstrap';
-import { NgbPopoverWindow } from '@ng-bootstrap/ng-bootstrap/popover/popover';
+import {
+  Directive,
+  HostListener,
+  ElementRef,
+  ComponentRef,
+} from "@angular/core";
+import { NgbPopover } from "@ng-bootstrap/ng-bootstrap";
+import { NgbPopoverWindow } from "@ng-bootstrap/ng-bootstrap/popover/popover";
 
 @Directive({
-  selector: '[closePopoverDirective][ngbPopover]'
+  selector: "[closePopoverDirective][ngbPopover]",
 })
 export class ClosePopoverDirective {
+  constructor(private elementRef: ElementRef, private ngbPopover: NgbPopover) {}
 
-  constructor(private elementRef: ElementRef,
-              private ngbPopover: NgbPopover) {
-
-  }
-
-  @HostListener('document:click', ['$event'])
+  @HostListener("document:click", ["$event"])
   private documentClicked(event: MouseEvent): void {
-
     // Popover is open
     if (this.ngbPopover && this.ngbPopover.isOpen()) {
-
       // Not clicked on self element
       if (!this.elementRef.nativeElement.contains(event.target)) {
-
         // Hacking typescript to access private member
-        const popoverWindowRef: ComponentRef<NgbPopoverWindow> = (this.ngbPopover as any)._windowRef;
+        const popoverWindowRef: ComponentRef<NgbPopoverWindow> = (
+          this.ngbPopover as any
+        )._windowRef;
 
         // If clicked outside popover window
         if (!popoverWindowRef.location.nativeElement.contains(event.target)) {
@@ -31,4 +31,4 @@ export class ClosePopoverDirective {
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/shared/directives/directives.module.ts b/Frontend Angular 4/src/app/shared/directives/directives.module.ts
index a453056c..00898e50 100755
--- a/Frontend Angular 4/src/app/shared/directives/directives.module.ts	
+++ b/Frontend Angular 4/src/app/shared/directives/directives.module.ts	
@@ -1,9 +1,9 @@
-import { NgModule } from '@angular/core';
-import { ClosePopoverDirective } from './closePopover.directive';
+import { NgModule } from "@angular/core";
+import { ClosePopoverDirective } from "./closePopover.directive";
 
 @NgModule({
-    imports: [],
-    declarations: [ClosePopoverDirective],
-    exports: [ClosePopoverDirective]
+  imports: [],
+  declarations: [ClosePopoverDirective],
+  exports: [ClosePopoverDirective],
 })
-export class DirectivesModule { }
+export class DirectivesModule {}
diff --git a/Frontend Angular 4/src/app/shared/guards/auth.guard.spec.ts b/Frontend Angular 4/src/app/shared/guards/auth.guard.spec.ts
index 7ed05ee8..8bfbefa1 100755
--- a/Frontend Angular 4/src/app/shared/guards/auth.guard.spec.ts	
+++ b/Frontend Angular 4/src/app/shared/guards/auth.guard.spec.ts	
@@ -1,15 +1,15 @@
-import { TestBed, async, inject } from '@angular/core/testing';
+import { TestBed, async, inject } from "@angular/core/testing";
 
-import { AuthGuard } from './auth.guard';
+import { AuthGuard } from "./auth.guard";
 
-describe('AuthGuard', () => {
+describe("AuthGuard", () => {
   beforeEach(() => {
     TestBed.configureTestingModule({
-      providers: [AuthGuard]
+      providers: [AuthGuard],
     });
   });
 
-  it('should ...', inject([AuthGuard], (guard: AuthGuard) => {
+  it("should ...", inject([AuthGuard], (guard: AuthGuard) => {
     expect(guard).toBeTruthy();
   }));
 });
diff --git a/Frontend Angular 4/src/app/shared/guards/auth.guard.ts b/Frontend Angular 4/src/app/shared/guards/auth.guard.ts
index ff9416ba..90296cad 100755
--- a/Frontend Angular 4/src/app/shared/guards/auth.guard.ts	
+++ b/Frontend Angular 4/src/app/shared/guards/auth.guard.ts	
@@ -1,22 +1,31 @@
-import { Injectable } from '@angular/core';
-import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
-import { Observable } from 'rxjs/Observable';
-import { TranslateService } from '@ngx-translate/core';
+import { Injectable } from "@angular/core";
+import {
+  CanActivate,
+  ActivatedRouteSnapshot,
+  RouterStateSnapshot,
+  Router,
+} from "@angular/router";
+import { Observable } from "rxjs/Observable";
+import { TranslateService } from "@ngx-translate/core";
 
 @Injectable()
 export class AuthGuard implements CanActivate {
   translateService: any;
 
-	constructor(private router: Router, public translate: TranslateService){
+  constructor(private router: Router, public translate: TranslateService) {
     this.translateService = translate;
-	}
+  }
 
-  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
-    
-    if(sessionStorage.getItem('currentUser')){
-    	return true;
+  canActivate(
+    next: ActivatedRouteSnapshot,
+    state: RouterStateSnapshot
+  ): Observable<boolean> | Promise<boolean> | boolean {
+    if (sessionStorage.getItem("currentUser")) {
+      return true;
     }
-    this.router.navigate(['/'+this.translateService.get('i18n.code').value+'/login']);
+    this.router.navigate([
+      "/" + this.translateService.get("i18n.code").value + "/login",
+    ]);
     return false;
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/shared/index.ts b/Frontend Angular 4/src/app/shared/index.ts
index f1bd6837..4edcd122 100755
--- a/Frontend Angular 4/src/app/shared/index.ts	
+++ b/Frontend Angular 4/src/app/shared/index.ts	
@@ -1,3 +1,3 @@
-export * from './pipes/shared-pipes.module';
-export * from './components';
-export * from './modules';
+export * from "./pipes/shared-pipes.module";
+export * from "./components";
+export * from "./modules";
diff --git a/Frontend Angular 4/src/app/shared/modal/confirm.component.ts b/Frontend Angular 4/src/app/shared/modal/confirm.component.ts
index f6c7eb39..5d8b36c4 100755
--- a/Frontend Angular 4/src/app/shared/modal/confirm.component.ts	
+++ b/Frontend Angular 4/src/app/shared/modal/confirm.component.ts	
@@ -1,42 +1,49 @@
-import { Component } from '@angular/core';
+import { Component } from "@angular/core";
 import { DialogComponent, DialogService } from "ng2-bootstrap-modal";
 export interface ConfirmModel {
-  title:string;
-  message:string;
+  title: string;
+  message: string;
   confirmText: string;
-  cancelText:string;
+  cancelText: string;
 }
-@Component({  
-    selector: 'confirm',
-    template: `<div class="modal-dialog" style="margin-top:100px;">
-                <div class="modal-content">
-                   <div class="modal-header">
-                     <h4 class="modal-title">{{title || 'Confirm'}}</h4>
-                     <button type="button" class="close" (click)="close()" >&times;</button>
-                   </div>
-                   <div class="modal-body">
-                     <p style="white-space: pre;">{{message || ''}}</p>
-                   </div>
-                   <div class="modal-footer">
-                     <button type="button" class="btn btn-primary" (click)="confirm()">{{confirmText || "i18n.action.confirm" | translate | titleCase }}</button>
-                     <button type="button" class="btn btn-default" (click)="close()" >{{cancelText || "i18n.action.cancel" | translate | titleCase }}</button>
-                   </div>
-                 </div>
-              </div>`
+@Component({
+  selector: "confirm",
+  template: `<div class="modal-dialog" style="margin-top:100px;">
+    <div class="modal-content">
+      <div class="modal-header">
+        <h4 class="modal-title">{{ title || "Confirm" }}</h4>
+        <button type="button" class="close" (click)="close()">&times;</button>
+      </div>
+      <div class="modal-body">
+        <p style="white-space: pre;">{{ message || "" }}</p>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-primary" (click)="confirm()">
+          {{ confirmText || "i18n.action.confirm" | translate | titleCase }}
+        </button>
+        <button type="button" class="btn btn-default" (click)="close()">
+          {{ cancelText || "i18n.action.cancel" | translate | titleCase }}
+        </button>
+      </div>
+    </div>
+  </div>`,
 })
-export class ConfirmComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
+export class ConfirmComponent
+  extends DialogComponent<ConfirmModel, boolean>
+  implements ConfirmModel
+{
   title: string;
   message: string;
   confirmText: string;
-  cancelText:string;
+  cancelText: string;
 
   constructor(dialogService: DialogService) {
     super(dialogService);
   }
   confirm() {
-    // we set dialog result as true on click on confirm button, 
-    // then we can get dialog result from caller code 
+    // we set dialog result as true on click on confirm button,
+    // then we can get dialog result from caller code
     this.result = true;
     this.close();
   }
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/shared/modules/index.ts b/Frontend Angular 4/src/app/shared/modules/index.ts
index b20424b7..e250faf0 100755
--- a/Frontend Angular 4/src/app/shared/modules/index.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/index.ts	
@@ -1,3 +1,3 @@
-export * from './stat/stat.module';
-export * from './page-header/page-header.module';
-export * from './translate/i18n.module';
+export * from "./stat/stat.module";
+export * from "./page-header/page-header.module";
+export * from "./translate/i18n.module";
diff --git a/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.spec.ts b/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.spec.ts
index 8b7949da..91176d2d 100755
--- a/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.spec.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.spec.ts	
@@ -1,16 +1,15 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
 
-import { PageHeaderComponent } from './page-header.component';
+import { PageHeaderComponent } from "./page-header.component";
 
-describe('PageHeaderComponent', () => {
+describe("PageHeaderComponent", () => {
   let component: PageHeaderComponent;
   let fixture: ComponentFixture<PageHeaderComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ PageHeaderComponent ]
-    })
-    .compileComponents();
+      declarations: [PageHeaderComponent],
+    }).compileComponents();
   }));
 
   beforeEach(() => {
@@ -19,7 +18,7 @@ describe('PageHeaderComponent', () => {
     fixture.detectChanges();
   });
 
-  it('should create', () => {
+  it("should create", () => {
     expect(component).toBeTruthy();
   });
 });
diff --git a/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.ts b/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.ts
index 7bc689cd..aab4179a 100755
--- a/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/page-header/page-header.component.ts	
@@ -1,11 +1,11 @@
-import { Component, Input } from '@angular/core';
+import { Component, Input } from "@angular/core";
 
 @Component({
-    selector: 'app-page-header',
-    templateUrl: './page-header.component.html',
-    styleUrls: ['./page-header.component.scss']
+  selector: "app-page-header",
+  templateUrl: "./page-header.component.html",
+  styleUrls: ["./page-header.component.scss"],
 })
 export class PageHeaderComponent {
-    @Input() heading: string;
-    @Input() icon: string;
+  @Input() heading: string;
+  @Input() icon: string;
 }
diff --git a/Frontend Angular 4/src/app/shared/modules/page-header/page-header.module.ts b/Frontend Angular 4/src/app/shared/modules/page-header/page-header.module.ts
index a6ee69a6..5ddce8a1 100755
--- a/Frontend Angular 4/src/app/shared/modules/page-header/page-header.module.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/page-header/page-header.module.ts	
@@ -1,15 +1,12 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { RouterModule } from '@angular/router';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { RouterModule } from "@angular/router";
 
-import { PageHeaderComponent } from './page-header.component';
+import { PageHeaderComponent } from "./page-header.component";
 
 @NgModule({
-    imports: [
-        CommonModule,
-        RouterModule
-    ],
-    declarations: [PageHeaderComponent],
-    exports: [PageHeaderComponent]
+  imports: [CommonModule, RouterModule],
+  declarations: [PageHeaderComponent],
+  exports: [PageHeaderComponent],
 })
-export class PageHeaderModule { }
+export class PageHeaderModule {}
diff --git a/Frontend Angular 4/src/app/shared/modules/stat/stat.component.spec.ts b/Frontend Angular 4/src/app/shared/modules/stat/stat.component.spec.ts
index 4a9b50f6..85ffad5a 100755
--- a/Frontend Angular 4/src/app/shared/modules/stat/stat.component.spec.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/stat/stat.component.spec.ts	
@@ -1,16 +1,15 @@
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed } from "@angular/core/testing";
 
-import { StatComponent } from './stat.component';
+import { StatComponent } from "./stat.component";
 
-describe('StatComponent', () => {
+describe("StatComponent", () => {
   let component: StatComponent;
   let fixture: ComponentFixture<StatComponent>;
 
   beforeEach(async(() => {
     TestBed.configureTestingModule({
-      declarations: [ StatComponent ]
-    })
-    .compileComponents();
+      declarations: [StatComponent],
+    }).compileComponents();
   }));
 
   beforeEach(() => {
@@ -19,7 +18,7 @@ describe('StatComponent', () => {
     fixture.detectChanges();
   });
 
-  it('should create', () => {
+  it("should create", () => {
     expect(component).toBeTruthy();
   });
 });
diff --git a/Frontend Angular 4/src/app/shared/modules/stat/stat.component.ts b/Frontend Angular 4/src/app/shared/modules/stat/stat.component.ts
index 12aaca07..69ac8c29 100755
--- a/Frontend Angular 4/src/app/shared/modules/stat/stat.component.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/stat/stat.component.ts	
@@ -1,19 +1,19 @@
-import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
+import { Component, OnInit, Input, Output, EventEmitter } from "@angular/core";
 
 @Component({
-    selector: 'app-stat',
-    templateUrl: './stat.component.html',
-    styleUrls: ['./stat.component.scss']
+  selector: "app-stat",
+  templateUrl: "./stat.component.html",
+  styleUrls: ["./stat.component.scss"],
 })
 export class StatComponent implements OnInit {
-    @Input() bgClass: string;
-    @Input() icon: string;
-    @Input() count: number;
-    @Input() label: string;
-    @Input() data: number;
-    @Output() event: EventEmitter<any> = new EventEmitter();
+  @Input() bgClass: string;
+  @Input() icon: string;
+  @Input() count: number;
+  @Input() label: string;
+  @Input() data: number;
+  @Output() event: EventEmitter<any> = new EventEmitter();
 
-    constructor() { }
+  constructor() {}
 
-    ngOnInit() {}
+  ngOnInit() {}
 }
diff --git a/Frontend Angular 4/src/app/shared/modules/stat/stat.module.ts b/Frontend Angular 4/src/app/shared/modules/stat/stat.module.ts
index 7b30f1b3..7f3a03d4 100755
--- a/Frontend Angular 4/src/app/shared/modules/stat/stat.module.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/stat/stat.module.ts	
@@ -1,12 +1,10 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { StatComponent } from './stat.component';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { StatComponent } from "./stat.component";
 
 @NgModule({
-    imports: [
-        CommonModule
-    ],
-    declarations: [StatComponent],
-    exports: [StatComponent]
+  imports: [CommonModule],
+  declarations: [StatComponent],
+  exports: [StatComponent],
 })
-export class StatModule { }
+export class StatModule {}
diff --git a/Frontend Angular 4/src/app/shared/modules/titlecase.module.ts b/Frontend Angular 4/src/app/shared/modules/titlecase.module.ts
index d3a9d95b..2b28bde6 100755
--- a/Frontend Angular 4/src/app/shared/modules/titlecase.module.ts	
+++ b/Frontend Angular 4/src/app/shared/modules/titlecase.module.ts	
@@ -1,9 +1,9 @@
-import { NgModule } from '@angular/core';
-import { TitleCasePipe } from '../pipes/titlecase.pipe';
+import { NgModule } from "@angular/core";
+import { TitleCasePipe } from "../pipes/titlecase.pipe";
 
 @NgModule({
-    imports: [],
-    declarations: [TitleCasePipe],
-    exports: [TitleCasePipe]
+  imports: [],
+  declarations: [TitleCasePipe],
+  exports: [TitleCasePipe],
 })
-export class TitleCaseModule { }
\ No newline at end of file
+export class TitleCaseModule {}
diff --git a/Frontend Angular 4/src/app/shared/objects/archivo.ts b/Frontend Angular 4/src/app/shared/objects/archivo.ts
index 6090668e..b47b32d6 100755
--- a/Frontend Angular 4/src/app/shared/objects/archivo.ts	
+++ b/Frontend Angular 4/src/app/shared/objects/archivo.ts	
@@ -1,4 +1,4 @@
-export class Evaluacion{
+export class Evaluacion {
   evaluacionId: number;
   cedulaDocente: string;
   fecha: Date;
@@ -16,13 +16,10 @@ export class Archivo {
   padreId: number;
   archivoOrigenId: number;
   archivos: Archivo[];
-  directorio :boolean;
+  directorio: boolean;
   estado: string;
-  eliminado:boolean;
+  eliminado: boolean;
   evaluacion: Evaluacion;
-  
-  constructor(){
-  	
-  }
 
-}
\ No newline at end of file
+  constructor() {}
+}
diff --git a/Frontend Angular 4/src/app/shared/objects/grupo.ts b/Frontend Angular 4/src/app/shared/objects/grupo.ts
index 43bff477..91ae95fd 100755
--- a/Frontend Angular 4/src/app/shared/objects/grupo.ts	
+++ b/Frontend Angular 4/src/app/shared/objects/grupo.ts	
@@ -1,5 +1,5 @@
-import { Archivo } from './archivo';
-import { Usuario } from './usuario';
+import { Archivo } from "./archivo";
+import { Usuario } from "./usuario";
 
 export class Grupo {
   anio: number;
@@ -9,13 +9,19 @@ export class Grupo {
   archivos: Archivo[];
   alumnos: Usuario[];
 
-  constructor(anio: number, grado: number, grupo: string,liceoId:number, archivos: Archivo[], alumnos:Usuario[]){
+  constructor(
+    anio: number,
+    grado: number,
+    grupo: string,
+    liceoId: number,
+    archivos: Archivo[],
+    alumnos: Usuario[]
+  ) {
     this.anio = anio;
     this.grado = grado;
     this.grupo = grupo;
     this.liceoId = liceoId;
-    this.archivos = archivos;    
-    this.alumnos = alumnos;  	
+    this.archivos = archivos;
+    this.alumnos = alumnos;
   }
-
-}
\ No newline at end of file
+}
diff --git a/Frontend Angular 4/src/app/shared/objects/usuario.ts b/Frontend Angular 4/src/app/shared/objects/usuario.ts
index 4218c62b..97799949 100755
--- a/Frontend Angular 4/src/app/shared/objects/usuario.ts	
+++ b/Frontend Angular 4/src/app/shared/objects/usuario.ts	
@@ -1,15 +1,15 @@
-export class Configuracion{
-	themeEditor: string;
-	fontSizeEditor: number;
-	argumentoI:boolean;
-	argumentoF:boolean;
+export class Configuracion {
+  themeEditor: string;
+  fontSizeEditor: number;
+  argumentoI: boolean;
+  argumentoF: boolean;
 }
 
-export class Usuario{
-	token: string;
-	cedula: string;
-    nombre: string;
-    apellido: string;
-    tipo: string;
-    configuracion: Configuracion;
-}
\ No newline at end of file
+export class Usuario {
+  token: string;
+  cedula: string;
+  nombre: string;
+  apellido: string;
+  tipo: string;
+  configuracion: Configuracion;
+}
diff --git a/Frontend Angular 4/src/app/shared/pipes/filter.pipe.ts b/Frontend Angular 4/src/app/shared/pipes/filter.pipe.ts
index 0faa74c0..3df29f2e 100755
--- a/Frontend Angular 4/src/app/shared/pipes/filter.pipe.ts	
+++ b/Frontend Angular 4/src/app/shared/pipes/filter.pipe.ts	
@@ -1,12 +1,14 @@
-import { Pipe, PipeTransform } from '@angular/core';
+import { Pipe, PipeTransform } from "@angular/core";
 
 @Pipe({
-    name: 'filter',
-    pure: false
+  name: "filter",
+  pure: false,
 })
 export class FilterPipe implements PipeTransform {
-   transform(items: any[], field : string, value : string): any[] {  
-        if (!items) return [];        
-        return items.filter(it => it[field].toLowerCase().indexOf(value.toLowerCase()) != -1);
-    }
-}
\ No newline at end of file
+  transform(items: any[], field: string, value: string): any[] {
+    if (!items) return [];
+    return items.filter(
+      (it) => it[field].toLowerCase().indexOf(value.toLowerCase()) != -1
+    );
+  }
+}
diff --git a/Frontend Angular 4/src/app/shared/pipes/shared-pipes.module.ts b/Frontend Angular 4/src/app/shared/pipes/shared-pipes.module.ts
index b4b1c166..2553cccf 100755
--- a/Frontend Angular 4/src/app/shared/pipes/shared-pipes.module.ts	
+++ b/Frontend Angular 4/src/app/shared/pipes/shared-pipes.module.ts	
@@ -1,10 +1,8 @@
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
+import { NgModule } from "@angular/core";
+import { CommonModule } from "@angular/common";
 
 @NgModule({
-    imports: [
-        CommonModule
-    ],
-    declarations: []
+  imports: [CommonModule],
+  declarations: [],
 })
-export class SharedPipesModule { }
+export class SharedPipesModule {}
diff --git a/Frontend Angular 4/src/app/shared/pipes/titlecase.pipe.ts b/Frontend Angular 4/src/app/shared/pipes/titlecase.pipe.ts
index 78abdceb..c8211631 100755
--- a/Frontend Angular 4/src/app/shared/pipes/titlecase.pipe.ts	
+++ b/Frontend Angular 4/src/app/shared/pipes/titlecase.pipe.ts	
@@ -1,15 +1,20 @@
-import { Pipe, PipeTransform } from '@angular/core';
+import { Pipe, PipeTransform } from "@angular/core";
 
 /*
  * Changes the case of the first letter of a given number of words in a string.
-*/
+ */
 
 @Pipe({
-    name: 'titleCase',
-    pure: false
+  name: "titleCase",
+  pure: false,
 })
 export class TitleCasePipe implements PipeTransform {
-    transform(input:string, length: number): string{
-        return input.length > 0 ? input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() )) : '';
-    }
-}
\ No newline at end of file
+  transform(input: string, length: number): string {
+    return input.length > 0
+      ? input.replace(
+          /\w\S*/g,
+          (txt) => txt[0].toUpperCase() + txt.substr(1).toLowerCase()
+        )
+      : "";
+  }
+}
diff --git a/Frontend Angular 4/src/app/shared/services/authentication.service.ts b/Frontend Angular 4/src/app/shared/services/authentication.service.ts
index 0a8655e3..9b3c2ec5 100755
--- a/Frontend Angular 4/src/app/shared/services/authentication.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/authentication.service.ts	
@@ -1,53 +1,57 @@
-import { Injectable } from '@angular/core';
-import { Http, Headers, Response, RequestOptions } from '@angular/http';
-import { Observable } from 'rxjs/Observable';
-import { hash } from '../utils/sha1'
-import { Usuario } from '../objects/usuario';
-import 'rxjs/add/operator/map'
-import { SERVER } from '../config'; 
+import { Injectable } from "@angular/core";
+import { HttpClient, HttpHeaders } from "@angular/common/http";
+import { Observable } from "rxjs/Observable";
+import { hash } from "../utils/sha1";
+import { Usuario } from "../objects/usuario";
+import "rxjs/add/operator/map";
+import { SERVER } from "../config";
 
 @Injectable()
 export class AuthenticationService {
-    constructor(private http: Http) { }
-
-    login(cedula: string, password: string, language: string) {
-        let headers = new Headers({ 'Content-Type': 'application/json' });
-        let options = new RequestOptions({ headers: headers });
-        return this.http.post(SERVER+'/servicios/login', JSON.stringify({ "cedula": cedula, "password": password }),options)
-            .map((response: Response) => {
-                let user = response.json();
-                user.language = language;
-                sessionStorage.setItem('currentUser', JSON.stringify(user));
-            });
-    }
-
-    getUser():Usuario{
-        return JSON.parse(sessionStorage.getItem('currentUser'));
-    }
-
-    getUserConfig(){
-         return JSON.parse(sessionStorage.getItem('currentUser')).configuracion;;
-    }
-
-    getToken(){
-        var currentUser = JSON.parse(sessionStorage.getItem('currentUser'));
-        return currentUser? currentUser.token: undefined;
-    }
-
-    getLanguage() {
-        var currentUser = JSON.parse(sessionStorage.getItem('currentUser'));
-        return currentUser? currentUser.language: undefined;
-    }
-
-    setUserConfig(config){
-        var user = JSON.parse(sessionStorage.getItem('currentUser'));
-        user.configuracion = config;
-        sessionStorage.setItem('currentUser', JSON.stringify(user));
-    }
-
-
-    logout() {
-        // remove user from local storage to log user out
-        sessionStorage.removeItem('currentUser');
-    }
-}
\ No newline at end of file
+  constructor(private http: HttpClient) {}
+
+  login(cedula: string, password: string, language: string) {
+    let headers = new HttpHeaders({ "Content-Type": "application/json" });
+    let httpOptions = { headers: headers };
+
+    return this.http
+      .post(
+        SERVER + "/servicios/login",
+        JSON.stringify({ cedula: cedula, password: password }),
+        httpOptions
+      )
+      .map((response: any) => {
+        response.language = language;
+        sessionStorage.setItem("currentUser", JSON.stringify(response));
+      });
+  }
+
+  getUser(): Usuario {
+    return JSON.parse(sessionStorage.getItem("currentUser"));
+  }
+
+  getUserConfig() {
+    return JSON.parse(sessionStorage.getItem("currentUser")).configuracion;
+  }
+
+  getToken() {
+    var currentUser = JSON.parse(sessionStorage.getItem("currentUser"));
+    return currentUser ? currentUser.token : undefined;
+  }
+
+  getLanguage() {
+    var currentUser = JSON.parse(sessionStorage.getItem("currentUser"));
+    return currentUser ? currentUser.language : undefined;
+  }
+
+  setUserConfig(config) {
+    var user = JSON.parse(sessionStorage.getItem("currentUser"));
+    user.configuracion = config;
+    sessionStorage.setItem("currentUser", JSON.stringify(user));
+  }
+
+  logout() {
+    // remove user from local storage to log user out
+    sessionStorage.removeItem("currentUser");
+  }
+}
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 7d1e5da5..2d836939 100755
--- a/Frontend Angular 4/src/app/shared/services/ghci.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/ghci.service.ts	
@@ -1,543 +1,625 @@
-import { Injectable,ViewChild,ElementRef } from '@angular/core';
-import { Router } from '@angular/router';
-import { Observable, Subject } from 'rxjs/Rx';
-import { WebsocketService } from './websocket.service';
-import { AuthenticationService } from './authentication.service';
-import { GHCI_URL } from '../config';
-import { TranslateService } from '@ngx-translate/core';
-
-declare var $:any;
-declare var that :any ;
+import { Injectable, ViewChild, ElementRef } from "@angular/core";
+import { Router } from "@angular/router";
+import { Observable, Subject } from "rxjs/Rx";
+import { WebsocketService } from "./websocket.service";
+import { AuthenticationService } from "./authentication.service";
+import { GHCI_URL } from "../config";
+import { TranslateService } from "@ngx-translate/core";
+
+declare var $: any;
+declare var that: any;
 const regex = /^color (errores|input|output|logs) (\d)$/g;
 
-import 'tippy.js/dist/tippy';
+import "tippy.js/dist/tippy";
 
 @Injectable()
 export class GHCIService {
-	public messages: Subject<any> = new Subject<any>();
-	private connection = undefined;
-	private cons = undefined;
-	private modoAvanzado: boolean = false;     // indica si debe mostrarse todo lo que ocurre en el intérprete.
-	private clear:boolean = false;
-	private error :string ="";
-	private warnings: any = [];
-	private codemirrorRef :any = null;
-	private warningStepReaded :number = 0;
-	private waitingForError : boolean = false;
-	private waitingForWarning : boolean = false;
-	private waitingForWarning2 : boolean = false;
-	private warningText :string = "";
-	private errorText :string = "";
-	private lastError : number = -1;
-	private lastErrorFile :string = "";	
-	private lastWarning :number = -1;
-	private lastWarningFile :string = "";	
-	private currentFile :string = "";
-    translateService: any;
-
-	private console_error_class : string = "jqconsole-asd";
-
-	consoleBuffer = [];
-
-	constructor(private authService:AuthenticationService,private router: Router, public translate: TranslateService){
-		this.translateService = translate;
-		console.log("contructor ghci");
-		this.conectarWS(GHCI_URL, authService.getUser().cedula, authService.getToken(), authService.getLanguage());
-		setInterval( this.checkConnection.bind(this), 5000);	
-		setInterval( this.doPing.bind(this), 30000);	
-	}
-
-	setCodemirrorRef(instance){
-		this.codemirrorRef = instance;
-	}
-
-	clearWarnings(){
-		this.warnings = [];
-	}
-
-	getWarnings(){
-		return this.warnings;
-	}
-
-	loadFile(fileId, fileName, dependencias) {
-		this.waitingForWarning = true;
-		this.currentFile = fileName;
-		var message = {
-			'token': this.authService.getToken(),
-			'load': fileId,
-			'dependencias' :[]
-
-		};
-		for(var i in dependencias){
-			message.dependencias.push(dependencias[i]);
-		};
-		this.connection.send(JSON.stringify(message));
-	}
-	reiniciarInterprete(){
-		var message = {
-			'token': this.authService.getToken(),
-			'restart': ''
-		};
-		console.log(message);
-		this.connection.send(JSON.stringify(message));
-	}
-
-	regex: string  = '/(<svg.*\s*.*<\/svg>)/g';
-	
-	consoleRef:any;
-
-	
-	conectarWS(wsUrl, cedula, token, language){
-		if(cedula && token && (!this.connection || this.connection.readyState == WebSocket.CLOSED)){
-			this.connection = new WebSocket(wsUrl+"/"+cedula+"/"+token+"/"+language);
-
-			this.connection.onopen = function(){
-				console.log('Conexión con web socket exitosa');
-			}
-			this.connection.onclose = function(reason){
-				//Codigo que indica la falta de permisos (sesion expirada por ejemplo)
-				if(reason.code == 1008){
-					this.router.navigate(['/'+this.translateService.get('i18n.code').value+'/login']);
-				}
-				console.log('Conexión con web socket cerrada',reason);
-			}.bind(this)
-			this.connection.onmessage = this.onMessage.bind(this);
-		}
-	}
-
-	desconectarWS(){
-		if(this.connection){
-			this.connection.close();
-		}
-	}
-
-	logConsole(text){
-		if(this.consoleRef){
-			this.consoleRef.Write(text, 'jqconsole-logs'); 
-		}else{
-			this.consoleBuffer.unshift({text: text, type:'jqconsole-logs'})
-			setTimeout(this.checkConsole.bind(this),100);
-		}
-	}
-
-	outputConsole(text){
-		if(this.consoleRef){
-			this.consoleRef.Write(text, 'jqconsole-output'); 
-		}else{
-			this.consoleBuffer.unshift({text: text, type:'jqconsole-output'})
-			setTimeout(this.checkConsole.bind(this),100);
-		}
-	}
-
-	errorConsole(text){
-		if(this.consoleRef){
-			this.consoleRef.Write(text, 'jqconsole-errors'); 
-		}else{
-			this.consoleBuffer.unshift({text: text, type:'jqconsole-errors'})
-			setTimeout(this.checkConsole.bind(this),100);
-		}
-	}
-	hayError(text){
-		var line = -1;
-		if(this.waitingForError){
-			var line = this.lastError;
-			var columna = this.errorText.split(`${this.translateService.get('i18n.codemirror.command.column').value}:`)[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;
-
-			if((this.currentFile.toLowerCase() == this.lastErrorFile.toLowerCase()) && (this.codemirrorRef!==null)){
-				var makeMarker = function() {
-					var marker = document.createElement("div");
-					marker.id = "error_" + line.toString();
-					marker.style.width = "15px";
-					marker.title = ErrorFinalText;
-					marker.style.height = "15px";
-					marker.style.marginLeft = "-5px";
-					marker.style.cursor = "pointer";
-					marker.style["background-image"] = "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=')";
-					marker.innerHTML = "<a href='@' title='cuidado , advertencia matefun'></a>";
-					return marker;
-				}
-				this.codemirrorRef.setGutterMarker(line, "breakpoints", makeMarker());
-				this.waitingForError = false;
-				this.lastError = -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]; 
-
-				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;
-
-				this.waitingForError = true;	
-				this.lastError = line;
-				this.lastErrorFile = file;
-				this.errorText = m.resultado.split(`${this.translateService.get('i18n.codemirror.command.outError').value}:`)[1].trim();
-			}catch(err){
-			}
-			return false;
-
-		}
-
-	}
-	
-	resetGutters(){
-		if(this.codemirrorRef!==null){
-			this.codemirrorRef.clearGutter("breakpoints");
-		}
-	}
-	
-	hayWarnings(text){
-		
-		var line = -1;
-		var m = JSON.parse(text);
-		
-		if(this.warningStepReaded===1){
-			try{
-				var warningText2 = m.resultado.split("OUT")[1].trim();
-				this.warningStepReaded = 2;
-				this.warningText = this.warningText + '\n\n' +  warningText2;
-
-				var line = this.lastWarning;
-				var title = this.warningText;
-
-				var columna = title.split(`${this.translateService.get('i18n.codemirror.command.column').value}:`)[1].split("}")[0];
-				var warningTextToShow = title.split("}")[1];
-
-				var warningFinalText = `${this.translateService.get('i18n.codemirror.command.inColumn').value}` + columna + ": " + warningTextToShow;
-
-				if((this.currentFile.toLowerCase() == this.lastWarningFile.toLowerCase()) && (this.codemirrorRef!==null)){
-					var makeMarker = function() {
-						var marker = document.createElement("div");
-						marker.style.width = "15px";
-						marker.style.height = "15px";
-						marker.style.marginLeft = "-5px";
-						marker.style.cursor = "pointer";
-						marker.innerHTML = "<a href='@' title='cuidado , advertencia matefun'></a>";
-						marker.title = warningFinalText;
-						marker.style["background-image"] = "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=')";
-						marker.innerHTML = "";
-						return marker;
-					}
-					this.codemirrorRef.setGutterMarker(line, "breakpoints", makeMarker());
-				}
-
-			}catch(err){
-
-			}
-		}
-
-		if(this.warningStepReaded===0){
-
-			try{ 
-				var file = m.resultado
-					.split(`${this.translateService.get('i18n.codemirror.command.outWarning').value}:`)[1]
-					.trim()
-					.split(`${this.translateService.get('i18n.object.file').value}:`)[1]
-					.split(" ")[1]; 
-					
-			   
-					
-				// retrive line of warning
-				var line = m.resultado
-					.split(`${this.translateService.get('i18n.codemirror.command.outWarning').value}:`)[1]
-					.trim()
-					.split(`${this.translateService.get('i18n.codemirror.command.line').value}:`)[1]
-					.split(" ")[1]-1;
-
-				this.lastWarning = line;
-				this.lastWarningFile = file;
-				this.warnings.push(line);
-				var warningText = m.resultado.split(`${this.translateService.get('i18n.codemirror.command.outWarning').value}:`)[1].trim();
-				this.warningStepReaded = 1;
-				this.warningText = warningText;
-				if(this.waitingForWarning){
-
-					this.outputConsole(`${this.translateService.get('i18n.msg.codemirror.consoleWarnings').value}\n`);
-					this.waitingForWarning = false;	
-				}
-
-			} catch(err){
-
-			}
-
-		}
-
-		
-	}
-
-	onMessage(e){
-		if(this.modoAvanzado){
-			this.logConsole('Respuesta: ' + e.data + '\n');
-		}
-		if(this.clear){
-			this.clearConsole();
-		}
-		var server_message = e.data;
-
-		if(this.hayError(server_message)){
-			this.error = "Error";
-		} else {
-			this.error = "";
-		}
-		
-		this.hayWarnings(server_message);
-
-		if(this.warningStepReaded==2){
-			this.warningStepReaded = 0;
-			return;
-		} else if(this.warningStepReaded==1){
-			return;
-		}
-
-		var json_server_message = JSON.parse(server_message);
-		if(json_server_message.tipo=='salida'){
-
-
-			var line = json_server_message.resultado.trim();
-			if(line.startsWith("OUT")){
-				this.outputConsole(line.substring(3) + '\n');     
-			}else if(line.startsWith("IN")){
-				var promptText = line.substring(3);
-				if(this.consoleRef===undefined){
-					this.renderConsole();
-				}
-				this.consoleRef.SetPromptLabel(promptText);
-				this.consoleRef.SetPromptText('');
-				this.startPrompt.bind(this);
-				this.startPrompt();
-			}
-
-			
-
-		} else if (json_server_message.tipo=='error'){
-			if(this.modoAvanzado){
-				this.errorConsole(json_server_message.resultado  + '\n');	
-			}
-		} else if (json_server_message.tipo == 'prompt'){
-			// console.log(json_server_message.resultado);
-			// console.log(this.consoleRef);
-			// console.log(this.consoleRef.SetPromptLabel);
-			// this.consoleRef.SetPromptLabel.bind(this);
-			this.consoleRef.SetPromptLabel(json_server_message.resultado+'>');
-			this.consoleRef.SetPromptText('');
-			this.startPrompt.bind(this);
-			this.startPrompt();
-			// console.log(x);
-		} else if (json_server_message.tipo == 'canvas' || 
-			json_server_message.tipo == 'animacion' || 
-			json_server_message.tipo == 'graph') {
-			document.getElementById("FigurasBtn2D").click()
-			this.focusConsole();
-			this.messages.next(json_server_message);
-		} else if  (json_server_message.tipo == 'canvas3D' || 
-			json_server_message.tipo == 'animacion3D') {
-			document.getElementById("FigurasBtn3D").click()
-			this.focusConsole();
-			this.messages.next(json_server_message);
-		}
-
-	}
-
-	checkConsole(){
-		if(this.consoleRef){
-			while(this.consoleBuffer.length > 0){
-				var bufferedMessage = this.consoleBuffer.pop();
-				this.consoleRef.Write(bufferedMessage.text,bufferedMessage.type);
-			}
-		}else{
-			setTimeout(this.checkConsole.bind(this),500);
-		}
-	}
-
-	checkConnection(){
-		var usuario = this.authService.getUser();
-		var token = this.authService.getToken();
-		var language = this.authService.getLanguage();
-		if(usuario && token && (!this.connection || this.connection.readyState == WebSocket.CLOSED)){
-			this.conectarWS(GHCI_URL, usuario.cedula, token, language);
-		}		
-	}
-
-	doPing(){
-		var token = this.authService.getToken();
-		if(this.connection && this.connection.readyState == WebSocket.OPEN && token){
-			var message = {
-				'token': token,
-				'ping': ''
-			};
-			this.connection.send(JSON.stringify(message));
-		}		
-	}
-
-	sendLine(line) {
-		if(line.trim()!==""){
-			var message = {
-				'token': this.authService.getToken(),
-				'comando': line
-			};
-			console.log(message);
-			if(this.connection && this.connection.readyState == WebSocket.OPEN){
-				this.connection.send(JSON.stringify(message));
-			}else{
-				this.errorConsole("Sin conexión al servidor...\n");
-			}
-		}
-	}
-
-	startPrompt() {
-		// Start the prompt with history enabled.
-		this.jqconsole.Prompt(true, this.callback.bind(this));
-		this.jqconsole.RegisterMatching('(', ')', 'paran');
-	};
-
-	focusConsole(){
-		this.jqconsole.Focus();
-	};
-
-	clearConsole(){
-		this.consoleRef.Reset();
-		this.startPrompt.bind(this);
-		this.startPrompt();
-		this.clear = false;
-	};
-
-	callback(input){
-		// Output input with the class jqconsole-output. 
-		var ejecutar: boolean;
-		ejecutar = this.procesarInput(input);
-		if(ejecutar) {
-			if(this.modoAvanzado){
-				this.logConsole("Ejecutar: " + input + '\n');
-			}
-			this.sendLine.bind(this);
-			this.sendLine(input);
-		}
-		this.startPrompt.bind(this);
-		this.startPrompt();
-	}
-
-	procesarInput(input){
-		var _input: string;
-		var send: boolean = false;
-		_input = input.trim().toLocaleLowerCase();
-		if(_input==="limpiar"){
-			this.clearConsole();
-		} else if(_input==="modo avanzado") {
-			this.modoAvanzado= true;
-			this.logConsole("Modo avanzado activado\n");
-		} else if(_input==="modo normal"){
-			this.modoAvanzado= false;
-			this.logConsole("Modo avanzado desactivado\n");
-		} else if(_input==="listar colores"){
-			this.outputConsole("1 - Azul\n");
-			this.outputConsole("2 - Rojo\n");
-			this.outputConsole("3 - Verde\n");
-			this.outputConsole("4 - Verde oscuro\n");
-			this.outputConsole("5 - Blanco\n");
-			this.outputConsole("6 - Naranja\n");
-			this.outputConsole("7 - Gris\n");
-			this.outputConsole("8 - Gris oscuro\n");
-			this.outputConsole("9 - Marrón\n");
-		} else if(_input.match(regex)!==null) {
-			var _tipoTexto :string = _input.split(" ")[1];
-			var _color : string = input.split(" ")[2];
-			this.jqconsoleColor(_color,_tipoTexto);
-			if(this.modoAvanzado){
-				this.logConsole("Color " + _tipoTexto + " seleccionado\n");	
-			}
-		} else {
-			send = true;
-		}	
-		return send;
-	}
-
-	getCSSColorName(n){
-		if(n==="1"){
-			return "rgb(77, 77, 255)";
-		} else if(n==="2"){
-			return "rgb(255, 26, 26)";
-		} else if (n==="3"){
-			return "rgb(0, 179, 60)";
-		} else if(n==="4"){
-			return "rgb(0, 77, 0)";
-		} else if(n==="5"){
-			return "rgb(255, 255, 255)";
-		} else if(n==="6"){
-			return "rgb(255, 133, 51)";
-		} else if(n==="7"){
-			return "rgb(204, 204, 179)";
-		} else if(n==="8"){
-			return "rgb(102, 102, 102)";
-		} else if(n==="9"){
-			return "rgb(101, 27, 27)";
-		}
-	}
-
-	getJQConsoleClass(jqconsoletext){
-		if(jqconsoletext==="input"){
-			return '.jqconsole-prompt';
-		} else if(jqconsoletext==="error"){
-			return '.jqconsole-error';
-		} else if (jqconsoletext==="logs"){
-			return '.jqconsole-logs';
-		} else if(jqconsoletext==="output"){
-			return '.jqconsole-output';
-		}
-	}
-
-	jqconsoleColor(color, clase){
-		var cssColor:string = this.getCSSColorName(color);
-		var jqConsoleClass: string = this.getJQConsoleClass(clase);
-
-
-		var style = document.createElement('style');
-		style.type = 'text/css';
-		style.innerHTML = jqConsoleClass +' { color: ' + cssColor + '; }';
-		document.getElementsByTagName('head')[0].appendChild(style);
-
-		if(jqConsoleClass==='.jqconsole-prompt'){
-			var style2 = document.createElement('style');
-			style2.type = 'text/css';
-			style2.innerHTML = '.jqconsole-old-prompt { color: ' + cssColor + '; }';
-			document.getElementsByTagName('head')[0].appendChild(style2);
-		}
-
-	}
-
-	consola: any=undefined;
-	renderConsole(){
-		if(this.jqconsole){
-			$('#console').replaceWith(this.consola);
-		}else{
-			if ($("#console").jqconsole!=undefined){ // Check if element has been found
-				this.jqconsole = $("#console").jqconsole('');
-				this.consoleRef = this.jqconsole;
-				this.startPrompt.bind(this);
-				this.startPrompt();
-			} else {
-				this.rendered();
-			}
-			this.consola = $("#console");
-			
-
-		}
-	}
-
-	jqconsole:any = undefined;
-	rendered(){
-		setTimeout(this.renderConsole.bind(this),1000);
-	}
-
-
-
+  public messages: Subject<any> = new Subject<any>();
+  private connection = undefined;
+  private cons = undefined;
+  private modoAvanzado: boolean = false; // indica si debe mostrarse todo lo que ocurre en el intérprete.
+  private clear: boolean = false;
+  private error: string = "";
+  private warnings: any = [];
+  private codemirrorRef: any = null;
+  private warningStepReaded: number = 0;
+  private waitingForError: boolean = false;
+  private waitingForWarning: boolean = false;
+  private waitingForWarning2: boolean = false;
+  private warningText: string = "";
+  private errorText: string = "";
+  private lastError: number = -1;
+  private lastErrorFile: string = "";
+  private lastWarning: number = -1;
+  private lastWarningFile: string = "";
+  private currentFile: string = "";
+  translateService: any;
+
+  private console_error_class: string = "jqconsole-asd";
+
+  consoleBuffer = [];
+
+  constructor(
+    private authService: AuthenticationService,
+    private router: Router,
+    public translate: TranslateService
+  ) {
+    this.translateService = translate;
+    console.log("contructor ghci");
+    this.conectarWS(
+      GHCI_URL,
+      authService.getUser().cedula,
+      authService.getToken(),
+      authService.getLanguage()
+    );
+    setInterval(this.checkConnection.bind(this), 5000);
+    setInterval(this.doPing.bind(this), 30000);
+  }
+
+  setCodemirrorRef(instance) {
+    this.codemirrorRef = instance;
+  }
+
+  clearWarnings() {
+    this.warnings = [];
+  }
+
+  getWarnings() {
+    return this.warnings;
+  }
+
+  loadFile(fileId, fileName, dependencias) {
+    this.waitingForWarning = true;
+    this.currentFile = fileName;
+    var message = {
+      token: this.authService.getToken(),
+      load: fileId,
+      dependencias: [],
+    };
+    for (var i in dependencias) {
+      message.dependencias.push(dependencias[i]);
+    }
+    this.connection.send(JSON.stringify(message));
+  }
+  reiniciarInterprete() {
+    var message = {
+      token: this.authService.getToken(),
+      restart: "",
+    };
+    console.log(message);
+    this.connection.send(JSON.stringify(message));
+  }
+
+  regex: string = "/(<svg.*s*.*</svg>)/g";
+
+  consoleRef: any;
+
+  conectarWS(wsUrl, cedula, token, language) {
+    if (
+      cedula &&
+      token &&
+      (!this.connection || this.connection.readyState == WebSocket.CLOSED)
+    ) {
+      this.connection = new WebSocket(
+        wsUrl + "/" + cedula + "/" + token + "/" + language
+      );
+
+      this.connection.onopen = function () {
+        console.log("Conexión con web socket exitosa");
+      };
+      this.connection.onclose = function (reason) {
+        //Codigo que indica la falta de permisos (sesion expirada por ejemplo)
+        if (reason.code == 1008) {
+          this.router.navigate([
+            "/" + this.translateService.get("i18n.code").value + "/login",
+          ]);
+        }
+        console.log("Conexión con web socket cerrada", reason);
+      }.bind(this);
+      this.connection.onmessage = this.onMessage.bind(this);
+    }
+  }
+
+  desconectarWS() {
+    if (this.connection) {
+      this.connection.close();
+    }
+  }
+
+  logConsole(text) {
+    if (this.consoleRef) {
+      this.consoleRef.Write(text, "jqconsole-logs");
+    } else {
+      this.consoleBuffer.unshift({ text: text, type: "jqconsole-logs" });
+      setTimeout(this.checkConsole.bind(this), 100);
+    }
+  }
+
+  outputConsole(text) {
+    if (this.consoleRef) {
+      this.consoleRef.Write(text, "jqconsole-output");
+    } else {
+      this.consoleBuffer.unshift({ text: text, type: "jqconsole-output" });
+      setTimeout(this.checkConsole.bind(this), 100);
+    }
+  }
+
+  errorConsole(text) {
+    if (this.consoleRef) {
+      this.consoleRef.Write(text, "jqconsole-errors");
+    } else {
+      this.consoleBuffer.unshift({ text: text, type: "jqconsole-errors" });
+      setTimeout(this.checkConsole.bind(this), 100);
+    }
+  }
+  hayError(text) {
+    var line = -1;
+    if (this.waitingForError) {
+      var line = this.lastError;
+      var columna = this.errorText
+        .split(
+          `${
+            this.translateService.get("i18n.codemirror.command.column").value
+          }:`
+        )[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;
+
+      if (
+        this.currentFile.toLowerCase() == this.lastErrorFile.toLowerCase() &&
+        this.codemirrorRef !== null
+      ) {
+        var makeMarker = function () {
+          var marker = document.createElement("div");
+          marker.id = "error_" + line.toString();
+          marker.style.width = "15px";
+          marker.title = ErrorFinalText;
+          marker.style.height = "15px";
+          marker.style.marginLeft = "-5px";
+          marker.style.cursor = "pointer";
+          marker.style["background-image"] =
+            "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII=')";
+          marker.innerHTML =
+            "<a href='@' title='cuidado , advertencia matefun'></a>";
+          return marker;
+        };
+        this.codemirrorRef.setGutterMarker(line, "breakpoints", makeMarker());
+        this.waitingForError = false;
+        this.lastError = -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];
+
+        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;
+
+        this.waitingForError = true;
+        this.lastError = line;
+        this.lastErrorFile = file;
+        this.errorText = m.resultado
+          .split(
+            `${
+              this.translateService.get("i18n.codemirror.command.outError")
+                .value
+            }:`
+          )[1]
+          .trim();
+      } catch (err) {}
+      return false;
+    }
+  }
+
+  resetGutters() {
+    if (this.codemirrorRef !== null) {
+      this.codemirrorRef.clearGutter("breakpoints");
+    }
+  }
+
+  hayWarnings(text) {
+    var line = -1;
+    var m = JSON.parse(text);
+
+    if (this.warningStepReaded === 1) {
+      try {
+        var warningText2 = m.resultado.split("OUT")[1].trim();
+        this.warningStepReaded = 2;
+        this.warningText = this.warningText + "\n\n" + warningText2;
+
+        var line = this.lastWarning;
+        var title = this.warningText;
+
+        var columna = title
+          .split(
+            `${
+              this.translateService.get("i18n.codemirror.command.column").value
+            }:`
+          )[1]
+          .split("}")[0];
+        var warningTextToShow = title.split("}")[1];
+
+        var warningFinalText =
+          `${
+            this.translateService.get("i18n.codemirror.command.inColumn").value
+          }` +
+          columna +
+          ": " +
+          warningTextToShow;
+
+        if (
+          this.currentFile.toLowerCase() ==
+            this.lastWarningFile.toLowerCase() &&
+          this.codemirrorRef !== null
+        ) {
+          var makeMarker = function () {
+            var marker = document.createElement("div");
+            marker.style.width = "15px";
+            marker.style.height = "15px";
+            marker.style.marginLeft = "-5px";
+            marker.style.cursor = "pointer";
+            marker.innerHTML =
+              "<a href='@' title='cuidado , advertencia matefun'></a>";
+            marker.title = warningFinalText;
+            marker.style["background-image"] =
+              "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII=')";
+            marker.innerHTML = "";
+            return marker;
+          };
+          this.codemirrorRef.setGutterMarker(line, "breakpoints", makeMarker());
+        }
+      } catch (err) {}
+    }
+
+    if (this.warningStepReaded === 0) {
+      try {
+        var file = m.resultado
+          .split(
+            `${
+              this.translateService.get("i18n.codemirror.command.outWarning")
+                .value
+            }:`
+          )[1]
+          .trim()
+          .split(`${this.translateService.get("i18n.object.file").value}:`)[1]
+          .split(" ")[1];
+
+        // retrive line of warning
+        var line =
+          m.resultado
+            .split(
+              `${
+                this.translateService.get("i18n.codemirror.command.outWarning")
+                  .value
+              }:`
+            )[1]
+            .trim()
+            .split(
+              `${
+                this.translateService.get("i18n.codemirror.command.line").value
+              }:`
+            )[1]
+            .split(" ")[1] - 1;
+
+        this.lastWarning = line;
+        this.lastWarningFile = file;
+        this.warnings.push(line);
+        var warningText = m.resultado
+          .split(
+            `${
+              this.translateService.get("i18n.codemirror.command.outWarning")
+                .value
+            }:`
+          )[1]
+          .trim();
+        this.warningStepReaded = 1;
+        this.warningText = warningText;
+        if (this.waitingForWarning) {
+          this.outputConsole(
+            `${
+              this.translateService.get("i18n.msg.codemirror.consoleWarnings")
+                .value
+            }\n`
+          );
+          this.waitingForWarning = false;
+        }
+      } catch (err) {}
+    }
+  }
+
+  onMessage(e) {
+    if (this.modoAvanzado) {
+      this.logConsole("Respuesta: " + e.data + "\n");
+    }
+    if (this.clear) {
+      this.clearConsole();
+    }
+    var server_message = e.data;
+
+    if (this.hayError(server_message)) {
+      this.error = "Error";
+    } else {
+      this.error = "";
+    }
+
+    this.hayWarnings(server_message);
+
+    if (this.warningStepReaded == 2) {
+      this.warningStepReaded = 0;
+      return;
+    } else if (this.warningStepReaded == 1) {
+      return;
+    }
+
+    var json_server_message = JSON.parse(server_message);
+    if (json_server_message.tipo == "salida") {
+      var line = json_server_message.resultado.trim();
+      if (line.startsWith("OUT")) {
+        this.outputConsole(line.substring(3) + "\n");
+      } else if (line.startsWith("IN")) {
+        var promptText = line.substring(3);
+        if (this.consoleRef === undefined) {
+          this.renderConsole();
+        }
+        this.consoleRef.SetPromptLabel(promptText);
+        this.consoleRef.SetPromptText("");
+        this.startPrompt.bind(this);
+        this.startPrompt();
+      }
+    } else if (json_server_message.tipo == "error") {
+      if (this.modoAvanzado) {
+        this.errorConsole(json_server_message.resultado + "\n");
+      }
+    } else if (json_server_message.tipo == "prompt") {
+      // console.log(json_server_message.resultado);
+      // console.log(this.consoleRef);
+      // console.log(this.consoleRef.SetPromptLabel);
+      // this.consoleRef.SetPromptLabel.bind(this);
+      this.consoleRef.SetPromptLabel(json_server_message.resultado + ">");
+      this.consoleRef.SetPromptText("");
+      this.startPrompt.bind(this);
+      this.startPrompt();
+      // console.log(x);
+    } else if (
+      json_server_message.tipo == "canvas" ||
+      json_server_message.tipo == "animacion" ||
+      json_server_message.tipo == "graph"
+    ) {
+      document.getElementById("FigurasBtn2D").click();
+      this.focusConsole();
+      this.messages.next(json_server_message);
+    } else if (
+      json_server_message.tipo == "canvas3D" ||
+      json_server_message.tipo == "animacion3D"
+    ) {
+      document.getElementById("FigurasBtn3D").click();
+      this.focusConsole();
+      this.messages.next(json_server_message);
+    }
+  }
+
+  checkConsole() {
+    if (this.consoleRef) {
+      while (this.consoleBuffer.length > 0) {
+        var bufferedMessage = this.consoleBuffer.pop();
+        this.consoleRef.Write(bufferedMessage.text, bufferedMessage.type);
+      }
+    } else {
+      setTimeout(this.checkConsole.bind(this), 500);
+    }
+  }
+
+  checkConnection() {
+    var usuario = this.authService.getUser();
+    var token = this.authService.getToken();
+    var language = this.authService.getLanguage();
+    if (
+      usuario &&
+      token &&
+      (!this.connection || this.connection.readyState == WebSocket.CLOSED)
+    ) {
+      this.conectarWS(GHCI_URL, usuario.cedula, token, language);
+    }
+  }
+
+  doPing() {
+    var token = this.authService.getToken();
+    if (
+      this.connection &&
+      this.connection.readyState == WebSocket.OPEN &&
+      token
+    ) {
+      var message = {
+        token: token,
+        ping: "",
+      };
+      this.connection.send(JSON.stringify(message));
+    }
+  }
+
+  sendLine(line) {
+    if (line.trim() !== "") {
+      var message = {
+        token: this.authService.getToken(),
+        comando: line,
+      };
+      console.log(message);
+      if (this.connection && this.connection.readyState == WebSocket.OPEN) {
+        this.connection.send(JSON.stringify(message));
+      } else {
+        this.errorConsole("Sin conexión al servidor...\n");
+      }
+    }
+  }
+
+  startPrompt() {
+    // Start the prompt with history enabled.
+    this.jqconsole.Prompt(true, this.callback.bind(this));
+    this.jqconsole.RegisterMatching("(", ")", "paran");
+  }
+
+  focusConsole() {
+    this.jqconsole.Focus();
+  }
+
+  clearConsole() {
+    this.consoleRef.Reset();
+    this.startPrompt.bind(this);
+    this.startPrompt();
+    this.clear = false;
+  }
+
+  callback(input) {
+    // Output input with the class jqconsole-output.
+    var ejecutar: boolean;
+    ejecutar = this.procesarInput(input);
+    if (ejecutar) {
+      if (this.modoAvanzado) {
+        this.logConsole("Ejecutar: " + input + "\n");
+      }
+      this.sendLine.bind(this);
+      this.sendLine(input);
+    }
+    this.startPrompt.bind(this);
+    this.startPrompt();
+  }
+
+  procesarInput(input) {
+    var _input: string;
+    var send: boolean = false;
+    _input = input.trim().toLocaleLowerCase();
+    if (_input === "limpiar") {
+      this.clearConsole();
+    } else if (_input === "modo avanzado") {
+      this.modoAvanzado = true;
+      this.logConsole("Modo avanzado activado\n");
+    } else if (_input === "modo normal") {
+      this.modoAvanzado = false;
+      this.logConsole("Modo avanzado desactivado\n");
+    } else if (_input === "listar colores") {
+      this.outputConsole("1 - Azul\n");
+      this.outputConsole("2 - Rojo\n");
+      this.outputConsole("3 - Verde\n");
+      this.outputConsole("4 - Verde oscuro\n");
+      this.outputConsole("5 - Blanco\n");
+      this.outputConsole("6 - Naranja\n");
+      this.outputConsole("7 - Gris\n");
+      this.outputConsole("8 - Gris oscuro\n");
+      this.outputConsole("9 - Marrón\n");
+    } else if (_input.match(regex) !== null) {
+      var _tipoTexto: string = _input.split(" ")[1];
+      var _color: string = input.split(" ")[2];
+      this.jqconsoleColor(_color, _tipoTexto);
+      if (this.modoAvanzado) {
+        this.logConsole("Color " + _tipoTexto + " seleccionado\n");
+      }
+    } else {
+      send = true;
+    }
+    return send;
+  }
+
+  getCSSColorName(n) {
+    if (n === "1") {
+      return "rgb(77, 77, 255)";
+    } else if (n === "2") {
+      return "rgb(255, 26, 26)";
+    } else if (n === "3") {
+      return "rgb(0, 179, 60)";
+    } else if (n === "4") {
+      return "rgb(0, 77, 0)";
+    } else if (n === "5") {
+      return "rgb(255, 255, 255)";
+    } else if (n === "6") {
+      return "rgb(255, 133, 51)";
+    } else if (n === "7") {
+      return "rgb(204, 204, 179)";
+    } else if (n === "8") {
+      return "rgb(102, 102, 102)";
+    } else if (n === "9") {
+      return "rgb(101, 27, 27)";
+    }
+  }
+
+  getJQConsoleClass(jqconsoletext) {
+    if (jqconsoletext === "input") {
+      return ".jqconsole-prompt";
+    } else if (jqconsoletext === "error") {
+      return ".jqconsole-error";
+    } else if (jqconsoletext === "logs") {
+      return ".jqconsole-logs";
+    } else if (jqconsoletext === "output") {
+      return ".jqconsole-output";
+    }
+  }
+
+  jqconsoleColor(color, clase) {
+    var cssColor: string = this.getCSSColorName(color);
+    var jqConsoleClass: string = this.getJQConsoleClass(clase);
+
+    var style = document.createElement("style");
+    style.type = "text/css";
+    style.innerHTML = jqConsoleClass + " { color: " + cssColor + "; }";
+    document.getElementsByTagName("head")[0].appendChild(style);
+
+    if (jqConsoleClass === ".jqconsole-prompt") {
+      var style2 = document.createElement("style");
+      style2.type = "text/css";
+      style2.innerHTML = ".jqconsole-old-prompt { color: " + cssColor + "; }";
+      document.getElementsByTagName("head")[0].appendChild(style2);
+    }
+  }
+
+  consola: any = undefined;
+  renderConsole() {
+    if (this.jqconsole) {
+      $("#console").replaceWith(this.consola);
+    } else {
+      if ($("#console").jqconsole != undefined) {
+        // Check if element has been found
+        this.jqconsole = $("#console").jqconsole("");
+        this.consoleRef = this.jqconsole;
+        this.startPrompt.bind(this);
+        this.startPrompt();
+      } else {
+        this.rendered();
+      }
+      this.consola = $("#console");
+    }
+  }
+
+  jqconsole: any = undefined;
+  rendered() {
+    setTimeout(this.renderConsole.bind(this), 1000);
+  }
 }
diff --git a/Frontend Angular 4/src/app/shared/services/haskell.service.ts b/Frontend Angular 4/src/app/shared/services/haskell.service.ts
index 0b8f0c57..826c310a 100755
--- a/Frontend Angular 4/src/app/shared/services/haskell.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/haskell.service.ts	
@@ -1,129 +1,201 @@
-import { Injectable } from '@angular/core';
-import { Router } from '@angular/router';
-import { Http, Response, Headers, RequestOptions, URLSearchParams } from '@angular/http';
-import { Observable } from 'rxjs/Observable';
-import { Archivo, Evaluacion } from '../objects/archivo';
-import { Grupo } from '../objects/grupo';
-
-import { SERVER } from '../config';
-import { TranslateService } from '@ngx-translate/core';
-import { AuthenticationService } from './authentication.service';
-import 'rxjs/add/operator/map';
-import 'rxjs/add/operator/catch';
+import { Injectable } from "@angular/core";
+import { Router } from "@angular/router";
+import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http";
+import { Observable } from "rxjs/Observable";
+import { Archivo, Evaluacion } from "../objects/archivo";
+import { Grupo } from "../objects/grupo";
+
+import { SERVER } from "../config";
+import { TranslateService } from "@ngx-translate/core";
+import { AuthenticationService } from "./authentication.service";
+import "rxjs/add/operator/map";
+import "rxjs/add/operator/catch";
 
 @Injectable()
 export class HaskellService {
   translateService: any;
 
   /**
-   * Creates a new HaskellService with the injected Http.
-   * @param {Http} http - The injected Http.
+   * Creates a new HaskellService with the injected HttpClient.
+   * @param {HttpClient} http - The injected HttpClient.
    * @constructor
    */
-   constructor(
-      private http: Http, private router: Router,
-      private authService: AuthenticationService,
-      public translate: TranslateService) {
+  constructor(
+    private http: HttpClient,
+    private router: Router,
+    private authService: AuthenticationService,
+    public translate: TranslateService
+  ) {
     this.translateService = translate;
-   }
-
-   getArchivos(cedula:string): Observable<Archivo[]> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken() });
-     let params: URLSearchParams = new URLSearchParams();
-     params.set('cedula', cedula);
-     let options = new RequestOptions({ headers: headers, search: params });
-     return this.http.get(SERVER+'/servicios/archivo',options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-
-   getArchivosCompartidosAlumno(cedula:string): Observable<Archivo[]> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-     let params: URLSearchParams = new URLSearchParams();
-     params.set('cedula', cedula);
-     params.set('compartidos','true');
-     let options = new RequestOptions({ headers: headers, search: params });
-     return this.http.get(SERVER+'/servicios/archivo',options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-
-   crearArchivo(archivo: Archivo): Observable<Archivo> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-     let options = new RequestOptions({ headers: headers });
-     return this.http.post(SERVER+'/servicios/archivo', archivo, options)
-     .map((res: Response) => res.json());
-     //.catch(this.handleError);
-   }
-
-   editarArchivo(archivoId, archivo: Archivo): Observable<Archivo> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken() });
-     let options = new RequestOptions({ headers: headers });
-     return this.http.put(SERVER+'/servicios/archivo/'+archivoId, archivo, options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-
-   eliminarArchivo(archivoId): Observable<Response> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-     let options = new RequestOptions({ headers: headers });
-     return this.http.delete(SERVER+'/servicios/archivo/'+archivoId, options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-
-   getCopiaArchivoCompartidoGrupo(cedula, archivoId): Observable<Archivo> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-     let params: URLSearchParams = new URLSearchParams();
-     params.set('cedula', cedula);
-     let options = new RequestOptions({ headers: headers, search: params });
-     return this.http.get(SERVER+'/servicios/archivo/compartido/'+archivoId, options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-
-   compartirArchivoGrupo(grupo,archivoId): Observable<Archivo> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-     let options = new RequestOptions({ headers: headers });
-     var archId = {
-       id:archivoId
-     }
-     return this.http.post(SERVER+'/servicios/grupo/'+grupo.liceoId+'/'+grupo.anio+'/'+grupo.grado+'/'+grupo.grupo+'/archivo', archId, options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-
-   calificarArchivo(archivoId, estado, evaluacion): Observable<Evaluacion> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-     let options = new RequestOptions({ headers: headers });
-     return this.http.post(SERVER+'/servicios/archivo/'+archivoId+'/'+estado+'/evaluacion', evaluacion, options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-
-
-   getGrupos(cedula:string): Observable<Grupo[]> {
-     let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-     let params: URLSearchParams = new URLSearchParams();
-     params.set('cedula', cedula);
-     let options = new RequestOptions({ headers: headers, search: params });
-     return this.http.get(SERVER+'/servicios/grupo',options)
-     .map((res: Response) => res.json())
-     .catch(this.handleError);
-   }
-   
+  }
+
+  getArchivos(cedula: string): Observable<Archivo[]> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let params: HttpParams = new HttpParams();
+    params.set("cedula", cedula);
+    let httpOptions = { headers: headers, params: params };
+
+    return this.http
+      .get(SERVER + "/servicios/archivo", httpOptions)
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
+  getArchivosCompartidosAlumno(cedula: string): Observable<Archivo[]> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let params: HttpParams = new HttpParams();
+    params.set("cedula", cedula);
+    params.set("compartidos", "true");
+    let httpOptions = { headers: headers, params: params };
+
+    return this.http
+      .get(SERVER + "/servicios/archivo", httpOptions)
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
+  crearArchivo(archivo: Archivo): Observable<Archivo> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+
+    let httpOptions = { headers: headers };
+
+    return this.http
+      .post(SERVER + "/servicios/archivo", archivo, httpOptions)
+      .map((res: any) => res);
+    //.catch(this.handleError);
+  }
+
+  editarArchivo(archivoId, archivo: Archivo): Observable<Archivo> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let httpOptions = { headers: headers };
+
+    return this.http
+      .put(SERVER + "/servicios/archivo/" + archivoId, archivo, httpOptions)
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
+  eliminarArchivo(archivoId): Observable<Response> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let httpOptions = { headers: headers };
+
+    return this.http
+      .delete(SERVER + "/servicios/archivo/" + archivoId, httpOptions)
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
+  getCopiaArchivoCompartidoGrupo(cedula, archivoId): Observable<Archivo> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let params: HttpParams = new HttpParams();
+    params.set("cedula", cedula);
+    let httpOptions = { headers: headers, params: params };
+
+    return this.http
+      .get(SERVER + "/servicios/archivo/compartido/" + archivoId, httpOptions)
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
+  compartirArchivoGrupo(grupo, archivoId): Observable<Archivo> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let httpOptions = { headers: headers };
+    var archId = {
+      id: archivoId,
+    };
+    return this.http
+      .post(
+        SERVER +
+          "/servicios/grupo/" +
+          grupo.liceoId +
+          "/" +
+          grupo.anio +
+          "/" +
+          grupo.grado +
+          "/" +
+          grupo.grupo +
+          "/archivo",
+        archId,
+        httpOptions
+      )
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
+  calificarArchivo(archivoId, estado, evaluacion): Observable<Evaluacion> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let httpOptions = { headers: headers };
+    return this.http
+      .post(
+        SERVER +
+          "/servicios/archivo/" +
+          archivoId +
+          "/" +
+          estado +
+          "/evaluacion",
+        evaluacion,
+        httpOptions
+      )
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
+  getGrupos(cedula: string): Observable<Grupo[]> {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let params: HttpParams = new HttpParams();
+    params.set("cedula", cedula);
+    let httpOptions = { headers: headers, params: params };
+
+    return this.http
+      .get(SERVER + "/servicios/grupo", httpOptions)
+      .map((res: any) => res)
+      .catch(this.handleError);
+  }
+
   /**
-    * Handle HTTP error
-    */
-    private handleError (error: any) {
-      if(error.status == 401){
-        this.router.navigate(['/'+this.translateService.get('i18n.code').value+'/login']);
-      }
-      // In a real world app, we might use a remote logging infrastructure
-      // We'd also dig deeper into the error to get a better message
-      let errMsg = (error.message) ? error.message :
-      error.status ? `${error.status} - ${error.statusText}` : 'Server error';
-      console.error(errMsg); // log to console instead
-      return Observable.throw(errMsg);
+   * Handle HTTP error
+   */
+  private handleError(error: any) {
+    if (error.status == 401) {
+      this.router.navigate([
+        "/" + this.translateService.get("i18n.code").value + "/login",
+      ]);
     }
+    // In a real world app, we might use a remote logging infrastructure
+    // We'd also dig deeper into the error to get a better message
+    let errMsg = error.message
+      ? error.message
+      : error.status
+      ? `${error.status} - ${error.statusText}`
+      : "Server error";
+    console.error(errMsg); // log to console instead
+    return Observable.throw(errMsg);
   }
+}
diff --git a/Frontend Angular 4/src/app/shared/services/notificacion.service.ts b/Frontend Angular 4/src/app/shared/services/notificacion.service.ts
index 0d61b31a..54d87f95 100755
--- a/Frontend Angular 4/src/app/shared/services/notificacion.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/notificacion.service.ts	
@@ -1,53 +1,53 @@
-import { Injectable } from '@angular/core';
-import { Router, NavigationStart } from '@angular/router';
-import { Observable } from 'rxjs/Observable';
-import { Subject } from 'rxjs/Subject';
+import { Injectable } from "@angular/core";
+import { Router, NavigationStart } from "@angular/router";
+import { Observable } from "rxjs/Observable";
+import { Subject } from "rxjs/Subject";
 
 @Injectable()
 export class NotificacionService {
-    private subject = new Subject<any>();
-    private keepAfterNavigationChange = false;
-
-    constructor(private router: Router) {
-        // clear alert message on route change
-        router.events.subscribe(event => {
-            if (event instanceof NavigationStart) {
-                if (this.keepAfterNavigationChange) {
-                    // only keep for a single location change
-                    this.keepAfterNavigationChange = false;
-                } else {
-                    // clear alert
-                    this.subject.next();
-                }
-            }
-        });
-    }
-
-    success(message: string, keepAfterNavigationChange = false) {
-        this.keepAfterNavigationChange = keepAfterNavigationChange;
-        this.subject.next({ type: 'success', text: message });
-    }
-
-    info(message: string, keepAfterNavigationChange = false) {
-        this.keepAfterNavigationChange = keepAfterNavigationChange;
-        this.subject.next({ type: 'info', text: message });
-    }
-
-    warning(message: string, keepAfterNavigationChange = false) {
-        this.keepAfterNavigationChange = keepAfterNavigationChange;
-        this.subject.next({ type: 'warning', text: message });
-    }
-
-    error(message: string, keepAfterNavigationChange = false) {
-        this.keepAfterNavigationChange = keepAfterNavigationChange;
-        this.subject.next({ type: 'danger', text: message });
-    }
-
-    getMessage(): Observable<any> {
-        return this.subject.asObservable();
-    }
-
-    getMessageSubject() {
-        return this.subject;
-    }
-}
\ No newline at end of file
+  private subject = new Subject<any>();
+  private keepAfterNavigationChange = false;
+
+  constructor(private router: Router) {
+    // clear alert message on route change
+    router.events.subscribe((event) => {
+      if (event instanceof NavigationStart) {
+        if (this.keepAfterNavigationChange) {
+          // only keep for a single location change
+          this.keepAfterNavigationChange = false;
+        } else {
+          // clear alert
+          this.subject.next();
+        }
+      }
+    });
+  }
+
+  success(message: string, keepAfterNavigationChange = false) {
+    this.keepAfterNavigationChange = keepAfterNavigationChange;
+    this.subject.next({ type: "success", text: message });
+  }
+
+  info(message: string, keepAfterNavigationChange = false) {
+    this.keepAfterNavigationChange = keepAfterNavigationChange;
+    this.subject.next({ type: "info", text: message });
+  }
+
+  warning(message: string, keepAfterNavigationChange = false) {
+    this.keepAfterNavigationChange = keepAfterNavigationChange;
+    this.subject.next({ type: "warning", text: message });
+  }
+
+  error(message: string, keepAfterNavigationChange = false) {
+    this.keepAfterNavigationChange = keepAfterNavigationChange;
+    this.subject.next({ type: "danger", text: message });
+  }
+
+  getMessage(): Observable<any> {
+    return this.subject.asObservable();
+  }
+
+  getMessageSubject() {
+    return this.subject;
+  }
+}
diff --git a/Frontend Angular 4/src/app/shared/services/session.service.ts b/Frontend Angular 4/src/app/shared/services/session.service.ts
index d599d8d2..640647ee 100755
--- a/Frontend Angular 4/src/app/shared/services/session.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/session.service.ts	
@@ -1,184 +1,173 @@
-import { Injectable } from '@angular/core';
-import { Archivo } from '../objects/archivo';
-import { Grupo } from '../objects/grupo';
+import { Injectable } from "@angular/core";
+import { Archivo } from "../objects/archivo";
+import { Grupo } from "../objects/grupo";
 
 @Injectable()
 export class SessionService {
-	archivo: Archivo = new Archivo();
-	archivos: any;
-	dependencias :any;
-	archivosList :any;
-	directorioActual : any;
-	archivosCompartidos : any;
-	grupos: Grupo[];
-
-	public setArchivo(archivo){
-		this.archivo = archivo;
-	}
-	public getArchivo(){
-		return this.archivo;
-	}
-	public setArchivosTree(tree){
-		this.archivos = tree;
-	}
-	public getArchivos(service){
-		if(this.archivos!=undefined){
-			return this.archivos;
-		}
-		if(service!==undefined){
-			return this.archivos;	
-		}		
-	}
-
-	public setGrupos(grupos: Grupo[]){
-		this.grupos = grupos;
-	}
-
-	public getGrupos(){
-		return this.grupos;
-	}
-
-
-	public setArchivosList(l){
-		this.archivosList=l;
-	}
-	public getArchivosList(){
-		return this.archivosList;
-	}
-	public getDependencias(){
-		return this.dependencias;
-	}
-	public setDependencias(d){
-		this.dependencias = d;
-	}
-	public reset(){
-		this.archivo = new Archivo();
-		this.archivos = [];
-		this.dependencias = [];
-		this.archivosList = [];
-		this.grupos = undefined;
-	}
-	public setDirectorioActual(d){
-		this.directorioActual = d;
-	}
-	public setArchivosCompartidos(d){
-		this.archivosCompartidos = d;
-	}
-	public getArchivosCompartidos(){
-		return this.archivosCompartidos;
-	}
-	
-
-	public cargarDependencias(arch){
-			
-			var resultado = this.buildDependenciesTree(arch,[]);
-			if(resultado["status"]==="miss"){
-				return resultado;
-			}
-			var list = this.toList(resultado["dependencies"]);
-			this.setDependencias(list);
-			return resultado;
-	}
-
-	//logica necesaria para cargar un archivo. "resuelve las dependencias 'incluir'"
-	buildDependenciesTree(pivot,archivosRecorridos){
-		var content = pivot.contenido;
-		var contentIncludes = this.extractIncludes(content);
-		var hijos:any = [];
-		var result : any = {};
-		var resultObject = {};
-		
-		result.id = pivot.id;
-		result.nombre = pivot.nombre;
-		result.contenido = pivot.contenido;
-		archivosRecorridos.push(pivot.nombre);
-		for(var i in contentIncludes){
-			if(!archivosRecorridos.includes(contentIncludes[i])){
-				try{
-					var archivo = this.directorioActual.archivos.filter(
-					function(a){
-						return a.nombre === contentIncludes[i];
-					}
-					)[0];
-					//archivosRecorridos.push(pivot.nombre);	
-				} catch(err){
-					
-				}
-				try{
-					var archivo2 = this.archivosCompartidos.filter(
-					function(a){
-						return a.nombre === contentIncludes[i];
-					}
-					)[0];
-					//archivosRecorridos.push(pivot.nombre);	
-				} catch(err){
-					
-				}
-				
-				if(archivo){
-				
-					var resultado_ = this.buildDependenciesTree(archivo,archivosRecorridos);
-					if(resultado_["status"]==="ok"){
-						hijos.push(resultado_["dependencies"]);						
-					} else{
-						return resultado_;
-					}
-
-
-				} else {
-
- 				      if(archivo2){
-				
-						var resultado_ = this.buildDependenciesTree(archivo2,archivosRecorridos);
-						if(resultado_["status"]==="ok"){
-							hijos.push(resultado_["dependencies"]);						
-						} else{
-						  return resultado_;
-						}
-				      } else {
-
-					resultObject["status"] = "miss";
-					resultObject["nombre"] = contentIncludes[i];
-					return resultObject;
-				      }
-				}
-			}
-		}
-		result.hijos = hijos;
-		resultObject["status"] = "ok";
-		resultObject["dependencies"] = result;
-		return resultObject;
-	} 
-
-	 toList(root){
-		var result:any = [];
-		result.push(root);
-		for(var i in root.hijos){
-			var sub = this.toList(root.hijos[i]);
-			result  = result.concat(sub);
-		}
-		return result;
-	}
-
-	extractIncludes(contenido){
-		contenido = contenido.replace(/\{-((?!-\})[\s\S])*-\}/g, ''); // no soporta comentarios anidados
-		var regex = /.*incluir\s*(\w*).*/gm;
-		let m;
-		var includes: any = [];
-
-		while ((m = regex.exec(contenido)) !== null) {
-			// This is necessary to avoid infinite loops with zero-width matches
-			if (m.index === regex.lastIndex) {
-				regex.lastIndex++;
-			}
-
-			// The result can be accessed through the `m`-variable.
-			m.forEach((match, groupIndex) => {
-				if(groupIndex===1){
-					includes.push(match);
-				}
-			});
-		}
-		return includes; 
-	}
+  archivo: Archivo = new Archivo();
+  archivos: any;
+  dependencias: any;
+  archivosList: any;
+  directorioActual: any;
+  archivosCompartidos: any;
+  grupos: Grupo[];
+
+  public setArchivo(archivo) {
+    this.archivo = archivo;
+  }
+  public getArchivo() {
+    return this.archivo;
+  }
+  public setArchivosTree(tree) {
+    this.archivos = tree;
+  }
+  public getArchivos(service) {
+    if (this.archivos != undefined) {
+      return this.archivos;
+    }
+    if (service !== undefined) {
+      return this.archivos;
+    }
+  }
+
+  public setGrupos(grupos: Grupo[]) {
+    this.grupos = grupos;
+  }
+
+  public getGrupos() {
+    return this.grupos;
+  }
+
+  public setArchivosList(l) {
+    this.archivosList = l;
+  }
+  public getArchivosList() {
+    return this.archivosList;
+  }
+  public getDependencias() {
+    return this.dependencias;
+  }
+  public setDependencias(d) {
+    this.dependencias = d;
+  }
+  public reset() {
+    this.archivo = new Archivo();
+    this.archivos = [];
+    this.dependencias = [];
+    this.archivosList = [];
+    this.grupos = undefined;
+  }
+  public setDirectorioActual(d) {
+    this.directorioActual = d;
+  }
+  public setArchivosCompartidos(d) {
+    this.archivosCompartidos = d;
+  }
+  public getArchivosCompartidos() {
+    return this.archivosCompartidos;
+  }
+
+  public cargarDependencias(arch) {
+    var resultado = this.buildDependenciesTree(arch, []);
+    if (resultado["status"] === "miss") {
+      return resultado;
+    }
+    var list = this.toList(resultado["dependencies"]);
+    this.setDependencias(list);
+    return resultado;
+  }
+
+  //logica necesaria para cargar un archivo. "resuelve las dependencias 'incluir'"
+  buildDependenciesTree(pivot, archivosRecorridos) {
+    var content = pivot.contenido;
+    var contentIncludes = this.extractIncludes(content);
+    var hijos: any = [];
+    var result: any = {};
+    var resultObject = {};
+
+    result.id = pivot.id;
+    result.nombre = pivot.nombre;
+    result.contenido = pivot.contenido;
+    archivosRecorridos.push(pivot.nombre);
+    for (var i in contentIncludes) {
+      if (!archivosRecorridos.includes(contentIncludes[i])) {
+        try {
+          var archivo = this.directorioActual.archivos.filter(function (a) {
+            return a.nombre === contentIncludes[i];
+          })[0];
+          //archivosRecorridos.push(pivot.nombre);
+        } catch (err) {}
+        try {
+          var archivo2 = this.archivosCompartidos.filter(function (a) {
+            return a.nombre === contentIncludes[i];
+          })[0];
+          //archivosRecorridos.push(pivot.nombre);
+        } catch (err) {}
+
+        if (archivo) {
+          var resultado_ = this.buildDependenciesTree(
+            archivo,
+            archivosRecorridos
+          );
+          if (resultado_["status"] === "ok") {
+            hijos.push(resultado_["dependencies"]);
+          } else {
+            return resultado_;
+          }
+        } else {
+          if (archivo2) {
+            var resultado_ = this.buildDependenciesTree(
+              archivo2,
+              archivosRecorridos
+            );
+            if (resultado_["status"] === "ok") {
+              hijos.push(resultado_["dependencies"]);
+            } else {
+              return resultado_;
+            }
+          } else {
+            resultObject["status"] = "miss";
+            resultObject["nombre"] = contentIncludes[i];
+            return resultObject;
+          }
+        }
+      }
+    }
+    result.hijos = hijos;
+    resultObject["status"] = "ok";
+    resultObject["dependencies"] = result;
+    return resultObject;
+  }
+
+  toList(root) {
+    var result: any = [];
+    result.push(root);
+    for (var i in root.hijos) {
+      var sub = this.toList(root.hijos[i]);
+      result = result.concat(sub);
+    }
+    return result;
+  }
+
+  extractIncludes(contenido) {
+    contenido = contenido.replace(/\{-((?!-\})[\s\S])*-\}/g, ""); // no soporta comentarios anidados
+    var regex = /.*incluir\s*(\w*).*/gm;
+    let m;
+    var includes: any = [];
+
+    while ((m = regex.exec(contenido)) !== null) {
+      // This is necessary to avoid infinite loops with zero-width matches
+      if (m.index === regex.lastIndex) {
+        regex.lastIndex++;
+      }
+
+      // The result can be accessed through the `m`-variable.
+      m.forEach((match, groupIndex) => {
+        if (groupIndex === 1) {
+          includes.push(match);
+        }
+      });
+    }
+    return includes;
+  }
 }
diff --git a/Frontend Angular 4/src/app/shared/services/usuario.service.ts b/Frontend Angular 4/src/app/shared/services/usuario.service.ts
index 0d2d7c90..e6b978fc 100755
--- a/Frontend Angular 4/src/app/shared/services/usuario.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/usuario.service.ts	
@@ -1,46 +1,61 @@
-import { Injectable } from '@angular/core';
-import { Router } from '@angular/router';
-import { Http, Headers, Response, RequestOptions } from '@angular/http';
-import { Observable } from 'rxjs/Observable';
-import { Usuario, Configuracion } from '../objects/usuario';
-import { TranslateService } from '@ngx-translate/core';
-import { AuthenticationService } from './authentication.service';
-import 'rxjs/add/operator/map'
-import 'rxjs/add/operator/catch'
+import { Injectable } from "@angular/core";
+import { Router } from "@angular/router";
+import { HttpClient, HttpHeaders } from "@angular/common/http";
+import { Observable } from "rxjs/Observable";
+import { Usuario, Configuracion } from "../objects/usuario";
+import { TranslateService } from "@ngx-translate/core";
+import { AuthenticationService } from "./authentication.service";
+import "rxjs/add/operator/map";
+import "rxjs/add/operator/catch";
 
-import { SERVER } from '../config';
+import { SERVER } from "../config";
 
 @Injectable()
 export class UsuarioService {
-    translateService: any;
+  translateService: any;
 
-    constructor(
-        private http: Http, private router: Router,
-        private authService: AuthenticationService,
-        public translate: TranslateService) {
-            this.translateService = translate;
-        }
+  constructor(
+    private http: HttpClient,
+    private router: Router,
+    private authService: AuthenticationService,
+    public translate: TranslateService
+  ) {
+    this.translateService = translate;
+  }
 
-    actualizarConfiguracion(cedula: string, config: Configuracion) {
-        let headers = new Headers({ 'Content-Type': 'application/json', 'Authorization':'Bearer '+this.authService.getToken()  });
-        let options = new RequestOptions({ headers: headers });
-        return this.http.put(SERVER + '/servicios/usuario/' + cedula + "/configuracion", config, options)
-            .map(this.extractData)
-            .catch(this.handleError);
-    }
+  actualizarConfiguracion(cedula: string, config: Configuracion) {
+    let headers = new HttpHeaders({
+      "Content-Type": "application/json",
+      Authorization: "Bearer " + this.authService.getToken(),
+    });
+    let options = { headers: headers };
+    return this.http
+      .put(
+        SERVER + "/servicios/usuario/" + cedula + "/configuracion",
+        config,
+        options
+      )
+      .map(this.extractData)
+      .catch(this.handleError);
+  }
 
-    private extractData(res: Response) {
-        let body = res.json();
-        return body || [];
-    }
+  private extractData(res: any) {
+    let body = res;
+    return body || [];
+  }
 
-    private handleError(error: any) {
-        if(error.status == 401){
-            this.router.navigate(['/'+this.translateService.get('i18n.code').value+'/login']);
-        }
-        let errMsg = (error.message) ? error.message :
-            error.status ? `${error.status} - ${error.statusText}` : 'Server error';
-        console.error(errMsg); // log to console instead
-        return Observable.throw(errMsg);
+  private handleError(error: any) {
+    if (error.status == 401) {
+      this.router.navigate([
+        "/" + this.translateService.get("i18n.code").value + "/login",
+      ]);
     }
+    let errMsg = error.message
+      ? error.message
+      : error.status
+      ? `${error.status} - ${error.statusText}`
+      : "Server error";
+    console.error(errMsg); // log to console instead
+    return Observable.throw(errMsg);
+  }
 }
diff --git a/Frontend Angular 4/src/app/shared/services/websocket.service.ts b/Frontend Angular 4/src/app/shared/services/websocket.service.ts
index f9d9aa80..973ddc61 100755
--- a/Frontend Angular 4/src/app/shared/services/websocket.service.ts	
+++ b/Frontend Angular 4/src/app/shared/services/websocket.service.ts	
@@ -1,41 +1,38 @@
-import { Injectable } from '@angular/core';
-import * as Rx from 'rxjs/Rx';
+import { Injectable } from "@angular/core";
+import * as Rx from "rxjs/Rx";
 
 @Injectable()
 export class WebsocketService {
-	constructor() { }
+  constructor() {}
 
-	private subject: Rx.Subject<MessageEvent>;
+  private subject: Rx.Subject<MessageEvent>;
 
-	public connect(url: string): Rx.Subject<MessageEvent> {
-		if (!this.subject) {
-			this.subject = this.create(url);
-			console.log("Successfully connected: " + url);
-		} 
-		return this.subject;
-	}
+  public connect(url: string): Rx.Subject<MessageEvent> {
+    if (!this.subject) {
+      this.subject = this.create(url);
+      console.log("Successfully connected: " + url);
+    }
+    return this.subject;
+  }
 
-	private create(url: string): Rx.Subject<MessageEvent> {
-		let ws = new WebSocket(url);
+  private create(url: string): Rx.Subject<MessageEvent> {
+    let ws = new WebSocket(url);
 
-		let observable = Rx.Observable.create(
-			(obs: Rx.Observer<MessageEvent>) => {
-				ws.onmessage = obs.next.bind(obs);
-				ws.onerror = obs.error.bind(obs);
-				ws.onclose = obs.complete.bind(obs);
-				return ws.close.bind(ws);
-			})
-		let observer = {
-			next: (data: Object) => {
-				if (ws.readyState === WebSocket.OPEN) {
-					ws.send(JSON.stringify(data));
-				}else{
-					console.log("Se perdio la conexion");
-				}
-			}
-
-		}
-		return Rx.Subject.create(observer, observable);
-	}
-
-}
\ No newline at end of file
+    let observable = Rx.Observable.create((obs: Rx.Observer<MessageEvent>) => {
+      ws.onmessage = obs.next.bind(obs);
+      ws.onerror = obs.error.bind(obs);
+      ws.onclose = obs.complete.bind(obs);
+      return ws.close.bind(ws);
+    });
+    let observer = {
+      next: (data: Object) => {
+        if (ws.readyState === WebSocket.OPEN) {
+          ws.send(JSON.stringify(data));
+        } else {
+          console.log("Se perdio la conexion");
+        }
+      },
+    };
+    return Rx.Subject.create(observer, observable);
+  }
+}
diff --git a/Frontend Angular 4/src/app/shared/utils/sha1.ts b/Frontend Angular 4/src/app/shared/utils/sha1.ts
index c5bf0822..a56ba576 100755
--- a/Frontend Angular 4/src/app/shared/utils/sha1.ts	
+++ b/Frontend Angular 4/src/app/shared/utils/sha1.ts	
@@ -1,165 +1,141 @@
+/* tslint:disable:no-bitwise */
+var POW_2_24 = Math.pow(2, 24);
 
+var POW_2_32 = Math.pow(2, 32);
 
-    var POW_2_24 = Math.pow(2, 24);
-    
-    var POW_2_32 = Math.pow(2, 32);
-    
-    function hex(n: number): string
-    {
-        var s = "",
-            v: number;
-        for (var i = 7; i >= 0; --i)
-        {
-            v = (n >>> (i << 2)) & 0xF;
-            s += v.toString(16);
-        }
-        return s;
-    }
-    
-    function lrot(n: number, bits: number): number
-    {
-        return ((n << bits) | (n >>> (32 - bits)));
-    }
-    
-    class Uint32ArrayBigEndian
-    {
-        bytes: Uint8Array;
-        constructor(length: number)
-        {
-            this.bytes = new Uint8Array(length << 2);
-        }
-        get(index: number): number
-        {
-            index <<= 2;
-            return (this.bytes[index] * POW_2_24)
-                + ((this.bytes[index + 1] << 16)
-                | (this.bytes[index + 2] << 8)
-                | this.bytes[index + 3]);
-        }
-        set(index: number, value: number)
-        {
-            var high = Math.floor(value / POW_2_24),
-                rest = value - (high * POW_2_24);
-            index <<= 2;
-            this.bytes[index] = high;
-            this.bytes[index + 1] = rest >> 16;
-            this.bytes[index + 2] = (rest >> 8) & 0xFF;
-            this.bytes[index + 3] = rest & 0xFF;
-        }
-    }
+function hex(n: number): string {
+  var s = "",
+    v: number;
+  for (var i = 7; i >= 0; --i) {
+    v = (n >>> (i << 2)) & 0xf;
+    s += v.toString(16);
+  }
+  return s;
+}
 
-    function string2ArrayBuffer(s: string): ArrayBuffer
-    {
-        s = s.replace(/[\u0080-\u07ff]/g,
-            function(c: string)
-            { 
-                var code = c.charCodeAt(0);
-                return String.fromCharCode(0xC0 | code >> 6, 0x80 | code & 0x3F);
-            });
-        s = s.replace(/[\u0080-\uffff]/g,
-            function(c: string)
-            { 
-                var code = c.charCodeAt(0);
-                return String.fromCharCode(0xE0 | code >> 12, 0x80 | code >> 6 & 0x3F, 0x80 | code & 0x3F);
-            });
-        var n = s.length,
-            array = new Uint8Array(n);
-        for (var i = 0; i < n; ++i)
-        {
-            array[i] = s.charCodeAt(i);
-        }
-        return array.buffer;
-    }
+function lrot(n: number, bits: number): number {
+  return (n << bits) | (n >>> (32 - bits));
+}
 
-    export function hash(bufferOrString: any): string
-    {
-        var source: ArrayBuffer;
-        if (bufferOrString instanceof ArrayBuffer)
-        {
-            source = <ArrayBuffer> bufferOrString;
-        }
-        else
-        {
-            source = string2ArrayBuffer(String(bufferOrString));
-        }
+class Uint32ArrayBigEndian {
+  bytes: Uint8Array;
+  constructor(length: number) {
+    this.bytes = new Uint8Array(length << 2);
+  }
+  get(index: number): number {
+    index <<= 2;
+    return (
+      this.bytes[index] * POW_2_24 +
+      ((this.bytes[index + 1] << 16) |
+        (this.bytes[index + 2] << 8) |
+        this.bytes[index + 3])
+    );
+  }
+  set(index: number, value: number) {
+    var high = Math.floor(value / POW_2_24),
+      rest = value - high * POW_2_24;
+    index <<= 2;
+    this.bytes[index] = high;
+    this.bytes[index + 1] = rest >> 16;
+    this.bytes[index + 2] = (rest >> 8) & 0xff;
+    this.bytes[index + 3] = rest & 0xff;
+  }
+}
 
-        var h0 = 0x67452301,
-            h1 = 0xEFCDAB89,
-            h2 = 0x98BADCFE,
-            h3 = 0x10325476,
-            h4 = 0xC3D2E1F0,
-            i: number,
-            sbytes = source.byteLength,
-            sbits = sbytes << 3,
-            minbits = sbits + 65,
-            bits = Math.ceil(minbits / 512) << 9,
-            bytes = bits >>> 3,
-            slen = bytes >>> 2,
-            s = new Uint32ArrayBigEndian(slen),
-            s8 = s.bytes,
-            j: number,
-            w = new Uint32Array(80),
-            sourceArray = new Uint8Array(source);
-        for (i = 0; i < sbytes; ++i)
-        {
-            s8[i] = sourceArray[i];
-        }
-        s8[sbytes] = 0x80;
-        s.set(slen - 2, Math.floor(sbits / POW_2_32));
-        s.set(slen - 1, sbits & 0xFFFFFFFF);
-        for (i = 0; i < slen; i += 16)
-        {
-            for (j = 0; j < 16; ++j)
-            {
-                w[j] = s.get(i + j);
-            }
-            for ( ; j < 80; ++j)
-            {
-                w[j] = lrot(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
-            }
-            var a = h0,
-                b = h1,
-                c = h2,
-                d = h3,
-                e = h4,
-                f: number,
-                k: number,
-                temp: number;
-            for (j = 0; j < 80; ++j)
-            {
-                if (j < 20)
-                {
-                    f = (b & c) | ((~b) & d);
-                    k = 0x5A827999;
-                }
-                else if (j < 40)
-                {
-                    f = b ^ c ^ d;
-                    k = 0x6ED9EBA1;
-                }
-                else if (j < 60)
-                {
-                    f = (b & c) ^ (b & d) ^ (c & d);
-                    k = 0x8F1BBCDC;
-                }
-                else
-                {
-                    f = b ^ c ^ d;
-                    k = 0xCA62C1D6;
-                }
+function string2ArrayBuffer(s: string): ArrayBuffer {
+  s = s.replace(/[\u0080-\u07ff]/g, function (c: string) {
+    var code = c.charCodeAt(0);
+    return String.fromCharCode(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
+  });
+  s = s.replace(/[\u0080-\uffff]/g, function (c: string) {
+    var code = c.charCodeAt(0);
+    return String.fromCharCode(
+      0xe0 | (code >> 12),
+      0x80 | ((code >> 6) & 0x3f),
+      0x80 | (code & 0x3f)
+    );
+  });
+  var n = s.length,
+    array = new Uint8Array(n);
+  for (var i = 0; i < n; ++i) {
+    array[i] = s.charCodeAt(i);
+  }
+  return array.buffer;
+}
+
+export function hash(bufferOrString: any): string {
+  var source: ArrayBuffer;
+  if (bufferOrString instanceof ArrayBuffer) {
+    source = <ArrayBuffer>bufferOrString;
+  } else {
+    source = string2ArrayBuffer(String(bufferOrString));
+  }
+
+  var h0 = 0x67452301,
+    h1 = 0xefcdab89,
+    h2 = 0x98badcfe,
+    h3 = 0x10325476,
+    h4 = 0xc3d2e1f0,
+    i: number,
+    sbytes = source.byteLength,
+    sbits = sbytes << 3,
+    minbits = sbits + 65,
+    bits = Math.ceil(minbits / 512) << 9,
+    bytes = bits >>> 3,
+    slen = bytes >>> 2,
+    s = new Uint32ArrayBigEndian(slen),
+    s8 = s.bytes,
+    j: number,
+    w = new Uint32Array(80),
+    sourceArray = new Uint8Array(source);
+  for (i = 0; i < sbytes; ++i) {
+    s8[i] = sourceArray[i];
+  }
+  s8[sbytes] = 0x80;
+  s.set(slen - 2, Math.floor(sbits / POW_2_32));
+  s.set(slen - 1, sbits & 0xffffffff);
+  for (i = 0; i < slen; i += 16) {
+    for (j = 0; j < 16; ++j) {
+      w[j] = s.get(i + j);
+    }
+    for (; j < 80; ++j) {
+      w[j] = lrot(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
+    }
+    var a = h0,
+      b = h1,
+      c = h2,
+      d = h3,
+      e = h4,
+      f: number,
+      k: number,
+      temp: number;
+    for (j = 0; j < 80; ++j) {
+      if (j < 20) {
+        f = (b & c) | (~b & d);
+        k = 0x5a827999;
+      } else if (j < 40) {
+        f = b ^ c ^ d;
+        k = 0x6ed9eba1;
+      } else if (j < 60) {
+        f = (b & c) ^ (b & d) ^ (c & d);
+        k = 0x8f1bbcdc;
+      } else {
+        f = b ^ c ^ d;
+        k = 0xca62c1d6;
+      }
 
-                temp = (lrot(a, 5) + f + e + k + w[j]) & 0xFFFFFFFF;
-                e = d;
-                d = c;
-                c = lrot(b, 30);
-                b = a;
-                a = temp;
-            }
-            h0 = (h0 + a) & 0xFFFFFFFF;
-            h1 = (h1 + b) & 0xFFFFFFFF;
-            h2 = (h2 + c) & 0xFFFFFFFF;
-            h3 = (h3 + d) & 0xFFFFFFFF;
-            h4 = (h4 + e) & 0xFFFFFFFF;
-        }
-        return hex(h0) + hex(h1) + hex(h2) + hex(h3) + hex(h4);
+      temp = (lrot(a, 5) + f + e + k + w[j]) & 0xffffffff;
+      e = d;
+      d = c;
+      c = lrot(b, 30);
+      b = a;
+      a = temp;
     }
+    h0 = (h0 + a) & 0xffffffff;
+    h1 = (h1 + b) & 0xffffffff;
+    h2 = (h2 + c) & 0xffffffff;
+    h3 = (h3 + d) & 0xffffffff;
+    h4 = (h4 + e) & 0xffffffff;
+  }
+  return hex(h0) + hex(h1) + hex(h2) + hex(h3) + hex(h4);
+}
diff --git a/Frontend Angular 4/src/index.html b/Frontend Angular 4/src/index.html
index 870ebc1b..11faeef1 100755
--- a/Frontend Angular 4/src/index.html	
+++ b/Frontend Angular 4/src/index.html	
@@ -1,33 +1,47 @@
-<!doctype html>
+<!DOCTYPE html>
 <html>
-<head>
-    <meta charset="utf-8">
+  <head>
+    <meta charset="utf-8" />
     <title>Proyecto MateFun</title>
-    <base href="/">
-    <meta name="viewport" content="width=device-width, initial-scale=1">
-    <link rel="icon" type="image/x-icon" href="favicon.ico">
+    <base href="/" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="icon" type="image/x-icon" href="favicon.ico" />
     <!-- despues lo saco de aca -->
     <!-- <link rel="stylesheet" type="text/css" href="node_modules/codemirror/addon/hint/show-hint.css">  -->
-    <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
-<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
-<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" crossorigin="anonymous"></script>
+    <script
+      src="https://code.jquery.com/jquery-3.1.1.slim.min.js"
+      integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n"
+      crossorigin="anonymous"
+    ></script>
+    <script
+      src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"
+      integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb"
+      crossorigin="anonymous"
+    ></script>
+    <script
+      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"
+      integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn"
+      crossorigin="anonymous"
+    ></script>
+    <script
+      src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"
+      crossorigin="anonymous"
+    ></script>
 
-<!--
+    <!--
     <script src="https://wzrd.in/standalone/function-plot@1.18.1" crossorigin="anonymous"></script>
 
     -->
-</head>
-<body>
+  </head>
+  <body>
     <app-root>
-        <div class="loading">
-            <div class="loading-bar"></div>
-            <div class="loading-bar"></div>
-            <div class="loading-bar"></div>
-            <div class="loading-bar"></div>
-            <div class="loading-bar"></div>
-        </div>
+      <div class="loading">
+        <div class="loading-bar"></div>
+        <div class="loading-bar"></div>
+        <div class="loading-bar"></div>
+        <div class="loading-bar"></div>
+        <div class="loading-bar"></div>
+      </div>
     </app-root>
-</body>
-
+  </body>
 </html>
diff --git a/Frontend Angular 4/src/main.ts b/Frontend Angular 4/src/main.ts
index a9ca1caf..ae0fb8bb 100755
--- a/Frontend Angular 4/src/main.ts	
+++ b/Frontend Angular 4/src/main.ts	
@@ -1,8 +1,8 @@
-import { enableProdMode } from '@angular/core';
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import { enableProdMode } from "@angular/core";
+import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
 
-import { AppModule } from './app/app.module';
-import { environment } from './environments/environment';
+import { AppModule } from "./app/app.module";
+import { environment } from "./environments/environment";
 
 if (environment.production) {
   enableProdMode();
diff --git a/Frontend Angular 4/src/polyfills.ts b/Frontend Angular 4/src/polyfills.ts
index f989042f..049416eb 100755
--- a/Frontend Angular 4/src/polyfills.ts	
+++ b/Frontend Angular 4/src/polyfills.ts	
@@ -19,19 +19,19 @@
  */
 
 /** IE9, IE10 and IE11 requires all of the following polyfills. **/
-import 'core-js/es6/symbol';
-import 'core-js/es6/object';
-import 'core-js/es6/function';
-import 'core-js/es6/parse-int';
-import 'core-js/es6/parse-float';
-import 'core-js/es6/number';
-import 'core-js/es6/math';
-import 'core-js/es6/string';
-import 'core-js/es6/date';
-import 'core-js/es6/array';
-import 'core-js/es6/regexp';
-import 'core-js/es6/map';
-import 'core-js/es6/set';
+import "core-js/es6/symbol";
+import "core-js/es6/object";
+import "core-js/es6/function";
+import "core-js/es6/parse-int";
+import "core-js/es6/parse-float";
+import "core-js/es6/number";
+import "core-js/es6/math";
+import "core-js/es6/string";
+import "core-js/es6/date";
+import "core-js/es6/array";
+import "core-js/es6/regexp";
+import "core-js/es6/map";
+import "core-js/es6/set";
 
 /** IE10 and IE11 requires the following for NgClass support on SVG elements */
 // import 'classlist.js';  // Run `npm install --save classlist.js`.
@@ -39,23 +39,17 @@ import 'core-js/es6/set';
 /** IE10 and IE11 requires the following to support `@angular/animation`. */
 // import 'web-animations-js';  // Run `npm install --save web-animations-js`.
 
-
 /** Evergreen browsers require these. **/
-import 'core-js/es6/reflect';
-import 'core-js/es7/reflect';
-
+import "core-js/es6/reflect";
+import "core-js/es7/reflect";
 
 /** ALL Firefox browsers require the following to support `@angular/animation`. **/
-import 'web-animations-js';  // Run `npm install --save web-animations-js`.
-
-
+import "web-animations-js"; // Run `npm install --save web-animations-js`.
 
 /***************************************************************************************************
  * Zone JS is required by Angular itself.
  */
-import 'zone.js/dist/zone';  // Included with Angular CLI.
-
-
+import "zone.js/dist/zone"; // Included with Angular CLI.
 
 /***************************************************************************************************
  * APPLICATION IMPORTS
diff --git a/Frontend Angular 4/src/test.ts b/Frontend Angular 4/src/test.ts
index 9bf72267..840500dd 100755
--- a/Frontend Angular 4/src/test.ts	
+++ b/Frontend Angular 4/src/test.ts	
@@ -1,16 +1,16 @@
 // This file is required by karma.conf.js and loads recursively all the .spec and framework files
 
-import 'zone.js/dist/long-stack-trace-zone';
-import 'zone.js/dist/proxy.js';
-import 'zone.js/dist/sync-test';
-import 'zone.js/dist/jasmine-patch';
-import 'zone.js/dist/async-test';
-import 'zone.js/dist/fake-async-test';
-import { getTestBed } from '@angular/core/testing';
+import "zone.js/dist/long-stack-trace-zone";
+import "zone.js/dist/proxy.js";
+import "zone.js/dist/sync-test";
+import "zone.js/dist/jasmine-patch";
+import "zone.js/dist/async-test";
+import "zone.js/dist/fake-async-test";
+import { getTestBed } from "@angular/core/testing";
 import {
   BrowserDynamicTestingModule,
-  platformBrowserDynamicTesting
-} from '@angular/platform-browser-dynamic/testing';
+  platformBrowserDynamicTesting,
+} from "@angular/platform-browser-dynamic/testing";
 
 // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any.
 declare var __karma__: any;
@@ -25,7 +25,7 @@ getTestBed().initTestEnvironment(
   platformBrowserDynamicTesting()
 );
 // Then we find all the tests.
-const context = require.context('./', true, /\.spec\.ts$/);
+const context = require.context("./", true, /\.spec\.ts$/);
 // And load the modules.
 context.keys().map(context);
 // Finally, start Karma to run the tests.
diff --git a/Frontend Angular 4/tsconfig.json b/Frontend Angular 4/tsconfig.json
index 1326363d..5820453f 100755
--- a/Frontend Angular 4/tsconfig.json	
+++ b/Frontend Angular 4/tsconfig.json	
@@ -9,13 +9,7 @@
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "target": "es5",
-    "typeRoots": [
-      "node_modules/@types",
-      "./src/typings.d.ts"
-    ],
-    "lib": [
-      "es2016",
-      "dom"
-    ]
+    "typeRoots": ["node_modules/@types", "./src/typings.d.ts"],
+    "lib": ["es2016", "dom"]
   }
 }
diff --git a/Frontend Angular 4/tslint.json b/Frontend Angular 4/tslint.json
index 9113f136..8e2eeda2 100755
--- a/Frontend Angular 4/tslint.json	
+++ b/Frontend Angular 4/tslint.json	
@@ -1,29 +1,18 @@
 {
-  "rulesDirectory": [
-    "node_modules/codelyzer"
-  ],
+  "rulesDirectory": ["node_modules/codelyzer"],
   "rules": {
     "callable-types": true,
     "class-name": true,
-    "comment-format": [
-      true,
-      "check-space"
-    ],
+    "comment-format": [true, "check-space"],
     "curly": true,
     "eofline": true,
     "forin": true,
     "import-blacklist": [true, "rxjs"],
     "import-spacing": true,
-    "indent": [
-      true,
-      "spaces"
-    ],
+    "indent": [true, "spaces"],
     "interface-over-type-literal": true,
     "label-position": true,
-    "max-line-length": [
-      true,
-      140
-    ],
+    "max-line-length": [true, 140],
     "member-access": false,
     "member-ordering": [
       true,
@@ -32,21 +21,14 @@
     ],
     "no-arg": true,
     "no-bitwise": true,
-    "no-console": [
-      true,
-      "debug",
-      "info",
-      "time",
-      "timeEnd",
-      "trace"
-    ],
+    "no-console": [true, "debug", "info", "time", "timeEnd", "trace"],
     "no-construct": true,
     "no-debugger": true,
     "no-duplicate-variable": true,
     "no-empty": false,
     "no-empty-interface": true,
     "no-eval": true,
-    "no-inferrable-types": [true, "ignore-params"],
+    "no-inferrable-types": [false, "ignore-params"],
     "no-shadowed-variable": true,
     "no-string-literal": false,
     "no-string-throw": true,
@@ -54,7 +36,7 @@
     "no-trailing-whitespace": true,
     "no-unused-expression": true,
     "no-use-before-declare": true,
-    "no-var-keyword": true,
+    "no-var-keyword": false,
     "object-literal-sort-keys": false,
     "one-line": [
       true,
@@ -63,19 +45,13 @@
       "check-else",
       "check-whitespace"
     ],
-    "prefer-const": true,
     "quotemark": [
-      true,
-      "single"
+      [true, "double"],
+      [true, "single"]
     ],
     "radix": true,
-    "semicolon": [
-      "always"
-    ],
-    "triple-equals": [
-      true,
-      "allow-null-check"
-    ],
+    "semicolon": ["always"],
+    "triple-equals": [false, "allow-null-check"],
     "typedef-whitespace": [
       true,
       {
@@ -108,9 +84,6 @@
     "use-life-cycle-interface": true,
     "use-pipe-transform-interface": true,
     "component-class-suffix": true,
-    "directive-class-suffix": true,
-    "no-access-missing-member": true,
-    "templates-use-public": true,
-    "invoke-injectable": true
+    "directive-class-suffix": true
   }
 }
-- 
GitLab