From 23f04635cc26e1b0553088f28553f518488a9fc8 Mon Sep 17 00:00:00 2001 From: Joris Date: Wed, 1 May 2019 15:52:32 +0200 Subject: Setup personal page with Hakyll --- .gitignore | 7 +- .gitlab-ci.yml | 10 + .tmuxinator.yml | 4 +- Makefile | 22 +- PersonalPage.cabal | 76 - README.md | 31 +- application.conf | 5 - assets/gitlab-icon.svg | 1 + assets/icon.png | Bin 0 -> 701 bytes build | 2 - css/Body.hs | 35 + css/Color.hs | 27 + css/Header.hs | 53 + css/IconLink.hs | 31 + css/Link.hs | 23 + css/Media.hs | 36 + css/NotFound.hs | 20 + css/Project.hs | 13 + css/Resume.hs | 87 + css/Section.hs | 43 + css/Size.hs | 24 + css/Skills.hs | 22 + css/Style.hs | 58 + cv.markdown | 55 + cv.tex | 23 + cv/education/1-insa.md | 8 + cv/education/2-master.md | 8 + cv/experience/1-developer.md | 22 + cv/experience/2-researcher.md | 15 + cv/experience/3-research-developer.md | 10 + cv/hobby/1-hobbies.md | 2 + cv/skill/1-technical-lead.md | 6 + cv/skill/2-developer.md | 10 + cv/skill/3-researcher.md | 8 + data.yaml | 308 ---- default.nix | 29 +- deploy | 12 + index.html | 66 + personalPage.cabal | 18 + project/01-shared-cost.md | 13 + project/02-ad-listener.md | 11 + project/03-reading.md | 14 + project/04-map-marks.md | 10 + project/05-catchvoid.md | 10 + project/06-personal-page.md | 13 + project/07-timer.md | 9 + project/08-cooking.md | 12 + project/09-nixos-config.md | 8 + project/10-dotfiles.md | 6 + projects.html | 5 + public/images/icon.png | Bin 701 -> 0 bytes .../font-awesome-4.2.0/css/font-awesome.css | 1672 -------------------- .../font-awesome-4.2.0/css/font-awesome.min.css | 4 - .../font-awesome-4.2.0/fonts/FontAwesome.otf | Bin 85908 -> 0 bytes .../fonts/fontawesome-webfont.eot | Bin 56006 -> 0 bytes .../fonts/fontawesome-webfont.svg | 520 ------ .../fonts/fontawesome-webfont.ttf | Bin 112160 -> 0 bytes .../fonts/fontawesome-webfont.woff | Bin 65452 -> 0 bytes public/stylesheets/reset.css | 57 - resume/email.png | Bin 1457 -> 0 bytes resume/external-link.png | Bin 0 -> 957 bytes resume/externalLink.png | Bin 957 -> 0 bytes resume/git.png | Bin 1744 -> 0 bytes resume/gitlab.png | Bin 0 -> 7718 bytes resume/missfont.log | 4 - resume/resume.cls | 101 -- src/Conf.hs | 27 - src/Daemon.hs | 18 - src/Daemon/Frequency.hs | 8 - src/Date.hs | 17 - src/Design/Color.hs | 27 - src/Design/Global.hs | 66 - src/Design/Header.hs | 56 - src/Design/Media.hs | 36 - src/Design/Name.hs | 15 - src/Design/NotFound.hs | 20 - src/Design/Projects.hs | 51 - src/Design/Resume.hs | 125 -- src/Design/Size.hs | 28 - src/Main.hs | 188 ++- src/Model.hs | 25 - src/Model/Company.hs | 13 - src/Model/Date.hs | 30 - src/Model/Degree.hs | 18 - src/Model/Header.hs | 25 - src/Model/Identity.hs | 14 - src/Model/Job.hs | 22 - src/Model/Project.hs | 18 - src/Model/School.hs | 13 - src/Model/SkillType.hs | 15 - src/Model/Translated.hs | 19 - src/Model/Translation/Key.hs | 28 - src/Model/Translation/Language.hs | 12 - src/Model/Translation/Message.hs | 90 -- src/PDF.hs | 41 - src/Resume.hs | 34 - src/Utils/String.hs | 21 - src/View/Git.hs | 37 - src/View/Header.hs | 42 - src/View/Icon.hs | 17 - src/View/Interval.hs | 39 - src/View/LaTeX/Resume.hs | 148 -- src/View/NotFound.hs | 26 - src/View/Page.hs | 33 - src/View/Project.hs | 66 - src/View/Resume.hs | 140 -- stack.yaml | 5 + templates/icons/code.svg | 1 + templates/icons/external-link.svg | 1 + templates/icons/gitlab.svg | 1 + templates/icons/printer.svg | 1 + templates/icons/user.svg | 1 + templates/layout.html | 34 + templates/layout.tex | 93 ++ templates/project.html | 37 + templates/resume.html | 28 + templates/resume.tex | 18 + 117 files changed, 1263 insertions(+), 4324 deletions(-) create mode 100644 .gitlab-ci.yml delete mode 100644 PersonalPage.cabal delete mode 100644 application.conf create mode 100644 assets/gitlab-icon.svg create mode 100644 assets/icon.png delete mode 100755 build create mode 100644 css/Body.hs create mode 100644 css/Color.hs create mode 100644 css/Header.hs create mode 100644 css/IconLink.hs create mode 100644 css/Link.hs create mode 100644 css/Media.hs create mode 100644 css/NotFound.hs create mode 100644 css/Project.hs create mode 100644 css/Resume.hs create mode 100644 css/Section.hs create mode 100644 css/Size.hs create mode 100644 css/Skills.hs create mode 100644 css/Style.hs create mode 100644 cv.markdown create mode 100644 cv.tex create mode 100644 cv/education/1-insa.md create mode 100644 cv/education/2-master.md create mode 100644 cv/experience/1-developer.md create mode 100644 cv/experience/2-researcher.md create mode 100644 cv/experience/3-research-developer.md create mode 100644 cv/hobby/1-hobbies.md create mode 100644 cv/skill/1-technical-lead.md create mode 100644 cv/skill/2-developer.md create mode 100644 cv/skill/3-researcher.md delete mode 100644 data.yaml create mode 100755 deploy create mode 100644 index.html create mode 100644 personalPage.cabal create mode 100644 project/01-shared-cost.md create mode 100644 project/02-ad-listener.md create mode 100644 project/03-reading.md create mode 100644 project/04-map-marks.md create mode 100644 project/05-catchvoid.md create mode 100644 project/06-personal-page.md create mode 100644 project/07-timer.md create mode 100644 project/08-cooking.md create mode 100644 project/09-nixos-config.md create mode 100644 project/10-dotfiles.md create mode 100644 projects.html delete mode 100644 public/images/icon.png delete mode 100644 public/stylesheets/font-awesome-4.2.0/css/font-awesome.css delete mode 100644 public/stylesheets/font-awesome-4.2.0/css/font-awesome.min.css delete mode 100644 public/stylesheets/font-awesome-4.2.0/fonts/FontAwesome.otf delete mode 100644 public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.eot delete mode 100644 public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.svg delete mode 100644 public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.ttf delete mode 100644 public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.woff delete mode 100644 public/stylesheets/reset.css delete mode 100644 resume/email.png create mode 100644 resume/external-link.png delete mode 100644 resume/externalLink.png delete mode 100644 resume/git.png create mode 100644 resume/gitlab.png delete mode 100644 resume/missfont.log delete mode 100644 resume/resume.cls delete mode 100644 src/Conf.hs delete mode 100644 src/Daemon.hs delete mode 100644 src/Daemon/Frequency.hs delete mode 100644 src/Date.hs delete mode 100644 src/Design/Color.hs delete mode 100644 src/Design/Global.hs delete mode 100644 src/Design/Header.hs delete mode 100644 src/Design/Media.hs delete mode 100644 src/Design/Name.hs delete mode 100644 src/Design/NotFound.hs delete mode 100644 src/Design/Projects.hs delete mode 100644 src/Design/Resume.hs delete mode 100644 src/Design/Size.hs delete mode 100644 src/Model.hs delete mode 100644 src/Model/Company.hs delete mode 100644 src/Model/Date.hs delete mode 100644 src/Model/Degree.hs delete mode 100644 src/Model/Header.hs delete mode 100644 src/Model/Identity.hs delete mode 100644 src/Model/Job.hs delete mode 100644 src/Model/Project.hs delete mode 100644 src/Model/School.hs delete mode 100644 src/Model/SkillType.hs delete mode 100644 src/Model/Translated.hs delete mode 100644 src/Model/Translation/Key.hs delete mode 100644 src/Model/Translation/Language.hs delete mode 100644 src/Model/Translation/Message.hs delete mode 100644 src/PDF.hs delete mode 100644 src/Resume.hs delete mode 100644 src/Utils/String.hs delete mode 100644 src/View/Git.hs delete mode 100644 src/View/Header.hs delete mode 100644 src/View/Icon.hs delete mode 100644 src/View/Interval.hs delete mode 100644 src/View/LaTeX/Resume.hs delete mode 100644 src/View/NotFound.hs delete mode 100644 src/View/Page.hs delete mode 100644 src/View/Project.hs delete mode 100644 src/View/Resume.hs create mode 100644 stack.yaml create mode 100644 templates/icons/code.svg create mode 100644 templates/icons/external-link.svg create mode 100644 templates/icons/gitlab.svg create mode 100644 templates/icons/printer.svg create mode 100644 templates/icons/user.svg create mode 100644 templates/layout.html create mode 100644 templates/layout.tex create mode 100644 templates/project.html create mode 100644 templates/resume.html create mode 100644 templates/resume.tex diff --git a/.gitignore b/.gitignore index 7c0f050..a40fba1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ -dist-newstyle -public/resumes -.ghc.environment.* +.stack-work/ +_cache/ +output/ +public/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..2062877 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,10 @@ +image: alpine:latest +pages: + stage: deploy + script: + - echo 'Nothing to do...' + artifacts: + paths: + - public + only: + - deploy diff --git a/.tmuxinator.yml b/.tmuxinator.yml index da872d4..90c4684 100644 --- a/.tmuxinator.yml +++ b/.tmuxinator.yml @@ -4,5 +4,5 @@ startup_window: app windows: - console: - clear - - app: - - make clean watch + - main: + - make install watch diff --git a/Makefile b/Makefile index e350236..446fb18 100644 --- a/Makefile +++ b/Makefile @@ -4,17 +4,21 @@ start: @nix-shell --command "tmuxinator local" stop: - @nix-shell --command "tmux kill-session -t personalPage" + @tmux kill-session -t personalPage clean: - @cabal new-clean > /dev/null + @stack exec personalPage clean > /dev/null 2>&1 || true + @stack clean > /dev/null -watch: - @nodemon --watch src/ application.conf ./data.yaml resume/ --ext hs,conf,yaml,cls --exec 'clear && make build-and-launch-server --silent' - -build-and-launch-server: - @(pkill personalPage || true) && (cabal new-run || true) +install: + @stack setup -.PHONY: build build: - @cabal new-build || true + @stack build + @stack exec personalPage build + +watch: + @nodemon --watch src -e hs --exec 'make watch-command --silent' + +watch-command: + @(killall personalPage || :) && sleep 1 && stack build && stack exec personalPage clean && stack exec personalPage watch diff --git a/PersonalPage.cabal b/PersonalPage.cabal deleted file mode 100644 index d9386eb..0000000 --- a/PersonalPage.cabal +++ /dev/null @@ -1,76 +0,0 @@ -Name: PersonalPage -Version: 1.0 -Synopsis: My personal page -Homepage: guyonvarch.me -License: GPL-3 -Author: Joris Guyonvarch -Category: Web -Build-type: Simple -Cabal-version: >= 1.8 - -Executable personalPage - Hs-source-dirs: src - Main-is: Main.hs - Ghc-options: -Wall -Werror - - Build-depends: - base - , text - , aeson - , yaml - , blaze-html - , blaze-markup - , clay - , bytestring - , HaTeX - , process - , mtl - , transformers - , temporary - , scotty - , wai-middleware-static - , time - , config-manager - , lens - , directory - , filepath - - Other-modules: - Conf - , Daemon - , Daemon.Frequency - , Date - , Design.Color - , Design.Global - , Design.Header - , Design.Media - , Design.NotFound - , Design.Projects - , Design.Resume - , Design.Size - , Model - , Model.Company - , Model.Date - , Model.Degree - , Model.Header - , Model.Identity - , Model.Job - , Model.Project - , Model.School - , Model.SkillType - , Model.Translated - , Model.Translation.Key - , Model.Translation.Language - , Model.Translation.Message - , PDF - , Resume - , Utils.String - , View.Git - , View.Header - , View.Icon - , View.Interval - , View.LaTeX.Resume - , View.NotFound - , View.Page - , View.Project - , View.Resume diff --git a/README.md b/README.md index 7190ea6..4faf3cd 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,24 @@ # Personal Page -Generate a website presenting resume and project from data given by a yaml -file. +Live [here](https://guyonvarch.gitlab.io/personalPage). + +[![build status](https://gitlab.com/guyonvarch/personalPage/badges/deploy/build.svg)](https://gitlab.com/guyonvarch/personalPage/commits/master) ## Required dependency - `pdflatex` -## Getting started +## Gettings started -Install nix: +Install nix and follow the instructions: -``` bash +```bash curl https://nixos.org/nix/install | sh ``` -Then, launch the environment with: +Then, start the environment with: -``` bash +```bash make start ``` @@ -27,16 +28,14 @@ Later, stop the environment with: make stop ``` -## Build +## Deploy on gitlab pages -``` sh -make build +```bash +./deploy ``` -## Configuration +## Improvements -``` -port = 3000 -git = "https://gitlab.com/" -generateResumes = Daily # Hourly / Daily -``` +- prettify urls +- i18n ? +- blog ? diff --git a/application.conf b/application.conf deleted file mode 100644 index 8a2979e..0000000 --- a/application.conf +++ /dev/null @@ -1,5 +0,0 @@ -port = 3000 -git = "https://gitlab.com/" -generateResumes = Daily - -importMaybe "local.conf" diff --git a/assets/gitlab-icon.svg b/assets/gitlab-icon.svg new file mode 100644 index 0000000..fd2bdb8 --- /dev/null +++ b/assets/gitlab-icon.svg @@ -0,0 +1 @@ +gitlab-icon-rgb \ No newline at end of file diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..115a297 Binary files /dev/null and b/assets/icon.png differ diff --git a/build b/build deleted file mode 100755 index 9eef0d2..0000000 --- a/build +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -nix-shell --command "make clean build" diff --git a/css/Body.hs b/css/Body.hs new file mode 100644 index 0000000..74aa969 --- /dev/null +++ b/css/Body.hs @@ -0,0 +1,35 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Body + ( style + ) where + +import Clay hiding (style) +import Prelude hiding ((**)) + +import qualified Color +import qualified Link +import qualified Media +import qualified Size + +style :: Css +style = do + + ".Body__Container" ** p ? do + lineHeight (px 28) + + ".Body__Container" ** ul ? do + paddingLeft (px 0) + Media.desktop $ margin (px 20) (px 0) (px 20) (px 30) + Media.tablet $ margin (px 15) (px 0) (px 15) (px 20) + Media.mobile $ marginBottom Size.listItemSep + + ".Body__Container" ** li ? do + Size.lineHeight + before & do + content (stringContent "•") + color Color.red + display inlineBlock + marginRight (px 10) + + Link.style (".Body__Container" ** a) diff --git a/css/Color.hs b/css/Color.hs new file mode 100644 index 0000000..bfc8134 --- /dev/null +++ b/css/Color.hs @@ -0,0 +1,27 @@ +module Color where + +import qualified Clay.Color as C + +white :: C.Color +white = C.white + +red :: C.Color +red = C.rgb 170 57 57 + +orange :: C.Color +orange = C.rgb 182 119 25 + +green :: C.Color +green = C.rgb 0 93 0 + +blue :: C.Color +blue = C.rgb 79 182 187 + +black :: C.Color +black = C.rgb 0 0 0 + +link :: C.Color +link = blue C.-. 70 + +gray :: C.Color +gray = C.rgb 100 100 100 diff --git a/css/Header.hs b/css/Header.hs new file mode 100644 index 0000000..ab58b0c --- /dev/null +++ b/css/Header.hs @@ -0,0 +1,53 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Header + ( style + ) where + +import Data.Monoid ((<>)) + +import Clay hiding (style) +import Clay.Display (displayTable) + +import qualified Color as Color +import qualified Media as Media + +style :: Css +style = do + + ".Header__Container" ? do + backgroundColor Color.red + color Color.white + fontSize (px 28) + display flex + + ".Header__Link" ? do + display flex + justifyContent center + alignItems center + flexGrow 1 + flexBasis (px 0) + height (em 3) + lineHeight (em 3) + textDecoration none + padding (px 0) (px 0) (px 0) (px 0) + textAlign (alignSide sideCenter) + color Color.white + textTransform capitalize + transition "background-color" (ms 500) ease (sec 0) + Media.tablet $ fontSize (em 0.8) + Media.mobile $ fontSize (em 0.6) + + (".Header__Link" # hover <> ".Header__Link" # focus <> ".Header__LinkCurrent") ? do + backgroundColor Color.red + borderBottomStyle solid + borderBottomColor (Color.red +. 40) + Media.mobile $ borderBottomWidth (px 6) + Media.tablet $ borderBottomWidth (px 8) + Media.desktop $ borderBottomWidth (px 10) + + ".Header__Icon" ? do + display flex + height (px 40) + marginRight (px 20) + Media.mobile $ display none diff --git a/css/IconLink.hs b/css/IconLink.hs new file mode 100644 index 0000000..9abbb5d --- /dev/null +++ b/css/IconLink.hs @@ -0,0 +1,31 @@ +{-# LANGUAGE OverloadedStrings #-} + +module IconLink + ( style + ) where + +import Clay hiding (style) + +import qualified Link +import qualified Media + +style :: Css +style = do + + Link.style ".IconLink__Link" + + ".IconLink__Link" ? do + display inlineFlex + alignItems center + marginBottom (px 15) + + Media.desktop $ fontSize (px 18) + Media.tablet $ fontSize (px 16) + Media.mobile $ fontSize (px 14) + + ".IconLink__Icon" ? do + marginRight (px 12) + + Media.desktop $ height (px 20) + Media.tablet $ height (px 16) + Media.mobile $ height (px 14) diff --git a/css/Link.hs b/css/Link.hs new file mode 100644 index 0000000..ba3b090 --- /dev/null +++ b/css/Link.hs @@ -0,0 +1,23 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Link + ( style + ) where + +import Clay hiding (style) +import Clay.Selector (Fix, SelectorF (SelectorF)) + +import qualified Color + +style :: (Fix SelectorF) -> Css +style selector = do + + selector ? do + textDecoration none + color Color.link + transition "color" (sec 0.3) easeOut (sec 0) + focus & outline solid (px 0) Color.white + + (selector # hover) <> (selector # focus) ? do + textDecoration underline + color Color.blue diff --git a/css/Media.hs b/css/Media.hs new file mode 100644 index 0000000..f9b56e1 --- /dev/null +++ b/css/Media.hs @@ -0,0 +1,36 @@ +module Media + ( mobile + , mobileTablet + , tablet + , tabletDesktop + , desktop + ) where + +import Clay hiding (query) +import qualified Clay +import qualified Clay.Media as Media +import Clay.Stylesheet (Feature) + +mobile :: Css -> Css +mobile = query [Media.maxWidth mobileTabletLimit] + +mobileTablet :: Css -> Css +mobileTablet = query [Media.maxWidth tabletDesktopLimit] + +tablet :: Css -> Css +tablet = query [Media.minWidth mobileTabletLimit, Media.maxWidth tabletDesktopLimit] + +tabletDesktop :: Css -> Css +tabletDesktop = query [Media.minWidth mobileTabletLimit] + +desktop :: Css -> Css +desktop = query [Media.minWidth tabletDesktopLimit] + +query :: [Feature] -> Css -> Css +query = Clay.query Media.screen + +mobileTabletLimit :: Size LengthUnit +mobileTabletLimit = (px 520) + +tabletDesktopLimit :: Size LengthUnit +tabletDesktopLimit = (px 950) diff --git a/css/NotFound.hs b/css/NotFound.hs new file mode 100644 index 0000000..ee8a0af --- /dev/null +++ b/css/NotFound.hs @@ -0,0 +1,20 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Design.NotFound + ( notFoundCss + ) where + +import Clay + +notFoundCss :: Css +notFoundCss = + + ".notFoundPage" ? do + + h1 ? do + fontSize (px 40) + fontWeight bold + margin (px 20) (px 20) (px 20) (px 20) + + p ? + margin (px 20) (px 20) (px 20) (px 20) diff --git a/css/Project.hs b/css/Project.hs new file mode 100644 index 0000000..99ddbd4 --- /dev/null +++ b/css/Project.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Project + ( style + ) where + +import Clay hiding (style) + +style :: Css +style = do + + ".Project__Body" ? do + marginTop (px 20) diff --git a/css/Resume.hs b/css/Resume.hs new file mode 100644 index 0000000..ec7af62 --- /dev/null +++ b/css/Resume.hs @@ -0,0 +1,87 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Resume + ( style + ) where + +import Clay hiding (style) + +import qualified Color +import qualified Media +import qualified Size + +style :: Css +style = do + + ".Resume__NameAndPrint" ? do + display flex + justifyContent spaceBetween + + ".Resume__Print" ? do + color Color.red + transition "all" (ms 100) ease (sec 0) + hover & transform (scale 1.2 1.2) + marginLeft (px 10) + + Media.desktop $ do + lineHeight (px 50) + height (px 50) + fontSize (px 40) + + Media.tablet $ do + lineHeight (px 40) + height (px 40) + fontSize (px 30) + + Media.mobile $ do + lineHeight (px 30) + height (px 30) + fontSize (px 20) + + ".Resume__GitLabLink" ? do + Media.desktop $ marginLeft (px 30) + Media.tablet $ marginLeft (px 20) + + ".Resume__Container" ? do + Media.desktop $ do + marginBottom (px 40) + marginLeft (px 30) + Media.tablet $ do + marginBottom (px 40) + marginLeft (px 20) + Media.mobile $ + marginBottom (px 25) + + ".Resume__Name" <> ".Resume__Location" <> ".Resume__Description" ? do + Size.lineHeight + + ".Resume__Name" ? do + backgroundColor Color.orange + color Color.white + padding (px 0) (px 10) (px 0) (px 10) + sym borderRadius (px 2) + + Media.desktop $ do + display inlineBlock + marginBottom (px 10) + + Media.mobileTablet $ + marginBottom (px 10) + + ".Resume__Time" ? do + fontStyle italic + marginBottom (px 10) + + Media.desktop $ do + display inlineBlock + marginLeft (px 15) + + Media.mobile $ + fontSize (pct 90) + + ".Resume__Location" ? do + color Color.green + Size.tabletMarginBottom + Media.mobile $ do + fontSize (pct 90) + marginBottom (px 10) diff --git a/css/Section.hs b/css/Section.hs new file mode 100644 index 0000000..4e236a3 --- /dev/null +++ b/css/Section.hs @@ -0,0 +1,43 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Section + ( style + ) where + +import Clay hiding (style) + +import qualified Color +import qualified Media + +style :: Css +style = do + + ".Section__Container" ? do + position relative + margin (pct 0) (pct 10) (pct 0) (pct 10) + + ".Section__Title" ? do + color Color.red + fontFamily [] [monospace] + fontWeight bold + + Media.desktop $ do + lineHeight (px 50) + fontSize (px 30) + marginBottom (px 40) + marginTop (px 55) + + Media.tablet $ do + lineHeight (px 40) + fontSize (px 27) + marginBottom (px 35) + marginTop (px 45) + + Media.mobile $ do + lineHeight (px 30) + fontSize (px 22) + marginBottom (px 20) + marginTop (px 35) + + ".Section__Entries" ? do + paddingLeft (px 0) diff --git a/css/Size.hs b/css/Size.hs new file mode 100644 index 0000000..1fc097b --- /dev/null +++ b/css/Size.hs @@ -0,0 +1,24 @@ +module Size + ( lineHeight + , listItemSep + , tabletMarginBottom + ) where + +import Clay hiding (lineHeight) +import qualified Clay + +import qualified Media + +lineHeight :: Css +lineHeight = do + Media.desktop $ Clay.lineHeight (px 40) + Media.tablet $ Clay.lineHeight (px 35) + Media.mobile $ Clay.lineHeight (px 30) + +listItemSep :: Size LengthUnit +listItemSep = + px 8 + +tabletMarginBottom :: Css +tabletMarginBottom = + Media.tablet $ marginBottom (px 15) diff --git a/css/Skills.hs b/css/Skills.hs new file mode 100644 index 0000000..96ef74e --- /dev/null +++ b/css/Skills.hs @@ -0,0 +1,22 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Skills + ( style + ) where + +import Clay hiding (style) +import qualified Clay.Flexbox as CF + +style :: Css +style = do + + ".Skills__List" ? do + display flex + flexWrap CF.wrap + sym2 margin (px 5) (px 0) + paddingLeft (px 0) + + ".Skills__Item" ? do + lineHeight normal + borderBottom solid (px 2) lightgray + margin (px 10) (px 15) (px 5) (px 0) diff --git a/css/Style.hs b/css/Style.hs new file mode 100644 index 0000000..f53ca1e --- /dev/null +++ b/css/Style.hs @@ -0,0 +1,58 @@ +{-# LANGUAGE OverloadedStrings #-} + +import Clay +import qualified Data.Text.Lazy.IO as T + +import qualified Body +import qualified Color +import qualified Header +import qualified IconLink +import qualified Media +import qualified Project +import qualified Resume +import qualified Section +import qualified Skills + +main :: IO () +main = T.putStrLn . renderWith compact [] $ do + + appearKeyframes + + body ? do + overflowX hidden + color Color.black + margin (px 0) (px 0) (px 40) (px 0) + Media.mobile $ fontSize (px 16) + Media.tabletDesktop $ fontSize (px 18) + + ".Main__Container" ? do + animationName "appear" + animationDuration (sec 0.2) + animationTimingFunction easeIn + animationIterationCount (iterationCount 1.0) + + svg ? do + width inherit + height inherit + + ul ? do + listStyleType none + paddingLeft (px 0) + + Body.style + Header.style + IconLink.style + Project.style + Resume.style + Section.style + Skills.style + +appearKeyframes :: Css +appearKeyframes = keyframes + "appear" + [ (0, do + "transform" -: "translateX(10px)" + opacity 0 + ) + , (100, "transform" -: "translateX(0px)") + ] diff --git a/cv.markdown b/cv.markdown new file mode 100644 index 0000000..a824ad5 --- /dev/null +++ b/cv.markdown @@ -0,0 +1,55 @@ +--- +test: bazzz +--- + +# Expérience + +## Développeur + +5 ans et 2 mois, depuis 2014 + +Zengularity, Paris + +Architecture web pour les systèmes d’information. + +- Catalogue de formations pour les bénéficiaires du RSA en Seine-Saint-Denis. +- Déclaration de sinistres pour Saretec. +- Affranchissement à l’unité et automatique d’étiquettes Colissimo pour La Poste. +- Espace adhérent de la Mutuelle Nationale Territoriale (MNT). +- Analyse d’échantillons alimentaires et visualisation des résultats pour Adisseo. + +- Scala +- Scala.js +- Elm +- Akka +- Play! +- MongoDB +- PostgreSQL +- ElasticSearch + +## Chercheur stagiaire + +5 mois, 2013 + +IRISA, Rennes + +Mise à l’échelle d’une recherche à facettes, à base de requêtes guidées et +expressives, dans le web sémantique. + +- Semantic Web +- Scala +- Java +- LaTeX +- GWT +- Jena + +## Ingénieur de recherche stagiaire + +3 mois, 2012 + +Mission Critical IT, Bruxelles + +Recherche et édition guidées de données du web sémantique. + +- Semantic Web +- Mercury diff --git a/cv.tex b/cv.tex new file mode 100644 index 0000000..3d6aa2f --- /dev/null +++ b/cv.tex @@ -0,0 +1,23 @@ +\section{Experience} + +$for(experience)$ + $body$ +$endfor$ + +\section{Études} + +$for(education)$ + $body$ +$endfor$ + +\section{Compétences} + +$for(skills)$ + $body$ +$endfor$ + +\section{Intérêts} + +$for(hobbies)$ + $body$ +$endfor$ diff --git a/cv/education/1-insa.md b/cv/education/1-insa.md new file mode 100644 index 0000000..fe722cc --- /dev/null +++ b/cv/education/1-insa.md @@ -0,0 +1,8 @@ +--- +name: Diplôme d’ingénieur en informatique +location: INSA, Rennes +--- + +- Langage +- Système +- Réseau diff --git a/cv/education/2-master.md b/cv/education/2-master.md new file mode 100644 index 0000000..4e9b9f3 --- /dev/null +++ b/cv/education/2-master.md @@ -0,0 +1,8 @@ +--- +name: Master Recherche en Informatique +location: University of Rennes I +--- + +- Apprentissage artificiel +- Modélisation +- Indexation de données diff --git a/cv/experience/1-developer.md b/cv/experience/1-developer.md new file mode 100644 index 0000000..2fb3ccb --- /dev/null +++ b/cv/experience/1-developer.md @@ -0,0 +1,22 @@ +--- +name: Développeur +time: depuis 2014 +location: Zengularity, Paris +skills: + - Scala + - Scala.js + - Elm + - Akka + - Play! + - MongoDB + - PostgreSQL + - ElasticSearch +--- + +Architecture web pour les systèmes d’information. + +- Catalogue de formations pour les bénéficiaires du RSA en Seine-Saint-Denis. +- Déclaration de sinistres pour Saretec. +- Affranchissement à l’unité et automatique d’étiquettes Colissimo pour La Poste. +- Espace adhérent de la Mutuelle Nationale Territoriale (MNT). +- Analyse d’échantillons alimentaires et visualisation des résultats pour Adisseo. diff --git a/cv/experience/2-researcher.md b/cv/experience/2-researcher.md new file mode 100644 index 0000000..6fe2c6d --- /dev/null +++ b/cv/experience/2-researcher.md @@ -0,0 +1,15 @@ +--- +name: Chercheur stagiaire +time: 5 mois +location: IRISA, Rennes +skills: + - Semantic Web + - Scala + - Java + - LaTeX + - GWT + - Jena +--- + +Mise à l’échelle d’une recherche à facettes, à base de requêtes guidées et +expressives, dans le web sémantique. diff --git a/cv/experience/3-research-developer.md b/cv/experience/3-research-developer.md new file mode 100644 index 0000000..f8da1cd --- /dev/null +++ b/cv/experience/3-research-developer.md @@ -0,0 +1,10 @@ +--- +name: Ingénieur de recherche stagiaire +time: 3 mois +location: Mission Critical IT, Bruxelles +skills: +- Semantic Web +- Mercury +--- + +Recherche et édition guidées de données du web sémantique. diff --git a/cv/hobby/1-hobbies.md b/cv/hobby/1-hobbies.md new file mode 100644 index 0000000..25fd153 --- /dev/null +++ b/cv/hobby/1-hobbies.md @@ -0,0 +1,2 @@ +- Ajuster mon poste informatique (NixOS, i3, clavier bépo). +- Créer des jeux vidéos (SDL, Elm). diff --git a/cv/skill/1-technical-lead.md b/cv/skill/1-technical-lead.md new file mode 100644 index 0000000..6fdd8b2 --- /dev/null +++ b/cv/skill/1-technical-lead.md @@ -0,0 +1,6 @@ +--- +name: Meneur technique +--- + +- Rédiger des tâches et sous-tâches à partir des besoins. +- Optimiser l’ordre des tâches pour l’équipe de développement. diff --git a/cv/skill/2-developer.md b/cv/skill/2-developer.md new file mode 100644 index 0000000..f62363c --- /dev/null +++ b/cv/skill/2-developer.md @@ -0,0 +1,10 @@ +--- +name: Développeur +--- + +- Programmer avec des langages fonctionnels (Haskell, Scala, Elm). +- Construire des applications web (protocole HTTP ; langages HTML, CSS, Javascript et JSON). +- Interagir avec des données (SQL, MongoDB, SPARQL). +- Travailler avec des versions (Git). +- Vérifier techniquement et fonctionnellement les développements. +- Écrire des scripts en Bash. diff --git a/cv/skill/3-researcher.md b/cv/skill/3-researcher.md new file mode 100644 index 0000000..5eb1320 --- /dev/null +++ b/cv/skill/3-researcher.md @@ -0,0 +1,8 @@ +--- +name: Chercheur +--- + +- Mener une recherche bibliographique. +- Construire un prototype et expérimenter à partir de ce prototype. +- Analyser les résultats du prototype et vérifier les hypothèses. +- Présenter un résultat de recherche à travers un article et un diaporama (LaTeX). diff --git a/data.yaml b/data.yaml deleted file mode 100644 index 27fae8d..0000000 --- a/data.yaml +++ /dev/null @@ -1,308 +0,0 @@ -description: I’m a developer using functional programming. View my resume and projects. - -identity: - name: Joris Guyonvarch - website: https://guyonvarch.me - git: guyonvarch - -jobs: - - name: - english: Software Architect - french: Architecte Logiciel - description: - english: Web Oriented Architecture (WOA) for information systems. - french: Architecture web pour les systèmes d’information. - company: - name: Zengularity - location: Paris - beginDate: - month: 03 - year: 2014 - details: - - english: Training platform for the unemployed in Seine-Saint-Denis. - french: Catalogue de formations pour les bénéficiaires du RSA en Seine-Saint-Denis. - - english: File house insurance claims for Saretec. - french: Déclaration de sinistres pour Saretec. - - english: Unit and automatic franking of Colissimo labels for La Poste. - french: Affranchissement à l’unité et automatique d’étiquettes Colissimo pour La Poste. - - english: Participant’s pages for the Mutuelle Nationale Territoriale (MNT). - french: Espace adhérent de la Mutuelle Nationale Territoriale (MNT). - - english: Food sample analysis with results visualization for Adisseo. - french: Analyse d’échantillons alimentaires avec visualisation des résultats pour Adisseo. - technos: - - Scala - - Scala.js - - Elm - - Akka - - Play! - - MongoDB - - PostgreSQL - - ElasticSearch - - name: - english: Phd Intern - french: Chercheur stagiaire - description: - english: Scalable query-based faceted search for guided and expressive - search on the semantic web. - french: Mise à l’échelle d’une recherche à facettes, à base de requêtes - guidées et expressives, dans le web sémantique. - company: - name: IRISA - location: Rennes - beginDate: - month: 02 - year: 2013 - endDate: - month: 06 - year: 2013 - technos: - - Semantic Web - - Scala - - Java - - LaTeX - - GWT - - Jena - - name: - english: R&D Engineering Intern - french: Ingénieur de recherche stagiaire - description: - english: Guided querying and edition of semantic web information. - french: Recherche et édition guidées de données du web sémantique. - company: - name: Mission Critical IT - location: Bruxelles - beginDate: - month: 06 - year: 2012 - endDate: - month: 08 - year: 2012 - technos: - - Semantic Web - - Mercury - -degrees: - - name: - english: Master of Science Computer Science - french: Diplôme d’ingénieur en informatique - school: - name: INSA - location: Rennes - year: 2013 - topics: - - english: Language - french: Langage - - english: System - french: Système - - english: Network - french: Réseau - - name: - english: Master of Research Computer Science - french: Master Recherche en Informatique - school: - name: University of Rennes I - year: 2013 - topics: - - english: Machine learning - french: Apprentissage artificiel - - english: Modelisation - french: Modélisation - - english: Data indexation - french: Indexation de données - -skillTypes: - - name: - english: Leader - french: Meneur - skills: - - english: Create tasks and subtasks from functional needs. - french: Rédiger des tâches et sous-tâches à partir des besoins. - - english: Optimise task order for the development team. - french: Optimiser l’ordre des tâches pour l’équipe de développement. - - name: - english: Developer - french: Développeur - skills: - - english: Program with functional languages (Haskell, Scala, Elm). - french: Programmer avec des langages fonctionnels (Haskell, Scala, Elm). - - english: Build web applications (HTTP protocol; HTML, CSS, Javascript and JSON languages). - french: Construire des applications web (protocole HTTP ; langages HTML, CSS, Javascript et JSON). - - english: Interact with data (SQL, MongoDB, SPARQL). - french: Interagir avec des données (SQL, MongoDB, SPARQL). - - english: Work with versioning (Git). - french: Travailler avec des versions (Git). - - english: Check code and run of developments. - french: Vérifier techniquement et fonctionnellement les développements. - - name: - english: Researcher - french: Chercheur - skills: - - english: Conduct a bibliographic research. - french: Mener une recherche bibliographique. - - english: Build a prototype and experiment from it. - french: Construire un prototype et expérimenter à partir de ce prototype. - - english: Analyse the results from an experimentation and check the hypotheses. - french: Analyser les résultats du prototype et vérifier les hypothèses. - - english: Present a research study through an article and a slideshow (LaTeX). - french: Présenter un résultat de recherche à travers un article et un - diaporama (LaTeX). - -interests: - - english: Tune my workstation (NixOS, i3, bépo keyboard layout). - french: Ajuster mon poste informatique (NixOS, i3, clavier bépo). - - english: Create video games (SDL, Elm). - french: Créer des jeux vidéos (SDL, Elm). - -projects: - - name: Shared Cost - git: guyonvarch/sharedCost - technologies: - - Haskell - - Scotty - - Elm - - Clay - - Persistent - description: - english: - Share costs with a group of people with a Rich Internet Application - (RIA). - french: - Partage des coûts au sein d’un groupe de personnes avec une Application - Internet Riche (RIA). - - name: ad-listener - git: guyonvarch/ad-listener - technologies: - - Haskell - - TagSoup - description: - english: - Watch for new ads according to custom search criteria and send an email - notification each time a new ad is available. - french: - Surveille l’ajout de nouvelles annonces à partir de critères de - recherche personnalisés et notifie par courriel lorsqu’une nouvelle - annonce est disponible. - - name: Reading - git: guyonvarch/reading - pageLink: http://guyonvarch.gitlab.io/reading - technologies: - - Scala - - Scala.js - - ScalaCSS - - Scalatags - - Scala.Rx - description: - english: Guide students to find a book by refining the result set with - faceted search. - french: Guide les élèves à trouver un livre en raffinant le résultat avec - une recherche à facettes. - - name: Map Marks - git: guyonvarch/mapMarks - pageLink: http://guyonvarch.gitlab.io/mapMarks - technologies: - - JavaScript - - Leaflet - description: - english: Show marks on a map from any given CSV file. - french: Affiche des marqueurs sur une carte à partir d’un fichier CSV. - - name: cAtchVoid - git: guyonvarch/catchvoid - pageLink: http://guyonvarch.gitlab.io/catchvoid - technologies: - - Elm - description: - english: - Catch the points of your color, avoid the others. You can switch colors - in order to reverse the game mechanic. Get the best score. - french: - Attrape les points de ta couleur tout en évitant les autres points. Tu - peux inverser la couleur de ton joueur, ce qui a pour effet d’inverser - la mécanique du jeu. Fais le meilleur score possible. - - name: Personal Page - git: guyonvarch/personalPage - pageLink: https://guyonvarch.me/ - technologies: - - Haskell - - Scotty - - BlazeHtml - - Clay - - HaTeX - description: - english: - Show resume and projects from YAML data with a web application. - french: - Présente le curriculum et les projets à partir de données au format - YAML avec une application web. - - name: Timer - git: guyonvarch/timer - pageLink: http://guyonvarch.gitlab.io/timer - technologies: - - Elm - description: - english: - Create and manage timers with a Rich Internet Application (RIA). - french: - Crée et gère une liste de minuteurs avec une Application Internet Riche - (RIA). - - name: Cooking - git: guyonvarch/cooking - pageLink: https://guyonvarch.gitlab.io/cooking - technologies: - - Haskell - - Hakyll - - Clay - description: - english: - Show recipes as a blog from markdown files. - french: - Présente des recettes sous la forme d’un blog à partir de fichiers markdown. - - name: nixos-config - git: guyonvarch/nixos-config - technologies: - - Nix - description: - english: - Declarative configuration of my NixOS system. - french: - Configuration déclarative de mon système NixOS. - - name: Events - git: guyonvarch/events - technologies: - - Haskell - - Parsec - description: - english: - Notify by email if there are any event today or next week. - french: - Notifie par courriel s’il y a des événements aujourd’hui ou la semaine - prochaine. - - name: Shopping - git: guyonvarch/shopping - technologies: - - Haskell - - Scotty - - Elm - - Clay - - Persistent - description: - english: - Creation, management and printing of shopping lists with a Rich - Internet Application (RIA). - french: - Création, gestion et impressions de listes de courses avec une - Application Internet Riche (RIA). - - name: Makeup - git: guyonvarch/makeup - technologies: - - HTML - - CSS - - JavaScript - - Markdown - description: - english: - Present makup tips grouped by categories thanks to other makeup - websites that are referenced. Makeup’s content is written in Markdown. - french: - Présente des astuces de maquillage groupées par catégories à partir de - nombreux sites de maquillage cités en référence. Le contenu de Makeup - est écrit en Markdown. diff --git a/default.nix b/default.nix index 155cee9..cde6a42 100644 --- a/default.nix +++ b/default.nix @@ -1,13 +1,18 @@ -with import {}; { - env = stdenv.mkDerivation { - name = "env"; - buildInputs = [ - cabal-install - nodePackages.nodemon - nodejs-8_x - tmux - tmuxinator - zlib - ]; - }; +with (import {}); + +haskell.lib.buildStackProject { + name = "myenv"; + + buildInputs = [ + zlib + stack + nodePackages.nodemon + tmux + tmuxinator + nodejs-8_x + ]; + + shellHook = '' + export PATH=node_modules/.bin:$PATH; + ''; } diff --git a/deploy b/deploy new file mode 100755 index 0000000..ec1ed47 --- /dev/null +++ b/deploy @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -e +git checkout master +git fetch +git merge --ff-only origin/master +nix-shell --command "make clean install build" +git checkout -b deploy +git add --force public +git commit -m "deploy $(date +%Y-%m-%d)" +git push --force origin deploy +git checkout master +git branch -D deploy diff --git a/index.html b/index.html new file mode 100644 index 0000000..960bc30 --- /dev/null +++ b/index.html @@ -0,0 +1,66 @@ +
+ +

