changeset 551:791cb4b91701

move things around add an improved demo script, add a systemd drop-in and harden the systemd configuration
author Louis Opter <louis@opter.org>
date Sun, 14 May 2017 13:29:30 -0700
parents c0b49dd420bf
children 384131f70406
files add_windows_support.patch while42_sf.patch
diffstat 2 files changed, 705 insertions(+), 640 deletions(-) [+]
line wrap: on
line diff
--- a/add_windows_support.patch	Sat Apr 29 23:52:02 2017 -0700
+++ b/add_windows_support.patch	Sun May 14 13:29:30 2017 -0700
@@ -1,5 +1,5 @@
 # HG changeset patch
-# Parent  1803cda7be2c37197f442deebb44b44ce44d8886
+# Parent  3eaedf3f30570024bdac00f3b6a784bed52d01f9
 lightsd: add windows support
 
 diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/while42_sf.patch	Sat Apr 29 23:52:02 2017 -0700
+++ b/while42_sf.patch	Sun May 14 13:29:30 2017 -0700
@@ -1,24 +1,716 @@
 # HG changeset patch
-# Parent  0689c022af3bedbaa433ceeb4bda7f64359c51de
+# Parent  dc2701ba73ff23c2273a684be729236c1ea57854
 slides: add slides for a small talk at while42 sf
 
