From dbfe642280c043e129752c488aa8c14159071281 Mon Sep 17 00:00:00 2001 From: Alexandre Jesus Date: Fri, 26 Aug 2022 13:10:42 +0100 Subject: Initial site, and first blog post --- content/_index.md | 40 ++++++ content/blog/01-hello-world/index.md | 193 +++++++++++++++++++++++++++ content/blog/01-hello-world/index.org | 190 ++++++++++++++++++++++++++ content/blog/_index.md | 6 + content/publications/dias2021nondlib.pdf | Bin 0 -> 429070 bytes content/publications/index.md | 61 +++++++++ content/publications/jesus2015implicit.pdf | Bin 0 -> 1086090 bytes content/publications/jesus2018finding.pdf | Bin 0 -> 306511 bytes content/publications/jesus2019model.pdf | Bin 0 -> 155999 bytes content/publications/jesus2020algorithm.pdf | Bin 0 -> 591676 bytes content/publications/jesus2020model.pdf | Bin 0 -> 2047324 bytes content/publications/jesus2021design.pdf | Bin 0 -> 759921 bytes content/publications/jesus2021techniques.pdf | Bin 0 -> 99184 bytes content/software/index.md | 58 ++++++++ content/teaching/index.md | 31 +++++ 15 files changed, 579 insertions(+) create mode 100644 content/_index.md create mode 100644 content/blog/01-hello-world/index.md create mode 100644 content/blog/01-hello-world/index.org create mode 100644 content/blog/_index.md create mode 100644 content/publications/dias2021nondlib.pdf create mode 100644 content/publications/index.md create mode 100644 content/publications/jesus2015implicit.pdf create mode 100644 content/publications/jesus2018finding.pdf create mode 100644 content/publications/jesus2019model.pdf create mode 100644 content/publications/jesus2020algorithm.pdf create mode 100644 content/publications/jesus2020model.pdf create mode 100644 content/publications/jesus2021design.pdf create mode 100644 content/publications/jesus2021techniques.pdf create mode 100644 content/software/index.md create mode 100644 content/teaching/index.md (limited to 'content') diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 0000000..9a0ca4e --- /dev/null +++ b/content/_index.md @@ -0,0 +1,40 @@ ++++ +title = "About" ++++ + +I'm a PhD student at the University of Coimbra and University of Lille +under a co-tutelle program advised by [Luís +Paquete](https://eden.dei.uc.pt/~paquete), [Arnaud +Liefooghe](https://sites.google.com/site/arnaudliefooghe/) and [Bilel +Derbel](https://sites.google.com/site/bilelderbelpro/). I'm also +working as an Invited Assistant at the University of Coimbra, part of +the [ALGO](https://algo.dei.uc.pt/) research lab, and a member of the +[TOPDEI](https://top.dei.uc.pt) project that is preparing students for +programming competitions. Previously, I worked as a full stack +developer at [Whitesmith](https://whitesmith.co). + +Research-wise I'm mainly interested in Multi-Objective Optimization, +Combinatorial Optimization, Anytime Algorithms, Automated Algorithm +Selection, Automated Algorithm Configuration, and Reproducibility. I +am also moderately interested in Compilers, Distributed Computing, and +High-Performance Computing (HPC). + +Technology-wise I'm mainly working with Linux, Emacs, C/C++, Rust, R, +Python, Nix, GLPK, Slurm, and SQLite. + +### Email + +- Personal: [public@adbjesus.com](mailto:public@adbjesus.com) +- Professional: [ajesus@dei.uc.pt](mailto:ajesus@dei.uc.pt) + +Please [use plaintext](https://useplaintext.email/) when contacting +me. + +### Around the Web + +* [ORCID](https://orcid.org/0000-0001-7691-0295) +* [Scholar](https://scholar.google.com/citations?user=D2me-IYAAAAJ&hl=en) +* [Research Gate](https://www.researchgate.net/profile/Alexandre_Jesus2) +* [Github](https://github.com/adbjesus) + + diff --git a/content/blog/01-hello-world/index.md b/content/blog/01-hello-world/index.md new file mode 100644 index 0000000..e0aaefe --- /dev/null +++ b/content/blog/01-hello-world/index.md @@ -0,0 +1,193 @@ +--- +author: A.D.B. Jesus +date: 2022-08-29 +slug: hello-world +title: Hello, world! +--- + +I have been thinking of starting a blog for a while, mostly to write +about stuff that makes no sense to publish academically, but also to +improve my writing skills. I expect to mostly write about Programming, +Emacs, Linux, and other tech topics. But we will see where it goes. + +In this first post I will quickly go over the implementation and +deployment of this site. Note that, you can find the code for this site +at . + +### Static Site Generator + +Since this site will contain static content, I've decided to go with a +static site generator. In particular, I chose +[Zola](https://getzola.org). The main reason for using Zola and not +something else is that I am familiar with its implementation language +(Rust). This can allow me to easily contribute to the project to fix any +issue or scratch any itch. + +In terms of styling, I'm using simple templates and CSS I implemented +myself, which match the light/dark system theme option set by the user. +Something I am not yet doing, is using syntax highlighting for code in +blog posts. Although Zola supports this, it does not support some of the +languages that I want, such as Emacs Lisp and Nix, and it is using old +and buggy Sublime syntaxes. There is currently an [open +issue](https://github.com/getzola/zola/issues/1787) to replace the +current system. Another option, would be to use a javascript based +syntax highlighter. However, I would rather keep my site +javascript-free. As a result, since I don't consider it to be a critical +feature for now, I will not implement any syntax highlighting for the +time being. + +### Using Org + +One issue I had with Zola is that it does not suppor +[Org](https://orgmode.org) for writing content (see this +[issue](https://github.com/getzola/zola/issues/909)). However, I would +prefer to use it instead of markdown because I prefer and am more +comfortable with its syntax, but also because I want to be able to use +[Org Babel](https://orgmode.org/worg/org-contrib/babel/) to execute code +within the `.org` file directly when writing posts for which executing +code is useful. + +Nonetheless, this proved not to be an issue for my simple use case +because I can automatically convert `.org` files to `.md` files +(following the [CommonMark](https://commonmark.org/) spec) using +[pandoc](https://pandoc.org), and the +[ox-pandoc](https://github.com/emacsorphanage/ox-pandoc) package for +Emacs. To setup ox-pandoc to export `.org` files to CommonMark I have +the following in my Emacs configuration: + +``` elisp +(use-package ox-pandoc + :ensure t + :after org + :custom + (org-pandoc-menu-entry + '((?c "to cmk." org-pandoc-export-to-commonmark) + (?C "to cmk and open." org-pandoc-export-to-commonmark-and-open)))) +``` + +Then, I put the `index.org` for a blog post inside a dedicated folder +for that post: + +``` example +content +└── blog + └── 01-hello-world + ├── index.org + └── ... // other files +``` + +The `index.org` file includes some metadata in its header for both Zola +and ox-pandoc. For example, for this post I'm using the following +header: + +``` org +#+TITLE: Hello, world! +#+DATE: 2022-08-25 +#+PANDOC_METADATA: slug:hello-world +#+PANDOC_EXTENSIONS: commonmark+yaml_metadata_block +#+PANDOC_OPTIONS: standalone:t +#+PANDOC_OPTIONS: shift-heading-level-by:2 +``` + +The `TITLE`, `DATE`, and `PANDOC_METADATA` fields are added to the +exported markdown metadata block. To add the metadata block to the +generated markdown file we set the `yaml_metadata_block` pandoc +extension in `PANDOC_EXTENSIONS`, and the `standalone:t` option in +`PANDOC_OPTIONS`. The last line is used to start the generated headings' +levels at 3 for styling purposes. + +Finally, I use the `C-c C-e p c` shortcut to generate the markdown file, +which goes into the same folder, i.e.: + +``` example +content +└── blog + └── 01-hello-world + ├── index.org + ├── index.md + └── ... // other files +``` + +You can find the Org source for this post [here](index.org). + +### Deploying with Nix + +I deploy this site to my [NixOS](https://nixos.org) server using the +declarative NixOS configuration capabilities. For this I have a +`flake.nix` in the repository of this site: + +``` nix +{ + description = "My personal website"; + + inputs = { + nixpkgs = { + url = "github:nixos/nixpkgs/nixos-22.05"; + }; + + flake-utils = { + url = "github:numtide/flake-utils"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + in rec { + packages.website = + pkgs.stdenv.mkDerivation { + name = "website"; + src = self; + + buildInputs = [ pkgs.zola ]; + + buildPhase = '' + zola build + ''; + + installPhase = '' + mkdir -p $out cp -Tr public $out/public + ''; + }; + + packages.default = self.packages.${system}.website; + } + ); +} +``` + +Then I add this repository to the inputs section of the NixOS +`flake.nix` configuration file. + +``` nix +inputs.website = { + url = "git+https://git.adbjesus.com/website"; + inputs.nixpkgs.follows = "nixpkgs"; +}; +``` + +and use the `nginx.virtualHosts` option to deploy it: + +``` nix +nginx.virtualHosts = { + "adbjesus.com" = { + default = true; + forceSSL = true; + enableACME = true; + locations = { + "/" = { + root = "${inputs.website.packages.${system}.website}/public"; + extraConfig = '' + add_header Last-Modified "${toDateTime inputs.website.lastModified}"; + add_header Cache-Control max-age="${toString (60 * 60 * 24)}"; + ''; + }; + }; + }; +}; +``` + +In the future, I will write more about my NixOS configuration using +flakes, which I use to manage my personal computers and server. diff --git a/content/blog/01-hello-world/index.org b/content/blog/01-hello-world/index.org new file mode 100644 index 0000000..aa51773 --- /dev/null +++ b/content/blog/01-hello-world/index.org @@ -0,0 +1,190 @@ +#+TITLE: Hello, world! +#+DATE: 2022-08-29 +#+AUTHOR: A.D.B. Jesus +#+PANDOC_METADATA: slug:hello-world +#+PANDOC_EXTENSIONS: commonmark+yaml_metadata_block +#+PANDOC_OPTIONS: standalone:t +#+PANDOC_OPTIONS: shift-heading-level-by:2 +#+SPDX-FileCopyrightText: 2022 A.D.B. Jesus +#+SPDX-License-Identifier: CC-BY-SA-4.0 + +I have been thinking of starting a blog for a while, mostly to write +about stuff that makes no sense to publish academically, but also to +improve my writing skills. I expect to mostly write about Programming, +Emacs, Linux, and other tech topics. But we will see where it goes. + +In this first post I will quickly go over the implementation and +deployment of this site. Note that, you can find the code for this +site at https://git.adbjesus.com/website. + +* Static Site Generator + +Since this site will contain static content, I've decided to go with a +static site generator. In particular, I chose [[https://getzola.org][Zola]]. The main reason +for using Zola and not something else is that I am familiar with its +implementation language (Rust). This can allow me to easily contribute +to the project to fix any issue or scratch any itch. + +In terms of styling, I'm using simple templates and CSS I implemented +myself, which match the light/dark system theme option set by the +user. Something I am not yet doing, is using syntax highlighting for +code in blog posts. Although Zola supports this, it does not support +some of the languages that I want, such as Emacs Lisp and Nix, and it +is using old and buggy Sublime syntaxes. There is currently an [[https://github.com/getzola/zola/issues/1787][open +issue]] to replace the current system. Another option, would be to use a +javascript based syntax highlighter. However, I would rather keep my +site javascript-free. As a result, since I don't consider it to be a +critical feature for now, I will not implement any syntax highlighting +for the time being. + +* Using Org + +One issue I had with Zola is that it does not suppor [[https://orgmode.org][Org]] for writing +content (see this [[https://github.com/getzola/zola/issues/909][issue]]). However, I would prefer to use it instead of +markdown because I prefer and am more comfortable with its syntax, but +also because I want to be able to use [[https://orgmode.org/worg/org-contrib/babel/][Org Babel]] to execute code within +the =.org= file directly when writing posts for which executing code +is useful. + +Nonetheless, this proved not to be an issue for my simple use case +because I can automatically convert =.org= files to =.md= files +(following the [[https://commonmark.org/][CommonMark]] spec) using [[https://pandoc.org][pandoc]], and the [[https://github.com/emacsorphanage/ox-pandoc][ox-pandoc]] +package for Emacs. To setup ox-pandoc to export =.org= files to +CommonMark I have the following in my Emacs configuration: + +#+begin_src elisp :eval no +(use-package ox-pandoc + :ensure t + :after org + :custom + (org-pandoc-menu-entry + '((?c "to cmk." org-pandoc-export-to-commonmark) + (?C "to cmk and open." org-pandoc-export-to-commonmark-and-open)))) +#+end_src + +Then, I put the =index.org= for a blog post inside a dedicated folder +for that post: + +#+begin_example +content +└── blog + └── 01-hello-world + ├── index.org + └── ... // other files +#+end_example + +The =index.org= file includes some metadata in its header for both +Zola and ox-pandoc. For example, for this post I'm using the following +header: + +#+begin_src org :eval no +#+TITLE: Hello, world! +#+DATE: 2022-08-25 +#+PANDOC_METADATA: slug:hello-world +#+PANDOC_EXTENSIONS: commonmark+yaml_metadata_block +#+PANDOC_OPTIONS: standalone:t +#+PANDOC_OPTIONS: shift-heading-level-by:2 +#+end_src + +The =TITLE=, =DATE=, and =PANDOC_METADATA= fields are added to the +exported markdown metadata block. To add the metadata block to the +generated markdown file we set the =yaml_metadata_block= pandoc +extension in =PANDOC_EXTENSIONS=, and the =standalone:t= option in +=PANDOC_OPTIONS=. The last line is used to start the generated +headings' levels at 3 for styling purposes. + +Finally, I use the =C-c C-e p c= shortcut to generate the markdown file, +which goes into the same folder, i.e.: + +#+begin_example +content +└── blog + └── 01-hello-world + ├── index.org + ├── index.md + └── ... // other files +#+end_example + +You can find the Org source for this post [[file:index.org][here]]. + +* Deploying with Nix + +I deploy this site to my [[https://nixos.org][NixOS]] server using the declarative NixOS +configuration capabilities. For this I have a =flake.nix= in the +repository of this site: + +#+begin_src nix +{ + description = "My personal website"; + + inputs = { + nixpkgs = { + url = "github:nixos/nixpkgs/nixos-22.05"; + }; + + flake-utils = { + url = "github:numtide/flake-utils"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { inherit system; }; + in rec { + packages.website = + pkgs.stdenv.mkDerivation { + name = "website"; + src = self; + + buildInputs = [ pkgs.zola ]; + + buildPhase = '' + zola build + ''; + + installPhase = '' + mkdir -p $out cp -Tr public $out/public + ''; + }; + + packages.default = self.packages.${system}.website; + } + ); +} +#+end_src + +Then I add this repository to the inputs section of the NixOS +=flake.nix= configuration file. + +#+begin_src nix +inputs.website = { + url = "git+https://git.adbjesus.com/website"; + inputs.nixpkgs.follows = "nixpkgs"; +}; +#+end_src + +and use the =nginx.virtualHosts= option to deploy it: + +#+begin_src nix +nginx.virtualHosts = { + "adbjesus.com" = { + default = true; + forceSSL = true; + enableACME = true; + locations = { + "/" = { + root = "${inputs.website.packages.${system}.website}/public"; + extraConfig = '' + add_header Last-Modified "${toDateTime inputs.website.lastModified}"; + add_header Cache-Control max-age="${toString (60 * 60 * 24)}"; + ''; + }; + }; + }; +}; +#+end_src + +In the future, I will write more about my NixOS configuration using +flakes, which I use to manage my personal computers and server. diff --git a/content/blog/_index.md b/content/blog/_index.md new file mode 100644 index 0000000..e6aaf2f --- /dev/null +++ b/content/blog/_index.md @@ -0,0 +1,6 @@ ++++ +title = "Blog" +sorted_by = "date" +template = "blog.html" +generate_feed = true ++++ diff --git a/content/publications/dias2021nondlib.pdf b/content/publications/dias2021nondlib.pdf new file mode 100644 index 0000000..8a3a888 Binary files /dev/null and b/content/publications/dias2021nondlib.pdf differ diff --git a/content/publications/index.md b/content/publications/index.md new file mode 100644 index 0000000..df1f564 --- /dev/null +++ b/content/publications/index.md @@ -0,0 +1,61 @@ ++++ +title = "Publications" ++++ + +### Journal Articles + +- **A. D. Jesus**, L. Paquete, and A. Liefooghe, “A model of + anytime algorithm performance for bi-objective optimization”, + _Journal of Global Optimization_, vol. 79, pp. 329–350, Feb. 2021. + [DOI](https://doi.org/10.1007/s10898-020-00909-9) :: + [PDF](jesus2020model.pdf) +- **A. D. Jesus**, L. Paquete, and J. R. Figueira. “Finding + representations for an unconstrained bi-objective combinatorial + optimization problem”, _Optimization Letters_, vol. 12, pp. + 321-334, March 2018. + [DOI](https://doi.org/10.1007/s11590-017-1129-6) :: + [PDF](jesus2018finding.pdf) + +### Conference Articles + +- **A. D. Jesus**, L. Paquete, B. Derbel, and A. Liefooghe, “On + the design and anytime performance of indicator-based branch and + bound for multi-objective combinatorial optimization”, in + _Proceedings of the 2021 Genetic and Evolutionary Computation + Conference (GECCO '21)_, pp. 234-242, June 2021. + [DOI](https://doi.org/10.1145/3449639.3459360) :: + [PDF](jesus2021design.pdf) +- **A. D. Jesus**, A. Liefooghe, B. Derbel, and L. Paquete, + “Algorithm Selection of Anytime Algorithms”, in + _Proceedings of the 2020 Genetic and Evolutionary Computation + Conference (GECCO '20)_, pp. 850-858, June 2020. + [DOI](https://doi.org/10.1145/3377930.3390185) :: + [PDF](jesus2020algorithm.pdf) + +### (Extended) Abstracts + +- **A. D. Jesus**, L. Paquete, A. Liefooghe, and B. Derbel, + “Techniques to analyze the anytime behavior of algorithms for + multi-objective optimization”, in _31st European Conference on + Operational Research (EURO 2021)_, July 2021. + [PDF](jesus2021techniques.pdf) +- D. M. Dias, **A. D. Jesus**, and L. Paquete, “A software + library for archiving nondominated points”, in _Proceedings of + the 2021 Genetic and Evolutionary Computation Conference Companion + (GECCO '21)_, pp. 53-54, June 2021. + [DOI](https://doi.org/10.1145/3449726.3462737) :: + [PDF](dias2021nondlib.pdf) +- **A. D. Jesus**, L. Paquete, A. Liefooghe. “A model of anytime + algorithm performance for biobjective optimization problems”, + in _Proceedings of the 14th International Global Optimization + Workshop (LeGO 2018)_, AIP Conference Proceedings 2070(1), + p. 020049, Feb. 2019. [DOI](https://doi.org/10.1063/1.5090016) :: + [PDF](jesus2019model.pdf) + +### Theses + +- **A. D. B. Jesus**, “Implicit Enumeration for Representation + Systems in Multi-objective Optimization”, MSc thesis, + University of Coimbra, Sep. 2015. + [Handle](https://hdl.handle.net/10316/35604) :: + [PDF](jesus2015implicit.pdf) diff --git a/content/publications/jesus2015implicit.pdf b/content/publications/jesus2015implicit.pdf new file mode 100644 index 0000000..36b9309 Binary files /dev/null and b/content/publications/jesus2015implicit.pdf differ diff --git a/content/publications/jesus2018finding.pdf b/content/publications/jesus2018finding.pdf new file mode 100644 index 0000000..4474004 Binary files /dev/null and b/content/publications/jesus2018finding.pdf differ diff --git a/content/publications/jesus2019model.pdf b/content/publications/jesus2019model.pdf new file mode 100644 index 0000000..35bcccc Binary files /dev/null and b/content/publications/jesus2019model.pdf differ diff --git a/content/publications/jesus2020algorithm.pdf b/content/publications/jesus2020algorithm.pdf new file mode 100644 index 0000000..baa70bd Binary files /dev/null and b/content/publications/jesus2020algorithm.pdf differ diff --git a/content/publications/jesus2020model.pdf b/content/publications/jesus2020model.pdf new file mode 100644 index 0000000..29bd249 Binary files /dev/null and b/content/publications/jesus2020model.pdf differ diff --git a/content/publications/jesus2021design.pdf b/content/publications/jesus2021design.pdf new file mode 100644 index 0000000..532b6ad Binary files /dev/null and b/content/publications/jesus2021design.pdf differ diff --git a/content/publications/jesus2021techniques.pdf b/content/publications/jesus2021techniques.pdf new file mode 100644 index 0000000..1575e10 Binary files /dev/null and b/content/publications/jesus2021techniques.pdf differ diff --git a/content/software/index.md b/content/software/index.md new file mode 100644 index 0000000..045624e --- /dev/null +++ b/content/software/index.md @@ -0,0 +1,58 @@ ++++ +title = "Software" ++++ + +### mooutils + + C++ library containing several utilities to aid in the + implementation of multi-objective optimization algorithms, such as: + quality indicators, dominance relations, sets of non-dominated + points/solutions, queues of solutions. + + [Github](https://github.com/adbjesus/mooutils), + [Zenodo](https://doi.org/10.5281/zenodo.6855878) + +### mobkp + + C++ library and solver for the multi-objective binary knapsack + problem, which includes several state of the art algorithms. + + [Github](https://github.com/adbjesus/mobkp), + [Zenodo](https://doi.org/10.5281/zenodo.6857685) + +### anytime + + R library to help analyze the anytime behavior of algorithms, which + provides several publication ready `ggplot2` plots, and a scalar + measure of anytime performance. + + [Github](https://github.com/adbjesus/anytime), + [Zenodo](https://doi.org/10.5281/zenodo.6856119) + +### nondLib + + C++ library for building and updatings sets of nondominated points, + providing several methods to filter the nondominated points from a + larger set, and a method to add nondominated points to a set. + + [Github](https://github.com/TLDart/nondLib), + [Zenodo](https://doi.org/10.5281/zenodo.4733026) + +### apm + + C++ library and binary for computing models of anytime + performance. Currently, it supports a theoretical model of anytime + performance for bi-objective anytime algorithms that find at each + iteration a solution to a bi-objective problem. + + [Github](https://github.com/adbjesus/apm), + [Zenodo](https://doi.org/10.5281/zenodo.6856094) + +### moco\_abm + + Rust library and binary to compute the ideal anytime behavior + theoretical model for bi-objective anytime algorithms that collect + an efficient solution at each iteration. + + [Github](https://github.com/adbjesus/moco_abm), + [Zenodo](https://doi.org/10.5281/zenodo.2551046) diff --git a/content/teaching/index.md b/content/teaching/index.md new file mode 100644 index 0000000..1a98c38 --- /dev/null +++ b/content/teaching/index.md @@ -0,0 +1,31 @@ ++++ +title = "Teaching" ++++ + +### MSc + +- Experimental Methods in Computer Science + - [2022-2023](https://apps.uc.pt/courses/EN/unit/88863/20328/2022-2023) + - [2021-2022](https://apps.uc.pt/courses/EN/unit/88863/20328/2021-2022) + - [2020-2021](https://apps.uc.pt/courses/EN/unit/88863/20328/2020-2021) + +### BSc + +- Algorithmic Strategies (previously Advanced Programming Laboratory) + - [2021-2022](https://apps.uc.pt/courses/EN/unit/89047/20442/2021-2022) + - [2020-2021](https://apps.uc.pt/courses/EN/unit/89047/20442/2020-2021) + - [2017-2018](https://apps.uc.pt/courses/EN/unit/9865/669/2017-2018) +- Compilers + - [2022-2023](https://apps.uc.pt/courses/EN/unit/9863/669/2022-2023) + - [2021-2022](https://apps.uc.pt/courses/EN/unit/9863/669/2021-2022) + - [2016-2017](https://apps.uc.pt/courses/EN/unit/9863/669/2016-2017) +- Data Structures and Algorithms + - [2020-2021](https://apps.uc.pt/courses/EN/unit/9854/20442/2020-2021) +- Introduction to Procedural Programming + - [2021-2022](https://apps.uc.pt/courses/EN/unit/9843/20442/2021-2022) + - [2020-2021](https://apps.uc.pt/courses/EN/unit/9843/20442/2020-2021) + +### Other + +- Introduction to Programming in Java + - [2013-2014](https://apps.uc.pt/courses/EN/unit/78102/14301/2013-2014) -- cgit v1.2.3