diff --git a/Changelog.md b/Changelog.md
new file mode 100644
--- /dev/null
+++ b/Changelog.md
@@ -0,0 +1,119 @@
+# Changelog for tttool
+
+## 1.8.1 (2019-03-30)
+
+ * The SVG patterns created with `./tttool oid-code` and `./tttool oid-codes`
+   now have `id`s that are valid (no spaces).
+ * The release tarball now contains a binary for Linux as well.
+ * The release tarball now contains a copy of [The tttool book](http://tttool.readthedocs.io/de/latest/)
+
+## 1.8 (2018-02-06)
+
+ * If the script for an oid code contains only one line, one can simply write
+
+        house: P(welcome)
+
+   instead of
+
+        house:
+         - P(welcome)
+ * `./tttool oid-table` aligns images on pixel boundaries, so that a naive
+   rastering of the whole page still yields crisp pixels.
+   Thanks to @m7thon for the patch!
+ * The PDF output uses PDF patterns for much smaller PDF files.
+ * The commands `./tttool oid-code` and `./tttool oid-table` can now also
+   produce SVG output with SVG patterns:
+
+   `--image-format SVG` produces SVG with vector squares
+   for the pixels, wihle `--image-format SVG+PNG` produces SVG with a small,
+   repeated pixel graphics in the pattern
+ * Games are now more likely to be properly round-tripped (GH issue #174)
+
+## 1.7 (2017-01-08)
+
+ * `./tttool oid-table` sorts naturally now, so that the sequence is `foo1`
+   `foo2` `foo10`, and not `foo1` `foo10` `foo2`.
+ * Read and write the language field in the GME header (GH issue #105)
+
+## 1.6.1 (2016-04-17)
+
+ * `./tttool assemble`: Do not fail with too many open files
+ * Handle “other” play commands (FFE0, FFE1) even if their argument is not 0,
+   with some crude syntax in the YAML format. The meaning of this argument is
+   not yet understood, volunteers are welcome!
+
+## 1.6 (2016-01-31)
+
+ * Completely re-done option parsing, so there now proper support for short and
+   long options, arbitrary order of options, better error messages and
+   per-command `--help` output.
+
+   **Incompatibility:** Some commands are now called differently. In
+   particular, to generate PNG files with all codes from a YAML file, use
+   `./tttool oid-codes`, not `./tttool oid-code`.
+ * The size of the OID codes written by `./tttool oid-code` is configurable.
+ * The png files written by `./tttool oid-code` and `./tttool oid-codes` store
+   their DPI value, so that importing them into DTP programs is likely to yield
+   the desired result.
+ * New command `tttool oid-table` that prints all OIDs of a given YAML file as
+   a nice and handy table in a PDF file
+ * The output of `./tttool games` is more detailed.
+ * Games are not exported by `tttool export` and assembled by `tttool
+   assemble`. This way, existing Tiptoi products can be modified without losing
+   them.
+ * The “other” play commands (FFE0, FFE1, FB00) are implemented in the parser,
+   printer and serializer, with syntax `P*(..)`, `PA*(..)` and `PA(..)`. These
+   are not interesting to you unless you want to understand existing Tiptoi
+   products.
+ * Support for the “timer” action (FF00) with syntax `T($register,123)`.
+ * `./tttool assemble` will print all errors due to missing audio files, not
+   just the first.
+ * Fix various crashes in corner cases, mostly involving games. Thanks to
+   @ToniMahagoni for reporting these!
+
+## 1.5.1 (2015-11-11)
+
+ * Do not assign object IDs >= 15000, as these are not recognized.
+
+## 1.5 (2015-10-28)
+
+ * New commands FB00 (alternative play range command), FFE0 (alternative
+   play random sample) and FFE1 (alternative play all samples)
+ * New pixel formats -d 1200d and -d 600d,w hich double the size of the
+   dots.
+ * Assign object IDs dependent on project IDs, to avoid overlap.
+ * Fix missing support in tttool play for > and <=
+
+## 1.4 (2015-04-29)
+
+ * The `tttool play` command is greatly enhanced:
+   + Audio samples are actually played (On linux, install `sox`).
+   + You can use the name of your scripts instead of the OID codes.
+   + The prompt supports a persistent history (press ↑).
+   + You can tab-complete your input.
+ * `tttool` knows its own version.
+ * `tttool assemble` warns if the comment field is too long for the GME file.
+
+## 1.3 (2015-03-18)
+
+ * The `tttool play` command now supports jump commands.
+
+## 1.2 (2015-03-08)
+
+ * The `language` fields takes arbitrary strings, which will hopefully be
+   understood by the text-to-speak engine.
+
+## 1.1 (2015-02-15)
+
+ * The yaml files support a `language` field, specifying the default language
+   for the text-to-speech feature.
+ * The `speak` section of the yaml file can have subsections with differing
+   languge settings, to allow multi-language files.
+ * The text-to-speech feature will use either pico2wave or espeak, depending on
+   what is available.
+ * The windows release zipfile now comes with espeak and oggenc, so Windows users
+   can use text-to-speech out of the box.
+
+## 1.0 (2015-01-29)
+
+ * Last release without a changelog
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,7 +3,6 @@
 tip-toi-reveng
 ==============
 
-
 The goal of this project is to understand the file and paper format for the
 Ravensburger TipToi pen. The ultimate goal is that everyone can create their
 own books, with their own sounds.
@@ -15,7 +14,8 @@
 The tool can also be used to generate completely new files from scratch; see
 below for details.
 
-If you want to learn more please have a look into our wiki (https://github.com/entropia/tip-toi-reveng/wiki).
+If you want to learn more please have a look into our wiki
+(https://github.com/entropia/tip-toi-reveng/wiki).
 
 The tttool tool
 ---------------
@@ -65,46 +65,11 @@
 Installation
 ------------
 
-This program is written in Haskell and can be installed on Windows, MacOS or Linux.
-
-For Windows users, we create zipfile containing `tttool`, you can find them in
-the [releases section](https://github.com/entropia/tip-toi-reveng/releases) of
-the github project.
-
-Otherwise, installation from source is not difficult either:
-
- 1. If you have not done so yet, fetch the source code and change to the
-    directory containing the code:
-
-        git clone https://github.com/entropia/tip-toi-reveng.git tttool
-        cd tttool
-
- 2. Install the *Haskell platform*, see http://www.haskell.org/platform/
-    for details for your system. Users of Debian or Ubuntu simply run
-
-        apt-get install haskell-platform
-
- 3. Install the development packages for ncurses, i.e.
-
-        apt-get install libncurses5-dev
-
- 4. Install the Haskell dependencies. The Haskell platform comes with a tool
-    called `cabal`, and you should run the two commands
-
-        cabal update
-        cabal install --only-dependencies
-
- 5. Now you can build the program using
-
-        cabal install --bindir=.
-
- 6. At this point, `tttool` should be ready to go. If you run
-
-        ./tttool
-
-    you should see the list of commands shown above.
+We release `tttool` for Windows and Linux users as a zipfile. You can find them
+in the [releases section](https://github.com/entropia/tip-toi-reveng/releases)
+of the GitHub project.
 
-If you have any problems, you can [report an issue via GitHub](https://github.com/entropia/tip-toi-reveng/issues).
+See `Building.md` for instructions on how to build `tttool` from source.
 
 Building your own gme files
 ---------------------------
@@ -174,7 +139,7 @@
 ----------------------------------
 
  * [`oid-decoder.html`](http://htmlpreview.github.io/?https://github.com/entropia/tip-toi-reveng/blob/master/oid-decoder.html) allows you to manually decode an OID image.
- * `scripts/update.sh` downloads all gme files from the Ravensburger server (requires perl and the [XML::Simple](http://search.cpan.org/~grantm/XML-Simple/) module).  
+ * `scripts/update.sh` downloads all gme files from the Ravensburger server (requires perl and the [XML::Simple](http://search.cpan.org/~grantm/XML-Simple/) module).
 
    Instead of downloading all of them, you can conveniently browse them at <http://tiptoi.vakat.de/>, a service provided by Falko Oldenburg <tiptoi@vakat.de>.
  * `gameanalyse.c` and `libtiptoi.c` is an alternative tool to investigate gme
diff --git a/src/Commands.hs b/src/Commands.hs
--- a/src/Commands.hs
+++ b/src/Commands.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE CPP, RecordWildCards, TupleSections #-}
+{-# LANGUAGE LambdaCase #-}
 module Commands where
 
 import qualified Data.ByteString.Lazy as B
@@ -12,7 +13,6 @@
 import Data.Bits
 import Data.List
 import Data.Either
-import Data.Functor
 import Data.Maybe
 import Data.Function
 import Data.Ord
@@ -63,7 +63,9 @@
             map (1,) ttBinaries1 ++
             map (2,) ttBinaries2 ++
             map (3,) ttBinaries3 ++
-            map (4,) ttBinaries4
+            map (4,) ttBinaries4 ++
+            map (5,) ttBinaries5 ++
+            map (6,) ttBinaries6
 
     printf "Binary Table entries: %d\n" (length binaries)
 
@@ -115,11 +117,14 @@
         (length (filter (isNothing . snd) st)) (length st)
     printf "Audio table entries: %d\n" (length ttAudioFiles)
     when ttAudioFilesDoubles $ printf "Audio table repeated twice\n"
-    printf "Binary tables entries: %d/%d/%d/%d\n"
+    printf "Binary tables entries: %d/%d/%d\n"
         (length ttBinaries1)
         (length ttBinaries2)
+        (length ttBinaries6)
+    printf "Single binary table entries: %d/%d/%d\n"
         (length ttBinaries3)
         (length ttBinaries4)
+        (length ttBinaries5)
     for_ ttSpecialOIDs $ \(oid1, oid2) ->
         printf "Special OIDs: %d, %d\n" oid1 oid2
     printf "Checksum found 0x%08X, calculated 0x%08X\n" ttChecksum ttChecksumCalc
@@ -154,7 +159,7 @@
 explain file = do
     bytes <- B.readFile file
     let (tt,segments) = parseTipToiFile bytes
-    forM_ (addHoles segments) $ \e -> case e of
+    forM_ (addHoles segments) $ \case
         Left (o,l) -> do
             printSegment (o,l,["-- unknown --"])
             printExtract bytes o l
@@ -163,6 +168,7 @@
             mapM_ printSegment ss
             printExtract bytes o l
             putStrLn ""
+        Right [] -> error "empty list of errors?"
 
 printExtract :: B.ByteString -> Offset -> Word32 -> IO ()
 printExtract b o 0 = return ()
@@ -302,7 +308,8 @@
     forM_  codes $ \(s,c) -> do
         let filename = printf "oid-%d-%s.%s" (ttProductId tt) s (suffixOf format)
         let title = printf "%s (product %d code %d)" s (ttProductId tt) c
-        writeImage format conf title c filename
+        let url   = printf "%s-%d" s c
+        writeImage format conf title url c filename
 
 writeImagesForCodes :: Bool -> Conf -> [Word16] -> IO ()
 writeImagesForCodes False conf codes =
@@ -310,40 +317,42 @@
         let format = fromMaybe PNG (cImageFormat conf)
         let filename = printf "oid-%d.%s" c (suffixOf format)
         let title = printf "code %d" c
-        writeImage format conf title c filename
+        let url   = printf "%d" c
+        writeImage format conf title url c filename
 writeImagesForCodes True conf codes =
     forM_ codes $ \r -> do
         let format = fromMaybe PNG (cImageFormat conf)
         let filename = printf "oid-raw-%d.%s" r (suffixOf format)
         let title = printf "raw code %d" r
+        let url   = printf "raw-%d" r
         printf "Writing %s... (raw code %d)\n" filename r
-        writeRawImage format conf title r filename
+        writeRawImage format conf title url r filename
 
-writeImage :: ImageFormat -> Conf -> String -> Word16 -> FilePath -> IO ()
-writeImage format conf title c filename =
+writeImage :: ImageFormat -> Conf -> String -> String -> Word16 -> FilePath -> IO ()
+writeImage format conf title url c filename =
     case code2RawCode c of
         Nothing -> printf "Skipping %s, code %d not known.\n" filename c
         Just r -> do
             printf "Writing %s.. (Code %d, raw code %d)\n" filename c r
-            writeRawImage format conf title r filename
+            writeRawImage format conf title url r filename
 
-writeRawImage :: ImageFormat -> Conf -> String -> Word16 -> FilePath -> IO ()
-writeRawImage PNG conf title raw_code filename =
+writeRawImage :: ImageFormat -> Conf -> String -> String -> Word16 -> FilePath -> IO ()
+writeRawImage PNG conf title _url raw_code filename =
     writeRawPNG w h conf title raw_code filename
   where
     (w,h) = cCodeDimPixels conf
-writeRawImage (SVG usePNG) conf title raw_code filename =
-    writeRawSVG conf usePNG title raw_code filename
-writeRawImage _ _ _ _ _ =
+writeRawImage (SVG usePNG) conf _title url raw_code filename =
+    writeRawSVG conf usePNG url raw_code filename
+writeRawImage _ _ _ _ _ _ =
     hPutStrLn stderr "this command only supports PNG and SVG" >> exitFailure
 
 cCodeDimPixels :: Conf -> (Int, Int)
 cCodeDimPixels conf = (w',h')
   where
     (w,h) = cCodeDim conf
-    -- (Roughly) 25mm per inch
-    w' = (w * cDPI conf) `div` 25
-    h' = (h * cDPI conf) `div` 25
+    -- 25.4mm per inch
+    w' = round $ fromIntegral (w * cDPI conf) / 25.4
+    h' = round $ fromIntegral (h * cDPI conf) / 25.4
 
 readTransscriptFile :: Maybe FilePath -> IO Transscript
 readTransscriptFile Nothing = return M.empty
diff --git a/src/GMEParser.hs b/src/GMEParser.hs
--- a/src/GMEParser.hs
+++ b/src/GMEParser.hs
@@ -7,17 +7,17 @@
 import qualified Data.Binary.Get as G
 import Text.Printf
 import Data.List
-import Data.Functor
 import Control.Applicative (Applicative, (<*>))
 import Data.Maybe
 import Control.Monad
+import Control.Monad.Fail (MonadFail)
+import qualified Control.Monad.Fail 
 import Control.Monad.Writer.Strict
 import Control.Monad.State.Strict
 import Control.Monad.Reader
 import Control.Monad.RWS.Strict
 import Control.Exception
 import Control.Arrow
-import Debug.Trace
 
 import Types
 import Constants
@@ -28,15 +28,17 @@
 newtype SGet a = SGet (RWS B.ByteString [Segment] Word32  a)
     deriving (Functor, Applicative, Monad)
 
+instance MonadFail SGet where fail = error
+
 liftGet :: G.Get a -> SGet a
 liftGet act = SGet $ do
     offset <- get
     bytes <- ask
-    when (offset > fromIntegral (B.length bytes)) $ do
+    when (offset > fromIntegral (B.length bytes)) $
         fail $ printf "Trying to read from offset 0x%08X, which is after the end of the file!" offset
     let (a, _, i) = G.runGetState act (B.drop (fromIntegral offset) bytes) 0
     put (offset + fromIntegral i)
-    return $ a
+    return a
 
 jumpTo :: Offset -> SGet ()
 jumpTo offset = SGet (put offset)
@@ -416,17 +418,21 @@
     ttLang <- getBSNul
 
     jumpTo 0x0071
-    ttWelcome <- indirection "initial play lists" $ getPlayListList
+    ttWelcome <- indirection "initial play lists" getPlayListList
 
     jumpTo 0x0090
     ttBinaries1 <- fromMaybe [] <$> maybeIndirection "Binaries 1" getBinaries
     ttSpecialOIDs <- maybeIndirection "special symbols" getSpecials
-    ttBinaries2 <- fromMaybe [] <$> maybeIndirection "Binaries 1" getBinaries
+    ttBinaries2 <- fromMaybe [] <$> maybeIndirection "Binaries 2" getBinaries
 
     jumpTo 0x00A0
     ttBinaries3 <- fromMaybe [] <$> maybeIndirection "Single binary 1" getBinaries
     getWord32 --ignored
     ttBinaries4 <- fromMaybe [] <$> maybeIndirection "Single binary 2" getBinaries
+
+    jumpTo 0x00C8
+    ttBinaries5 <- fromMaybe [] <$> maybeIndirection "Single binary 3" getBinaries
+    ttBinaries6 <- fromMaybe [] <$> maybeIndirection "Binaries 3" getBinaries
 
     ttChecksum <- getChecksum
     ttChecksumCalc <- calcChecksum
diff --git a/src/GMEWriter.hs b/src/GMEWriter.hs
--- a/src/GMEWriter.hs
+++ b/src/GMEWriter.hs
@@ -10,7 +10,6 @@
 import qualified Data.Map as M
 import Control.Monad.Writer.Lazy
 import Control.Monad.State.Lazy
-import Debug.Trace
 
 import Types
 import Constants
diff --git a/src/KnownCodes.hs b/src/KnownCodes.hs
--- a/src/KnownCodes.hs
+++ b/src/KnownCodes.hs
@@ -1,5 +1,4 @@
 {-# LANGUAGE QuasiQuotes #-}
-
 module KnownCodes where
 
 import Data.Word
diff --git a/src/OidCode.hs b/src/OidCode.hs
--- a/src/OidCode.hs
+++ b/src/OidCode.hs
@@ -4,15 +4,12 @@
 
 import Data.Word
 import Data.Bits
-import Data.Functor
 import qualified Data.ByteString.Lazy as B
-import Data.Monoid
 import Control.Monad
 import Codec.Picture
 import Codec.Picture.Types
 import Codec.Picture.Metadata
 import Control.Monad.ST
-import Control.Applicative
 import Data.Vector.Storable.ByteString
 import qualified Data.ByteString.Base64.Lazy
 import qualified Data.Text as T
@@ -99,6 +96,7 @@
     value 1 = at (-2,2)  plain
     value 2 = at (-2,-2) plain
     value 3 = at (2,-2)  plain
+    value _ = error "value: unexpected param"
     special = at (3,0)   plain
 
     position ((n,m), p) = at (n*12, m*12) p
@@ -169,6 +167,7 @@
     value 1 = at (-s, s) centeredDot
     value 2 = at (-s,-s) centeredDot
     value 3 = at ( s,-s) centeredDot
+    value _ = error "value: unexpected param"
     special = at (ss,0)  centeredDot
 
     position ((n,m), p) = at (n*spacePerPoint, m*spacePerPoint) p
diff --git a/src/OidTableSVG.hs b/src/OidTableSVG.hs
--- a/src/OidTableSVG.hs
+++ b/src/OidTableSVG.hs
@@ -2,7 +2,6 @@
 
 import Data.Word
 import qualified Data.ByteString.Lazy as LB
-import Control.Monad hiding (forM_)
 import Data.Foldable (forM_)
 import Text.Printf
 import Control.Arrow ((***))
diff --git a/src/RangeParser.hs b/src/RangeParser.hs
--- a/src/RangeParser.hs
+++ b/src/RangeParser.hs
@@ -1,7 +1,6 @@
 module RangeParser (parseRange) where
 
 import Text.Printf
-import Data.Functor
 import Control.Monad
 import Text.Parsec hiding (Line, lookAhead, spaces)
 import Text.Parsec.String
diff --git a/src/TipToiYaml.hs b/src/TipToiYaml.hs
--- a/src/TipToiYaml.hs
+++ b/src/TipToiYaml.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE RecordWildCards, DeriveGeneric, CPP, TupleSections, TemplateHaskell #-}
+{-# LANGUAGE RecordWildCards, DeriveGeneric, CPP, TupleSections #-}
 
 module TipToiYaml
     ( tt2ttYaml, ttYaml2tt
@@ -17,14 +17,12 @@
 import Text.Printf
 import Data.Char
 import Data.Either
-import Data.Functor
 import Data.Maybe
 import Control.Monad
 import System.Directory
 import qualified Data.Map as M
 import qualified Data.Set as S
 import qualified Data.Vector as V
-import Control.Monad.Writer.Strict
 #if MIN_VERSION_time(1,5,0)
 import Data.Time.Format (defaultTimeLocale)
 #else
@@ -33,7 +31,6 @@
 import Data.Time (getCurrentTime, formatTime)
 import Data.Yaml hiding ((.=), Parser)
 import Data.Aeson.Types hiding ((.=), Parser)
-import Data.Aeson.TH
 import Text.Parsec hiding (Line, lookAhead, spaces)
 import Text.Parsec.String
 import qualified Text.Parsec as P
@@ -256,6 +253,7 @@
         , gyExtraPlayLists           :: [PlayListListYaml]
         }
     | Game253Yaml
+    deriving Generic
 
 data SubGameYaml = SubGameYaml
     { sgUnknown :: String
@@ -264,10 +262,23 @@
     , sgOids3 :: OIDListYaml
     , sgPlaylist :: [PlayListListYaml]
     }
+    deriving Generic
 
 
-$(deriveJSON gameYamlOptions ''GameYaml)
-$(deriveJSON gameYamlOptions ''SubGameYaml)
+instance FromJSON GameYaml where
+    parseJSON = genericParseJSON gameYamlOptions
+instance ToJSON GameYaml where
+    toJSON = genericToJSON gameYamlOptions
+#if MIN_VERSION_aeson(0,10,0)
+    toEncoding = genericToEncoding gameYamlOptions
+#endif
+instance FromJSON SubGameYaml where
+    parseJSON = genericParseJSON gameYamlOptions
+instance ToJSON SubGameYaml where
+    toJSON = genericToJSON gameYamlOptions
+#if MIN_VERSION_aeson(0,10,0)
+    toEncoding = genericToEncoding gameYamlOptions
+#endif
 
 tipToiYamlOptions = defaultOptions
     { fieldLabelModifier = map fix . map toLower . drop 3
@@ -860,6 +871,8 @@
         , ttBinaries2 = []
         , ttBinaries3 = []
         , ttBinaries4 = []
+        , ttBinaries5 = []
+        , ttBinaries6 = []
         , ttSpecialOIDs = Nothing
         }, totalMap)
 
diff --git a/src/Types.hs b/src/Types.hs
--- a/src/Types.hs
+++ b/src/Types.hs
@@ -83,6 +83,8 @@
     , ttBinaries2 :: [(B.ByteString, B.ByteString)]
     , ttBinaries3 :: [(B.ByteString, B.ByteString)]
     , ttBinaries4 :: [(B.ByteString, B.ByteString)]
+    , ttBinaries5 :: [(B.ByteString, B.ByteString)]
+    , ttBinaries6 :: [(B.ByteString, B.ByteString)]
     , ttSpecialOIDs :: Maybe (Word16, Word16)
     , ttChecksum :: Word32
     , ttChecksumCalc :: Word32
diff --git a/src/Utils.hs b/src/Utils.hs
--- a/src/Utils.hs
+++ b/src/Utils.hs
@@ -1,6 +1,5 @@
 module Utils where
 
-import Control.Applicative
 import Control.Monad (forM, forM_)
 import Data.Traversable (for)
 
diff --git a/src/tttool.hs b/src/tttool.hs
--- a/src/tttool.hs
+++ b/src/tttool.hs
@@ -4,7 +4,6 @@
 import Numeric
 import Data.List (intercalate)
 import Options.Applicative.Help.Chunk
-import Data.Monoid
 import Data.Maybe
 import Data.Foldable (asum)
 import Data.Char (toLower)
diff --git a/tttool.cabal b/tttool.cabal
--- a/tttool.cabal
+++ b/tttool.cabal
@@ -1,30 +1,23 @@
 name:                tttool
-version:             1.8
+version:             1.8.1
 synopsis:            Working with files for the Tiptoi® pen
 description:         The Ravensburger Tiptoi® pen is programmed via special
                      files. Their file format has been reverse engineered; this
                      is a tool to analyse and create such files.
+                     .
+                     For more user-facing documentation, see
+                     <http://tttool.entropia.de/> (in German).
 category:            Reverse Engineering
 homepage:            https://github.com/entropia/tip-toi-reveng
 license:             MIT
 license-file:        LICENSE
 author:              Joachim Breitner
 maintainer:          mail@joachim-breitner.de
-copyright:           2013-2017 Joachim Breitner
+copyright:           2013-2019 Joachim Breitner
 build-type:          Simple
-extra-source-files:  README.md
+extra-source-files:  README.md Changelog.md
 cabal-version:       >=1.10
 
-flag old-locale
- description:
-   If false then depend on time >= 1.5.
-   .
-   If true then depend on time < 1.5 together with old-locale.
- default: False
-
-Flag bytestring_has_builder
-  default: True
-
 executable tttool
   main-is:             tttool.hs
   other-modules:
@@ -51,53 +44,34 @@
     Commands,
     Utils
 
-  build-depends:
-    base        >= 4.5 && < 4.11,
-    binary      >= 0.5 && < 0.9,
-    containers  == 0.4.*   ||  == 0.5.*,
-    directory   >= 1.2 && < 1.4,
-    executable-path == 0.0.*,
-    filepath    == 1.3.*   ||  == 1.4.*,
-    template-haskell >= 2.7 && < 2.13,
-
-    JuicyPixels >= 3.2.5   &&   < 3.3,
-    aeson       >= 0.7     &&   < 1.3,
-    hashable    == 1.2.*,
-    haskeline   == 0.7.*,
-    mtl         == 2.1.*   ||  == 2.2.*,
-    parsec      == 3.1.*,
-    process     >= 1.1      &&   < 1.7,
-    random      >= 1.0      &&   < 1.2,
-    vector      >= 0.10     &&   < 0.13,
-    yaml        == 0.8.*,
-    HPDF        >= 1.4.10   && < 1.5,
-    split       == 0.2.*,
-    optparse-applicative >= 0.13 && < 0.15,
-    spool       == 0.1.*,
-    zlib        >= 0.5      && < 0.7,
-    natural-sort >= 0.1     && < 0.2,
-    blaze-svg   == 0.3.*,
-    base64-bytestring == 1.0.*,
-    text        == 1.2.*
-
-  if impl(ghc < 7.5)
-    build-depends: ghc-prim
-
-  ghc-options: -fcontext-stack=42
-
-  if flag(old-locale)
-    build-depends: time == 1.4.*, old-locale
-  else
-    build-depends: time >= 1.5 && < 1.9
-
-  if flag(bytestring_has_builder)
-    build-depends:
-      bytestring >= 0.10.4 && < 0.11
-  else
-    build-depends:
-      bytestring >= 0.10 && < 0.10.4,
-      bytestring-builder >= 0.10.4.1.1
-
+  build-depends: aeson >= 0.7 && < 1.5
+  build-depends: base >= 4.9 && < 4.13
+  build-depends: base64-bytestring == 1.0.*
+  build-depends: binary >= 0.5 && < 0.9
+  build-depends: blaze-svg == 0.3.*
+  build-depends: bytestring >= 0.10.4 && < 0.11
+  build-depends: containers >= 0.4 && <0.7
+  build-depends: directory >= 1.2 && < 1.4
+  build-depends: executable-path == 0.0.*
+  build-depends: filepath == 1.3.* || == 1.4.*
+  build-depends: hashable == 1.2.*
+  build-depends: haskeline == 0.7.*
+  build-depends: HPDF >= 1.4.10 && < 1.5
+  build-depends: JuicyPixels >= 3.2.5 && < 3.4
+  build-depends: mtl == 2.2.*
+  build-depends: natural-sort >= 0.1 && < 0.2
+  build-depends: optparse-applicative >= 0.13 && < 0.15
+  build-depends: parsec == 3.1.*
+  build-depends: process >= 1.1 && < 1.7
+  build-depends: random >= 1.0 && < 1.2
+  build-depends: split == 0.2.*
+  build-depends: spool == 0.1.*
+  build-depends: template-haskell >= 2.7 && < 2.15
+  build-depends: text == 1.2.*
+  build-depends: time >= 1.5 && < 1.9
+  build-depends: vector >= 0.10 && < 0.13
+  build-depends: yaml >= 0.8 && < 0.12
+  build-depends: zlib >= 0.5 && < 0.7
 
   hs-source-dirs:      src
   default-language:    Haskell2010
