diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,37 @@
+Version 0.9 released 29 Feb 2012
+
+*   Gitit now uses the latest pandoc (1.9.x) and happstack-server (6.6.x),
+    and compiles on ghc 7.4.1.
+
+*   Added Docx, AsciiDoc, and DZSlides as export formats.
+
+*   HTML slide show exports are now "self-contained":  they embed all
+    required js, css, and images, so they can be used offline.
+
+*   Allow spaces in usernames (Juraj Hercek).
+
+*   Improve PDF/RTF exports containing images in the wiki.
+    Wikidata paths are translated to absolute ones, so pandoc/pdflatex
+    can find them (Juraj Hercek).
+
+*   Protect against XSS in slide show exports.  Previous versions
+    of gitit sanitized wikipages, but not HTML slide shows.
+
+*   Table of contents is now in a div with ID `TOC`, so it can
+    be styled.
+
+*   Removed letter and word spacing from print.css.
+
+*   Added s5 directory to static.  This is needed by pandoc 1.9.
+
+*   Updated Interwiki plugin (gwern).
+
+*   Added `fromEntities` to `Types`, since `decodeCharacterReferences`
+    is no longer exported from Pandoc.  Added dependency on tagsoup.
+
+*   Provided `FromReqURI` instance for `[String]`, since
+    this is not automatic with recent happstack.
+
 Version 0.8.1 released 02 Sep 2011
 
 *   Support mathjax as a math option.
diff --git a/Network/Gitit.hs b/Network/Gitit.hs
--- a/Network/Gitit.hs
+++ b/Network/Gitit.hs
@@ -173,9 +173,9 @@
   , dir "_go"       goToPage
   , dir "_search"   searchResults
   , dir "_upload"   $  do guard =<< return . uploadsAllowed =<< getConfig
-                          msum [ methodOnly GET  >> authenticate ForModify uploadForm
-                                 , methodOnly POST >> authenticate ForModify uploadFile ]
-  , dir "_random"   $ methodOnly GET  >> randomPage
+                          msum [ method GET  >> authenticate ForModify uploadForm
+                                 , method POST >> authenticate ForModify uploadFile ]
+  , dir "_random"   $ method GET  >> randomPage
   , dir "_index"    indexPage
   , dir "_feed"     feedHandler
   , dir "_category" categoryPage
@@ -193,18 +193,18 @@
       , guardPath isSourceCode >> showFileDiff ]
   , dir "_discuss" discussPage
   , dir "_delete" $ msum
-      [ methodOnly GET  >>
+      [ method GET  >>
           authenticate ForModify (unlessNoDelete confirmDelete showPage)
-      , methodOnly POST >>
+      , method POST >>
           authenticate ForModify (unlessNoDelete deletePage showPage) ]
   , dir "_preview" preview
   , guardIndex >> indexPage
   , guardCommand "export" >> exportPage
-  , methodOnly POST >> guardCommand "cancel" >> showPage
-  , methodOnly POST >> guardCommand "update" >>
+  , method POST >> guardCommand "cancel" >> showPage
+  , method POST >> guardCommand "update" >>
       authenticate ForModify (unlessNoEdit updatePage showPage)
   , showPage
-  , guardPath isSourceCode >> methodOnly GET >> showHighlightedSource
+  , guardPath isSourceCode >> method GET >> showHighlightedSource
   , handleAny
   , notFound =<< (guardPath isPage >> createPage)
   ]
diff --git a/Network/Gitit/Authentication.hs b/Network/Gitit/Authentication.hs
--- a/Network/Gitit/Authentication.hs
+++ b/Network/Gitit/Authentication.hs
@@ -264,7 +264,8 @@
                  -> Params
                  -> GititServerPart (Either [String] (String,String,String))
 sharedValidation validationType params = do
-  let isValidUsername u = length u >= 3 && all isAlphaNum u
+  let isValidUsernameChar c = isAlphaNum c || c == ' '
+  let isValidUsername u = length u >= 3 && all isValidUsernameChar u
   let isValidPassword pw = length pw >= 6 && not (all isAlpha pw)
   let accessCode = pAccessCode params
   let uname = pUsername params
@@ -404,15 +405,15 @@
 
 formAuthHandlers :: [Handler]
 formAuthHandlers =