+ Joris Guyonvarch + + + $partial("templates/icons/printer.svg")$ + +

+ + + + $partial("templates/icons/gitlab.svg")$ + + guyonvarch + + +
+ +
+ +

Expérience

+ +
    + $for(experience)$ + $body$ + $endfor$ +
+ +
+ +
+ +

Études

+ +
    + $for(education)$ + $body$ + $endfor$ +
+ +
+ +
+ +

Compétences

+ +
    + $for(skills)$ + $body$ + $endfor$ +
+ +
+ +
+ +

Intérêts

+ +
    + $for(hobbies)$ + $body$ + $endfor$ +
+ +
diff --git a/personalPage.cabal b/personalPage.cabal new file mode 100644 index 0000000..f1d5bae --- /dev/null +++ b/personalPage.cabal @@ -0,0 +1,18 @@ +name: personalPage +version: 0.0.1 +build-type: Simple +cabal-version: >= 1.10 + +executable personalPage + main-is: Main.hs + ghc-options: -Wall -Werror + hs-source-dirs: src + default-language: Haskell2010 + ghc-options: -threaded + build-depends: base + , hakyll + , clay + , process + , filepath + , text + , pandoc diff --git a/project/01-shared-cost.md b/project/01-shared-cost.md new file mode 100644 index 0000000..fc82853 --- /dev/null +++ b/project/01-shared-cost.md @@ -0,0 +1,13 @@ +--- +name: Shared Cost +gitlab: guyonvarch/sharedCost +skills: + - Haskell + - Scotty + - Elm + - Clay + - Persistent +--- + +Partage des coûts au sein d’un groupe de personnes avec une Application +Internet Riche (RIA). diff --git a/project/02-ad-listener.md b/project/02-ad-listener.md new file mode 100644 index 0000000..4cf85c3 --- /dev/null +++ b/project/02-ad-listener.md @@ -0,0 +1,11 @@ +--- +name: ad-listener +gitlab: guyonvarch/ad-listener +skills: + - Haskell + - TagSoup +--- + +Surveille l’ajout de nouvelles annonces à partir de critères de recherche +personnalisés et notifie par courriel lorsqu’une nouvelle annonce est +disponible. diff --git a/project/03-reading.md b/project/03-reading.md new file mode 100644 index 0000000..ab8493a --- /dev/null +++ b/project/03-reading.md @@ -0,0 +1,14 @@ +--- +name: Reading +gitlab: guyonvarch/reading +live: https://guyonvarch.gitlab.io/reading +skills: + - Scala + - Scala.js + - ScalaCSS + - Scalatags + - Scala.Rx +--- + +Guide les élèves à trouver un livre en raffinant le résultat avec une recherche +à facettes. diff --git a/project/04-map-marks.md b/project/04-map-marks.md new file mode 100644 index 0000000..4808a0a --- /dev/null +++ b/project/04-map-marks.md @@ -0,0 +1,10 @@ +--- +name: Map Marks +gitlab: guyonvarch/mapMarks +live: https://guyonvarch.gitlab.io/mapMarks +skills: + - JavaScript + - Leaflet +--- + +Affiche des marqueurs sur une carte à partir d’un fichier CSV. diff --git a/project/05-catchvoid.md b/project/05-catchvoid.md new file mode 100644 index 0000000..b270781 --- /dev/null +++ b/project/05-catchvoid.md @@ -0,0 +1,10 @@ +--- +name: cAtchVoid +gitlab: guyonvarch/catchvoid +live: http://guyonvarch.gitlab.io/catchvoid +skills: + - Elm + - Game development +--- + +Attrape les points de ta couleur tout en évitant les autres points. Tu peux inverser la couleur de ton joueur, ce qui a pour effet d’inverser la mécanique du jeu. Fais le meilleur score possible. diff --git a/project/06-personal-page.md b/project/06-personal-page.md new file mode 100644 index 0000000..b391e97 --- /dev/null +++ b/project/06-personal-page.md @@ -0,0 +1,13 @@ +--- +name: Personal Page +gitlab: guyonvarch/personalPage +live: https://guyonvarch.me/ +skills: + - Haskell + - Hakyll + - Clay + - LaTeX +--- + +Présente le curriculum et les projets à partir de données au format YAML avec +une application web. diff --git a/project/07-timer.md b/project/07-timer.md new file mode 100644 index 0000000..8a5c1f7 --- /dev/null +++ b/project/07-timer.md @@ -0,0 +1,9 @@ +--- +name: Timer +gitlab: guyonvarch/timer +live: http://guyonvarch.gitlab.io/timer +skills: + - Elm +--- + +Crée et gère une liste de minuteurs avec une Application Internet Riche (RIA). diff --git a/project/08-cooking.md b/project/08-cooking.md new file mode 100644 index 0000000..9485e30 --- /dev/null +++ b/project/08-cooking.md @@ -0,0 +1,12 @@ +--- +name: Cooking +gitlab: guyonvarch/cooking +live: https://guyonvarch.gitlab.io/cooking +skills: + - Haskell + - Hakyll + - Clay +--- + +Présente des recettes sous la forme d’un blog à partir de fichiers +markdown. diff --git a/project/09-nixos-config.md b/project/09-nixos-config.md new file mode 100644 index 0000000..2884686 --- /dev/null +++ b/project/09-nixos-config.md @@ -0,0 +1,8 @@ +--- +name: nixos-config +gitlab: guyonvarch/nixos-config +skills: + - Nix +--- + +Configure de manière déclarative mon système NixOS. diff --git a/project/10-dotfiles.md b/project/10-dotfiles.md new file mode 100644 index 0000000..685f385 --- /dev/null +++ b/project/10-dotfiles.md @@ -0,0 +1,6 @@ +--- +name: dotfiles +gitlab: guyonvarch/dotfiles +--- + +Configure les applications que j’utilise. diff --git a/projects.html b/projects.html new file mode 100644 index 0000000..8659cbc --- /dev/null +++ b/projects.html @@ -0,0 +1,5 @@ + diff --git a/public/images/icon.png b/public/images/icon.png deleted file mode 100644 index 115a297..0000000 Binary files a/public/images/icon.png and /dev/null differ diff --git a/public/stylesheets/font-awesome-4.2.0/css/font-awesome.css b/public/stylesheets/font-awesome-4.2.0/css/font-awesome.css deleted file mode 100644 index 4040b3c..0000000 --- a/public/stylesheets/font-awesome-4.2.0/css/font-awesome.css +++ /dev/null @@ -1,1672 +0,0 @@ -/*! - * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */ -/* FONT PATH - * -------------------------- */ -@font-face { - font-family: 'FontAwesome'; - src: url('../fonts/fontawesome-webfont.eot?v=4.2.0'); - src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg'); - font-weight: normal; - font-style: normal; -} -.fa { - display: inline-block; - font: normal normal normal 14px/1 FontAwesome; - font-size: inherit; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -/* makes the font 33% larger relative to the icon container */ -.fa-lg { - font-size: 1.33333333em; - line-height: 0.75em; - vertical-align: -15%; -} -.fa-2x { - font-size: 2em; -} -.fa-3x { - font-size: 3em; -} -.fa-4x { - font-size: 4em; -} -.fa-5x { - font-size: 5em; -} -.fa-fw { - width: 1.28571429em; - text-align: center; -} -.fa-ul { - padding-left: 0; - margin-left: 2.14285714em; - list-style-type: none; -} -.fa-ul > li { - position: relative; -} -.fa-li { - position: absolute; - left: -2.14285714em; - width: 2.14285714em; - top: 0.14285714em; - text-align: center; -} -.fa-li.fa-lg { - left: -1.85714286em; -} -.fa-border { - padding: .2em .25em .15em; - border: solid 0.08em #eeeeee; - border-radius: .1em; -} -.pull-right { - float: right; -} -.pull-left { - float: left; -} -.fa.pull-left { - margin-right: .3em; -} -.fa.pull-right { - margin-left: .3em; -} -.fa-spin { - -webkit-animation: fa-spin 2s infinite linear; - animation: fa-spin 2s infinite linear; -} -@-webkit-keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -.fa-rotate-90 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} -.fa-rotate-180 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); - -webkit-transform: rotate(180deg); - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} -.fa-rotate-270 { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); - -webkit-transform: rotate(270deg); - -ms-transform: rotate(270deg); - transform: rotate(270deg); -} -.fa-flip-horizontal { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); - -webkit-transform: scale(-1, 1); - -ms-transform: scale(-1, 1); - transform: scale(-1, 1); -} -.fa-flip-vertical { - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); - -webkit-transform: scale(1, -1); - -ms-transform: scale(1, -1); - transform: scale(1, -1); -} -:root .fa-rotate-90, -:root .fa-rotate-180, -:root .fa-rotate-270, -:root .fa-flip-horizontal, -:root .fa-flip-vertical { - filter: none; -} -.fa-stack { - position: relative; - display: inline-block; - width: 2em; - height: 2em; - line-height: 2em; - vertical-align: middle; -} -.fa-stack-1x, -.fa-stack-2x { - position: absolute; - left: 0; - width: 100%; - text-align: center; -} -.fa-stack-1x { - line-height: inherit; -} -.fa-stack-2x { - font-size: 2em; -} -.fa-inverse { - color: #ffffff; -} -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen - readers do not read off random characters that represent icons */ -.fa-glass:before { - content: "\f000"; -} -.fa-music:before { - content: "\f001"; -} -.fa-search:before { - content: "\f002"; -} -.fa-envelope-o:before { - content: "\f003"; -} -.fa-heart:before { - content: "\f004"; -} -.fa-star:before { - content: "\f005"; -} -.fa-star-o:before { - content: "\f006"; -} -.fa-user:before { - content: "\f007"; -} -.fa-film:before { - content: "\f008"; -} -.fa-th-large:before { - content: "\f009"; -} -.fa-th:before { - content: "\f00a"; -} -.fa-th-list:before { - content: "\f00b"; -} -.fa-check:before { - content: "\f00c"; -} -.fa-remove:before, -.fa-close:before, -.fa-times:before { - content: "\f00d"; -} -.fa-search-plus:before { - content: "\f00e"; -} -.fa-search-minus:before { - content: "\f010"; -} -.fa-power-off:before { - content: "\f011"; -} -.fa-signal:before { - content: "\f012"; -} -.fa-gear:before, -.fa-cog:before { - content: "\f013"; -} -.fa-trash-o:before { - content: "\f014"; -} -.fa-home:before { - content: "\f015"; -} -.fa-file-o:before { - content: "\f016"; -} -.fa-clock-o:before { - content: "\f017"; -} -.fa-road:before { - content: "\f018"; -} -.fa-download:before { - content: "\f019"; -} -.fa-arrow-circle-o-down:before { - content: "\f01a"; -} -.fa-arrow-circle-o-up:before { - content: "\f01b"; -} -.fa-inbox:before { - content: "\f01c"; -} -.fa-play-circle-o:before { - content: "\f01d"; -} -.fa-rotate-right:before, -.fa-repeat:before { - content: "\f01e"; -} -.fa-refresh:before { - content: "\f021"; -} -.fa-list-alt:before { - content: "\f022"; -} -.fa-lock:before { - content: "\f023"; -} -.fa-flag:before { - content: "\f024"; -} -.fa-headphones:before { - content: "\f025"; -} -.fa-volume-off:before { - content: "\f026"; -} -.fa-volume-down:before { - content: "\f027"; -} -.fa-volume-up:before { - content: "\f028"; -} -.fa-qrcode:before { - content: "\f029"; -} -.fa-barcode:before { - content: "\f02a"; -} -.fa-tag:before { - content: "\f02b"; -} -.fa-tags:before { - content: "\f02c"; -} -.fa-book:before { - content: "\f02d"; -} -.fa-bookmark:before { - content: "\f02e"; -} -.fa-print:before { - content: "\f02f"; -} -.fa-camera:before { - content: "\f030"; -} -.fa-font:before { - content: "\f031"; -} -.fa-bold:before { - content: "\f032"; -} -.fa-italic:before { - content: "\f033"; -} -.fa-text-height:before { - content: "\f034"; -} -.fa-text-width:before { - content: "\f035"; -} -.fa-align-left:before { - content: "\f036"; -} -.fa-align-center:before { - content: "\f037"; -} -.fa-align-right:before { - content: "\f038"; -} -.fa-align-justify:before { - content: "\f039"; -} -.fa-list:before { - content: "\f03a"; -} -.fa-dedent:before, -.fa-outdent:before { - content: "\f03b"; -} -.fa-indent:before { - content: "\f03c"; -} -.fa-video-camera:before { - content: "\f03d"; -} -.fa-photo:before, -.fa-image:before, -.fa-picture-o:before { - content: "\f03e"; -} -.fa-pencil:before { - content: "\f040"; -} -.fa-map-marker:before { - content: "\f041"; -} -.fa-adjust:before { - content: "\f042"; -} -.fa-tint:before { - content: "\f043"; -} -.fa-edit:before, -.fa-pencil-square-o:before { - content: "\f044"; -} -.fa-share-square-o:before { - content: "\f045"; -} -.fa-check-square-o:before { - content: "\f046"; -} -.fa-arrows:before { - content: "\f047"; -} -.fa-step-backward:before { - content: "\f048"; -} -.fa-fast-backward:before { - content: "\f049"; -} -.fa-backward:before { - content: "\f04a"; -} -.fa-play:before { - content: "\f04b"; -} -.fa-pause:before { - content: "\f04c"; -} -.fa-stop:before { - content: "\f04d"; -} -.fa-forward:before { - content: "\f04e"; -} -.fa-fast-forward:before { - content: "\f050"; -} -.fa-step-forward:before { - content: "\f051"; -} -.fa-eject:before { - content: "\f052"; -} -.fa-chevron-left:before { - content: "\f053"; -} -.fa-chevron-right:before { - content: "\f054"; -} -.fa-plus-circle:before { - content: "\f055"; -} -.fa-minus-circle:before { - content: "\f056"; -} -.fa-times-circle:before { - content: "\f057"; -} -.fa-check-circle:before { - content: "\f058"; -} -.fa-question-circle:before { - content: "\f059"; -} -.fa-info-circle:before { - content: "\f05a"; -} -.fa-crosshairs:before { - content: "\f05b"; -} -.fa-times-circle-o:before { - content: "\f05c"; -} -.fa-check-circle-o:before { - content: "\f05d"; -} -.fa-ban:before { - content: "\f05e"; -} -.fa-arrow-left:before { - content: "\f060"; -} -.fa-arrow-right:before { - content: "\f061"; -} -.fa-arrow-up:before { - content: "\f062"; -} -.fa-arrow-down:before { - content: "\f063"; -} -.fa-mail-forward:before, -.fa-share:before { - content: "\f064"; -} -.fa-expand:before { - content: "\f065"; -} -.fa-compress:before { - content: "\f066"; -} -.fa-plus:before { - content: "\f067"; -} -.fa-minus:before { - content: "\f068"; -} -.fa-asterisk:before { - content: "\f069"; -} -.fa-exclamation-circle:before { - content: "\f06a"; -} -.fa-gift:before { - content: "\f06b"; -} -.fa-leaf:before { - content: "\f06c"; -} -.fa-fire:before { - content: "\f06d"; -} -.fa-eye:before { - content: "\f06e"; -} -.fa-eye-slash:before { - content: "\f070"; -} -.fa-warning:before, -.fa-exclamation-triangle:before { - content: "\f071"; -} -.fa-plane:before { - content: "\f072"; -} -.fa-calendar:before { - content: "\f073"; -} -.fa-random:before { - content: "\f074"; -} -.fa-comment:before { - content: "\f075"; -} -.fa-magnet:before { - content: "\f076"; -} -.fa-chevron-up:before { - content: "\f077"; -} -.fa-chevron-down:before { - content: "\f078"; -} -.fa-retweet:before { - content: "\f079"; -} -.fa-shopping-cart:before { - content: "\f07a"; -} -.fa-folder:before { - content: "\f07b"; -} -.fa-folder-open:before { - content: "\f07c"; -} -.fa-arrows-v:before { - content: "\f07d"; -} -.fa-arrows-h:before { - content: "\f07e"; -} -.fa-bar-chart-o:before, -.fa-bar-chart:before { - content: "\f080"; -} -.fa-twitter-square:before { - content: "\f081"; -} -.fa-facebook-square:before { - content: "\f082"; -} -.fa-camera-retro:before { - content: "\f083"; -} -.fa-key:before { - content: "\f084"; -} -.fa-gears:before, -.fa-cogs:before { - content: "\f085"; -} -.fa-comments:before { - content: "\f086"; -} -.fa-thumbs-o-up:before { - content: "\f087"; -} -.fa-thumbs-o-down:before { - content: "\f088"; -} -.fa-star-half:before { - content: "\f089"; -} -.fa-heart-o:before { - content: "\f08a"; -} -.fa-sign-out:before { - content: "\f08b"; -} -.fa-linkedin-square:before { - content: "\f08c"; -} -.fa-thumb-tack:before { - content: "\f08d"; -} -.fa-external-link:before { - content: "\f08e"; -} -.fa-sign-in:before { - content: "\f090"; -} -.fa-trophy:before { - content: "\f091"; -} -.fa-github-square:before { - content: "\f092"; -} -.fa-upload:before { - content: "\f093"; -} -.fa-lemon-o:before { - content: "\f094"; -} -.fa-phone:before { - content: "\f095"; -} -.fa-square-o:before { - content: "\f096"; -} -.fa-bookmark-o:before { - content: "\f097"; -} -.fa-phone-square:before { - content: "\f098"; -} -.fa-twitter:before { - content: "\f099"; -} -.fa-facebook:before { - content: "\f09a"; -} -.fa-github:before { - content: "\f09b"; -} -.fa-unlock:before { - content: "\f09c"; -} -.fa-credit-card:before { - content: "\f09d"; -} -.fa-rss:before { - content: "\f09e"; -} -.fa-hdd-o:before { - content: "\f0a0"; -} -.fa-bullhorn:before { - content: "\f0a1"; -} -.fa-bell:before { - content: "\f0f3"; -} -.fa-certificate:before { - content: "\f0a3"; -} -.fa-hand-o-right:before { - content: "\f0a4"; -} -.fa-hand-o-left:before { - content: "\f0a5"; -} -.fa-hand-o-up:before { - content: "\f0a6"; -} -.fa-hand-o-down:before { - content: "\f0a7"; -} -.fa-arrow-circle-left:before { - content: "\f0a8"; -} -.fa-arrow-circle-right:before { - content: "\f0a9"; -} -.fa-arrow-circle-up:before { - content: "\f0aa"; -} -.fa-arrow-circle-down:before { - content: "\f0ab"; -} -.fa-globe:before { - content: "\f0ac"; -} -.fa-wrench:before { - content: "\f0ad"; -} -.fa-tasks:before { - content: "\f0ae"; -} -.fa-filter:before { - content: "\f0b0"; -} -.fa-briefcase:before { - content: "\f0b1"; -} -.fa-arrows-alt:before { - content: "\f0b2"; -} -.fa-group:before, -.fa-users:before { - content: "\f0c0"; -} -.fa-chain:before, -.fa-link:before { - content: "\f0c1"; -} -.fa-cloud:before { - content: "\f0c2"; -} -.fa-flask:before { - content: "\f0c3"; -} -.fa-cut:before, -.fa-scissors:before { - content: "\f0c4"; -} -.fa-copy:before, -.fa-files-o:before { - content: "\f0c5"; -} -.fa-paperclip:before { - content: "\f0c6"; -} -.fa-save:before, -.fa-floppy-o:before { - content: "\f0c7"; -} -.fa-square:before { - content: "\f0c8"; -} -.fa-navicon:before, -.fa-reorder:before, -.fa-bars:before { - content: "\f0c9"; -} -.fa-list-ul:before { - content: "\f0ca"; -} -.fa-list-ol:before { - content: "\f0cb"; -} -.fa-strikethrough:before { - content: "\f0cc"; -} -.fa-underline:before { - content: "\f0cd"; -} -.fa-table:before { - content: "\f0ce"; -} -.fa-magic:before { - content: "\f0d0"; -} -.fa-truck:before { - content: "\f0d1"; -} -.fa-pinterest:before { - content: "\f0d2"; -} -.fa-pinterest-square:before { - content: "\f0d3"; -} -.fa-google-plus-square:before { - content: "\f0d4"; -} -.fa-google-plus:before { - content: "\f0d5"; -} -.fa-money:before { - content: "\f0d6"; -} -.fa-caret-down:before { - content: "\f0d7"; -} -.fa-caret-up:before { - content: "\f0d8"; -} -.fa-caret-left:before { - content: "\f0d9"; -} -.fa-caret-right:before { - content: "\f0da"; -} -.fa-columns:before { - content: "\f0db"; -} -.fa-unsorted:before, -.fa-sort:before { - content: "\f0dc"; -} -.fa-sort-down:before, -.fa-sort-desc:before { - content: "\f0dd"; -} -.fa-sort-up:before, -.fa-sort-asc:before { - content: "\f0de"; -} -.fa-envelope:before { - content: "\f0e0"; -} -.fa-linkedin:before { - content: "\f0e1"; -} -.fa-rotate-left:before, -.fa-undo:before { - content: "\f0e2"; -} -.fa-legal:before, -.fa-gavel:before { - content: "\f0e3"; -} -.fa-dashboard:before, -.fa-tachometer:before { - content: "\f0e4"; -} -.fa-comment-o:before { - content: "\f0e5"; -} -.fa-comments-o:before { - content: "\f0e6"; -} -.fa-flash:before, -.fa-bolt:before { - content: "\f0e7"; -} -.fa-sitemap:before { - content: "\f0e8"; -} -.fa-umbrella:before { - content: "\f0e9"; -} -.fa-paste:before, -.fa-clipboard:before { - content: "\f0ea"; -} -.fa-lightbulb-o:before { - content: "\f0eb"; -} -.fa-exchange:before { - content: "\f0ec"; -} -.fa-cloud-download:before { - content: "\f0ed"; -} -.fa-cloud-upload:before { - content: "\f0ee"; -} -.fa-user-md:before { - content: "\f0f0"; -} -.fa-stethoscope:before { - content: "\f0f1"; -} -.fa-suitcase:before { - content: "\f0f2"; -} -.fa-bell-o:before { - content: "\f0a2"; -} -.fa-coffee:before { - content: "\f0f4"; -} -.fa-cutlery:before { - content: "\f0f5"; -} -.fa-file-text-o:before { - content: "\f0f6"; -} -.fa-building-o:before { - content: "\f0f7"; -} -.fa-hospital-o:before { - content: "\f0f8"; -} -.fa-ambulance:before { - content: "\f0f9"; -} -.fa-medkit:before { - content: "\f0fa"; -} -.fa-fighter-jet:before { - content: "\f0fb"; -} -.fa-beer:before { - content: "\f0fc"; -} -.fa-h-square:before { - content: "\f0fd"; -} -.fa-plus-square:before { - content: "\f0fe"; -} -.fa-angle-double-left:before { - content: "\f100"; -} -.fa-angle-double-right:before { - content: "\f101"; -} -.fa-angle-double-up:before { - content: "\f102"; -} -.fa-angle-double-down:before { - content: "\f103"; -} -.fa-angle-left:before { - content: "\f104"; -} -.fa-angle-right:before { - content: "\f105"; -} -.fa-angle-up:before { - content: "\f106"; -} -.fa-angle-down:before { - content: "\f107"; -} -.fa-desktop:before { - content: "\f108"; -} -.fa-laptop:before { - content: "\f109"; -} -.fa-tablet:before { - content: "\f10a"; -} -.fa-mobile-phone:before, -.fa-mobile:before { - content: "\f10b"; -} -.fa-circle-o:before { - content: "\f10c"; -} -.fa-quote-left:before { - content: "\f10d"; -} -.fa-quote-right:before { - content: "\f10e"; -} -.fa-spinner:before { - content: "\f110"; -} -.fa-circle:before { - content: "\f111"; -} -.fa-mail-reply:before, -.fa-reply:before { - content: "\f112"; -} -.fa-github-alt:before { - content: "\f113"; -} -.fa-folder-o:before { - content: "\f114"; -} -.fa-folder-open-o:before { - content: "\f115"; -} -.fa-smile-o:before { - content: "\f118"; -} -.fa-frown-o:before { - content: "\f119"; -} -.fa-meh-o:before { - content: "\f11a"; -} -.fa-gamepad:before { - content: "\f11b"; -} -.fa-keyboard-o:before { - content: "\f11c"; -} -.fa-flag-o:before { - content: "\f11d"; -} -.fa-flag-checkered:before { - content: "\f11e"; -} -.fa-terminal:before { - content: "\f120"; -} -.fa-code:before { - content: "\f121"; -} -.fa-mail-reply-all:before, -.fa-reply-all:before { - content: "\f122"; -} -.fa-star-half-empty:before, -.fa-star-half-full:before, -.fa-star-half-o:before { - content: "\f123"; -} -.fa-location-arrow:before { - content: "\f124"; -} -.fa-crop:before { - content: "\f125"; -} -.fa-code-fork:before { - content: "\f126"; -} -.fa-unlink:before, -.fa-chain-broken:before { - content: "\f127"; -} -.fa-question:before { - content: "\f128"; -} -.fa-info:before { - content: "\f129"; -} -.fa-exclamation:before { - content: "\f12a"; -} -.fa-superscript:before { - content: "\f12b"; -} -.fa-subscript:before { - content: "\f12c"; -} -.fa-eraser:before { - content: "\f12d"; -} -.fa-puzzle-piece:before { - content: "\f12e"; -} -.fa-microphone:before { - content: "\f130"; -} -.fa-microphone-slash:before { - content: "\f131"; -} -.fa-shield:before { - content: "\f132"; -} -.fa-calendar-o:before { - content: "\f133"; -} -.fa-fire-extinguisher:before { - content: "\f134"; -} -.fa-rocket:before { - content: "\f135"; -} -.fa-maxcdn:before { - content: "\f136"; -} -.fa-chevron-circle-left:before { - content: "\f137"; -} -.fa-chevron-circle-right:before { - content: "\f138"; -} -.fa-chevron-circle-up:before { - content: "\f139"; -} -.fa-chevron-circle-down:before { - content: "\f13a"; -} -.fa-html5:before { - content: "\f13b"; -} -.fa-css3:before { - content: "\f13c"; -} -.fa-anchor:before { - content: "\f13d"; -} -.fa-unlock-alt:before { - content: "\f13e"; -} -.fa-bullseye:before { - content: "\f140"; -} -.fa-ellipsis-h:before { - content: "\f141"; -} -.fa-ellipsis-v:before { - content: "\f142"; -} -.fa-rss-square:before { - content: "\f143"; -} -.fa-play-circle:before { - content: "\f144"; -} -.fa-ticket:before { - content: "\f145"; -} -.fa-minus-square:before { - content: "\f146"; -} -.fa-minus-square-o:before { - content: "\f147"; -} -.fa-level-up:before { - content: "\f148"; -} -.fa-level-down:before { - content: "\f149"; -} -.fa-check-square:before { - content: "\f14a"; -} -.fa-pencil-square:before { - content: "\f14b"; -} -.fa-external-link-square:before { - content: "\f14c"; -} -.fa-share-square:before { - content: "\f14d"; -} -.fa-compass:before { - content: "\f14e"; -} -.fa-toggle-down:before, -.fa-caret-square-o-down:before { - content: "\f150"; -} -.fa-toggle-up:before, -.fa-caret-square-o-up:before { - content: "\f151"; -} -.fa-toggle-right:before, -.fa-caret-square-o-right:before { - content: "\f152"; -} -.fa-euro:before, -.fa-eur:before { - content: "\f153"; -} -.fa-gbp:before { - content: "\f154"; -} -.fa-dollar:before, -.fa-usd:before { - content: "\f155"; -} -.fa-rupee:before, -.fa-inr:before { - content: "\f156"; -} -.fa-cny:before, -.fa-rmb:before, -.fa-yen:before, -.fa-jpy:before { - content: "\f157"; -} -.fa-ruble:before, -.fa-rouble:before, -.fa-rub:before { - content: "\f158"; -} -.fa-won:before, -.fa-krw:before { - content: "\f159"; -} -.fa-bitcoin:before, -.fa-btc:before { - content: "\f15a"; -} -.fa-file:before { - content: "\f15b"; -} -.fa-file-text:before { - content: "\f15c"; -} -.fa-sort-alpha-asc:before { - content: "\f15d"; -} -.fa-sort-alpha-desc:before { - content: "\f15e"; -} -.fa-sort-amount-asc:before { - content: "\f160"; -} -.fa-sort-amount-desc:before { - content: "\f161"; -} -.fa-sort-numeric-asc:before { - content: "\f162"; -} -.fa-sort-numeric-desc:before { - content: "\f163"; -} -.fa-thumbs-up:before { - content: "\f164"; -} -.fa-thumbs-down:before { - content: "\f165"; -} -.fa-youtube-square:before { - content: "\f166"; -} -.fa-youtube:before { - content: "\f167"; -} -.fa-xing:before { - content: "\f168"; -} -.fa-xing-square:before { - content: "\f169"; -} -.fa-youtube-play:before { - content: "\f16a"; -} -.fa-dropbox:before { - content: "\f16b"; -} -.fa-stack-overflow:before { - content: "\f16c"; -} -.fa-instagram:before { - content: "\f16d"; -} -.fa-flickr:before { - content: "\f16e"; -} -.fa-adn:before { - content: "\f170"; -} -.fa-bitbucket:before { - content: "\f171"; -} -.fa-bitbucket-square:before { - content: "\f172"; -} -.fa-tumblr:before { - content: "\f173"; -} -.fa-tumblr-square:before { - content: "\f174"; -} -.fa-long-arrow-down:before { - content: "\f175"; -} -.fa-long-arrow-up:before { - content: "\f176"; -} -.fa-long-arrow-left:before { - content: "\f177"; -} -.fa-long-arrow-right:before { - content: "\f178"; -} -.fa-apple:before { - content: "\f179"; -} -.fa-windows:before { - content: "\f17a"; -} -.fa-android:before { - content: "\f17b"; -} -.fa-linux:before { - content: "\f17c"; -} -.fa-dribbble:before { - content: "\f17d"; -} -.fa-skype:before { - content: "\f17e"; -} -.fa-foursquare:before { - content: "\f180"; -} -.fa-trello:before { - content: "\f181"; -} -.fa-female:before { - content: "\f182"; -} -.fa-male:before { - content: "\f183"; -} -.fa-gittip:before { - content: "\f184"; -} -.fa-sun-o:before { - content: "\f185"; -} -.fa-moon-o:before { - content: "\f186"; -} -.fa-archive:before { - content: "\f187"; -} -.fa-bug:before { - content: "\f188"; -} -.fa-vk:before { - content: "\f189"; -} -.fa-weibo:before { - content: "\f18a"; -} -.fa-renren:before { - content: "\f18b"; -} -.fa-pagelines:before { - content: "\f18c"; -} -.fa-stack-exchange:before { - content: "\f18d"; -} -.fa-arrow-circle-o-right:before { - content: "\f18e"; -} -.fa-arrow-circle-o-left:before { - content: "\f190"; -} -.fa-toggle-left:before, -.fa-caret-square-o-left:before { - content: "\f191"; -} -.fa-dot-circle-o:before { - content: "\f192"; -} -.fa-wheelchair:before { - content: "\f193"; -} -.fa-vimeo-square:before { - content: "\f194"; -} -.fa-turkish-lira:before, -.fa-try:before { - content: "\f195"; -} -.fa-plus-square-o:before { - content: "\f196"; -} -.fa-space-shuttle:before { - content: "\f197"; -} -.fa-slack:before { - content: "\f198"; -} -.fa-envelope-square:before { - content: "\f199"; -} -.fa-wordpress:before { - content: "\f19a"; -} -.fa-openid:before { - content: "\f19b"; -} -.fa-institution:before, -.fa-bank:before, -.fa-university:before { - content: "\f19c"; -} -.fa-mortar-board:before, -.fa-graduation-cap:before { - content: "\f19d"; -} -.fa-yahoo:before { - content: "\f19e"; -} -.fa-google:before { - content: "\f1a0"; -} -.fa-reddit:before { - content: "\f1a1"; -} -.fa-reddit-square:before { - content: "\f1a2"; -} -.fa-stumbleupon-circle:before { - content: "\f1a3"; -} -.fa-stumbleupon:before { - content: "\f1a4"; -} -.fa-delicious:before { - content: "\f1a5"; -} -.fa-digg:before { - content: "\f1a6"; -} -.fa-pied-piper:before { - content: "\f1a7"; -} -.fa-pied-piper-alt:before { - content: "\f1a8"; -} -.fa-drupal:before { - content: "\f1a9"; -} -.fa-joomla:before { - content: "\f1aa"; -} -.fa-language:before { - content: "\f1ab"; -} -.fa-fax:before { - content: "\f1ac"; -} -.fa-building:before { - content: "\f1ad"; -} -.fa-child:before { - content: "\f1ae"; -} -.fa-paw:before { - content: "\f1b0"; -} -.fa-spoon:before { - content: "\f1b1"; -} -.fa-cube:before { - content: "\f1b2"; -} -.fa-cubes:before { - content: "\f1b3"; -} -.fa-behance:before { - content: "\f1b4"; -} -.fa-behance-square:before { - content: "\f1b5"; -} -.fa-steam:before { - content: "\f1b6"; -} -.fa-steam-square:before { - content: "\f1b7"; -} -.fa-recycle:before { - content: "\f1b8"; -} -.fa-automobile:before, -.fa-car:before { - content: "\f1b9"; -} -.fa-cab:before, -.fa-taxi:before { - content: "\f1ba"; -} -.fa-tree:before { - content: "\f1bb"; -} -.fa-spotify:before { - content: "\f1bc"; -} -.fa-deviantart:before { - content: "\f1bd"; -} -.fa-soundcloud:before { - content: "\f1be"; -} -.fa-database:before { - content: "\f1c0"; -} -.fa-file-pdf-o:before { - content: "\f1c1"; -} -.fa-file-word-o:before { - content: "\f1c2"; -} -.fa-file-excel-o:before { - content: "\f1c3"; -} -.fa-file-powerpoint-o:before { - content: "\f1c4"; -} -.fa-file-photo-o:before, -.fa-file-picture-o:before, -.fa-file-image-o:before { - content: "\f1c5"; -} -.fa-file-zip-o:before, -.fa-file-archive-o:before { - content: "\f1c6"; -} -.fa-file-sound-o:before, -.fa-file-audio-o:before { - content: "\f1c7"; -} -.fa-file-movie-o:before, -.fa-file-video-o:before { - content: "\f1c8"; -} -.fa-file-code-o:before { - content: "\f1c9"; -} -.fa-vine:before { - content: "\f1ca"; -} -.fa-codepen:before { - content: "\f1cb"; -} -.fa-jsfiddle:before { - content: "\f1cc"; -} -.fa-life-bouy:before, -.fa-life-buoy:before, -.fa-life-saver:before, -.fa-support:before, -.fa-life-ring:before { - content: "\f1cd"; -} -.fa-circle-o-notch:before { - content: "\f1ce"; -} -.fa-ra:before, -.fa-rebel:before { - content: "\f1d0"; -} -.fa-ge:before, -.fa-empire:before { - content: "\f1d1"; -} -.fa-git-square:before { - content: "\f1d2"; -} -.fa-git:before { - content: "\f1d3"; -} -.fa-hacker-news:before { - content: "\f1d4"; -} -.fa-tencent-weibo:before { - content: "\f1d5"; -} -.fa-qq:before { - content: "\f1d6"; -} -.fa-wechat:before, -.fa-weixin:before { - content: "\f1d7"; -} -.fa-send:before, -.fa-paper-plane:before { - content: "\f1d8"; -} -.fa-send-o:before, -.fa-paper-plane-o:before { - content: "\f1d9"; -} -.fa-history:before { - content: "\f1da"; -} -.fa-circle-thin:before { - content: "\f1db"; -} -.fa-header:before { - content: "\f1dc"; -} -.fa-paragraph:before { - content: "\f1dd"; -} -.fa-sliders:before { - content: "\f1de"; -} -.fa-share-alt:before { - content: "\f1e0"; -} -.fa-share-alt-square:before { - content: "\f1e1"; -} -.fa-bomb:before { - content: "\f1e2"; -} -.fa-soccer-ball-o:before, -.fa-futbol-o:before { - content: "\f1e3"; -} -.fa-tty:before { - content: "\f1e4"; -} -.fa-binoculars:before { - content: "\f1e5"; -} -.fa-plug:before { - content: "\f1e6"; -} -.fa-slideshare:before { - content: "\f1e7"; -} -.fa-twitch:before { - content: "\f1e8"; -} -.fa-yelp:before { - content: "\f1e9"; -} -.fa-newspaper-o:before { - content: "\f1ea"; -} -.fa-wifi:before { - content: "\f1eb"; -} -.fa-calculator:before { - content: "\f1ec"; -} -.fa-paypal:before { - content: "\f1ed"; -} -.fa-google-wallet:before { - content: "\f1ee"; -} -.fa-cc-visa:before { - content: "\f1f0"; -} -.fa-cc-mastercard:before { - content: "\f1f1"; -} -.fa-cc-discover:before { - content: "\f1f2"; -} -.fa-cc-amex:before { - content: "\f1f3"; -} -.fa-cc-paypal:before { - content: "\f1f4"; -} -.fa-cc-stripe:before { - content: "\f1f5"; -} -.fa-bell-slash:before { - content: "\f1f6"; -} -.fa-bell-slash-o:before { - content: "\f1f7"; -} -.fa-trash:before { - content: "\f1f8"; -} -.fa-copyright:before { - content: "\f1f9"; -} -.fa-at:before { - content: "\f1fa"; -} -.fa-eyedropper:before { - content: "\f1fb"; -} -.fa-paint-brush:before { - content: "\f1fc"; -} -.fa-birthday-cake:before { - content: "\f1fd"; -} -.fa-area-chart:before { - content: "\f1fe"; -} -.fa-pie-chart:before { - content: "\f200"; -} -.fa-line-chart:before { - content: "\f201"; -} -.fa-lastfm:before { - content: "\f202"; -} -.fa-lastfm-square:before { - content: "\f203"; -} -.fa-toggle-off:before { - content: "\f204"; -} -.fa-toggle-on:before { - content: "\f205"; -} -.fa-bicycle:before { - content: "\f206"; -} -.fa-bus:before { - content: "\f207"; -} -.fa-ioxhost:before { - content: "\f208"; -} -.fa-angellist:before { - content: "\f209"; -} -.fa-cc:before { - content: "\f20a"; -} -.fa-shekel:before, -.fa-sheqel:before, -.fa-ils:before { - content: "\f20b"; -} -.fa-meanpath:before { - content: "\f20c"; -} diff --git a/public/stylesheets/font-awesome-4.2.0/css/font-awesome.min.css b/public/stylesheets/font-awesome-4.2.0/css/font-awesome.min.css deleted file mode 100644 index ec53d4d..0000000 --- a/public/stylesheets/font-awesome-4.2.0/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/public/stylesheets/font-awesome-4.2.0/fonts/FontAwesome.otf b/public/stylesheets/font-awesome-4.2.0/fonts/FontAwesome.otf deleted file mode 100644 index 81c9ad9..0000000 Binary files a/public/stylesheets/font-awesome-4.2.0/fonts/FontAwesome.otf and /dev/null differ diff --git a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.eot b/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.eot deleted file mode 100644 index 84677bc..0000000 Binary files a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.svg b/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.svg deleted file mode 100644 index d907b25..0000000 --- a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,520 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.ttf b/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 96a3639..0000000 Binary files a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.woff b/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.woff deleted file mode 100644 index 628b6a5..0000000 Binary files a/public/stylesheets/font-awesome-4.2.0/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/public/stylesheets/reset.css b/public/stylesheets/reset.css deleted file mode 100644 index ad3a3cc..0000000 --- a/public/stylesheets/reset.css +++ /dev/null @@ -1,57 +0,0 @@ -/* http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) -*/ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} - -/* Box Sizing */ -html { - box-sizing: border-box; -} -*, *:before, *:after { - box-sizing: inherit; -} diff --git a/resume/email.png b/resume/email.png deleted file mode 100644 index 3f50cc3..0000000 Binary files a/resume/email.png and /dev/null differ diff --git a/resume/external-link.png b/resume/external-link.png new file mode 100644 index 0000000..cf25c68 Binary files /dev/null and b/resume/external-link.png differ diff --git a/resume/externalLink.png b/resume/externalLink.png deleted file mode 100644 index cf25c68..0000000 Binary files a/resume/externalLink.png and /dev/null differ diff --git a/resume/git.png b/resume/git.png deleted file mode 100644 index 96c2653..0000000 Binary files a/resume/git.png and /dev/null differ diff --git a/resume/gitlab.png b/resume/gitlab.png new file mode 100644 index 0000000..0d8b975 Binary files /dev/null and b/resume/gitlab.png differ diff --git a/resume/missfont.log b/resume/missfont.log deleted file mode 100644 index 45e2b6b..0000000 --- a/resume/missfont.log +++ /dev/null @@ -1,4 +0,0 @@ -mktextfm pagk8t -mktextfm pagk8t -mktextfm pagk8t -mktextfm pagk8t diff --git a/resume/resume.cls b/resume/resume.cls deleted file mode 100644 index e9fc2e6..0000000 --- a/resume/resume.cls +++ /dev/null @@ -1,101 +0,0 @@ -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{joris-cv}[2015/11/27 Joris CV class] -\LoadClass[10pt]{article} - -\RequirePackage[hmargin=3cm,tmargin=2cm,bmargin=3.5cm,footskip=2cm]{geometry} - -\RequirePackage[utf8]{inputenc} -\RequirePackage[T1]{fontenc} -\RequirePackage{fp,etoolbox,marvosym,bookman,titlesec,hyperref,tabularx,graphicx,fancyhdr,changepage,lastpage,ulem} -\RequirePackage[dvipsnames]{xcolor} -\RequirePackage[inline]{enumitem} -\RequirePackage{xifthen} - -\setlength{\parindent}{0pt} -\color[HTML]{303030} % Default foreground color -\definecolor{link}{HTML}{505070} -\hypersetup{colorlinks,breaklinks,urlcolor=link,linkcolor=link} -\setlength{\tabcolsep}{0pt} - -\pagestyle{fancy} -\lhead{} -\chead{} -\rhead{} -\renewcommand{\headrulewidth}{0pt} -\cfoot{\thepage\ / \pageref{LastPage}} - -\newcommand{\header}[5] { - \begin{minipage}[t]{0.65\textwidth} - \centering - {\Huge #1} \\ - \vspace{0.6em} - {\Large #2} \\ - \end{minipage} - \begin{minipage}[t]{0.35\textwidth} - \begin{flushright} - \vspace{-1.3em} - \personal{#3}{#4}{#5} - \end{flushright} - \end{minipage} - \vspace{1em} -} - -\newcommand{\personal}[3] { - \begin{tabular}{p{15pt}l} - \iconLink{externalLink.png}{#1}{#1} - \iconLink{git.png}{#2#3}{#3} - \end{tabular} -} - -\newcommand{\iconLink}[3] { - \includegraphics[width=8px]{#1} & \href{#2}{\sf\small#3} \vspace{0.3em} \\ -} - -\titleformat{\section} - {\LARGE\scshape\raggedright\color{brown}} % format - {} % label - {0em} % sep - {} % before code - [\titlerule\vspace{1em}] % after - -\titleformat - {\subsection} % command - {\large\raggedright\bf} % format - {} % label - {0em} % sep - {} % before code - [\vspace{0.5em}] % after - -\newcommand{\position}[6] { - {\large\bf #1} \hspace{0.2em} {\color{gray}#2} \vspace{0.5em} - - {\color{OliveGreen}#3} \vspace{0.5em} - - \ifthenelse{\isempty{#4}}{}{#4 \vspace{1em}} - - \ifthenelse{\isempty{#5}}{}{#5 \vspace{1em}} - - \ifthenelse{\isempty{#6}}{}{#6 \vspace{1em}} - - \vspace{0.8em} -} - -\newenvironment{bullets} { - \vspace{-0.5em} - \begin{enumerate}[label=\color{brown}$\bullet$,leftmargin=0.5cm]\itemsep2pt -} { - \end{enumerate} - \vspace{-0.5em} -} - -\newenvironment{technos} { - \begin{enumerate*}[label={}] -} { - \end{enumerate*} -} - -\newcommand{\techno}[1] { - \hspace{-0.2cm} - {\color{gray}\uline{\textcolor{black}{#1}}} - \hspace{0.1cm} -} diff --git a/src/Conf.hs b/src/Conf.hs deleted file mode 100644 index cd00fd9..0000000 --- a/src/Conf.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Conf - ( getConf - , Conf(..) - ) where - -import Data.Text (Text) -import qualified Data.ConfigManager as Conf - -import Daemon.Frequency (Frequency) - -data Conf = Conf - { port :: Int - , git :: String - , generateResumes :: Frequency - } deriving (Read, Eq, Show) - -getConf :: FilePath -> IO (Either Text Conf) -getConf path = - (flip fmap) (Conf.readConfig path) (\configOrError -> do - conf <- configOrError - Conf <$> - Conf.lookup "port" conf <*> - Conf.lookup "git" conf <*> - Conf.lookup "generateResumes" conf - ) diff --git a/src/Daemon.hs b/src/Daemon.hs deleted file mode 100644 index 1351ad5..0000000 --- a/src/Daemon.hs +++ /dev/null @@ -1,18 +0,0 @@ -module Daemon - ( runDaemon - ) where - -import Control.Concurrent (threadDelay) -import Control.Monad (forever) - -import Daemon.Frequency - -runDaemon :: Frequency -> (() -> IO ()) -> IO () -runDaemon frequency process = - forever $ do - process () - threadDelay (sleepDelayMs frequency) - -sleepDelayMs :: Frequency -> Int -sleepDelayMs Hourly = 1000000 * 60 * 60 -sleepDelayMs Daily = (sleepDelayMs Hourly) * 24 diff --git a/src/Daemon/Frequency.hs b/src/Daemon/Frequency.hs deleted file mode 100644 index d989d7f..0000000 --- a/src/Daemon/Frequency.hs +++ /dev/null @@ -1,8 +0,0 @@ -module Daemon.Frequency - ( Frequency(..) - ) where - -data Frequency = - Hourly - | Daily - deriving (Eq, Read, Show) diff --git a/src/Date.hs b/src/Date.hs deleted file mode 100644 index e3c16e5..0000000 --- a/src/Date.hs +++ /dev/null @@ -1,17 +0,0 @@ -module Date - ( getCurrentDate - ) where - -import Data.Time.Clock -import Data.Time.Calendar -import Data.Time.LocalTime - -import Model.Date - -getCurrentDate :: IO Date -getCurrentDate = do - now <- getCurrentTime - timezone <- getCurrentTimeZone - let zoneNow = utcToLocalTime timezone now - let (y, m, _) = toGregorian $ localDay zoneNow - return (Date m (fromIntegral y)) diff --git a/src/Design/Color.hs b/src/Design/Color.hs deleted file mode 100644 index bbe20c4..0000000 --- a/src/Design/Color.hs +++ /dev/null @@ -1,27 +0,0 @@ -module Design.Color where - -import qualified Clay.Color as C - -white :: C.Color -white = C.white - -red :: C.Color -red = C.rgb 170 57 57 - -orange :: C.Color -orange = C.rgb 182 119 25 - -green :: C.Color -green = C.rgb 0 93 0 - -blue :: C.Color -blue = C.rgb 79 182 187 - -black :: C.Color -black = C.rgb 0 0 0 - -link :: C.Color -link = blue C.-. 70 - -gray :: C.Color -gray = C.rgb 100 100 100 diff --git a/src/Design/Global.hs b/src/Design/Global.hs deleted file mode 100644 index 379d612..0000000 --- a/src/Design/Global.hs +++ /dev/null @@ -1,66 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Design.Global - ( compactDesign - ) where - -import qualified Data.Text.Lazy as T -import Data.Monoid ((<>)) - -import Clay - -import qualified Design.Color as Color -import qualified Design.Media as Media -import Design.Header (headerCss) -import Design.Resume (resumeCss) -import Design.Projects (projectsCss) -import Design.NotFound (notFoundCss) - -compactDesign :: T.Text -compactDesign = renderWith compact [] $ global - -global :: Css -global = - body ? do - color Color.black - marginBottom (px 40) - Media.mobile $ fontSize (px 16) - Media.tabletDesktop $ fontSize (px 18) - - h1 ? do - fontFamily [] [monospace] - fontWeight bold - color Color.red - - Media.mobile $ do - lineHeight (px 30) - fontSize (px 22) - marginBottom (px 20) - marginTop (px 35) - - Media.tablet $ do - lineHeight (px 40) - fontSize (px 27) - marginBottom (px 35) - marginTop (px 45) - - Media.desktop $ do - lineHeight (px 50) - fontSize (px 30) - marginBottom (px 40) - marginTop (px 55) - - a ? do - textDecoration none - color Color.link - transition "color" (sec 0.3) easeOut (sec 0) - focus & outline solid (px 0) Color.white - - (a # hover) <> (a # focus) ? do - textDecoration underline - color Color.blue - - headerCss - resumeCss - projectsCss - notFoundCss diff --git a/src/Design/Header.hs b/src/Design/Header.hs deleted file mode 100644 index d2bbace..0000000 --- a/src/Design/Header.hs +++ /dev/null @@ -1,56 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Design.Header - ( headerCss - ) where - -import Data.Monoid ((<>)) - -import Clay -import Clay.Display (displayTable) - -import qualified Design.Color as Color -import qualified Design.Media as Media - -headerCss :: Css -headerCss = do - ".header" ? do - backgroundColor Color.red - color Color.white - fontSize (px 28) - - ul ? do - width (pct 100) - display displayTable - "table-layout" -: "fixed" - - li ? do - display tableCell - - a ? do - display block - height (em 3) - lineHeight (em 3) - textDecoration none - padding (px 0) (px 0) (px 0) (px 0) - textAlign (alignSide sideCenter) - color Color.white - textTransform capitalize - transition "background-color" (ms 500) ease (sec 0) - - i ? marginRight (em 0.5) - - Media.mobile $ do - i ? display none - fontSize (em 0.6) - - Media.tablet $ fontSize (em 0.8) - - (a # hover <> a # focus <> a # ".currentHeader") ? do - backgroundColor Color.red - borderBottomStyle solid - borderBottomColor (Color.red +. 40) - - Media.mobile $ borderBottomWidth (px 6) - Media.tablet $ borderBottomWidth (px 8) - Media.desktop $ borderBottomWidth (px 10) diff --git a/src/Design/Media.hs b/src/Design/Media.hs deleted file mode 100644 index 77220ee..0000000 --- a/src/Design/Media.hs +++ /dev/null @@ -1,36 +0,0 @@ -module Design.Media - ( mobile - , mobileTablet - , tablet - , tabletDesktop - , desktop - ) where - -import Clay hiding (query) -import qualified Clay -import Clay.Stylesheet (Feature) -import qualified Clay.Media as Media - -mobile :: Css -> Css -mobile = query [Media.maxWidth mobileTabletLimit] - -mobileTablet :: Css -> Css -mobileTablet = query [Media.maxWidth tabletDesktopLimit] - -tablet :: Css -> Css -tablet = query [Media.minWidth mobileTabletLimit, Media.maxWidth tabletDesktopLimit] - -tabletDesktop :: Css -> Css -tabletDesktop = query [Media.minWidth mobileTabletLimit] - -desktop :: Css -> Css -desktop = query [Media.minWidth tabletDesktopLimit] - -query :: [Feature] -> Css -> Css -query = Clay.query Media.screen - -mobileTabletLimit :: Size LengthUnit -mobileTabletLimit = (px 520) - -tabletDesktopLimit :: Size LengthUnit -tabletDesktopLimit = (px 950) diff --git a/src/Design/Name.hs b/src/Design/Name.hs deleted file mode 100644 index 84c91fb..0000000 --- a/src/Design/Name.hs +++ /dev/null @@ -1,15 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Design.Name - ( nameCss - ) where - -import Clay - -nameCss :: Css -nameCss = do - fontWeight bold - letterSpacing (px 10) - margin (px 100) (px 0) (px 80) (px 0) - lineHeight (em 1.2) - fontSize (px 48) diff --git a/src/Design/NotFound.hs b/src/Design/NotFound.hs deleted file mode 100644 index ee8a0af..0000000 --- a/src/Design/NotFound.hs +++ /dev/null @@ -1,20 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Design.NotFound - ( notFoundCss - ) where - -import Clay - -notFoundCss :: Css -notFoundCss = - - ".notFoundPage" ? do - - h1 ? do - fontSize (px 40) - fontWeight bold - margin (px 20) (px 20) (px 20) (px 20) - - p ? - margin (px 20) (px 20) (px 20) (px 20) diff --git a/src/Design/Projects.hs b/src/Design/Projects.hs deleted file mode 100644 index 311b7f8..0000000 --- a/src/Design/Projects.hs +++ /dev/null @@ -1,51 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Design.Projects - ( projectsCss - ) where - -import Prelude hiding ((**)) - -import Data.Monoid ((<>)) - -import Clay -import qualified Clay.Flexbox as CF - -import qualified Design.Color as Color -import qualified Design.Media as Media -import qualified Design.Size as Size - -projectsCss :: Css -projectsCss = - ".project" ? do - margin (pct 0) (pct 10) (pct 0) (pct 10) - - h1 ? ".separator" ? color Color.black - - ".body" ? do - Size.indentation - - ".technologies" <> ".pageLink" ? do - i ? marginRight (em 0.5) - Size.lineHeight - marginBottom (px 10) - - ".technologies" ? do - Media.mobile $ fontSize (pct 90) - ul ? do - display flex - flexWrap CF.wrap - li ? do - backgroundColor Color.orange - color Color.white - borderRadius (px 2) (px 2) (px 2) (px 2) - margin (px 0) (px 10) (px 5) (px 0) - ":last-child:after" & marginRight (px 0) - - Media.desktop $ padding (px 0) (px 10) (px 0) (px 10) - Media.mobileTablet $ padding (px 0) (px 5) (px 0) (px 5) - - ".description" ? do - Size.lineHeight - marginTop (px 10) - Media.desktop $ width (pct 50) diff --git a/src/Design/Resume.hs b/src/Design/Resume.hs deleted file mode 100644 index d668987..0000000 --- a/src/Design/Resume.hs +++ /dev/null @@ -1,125 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Design.Resume - ( resumeCss - ) where - -import Prelude hiding ((**)) - -import Clay -import qualified Clay.Flexbox as CF - -import qualified Design.Color as Color -import qualified Design.Media as Media -import qualified Design.Size as Size - -resumeCss :: Css -resumeCss = - ".section" ? do - position relative - margin (pct 0) (pct 10) (pct 0) (pct 10) - - h1 ? textTransform capitalize - - ".identity" ? do - ".mail" <> ".git" ? do - Size.indentation - i ? marginRight (em 0.5) - - Media.mobile $ do - fontSize (px 14) - marginBottom (px 15) - - Media.tablet $ do - fontSize (px 18) - marginBottom (px 25) - - Media.desktop $ do - fontSize (px 20) - marginBottom (px 30) - - ".pdf" ? do - position absolute - right (px 0) - top (px 0) - color Color.red - transition "all" (ms 100) ease (sec 0) - i ? marginRight (px 0) - hover & transform (scale 1.2 1.2) - - Media.mobile $ do - lineHeight (px 30) - height (px 30) - fontSize (px 20) - - Media.tablet $ do - lineHeight (px 40) - height (px 40) - fontSize (px 30) - - Media.desktop $ do - lineHeight (px 50) - height (px 50) - fontSize (px 40) - - ".item" ? do - marginBottom (px 40) - Size.indentation - Media.mobile $ marginBottom (px 25) - - ".title" <> ".location" <> ".description" ? do - Size.lineHeight - - ".title" ? do - Media.desktop $ do - display flex - marginBottom (px 10) - - ".skills" & do - Size.tabletMarginBottom - - ".text" ? do - backgroundColor Color.orange - color Color.white - padding (px 0) (px 10) (px 0) (px 10) - sym borderRadius (px 2) - Media.mobileTablet $ marginBottom (px 10) - - ".date" ? do - fontStyle italic - Media.mobile $ fontSize (pct 90) - Media.desktop $ marginLeft (px 15) - - ".description" ? ".detail" ? - marginTop Size.listItemSep - - ".location" ? do - color Color.green - Media.mobile $ do - fontSize (pct 90) - marginBottom (px 10) - Size.tabletMarginBottom - - ".itemList" ? marginTop (px 5) - - ".bullets" |> ".detail" ? do - Media.mobile $ marginBottom Size.listItemSep - Size.tabletMarginBottom - - ".bullets" |> li ? do - Size.lineHeight - before & do - content (stringContent "•") - color Color.red - display inlineBlock - marginRight (px 10) - - ".technos" ? do - display flex - flexWrap CF.wrap - sym2 margin (px 5) (px 0) - - ".technos" |> ".techno" ? do - lineHeight normal - borderBottom solid (px 2) lightgray - margin (px 10) (px 15) (px 5) (px 0) diff --git a/src/Design/Size.hs b/src/Design/Size.hs deleted file mode 100644 index 8b323bf..0000000 --- a/src/Design/Size.hs +++ /dev/null @@ -1,28 +0,0 @@ -module Design.Size - ( indentation - , lineHeight - , listItemSep - , tabletMarginBottom - ) where - -import Clay hiding (lineHeight) -import qualified Clay - -import qualified Design.Media as Media - -indentation :: Css -indentation = do - Media.tablet $ marginLeft (px 10) - Media.desktop $ marginLeft (px 20) - -lineHeight :: Css -lineHeight = do - Media.mobile $ Clay.lineHeight (px 30) - Media.tablet $ Clay.lineHeight (px 35) - Media.desktop $ Clay.lineHeight (px 40) - -listItemSep :: Size LengthUnit -listItemSep = px 8 - -tabletMarginBottom :: Css -tabletMarginBottom = Media.tablet $ marginBottom (px 15) diff --git a/src/Main.hs b/src/Main.hs index fd1e076..d66e67b 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -1,67 +1,149 @@ {-# LANGUAGE OverloadedStrings #-} -module Main - ( main - ) where +import Control.Applicative (empty) +import qualified Data.Text as T +import Hakyll ((.&&.)) +import Hakyll (Compiler, Configuration (..), + Context (Context), + ContextField (ListField), Identifier, + Item, MonadMetadata, TmpFile (TmpFile)) +import qualified Hakyll as H +import qualified System.FilePath as FilePath (replaceExtension, + takeDirectory) +import qualified System.Process as Process (readCreateProcess, shell, + system) +import qualified Text.Pandoc as Pandoc -import Control.Concurrent (forkIO) -import Control.Monad.IO.Class (liftIO) +main :: IO () +main = H.hakyllWith configuration $ do -import Network.Wai.Middleware.Static + -- Static files + H.match "assets/**" $ do + H.route H.idRoute + H.compile H.copyFileCompiler -import Web.Scotty + H.match "css/**.hs" $ do + H.route . H.customRoute $ const "style.css" + H.compile $ do + H.unsafeCompiler (Process.readCreateProcess (Process.shell "cd css && runghc Style.hs") "") + >>= H.makeItem -import Data.Text.Lazy (isPrefixOf) -import Data.Yaml (decodeFileEither) + H.match "cv/**" $ H.version "html" $ do + H.route $ H.setExtension "html" + let context = + metadataListField `mappend` + H.defaultContext + H.compile $ H.pandocCompiler + >>= H.loadAndApplyTemplate "templates/resume.html" context + >>= H.relativizeUrls -import Model -import Model.Translation.Language + H.match "cv/**" $ H.version "tex" $ do + H.route $ H.setExtension "tex" + let context = + metadataListField `mappend` + H.defaultContext + H.compile $ H.getResourceBody + >>= H.readPandoc + >>= writeLaTeX + >>= H.loadAndApplyTemplate "templates/resume.tex" context -import View.NotFound (renderNotFound) -import View.Page (renderPage) -import View.Project (renderProjects) -import View.Resume (renderResume) + H.match "project/**" $ do + H.route $ H.setExtension "html" + let context = + metadataListField `mappend` + H.defaultContext + H.compile $ H.pandocCompiler + >>= H.loadAndApplyTemplate "templates/project.html" context + >>= H.relativizeUrls -import Design.Global (compactDesign) + H.match "index.html" $ do + H.route H.idRoute + let layoutContext = + H.constField "isResume" "true" `mappend` + H.defaultContext + let context = + H.listField "experience" H.defaultContext (H.loadAll ("cv/experience/*" .&&. H.hasVersion "html")) `mappend` + H.listField "education" H.defaultContext (H.loadAll ("cv/education/*" .&&. H.hasVersion "html")) `mappend` + H.listField "skills" H.defaultContext (H.loadAll ("cv/skill/*" .&&. H.hasVersion "html")) `mappend` + H.listField "hobbies" H.defaultContext (H.loadAll ("cv/hobby/*" .&&. H.hasVersion "html")) `mappend` + H.defaultContext + H.compile $ + H.getResourceBody + >>= H.applyAsTemplate context + >>= H.loadAndApplyTemplate "templates/layout.html" layoutContext + >>= H.relativizeUrls -import qualified Conf as Conf + H.match "projects.html" $ do + H.route H.idRoute + let layoutContext = + H.constField "isProjects" "true" `mappend` + H.defaultContext + let context = + H.listField "projects" H.defaultContext (H.loadAll "project/*") `mappend` + H.defaultContext + H.compile $ + H.getResourceBody + >>= H.applyAsTemplate context + >>= H.loadAndApplyTemplate "templates/layout.html" layoutContext + >>= H.relativizeUrls -import Date (getCurrentDate) + H.match "cv.tex" $ do + H.route $ H.setExtension ".pdf" + let context = + H.listField "experience" H.defaultContext (H.loadAll ("cv/experience/*" .&&. H.hasVersion "tex")) `mappend` + H.listField "education" H.defaultContext (H.loadAll ("cv/education/*" .&&. H.hasVersion "tex")) `mappend` + H.listField "skills" H.defaultContext (H.loadAll ("cv/skill/*" .&&. H.hasVersion "tex")) `mappend` + H.listField "hobbies" H.defaultContext (H.loadAll ("cv/hobby/*" .&&. H.hasVersion "tex")) `mappend` + H.defaultContext + H.compile $ + H.getResourceBody + >>= H.applyAsTemplate context + >>= H.readPandoc + >>= writeLaTeX + >>= H.loadAndApplyTemplate "templates/layout.tex" context + >>= generatePdf -import Daemon (runDaemon) + H.match "templates/**" $ + H.compile H.templateBodyCompiler -import Resume (generateResumes) +writeLaTeX :: Item Pandoc.Pandoc -> Compiler (Item String) +writeLaTeX = traverse $ \pandoc -> + case Pandoc.runPure (Pandoc.writeLaTeX Pandoc.def pandoc) of + Left err -> fail $ show err + Right x -> return (T.unpack x) -main :: IO () -main = do - modelOrError <- decodeFileEither "data.yaml" - confOrError <- Conf.getConf "application.conf" - case (modelOrError, confOrError) of - (Left modelError, _) -> - putStrLn $ "Model error: " ++ (show modelError) - (_, Left confError) -> - putStrLn $ "Configuration error: " ++ (show confError) - (Right model, Right conf) -> do - _ <- forkIO . runDaemon (Conf.generateResumes conf) $ \() -> generateResumes model conf - scotty (Conf.port conf) $ do - middleware $ staticPolicy (noDots >-> addBase "public") - get "/design" $ do - addHeader "Content-Type" "text/css" - text compactDesign - get "/" $ do - language <- getLanguage - currentDate <- liftIO getCurrentDate - html $ renderPage model (renderResume conf language currentDate model) - get "/projects" $ do - language <- getLanguage - html $ renderPage model (renderProjects conf language (projects model)) - notFound $ do - language <- getLanguage - html $ renderPage model (renderNotFound language) - -getLanguage :: ActionM Language -getLanguage = do - mbLang <- header "Accept-Language" - case mbLang of - Just lang | "fr" `isPrefixOf` lang -> return French - _ -> return English +configuration :: Configuration +configuration = H.defaultConfiguration + { destinationDirectory = "public" + } + +metadataListField :: Context a +metadataListField = Context $ \k _ i -> do + values <- getMetadataListField (H.itemIdentifier i) k + case values of + Just vs -> do + listItems <- mapM H.makeItem vs + return $ ListField (H.field "item" (return . H.itemBody)) listItems + Nothing -> + empty + +getMetadataListField :: MonadMetadata m => Identifier -> String -> m (Maybe [String]) +getMetadataListField identifier key = do + metadata <- H.getMetadata identifier + return $ H.lookupStringList key metadata + +generatePdf :: Item String -> Compiler (Item TmpFile) +generatePdf item = do + TmpFile texPath <- H.newTmpFile "file.tex" + let tmpDir = FilePath.takeDirectory texPath + pdfPath = FilePath.replaceExtension texPath "pdf" + + H.unsafeCompiler $ do + writeFile texPath $ H.itemBody item + _ <- Process.system $ unwords ["cd resume", "&&", "pdflatex", "-halt-on-error", + "-output-directory", "../" ++ tmpDir, "../" ++ texPath, ">/dev/null", "2>&1"] + _ <- Process.system $ unwords ["cd resume", "&&", "pdflatex", "-halt-on-error", + "-output-directory", "../" ++ tmpDir, "../" ++ texPath, ">/dev/null", "2>&1"] + return () + + H.makeItem $ TmpFile pdfPath diff --git a/src/Model.hs b/src/Model.hs deleted file mode 100644 index 846d98a..0000000 --- a/src/Model.hs +++ /dev/null @@ -1,25 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model where - -import GHC.Generics -import Data.Yaml - -import Model.Identity (Identity) -import Model.Job (Job) -import Model.Degree (Degree) -import Model.SkillType (SkillType) -import Model.Project (Project) -import Model.Translated (Translated) - -data Model = Model - { description :: String - , identity :: Identity - , jobs :: [Job] - , degrees :: [Degree] - , skillTypes :: [SkillType] - , interests :: [Translated] - , projects :: [Project] - } deriving (Show, Read, Eq, Generic) - -instance FromJSON Model diff --git a/src/Model/Company.hs b/src/Model/Company.hs deleted file mode 100644 index 3069488..0000000 --- a/src/Model/Company.hs +++ /dev/null @@ -1,13 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.Company where - -import GHC.Generics -import Data.Yaml - -data Company = Company - { name :: String - , location :: String - } deriving (Show, Read, Eq, Generic) - -instance FromJSON Company diff --git a/src/Model/Date.hs b/src/Model/Date.hs deleted file mode 100644 index 7edb6fb..0000000 --- a/src/Model/Date.hs +++ /dev/null @@ -1,30 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.Date where - -import GHC.Generics -import Data.Yaml - -data Date = Date - { month :: Int - , year :: Int - } deriving (Show, Read, Eq, Generic) - -yearAndMonthDiff :: Date -> Date -> (Int, Int) -yearAndMonthDiff d1 d2 = - let totalMonths = monthDiff d1 d2 - in (totalMonths `div` 12, totalMonths `mod` 12) - -monthDiff :: Date -> Date -> Int -monthDiff (Date m1 y1) (Date m2 y2) = - if y1 == y2 then - 1 + abs (m1 - m2) - else - let (minM, minY, maxM, maxY) = - if y1 < y2 then - (m1, y1, m2, y2) - else - (m2, y2, m1, y1) - in 12 * (maxY - minY - 1) + (13 - minM) + maxM - -instance FromJSON Date diff --git a/src/Model/Degree.hs b/src/Model/Degree.hs deleted file mode 100644 index 90feacc..0000000 --- a/src/Model/Degree.hs +++ /dev/null @@ -1,18 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.Degree where - -import GHC.Generics -import Data.Yaml - -import Model.School -import Model.Translated - -data Degree = Degree - { name :: Translated - , school :: School - , year :: Int - , topics :: [Translated] - } deriving (Show, Read, Eq, Generic) - -instance FromJSON Degree diff --git a/src/Model/Header.hs b/src/Model/Header.hs deleted file mode 100644 index 7581fc5..0000000 --- a/src/Model/Header.hs +++ /dev/null @@ -1,25 +0,0 @@ -module Model.Header - ( Header(..) - , allHeaders - , headerLink - , headerKey - ) where - -import Model.Translation.Key (Key) -import qualified Model.Translation.Key as K - -data Header = - Resume - | Projects - deriving (Enum, Bounded, Show, Eq) - -allHeaders :: [Header] -allHeaders = [minBound..] - -headerLink :: Header -> String -headerLink Resume = "/" -headerLink Projects = "/projects" - -headerKey :: Header -> Key -headerKey Resume = K.Resume -headerKey Projects = K.Projects diff --git a/src/Model/Identity.hs b/src/Model/Identity.hs deleted file mode 100644 index fb640fa..0000000 --- a/src/Model/Identity.hs +++ /dev/null @@ -1,14 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.Identity where - -import Data.Yaml -import GHC.Generics - -data Identity = Identity - { name :: String - , website :: String - , git :: String - } deriving (Show, Read, Eq, Generic) - -instance FromJSON Identity diff --git a/src/Model/Job.hs b/src/Model/Job.hs deleted file mode 100644 index f6865f4..0000000 --- a/src/Model/Job.hs +++ /dev/null @@ -1,22 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.Job where - -import Data.Yaml -import GHC.Generics - -import Model.Company -import Model.Date -import Model.Translated - -data Job = Job - { name :: Translated - , description :: Translated - , details :: Maybe [Translated] - , technos :: Maybe [String] - , company :: Company - , beginDate :: Date - , endDate :: Maybe Date - } deriving (Show, Read, Eq, Generic) - -instance FromJSON Job diff --git a/src/Model/Project.hs b/src/Model/Project.hs deleted file mode 100644 index 7825e60..0000000 --- a/src/Model/Project.hs +++ /dev/null @@ -1,18 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.Project where - -import GHC.Generics -import Data.Yaml - -import Model.Translated - -data Project = Project - { name :: String - , technologies :: [String] - , description :: Maybe Translated - , git :: String - , pageLink :: Maybe String - } deriving (Show, Read, Eq, Generic) - -instance FromJSON Project diff --git a/src/Model/School.hs b/src/Model/School.hs deleted file mode 100644 index cb10ed9..0000000 --- a/src/Model/School.hs +++ /dev/null @@ -1,13 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.School where - -import GHC.Generics -import Data.Yaml - -data School = School - { name :: String - , location :: Maybe String - } deriving (Show, Read, Eq, Generic) - -instance FromJSON School diff --git a/src/Model/SkillType.hs b/src/Model/SkillType.hs deleted file mode 100644 index 3e533b8..0000000 --- a/src/Model/SkillType.hs +++ /dev/null @@ -1,15 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.SkillType where - -import GHC.Generics -import Data.Yaml - -import Model.Translated - -data SkillType = SkillType - { name :: Translated - , skills :: [Translated] - } deriving (Show, Read, Eq, Generic) - -instance FromJSON SkillType diff --git a/src/Model/Translated.hs b/src/Model/Translated.hs deleted file mode 100644 index b92ae39..0000000 --- a/src/Model/Translated.hs +++ /dev/null @@ -1,19 +0,0 @@ -{-# LANGUAGE DeriveGeneric #-} - -module Model.Translated where - -import GHC.Generics -import Data.Yaml - -import Model.Translation.Language - -data Translated = Translated - { english :: String - , french :: String - } deriving (Show, Read, Eq, Generic) - -instance FromJSON Translated - -getTranslation :: Language -> Translated -> String -getTranslation English translated = english translated -getTranslation French translated = french translated diff --git a/src/Model/Translation/Key.hs b/src/Model/Translation/Key.hs deleted file mode 100644 index 43381fb..0000000 --- a/src/Model/Translation/Key.hs +++ /dev/null @@ -1,28 +0,0 @@ -module Model.Translation.Key - ( Key(..) - ) where - -data Key = - - Home - | Resume - | Projects - | Contact - - | Experience - | EducationalBackground - | Skills - | Interests - - | Since - | From - | To - | And - - | Month Int - | MonthText Int - | YearText Int - - | TryIt - - | PageNotFound diff --git a/src/Model/Translation/Language.hs b/src/Model/Translation/Language.hs deleted file mode 100644 index a8f5eb9..0000000 --- a/src/Model/Translation/Language.hs +++ /dev/null @@ -1,12 +0,0 @@ -module Model.Translation.Language - ( Language(..) - , languages - ) where - -data Language = - English - | French - deriving (Show, Read, Eq, Enum, Bounded) - -languages :: [Language] -languages = [minBound..] diff --git a/src/Model/Translation/Message.hs b/src/Model/Translation/Message.hs deleted file mode 100644 index c9e0fcb..0000000 --- a/src/Model/Translation/Message.hs +++ /dev/null @@ -1,90 +0,0 @@ -module Model.Translation.Message - ( getMessage - ) where - -import Model.Translation.Language -import Model.Translation.Key - -getMessage :: Key -> Language -> String - -getMessage Home English = "home" -getMessage Home French = "accueil" - -getMessage Resume English = "resume" -getMessage Resume French = "curriculum" - -getMessage Projects English = "projects" -getMessage Projects French = "projets" - -getMessage Contact English = "contact" -getMessage Contact French = "contact" - -getMessage Experience English = "experience" -getMessage Experience French = "expérience" - -getMessage EducationalBackground English = "educational background" -getMessage EducationalBackground French = "études" - -getMessage Skills English = "skills" -getMessage Skills French = "compétences" - -getMessage Interests English = "interests" -getMessage Interests French = "intérêts" - -getMessage Since English = "since" -getMessage Since French = "depuis" - -getMessage From English = "from" -getMessage From French = "de" - -getMessage To English = "to" -getMessage To French = "à" - -getMessage And English = "and" -getMessage And French = "et" - -getMessage (Month m) English = - case m of - 1 -> "january" - 2 -> "february" - 3 -> "march" - 4 -> "april" - 5 -> "may" - 6 -> "june" - 7 -> "july" - 8 -> "august" - 9 -> "september" - 10 -> "october" - 11 -> "november" - 12 -> "december" - _ -> "" -getMessage (Month m) French = - case m of - 1 -> "janvier" - 2 -> "février" - 3 -> "mars" - 4 -> "avril" - 5 -> "mai" - 6 -> "juin" - 7 -> "juillet" - 8 -> "août" - 9 -> "septembre" - 10 -> "octoble" - 11 -> "novembre" - 12 -> "décembre" - _ -> "" - -getMessage (MonthText count) English = "month" ++ (plural count) -getMessage (MonthText _) French = "mois" - -getMessage (YearText count) English = "year" ++ (plural count) -getMessage (YearText count) French = "an" ++ (plural count) - -getMessage TryIt English = "Try it!" -getMessage TryIt French = "Voir" - -getMessage PageNotFound English = "Page not found." -getMessage PageNotFound French = "La page que vous recherchez n'est pas disponible." - -plural :: Int -> String -plural count = if count > 1 then "s" else "" diff --git a/src/PDF.hs b/src/PDF.hs deleted file mode 100644 index a002b38..0000000 --- a/src/PDF.hs +++ /dev/null @@ -1,41 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module PDF - ( generatePDFAt - ) where - -import Control.Exception (SomeException, try) -import System.Directory (copyFile, createDirectoryIfMissing) -import System.FilePath (takeDirectory) -import System.IO (hClose) -import System.IO.Temp (withTempFile) -import qualified System.Process as Process (callCommand) -import Text.LaTeX (LaTeX, renderFile) - -generatePDFAt :: FilePath -> LaTeX -> IO () -generatePDFAt path latex = do - (basePath, tmpPath) <- generatePDF latex - createDirectoryIfMissing True (takeDirectory path) - copyFile tmpPath path - Process.callCommand ("rm " ++ basePath ++ "*") - -generatePDF :: LaTeX -> IO (FilePath, FilePath) -generatePDF latex = - withTempFile "/tmp" "latex" $ \filePath handle -> do - hClose handle - renderFile filePath latex - renderFile "/home/joris/resume.tex" latex - pdfCommand filePath - pdfCommand filePath - return (filePath, filePath ++ ".pdf") - -pdfCommand :: String -> IO () -pdfCommand path = do - let command = "cd resume && pdflatex --output-directory /tmp " ++ path ++ " >/dev/null" - result <- try $ Process.callCommand command :: IO (Either SomeException ()) - case result of - Left err -> do - putStrLn "Error generating PDF:" - putStrLn (show err) - Right _ -> - return () diff --git a/src/Resume.hs b/src/Resume.hs deleted file mode 100644 index 9b691c6..0000000 --- a/src/Resume.hs +++ /dev/null @@ -1,34 +0,0 @@ -module Resume - ( generateResumes - , resumePath - ) where - -import Conf (Conf) - -import Model -import Model.Date (Date) -import Model.Identity (Identity(name)) -import Model.Translation.Language -import Model.Translation.Message (getMessage) -import qualified Model.Translation.Key as K - -import View.LaTeX.Resume (resumeLaTeX) - -import Date (getCurrentDate) - -import PDF (generatePDFAt) - -generateResumes :: Model -> Conf -> IO () -generateResumes model conf = do - currentDate <- getCurrentDate - mapM_ (generateResume model currentDate conf) languages - -generateResume :: Model -> Date -> Conf -> Language -> IO () -generateResume model date conf language = - let path = "public/" ++ (resumePath model language) - resume = resumeLaTeX conf language date model - in generatePDFAt path resume - -resumePath :: Model -> Language -> FilePath -resumePath model language = - "resumes/" ++ (getMessage K.Resume language) ++ " " ++ (name . identity $ model) ++ ".pdf" diff --git a/src/Utils/String.hs b/src/Utils/String.hs deleted file mode 100644 index 44cdf03..0000000 --- a/src/Utils/String.hs +++ /dev/null @@ -1,21 +0,0 @@ -module Utils.String - ( capitalizeWords - , capitalizeFirstWord - , capitalizeWord - ) where - -import Data.Char - -capitalizeWords :: String -> String -capitalizeWords = unwords . map capitalizeWord . words - -capitalizeFirstWord :: String -> String -capitalizeFirstWord = unwords . mapFirst capitalizeWord . words - -capitalizeWord :: String -> String -capitalizeWord [] = [] -capitalizeWord (x:xs) = toUpper x : map toLower xs - -mapFirst :: (a -> a) -> [a] -> [a] -mapFirst _ [] = [] -mapFirst f (x:xs) = f x : xs diff --git a/src/View/Git.hs b/src/View/Git.hs deleted file mode 100644 index abf5226..0000000 --- a/src/View/Git.hs +++ /dev/null @@ -1,37 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.Git - ( renderGit - , renderGitIcon - ) where - -import Data.String (fromString) - -import Text.Blaze.Html -import Text.Blaze.Html5.Attributes -import qualified Text.Blaze.Html5 as H - -import Conf (Conf) -import qualified Conf as Conf - -import View.Icon (renderIcon) - -renderGit :: Conf -> String -> Html -renderGit conf ref = - H.div - ! class_ "git" - $ H.a - ! href (fromString $ gitLink conf ref) - $ do - renderIcon "git-square" - fromString ref - -renderGitIcon :: Conf -> String -> Html -renderGitIcon conf ref = - H.a - ! class_ "git" - ! href (fromString $ gitLink conf ref) - $ renderIcon "git-square" - -gitLink :: Conf -> String -> String -gitLink conf ref = (Conf.git conf) ++ ref diff --git a/src/View/Header.hs b/src/View/Header.hs deleted file mode 100644 index a29b9a3..0000000 --- a/src/View/Header.hs +++ /dev/null @@ -1,42 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.Header - ( renderHeader - ) where - -import Control.Monad (forM_) - -import Data.String (fromString) - -import Text.Blaze.Html -import Text.Blaze.Html5 -import Text.Blaze.Html5.Attributes -import qualified Text.Blaze.Html5 as H - -import Model.Header -import Model.Translation.Language -import Model.Translation.Message - -renderHeader :: Language -> Maybe Header -> Html -renderHeader language mbCurrentHeader = - H.div ! class_ "header" $ - ul $ - forM_ allHeaders (headerItem language mbCurrentHeader) - -headerItem :: Language -> Maybe Header -> Header -> Html -headerItem language mbCurrentHeader pageHeader = - li $ a - ! class_ (fromString $ (headerClass pageHeader) ++ " " ++ (if mbCurrentHeader == Just pageHeader then "currentHeader" else "")) - ! href (fromString . headerLink $ pageHeader) $ do - i ! class_ (fromString $ "fa fa-lg " ++ (headerIcon pageHeader)) $ "" - H.span - ! class_ "text" - $ fromString (getMessage (headerKey pageHeader) language) - -headerClass :: Header -> String -headerClass Resume = "resume" -headerClass Projects = "projects" - -headerIcon :: Header -> String -headerIcon Resume = "fa-user" -headerIcon Projects = "fa-flask" diff --git a/src/View/Icon.hs b/src/View/Icon.hs deleted file mode 100644 index 67db0a9..0000000 --- a/src/View/Icon.hs +++ /dev/null @@ -1,17 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.Icon - ( renderIcon - ) where - -import Data.String (fromString) - -import Text.Blaze.Html -import Text.Blaze.Html5 -import Text.Blaze.Html5.Attributes - -renderIcon :: String -> Html -renderIcon iconName = - i - ! class_ (fromString $ "fa fa-fw fa-" ++ iconName) - $ "" diff --git a/src/View/Interval.hs b/src/View/Interval.hs deleted file mode 100644 index 05cb62c..0000000 --- a/src/View/Interval.hs +++ /dev/null @@ -1,39 +0,0 @@ -module View.Interval - ( renderDurationAndInterval - , renderYearInterval - , renderDuration - ) where - -import Data.Maybe (fromMaybe) - -import Model.Date -import Model.Translation.Language -import qualified Model.Translation.Key as K -import Model.Translation.Message - -renderDurationAndInterval :: Language -> Date -> Date -> Maybe Date -> String -renderDurationAndInterval language currentDate beginDate mbEndDate = - let duration = renderDuration language beginDate (fromMaybe currentDate mbEndDate) - interval = renderYearInterval language beginDate mbEndDate - in duration ++ ", " ++ interval - -renderDuration :: Language -> Date -> Date -> String -renderDuration language d1 d2 = - let (years, months) = yearAndMonthDiff d1 d2 - renderYears = (show years) ++ " " ++ (getMessage (K.YearText years) language) - renderMonths = (show months) ++ " " ++ (getMessage (K.MonthText months) language) - spaceAnd = " " ++ (getMessage K.And language) ++ " " - in if years > 0 then - renderYears ++ (if months > 0 then spaceAnd ++ renderMonths else "") - else - renderMonths - -renderYearInterval :: Language -> Date -> (Maybe Date) -> String -renderYearInterval language beginDate Nothing = - (getMessage K.Since language) ++ " " ++ (show . year $ beginDate) -renderYearInterval language beginDate (Just endDate) = - let beginYear = year beginDate - endYear = year endDate - in if beginYear == endYear - then show beginYear - else (show beginYear) ++ " " ++ (getMessage K.To language) ++ " " ++ (show endYear) diff --git a/src/View/LaTeX/Resume.hs b/src/View/LaTeX/Resume.hs deleted file mode 100644 index 6ec717f..0000000 --- a/src/View/LaTeX/Resume.hs +++ /dev/null @@ -1,148 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.LaTeX.Resume - ( resumeLaTeX - ) where - -import Text.LaTeX -import Text.LaTeX.Base.Syntax (LaTeX (TeXComm), TeXArg (FixArg)) - -import Data.Maybe (fromMaybe, listToMaybe) - -import Conf (Conf) -import qualified Conf as Conf - -import Model (Model) -import qualified Model as M -import qualified Model.Company as C -import Model.Date (Date) -import Model.Degree (Degree) -import qualified Model.Degree as D -import Model.Identity (Identity) -import qualified Model.Identity as I -import Model.Job (Job) -import qualified Model.Job as J -import qualified Model.School as S -import Model.SkillType (SkillType) -import qualified Model.SkillType as ST - -import Model.Translated -import Model.Translation.Key (Key) -import qualified Model.Translation.Key as K -import Model.Translation.Language -import Model.Translation.Message - -import View.Interval (renderDurationAndInterval) - -import Utils.String - -resumeLaTeX :: Conf -> Language -> Date -> Model -> LaTeX -resumeLaTeX conf language currentDate model = - preamble - <> document (body conf language currentDate model) - -preamble :: LaTeX -preamble = documentclass [] "resume" - -body :: Conf -> Language -> Date -> Model -> LaTeX -body conf language currentDate model = - identityLaTeX conf language (M.identity model) (M.jobs model) - <> jobsLaTeX language currentDate (M.jobs model) - <> degreesLaTeX language (M.degrees model) - <> skillTypesLaTeX language (M.skillTypes model) - <> interestsLaTeX language (M.interests model) - -identityLaTeX :: Conf -> Language -> Identity -> [Job] -> LaTeX -identityLaTeX conf language identity jobs = - TeXComm "header" - [ FixArg (fromString $ I.name identity) - , FixArg (fromString . fromMaybe "" . (fmap (getTranslation language . J.name)) . listToMaybe $ jobs) - , FixArg (fromString $ I.website identity) - , FixArg (fromString $ Conf.git conf) - , FixArg (fromString $ I.git identity) - ] - -jobsLaTeX :: Language -> Date -> [Job] -> LaTeX -jobsLaTeX language currentDate jobs = - translatedSection K.Experience language - <> mconcat (map (jobLaTeX language currentDate) jobs) - -jobLaTeX :: Language -> Date -> Job -> LaTeX -jobLaTeX language currentDate job = - customCommand "position" - [ fromString . getTranslation language $ J.name job - , fromString $ renderDurationAndInterval language currentDate (J.beginDate job) (J.endDate job) - , fromString $ ((C.name . J.company) job) ++ ", " ++ ((C.location . J.company) job) - , (fromString . getTranslation language . J.description $ job) - , case J.details job of - Just details@(_:_) -> translatedBullets language details - _ -> mempty - , case J.technos job of - Just ts -> technos ts - _ -> mempty - ] - -degreesLaTeX :: Language -> [Degree] -> LaTeX -degreesLaTeX language degrees = - translatedSection K.EducationalBackground language - <> mconcat (map (degreeLaTeX language) degrees) - -degreeLaTeX :: Language -> Degree -> LaTeX -degreeLaTeX language degree = - customCommand "position" - [ fromString . getTranslation language $ D.name degree - , fromString . show . D.year $ degree - , fromString $ S.name school ++ (fromMaybe "" (((++) ", ") <$> S.location school)) - , mempty - , translatedBullets language $ D.topics degree - , mempty - ] - where school = D.school degree - -skillTypesLaTeX :: Language -> [SkillType] -> LaTeX -skillTypesLaTeX language skillTypes = - translatedSection K.Skills language - <> (mconcat . map (skillTypeLaTeX language) $ skillTypes) - -skillTypeLaTeX :: Language -> SkillType -> LaTeX -skillTypeLaTeX language skillType = - subsection (fromString . capitalizeFirstWord . getTranslation language . ST.name $ skillType) - <> translatedBullets language (ST.skills skillType) - -interestsLaTeX :: Language -> [Translated] -> LaTeX -interestsLaTeX language interests = - translatedSection K.Interests language - <> translatedBullets language interests - -translatedBullets :: Language -> [Translated] -> LaTeX -translatedBullets language = itemsEnv "bullets" . map (getTranslation language) - -itemsEnv :: String -> [String] -> LaTeX -itemsEnv name items = - environment name . mconcat . concat . map getItem $ items - where getItem i = - [ item Nothing - , fromString . capitalizeFirstWord $ i - ] - -technos :: [String] -> LaTeX -technos names = - environment "technos" . mconcat . concat . map getItem $ names - where getItem name = - [ item Nothing - , TeXComm "techno" [ FixArg (fromString name) ] - ] - -translatedSection :: Key -> Language -> LaTeX -translatedSection key language = - section (fromString . capitalizeWords $ getMessage key language) - -customCommand :: String -> [LaTeX] -> LaTeX -customCommand commandName commandParameters = - TeXComm commandName (map FixArg commandParameters) - -environment :: String -> LaTeX -> LaTeX -environment name inside = - (TeXComm "begin" [ FixArg (fromString name) ]) - <> inside - <> (TeXComm "end" [ FixArg (fromString name) ]) diff --git a/src/View/NotFound.hs b/src/View/NotFound.hs deleted file mode 100644 index c16eb6c..0000000 --- a/src/View/NotFound.hs +++ /dev/null @@ -1,26 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.NotFound - ( renderNotFound - ) where - -import Data.String (fromString) - -import Text.Blaze.Html -import Text.Blaze.Html5 -import Text.Blaze.Html5.Attributes -import qualified Text.Blaze.Html5 as H - -import Model.Translation.Language -import qualified Model.Translation.Key as K -import Model.Translation.Message - -import View.Header (renderHeader) - -renderNotFound :: Language -> Html -renderNotFound language = - H.div $ do - renderHeader language Nothing - H.div ! class_ "notFoundPage" $ do - h1 "404" - p .fromString $ getMessage K.PageNotFound language diff --git a/src/View/Page.hs b/src/View/Page.hs deleted file mode 100644 index b7267e8..0000000 --- a/src/View/Page.hs +++ /dev/null @@ -1,33 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.Page - ( renderPage - ) where - -import Data.Text.Internal.Lazy -import Data.String (fromString) - -import Text.Blaze.Html -import Text.Blaze.Html5 -import Text.Blaze.Html5.Attributes -import qualified Text.Blaze.Html5 as H -import Text.Blaze.Html.Renderer.Text (renderHtml) - -import qualified Model as M -import qualified Model.Identity as I - -renderPage :: M.Model -> Html -> Text -renderPage model page = - renderHtml $ do - docTypeHtml $ do - H.head $ do - H.title $ fromString . I.name . M.identity $ model - meta ! charset "UTF-8" - meta ! name "viewport" ! content "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" - meta ! name "author" ! content (toValue $ I.name . M.identity $ model) - meta ! name "description" ! content (toValue $ M.description model) - link ! rel "stylesheet" ! type_ "text/css" ! href "/stylesheets/reset.css" - link ! rel "stylesheet" ! href "/stylesheets/font-awesome-4.2.0/css/font-awesome.min.css" - link ! rel "stylesheet" ! type_ "text/css" ! href "/design" - link ! rel "icon" ! type_ "image/png" ! href "/images/icon.png" - H.body page diff --git a/src/View/Project.hs b/src/View/Project.hs deleted file mode 100644 index a5aaf2c..0000000 --- a/src/View/Project.hs +++ /dev/null @@ -1,66 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.Project - ( renderProjects - ) where - -import Data.String (fromString) - -import Text.Blaze.Html -import Text.Blaze.Html5 -import Text.Blaze.Html5.Attributes -import qualified Text.Blaze.Html5 as H - -import Conf (Conf) - -import Model.Header (Header(Projects)) -import qualified Model.Project as P -import Model.Translated -import Model.Translation.Language - -import View.Header (renderHeader) -import View.Git (renderGitIcon) - -renderProjects :: Conf -> Language -> [P.Project] -> Html -renderProjects conf language projects = - H.div $ do - renderHeader language (Just Projects) - H.div ! class_ "projectsPage" $ - mapM_ (renderProject conf language) projects - -renderProject :: Conf -> Language -> P.Project -> Html -renderProject conf language project = - H.div ! class_ "project" $ do - renderTitle conf project - H.div ! class_ "body" $ do - renderTechnologies (P.technologies project) - case P.pageLink project of - Just pageLink -> renderPageLink pageLink - Nothing -> fromString "" - case P.description project of - Just description -> renderDescription language description - Nothing -> H.div "" - -renderTitle :: Conf -> P.Project -> Html -renderTitle conf project = - h1 $ do - toHtml (P.name project) - H.span ! class_ "separator" $ fromString " − " - renderGitIcon conf (P.git project) - -renderTechnologies :: [String] -> Html -renderTechnologies technologies = - H.div ! class_ "technologies" $ do - ul $ mapM_ (H.li . fromString) technologies - -renderPageLink :: String -> Html -renderPageLink pageLink = - H.div ! class_ "pageLink" $ do - H.a - ! href (fromString pageLink) - $ toHtml pageLink - -renderDescription :: Language -> Translated -> Html -renderDescription language description = - H.div ! class_ "description" $ do - fromString . getTranslation language $ description diff --git a/src/View/Resume.hs b/src/View/Resume.hs deleted file mode 100644 index ffd5c8c..0000000 --- a/src/View/Resume.hs +++ /dev/null @@ -1,140 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module View.Resume - ( renderResume - ) where - -import Data.Maybe -import Data.String (fromString) - -import Text.Blaze.Html -import Text.Blaze.Html5 hiding (details) -import qualified Text.Blaze.Html5 as H -import Text.Blaze.Html5.Attributes - -import Conf (Conf) - -import qualified Model as M -import qualified Model.Company as C -import Model.Date -import qualified Model.Degree as D -import Model.Header (Header (Resume)) -import qualified Model.Identity as I -import qualified Model.Job as J -import qualified Model.School as S -import qualified Model.SkillType as ST -import Model.Translated -import Model.Translation.Key (Key) -import qualified Model.Translation.Key as K -import Model.Translation.Language -import Model.Translation.Message - -import View.Git (renderGit) -import View.Header (renderHeader) -import View.Icon (renderIcon) -import View.Interval (renderDurationAndInterval) - -import Resume (resumePath) - -renderResume :: Conf -> Language -> Date -> M.Model -> Html -renderResume conf language currentDate model = - H.div $ do - renderHeader language (Just Resume) - H.div ! class_ "resumePage" $ do - renderIdentity conf language model - renderJobs language currentDate . M.jobs $ model - renderDegrees language . M.degrees $ model - renderSkillTypes language . M.skillTypes $ model - renderInterests language . M.interests $ model - -renderIdentity :: Conf -> Language -> M.Model -> Html -renderIdentity conf language model = - let identity = M.identity model - in H.div ! class_ "section" $ do - H.div ! class_ "identity" $ do - h1 (fromString (I.name identity)) - renderGit conf (I.git identity) - a ! href (fromString $ resumePath model language) ! class_ "pdf" ! target "_blank" $ - renderIcon "print" - -renderJobs :: Language -> Date -> [J.Job] -> Html -renderJobs language currentDate jobs = - H.div ! class_ "section" $ do - sectionTitle K.Experience language - mapM_ (renderJob language currentDate) jobs - -renderJob :: Language -> Date -> J.Job -> Html -renderJob language currentDate job = - H.div ! class_ "item" $ do - - H.div ! class_ "title" $ do - H.div ! class_ "text" $ - fromString . getTranslation language . J.name $ job - H.div ! class_ "date" $ - fromString $ renderDurationAndInterval language currentDate (J.beginDate job) (J.endDate job) - - H.div ! class_ "location" $ do - let company = J.company job - companyName = C.name company - companyLocation = C.location company - fromString $ companyName ++ ", " ++ companyLocation - - H.div ! class_ "description" $ do - _ <- fromString . getTranslation language . J.description $ job - case J.details job of - Just details -> - ul ! class_ "bullets detail" $ - mapM_ (\detail -> li . fromString . getTranslation language $ detail) details - Nothing -> - fromString "" - renderTechnos $ fromMaybe [] (J.technos job) - -renderTechnos :: [String] -> Html -renderTechnos = (ul ! class_ "technos") . mapM_ ((li ! class_ "techno") . fromString) - -renderDegrees :: Language -> [D.Degree] -> Html -renderDegrees language degrees = - H.div ! class_ "section" $ do - sectionTitle K.EducationalBackground language - mapM_ (renderDegree language) degrees - -renderDegree :: Language -> D.Degree -> Html -renderDegree language degree = - H.div ! class_ "item" $ do - - H.div ! class_ "title" $ do - H.div ! class_ "text " $ - fromString . getTranslation language . D.name $ degree - H.div ! class_ "date" $ - fromString . show . D.year $ degree - - H.div ! class_ "location" $ - let school = D.school degree - location = fromMaybe "" $ fmap (", " ++ ) (S.location school) - in fromString $ (S.name school) ++ location - - ul ! class_ "bullets itemList" $ - mapM_ (\topic -> li . fromString . getTranslation language $ topic) (D.topics degree) - -renderSkillTypes :: Language -> [ST.SkillType] -> Html -renderSkillTypes language skillTypes = - H.div ! class_ "section" $ do - sectionTitle K.Skills language - mapM_ (renderSkillType language) skillTypes - -renderSkillType :: Language -> ST.SkillType -> Html -renderSkillType language skillType = - H.div ! class_ "item" $ do - H.div ! class_ "title skills" $ H.div ! class_ "text" $ - fromString . getTranslation language . ST.name $ skillType - ul ! class_ "bullets itemList" $ - mapM_ (\skill -> li . fromString . getTranslation language $ skill) (ST.skills skillType) - -renderInterests :: Language -> [Translated] -> Html -renderInterests language interests = - H.div ! class_ "section" $ do - sectionTitle K.Interests language - ul ! class_ "bullets" $ mapM_ (\interest -> li . fromString . getTranslation language $ interest) interests - -sectionTitle :: Key -> Language -> Html -sectionTitle key language = h1 . fromString $ getMessage key language diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..edf25f8 --- /dev/null +++ b/stack.yaml @@ -0,0 +1,5 @@ +resolver: lts-13.18 + +extra-deps: + - hakyll-4.12.5.1@sha256:d1948b265e6628bcb6875571212f9acefe23179c73ca4f87f417b290ff381ca6 + - lrucache-1.2.0.1@sha256:18fc3d7052012c7ab3cd395160f34b53c5e1ec5379cc45185baf35b90ffadc2e diff --git a/templates/icons/code.svg b/templates/icons/code.svg new file mode 100644 index 0000000..c4954b5 --- /dev/null +++ b/templates/icons/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/icons/external-link.svg b/templates/icons/external-link.svg new file mode 100644 index 0000000..6371124 --- /dev/null +++ b/templates/icons/external-link.svg @@ -0,0 +1 @@ + diff --git a/templates/icons/gitlab.svg b/templates/icons/gitlab.svg new file mode 100644 index 0000000..85d54a1 --- /dev/null +++ b/templates/icons/gitlab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/icons/printer.svg b/templates/icons/printer.svg new file mode 100644 index 0000000..8a9a7ac --- /dev/null +++ b/templates/icons/printer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/icons/user.svg b/templates/icons/user.svg new file mode 100644 index 0000000..7bb5f29 --- /dev/null +++ b/templates/icons/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/templates/layout.html b/templates/layout.html new file mode 100644 index 0000000..18a3817 --- /dev/null +++ b/templates/layout.html @@ -0,0 +1,34 @@ + + + + + + + + + Joris Guyonvarch + + + + + + +
+ +
$partial("templates/icons/user.svg")$
+ CV +
+ + +
$partial("templates/icons/code.svg")$
+ Projets +
+
+ +
+ $body$ +
+ + + + diff --git a/templates/layout.tex b/templates/layout.tex new file mode 100644 index 0000000..e49ea84 --- /dev/null +++ b/templates/layout.tex @@ -0,0 +1,93 @@ +\documentclass[a4paper, 11pt]{article} + +\usepackage[hmargin=2.5cm,tmargin=2cm,bmargin=3.5cm,footskip=2cm]{geometry} + +\usepackage{color} +\definecolor{darkblue}{RGB}{0,0,100} + +\usepackage[colorlinks=true, allcolors=darkblue, pdfborder={0 0 0}]{hyperref} + +\usepackage{titlesec} + +\usepackage{graphicx} + +\usepackage{parskip} +\setlength{\parindent}{0em} +\setlength{\parskip}{0.25cm} +\setcounter{secnumdepth}{-1} + +\usepackage[dvipsnames]{xcolor} +\usepackage[inline]{enumitem} +\setlist[itemize]{leftmargin=0.8cm,after=\vspace{0.1cm}} +\renewcommand{\labelitemi}{$$\color{brown}\bullet$$} + +% Other packages + +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +\usepackage{fp,etoolbox,marvosym,bookman,titlesec,hyperref,tabularx,graphicx,fancyhdr,changepage,lastpage,ulem} +\usepackage{xifthen} + +% Conf + +\setlength{\parindent}{0pt} +\color[HTML]{303030} % Default foreground color +\definecolor{link}{HTML}{505070} +\hypersetup{colorlinks,breaklinks,urlcolor=link,linkcolor=link} +\setlength{\tabcolsep}{0pt} + +\pagestyle{fancy} +\lhead{} +\chead{} +\rhead{} +\renewcommand{\headrulewidth}{0pt} +\cfoot{\thepage\ / \pageref{LastPage}} + +\titleformat + {\section} + {\LARGE\scshape\raggedright\color{brown}} % format + {} % label + {0cm} % sep + {\vspace{0.3cm}} % before + [\titlerule\vspace{0.2cm}] % after + +\titleformat + {\subsection} + {\large\raggedright\bf} % format + {} % label + {0cm} % sep + {\vspace{0.3cm}} % before + [\vspace{0.1cm}] % after + +% Commands + +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} + +\newcommand{\iconLink}[3] { + \includegraphics[width=8px]{#1} & \href{#2}{\sf\small#3} \\ +} + +% Doc + +\begin{document} + +\begin{minipage}[t]{0.6\textwidth} + \centering + {\Huge Joris Guyonvarch} \\ + \vspace{0.2cm} + {\Large Développeur} \\ +\end{minipage} +\begin{minipage}[t]{0.4\textwidth} + \begin{flushright} + \vspace{-1.3em} + \begin{tabular}{p{15pt}l} + \iconLink{external-link.png}{https://guyonvarch.me}{guyonvarch.me} + \iconLink{gitlab.png}{https://gitlab.com/guyonvarch}{guyonvarch} + \end{tabular} + \end{flushright} +\end{minipage} + +$body$ + +\end{document} diff --git a/templates/project.html b/templates/project.html new file mode 100644 index 0000000..4bcc386 --- /dev/null +++ b/templates/project.html @@ -0,0 +1,37 @@ +
  • + +

    $name$

    + +
    + + + $partial("templates/icons/gitlab.svg")$ + + $gitlab$ + +
    + +
    + $if(live)$ + + + $partial("templates/icons/external-link.svg")$ + + $live$ + + $endif$ +
    + +
    + $body$ +
    + + $if(skills)$ +
      + $for(skills)$ +
    • $item$
    • + $endfor$ +
    + $endif$ + +
  • diff --git a/templates/resume.html b/templates/resume.html new file mode 100644 index 0000000..e848025 --- /dev/null +++ b/templates/resume.html @@ -0,0 +1,28 @@ +
  • + + $if(name)$ +
    + $name$ +
    + $endif$ + + $if(location)$ +
    + $location$ + $if(time)$– $time$$endif$ +
    + $endif$ + +
    + $body$ +
    + + $if(skills)$ +
      + $for(skills)$ +
    • $item$
    • + $endfor$ +
    + $endif$ + +
  • diff --git a/templates/resume.tex b/templates/resume.tex new file mode 100644 index 0000000..678e20b --- /dev/null +++ b/templates/resume.tex @@ -0,0 +1,18 @@ +$if(name)$ + \subsection{$name$} +$endif$ + +{\color{OliveGreen} $if(location)$ $location$ $endif$ $if(time)$ – $time$ $endif$} + +$body$ + +$if(skills)$ + \begin{enumerate*}[label={}] + $for(skills)$ + \item{} + \hspace{-0.3cm} + {\color{gray}\uline{\textcolor{black}{$item$}}} + \hspace{0.2cm} + $endfor$ + \end{enumerate*} +$endif$ -- cgit v1.2.3