-diff --git a/slides/fosdem_2017/CMakeLists.txt b/slides/2017-02-04_fosdem/CMakeLists.txt
-rename from slides/fosdem_2017/CMakeLists.txt
-rename to slides/2017-02-04_fosdem/CMakeLists.txt
+diff --git a/dist/lightsd.service b/dist/lightsd.service
+--- a/dist/lightsd.service
++++ b/dist/lightsd.service
+@@ -8,6 +8,14 @@
+ Group=lightsd
+ RuntimeDirectory=lightsd
+ Restart=on-failure
++ProtectSystem=full
++ProtectHome=true
++ProtectKernelTunables=yes
++ProtectControlGroups=yes
++ProtectKernelModules=yes
++RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
++# Debian Stretch and after:
++# RestrictNamespaces=yes
+ 
+ [Install]
+ WantedBy=multi-user.target
+diff --git a/examples/custom-exec-start.conf b/examples/custom-exec-start.conf
+new file mode 100644
+--- /dev/null
++++ b/examples/custom-exec-start.conf
+@@ -0,0 +1,3 @@
++[Service]
++ExecStart=
++ExecStart=/usr/bin/lightsd -t -v warning -s %t/lightsd/socket -c %t/lightsd/pipe -l :::56742
+diff --git a/slides/2017_fosdem b/slides/2017_fosdem
+new file mode 120000
+--- /dev/null
++++ b/slides/2017_fosdem
+@@ -0,0 +1,1 @@
++fosdem_2017
+\ No newline at end of file
+diff --git a/slides/2017_while-42/CMakeLists.txt b/slides/2017_while-42/CMakeLists.txt
+new file mode 100644
+--- /dev/null
++++ b/slides/2017_while-42/CMakeLists.txt
+@@ -0,0 +1,3 @@
++LIGHTSD_COPY_COMMON_LATEX()
++
++ADD_LATEX_DOCUMENT(while42.tex)
+diff --git a/slides/fosdem_2017/monolight-demo.sh b/slides/2017_while-42/monolight-demo.zsh
+copy from slides/fosdem_2017/monolight-demo.sh
+copy to slides/2017_while-42/monolight-demo.zsh
+--- a/slides/fosdem_2017/monolight-demo.sh
++++ b/slides/2017_while-42/monolight-demo.zsh
+@@ -1,20 +1,33 @@
+-#!/bin/sh
++#!/usr/bin/env zsh
++
++PY3_BIN="${$(command -v python3):?"Couldn't find python3"}"
++
++VIRTUALENVWRAPPER_PYTHON="${PY3_BIN}"
++. "$(command -v virtualenvwrapper.sh)"
+ 
+ check_process() {
+   local name=$1
+ 
+-  /bin/echo -n "checking that ${name} is running: "
++  printf "checking that %s is running: " "${name}"
+   pgrep ${name} 2>&1 >/dev/null && echo ok || { echo "not running"; exit 1; }
+ }
+ 
+-check_venv() {
++setup_venv() {
+   local name=$1
+ 
+-  /bin/echo -n "checking that the virtualenv ${name} is active: "
+-  echo ${VIRTUAL_ENV} | grep ${name} 2>&1 >/dev/null && echo ok || { echo nope; exit 1; }
++  [ "$(lsvirtualenv | grep -c "^${name}$")" -eq 1 ] || {
++    mkvirtualenv -qp "${PY3_BIN}" "${name}";
++    pip install -q \
++        ~/projs/lightsd/clients/python/lightsc \
++        ~/projs/lightsd/apps/monolight/;
++  }
++
++  [ "${name}" = "${VIRTUAL_ENV}" ] || { workon "${name}"; }
++
++  :
+ }
+ 
+-check_venv monolight
++setup_venv monolight
+ 
+ check_process serialoscd
+ 
+diff --git a/slides/2017_while-42/while42.tex b/slides/2017_while-42/while42.tex
+new file mode 100644
+--- /dev/null
++++ b/slides/2017_while-42/while42.tex
+@@ -0,0 +1,392 @@
++\documentclass{lgtdslides}
++
++\usepackage{tikz}
++\usepackage{tikzsymbols}
++\usepackage[francais]{babel}
++
++\usepackage{lgtdfigs}
++
++\title{S'amuser avec la lumière}
++\subtitle{\textit{Avec des ampoules LIFX et un Monome 128}}
++\date{While 42 SF : side projects}
++\author{Louis Opter <louis@opter.org>}
++
++\tikzset{arrow/.style={->, >=stealth,ultra thick,rounded corners}}
++
++\begin{document}
++
++\begin{frame}\titlepage\end{frame}
++
++\section{Intro}
++
++\begin{frame}{\LARGE{\texttt{\$ whoami}}}
++Bonjour, moi c'est Louis (Opter) et :\vspace{1em}
++\begin{itemize}
++\item je bosse sur SF depuis ~2012 (docker/Uber) ;
++\item j'y connais rien en hardware ;
++\item donc j'ai acheté des trucs tous faits « simples » ;
++\item et voici une démo de ce que j'ai fait.
++\end{itemize}
++\end{frame}
++
++\section{Démo}
++
++\begin{frame}{Sous vos yeux}
++\begin{center}
++\begin{tikzpicture}
++\pic (0, 0) {monolightarch};
++\end{tikzpicture}
++\end{center}
++\end{frame}
++
++
++\begin{frame}{Effet sablier/alerte}
++\only<1>{Une autre idée que j'aimerais implémenter\ldots}
++\begin{center}
++\begin{tikzpicture}[overlay,scale=1.2]
++\onslide<2->{%
++\pic (0, 0) {monome={scale 1.2}};
++
++\coordinate (NW) at (-4, 1.75);
++\coordinate (caption) at ($(NW) + (-1.155,0.65)$);
++
++\foreach \x in {-4,-3.5,...,-1}
++\fill[mbutton] (\x, -1.75) rectangle +(0.36, -0.36); % function row
++
++\node[rectangle] (b117) at (-1.32,-1.93) {};
++\node[rectangle] (b118) at (-0.82,-1.93) {};
++}
++\onslide<2,4->{%
++% targets toggles:
++\fill[mbutton] (-4, 1.75) rectangle +(0.36, -0.36);
++\foreach \x in {-2,0,...,3.5}
++\fill[mbuttvlow] (\x, 1.75) rectangle +(0.36, -0.36);
++
++% h:
++\fill[mbutthigh] (-4, -0.25) rectangle +(0.36, -0.36);
++\fill[mbutton] (-4, -0.75) rectangle +(0.36, -0.36);
++\fill[mbutton] (-4, -1.25) rectangle +(0.36, -0.36);
++
++% s:
++\fill[mbuttmed] (-3.5, -0.75) rectangle +(0.36, -0.36);
++\fill[mbutton] (-3.5, -1.25) rectangle +(0.36, -0.36);
++
++% b:
++\foreach \y in {1.25,0.75,...,-1.25}
++\fill[mbutton] (-3, \y) rectangle +(0.36, -0.36);
++
++% k:
++\fill[mbutthigh] (-2.5, -1.25) rectangle +(0.36, -0.36);
++}
++\onslide<2>{%
++\draw (caption) node[right] {Ajoutons deux nouvelles fonctions :};
++
++\node (timer) [below=0.5cm of b117] {timer};
++\node (alert) [below=0.9cm of b118] {alert};
++\draw[arrow] (timer) -- (b117);
++\draw[arrow] (alert) -- (b118);
++}
++\onslide<3>{%
++\draw (caption) node[right] {Sélection du compte à rebours:};
++\node[below right] at ($(caption.south) + (0, -0.09)$) {\footnotesize{(1 bouton allumé = 1 unité de temps)}};
++
++% partially lit grid:
++\foreach \x in {-4,-3.5,...,-0.5}
++\foreach \y in {1.75,1.25,...,-1.25}
++\fill[mbutton] (\x, \y) rectangle +(0.36, -0.36);
++\foreach \y in {1.75,1.25,...,-0.5}
++\fill[mbutton] (0, \y) rectangle +(0.36, -0.36);
++
++\foreach \x in {-4,-3.5,...,3.5}
++\fill[mbuttoff] (\x, -1.75) rectangle +(0.36, -0.36); % blank function row
++
++\fill[mbutton] (-1.5, -1.75) rectangle +(0.36, -0.36); % time button
++\fill[mbutton] (0, -1.75) rectangle +(0.36, -0.36); % dec time scale
++\fill[mbutton] (0.5, -1.75) rectangle +(0.36, -0.36); % inc time scale
++
++%\node[rectangle] (b117) at (-1.32,-1.93) {};
++%\node[rectangle] (b118) at (-0.82,-1.93) {};
++%\node[rectangle] (b119) at (-0.32,-1.93) {};
++\node[rectangle] (b120) at (0.18,-1.93) {};
++\node[rectangle] (b121) at (0.68,-1.93) {};
++\node[rectangle] (b122) at (1.18,-1.93) {};
++\draw[ultra thick,decorate,decoration={name=brace,mirror}]
++  ($(b120.south west) + (-0.1,-0.35)$) -- ($(b121.south east) + (0.1,-0.35)$);
++\node (timectl) [below=0.5cm of b121] {déc/inc de l'unité de temps};
++}
++\onslide<4>{%
++\draw (caption) node[right] {Sélection de la cible et de la fonction (alert):};
++
++\node (alert) [below=0.5cm of b118] {alert};
++\draw[arrow] (alert) -- (b118);
++
++\node[rectangle,opacity=0] (b0) at (-3.82,1.57) {B};
++\node[rectangle,opacity=0] (b4) at (-1.82,1.57) {B};
++\node[rectangle,opacity=0] (b8) at (0.18,1.57) {B};
++\node[rectangle,opacity=0] (b12) at (2.18,1.57) {B};
++
++\coordinate (legend) at ($(caption) + (0.7, -0.15)$);
++\coordinate (upturn) at ($(legend) + (0,-1.26)$);
++\draw[arrow,<-] (b0.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
++\draw[arrow,<-] (b4.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
++\draw[arrow,<-] (b8.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
++\draw[arrow,<-] (b12.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
++}
++\onslide<5>{%
++\fill[mbutton] (-3.5, 1.75) rectangle +(0.36, -0.36);
++
++\node[rectangle] (b1) at (-3.32,1.57) {};
++\node (feedback) [above right=0.5cm of b1] {Voyant d'activité du sablier};
++\draw[arrow] (feedback) -| (b1);
++}
++\end{tikzpicture}
++\end{center}
++\end{frame}
++
++\section{À propos du projet}
++
++\begin{frame}{Motivations}
++À l'origine du projet :
++\vspace{1em}
++\begin{itemize}
++\item Délais de découverte/utilisation, fiabilité ;
++\item Sécurité, vie privée, (dé-)centralisation ;
++\item Obsolescence programmée (ou non) ;
++\item « Accessibilité » ;
++\item Insatisfaction professionnelle.
++\end{itemize}
++\end{frame}
++
++\begin{frame}{Résultats}
++\only<1,3>{%
++Quelques découvertes et confirmations :
++\vspace{1em}
++\begin{itemize}
++\item Les blobs binaires c'est de la merde ;
++\item L'IoT s'améliore mais c'est pas encore ça ;
++\item Spectre de problèmes vraiment intéressant ;
++\item Une méthode d'apprentissage de premier ordre.
++\end{itemize}
++}
++\only<2>{%
++\emph{\leavevmode\usebeamertemplate***{itemize item} Spectre de problèmes vraiment intéressant :}
++\vspace{1em}
++\begin{center}
++\setlength{\tabcolsep}{15pt}
++\begin{tabular}{ccc}
++\textbf{LIFX} & \textbf{lightsd} & \textbf{monolight} \\
++\hline
++hardware & daemon & GUI \\
++\hline
++embarqué & C & Python \\
++\end{tabular}
++\begin{tikzpicture}
++\draw[arrow] (0,0) -- node[below,pos=0.6] {Bas-niveau} (-4.8,0);
++\draw[arrow] (0,0) -- node[below,pos=0.6] {Haut-niveau} (4.8,0);
++\end{tikzpicture}
++\end{center}
++}
++\end{frame}
++
++\section{Merci}
++
++{\setbeamertemplate{headline}{}
++\begin{frame}
++\begin{center}\Huge{Merci}\end{center}
++\vspace{1em}
++\begin{center}\Large{\emph{Place aux questions et à la discussion}}\end{center}
++\vspace{1em}
++\begin{itemize}
++\item \Large{\href{https://twitter.com/1opter}{@1opter}}
++\item \Large{\emph{\#lightsd} sur IRC (\emph{chat.freenode.net})}
++\item \Large{\url{https://www.lightsd.io/}}
++\end{itemize}
++\end{frame}}
++
++\section{Extras}
++
++\begin{frame}{Table des modèles LIFX}
++\begin{tabular}{lll}
++\textbf{Génération} & \textbf{Modèle} & \textbf{En vente} \\
++\hline
++Gen 1 & Original 1000, Color 650 & Non \\
++\hline
++Gen 2 & Color 1000, White 800 & Oui \\
++\hline
++Gen 3 & A19, BR30, Z (ruban) & Oui \\
++\end{tabular}
++\par\vspace{2em}
++\begin{tabular}{ll}
++\textbf{Génération} & \textbf{Notes} \\
++\hline
++Gen 1 & Supporte 802.11 et 802.15.4 (inutilisé) \\
++\hline
++Gen 2 & QCA 4002, AllJoyn, \emph{plante} \\
++\hline
++Gen 3 & versions + avec IR, \emph{plante toujours} \\
++\end{tabular}
++\end{frame}
++
++\section{Démo (papier)}
++
++\begin{frame}{La grille}
++\begin{center}
++\begin{tikzpicture}[overlay]
++\pic (0, 0) {monome={scale 1.2}};
++\end{tikzpicture}
++\end{center}
++\end{frame}
++
++\begin{frame}{Ligne de fonctions/scènes}
++\begin{center}
++\begin{tikzpicture}[overlay,scale=1.2]
++\onslide<1->{%
++\pic (0, 0) {monome={scale 1.2}};
++
++\foreach \x in {-4,-3.5,...,3.5}
++\fill[mbutton] (\x, -1.75) rectangle +(0.36, -0.36);
++}
++\onslide<2->{%
++\foreach \x in {-1.5,-1,...,3}
++\fill[mbuttoff] (\x, -1.75) rectangle +(0.36, -0.36);
++
++\fill[color=fgcolor,decoration={name=snake,amplitude=2,segment length=45}]
++  decorate {(-4.25,-1.35) -- (4.15,-1.35)} -- (4.15,2) -- (-4.25,2) -- cycle;
++
++\node[rectangle] (b112) at (-3.82,-1.93) {};
++\node[rectangle] (b113) at (-3.32,-1.93) {};
++\node[rectangle] (b114) at (-2.82,-1.93) {};
++\node[rectangle] (b115) at (-2.32,-1.93) {};
++\node[rectangle] (b116) at (-1.82,-1.93) {};
++\node[rectangle] (b117) at (-1.32,-1.93) {};
++\node[rectangle] (b127) at (3.68,-1.93)  {};
++}
++\onslide<2>{
++\node (toggle) [above=1.1cm of b112] {%
++\begin{minipage}{2cm}
++\begin{center}
++on/off
++
++toggle
++\end{center}
++\end{minipage}};
++\node (off) [above=0.7cm of b113] {off};
++\node (on) [above=1.1cm of b114] {on};
++\node (scenes) [above=0.7cm of b116] {scenes\ldots};
++\node (uitoggle) [above=1.1cm of b127] {toggle UI};
++
++\draw[arrow] (toggle) -- (b112);
++\draw[arrow] (off) -- (b113);
++\draw[arrow] (on) -- (b114);
++\draw[arrow] (uitoggle) -- (b127);
++
++\draw[ultra thick,decorate,decoration={name=brace}]
++  ($(b115.north west) + (-0.1,0.35)$) -- ($(b116.north east) + (0.1,0.35)$);
++}
++\onslide<3->{%
++\coordinate (b0) at (-4, 1.75);
++\draw ($(b0) + (-0.25, 0)$) node[below right] {%
++\begin{minipage}{10cm}
++D'autres idées :
++\vspace{1em}
++\begin{itemize}
++\item Boutons pour la navigation (pagination\ldots);  % will make sense on the next slide
++\item Boutons pour contrôler MPD.
++\end{itemize}
++\end{minipage}
++};
++}
++\end{tikzpicture}
++\end{center}
++\end{frame}
++
++\begin{frame}{Panneau de contrôle pour une cible (x4)}
++\begin{center}
++\begin{tikzpicture}[overlay,scale=1.2]
++\onslide<1->{%
++\pic (0, 0) {monome={scale 1.2}};
++
++\foreach \x in {-4,-3.5,...,-2.5}
++\foreach \y in {1.75,1.25,...,-1.25}
++\fill[mbutton] (\x, \y) rectangle +(0.36, -0.36);
++
++\foreach \x in {-2,-1.5,...,-0.5}
++\foreach \y in {1.75,1.25,...,-1.25}
++\fill[mbuttmed] (\x, \y) rectangle +(0.36, -0.36);
++
++\foreach \x in {0,0.5,...,1.5}
++\foreach \y in {1.75,1.25,...,-1.25}
++\fill[mbutton] (\x, \y) rectangle +(0.36, -0.36);
++
++\foreach \x in {2,2.5,...,3.5}
++\foreach \y in {1.75,1.25,...,-1.25}
++\fill[mbuttmed] (\x, \y) rectangle +(0.36, -0.36);
++
++\foreach \x in {-4,-3.5,...,3.5}
++\fill[mbuttoff] (\x, -1.75) rectangle +(0.36, -0.36);
++}
++\onslide<2->{%
++\foreach \y in {1.75,1.25,...,-1.25}
++\fill[mbuttoff] (-2, \y) rectangle +(0.36, -0.36);
++
++\fill[color=fgcolor,decoration={name=snake,amplitude=2,segment length=45}]
++  decorate {(-1.75,2) -- (-1.75,-2.36)} -- (4.2,-2.36) -- (4.2,2) -- cycle;
++
++\foreach \x in {-3.5,-3,...,-2.5}
++\fill[mbuttoff] (\x, 1.75) rectangle +(0.36, -0.36);
++
++\foreach \y in {1.25,0.75,...,-0.25} % h
++\fill[mbuttoff] (-4, \y) rectangle +(0.36, -0.36);
++\fill[mbutthigh] (-4, -0.25) rectangle +(0.36, -0.36);
++
++\foreach \y in {1.25,0.75,...,-0.75} % s
++\fill[mbuttoff] (-3.5, \y) rectangle +(0.36, -0.36);
++\fill[mbuttmed] (-3.5, -0.75) rectangle +(0.36, -0.36);
++
++\foreach \y in {1.25,0.75,...,-1.25} % b
++\fill[mbutton] (-3, \y) rectangle +(0.36, -0.36);
++
++\foreach \y in {1.25,0.75,...,-1.25} % k
++\fill[mbuttoff] (-2.5, \y) rectangle +(0.36, -0.36);
++\fill[mbutthigh] (-2.5, -1.25) rectangle +(0.36, -0.36);
++
++\node[rectangle] (b16) at (-3.82,1.07) {};
++\node (INC) at (-4.82,1.07) {INC};
++\draw[arrow] (INC) -- (b16);
++
++\node[rectangle] (b32) at (-3.82,0.57) {};
++\node (inc) at (-4.82,0.57) {inc};
++\draw[arrow] (inc) -- (b32);
++
++\node[rectangle] (b80) at (-3.82,-0.93) {};
++\node (dec) at (-4.82,-0.93) {déc};
++\draw[arrow] (dec) -- (b80);
++
++\node[rectangle] (b96) at (-3.82,-1.43) {};
++\node (DEC) at (-4.82,-1.43) {DÉC};
++\draw[arrow] (DEC) -- (b96);
++
++\node[rectangle] (b4) at (-1.82,1.57) {};
++\node[rectangle] (b5) at (-1.32,1.57) {};
++\draw[arrow] (b5) -- (b4.west);
++\draw (b5) node[right] {Ligne de fonctions/voyants (toggle\ldots)};
++
++\node[rectangle] (b20) at (-1.82,1.07) {};
++\node[rectangle] (b21) at (-1.32,1.07) {};
++\draw[arrow] (b21) -- (b20.west);
++\draw (-1.32,1.32) node[below right] {%
++\begin{minipage}{10cm}
++4 barres de contrôle (HSBK):
++\vspace{1ex}
++\begin{itemize}
++\item Hue : 0.0--360.0°;
++\item Saturation : 0.0--1.0;
++\item (B) Luminosité : 0.0--1.0;
++\item (K) Température : 2500--9000K.
++\end{itemize}
++\end{minipage}};
++}
++\end{tikzpicture}
++\end{center}
++\end{frame}
++\end{document}
+diff --git a/slides/CMakeLists.txt b/slides/CMakeLists.txt
+--- a/slides/CMakeLists.txt
++++ b/slides/CMakeLists.txt
+@@ -1,1 +1,15 @@
++FUNCTION(LIGHTSD_COPY_COMMON_LATEX)
++    SET(
++        SOURCES
++        common/lgtdfigs.sty
++        common/lgtdslides.cls
++    )
++    FOREACH(F ${SOURCES})
++        FILE(
++            COPY ${PROJECT_SOURCE_DIR}/slides/${F}
++            DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
++        )
++    ENDFOREACH()
++ENDFUNCTION()
++
+ ADD_ALL_SUBDIRECTORIES()
+diff --git a/slides/common/lgtdfigs.sty b/slides/common/lgtdfigs.sty
+new file mode 100644
+--- /dev/null
++++ b/slides/common/lgtdfigs.sty
+@@ -0,0 +1,169 @@
++\ProvidesPackage{lgtdfigs}
++
++\usetikzlibrary{%
++  calc,
++  decorations.pathreplacing,
++  decorations.pathmorphing,
++  shapes,
++  positioning
++}
++
++%%% LIFX inspired light bulb
++
++\colorlet{LightBulbBodyColor}{Grey!90!black}
++\colorlet{LightBulbSocketColor}{Silver!90!black}
++
++\tikzset{screw/.style={decoration={%
++    name=snake,amplitude=0.1mm,segment length=0.6mm
++}}}
++
++\tikzset{pics/lightbulb/.style args={#1 scale #2 rotate #3}{code={% arg1 is light color
++
++\tikzset{screw/.style={decoration={%
++    name=snake,amplitude=0.1mm,segment length=0.6mm
++}}}
++
++\begin{scope}[scale=#2,rotate=#3]
++
++% main body
++\fill[color=LightBulbBodyColor]
++    (-28mm,0) -- ++(0,32mm) -- ++(56mm,0) -- ++(0,-32mm) --
++    ++(-10mm,-18mm) -- ++(-36mm,0) -- cycle;
++
++% main body light
++\draw[line width=1.5mm,line cap=round,rounded corners=1pt,color=LightBulbBodyColor!80!white]
++    (-16mm,0.5mm) .. controls (0,-0.4mm) .. (16mm,0.5mm);
++\draw[line width=2mm,rounded corners=1pt,color=LightBulbBodyColor!80!white]
++    (16.5mm,32mm) -- ++(0,-32mm) -- ++(-15mm,-22mm);
++
++% led - body separator
++\fill[color=LightBulbBodyColor!90!black]
++    (-20mm,32mm) -- ++(0,2.5mm) -- ++(40mm,0) -- ++(0,-2.5mm) -- cycle;
++
++% led part
++\fill[color=#1]
++    (-28mm,34.5mm) -- ++(0,14mm)
++    .. controls ++(28mm,1mm) .. ++(56mm,0)
++    -- ++(0,-14mm) -- cycle;
++
++% lower body
++\fill[color=LightBulbBodyColor!90!black]
++    (-14mm,-18mm) -- ++(0,-18mm) --
++    ++(2mm,-2mm) -- ++(24mm,0) -- ++(2mm,2mm)
++    -- ++(0,18mm);
++
++% socket
++\fill[color=LightBulbSocketColor]
++    (-10mm,-38mm) -- ++(0,-4mm)
++    decorate[screw] {(-10mm,-42mm) -- ++(0,-10mm)}
++    -- ++(0,-0.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm) -- ++(0,0.5mm)
++    decorate[screw] {(10mm,-52mm) -- ++(0,10mm)}
++    -- (10mm,-38mm) -- ++(-20mm,0) -- ++(0,-4mm) -- cycle;
++\draw[thin,color=LightBulbSocketColor] (-10mm,-42mm) -- (10mm,-52mm);
++
++% socket light
++\draw[line width=1mm,line cap=round,rounded corners=1pt,color=LightBulbSocketColor!90!white]
++    (4.5mm,-38mm) -- ++(0,-14mm) -- ++(-4mm,-2.5mm);
++
++% lower body light
++\draw[line width=1.8mm,color=LightBulbBodyColor]
++    (5mm,-18mm) -- ++(0,-20mm);
++
++% led - body separator light
++\draw[line width=1.6mm, color=LightBulbBodyColor] (16mm,32mm) -- ++(0,2.5mm);
++% led - body separator shade
++\draw[thin, color=LightBulbBodyColor!80!black] (-20mm,32mm) -- ++(0,2.5mm);
++\draw[thin, color=LightBulbBodyColor!80!black] (20mm,32mm) -- ++(0,2.5mm);
++
++% socket shade
++\draw[color=LightBulbSocketColor!80!black]
++    (-10mm,-38mm) -- ++(0,-4mm)
++    decorate[screw] {(-10mm,-42mm) -- ++(0,-10mm)}
++    -- ++(0,-0.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm) -- ++(0,0.5mm)
++    decorate[screw] {(10mm,-52mm) -- ++(0,10mm)}
++    -- (10mm,-38mm);
++\draw[color=fgcolor]
++    (-10mm,-52.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm);
++\draw[rounded corners=1pt,color=LightBulbSocketColor!80!black]
++    (-10mm,-52.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm);
++
++% lower body shade
++\draw[rounded corners=1pt,color=LightBulbBodyColor!50!black]
++    (-14mm,-18mm) -- ++(0,-18mm) --
++    ++(2mm,-2mm) -- ++(24mm,0) -- ++(2mm,2mm)
++    -- ++(0,18mm);
++
++% body shade
++\draw[thick,rounded corners=1pt,color=LightBulbBodyColor!60!black]
++    (-28mm,0) -- ++(0,32mm) -- ++(56mm,0) -- ++(0,-32mm) --
++    ++(-10mm,-18mm) -- ++(-36mm,0) -- cycle;
++
++% led shade
++\draw[thick,rounded corners=1pt,color=#1!70!white]
++    (-28mm,34.5mm) -- ++(0,14mm)
++    .. controls ++(28mm,1mm) .. ++(56mm,0)
++    -- ++(0,-14mm) -- cycle;
++
++\end{scope}
++}}}
++
++%%% Monome inspired grid
++
++\colorlet{MonomePlate}{Gainsboro}
++\colorlet{MonomeCase}{Sienna}
++
++\tikzset{mbuttoff/.style={color=gray,rounded corners=1pt}}
++\tikzset{mbuttvlow/.style={color=orange!20!gray,rounded corners=1pt}}
++\tikzset{mbuttlow/.style={color=orange!35!gray,rounded corners=1pt}}
++\tikzset{mbuttmed/.style={color=orange!50!gray,rounded corners=1pt}}
++\tikzset{mbutthigh/.style={color=orange!80!gray,rounded corners=1pt}}
++\tikzset{mbutton/.style={fill,color=orange!95!white,rounded corners=1pt}}
++
++\tikzset{pics/monome/.style args={scale #1}{code={%
++
++\begin{scope}[scale=#1]
++\coordinate (NW) at (-4, 1.75);
++\coordinate (SE) at (3.86, -2.11);
++
++\fill[color=MonomeCase,rounded corners=2pt] ($(NW) + (-0.18,0.18)$) rectangle ($(SE) + (0.18,-0.18)$);
++\fill[color=MonomePlate,rounded corners=2pt] ($(NW) + (-0.10,0.10)$) rectangle ($(SE) + (0.10,-0.10)$);
++
++\foreach \x in {-4,-3.5,...,3.5}{
++    \foreach \y in {1.75,1.25,...,-1.75}{
++        \fill[mbuttoff] (\x, \y) rectangle +(0.36, -0.36);
++    }
++}
++
++\end{scope}
++}}}
++
++%%% Detailed arch diagram
++
++\tikzset{pics/monolightarch/.style={code={%
++
++\tikzset{wifipath/.style={thick,opacity=0.8,decorate,decoration={name=expanding waves,angle=25,segment length=3.5}}}
++\tikzset{box/.style={draw,ultra thick, color=BeamerBlue, text=black, rectangle, rounded corners=1pt}}
++
++\coordinate (Origin) at (0,0);
++\node[box,color=black] (serialoscd) at (0.5,1.5) {serialoscd};
++\draw[ultra thick] (-1.46, 2.2) -| node[above, pos=0.4] {Serial \small{(FTDI)}} (serialoscd);
++\node (monome) at (-3.5,1.5) {\begin{tikzpicture}
++\pic (0, 0) {monome={scale 0.5}};
++\end{tikzpicture}};
++\node[box] (monolight) at (3.5,-0.25) {monolight};
++\node[box] (lightsd) at (0.5,-2) {lightsd};
++\node (bulbh) at (-4.2,-1.1) {\begin{tikzpicture}
++\pic (0, 0) {lightbulb={LightSlateBlue scale 0.19 rotate 90}};
++\end{tikzpicture}};
++\node (bulbl) at (-4.2,-2.9) {\begin{tikzpicture}
++\pic (0, 0) {lightbulb={IndianRed scale 0.19 rotate 90}};
++\end{tikzpicture}};
++
++\draw[ultra thick] (serialoscd) -| node[above,pos=0.25] {OSC} node[below,pos=0.25] {\small{(UDP)}} (monolight);
++\draw[ultra thick] (lightsd) -| node[above,pos=0.25] {JSON-RPC} node[below,pos=0.25] {\small{(TCP/Unix)}} (monolight);
++\draw[wifipath] (bulbh.east) -- (-2.2,-1.15);
++\draw[wifipath] (lightsd.west) -- (-1.1,-2);
++\draw[wifipath] (bulbl.east) -- (-2.2,-2.85);
++\node (wifi) at (-2.1,-2.25) {\small{(UDP)}};
++\draw ($(wifi.north) + (0,0.2)$) node {LIFX-LAN};
++}}}
+diff --git a/slides/common/lgtdslides.cls b/slides/common/lgtdslides.cls
+new file mode 100644
+--- /dev/null
++++ b/slides/common/lgtdslides.cls
+@@ -0,0 +1,18 @@
++\ProvidesClass{lgtdslides}
++
++\LoadClass[utf8x,xcolor={usenames,svgnames}]{beamer}
++
++\RequirePackage{lmodern}
++\RequirePackage{arev}
++\RequirePackage{tgbonum}
++\RequirePackage{inconsolata}
++\RequirePackage[T1]{fontenc}
++\RequirePackage[fixlanguage]{babelbib}
++
++\useoutertheme{infolines}
++\setbeamertemplate{navigation symbols}{}
++\setbeamertemplate{bibliography item}[text]
++\setbeamerfont{footnote}{size=\tiny}
++
++\colorlet{fgcolor}{White}
++\definecolor{BeamerBlue}{RGB}{49,56,172}
+diff --git a/slides/fosdem_2017/CMakeLists.txt b/slides/fosdem_2017/CMakeLists.txt
 --- a/slides/fosdem_2017/CMakeLists.txt
-+++ b/slides/2017-02-04_fosdem/CMakeLists.txt
++++ b/slides/fosdem_2017/CMakeLists.txt
 @@ -1,1 +1,3 @@
 +LIGHTSD_COPY_COMMON_LATEX()
 +
  ADD_LATEX_DOCUMENT(fosdem_2017.tex)
-diff --git a/slides/fosdem_2017/fosdem_2017.pdf b/slides/2017-02-04_fosdem/fosdem_2017.pdf
-rename from slides/fosdem_2017/fosdem_2017.pdf
-rename to slides/2017-02-04_fosdem/fosdem_2017.pdf
-diff --git a/slides/fosdem_2017/fosdem_2017.tex b/slides/2017-02-04_fosdem/fosdem_2017.tex
-rename from slides/fosdem_2017/fosdem_2017.tex
-rename to slides/2017-02-04_fosdem/fosdem_2017.tex
+diff --git a/slides/fosdem_2017/fosdem_2017.tex b/slides/fosdem_2017/fosdem_2017.tex
 --- a/slides/fosdem_2017/fosdem_2017.tex
-+++ b/slides/2017-02-04_fosdem/fosdem_2017.tex
++++ b/slides/fosdem_2017/fosdem_2017.tex
 @@ -1,41 +1,16 @@
 -\documentclass[utf8x,xcolor={usenames,svgnames}]{beamer}
 +\documentclass{lgtdslides}
@@ -777,630 +1469,3 @@
  \end{tikzpicture}
  \end{center}
  \end{frame}
-diff --git a/slides/fosdem_2017/lightsd-demo.sh b/slides/2017-02-04_fosdem/lightsd-demo.sh
-rename from slides/fosdem_2017/lightsd-demo.sh
-rename to slides/2017-02-04_fosdem/lightsd-demo.sh
-diff --git a/slides/fosdem_2017/monolight-demo.sh b/slides/2017-02-04_fosdem/monolight-demo.sh
-rename from slides/fosdem_2017/monolight-demo.sh
-rename to slides/2017-02-04_fosdem/monolight-demo.sh
-diff --git a/slides/2017-04-XX_while_42/CMakeLists.txt b/slides/2017-04-XX_while_42/CMakeLists.txt
-new file mode 100644
---- /dev/null
-+++ b/slides/2017-04-XX_while_42/CMakeLists.txt
-@@ -0,0 +1,3 @@
-+LIGHTSD_COPY_COMMON_LATEX()
-+
-+ADD_LATEX_DOCUMENT(while42.tex)
-diff --git a/slides/2017-04-XX_while_42/while42.tex b/slides/2017-04-XX_while_42/while42.tex
-new file mode 100644
---- /dev/null
-+++ b/slides/2017-04-XX_while_42/while42.tex
-@@ -0,0 +1,392 @@
-+\documentclass{lgtdslides}
-+
-+\usepackage{tikz}
-+\usepackage{tikzsymbols}
-+\usepackage[francais]{babel}
-+
-+\usepackage{lgtdfigs}
-+
-+\title{S'amuser avec la lumière}
-+\subtitle{\textit{Avec des ampoules LIFX et un Monome 128}}
-+\date{While 42 SF : side projects}
-+\author{Louis Opter <louis@opter.org>}
-+
-+\tikzset{arrow/.style={->, >=stealth,ultra thick,rounded corners}}
-+
-+\begin{document}
-+
-+\begin{frame}\titlepage\end{frame}
-+
-+\section{Intro}
-+
-+\begin{frame}{\LARGE{\texttt{\$ whoami}}}
-+Bonjour, moi c'est Louis (Opter) et :\vspace{1em}
-+\begin{itemize}
-+\item je bosse sur SF depuis ~2012 (docker/Uber) ;
-+\item j'y connais rien en hardware ;
-+\item donc j'ai acheté des trucs tous faits « simples » ;
-+\item et voici une démo de ce que j'ai fait.
-+\end{itemize}
-+\end{frame}
-+
-+\section{Démo}
-+
-+\begin{frame}{Sous vos yeux}
-+\begin{center}
-+\begin{tikzpicture}
-+\pic (0, 0) {monolightarch};
-+\end{tikzpicture}
-+\end{center}
-+\end{frame}
-+
-+
-+\begin{frame}{Effet sablier/alerte}
-+\only<1>{Une autre idée que j'aimerais implémenter\ldots}
-+\begin{center}
-+\begin{tikzpicture}[overlay,scale=1.2]
-+\onslide<2->{%
-+\pic (0, 0) {monome={scale 1.2}};
-+
-+\coordinate (NW) at (-4, 1.75);
-+\coordinate (caption) at ($(NW) + (-1.155,0.65)$);
-+
-+\foreach \x in {-4,-3.5,...,-1}
-+\fill[mbutton] (\x, -1.75) rectangle +(0.36, -0.36); % function row
-+
-+\node[rectangle] (b117) at (-1.32,-1.93) {};
-+\node[rectangle] (b118) at (-0.82,-1.93) {};
-+}
-+\onslide<2,4->{%
-+% targets toggles:
-+\fill[mbutton] (-4, 1.75) rectangle +(0.36, -0.36);
-+\foreach \x in {-2,0,...,3.5}
-+\fill[mbuttvlow] (\x, 1.75) rectangle +(0.36, -0.36);
-+
-+% h:
-+\fill[mbutthigh] (-4, -0.25) rectangle +(0.36, -0.36);
-+\fill[mbutton] (-4, -0.75) rectangle +(0.36, -0.36);
-+\fill[mbutton] (-4, -1.25) rectangle +(0.36, -0.36);
-+
-+% s:
-+\fill[mbuttmed] (-3.5, -0.75) rectangle +(0.36, -0.36);
-+\fill[mbutton] (-3.5, -1.25) rectangle +(0.36, -0.36);
-+
-+% b:
-+\foreach \y in {1.25,0.75,...,-1.25}
-+\fill[mbutton] (-3, \y) rectangle +(0.36, -0.36);
-+
-+% k:
-+\fill[mbutthigh] (-2.5, -1.25) rectangle +(0.36, -0.36);
-+}
-+\onslide<2>{%
-+\draw (caption) node[right] {Ajoutons deux nouvelles fonctions :};
-+
-+\node (timer) [below=0.5cm of b117] {timer};
-+\node (alert) [below=0.9cm of b118] {alert};
-+\draw[arrow] (timer) -- (b117);
-+\draw[arrow] (alert) -- (b118);
-+}
-+\onslide<3>{%
-+\draw (caption) node[right] {Sélection du compte à rebours:};
-+\node[below right] at ($(caption.south) + (0, -0.09)$) {\footnotesize{(1 bouton allumé = 1 unité de temps)}};
-+
-+% partially lit grid:
-+\foreach \x in {-4,-3.5,...,-0.5}
-+\foreach \y in {1.75,1.25,...,-1.25}
-+\fill[mbutton] (\x, \y) rectangle +(0.36, -0.36);
-+\foreach \y in {1.75,1.25,...,-0.5}
-+\fill[mbutton] (0, \y) rectangle +(0.36, -0.36);
-+
-+\foreach \x in {-4,-3.5,...,3.5}
-+\fill[mbuttoff] (\x, -1.75) rectangle +(0.36, -0.36); % blank function row
-+
-+\fill[mbutton] (-1.5, -1.75) rectangle +(0.36, -0.36); % time button
-+\fill[mbutton] (0, -1.75) rectangle +(0.36, -0.36); % dec time scale
-+\fill[mbutton] (0.5, -1.75) rectangle +(0.36, -0.36); % inc time scale
-+
-+%\node[rectangle] (b117) at (-1.32,-1.93) {};
-+%\node[rectangle] (b118) at (-0.82,-1.93) {};
-+%\node[rectangle] (b119) at (-0.32,-1.93) {};
-+\node[rectangle] (b120) at (0.18,-1.93) {};
-+\node[rectangle] (b121) at (0.68,-1.93) {};
-+\node[rectangle] (b122) at (1.18,-1.93) {};
-+\draw[ultra thick,decorate,decoration={name=brace,mirror}]
-+  ($(b120.south west) + (-0.1,-0.35)$) -- ($(b121.south east) + (0.1,-0.35)$);
-+\node (timectl) [below=0.5cm of b121] {déc/inc de l'unité de temps};
-+}
-+\onslide<4>{%
-+\draw (caption) node[right] {Sélection de la cible et de la fonction (alert):};
-+
-+\node (alert) [below=0.5cm of b118] {alert};
-+\draw[arrow] (alert) -- (b118);
-+
-+\node[rectangle,opacity=0] (b0) at (-3.82,1.57) {B};
-+\node[rectangle,opacity=0] (b4) at (-1.82,1.57) {B};
-+\node[rectangle,opacity=0] (b8) at (0.18,1.57) {B};
-+\node[rectangle,opacity=0] (b12) at (2.18,1.57) {B};
-+
-+\coordinate (legend) at ($(caption) + (0.7, -0.15)$);
-+\coordinate (upturn) at ($(legend) + (0,-1.26)$);
-+\draw[arrow,<-] (b0.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
-+\draw[arrow,<-] (b4.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
-+\draw[arrow,<-] (b8.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
-+\draw[arrow,<-] (b12.south) -- ++(0,-0.35) -- (upturn) -- (legend.south);
-+}
-+\onslide<5>{%
-+\fill[mbutton] (-3.5, 1.75) rectangle +(0.36, -0.36);
-+
-+\node[rectangle] (b1) at (-3.32,1.57) {};
-+\node (feedback) [above right=0.5cm of b1] {Voyant d'activité du sablier};
-+\draw[arrow] (feedback) -| (b1);
-+}
-+\end{tikzpicture}
-+\end{center}
-+\end{frame}
-+
-+\section{À propos du projet}
-+
-+\begin{frame}{Motivations}
-+À l'origine du projet :
-+\vspace{1em}
-+\begin{itemize}
-+\item Délais de découverte/utilisation, fiabilité ;
-+\item Sécurité, vie privée, (dé-)centralisation ;
-+\item Obsolescence programmée (ou non) ;
-+\item « Accessibilité » ;
-+\item Insatisfaction professionnelle.
-+\end{itemize}
-+\end{frame}
-+
-+\begin{frame}{Résultats}
-+\only<1,3>{%
-+Quelques découvertes et confirmations :
-+\vspace{1em}
-+\begin{itemize}
-+\item Les blobs binaires c'est de la merde ;
-+\item L'IoT s'améliore mais c'est pas encore ça ;
-+\item Spectre de problèmes vraiment intéressant ;
-+\item Une méthode d'apprentissage de premier ordre.
-+\end{itemize}
-+}
-+\only<2>{%
-+\emph{\leavevmode\usebeamertemplate***{itemize item} Spectre de problèmes vraiment intéressant :}
-+\vspace{1em}
-+\begin{center}
-+\setlength{\tabcolsep}{15pt}
-+\begin{tabular}{ccc}
-+\textbf{LIFX} & \textbf{lightsd} & \textbf{monolight} \\
-+\hline
-+hardware & daemon & GUI \\
-+\hline
-+embarqué & C & Python \\
-+\end{tabular}
-+\begin{tikzpicture}
-+\draw[arrow] (0,0) -- node[below,pos=0.6] {Bas-niveau} (-4.8,0);
-+\draw[arrow] (0,0) -- node[below,pos=0.6] {Haut-niveau} (4.8,0);
-+\end{tikzpicture}
-+\end{center}
-+}
-+\end{frame}
-+
-+\section{Merci}
-+
-+{\setbeamertemplate{headline}{}
-+\begin{frame}
-+\begin{center}\Huge{Merci}\end{center}
-+\vspace{1em}
-+\begin{center}\Large{\emph{Place aux questions et à la discussion}}\end{center}
-+\vspace{1em}
-+\begin{itemize}
-+\item \Large{\href{https://twitter.com/1opter}{@1opter}}
-+\item \Large{\emph{\#lightsd} sur IRC (\emph{chat.freenode.net})}
-+\item \Large{\url{https://www.lightsd.io/}}
-+\end{itemize}
-+\end{frame}}
-+
-+\section{Extras}
-+
-+\begin{frame}{Table des modèles LIFX}
-+\begin{tabular}{lll}
-+\textbf{Génération} & \textbf{Modèle} & \textbf{En vente} \\
-+\hline
-+Gen 1 & Original 1000, Color 650 & Non \\
-+\hline
-+Gen 2 & Color 1000, White 800 & Oui \\
-+\hline
-+Gen 3 & A19, BR30, Z (ruban) & Oui \\
-+\end{tabular}
-+\par\vspace{2em}
-+\begin{tabular}{ll}
-+\textbf{Génération} & \textbf{Notes} \\
-+\hline
-+Gen 1 & Supporte 802.11 et 802.15.4 (inutilisé) \\
-+\hline
-+Gen 2 & QCA 4002, AllJoyn, \emph{plante} \\
-+\hline
-+Gen 3 & versions + avec IR, \emph{plante toujours} \\
-+\end{tabular}
-+\end{frame}
-+
-+\section{Démo (papier)}
-+
-+\begin{frame}{La grille}
-+\begin{center}
-+\begin{tikzpicture}[overlay]
-+\pic (0, 0) {monome={scale 1.2}};
-+\end{tikzpicture}
-+\end{center}
-+\end{frame}
-+
-+\begin{frame}{Ligne de fonctions/scènes}
-+\begin{center}
-+\begin{tikzpicture}[overlay,scale=1.2]
-+\onslide<1->{%
-+\pic (0, 0) {monome={scale 1.2}};
-+
-+\foreach \x in {-4,-3.5,...,3.5}
-+\fill[mbutton] (\x, -1.75) rectangle +(0.36, -0.36);
-+}
-+\onslide<2->{%
-+\foreach \x in {-1.5,-1,...,3}
-+\fill[mbuttoff] (\x, -1.75) rectangle +(0.36, -0.36);
-+
-+\fill[color=fgcolor,decoration={name=snake,amplitude=2,segment length=45}]
-+  decorate {(-4.25,-1.35) -- (4.15,-1.35)} -- (4.15,2) -- (-4.25,2) -- cycle;
-+
-+\node[rectangle] (b112) at (-3.82,-1.93) {};
-+\node[rectangle] (b113) at (-3.32,-1.93) {};
-+\node[rectangle] (b114) at (-2.82,-1.93) {};
-+\node[rectangle] (b115) at (-2.32,-1.93) {};
-+\node[rectangle] (b116) at (-1.82,-1.93) {};
-+\node[rectangle] (b117) at (-1.32,-1.93) {};
-+\node[rectangle] (b127) at (3.68,-1.93)  {};
-+}
-+\onslide<2>{
-+\node (toggle) [above=1.1cm of b112] {%
-+\begin{minipage}{2cm}
-+\begin{center}
-+on/off
-+
-+toggle
-+\end{center}
-+\end{minipage}};
-+\node (off) [above=0.7cm of b113] {off};
-+\node (on) [above=1.1cm of b114] {on};
-+\node (scenes) [above=0.7cm of b116] {scenes\ldots};
-+\node (uitoggle) [above=1.1cm of b127] {toggle UI};
-+
-+\draw[arrow] (toggle) -- (b112);
-+\draw[arrow] (off) -- (b113);
-+\draw[arrow] (on) -- (b114);
-+\draw[arrow] (uitoggle) -- (b127);
-+
-+\draw[ultra thick,decorate,decoration={name=brace}]
-+  ($(b115.north west) + (-0.1,0.35)$) -- ($(b116.north east) + (0.1,0.35)$);
-+}
-+\onslide<3->{%
-+\coordinate (b0) at (-4, 1.75);
-+\draw ($(b0) + (-0.25, 0)$) node[below right] {%
-+\begin{minipage}{10cm}
-+D'autres idées :
-+\vspace{1em}
-+\begin{itemize}
-+\item Boutons pour la navigation (pagination\ldots);  % will make sense on the next slide
-+\item Boutons pour contrôler MPD.
-+\end{itemize}
-+\end{minipage}
-+};
-+}
-+\end{tikzpicture}
-+\end{center}
-+\end{frame}
-+
-+\begin{frame}{Panneau de contrôle pour une cible (x4)}
-+\begin{center}
-+\begin{tikzpicture}[overlay,scale=1.2]
-+\onslide<1->{%
-+\pic (0, 0) {monome={scale 1.2}};
-+
-+\foreach \x in {-4,-3.5,...,-2.5}
-+\foreach \y in {1.75,1.25,...,-1.25}
-+\fill[mbutton] (\x, \y) rectangle +(0.36, -0.36);
-+
-+\foreach \x in {-2,-1.5,...,-0.5}
-+\foreach \y in {1.75,1.25,...,-1.25}
-+\fill[mbuttmed] (\x, \y) rectangle +(0.36, -0.36);
-+
-+\foreach \x in {0,0.5,...,1.5}
-+\foreach \y in {1.75,1.25,...,-1.25}
-+\fill[mbutton] (\x, \y) rectangle +(0.36, -0.36);
-+
-+\foreach \x in {2,2.5,...,3.5}
-+\foreach \y in {1.75,1.25,...,-1.25}
-+\fill[mbuttmed] (\x, \y) rectangle +(0.36, -0.36);
-+
-+\foreach \x in {-4,-3.5,...,3.5}
-+\fill[mbuttoff] (\x, -1.75) rectangle +(0.36, -0.36);
-+}
-+\onslide<2->{%
-+\foreach \y in {1.75,1.25,...,-1.25}
-+\fill[mbuttoff] (-2, \y) rectangle +(0.36, -0.36);
-+
-+\fill[color=fgcolor,decoration={name=snake,amplitude=2,segment length=45}]
-+  decorate {(-1.75,2) -- (-1.75,-2.36)} -- (4.2,-2.36) -- (4.2,2) -- cycle;
-+
-+\foreach \x in {-3.5,-3,...,-2.5}
-+\fill[mbuttoff] (\x, 1.75) rectangle +(0.36, -0.36);
-+
-+\foreach \y in {1.25,0.75,...,-0.25} % h
-+\fill[mbuttoff] (-4, \y) rectangle +(0.36, -0.36);
-+\fill[mbutthigh] (-4, -0.25) rectangle +(0.36, -0.36);
-+
-+\foreach \y in {1.25,0.75,...,-0.75} % s
-+\fill[mbuttoff] (-3.5, \y) rectangle +(0.36, -0.36);
-+\fill[mbuttmed] (-3.5, -0.75) rectangle +(0.36, -0.36);
-+
-+\foreach \y in {1.25,0.75,...,-1.25} % b
-+\fill[mbutton] (-3, \y) rectangle +(0.36, -0.36);
-+
-+\foreach \y in {1.25,0.75,...,-1.25} % k
-+\fill[mbuttoff] (-2.5, \y) rectangle +(0.36, -0.36);
-+\fill[mbutthigh] (-2.5, -1.25) rectangle +(0.36, -0.36);
-+
-+\node[rectangle] (b16) at (-3.82,1.07) {};
-+\node (INC) at (-4.82,1.07) {INC};
-+\draw[arrow] (INC) -- (b16);
-+
-+\node[rectangle] (b32) at (-3.82,0.57) {};
-+\node (inc) at (-4.82,0.57) {inc};
-+\draw[arrow] (inc) -- (b32);
-+
-+\node[rectangle] (b80) at (-3.82,-0.93) {};
-+\node (dec) at (-4.82,-0.93) {déc};
-+\draw[arrow] (dec) -- (b80);
-+
-+\node[rectangle] (b96) at (-3.82,-1.43) {};
-+\node (DEC) at (-4.82,-1.43) {DÉC};
-+\draw[arrow] (DEC) -- (b96);
-+
-+\node[rectangle] (b4) at (-1.82,1.57) {};
-+\node[rectangle] (b5) at (-1.32,1.57) {};
-+\draw[arrow] (b5) -- (b4.west);
-+\draw (b5) node[right] {Ligne de fonctions/voyants (toggle\ldots)};
-+
-+\node[rectangle] (b20) at (-1.82,1.07) {};
-+\node[rectangle] (b21) at (-1.32,1.07) {};
-+\draw[arrow] (b21) -- (b20.west);
-+\draw (-1.32,1.32) node[below right] {%
-+\begin{minipage}{10cm}
-+4 barres de contrôle (HSBK):
-+\vspace{1ex}
-+\begin{itemize}
-+\item Hue : 0.0--360.0°;
-+\item Saturation : 0.0--1.0;
-+\item (B) Luminosité : 0.0--1.0;
-+\item (K) Température : 2500--9000K.
-+\end{itemize}
-+\end{minipage}};
-+}
-+\end{tikzpicture}
-+\end{center}
-+\end{frame}
-+\end{document}
-diff --git a/slides/CMakeLists.txt b/slides/CMakeLists.txt
---- a/slides/CMakeLists.txt
-+++ b/slides/CMakeLists.txt
-@@ -1,1 +1,15 @@
-+FUNCTION(LIGHTSD_COPY_COMMON_LATEX)
-+    SET(
-+        SOURCES
-+        common/lgtdfigs.sty
-+        common/lgtdslides.cls
-+    )
-+    FOREACH(F ${SOURCES})
-+        FILE(
-+            COPY ${PROJECT_SOURCE_DIR}/slides/${F}
-+            DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
-+        )
-+    ENDFOREACH()
-+ENDFUNCTION()
-+
- ADD_ALL_SUBDIRECTORIES()
-diff --git a/slides/common/lgtdfigs.sty b/slides/common/lgtdfigs.sty
-new file mode 100644
---- /dev/null
-+++ b/slides/common/lgtdfigs.sty
-@@ -0,0 +1,169 @@
-+\ProvidesPackage{lgtdfigs}
-+
-+\usetikzlibrary{%
-+  calc,
-+  decorations.pathreplacing,
-+  decorations.pathmorphing,
-+  shapes,
-+  positioning
-+}
-+
-+%%% LIFX inspired light bulb
-+
-+\colorlet{LightBulbBodyColor}{Grey!90!black}
-+\colorlet{LightBulbSocketColor}{Silver!90!black}
-+
-+\tikzset{screw/.style={decoration={%
-+    name=snake,amplitude=0.1mm,segment length=0.6mm
-+}}}
-+
-+\tikzset{pics/lightbulb/.style args={#1 scale #2 rotate #3}{code={% arg1 is light color
-+
-+\tikzset{screw/.style={decoration={%
-+    name=snake,amplitude=0.1mm,segment length=0.6mm
-+}}}
-+
-+\begin{scope}[scale=#2,rotate=#3]
-+
-+% main body
-+\fill[color=LightBulbBodyColor]
-+    (-28mm,0) -- ++(0,32mm) -- ++(56mm,0) -- ++(0,-32mm) --
-+    ++(-10mm,-18mm) -- ++(-36mm,0) -- cycle;
-+
-+% main body light
-+\draw[line width=1.5mm,line cap=round,rounded corners=1pt,color=LightBulbBodyColor!80!white]
-+    (-16mm,0.5mm) .. controls (0,-0.4mm) .. (16mm,0.5mm);
-+\draw[line width=2mm,rounded corners=1pt,color=LightBulbBodyColor!80!white]
-+    (16.5mm,32mm) -- ++(0,-32mm) -- ++(-15mm,-22mm);
-+
-+% led - body separator
-+\fill[color=LightBulbBodyColor!90!black]
-+    (-20mm,32mm) -- ++(0,2.5mm) -- ++(40mm,0) -- ++(0,-2.5mm) -- cycle;
-+
-+% led part
-+\fill[color=#1]
-+    (-28mm,34.5mm) -- ++(0,14mm)
-+    .. controls ++(28mm,1mm) .. ++(56mm,0)
-+    -- ++(0,-14mm) -- cycle;
-+
-+% lower body
-+\fill[color=LightBulbBodyColor!90!black]
-+    (-14mm,-18mm) -- ++(0,-18mm) --
-+    ++(2mm,-2mm) -- ++(24mm,0) -- ++(2mm,2mm)
-+    -- ++(0,18mm);
-+
-+% socket
-+\fill[color=LightBulbSocketColor]
-+    (-10mm,-38mm) -- ++(0,-4mm)
-+    decorate[screw] {(-10mm,-42mm) -- ++(0,-10mm)}
-+    -- ++(0,-0.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm) -- ++(0,0.5mm)
-+    decorate[screw] {(10mm,-52mm) -- ++(0,10mm)}
-+    -- (10mm,-38mm) -- ++(-20mm,0) -- ++(0,-4mm) -- cycle;
-+\draw[thin,color=LightBulbSocketColor] (-10mm,-42mm) -- (10mm,-52mm);
-+
-+% socket light
-+\draw[line width=1mm,line cap=round,rounded corners=1pt,color=LightBulbSocketColor!90!white]
-+    (4.5mm,-38mm) -- ++(0,-14mm) -- ++(-4mm,-2.5mm);
-+
-+% lower body light
-+\draw[line width=1.8mm,color=LightBulbBodyColor]
-+    (5mm,-18mm) -- ++(0,-20mm);
-+
-+% led - body separator light
-+\draw[line width=1.6mm, color=LightBulbBodyColor] (16mm,32mm) -- ++(0,2.5mm);
-+% led - body separator shade
-+\draw[thin, color=LightBulbBodyColor!80!black] (-20mm,32mm) -- ++(0,2.5mm);
-+\draw[thin, color=LightBulbBodyColor!80!black] (20mm,32mm) -- ++(0,2.5mm);
-+
-+% socket shade
-+\draw[color=LightBulbSocketColor!80!black]
-+    (-10mm,-38mm) -- ++(0,-4mm)
-+    decorate[screw] {(-10mm,-42mm) -- ++(0,-10mm)}
-+    -- ++(0,-0.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm) -- ++(0,0.5mm)
-+    decorate[screw] {(10mm,-52mm) -- ++(0,10mm)}
-+    -- (10mm,-38mm);
-+\draw[color=fgcolor]
-+    (-10mm,-52.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm);
-+\draw[rounded corners=1pt,color=LightBulbSocketColor!80!black]
-+    (-10mm,-52.5mm) -- ++(7.5mm,-6mm) -- ++(5mm,0) -- ++(7.5mm,6mm);
-+
-+% lower body shade
-+\draw[rounded corners=1pt,color=LightBulbBodyColor!50!black]
-+    (-14mm,-18mm) -- ++(0,-18mm) --
-+    ++(2mm,-2mm) -- ++(24mm,0) -- ++(2mm,2mm)
-+    -- ++(0,18mm);
-+
-+% body shade
-+\draw[thick,rounded corners=1pt,color=LightBulbBodyColor!60!black]
-+    (-28mm,0) -- ++(0,32mm) -- ++(56mm,0) -- ++(0,-32mm) --
-+    ++(-10mm,-18mm) -- ++(-36mm,0) -- cycle;
-+
-+% led shade
-+\draw[thick,rounded corners=1pt,color=#1!70!white]
-+    (-28mm,34.5mm) -- ++(0,14mm)
-+    .. controls ++(28mm,1mm) .. ++(56mm,0)
-+    -- ++(0,-14mm) -- cycle;
-+
-+\end{scope}
-+}}}
-+
-+%%% Monome inspired grid
-+
-+\colorlet{MonomePlate}{Gainsboro}
-+\colorlet{MonomeCase}{Sienna}
-+
-+\tikzset{mbuttoff/.style={color=gray,rounded corners=1pt}}
-+\tikzset{mbuttvlow/.style={color=orange!20!gray,rounded corners=1pt}}
-+\tikzset{mbuttlow/.style={color=orange!35!gray,rounded corners=1pt}}
-+\tikzset{mbuttmed/.style={color=orange!50!gray,rounded corners=1pt}}
-+\tikzset{mbutthigh/.style={color=orange!80!gray,rounded corners=1pt}}
-+\tikzset{mbutton/.style={fill,color=orange!95!white,rounded corners=1pt}}
-+
-+\tikzset{pics/monome/.style args={scale #1}{code={%
-+
-+\begin{scope}[scale=#1]
-+\coordinate (NW) at (-4, 1.75);
-+\coordinate (SE) at (3.86, -2.11);
-+
-+\fill[color=MonomeCase,rounded corners=2pt] ($(NW) + (-0.18,0.18)$) rectangle ($(SE) + (0.18,-0.18)$);
-+\fill[color=MonomePlate,rounded corners=2pt] ($(NW) + (-0.10,0.10)$) rectangle ($(SE) + (0.10,-0.10)$);
-+
-+\foreach \x in {-4,-3.5,...,3.5}{
-+    \foreach \y in {1.75,1.25,...,-1.75}{
-+        \fill[mbuttoff] (\x, \y) rectangle +(0.36, -0.36);
-+    }
-+}
-+
-+\end{scope}
-+}}}
-+
-+%%% Detailed arch diagram
-+
-+\tikzset{pics/monolightarch/.style={code={%
-+
-+\tikzset{wifipath/.style={thick,opacity=0.8,decorate,decoration={name=expanding waves,angle=25,segment length=3.5}}}
-+\tikzset{box/.style={draw,ultra thick, color=BeamerBlue, text=black, rectangle, rounded corners=1pt}}
-+
-+\coordinate (Origin) at (0,0);
-+\node[box,color=black] (serialoscd) at (0.5,1.5) {serialoscd};
-+\draw[ultra thick] (-1.46, 2.2) -| node[above, pos=0.4] {Serial \small{(FTDI)}} (serialoscd);
-+\node (monome) at (-3.5,1.5) {\begin{tikzpicture}
-+\pic (0, 0) {monome={scale 0.5}};
-+\end{tikzpicture}};
-+\node[box] (monolight) at (3.5,-0.25) {monolight};
-+\node[box] (lightsd) at (0.5,-2) {lightsd};
-+\node (bulbh) at (-4.2,-1.1) {\begin{tikzpicture}
-+\pic (0, 0) {lightbulb={LightSlateBlue scale 0.19 rotate 90}};
-+\end{tikzpicture}};
-+\node (bulbl) at (-4.2,-2.9) {\begin{tikzpicture}
-+\pic (0, 0) {lightbulb={IndianRed scale 0.19 rotate 90}};
-+\end{tikzpicture}};
-+
-+\draw[ultra thick] (serialoscd) -| node[above,pos=0.25] {OSC} node[below,pos=0.25] {\small{(UDP)}} (monolight);
-+\draw[ultra thick] (lightsd) -| node[above,pos=0.25] {JSON-RPC} node[below,pos=0.25] {\small{(TCP/Unix)}} (monolight);
-+\draw[wifipath] (bulbh.east) -- (-2.2,-1.15);
-+\draw[wifipath] (lightsd.west) -- (-1.1,-2);
-+\draw[wifipath] (bulbl.east) -- (-2.2,-2.85);
-+\node (wifi) at (-2.1,-2.25) {\small{(UDP)}};
-+\draw ($(wifi.north) + (0,0.2)$) node {LIFX-LAN};
-+}}}
-diff --git a/slides/common/lgtdslides.cls b/slides/common/lgtdslides.cls
-new file mode 100644
---- /dev/null
-+++ b/slides/common/lgtdslides.cls
-@@ -0,0 +1,18 @@
-+\ProvidesClass{lgtdslides}
-+
-+\LoadClass[utf8x,xcolor={usenames,svgnames}]{beamer}
-+
-+\RequirePackage{lmodern}
-+\RequirePackage{arev}
-+\RequirePackage{tgbonum}
-+\RequirePackage{inconsolata}
-+\RequirePackage[T1]{fontenc}
-+\RequirePackage[fixlanguage]{babelbib}
-+
-+\useoutertheme{infolines}
-+\setbeamertemplate{navigation symbols}{}
-+\setbeamertemplate{bibliography item}[text]
-+\setbeamerfont{footnote}{size=\tiny}
-+
-+\colorlet{fgcolor}{White}
-+\definecolor{BeamerBlue}{RGB}{49,56,172}