-  [ dir "_register"  $ methodSP GET  registerUserForm
-  , dir "_register"  $ methodSP POST $ withData registerUser
-  , dir "_login"     $ methodSP GET  loginUserForm
-  , dir "_login"     $ methodSP POST $ withData loginUser
-  , dir "_logout"    $ methodSP GET  $ withData logoutUser
-  , dir "_resetPassword"   $ methodSP GET  $ withData resetPasswordRequestForm
-  , dir "_resetPassword"   $ methodSP POST $ withData resetPasswordRequest
-  , dir "_doResetPassword" $ methodSP GET  $ withData resetPassword
-  , dir "_doResetPassword" $ methodSP POST $ withData doResetPassword
+  [ dir "_register"  $ method GET >> registerUserForm
+  , dir "_register"  $ method POST >> withData registerUser
+  , dir "_login"     $ method GET  >> loginUserForm
+  , dir "_login"     $ method POST >> withData loginUser
+  , dir "_logout"    $ method GET  >> withData logoutUser
+  , dir "_resetPassword"   $ method GET  >> withData resetPasswordRequestForm
+  , dir "_resetPassword"   $ method POST >> withData resetPasswordRequest
+  , dir "_doResetPassword" $ method GET  >> withData resetPassword
+  , dir "_doResetPassword" $ method POST >> withData doResetPassword
   , dir "_user" currentUser
   ]
 
@@ -486,7 +487,7 @@
 
 rpxAuthHandlers :: [Handler]
 rpxAuthHandlers =
-  [ dir "_logout" $ methodSP GET $ withData logoutUser
+  [ dir "_logout" $ method GET >> withData logoutUser
   , dir "_login"  $ withData loginRPXUser
   , dir "_user" currentUser ]
 
diff --git a/Network/Gitit/ContentTransformer.hs b/Network/Gitit/ContentTransformer.hs
--- a/Network/Gitit/ContentTransformer.hs
+++ b/Network/Gitit/ContentTransformer.hs
@@ -89,6 +89,7 @@
 import Text.Pandoc hiding (MathML, WebTeX, MathJax)
 import Text.Pandoc.Shared (ObfuscationMethod(..))
 import Text.XHtml hiding ( (</>), dir, method, password, rev )
+import Text.Blaze.Renderer.String as Blaze ( renderHtml )
 import qualified Data.Text as T
 import qualified Data.ByteString as S (concat)
 import qualified Data.ByteString.Lazy as L (toChunks, fromChunks)
@@ -342,7 +343,7 @@
            (if xssSanitize cfg then sanitizeBalance else id) . T.pack $
            writeHtmlString defaultWriterOptions{
                         writerStandalone = True
-                      , writerTemplate = "$if(toc)$\n$toc$\n$endif$\n$body$"
+                      , writerTemplate = "$if(toc)$<div id=\"TOC\">\n$toc$\n</div>\n$endif$\n$body$"
                       , writerHTMLMathMethod =
                             case mathMethod cfg of
                                  MathML -> Pandoc.MathML Nothing
@@ -361,12 +362,12 @@
 highlightSource Nothing = mzero
 highlightSource (Just source) = do
   file <- getFileName
-  let formatOpts = [OptNumberLines, OptLineAnchors]
+  let formatOpts = defaultFormatOpts { numberLines = True, lineAnchors = True }
   case languagesByExtension $ takeExtension file of
         []    -> mzero
-        (l:_) -> case highlightAs l (filter (/='\r') source) of
-                   Left _       -> mzero
-                   Right res    -> return $ formatAsXHtml formatOpts l $! res
+        (l:_) -> return $ primHtml $ Blaze.renderHtml
+                        $ formatHtmlBlock formatOpts
+                        $! highlightAs l $ filter (/='\r') source
 
 --
 -- Plugin combinators
@@ -536,10 +537,6 @@
                Cite _ xs               -> concatMap go xs
                Code _ s                -> s
                Space                   -> " "
-               EmDash                  -> "---"
-               EnDash                  -> "--"
-               Apostrophe              -> "'"
-               Ellipses                -> "..."
                LineBreak               -> " "
                Math DisplayMath s      -> "$$" ++ s ++ "$$"
                Math InlineMath s       -> "$" ++ s ++ "$"
diff --git a/Network/Gitit/Export.hs b/Network/Gitit/Export.hs
--- a/Network/Gitit/Export.hs
+++ b/Network/Gitit/Export.hs
@@ -22,7 +22,7 @@
 module Network.Gitit.Export ( exportFormats ) where
 import Text.Pandoc hiding (HTMLMathMethod(..))
 import qualified Text.Pandoc as Pandoc
-import Text.Pandoc.S5 (s5HeaderIncludes)
+import Text.Pandoc.SelfContained as SelfContained
 import Text.Pandoc.Shared (escapeStringUsing, readDataFile)
 import Network.Gitit.Server
 import Network.Gitit.Framework (pathForPage, getWikiBase)
@@ -36,7 +36,7 @@
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as L
 import Data.ByteString.Lazy.UTF8 (fromString)
-import System.FilePath ((<.>), (</>))
+import System.FilePath ((<.>), (</>), takeDirectory)
 import Control.Exception (throwIO)
 import System.Environment (getEnvironment)
 import System.Exit (ExitCode(..))
@@ -44,6 +44,9 @@
 import System.Directory (getCurrentDirectory, setCurrentDirectory, removeFile)
 import System.Process (runProcess, waitForProcess)
 import Codec.Binary.UTF8.String (encodeString)
+import Text.HTML.SanitizeXSS
+import qualified Data.Text as T
+import Data.List (isPrefixOf)
 
 defaultRespOptions :: WriterOptions
 defaultRespOptions = defaultWriterOptions { writerStandalone = True }
@@ -68,19 +71,77 @@
   template <- case template' of
                   Right t  -> return t
                   Left e   -> liftIO $ throwIO e
-  doc' <- if ext `elem` ["odt","pdf","epub"]
-             then fixURLs doc
+  doc' <- if ext `elem` ["odt","pdf","epub","docx","rtf"]
+             then fixURLs page doc
              else return doc
+  doc'' <- if ext == "rtf"
+              then liftIO $ bottomUpM rtfEmbedImage doc'
+              else return doc'
   respond mimetype ext (fn opts{writerTemplate = template
                                ,writerSourceDirectory = repositoryPath cfg
                                ,writerUserDataDir = pandocUserData cfg})
-          page doc'
+          page doc''
 
 respondS :: String -> String -> String -> (WriterOptions -> Pandoc -> String)
           -> WriterOptions -> String -> Pandoc -> Handler
 respondS templ mimetype ext fn =
   respondX templ mimetype ext (\o d -> return $ fromString $ fn o d)
 
+respondSlides :: String -> HTMLSlideVariant -> String -> Pandoc -> Handler
+respondSlides templ slideVariant page doc = do
+    cfg <- getConfig
+    base' <- getWikiBase
+    let math = case mathMethod cfg of
+                   MathML       -> Pandoc.MathML Nothing
+                   WebTeX u     -> Pandoc.WebTeX u
+                   JsMathScript -> Pandoc.JsMath
+                                    (Just $ base' ++ "/js/jsMath/easy/load.js")
+                   _            -> Pandoc.PlainMath
+    let opts' = defaultRespOptions {
+                     writerSlideVariant = slideVariant
+                    ,writerIncremental = True
+                    ,writerHtml5 = templ == "dzslides"
+                    ,writerHTMLMathMethod = math}
+    -- We sanitize the body only, to protect against XSS attacks.
+    -- (Sanitizing the whole HTML page would strip out javascript
+    -- needed for the slides.)  We then pass the body into the
+    -- slide template using the 'body' variable.
+    Pandoc meta blocks <- fixURLs page doc
+    let body' = writeHtmlString opts'{writerStandalone = False}
+                   (Pandoc meta blocks) -- just body
+    let body'' = T.unpack
+               $ (if xssSanitize cfg then sanitizeBalance else id)
+               $ T.pack body'
+    variables' <- if mathMethod cfg == MathML
+                     then do
+                        s <- liftIO $ readDataFile (pandocUserData cfg) $
+                                  "data"</>"MathMLinHTML.js"
+                        return [("mathml-script", s)]
+                     else return []
+    template' <- liftIO $ getDefaultTemplate (pandocUserData cfg) templ
+    template <- case template' of
+                     Right t  -> return t
+                     Left e   -> liftIO $ throwIO e
+    dzcore <- if templ == "dzslides"
+                  then do
+                    dztempl <- liftIO $ readDataFile (pandocUserData cfg)
+                           $ "dzslides" </> "template.html"
+                    return $ unlines
+                        $ dropWhile (not . isPrefixOf "<!-- {{{{ dzslides core")
+                        $ lines dztempl
+                  else return ""
+    let h = writeHtmlString opts'{
+                writerVariables =
+                  ("body",body''):("dzslides-core",dzcore):variables'
+               ,writerTemplate = template
+               ,writerSourceDirectory = repositoryPath cfg
+               ,writerUserDataDir = pandocUserData cfg
+               } (Pandoc meta [])
+    h' <- liftIO $ makeSelfContained (pandocUserData cfg) h
+    ok . setContentType "text/html;charset=UTF-8" .
+      -- (setFilename (page ++ ".html")) .
+      toResponseBS B.empty $ fromString h'
+
 respondLaTeX :: String -> Pandoc -> Handler
 respondLaTeX = respondS "latex" "application/x-latex" "tex"
   writeLaTeX defaultRespOptions
@@ -110,55 +171,6 @@
 respondMan = respondS "man" "text/plain; charset=utf-8" ""
   writeMan defaultRespOptions
 
-respondS5 :: String -> Pandoc -> Handler
-respondS5 pg doc = do
-  cfg <- getConfig
-  base' <- getWikiBase
-  inc <- liftIO $ s5HeaderIncludes (pandocUserData cfg)
-  let math = case mathMethod cfg of
-                 MathML       -> Pandoc.MathML Nothing
-                 WebTeX u     -> Pandoc.WebTeX u
-                 JsMathScript -> Pandoc.JsMath
-                                  (Just $ base' ++ "/js/jsMath/easy/load.js")
-                 _            -> Pandoc.PlainMath
-  variables' <- if mathMethod cfg == MathML
-                   then do
-                      s <- liftIO $ readDataFile (pandocUserData cfg) $
-                                "data"</>"MathMLinHTML.js"
-                      return [("mathml-script", s),("s5includes",inc)]
-                   else return [("s5includes",inc)]
-  respondS "s5" "text/html; charset=utf-8" ""
-    writeHtmlString
-    defaultRespOptions{writerSlideVariant = S5Slides
-                      ,writerIncremental = True
-                      ,writerVariables = variables'
-                      ,writerHTMLMathMethod = math}
-    pg doc
-
-respondSlidy :: String -> Pandoc -> Handler
-respondSlidy pg doc = do
-  cfg <- getConfig
-  base' <- getWikiBase
-  let math = case mathMethod cfg of
-                 MathML       -> Pandoc.MathML Nothing
-                 WebTeX u     -> Pandoc.WebTeX u
-                 JsMathScript -> Pandoc.JsMath
-                                  (Just $ base' ++ "/js/jsMath/easy/load.js")
-                 _            -> Pandoc.PlainMath
-  variables' <- if mathMethod cfg == MathML
-                   then do
-                      s <- liftIO $ readDataFile (pandocUserData cfg) $
-                                "data"</>"MathMLinHTML.js"
-                      return [("mathml-script", s)]
-                   else return []
-  respondS "slidy" "text/html; charset=utf-8" ""
-    writeHtmlString
-    defaultRespOptions{writerSlideVariant = SlidySlides
-                      ,writerIncremental = True
-                      ,writerHTMLMathMethod = math
-                      ,writerVariables = variables'}
-    pg doc
-
 respondTexinfo :: String -> Pandoc -> Handler
 respondTexinfo = respondS "texinfo" "application/x-texinfo" "texi"
   writeTexinfo defaultRespOptions
@@ -175,6 +187,10 @@
 respondTextile = respondS "textile" "text/plain; charset=utf-8" ""
   writeTextile defaultRespOptions
 
+respondAsciiDoc :: String -> Pandoc -> Handler
+respondAsciiDoc = respondS "asciidoc" "text/plain; charset=utf-8" ""
+  writeAsciiDoc defaultRespOptions
+
 respondMediaWiki :: String -> Pandoc -> Handler
 respondMediaWiki = respondS "mediawiki" "text/plain; charset=utf-8" ""
   writeMediaWiki defaultRespOptions
@@ -184,10 +200,15 @@
               "odt" (writeODT Nothing) defaultRespOptions
 
 respondEPUB :: String -> Pandoc -> Handler
-respondEPUB = respondX "html" "application/epub+zip" "epub" (writeEPUB Nothing)
+respondEPUB = respondX "html" "application/epub+zip" "epub" (writeEPUB Nothing [])
                defaultRespOptions
 
--- | Run shell command and return error status.  Assumes
+respondDocx :: String -> Pandoc -> Handler
+respondDocx = respondX "native"
+  "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
+  "docx" (writeDocx Nothing) defaultRespOptions
+
+--- | Run shell command and return error status.  Assumes
 -- UTF-8 locale. Note that this does not actually go through \/bin\/sh!
 runShellCommand :: FilePath                     -- ^ Working directory
                 -> Maybe [(String, String)]     -- ^ Environment
@@ -203,7 +224,7 @@
   return status
 
 respondPDF :: String -> Pandoc -> Handler
-respondPDF page old_pndc = fixURLs old_pndc >>= \pndc -> do
+respondPDF page old_pndc = fixURLs page old_pndc >>= \pndc -> do
   cfg <- getConfig
   unless (pdfExport cfg) $ error "PDF export disabled"
   let cacheName = pathForPage page ++ ".export.pdf"
@@ -253,8 +274,8 @@
 -- Because the working directory will not in general be the root of the gitit instance
 -- at the time the Pandoc is fed to e.g. pdflatex, this function replaces the URLs of
 -- images in the staticDir with their correct absolute file path.
-fixURLs :: Pandoc -> GititServerPart Pandoc
-fixURLs pndc = do
+fixURLs :: String -> Pandoc -> GititServerPart Pandoc
+fixURLs page pndc = do
     curdir <- liftIO getCurrentDirectory
     cfg <- getConfig
 
@@ -262,7 +283,7 @@
         go x                        = x
 
         fixURL ('/':url) = curdir </> staticDir cfg </> url
-        fixURL url       = url
+        fixURL url       = curdir </> repositoryPath cfg </> takeDirectory page </> url
 
     return $ bottomUp go pndc
 
@@ -274,15 +295,18 @@
                 , ("ConTeXt",   respondConTeXt)
                 , ("Texinfo",   respondTexinfo)
                 , ("reST",      respondRST)
-                , ("markdown",  respondMarkdown)
-                , ("plain text",respondPlain)
+                , ("Markdown",  respondMarkdown)
+                , ("Plain text",respondPlain)
                 , ("MediaWiki", respondMediaWiki)
-                , ("man",       respondMan)
+                , ("Org-mode",  respondOrg)
+                , ("Textile",   respondTextile)
+                , ("AsciiDoc",  respondAsciiDoc)
+                , ("Man page",  respondMan)
                 , ("DocBook",   respondDocbook)
-                , ("Slidy",     respondSlidy)
-                , ("S5",        respondS5)
-                , ("ODT",       respondODT)
+                , ("DZSlides",  respondSlides "dzslides" DZSlides)
+                , ("Slidy",     respondSlides "slidy" SlidySlides)
+                , ("S5",        respondSlides "s5" S5Slides)
                 , ("EPUB",      respondEPUB)
-                , ("Org",       respondOrg)
-                , ("Textile",   respondTextile)
+                , ("ODT",       respondODT)
+                , ("Docx",      respondDocx)
                 , ("RTF",       respondRTF) ]
diff --git a/Network/Gitit/Plugins.hs b/Network/Gitit/Plugins.hs
--- a/Network/Gitit/Plugins.hs
+++ b/Network/Gitit/Plugins.hs
@@ -53,14 +53,22 @@
                else if "Network/Gitit/Plugin/" `isInfixOf` pluginName
                        then "Network.Gitit.Plugin." ++ takeBaseName pluginName
                        else takeBaseName pluginName
+#if MIN_VERSION_ghc(7,4,0)
+      pr <- parseImportDecl "import Prelude"
+      i <- parseImportDecl "import Network.Gitit.Interface"
+      m <- parseImportDecl ("import " ++ modName)
+      setContext [IIDecl m, IIDecl  i, IIDecl pr]
+#else
       pr <- findModule (mkModuleName "Prelude") Nothing
       i <- findModule (mkModuleName "Network.Gitit.Interface") Nothing
       m <- findModule (mkModuleName modName) Nothing
-      setContext []
-#if MIN_VERSION_ghc(7,0,0)
-        [(m, Nothing), (i, Nothing), (pr, Nothing)]
+#if MIN_VERSION_ghc(7,2,0)
+      setContext [IIModule m, IIModule i, IIModule pr] []
+#elif MIN_VERSION_ghc(7,0,0)
+      setContext [] [(m, Nothing), (i, Nothing), (pr, Nothing)]
 #else
-        [m, i, pr]
+      setContext [] [m, i, pr]
+#endif
 #endif
       value <- compileExpr (modName ++ ".plugin :: Plugin")
       let value' = (unsafeCoerce value) :: Plugin
diff --git a/Network/Gitit/Types.hs b/Network/Gitit/Types.hs
--- a/Network/Gitit/Types.hs
+++ b/Network/Gitit/Types.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TypeSynonymInstances #-}
+{-# LANGUAGE TypeSynonymInstances, ScopedTypeVariables, FlexibleInstances #-}
 {-
 Copyright (C) 2009 John MacFarlane <jgm@berkeley.edu>,
 Anton van Straaten <anton@appsolutions.com>
@@ -35,7 +35,7 @@
 import System.Locale (defaultTimeLocale)
 import Data.FileStore.Types
 import Network.Gitit.Server
-import Text.Pandoc.CharacterReferences (decodeCharacterReferences)
+import Text.HTML.TagSoup.Entity (lookupEntity)
 
 data PageType = Markdown | RST | LaTeX | HTML | Textile
                 deriving (Read, Show, Eq)
@@ -289,9 +289,17 @@
                      , pResetCode    :: String
                      }  deriving Show
 
+instance FromReqURI [String] where
+  fromReqURI s = case fromReqURI s of
+                      Just (s' :: String) ->
+                                   case reads s' of
+                                        ((xs,""):_) -> xs
+                                        _           -> Nothing
+                      Nothing             -> Nothing
+
 instance FromData Params where
      fromData = do
-         let look' = liftM decodeCharacterReferences . look
+         let look' = liftM fromEntities . look
          un <- look' "username"       `mplus` return ""
          pw <- look' "password"       `mplus` return ""
          p2 <- look' "password2"      `mplus` return ""
@@ -384,3 +392,16 @@
 type GititServerPart = ServerPartT (ReaderT WikiState IO)
 
 type Handler = GititServerPart Response
+
+-- Unescapes XML entities
+fromEntities :: String -> String
+fromEntities ('&':xs) =
+  case lookupEntity ent of
+        Just c  -> c : fromEntities rest
+        Nothing -> '&' : fromEntities rest
+    where (ent, rest) = case break (==';') xs of
+                             (zs,';':ys) -> (zs,ys)
+                             _           -> ("",xs)
+fromEntities (x:xs) = x : fromEntities xs
+fromEntities [] = []
+
diff --git a/data/s5/default/blank.gif b/data/s5/default/blank.gif
new file mode 100644
Binary files /dev/null and b/data/s5/default/blank.gif differ
diff --git a/data/s5/default/bodybg.gif b/data/s5/default/bodybg.gif
new file mode 100644
Binary files /dev/null and b/data/s5/default/bodybg.gif differ
diff --git a/data/s5/default/framing.css b/data/s5/default/framing.css
new file mode 100644
--- /dev/null
+++ b/data/s5/default/framing.css
@@ -0,0 +1,23 @@
+/* The following styles size, place, and layer the slide components.
+   Edit these if you want to change the overall slide layout.
+   The commented lines can be uncommented (and modified, if necessary) 
+    to help you with the rearrangement process. */
+
+/* target = 1024x768 */
+
+div#header, div#footer, .slide {width: 100%; top: 0; left: 0;}
+div#header {top: 0; height: 3em; z-index: 1;}
+div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;}
+.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2;  list-style: none;}
+div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;}
+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
+  margin: 0;}
+#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;}
+html>body #currentSlide {position: fixed;}
+
+/*
+div#header {background: #FCC;}
+div#footer {background: #CCF;}
+div#controls {background: #BBD;}
+div#currentSlide {background: #FFC;}
+*/
diff --git a/data/s5/default/iepngfix.htc b/data/s5/default/iepngfix.htc
new file mode 100644
--- /dev/null
+++ b/data/s5/default/iepngfix.htc
@@ -0,0 +1,42 @@
+<public:component>
+<public:attach event="onpropertychange" onevent="doFix()" />
+
+<script>
+
+// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com
+// Free usage permitted as long as this notice remains intact.
+
+// This must be a path to a blank image. That's all the configuration you need here.
+var blankImg = 'ui/default/blank.gif';
+
+var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
+
+function filt(s, m) {
+ if (filters[f]) {
+  filters[f].enabled = s ? true : false;
+  if (s) with (filters[f]) { src = s; sizingMethod = m }
+ } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
+}
+
+function doFix() {
+ if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) ||
+  (event && !/(background|src)/.test(event.propertyName))) return;
+
+ if (tagName == 'IMG') {
+  if ((/\.png$/i).test(src)) {
+   filt(src, 'image');  // was 'scale'
+   src = blankImg;
+  } else if (src.indexOf(blankImg) < 0) filt();
+ } else if (style.backgroundImage) {
+  if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) {
+   var s = RegExp.$1;
+   style.backgroundImage = '';
+   filt(s, 'crop');
+  } else filt();
+ }
+}
+
+doFix();
+
+</script>
+</public:component>
diff --git a/data/s5/default/opera.css b/data/s5/default/opera.css
new file mode 100644
--- /dev/null
+++ b/data/s5/default/opera.css
@@ -0,0 +1,7 @@
+/* DO NOT CHANGE THESE unless you really want to break Opera Show */
+.slide {
+	visibility: visible !important;
+	position: static !important;
+	page-break-before: always;
+}
+#slide0 {page-break-before: avoid;}
diff --git a/data/s5/default/outline.css b/data/s5/default/outline.css
new file mode 100644
--- /dev/null
+++ b/data/s5/default/outline.css
@@ -0,0 +1,15 @@
+/* don't change this unless you want the layout stuff to show up in the outline view! */
+
+.layout div, #footer *, #controlForm * {display: none;}
+#footer, #controls, #controlForm, #navLinks, #toggle {
+  display: block; visibility: visible; margin: 0; padding: 0;}
+#toggle {float: right; padding: 0.5em;}
+html>body #toggle {position: fixed; top: 0; right: 0;}
+
+/* making the outline look pretty-ish */
+
+#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;}
+#slide0 h1 {padding-top: 1.5em;}
+.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em;
+  border-top: 1px solid #888; border-bottom: 1px solid #AAA;}
+#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;}
diff --git a/data/s5/default/pretty.css b/data/s5/default/pretty.css
new file mode 100644
--- /dev/null
+++ b/data/s5/default/pretty.css
@@ -0,0 +1,86 @@
+/* Following are the presentation styles -- edit away! */
+
+body {background: #FFF url(bodybg.gif) -16px 0 no-repeat; color: #000; font-size: 2em;}
+:link, :visited {text-decoration: none; color: #00C;}
+#controls :active {color: #88A !important;}
+#controls :focus {outline: 1px dotted #227;}
+h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;}
+ul, pre {margin: 0; line-height: 1em;}
+html, body {margin: 0; padding: 0;}
+
+blockquote, q {font-style: italic;}
+blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;}
+blockquote p {margin: 0;}
+blockquote i {font-style: normal;}
+blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;}
+blockquote b i {font-style: italic;}
+
+kbd {font-weight: bold; font-size: 1em;}
+sup {font-size: smaller; line-height: 1px;}
+
+.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;}
+.slide code.bad, code del {color: red;}
+.slide code.old {color: silver;}
+.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;}
+.slide pre code {display: block;}
+.slide ul {margin-left: 5%; margin-right: 7%; list-style: disc;}
+.slide li {margin-top: 0.75em; margin-right: 0;}
+.slide ul ul {line-height: 1;}
+.slide ul ul li {margin: .2em; font-size: 85%; list-style: square;}
+.slide img.leader {display: block; margin: 0 auto;}
+
+div#header, div#footer {background: #005; color: #AAB;
+  font-family: Verdana, Helvetica, sans-serif;}
+div#header {background: #005 url(bodybg.gif) -16px 0 no-repeat;
+  line-height: 1px;}
+div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;}
+#footer h1, #footer h2 {display: block; padding: 0 1em;}
+#footer h2 {font-style: italic;}
+
+div.long {font-size: 0.75em;}
+.slide h1 {position: absolute; top: 0.7em; left: 87px; z-index: 1;
+  margin: 0; padding: 0.3em 0 0 50px; white-space: nowrap;
+  font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize;
+  color: #DDE; background: #005;}
+.slide h3 {font-size: 130%;}
+h1 abbr {font-variant: small-caps;}
+
+div#controls {position: absolute; left: 50%; bottom: 0;
+  width: 50%;
+  text-align: right; font: bold 0.9em Verdana, Helvetica, sans-serif;}
+html>body div#controls {position: fixed; padding: 0 0 1em 0;
+  top: auto;}
+div#controls form {position: absolute; bottom: 0; right: 0; width: 100%;
+  margin: 0; padding: 0;}
+#controls #navLinks a {padding: 0; margin: 0 0.5em; 
+  background: #005; border: none; color: #779; 
+  cursor: pointer;}
+#controls #navList {height: 1em;}
+#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #DDD; color: #227;}
+
+#currentSlide {text-align: center; font-size: 0.5em; color: #449;}
+
+#slide0 {padding-top: 3.5em; font-size: 90%;}
+#slide0 h1 {position: static; margin: 1em 0 0; padding: 0;
+   font: bold 2em Helvetica, sans-serif; white-space: normal;
+   color: #000; background: transparent;}
+#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 0.25em;}
+#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;}
+#slide0 h4 {margin-top: 0; font-size: 1em;}
+
+ul.urls {list-style: none; display: inline; margin: 0;}
+.urls li {display: inline; margin: 0;}
+.note {display: none;}
+.external {border-bottom: 1px dotted gray;}
+html>body .external {border-bottom: none;}
+.external:after {content: " \274F"; font-size: smaller; color: #77B;}
+
+.incremental, .incremental *, .incremental *:after {color: #DDE; visibility: visible;}
+img.incremental {visibility: hidden;}
+.slide .current {color: #B02;}
+
+
+/* diagnostics
+
+li:after {content: " [" attr(class) "]"; color: #F88;}
+*/
diff --git a/data/s5/default/print.css b/data/s5/default/print.css
new file mode 100644
--- /dev/null
+++ b/data/s5/default/print.css
@@ -0,0 +1,24 @@
+/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */
+.slide, ul {page-break-inside: avoid; visibility: visible !important;}
+h1 {page-break-after: avoid;}
+
+body {font-size: 12pt; background: white;}
+* {color: black;}
+
+#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}
+#slide0 h3 {margin: 0; padding: 0;}
+#slide0 h4 {margin: 0 0 0.5em; padding: 0;}
+#slide0 {margin-bottom: 3em;}
+
+h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;}
+.extra {background: transparent !important;}
+div.extra, pre.extra, .example {font-size: 10pt; color: #333;}
+ul.extra a {font-weight: bold;}
+p.example {display: none;}
+
+#header {display: none;}
+#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;}
+#footer h2, #controls {display: none;}
+
+/* The following rule keeps the layout stuff out of print.  Remove at your own risk! */
+.layout, .layout * {display: none !important;}
diff --git a/data/s5/default/s5-core.css b/data/s5/default/s5-core.css
new file mode 100644
--- /dev/null
+++ b/data/s5/default/s5-core.css
@@ -0,0 +1,9 @@
+/* Do not edit or override these styles! The system will likely break if you do. */
+
+div#header, div#footer, div#controls, .slide {position: absolute;}
+html>body div#header, html>body div#footer, 
+  html>body div#controls, html>body .slide {position: fixed;}
+.handout {display: none;}
+.layout {display: block;}
+.slide, .hideme, .incremental {visibility: hidden;}
+#slide0 {visibility: visible;}
diff --git a/data/s5/default/slides.css b/data/s5/default/slides.css
new file mode 100644
--- /dev/null
+++ b/data/s5/default/slides.css
@@ -0,0 +1,3 @@
+@import url(s5-core.css); /* required to make the slide show run at all */
+@import url(framing.css); /* sets basic placement and size of slide components */
+@import url(pretty.css);  /* stuff that makes the slides look better than blah */
diff --git a/data/s5/default/slides.js b/data/s5/default/slides.js
new file mode 100644
--- /dev/null
+++ b/data/s5/default/slides.js
@@ -0,0 +1,553 @@
+// S5 v1.1 slides.js -- released into the Public Domain
+//
+// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information 
+// about all the wonderful and talented contributors to this code!
+
+var undef;
+var slideCSS = '';
+var snum = 0;
+var smax = 1;
+var incpos = 0;
+var number = undef;
+var s5mode = true;
+var defaultView = 'slideshow';
+var controlVis = 'visible';
+
+var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0;
+var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0;
+var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0;
+
+function hasClass(object, className) {
+	if (!object.className) return false;
+	return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1);
+}
+
+function hasValue(object, value) {
+	if (!object) return false;
+	return (object.search('(^|\\s)' + value + '(\\s|$)') != -1);
+}
+
+function removeClass(object,className) {
+	if (!object) return;
+	object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2);
+}
+
+function addClass(object,className) {
+	if (!object || hasClass(object, className)) return;
+	if (object.className) {
+		object.className += ' '+className;
+	} else {
+		object.className = className;
+	}
+}
+
+function GetElementsWithClassName(elementName,className) {
+	var allElements = document.getElementsByTagName(elementName);
+	var elemColl = new Array();
+	for (var i = 0; i< allElements.length; i++) {
+		if (hasClass(allElements[i], className)) {
+			elemColl[elemColl.length] = allElements[i];
+		}
+	}
+	return elemColl;
+}
+
+function isParentOrSelf(element, id) {
+	if (element == null || element.nodeName=='BODY') return false;
+	else if (element.id == id) return true;
+	else return isParentOrSelf(element.parentNode, id);
+}
+
+function nodeValue(node) {
+	var result = "";
+	if (node.nodeType == 1) {
+		var children = node.childNodes;
+		for (var i = 0; i < children.length; ++i) {
+			result += nodeValue(children[i]);
+		}		
+	}
+	else if (node.nodeType == 3) {
+		result = node.nodeValue;
+	}
+	return(result);
+}
+
+function slideLabel() {
+	var slideColl = GetElementsWithClassName('*','slide');
+	var list = document.getElementById('jumplist');
+	smax = slideColl.length;
+	for (var n = 0; n < smax; n++) {
+		var obj = slideColl[n];
+
+		var did = 'slide' + n.toString();
+		obj.setAttribute('id',did);
+		if (isOp) continue;
+
+		var otext = '';
+		var menu = obj.firstChild;
+		if (!menu) continue; // to cope with empty slides
+		while (menu && menu.nodeType == 3) {
+			menu = menu.nextSibling;
+		}
+	 	if (!menu) continue; // to cope with slides with only text nodes
+
+		var menunodes = menu.childNodes;
+		for (var o = 0; o < menunodes.length; o++) {
+			otext += nodeValue(menunodes[o]);
+		}
+		list.options[list.length] = new Option(n + ' : '  + otext, n);
+	}
+}
+
+function currentSlide() {
+	var cs;
+	if (document.getElementById) {
+		cs = document.getElementById('currentSlide');
+	} else {
+		cs = document.currentSlide;
+	}
+	cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' + 
+		'<span id="csSep">\/<\/span> ' + 
+		'<span id="csTotal">' + (smax-1) + '<\/span>';
+	if (snum == 0) {
+		cs.style.visibility = 'hidden';
+	} else {
+		cs.style.visibility = 'visible';
+	}
+}
+
+function go(step) {
+	if (document.getElementById('slideProj').disabled || step == 0) return;
+	var jl = document.getElementById('jumplist');
+	var cid = 'slide' + snum;
+	var ce = document.getElementById(cid);
+	if (incrementals[snum].length > 0) {
+		for (var i = 0; i < incrementals[snum].length; i++) {
+			removeClass(incrementals[snum][i], 'current');
+			removeClass(incrementals[snum][i], 'incremental');
+		}
+	}
+	if (step != 'j') {
+		snum += step;
+		lmax = smax - 1;
+		if (snum > lmax) snum = lmax;
+		if (snum < 0) snum = 0;
+	} else
+		snum = parseInt(jl.value);
+	var nid = 'slide' + snum;
+	var ne = document.getElementById(nid);
+	if (!ne) {
+		ne = document.getElementById('slide0');
+		snum = 0;
+	}
+	if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;}
+	if (incrementals[snum].length > 0 && incpos == 0) {
+		for (var i = 0; i < incrementals[snum].length; i++) {
+			if (hasClass(incrementals[snum][i], 'current'))
+				incpos = i + 1;
+			else
+				addClass(incrementals[snum][i], 'incremental');
+		}
+	}
+	if (incrementals[snum].length > 0 && incpos > 0)
+		addClass(incrementals[snum][incpos - 1], 'current');
+	ce.style.visibility = 'hidden';
+	ne.style.visibility = 'visible';
+	jl.selectedIndex = snum;
+	currentSlide();
+	number = 0;
+}
+
+function goTo(target) {
+	if (target >= smax || target == snum) return;
+	go(target - snum);
+}
+
+function subgo(step) {
+	if (step > 0) {
+		removeClass(incrementals[snum][incpos - 1],'current');
+		removeClass(incrementals[snum][incpos], 'incremental');
+		addClass(incrementals[snum][incpos],'current');
+		incpos++;
+	} else {
+		incpos--;
+		removeClass(incrementals[snum][incpos],'current');
+		addClass(incrementals[snum][incpos], 'incremental');
+		addClass(incrementals[snum][incpos - 1],'current');
+	}
+}
+
+function toggle() {
+	var slideColl = GetElementsWithClassName('*','slide');
+	var slides = document.getElementById('slideProj');
+	var outline = document.getElementById('outlineStyle');
+	if (!slides.disabled) {
+		slides.disabled = true;
+		outline.disabled = false;
+		s5mode = false;
+		fontSize('1em');
+		for (var n = 0; n < smax; n++) {
+			var slide = slideColl[n];
+			slide.style.visibility = 'visible';
+		}
+	} else {
+		slides.disabled = false;
+		outline.disabled = true;
+		s5mode = true;
+		fontScale();
+		for (var n = 0; n < smax; n++) {
+			var slide = slideColl[n];
+			slide.style.visibility = 'hidden';
+		}
+		slideColl[snum].style.visibility = 'visible';
+	}
+}
+
+function showHide(action) {
+	var obj = GetElementsWithClassName('*','hideme')[0];
+	switch (action) {
+	case 's': obj.style.visibility = 'visible'; break;
+	case 'h': obj.style.visibility = 'hidden'; break;
+	case 'k':
+		if (obj.style.visibility != 'visible') {
+			obj.style.visibility = 'visible';
+		} else {
+			obj.style.visibility = 'hidden';
+		}
+	break;
+	}
+}
+
+// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/)
+function keys(key) {
+	if (!key) {
+		key = event;
+		key.which = key.keyCode;
+	}
+	if (key.which == 84) {
+		toggle();
+		return;
+	}
+	if (s5mode) {
+		switch (key.which) {
+			case 10: // return
+			case 13: // enter
+				if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
+				if (key.target && isParentOrSelf(key.target, 'controls')) return;
+				if(number != undef) {
+					goTo(number);
+					break;
+				}
+			case 32: // spacebar
+			case 34: // page down
+			case 39: // rightkey
+			case 40: // downkey
+				if(number != undef) {
+					go(number);
+				} else if (!incrementals[snum] || incpos >= incrementals[snum].length) {
+					go(1);
+				} else {
+					subgo(1);
+				}
+				break;
+			case 33: // page up
+			case 37: // leftkey
+			case 38: // upkey
+				if(number != undef) {
+					go(-1 * number);
+				} else if (!incrementals[snum] || incpos <= 0) {
+					go(-1);
+				} else {
+					subgo(-1);
+				}
+				break;
+			case 36: // home
+				goTo(0);
+				break;
+			case 35: // end
+				goTo(smax-1);
+				break;
+			case 67: // c
+				showHide('k');
+				break;
+		}
+		if (key.which < 48 || key.which > 57) {
+			number = undef;
+		} else {
+			if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return;
+			if (key.target && isParentOrSelf(key.target, 'controls')) return;
+			number = (((number != undef) ? number : 0) * 10) + (key.which - 48);
+		}
+	}
+	return false;
+}
+
+function clicker(e) {
+	number = undef;
+	var target;
+	if (window.event) {
+		target = window.event.srcElement;
+		e = window.event;
+	} else target = e.target;
+	if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true;
+	if (!e.which || e.which == 1) {
+		if (!incrementals[snum] || incpos >= incrementals[snum].length) {
+			go(1);
+		} else {
+			subgo(1);
+		}
+	}
+}
+
+function findSlide(hash) {
+	var target = null;
+	var slides = GetElementsWithClassName('*','slide');
+	for (var i = 0; i < slides.length; i++) {
+		var targetSlide = slides[i];
+		if ( (targetSlide.name && targetSlide.name == hash)
+		 || (targetSlide.id && targetSlide.id == hash) ) {
+			target = targetSlide;
+			break;
+		}
+	}
+	while(target != null && target.nodeName != 'BODY') {
+		if (hasClass(target, 'slide')) {
+			return parseInt(target.id.slice(5));
+		}
+		target = target.parentNode;
+	}
+	return null;
+}
+
+function slideJump() {
+	if (window.location.hash == null) return;
+	var sregex = /^#slide(\d+)$/;
+	var matches = sregex.exec(window.location.hash);
+	var dest = null;
+	if (matches != null) {
+		dest = parseInt(matches[1]);
+	} else {
+		dest = findSlide(window.location.hash.slice(1));
+	}
+	if (dest != null)
+		go(dest - snum);
+}
+
+function fixLinks() {
+	var thisUri = window.location.href;
+	thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length);
+	var aelements = document.getElementsByTagName('A');
+	for (var i = 0; i < aelements.length; i++) {
+		var a = aelements[i].href;
+		var slideID = a.match('\#slide[0-9]{1,2}');
+		if ((slideID) && (slideID[0].slice(0,1) == '#')) {
+			var dest = findSlide(slideID[0].slice(1));
+			if (dest != null) {
+				if (aelements[i].addEventListener) {
+					aelements[i].addEventListener("click", new Function("e",
+						"if (document.getElementById('slideProj').disabled) return;" +
+						"go("+dest+" - snum); " +
+						"if (e.preventDefault) e.preventDefault();"), true);
+				} else if (aelements[i].attachEvent) {
+					aelements[i].attachEvent("onclick", new Function("",
+						"if (document.getElementById('slideProj').disabled) return;" +
+						"go("+dest+" - snum); " +
+						"event.returnValue = false;"));
+				}
+			}
+		}
+	}
+}
+
+function externalLinks() {
+	if (!document.getElementsByTagName) return;
+	var anchors = document.getElementsByTagName('a');
+	for (var i=0; i<anchors.length; i++) {
+		var anchor = anchors[i];
+		if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) {
+			anchor.target = '_blank';
+			addClass(anchor,'external');
+		}
+	}
+}
+
+function createControls() {
+	var controlsDiv = document.getElementById("controls");
+	if (!controlsDiv) return;
+	var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"';
+	var hideDiv, hideList = '';
+	if (controlVis == 'hidden') {
+		hideDiv = hider;
+	} else {
+		hideList = hider;
+	}
+	controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' +
+	'<div id="navLinks">' +
+	'<a accesskey="t" id="toggle" href="javascript:toggle();">&#216;<\/a>' +
+	'<a accesskey="z" id="prev" href="javascript:go(-1);">&laquo;<\/a>' +
+	'<a accesskey="x" id="next" href="javascript:go(1);">&raquo;<\/a>' +
+	'<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' +
+	'<\/div><\/form>';
+	if (controlVis == 'hidden') {
+		var hidden = document.getElementById('navLinks');
+	} else {
+		var hidden = document.getElementById('jumplist');
+	}
+	addClass(hidden,'hideme');
+}
+
+function fontScale() {  // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers
+	if (!s5mode) return false;
+	var vScale = 22;  // both yield 32 (after rounding) at 1024x768
+	var hScale = 32;  // perhaps should auto-calculate based on theme's declared value?
+	if (window.innerHeight) {
+		var vSize = window.innerHeight;
+		var hSize = window.innerWidth;
+	} else if (document.documentElement.clientHeight) {
+		var vSize = document.documentElement.clientHeight;
+		var hSize = document.documentElement.clientWidth;
+	} else if (document.body.clientHeight) {
+		var vSize = document.body.clientHeight;
+		var hSize = document.body.clientWidth;
+	} else {
+		var vSize = 700;  // assuming 1024x768, minus chrome and such
+		var hSize = 1024; // these do not account for kiosk mode or Opera Show
+	}
+	var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale));
+	fontSize(newSize + 'px');
+	if (isGe) {  // hack to counter incremental reflow bugs
+		var obj = document.getElementsByTagName('body')[0];
+		obj.style.display = 'none';
+		obj.style.display = 'block';
+	}
+}
+
+function fontSize(value) {
+	if (!(s5ss = document.getElementById('s5ss'))) {
+		if (!isIE) {
+			document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style'));
+			s5ss.setAttribute('media','screen, projection');
+			s5ss.setAttribute('id','s5ss');
+		} else {
+			document.createStyleSheet();
+			document.s5ss = document.styleSheets[document.styleSheets.length - 1];
+		}
+	}
+	if (!isIE) {
+		while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild);
+		s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}'));
+	} else {
+		document.s5ss.addRule('body','font-size: ' + value + ' !important;');
+	}
+}
+
+function notOperaFix() {
+	slideCSS = document.getElementById('slideProj').href;
+	var slides = document.getElementById('slideProj');
+	var outline = document.getElementById('outlineStyle');
+	slides.setAttribute('media','screen');
+	outline.disabled = true;
+	if (isGe) {
+		slides.setAttribute('href','null');   // Gecko fix
+		slides.setAttribute('href',slideCSS); // Gecko fix
+	}
+	if (isIE && document.styleSheets && document.styleSheets[0]) {
+		document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)');
+		document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)');
+		document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)');
+	}
+}
+
+function getIncrementals(obj) {
+	var incrementals = new Array();
+	if (!obj) 
+		return incrementals;
+	var children = obj.childNodes;
+	for (var i = 0; i < children.length; i++) {
+		var child = children[i];
+		if (hasClass(child, 'incremental')) {
+			if (child.nodeName == 'OL' || child.nodeName == 'UL') {
+				removeClass(child, 'incremental');
+				for (var j = 0; j < child.childNodes.length; j++) {
+					if (child.childNodes[j].nodeType == 1) {
+						addClass(child.childNodes[j], 'incremental');
+					}
+				}
+			} else {
+				incrementals[incrementals.length] = child;
+				removeClass(child,'incremental');
+			}
+		}
+		if (hasClass(child, 'show-first')) {
+			if (child.nodeName == 'OL' || child.nodeName == 'UL') {
+				removeClass(child, 'show-first');
+				if (child.childNodes[isGe].nodeType == 1) {
+					removeClass(child.childNodes[isGe], 'incremental');
+				}
+			} else {
+				incrementals[incrementals.length] = child;
+			}
+		}
+		incrementals = incrementals.concat(getIncrementals(child));
+	}
+	return incrementals;
+}
+
+function createIncrementals() {
+	var incrementals = new Array();
+	for (var i = 0; i < smax; i++) {
+		incrementals[i] = getIncrementals(document.getElementById('slide'+i));
+	}
+	return incrementals;
+}
+
+function defaultCheck() {
+	var allMetas = document.getElementsByTagName('meta');
+	for (var i = 0; i< allMetas.length; i++) {
+		if (allMetas[i].name == 'defaultView') {
+			defaultView = allMetas[i].content;
+		}
+		if (allMetas[i].name == 'controlVis') {
+			controlVis = allMetas[i].content;
+		}
+	}
+}
+
+// Key trap fix, new function body for trap()
+function trap(e) {
+	if (!e) {
+		e = event;
+		e.which = e.keyCode;
+	}
+	try {
+		modifierKey = e.ctrlKey || e.altKey || e.metaKey;
+	}
+	catch(e) {
+		modifierKey = false;
+	}
+	return modifierKey || e.which == 0;
+}
+
+function startup() {
+	defaultCheck();
+	if (!isOp) 
+		createControls();
+	slideLabel();
+	fixLinks();
+	externalLinks();
+	fontScale();
+	if (!isOp) {
+		notOperaFix();
+		incrementals = createIncrementals();
+		slideJump();
+		if (defaultView == 'outline') {
+			toggle();
+		}
+		document.onkeyup = keys;
+		document.onkeypress = trap;
+		document.onclick = clicker;
+	}
+}
+
+window.onload = startup;
+window.onresize = function(){setTimeout('fontScale()', 50);}
diff --git a/data/s5/default/slides.min.js b/data/s5/default/slides.min.js
new file mode 100644
--- /dev/null
+++ b/data/s5/default/slides.min.js
@@ -0,0 +1,1 @@
+var undef;var slideCSS="";var snum=0;var smax=1;var incpos=0;var number=undef;var s5mode=true;var defaultView="slideshow";var controlVis="visible";var isIE=navigator.appName=="Microsoft Internet Explorer"&&navigator.userAgent.indexOf("Opera")<1?1:0;var isOp=navigator.userAgent.indexOf("Opera")>-1?1:0;var isGe=navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("Safari")<1?1:0;function hasClass(a,b){if(!a.className){return false}return(a.className.search("(^|\\s)"+b+"(\\s|$)")!=-1)}function hasValue(a,b){if(!a){return false}return(a.search("(^|\\s)"+b+"(\\s|$)")!=-1)}function removeClass(a,b){if(!a){return}a.className=a.className.replace(new RegExp("(^|\\s)"+b+"(\\s|$)"),RegExp.$1+RegExp.$2)}function addClass(a,b){if(!a||hasClass(a,b)){return}if(a.className){a.className+=" "+b}else{a.className=b}}function GetElementsWithClassName(a,c){var d=document.getElementsByTagName(a);var e=new Array();for(var b=0;b<d.length;b++){if(hasClass(d[b],c)){e[e.length]=d[b]}}return e}function isParentOrSelf(a,b){if(a==null||a.nodeName=="BODY"){return false}else{if(a.id==b){return true}else{return isParentOrSelf(a.parentNode,b)}}}function nodeValue(d){var a="";if(d.nodeType==1){var c=d.childNodes;for(var b=0;b<c.length;++b){a+=nodeValue(c[b])}}else{if(d.nodeType==3){a=d.nodeValue}}return(a)}function slideLabel(){var f=GetElementsWithClassName("*","slide");var g=document.getElementById("jumplist");smax=f.length;for(var c=0;c<smax;c++){var e=f[c];var i="slide"+c.toString();e.setAttribute("id",i);if(isOp){continue}var d="";var b=e.firstChild;if(!b){continue}while(b&&b.nodeType==3){b=b.nextSibling}if(!b){continue}var h=b.childNodes;for(var a=0;a<h.length;a++){d+=nodeValue(h[a])}g.options[g.length]=new Option(c+" : "+d,c)}}function currentSlide(){var a;if(document.getElementById){a=document.getElementById("currentSlide")}else{a=document.currentSlide}a.innerHTML='<span id="csHere">'+snum+'</span> <span id="csSep">/</span> <span id="csTotal">'+(smax-1)+"</span>";if(snum==0){a.style.visibility="hidden"}else{a.style.visibility="visible"}}function go(c){if(document.getElementById("slideProj").disabled||c==0){return}var b=document.getElementById("jumplist");var g="slide"+snum;var e=document.getElementById(g);if(incrementals[snum].length>0){for(var a=0;a<incrementals[snum].length;a++){removeClass(incrementals[snum][a],"current");removeClass(incrementals[snum][a],"incremental")}}if(c!="j"){snum+=c;lmax=smax-1;if(snum>lmax){snum=lmax}if(snum<0){snum=0}}else{snum=parseInt(b.value)}var f="slide"+snum;var d=document.getElementById(f);if(!d){d=document.getElementById("slide0");snum=0}if(c<0){incpos=incrementals[snum].length}else{incpos=0}if(incrementals[snum].length>0&&incpos==0){for(var a=0;a<incrementals[snum].length;a++){if(hasClass(incrementals[snum][a],"current")){incpos=a+1}else{addClass(incrementals[snum][a],"incremental")}}}if(incrementals[snum].length>0&&incpos>0){addClass(incrementals[snum][incpos-1],"current")}e.style.visibility="hidden";d.style.visibility="visible";b.selectedIndex=snum;currentSlide();number=0}function goTo(a){if(a>=smax||a==snum){return}go(a-snum)}function subgo(a){if(a>0){removeClass(incrementals[snum][incpos-1],"current");removeClass(incrementals[snum][incpos],"incremental");addClass(incrementals[snum][incpos],"current");incpos++}else{incpos--;removeClass(incrementals[snum][incpos],"current");addClass(incrementals[snum][incpos],"incremental");addClass(incrementals[snum][incpos-1],"current")}}function toggle(){var b=GetElementsWithClassName("*","slide");var d=document.getElementById("slideProj");var c=document.getElementById("outlineStyle");if(!d.disabled){d.disabled=true;c.disabled=false;s5mode=false;fontSize("1em");for(var e=0;e<smax;e++){var a=b[e];a.style.visibility="visible"}}else{d.disabled=false;c.disabled=true;s5mode=true;fontScale();for(var e=0;e<smax;e++){var a=b[e];a.style.visibility="hidden"}b[snum].style.visibility="visible"}}function showHide(a){var b=GetElementsWithClassName("*","hideme")[0];switch(a){case"s":b.style.visibility="visible";break;case"h":b.style.visibility="hidden";break;case"k":if(b.style.visibility!="visible"){b.style.visibility="visible"}else{b.style.visibility="hidden"}break}}function keys(a){if(!a){a=event;a.which=a.keyCode}if(a.which==84){toggle();return}if(s5mode){switch(a.which){case 10:case 13:if(window.event&&isParentOrSelf(window.event.srcElement,"controls")){return}if(a.target&&isParentOrSelf(a.target,"controls")){return}if(number!=undef){goTo(number);break}case 32:case 34:case 39:case 40:if(number!=undef){go(number)}else{if(!incrementals[snum]||incpos>=incrementals[snum].length){go(1)}else{subgo(1)}}break;case 33:case 37:case 38:if(number!=undef){go(-1*number)}else{if(!incrementals[snum]||incpos<=0){go(-1)}else{subgo(-1)}}break;case 36:goTo(0);break;case 35:goTo(smax-1);break;case 67:showHide("k");break}if(a.which<48||a.which>57){number=undef}else{if(window.event&&isParentOrSelf(window.event.srcElement,"controls")){return}if(a.target&&isParentOrSelf(a.target,"controls")){return}number=(((number!=undef)?number:0)*10)+(a.which-48)}}return false}function clicker(b){number=undef;var a;if(window.event){a=window.event.srcElement;b=window.event}else{a=b.target}if(a.getAttribute("href")!=null||hasValue(a.rel,"external")||isParentOrSelf(a,"controls")||isParentOrSelf(a,"embed")||isParentOrSelf(a,"object")){return true}if(!b.which||b.which==1){if(!incrementals[snum]||incpos>=incrementals[snum].length){go(1)}else{subgo(1)}}}function findSlide(d){var c=null;var b=GetElementsWithClassName("*","slide");for(var a=0;a<b.length;a++){var e=b[a];if((e.name&&e.name==d)||(e.id&&e.id==d)){c=e;break}}while(c!=null&&c.nodeName!="BODY"){if(hasClass(c,"slide")){return parseInt(c.id.slice(5))}c=c.parentNode}return null}function slideJump(){if(window.location.hash==null){return}var b=/^#slide(\d+)$/;var c=b.exec(window.location.hash);var a=null;if(c!=null){a=parseInt(c[1])}else{a=findSlide(window.location.hash.slice(1))}if(a!=null){go(a-snum)}}function fixLinks(){var f=window.location.href;f=f.slice(0,f.length-window.location.hash.length);var g=document.getElementsByTagName("A");for(var e=0;e<g.length;e++){var b=g[e].href;var d=b.match("#slide[0-9]{1,2}");if((d)&&(d[0].slice(0,1)=="#")){var c=findSlide(d[0].slice(1));if(c!=null){if(g[e].addEventListener){g[e].addEventListener("click",new Function("e","if (document.getElementById('slideProj').disabled) return;go("+c+" - snum); if (e.preventDefault) e.preventDefault();"),true)}else{if(g[e].attachEvent){g[e].attachEvent("onclick",new Function("","if (document.getElementById('slideProj').disabled) return;go("+c+" - snum); event.returnValue = false;"))}}}}}}function externalLinks(){if(!document.getElementsByTagName){return}var c=document.getElementsByTagName("a");for(var b=0;b<c.length;b++){var a=c[b];if(a.getAttribute("href")&&hasValue(a.rel,"external")){a.target="_blank";addClass(a,"external")}}}function createControls(){var e=document.getElementById("controls");if(!e){return}var c=" onmouseover=\"showHide('s');\" onmouseout=\"showHide('h');\"";var d,a="";if(controlVis=="hidden"){d=c}else{a=c}e.innerHTML='<form action="#" id="controlForm"'+d+'><div id="navLinks"><a accesskey="t" id="toggle" href="javascript:toggle();">&#216;</a><a accesskey="z" id="prev" href="javascript:go(-1);">&laquo;</a><a accesskey="x" id="next" href="javascript:go(1);">&raquo;</a><div id="navList"'+a+'><select id="jumplist" onchange="go(\'j\');"></select></div></div></form>';if(controlVis=="hidden"){var b=document.getElementById("navLinks")}else{var b=document.getElementById("jumplist")}addClass(b,"hideme")}function fontScale(){if(!s5mode){return false}var f=22;var a=32;if(window.innerHeight){var c=window.innerHeight;var e=window.innerWidth}else{if(document.documentElement.clientHeight){var c=document.documentElement.clientHeight;var e=document.documentElement.clientWidth}else{if(document.body.clientHeight){var c=document.body.clientHeight;var e=document.body.clientWidth}else{var c=700;var e=1024}}}var b=Math.min(Math.round(c/f),Math.round(e/a));fontSize(b+"px");if(isGe){var d=document.getElementsByTagName("body")[0];d.style.display="none";d.style.display="block"}}function fontSize(a){if(!(s5ss=document.getElementById("s5ss"))){if(!isIE){document.getElementsByTagName("head")[0].appendChild(s5ss=document.createElement("style"));s5ss.setAttribute("media","screen, projection");s5ss.setAttribute("id","s5ss")}else{document.createStyleSheet();document.s5ss=document.styleSheets[document.styleSheets.length-1]}}if(!isIE){while(s5ss.lastChild){s5ss.removeChild(s5ss.lastChild)}s5ss.appendChild(document.createTextNode("body {font-size: "+a+" !important;}"))}else{document.s5ss.addRule("body","font-size: "+a+" !important;")}}function notOperaFix(){slideCSS=document.getElementById("slideProj").href;var b=document.getElementById("slideProj");var a=document.getElementById("outlineStyle");b.setAttribute("media","screen");a.disabled=true;if(isGe){b.setAttribute("href","null");b.setAttribute("href",slideCSS)}if(isIE&&document.styleSheets&&document.styleSheets[0]){document.styleSheets[0].addRule("img","behavior: url(ui/default/iepngfix.htc)");document.styleSheets[0].addRule("div","behavior: url(ui/default/iepngfix.htc)");document.styleSheets[0].addRule(".slide","behavior: url(ui/default/iepngfix.htc)")}}function getIncrementals(e){var d=new Array();if(!e){return d}var c=e.childNodes;for(var b=0;b<c.length;b++){var f=c[b];if(hasClass(f,"incremental")){if(f.nodeName=="OL"||f.nodeName=="UL"){removeClass(f,"incremental");for(var a=0;a<f.childNodes.length;a++){if(f.childNodes[a].nodeType==1){addClass(f.childNodes[a],"incremental")}}}else{d[d.length]=f;removeClass(f,"incremental")}}if(hasClass(f,"show-first")){if(f.nodeName=="OL"||f.nodeName=="UL"){removeClass(f,"show-first");if(f.childNodes[isGe].nodeType==1){removeClass(f.childNodes[isGe],"incremental")}}else{d[d.length]=f}}d=d.concat(getIncrementals(f))}return d}function createIncrementals(){var b=new Array();for(var a=0;a<smax;a++){b[a]=getIncrementals(document.getElementById("slide"+a))}return b}function defaultCheck(){var a=document.getElementsByTagName("meta");for(var b=0;b<a.length;b++){if(a[b].name=="defaultView"){defaultView=a[b].content}if(a[b].name=="controlVis"){controlVis=a[b].content}}}function trap(a){if(!a){a=event;a.which=a.keyCode}try{modifierKey=a.ctrlKey||a.altKey||a.metaKey}catch(a){modifierKey=false}return modifierKey||a.which==0}function startup(){defaultCheck();if(!isOp){createControls()}slideLabel();fixLinks();externalLinks();fontScale();if(!isOp){notOperaFix();incrementals=createIncrementals();slideJump();if(defaultView=="outline"){toggle()}document.onkeyup=keys;document.onkeypress=trap;document.onclick=clicker}}window.onload=startup;window.onresize=function(){setTimeout("fontScale()",50)};
diff --git a/data/static/css/hk-pyg.css b/data/static/css/hk-pyg.css
--- a/data/static/css/hk-pyg.css
+++ b/data/static/css/hk-pyg.css
@@ -1,19 +1,17 @@
-/* Loosely based on pygment's default colors */
-table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre 
-   { margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
-td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; } 
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
+  margin: 0; padding: 0; vertical-align: baseline; border: none; }
+table.sourceCode { width: 100%; }
+td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
 td.sourceCode { padding-left: 5px; }
-pre.sourceCode { }
-pre.sourceCode span.kw { color: #007020; font-weight: bold; } 
-pre.sourceCode span.dt { color: #902000; }
-pre.sourceCode span.dv { color: #40a070; }
-pre.sourceCode span.bn { color: #40a070; }
-pre.sourceCode span.fl { color: #40a070; }
-pre.sourceCode span.ch { color: #4070a0; }
-pre.sourceCode span.st { color: #4070a0; }
-pre.sourceCode span.co { color: #60a0b0; font-style: italic; }
-pre.sourceCode span.ot { color: #007020; }
-pre.sourceCode span.al { color: red; font-weight: bold; }
-pre.sourceCode span.fu { color: #06287e; }
-pre.sourceCode span.re { }
-pre.sourceCode span.er { color: red; font-weight: bold; }
+code > span.kw { color: #007020; font-weight: bold; }
+code > span.dt { color: #902000; }
+code > span.dv { color: #40a070; }
+code > span.bn { color: #40a070; }
+code > span.fl { color: #40a070; }
+code > span.ch { color: #4070a0; }
+code > span.st { color: #4070a0; }
+code > span.co { color: #60a0b0; font-style: italic; }
+code > span.ot { color: #007020; }
+code > span.al { color: #ff0000; font-weight: bold; }
+code > span.fu { color: #06287e; }
+code > span.er { color: #ff0000; font-weight: bold; }
diff --git a/data/static/css/print.css b/data/static/css/print.css
--- a/data/static/css/print.css
+++ b/data/static/css/print.css
@@ -3,8 +3,7 @@
 margin:0 !important;
 padding:0 !important;
 line-height: 1.4;
-word-spacing:1.1pt;
-letter-spacing:0.2pt; font-family: "Times New Roman", serif; color: #000; background: none; font-size: 12pt; }
+font-family: "Times New Roman", serif; color: #000; background: none; font-size: 12pt; }
 
 /*Headings */
 h1,h2,h3,h4,h5,h6 { font-family: Helvetica, Arial, sans-serif; }
diff --git a/data/static/css/screen.css b/data/static/css/screen.css
--- a/data/static/css/screen.css
+++ b/data/static/css/screen.css
@@ -80,8 +80,8 @@
 #sidebar ul { padding: 0; margin: 0; margin-left: 1.6em; line-height: 1.5em; }
 #sidebar ul li { color: #888; list-style: square; }
 
-div#toc { background-color: #f9f9f9; border: 10px solid white; margin: 0.8em; margin-right: 0; padding: 0.4em; }
-#toc ul { padding: 0 0 0 1em; margin: 0; list-style: none; }
+div#TOC { background-color: #f9f9f9; border: 10px solid white; margin: 0.8em; margin-right: 0; padding: 0.4em; }
+#TOC ul { padding: 0 0 0 1em; margin: 0; list-style: none; }
 
 #sidebar input, #sidebar select { font-size:  93%; padding: 0.1em; }
 #sidebar input[type='submit'] { border: none; background-color: #ccc; color: white; }
diff --git a/gitit.cabal b/gitit.cabal
--- a/gitit.cabal
+++ b/gitit.cabal
@@ -1,5 +1,5 @@
 name:                gitit
-version:             0.8.1
+version:             0.9
 Cabal-version:       >= 1.6
 build-type:          Simple
 synopsis:            Wiki using happstack, git or darcs, and pandoc.
@@ -54,6 +54,18 @@
                      data/static/js/preview.js, data/static/js/search.js,
                      data/static/js/MathMLinHTML.js,
                      data/static/robots.txt,
+                     data/s5/default/blank.gif,
+                     data/s5/default/bodybg.gif,
+                     data/s5/default/framing.css,
+                     data/s5/default/iepngfix.htc,
+                     data/s5/default/opera.css,
+                     data/s5/default/outline.css,
+                     data/s5/default/pretty.css,
+                     data/s5/default/print.css,
+                     data/s5/default/s5-core.css,
+                     data/s5/default/slides.css,
+                     data/s5/default/slides.js,
+                     data/s5/default/slides.min.js,
                      data/post-update, data/FrontPage.page, data/Help.page,
                      data/markup.Markdown, data/markup.RST,
                      data/markup.HTML, data/markup.LaTeX,
@@ -105,7 +117,8 @@
     exposed-modules: Network.Gitit.Interface
     build-depends:   ghc, ghc-paths
     cpp-options:     -D_PLUGINS
-  build-depends:     base >= 3, pandoc >= 1.8.2, pandoc-types >= 1.8.2, filepath, safe
+  build-depends:     base >= 3, pandoc >= 1.9.0.5 && < 1.10,
+                     pandoc-types >= 1.9.0.2 && < 1.10, filepath, safe
   extensions:        CPP
   if impl(ghc >= 6.12)
     ghc-options:     -Wall -fno-warn-unused-do-bind
@@ -121,37 +134,39 @@
                      pretty,
                      xhtml,
                      containers,
-                     pandoc >= 1.8.2,
-                     pandoc-types >= 1.8.2,
+                     pandoc >= 1.9.0.5 && < 1.10,
+                     pandoc-types >= 1.9.0.2 && < 1.10,
                      process,
                      filepath,
                      directory,
                      mtl,
                      cgi,
                      old-time,
-                     highlighting-kate >= 0.2.7.1,
+                     highlighting-kate >= 0.5.0.1 && < 0.6,
                      bytestring,
                      text,
                      random,
                      network >= 2.1.0.0 && < 2.4,
                      utf8-string >= 0.3 && < 0.4,
                      SHA > 1 && < 1.6,
-                     HTTP >= 4000.0 && < 4000.2,
+                     HTTP >= 4000.0 && < 4000.3,
                      HStringTemplate >= 0.6 && < 0.7,
                      old-locale >= 1,
-                     time >= 1.1 && < 1.3,
+                     time >= 1.1 && < 1.5,
                      recaptcha >= 0.1,
                      filestore >= 0.4.0.2 && < 0.5,
                      zlib >= 0.5 && < 0.6,
                      url >= 2.1 && < 2.2,
-                     happstack-server >= 6.0 && < 6.3,
-                     happstack-util >= 6.0 && < 6.2,
+                     happstack-server >= 6.6 && < 6.7,
+                     happstack-util >= 6.0 && < 6.1,
                      xml >= 1.3.5,
                      hslogger >= 1 && < 1.2,
                      ConfigFile >= 1 && < 1.2,
                      feed >= 0.3.6 && < 0.4,
                      xss-sanitize >= 0.3 && < 0.4,
-                     json >= 0.4 && < 0.5
+                     tagsoup >= 0.12 && < 0.13,
+                     blaze-html >= 0.4 && < 0.5,
+                     json >= 0.4 && < 0.6
   if impl(ghc >= 6.10)
     build-depends:   base >= 4, syb
   if impl(ghc >= 7.0.3)
diff --git a/plugins/Interwiki.hs b/plugins/Interwiki.hs
--- a/plugins/Interwiki.hs
+++ b/plugins/Interwiki.hs
@@ -61,7 +61,7 @@
                       ("Hoogle", "http://www.haskell.org/hoogle/?hoogle=")]
 
 -- This mapping is derived from <https://secure.wikimedia.org/wikipedia/meta/wiki/Interwiki_map>
--- as of 11:30 AM, 6 February 2011.
+-- as of 5:18 PM, 6 February 2012.
 wpInterwikiMap = [ ("AbbeNormal", "http://ourpla.net/cgi/pikie?"),
                  ("AIWiki", "http://www.ifi.unizh.ch/ailab/aiwiki/aiw.cgi?"),
                  ("Acronym", "http://www.acronymfinder.com/af-query.asp?String=exact&Acronym="),
@@ -74,12 +74,13 @@
                  ("AquariumWiki", "http://www.theaquariumwiki.com/"),
                  ("AspieNetWiki", "http://aspie.mela.de/index.php/"),
                  ("AtmWiki", "http://www.otterstedt.de/wiki/index.php/"),
+                 ("BCNbio", "http://historiapolitica.bcn.cl/resenas_parlamentarias/wiki/"),
                  ("BEMI", "http://bemi.free.fr/vikio/index.php?"),
                  ("BLW", "http://britainloveswikipedia.org/wiki/"),
                  ("BattlestarWiki", "http://en.battlestarwiki.org/wiki/"),
                  ("BenefitsWiki", "http://www.benefitslink.com/cgi-bin/wiki.cgi?"),
                  ("BibleWiki", "http://bible.tmtm.com/wiki/"),
-                 ("BluWiki", "http://www.bluwiki.org/go/"),
+                 ("BluWiki", "http://bluwiki.com/go/"),
                  ("Botwiki", "http://botwiki.sno.cc/wiki/"),
                  ("Boxrec", "http://www.boxrec.com/media/index.php?"),
                  ("BrickWiki", "http://lego.wikia.com/index.php?title="),
@@ -100,6 +101,7 @@
                  ("Comixpedia", "http://www.comixpedia.org/index.php/"),
                  ("Commons", "http://commons.wikimedia.org/wiki/"),
                  ("CommunityScheme", "http://community.schemewiki.org/?c=s&key="),
+                 ("CommunityWiki", "http://www.communitywiki.org/"),
                  ("CorpKnowPedia", "http://corpknowpedia.org/wiki/index.php/"),
                  ("CrazyHacks", "http://www.crazy-hacks.org/wiki/index.php?title="),
                  ("CreativeCommons", "http://www.creativecommons.org/licenses/"),
@@ -115,11 +117,12 @@
                  ("DejaNews", "http://www.deja.com/=dnc/getdoc.xp?AN="),
                  ("Delicious", "http://www.delicious.com/tag/"),
                  ("Demokraatia", "http://wiki.demokraatia.ee/index.php/"),
-                 ("Devmo", "http://developer.mozilla.org/en/docs/"),
+                 ("Devmo", "https://developer.mozilla.org/en/docs/"),
                  ("Dict", "http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query="),
                  ("Dictionary", "http://www.dict.org/bin/Dict?Database=*&Form=Dict1&Strategy=*&Query="),
                  ("Disinfopedia", "http://www.sourcewatch.org/wiki.phtml?title="),
                  ("DocBook", "http://wiki.docbook.org/topic/"),
+                 ("Donate", "http://donate.wikimedia.org/wiki/"),
                  ("Dreamhost", "http://wiki.dreamhost.com/index.php/"),
                  ("DrumCorpsWiki", "http://www.drumcorpswiki.com/index.php/"),
                  ("ELibre", "http://enciclopedia.us.es/index.php/"),
@@ -130,7 +133,9 @@
                  ("Encyc", "http://encyc.org/wiki/"),
                  ("EnergieWiki", "http://www.netzwerk-energieberater.de/wiki/index.php/"),
                  ("EoKulturCentro", "http://esperanto.toulouse.free.fr/nova/wikini/wakka.php?wiki="),
+                 ("Etherpad", "http://etherpad.wikimedia.org/"),
                  ("Ethnologue", "http://www.ethnologue.com/show_language.asp?code="),
+                 ("EthnologueFamily", "http://www.ethnologue.com/show_family.asp?subid="),
                  ("EvoWiki", "http://wiki.cotch.net/index.php/"),
                  ("Exotica", "http://www.exotica.org.uk/wiki/"),
                  ("EĉeI", "http://www.ikso.net/cgi-bin/wiki.pl?"),
@@ -160,7 +165,6 @@
                  ("GlobalVoices", "http://cyber.law.harvard.edu/dyn/globalvoices/wiki/"),
                  ("GlossarWiki", "http://glossar.hs-augsburg.de/"),
                  ("GlossaryWiki", "http://glossary.hs-augsburg.de/"),
-                 ("Golem", "http://golem.linux.it/index.php/"),
                  ("Google", "http://www.google.com/search?q="),
                  ("GoogleDefine", "http://www.google.com/search?q=define:"),
                  ("GoogleGroups", "http://groups.google.com/groups?q="),
@@ -217,6 +221,7 @@
                  ("Mariowiki", "http://www.mariowiki.com/"),
                  ("MarvelDatabase", "http://www.marveldatabase.com/wiki/index.php/"),
                  ("MeatBall", "http://meatballwiki.org/wiki/"),
+                 ("MediaWikiWiki", "http://www.mediawiki.org/wiki/"),
                  ("MediaZilla", "https://bugzilla.wikimedia.org/"),
                  ("MemoryAlpha", "http://memory-alpha.org/wiki/"),
                  ("MetaWiki", "http://sunir.org/apps/meta.pl?"),
@@ -226,7 +231,7 @@
                  ("Monstropedia", "http://www.monstropedia.org/?title="),
                  ("MosaPedia", "http://mosapedia.de/wiki/index.php/"),
                  ("MozCom", "http://mozilla.wikia.com/wiki/"),
-                 ("MozillaWiki", "http://wiki.mozilla.org/"),
+                 ("MozillaWiki", "https://wiki.mozilla.org/"),
                  ("MozillaZineKB", "http://kb.mozillazine.org/"),
                  ("MusicBrainz", "http://musicbrainz.org/doc/"),
                  ("NKcells", "http://www.nkcells.info/wiki/index.php/"),
@@ -235,6 +240,7 @@
                  ("OEIS", "http://oeis.org/"),
                  ("OLPC", "http://wiki.laptop.org/go/"),
                  ("OSI", "http://wiki.tigma.ee/index.php/"),
+                 ("OSMwiki", "http://wiki.openstreetmap.org/wiki/"),
                  ("OTRS", "https://ticket.wikimedia.org/otrs/index.pl?Action=AgentTicketZoom&TicketID="),
                  ("OTRSwiki", "http://otrs-wiki.wikimedia.org/wiki/"),
                  ("OldWikisource", "http://wikisource.org/wiki/"),
@@ -247,11 +253,11 @@
                  ("Opera7Wiki", "http://operawiki.info/"),
                  ("OrganicDesign", "http://www.organicdesign.co.nz/"),
                  ("OrthodoxWiki", "http://orthodoxwiki.org/"),
-                 ("OurMedia", "http://www.socialtext.net/ourmedia/index.cgi?"),
+                 ("OurMedia", "https://www.socialtext.net/ourmedia/index.cgi?"),
                  ("Outreach", "http://outreach.wikimedia.org/wiki/"),
                  ("OutreachWiki", "http://outreach.wikimedia.org/wiki/"),
                  ("PHWiki", "http://wiki.pocketheaven.com/"),
-                 ("PMEG", "http://www.bertilow.com/pmeg/.php"),
+                 ("PMEG", "http://www.bertilow.com/pmeg/"),
                  ("Panawiki", "http://wiki.alairelibre.net/index.php?title="),
                  ("PatWIKI", "http://gauss.ffii.org/"),
                  ("PerlNet", "http://perl.net.au/wiki/"),
@@ -284,9 +290,10 @@
                  ("SourceForge", "http://sourceforge.net/"),
                  ("Species", "http://species.wikimedia.org/wiki/"),
                  ("Squeak", "http://wiki.squeak.org/squeak/"),
+                 ("Stewardry", "http://toolserver.org/~pathoschild/stewardry/?wiki="),
                  ("Strategy", "http://strategy.wikimedia.org/wiki/"),
                  ("StrategyWiki", "http://strategywiki.org/wiki/"),
-                 ("Sulutil", "http://toolserver.org/~vvv/sulutil.php?user="),
+                 ("Sulutil", "http://toolserver.org/~quentinv57/sulinfo/"),
                  ("SwinBrain", "http://mercury.it.swin.edu.au/swinbrain/index.php/"),
                  ("SwingWiki", "http://www.swingwiki.org/"),
                  ("Swtrain", "http://train.spottingworld.com/"),
@@ -309,7 +316,6 @@
                  ("Ticket", "https://ticket.wikimedia.org/otrs/index.pl?Action=AgentTicketZoom&TicketNumber="),
                  ("TmNet", "http://www.technomanifestos.net/?"),
                  ("Tools", "http://toolserver.org/"),
-                 ("Trash!Italia", "http://trashware.linux.it/wiki/"),
                  ("Turismo", "http://www.tejo.org/turismo/"),
                  ("TyvaWiki", "http://www.tyvawiki.org/wiki/"),
                  ("USEJ", "http://www.tejo.org/usej/"),
@@ -320,11 +326,11 @@
                  ("VKoL", "http://kol.coldfront.net/thekolwiki/index.php/"),
                  ("VLOS", "http://www.thuvienkhoahoc.com/tusach/"),
                  ("ValueWiki", "http://www.valuewiki.com/w/"),
-                 ("Veropedia", "http://en.veropedia.com/a/"),
                  ("Vinismo", "http://vinismo.com/en/"),
                  ("VoIPinfo", "http://www.voip-info.org/wiki/view/"),
                  ("WLUG", "http://www.wlug.org.nz/"),
                  ("WMF", "http://wikimediafoundation.org/wiki/"),
+                 ("WMFblog", "http://blog.wikimedia.org/"),
                  ("Webisodes", "http://www.webisodes.org/"),
                  ("Wiki", "http://c2.com/cgi/wiki?"),
                  ("WikiChristian", "http://www.wikichristian.org/index.php?title="),
@@ -400,15 +406,18 @@
                  ("infoAnarchy", "http://www.infoanarchy.org/en/"),
                  ("lyricwiki", "http://lyrics.wikia.com/"),
                  ("mailarchive", "http://lists.wikimedia.org/pipermail/"),
+                 ("nostalgia", "http://nostalgia.wikipedia.org/wiki/"),
                  ("psycle", "http://psycle.sourceforge.net/wiki/"),
-                 ("pyrev", "http://svn.wikimedia.org/viewvc/pywikipedia?view=rev&revision="),
+                 ("pyrev", "http://www.mediawiki.org/wiki/Special:Code/pywikipedia/"),
                  ("qcwiki", "http://wiki.quantumchemistry.net/index.php/"),
                  ("rev", "http://www.mediawiki.org/wiki/Special:Code/MediaWiki/"),
                  ("rtfm", "http://s23.org/wiki/"),
+                 ("securewikidc", "https://secure.wikidc.org/"),
                  ("semantic-mw", "http://www.semantic-mediawiki.org/wiki/"),
                  ("silcode", "http://www.sil.org/iso639-3/documentation.asp?id="),
                  ("spcom", "http://spcom.wikimedia.org/wiki/"),
                  ("stable", "http://stable.toolserver.org/"),
+                 ("stats", "http://stats.wikimedia.org/"),
                  ("svn", "http://svn.wikimedia.org/viewvc/mediawiki/?view=log"),
                  ("translatewiki", "http://translatewiki.net/wiki/"),
                  ("tswiki", "http://wiki.toolserver.org/view/"),
@@ -418,19 +427,25 @@
                  ("wikisophia", "http://wikisophia.org/index.php?title="),
                  ("wmar", "http://www.wikimedia.org.ar/wiki/"),
                  ("wmau", "http://wikimedia.org.au/wiki/"),
-                 ("wmca", "http://wikimedia.ca/index.php/"),
+                 ("wmbe", "http://be.wikimedia.org/wiki/"),
+                 ("wmbr", "http://br.wikimedia.org/wiki/"),
+                 ("wmca", "http://wikimedia.ca/wiki/"),
                  ("wmch", "http://www.wikimedia.ch/"),
                  ("wmcz", "http://meta.wikimedia.org/wiki/Wikimedia_Czech_Republic/"),
+                 ("wmdc", "http://wikimediadc.org/wiki/"),
                  ("wmde", "http://wikimedia.de/wiki/"),
                  ("wmfi", "http://fi.wikimedia.org/wiki/"),
+                 ("wmfr", "http://wikimedia.fr/"),
                  ("wmhk", "http://wikimedia.hk/index.php/"),
                  ("wmhu", "http://wiki.media.hu/wiki/"),
                  ("wmid", "http://www.wikimedia.or.id/wiki/"),
                  ("wmil", "http://www.wikimedia.org.il/"),
-                 ("wmin", "http://wikimedia.in/wiki/"),
+                 ("wmin", "http://wiki.wikimedia.in/"),
                  ("wmit", "http://wikimedia.it/index.php/"),
+                 ("wmmx", "http://mx.wikimedia.org/wiki/"),
                  ("wmnl", "http://nl.wikimedia.org/wiki/"),
                  ("wmno", "http://no.wikimedia.org/wiki/"),
+                 ("wmnyc", "http://nyc.wikimedia.org/wiki/"),
                  ("wmpl", "http://pl.wikimedia.org/wiki/"),
                  ("wmrs", "http://rs.wikimedia.org/wiki/"),
                  ("wmru", "http://ru.wikimedia.org/wiki/"),
