diff --git a/Controller.hs b/Controller.hs
--- a/Controller.hs
+++ b/Controller.hs
@@ -10,7 +10,7 @@
 import Network.Wai (Application)
 import Settings
 import TKYProf
-import Yesod.Helpers.Static
+import Yesod.Static
 -- Import all relevant handler modules here.
 import Handler.Home
 import Handler.Reports
@@ -35,11 +35,10 @@
 withTKYProf :: (Application -> IO a) -> IO a
 withTKYProf f = do
   rs <- atomically $ emptyReports
+  s <- static Settings.staticdir
   let h = TKYProf { getStatic  = s
                   , getReports = rs }
   toWaiApp h >>= f
-  where
-    s = static Settings.staticdir
 
 withDevelApp :: Dynamic
 withDevelApp = toDyn (withTKYProf :: (Application -> IO ()) -> IO ())
diff --git a/Handler/Home.hs b/Handler/Home.hs
--- a/Handler/Home.hs
+++ b/Handler/Home.hs
@@ -21,4 +21,4 @@
     addScript $ StaticR js_jquery_ui_widget_js
     addScript $ StaticR js_jquery_iframe_transport_js
     addScript $ StaticR js_jquery_fileupload_js
-    addWidget $(widgetFile "home")
+    $(widgetFile "home")
diff --git a/Handler/Reports.hs b/Handler/Reports.hs
--- a/Handler/Reports.hs
+++ b/Handler/Reports.hs
@@ -11,20 +11,20 @@
 import Data.Text (Text)
 import Handler.Reports.Helpers (getAllReports, getProfilingReport, postProfilingReport)
 import ProfilingReport
-import TKYProf
-import Yesod.Request
+import TKYProf hiding (lift)
+import Yesod.Core (lift)
 import qualified Data.Aeson as A (encode)
-import qualified Data.Attoparsec as A
-import qualified Data.ByteString as S
-import qualified Data.ByteString.Lazy as L
 import qualified Data.Text.Lazy.Encoding as T (decodeUtf8)
+import Network.HTTP.Types.Status (seeOther303)
+import Data.Conduit (($$))
+import Text.Julius
 
 getReportsR :: Handler RepHtml
 getReportsR = do
   reports <- getAllReports
   defaultLayout $ do
     setTitle "TKYProf Reports"
-    addWidget $(widgetFile "reports")
+    $(widgetFile "reports")
 
 postReportsR :: Handler ()
 postReportsR = do
@@ -36,7 +36,7 @@
                      sendResponseCreated ReportsR
 
 getReportsIdR :: ReportID -> Handler RepHtml
-getReportsIdR reportId = redirect RedirectSeeOther (ReportsIdTimeR reportId [])
+getReportsIdR reportId = redirectWith seeOther303 (ReportsIdTimeR reportId [])
 
 getReportsIdTimeR :: ReportID -> [a] -> Handler RepHtml
 getReportsIdTimeR reportId _ = getReportsIdCommon reportId "time"
@@ -53,23 +53,17 @@
     found -> return found
 
 postFileInfo :: FileInfo -> Handler ReportID
-postFileInfo FileInfo {fileContent} = do
-  prof <- parseFileContent fileContent
+postFileInfo info = do
+  prof <- lift $ fileSource info $$ profilingReportI
   postProfilingReport prof
 
-parseFileContent :: L.ByteString -> Handler ProfilingReport
-parseFileContent content =
-  case A.parseOnly profilingReport (S.concat $ L.toChunks content) of
-    Left err   -> invalidArgs ["Invalid format", toMessage err]
-    Right tree -> return tree
-
 getReportsIdCommon :: ReportID -> Text -> Handler RepHtml
 getReportsIdCommon reportId profilingType = do
   report@ProfilingReport {..} <- getProfilingReport reportId
-  let json = T.decodeUtf8 $ A.encode reportCostCentres
+  let json = rawJS $ T.decodeUtf8 $ A.encode reportCostCentres
   defaultLayout $ do
     setTitle $ "TKYProf Reports"
     addScript $ StaticR js_tkyprof_js
     addScript $ StaticR js_d3_min_js
     addScript $ StaticR js_d3_layout_min_js
-    addWidget $(widgetFile "reports-id")
+    $(widgetFile "reports-id")
diff --git a/ProfilingReport.hs b/ProfilingReport.hs
--- a/ProfilingReport.hs
+++ b/ProfilingReport.hs
@@ -27,16 +27,16 @@
 import Control.Applicative hiding (many)
 import Data.Aeson
 import Data.Attoparsec.Char8 as A8
-import Data.Attoparsec.Enumerator (iterParser)
+import Data.Conduit.Attoparsec (sinkParser)
 import Data.ByteString (ByteString)
-import Data.Enumerator (Iteratee)
+import Data.Conduit
 import Data.Foldable (foldl')
 import Data.Time (UTCTime(..), TimeOfDay(..), timeOfDayToTime, fromGregorian)
 import Data.Tree (Tree(..), Forest)
 import Data.Tree.Zipper (TreePos, Full)
 import Prelude hiding (takeWhile)
 import qualified Data.Attoparsec as A
-import qualified Data.Map as M
+import qualified Data.HashMap.Strict as M
 import qualified Data.Tree.Zipper as Z
 import qualified Data.Vector as V
 import Data.Text (Text)
@@ -59,6 +59,7 @@
   { totalSecs  :: Double
   , totalTicks :: Integer
   , resolution :: Integer
+  , processors :: Integer
   } deriving Show
 
 newtype TotalAlloc = TotalAlloc
@@ -83,8 +84,8 @@
   , inheritedAlloc    :: Double
   } deriving Show
 
-profilingReportI :: Monad m => Iteratee ByteString m ProfilingReport
-profilingReportI = iterParser profilingReport
+profilingReportI :: MonadThrow m => GLSink ByteString m ProfilingReport
+profilingReportI = sinkParser profilingReport
 
 profilingReport :: Parser ProfilingReport
 profilingReport = spaces >>
@@ -128,12 +129,15 @@
   string "total time  ="; spaces
   secs <- double
   string " secs"; spaces
-  (ticks, res) <- parens $
-    (,) <$> decimal <* string " ticks @ "
-        <*> decimal <* string " ms"
+  (ticks, res, procs) <- parens $
+    (,,) <$> decimal <* string " ticks @ "
+         <*> time
+         <*> ( string ", " *> decimal <* string " processor" <|> pure 1 )
   return TotalTime { totalSecs  = secs
                    , totalTicks = ticks
-                   , resolution = res }
+                   , resolution = res
+                   , processors = procs }
+  where time = (decimal <* string " us") <|> (pure (*1000) <*> decimal <* string " ms")
 
 totalAlloc :: Parser TotalAlloc
 totalAlloc = do
@@ -205,7 +209,7 @@
   where howMany' !n = (p >> howMany' (succ n)) <|> return n
 
 spaces :: Parser ()
-spaces = () <$ many space
+spaces = () <$ skipMany space
 
 line :: Parser ByteString
 line = A.takeWhile (not . isEndOfLine) <* spaces
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -26,3 +26,6 @@
 ------------------------
 
 This tool is written and maintained by Mitsutoshi Aoe, <maoe@foldr.in>.
+And thanks to the following contributors:
+
+* Ben Gamari (@bgamari)
diff --git a/TKYProf.hs b/TKYProf.hs
--- a/TKYProf.hs
+++ b/TKYProf.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings #-}
 module TKYProf
   ( TKYProf (..)
-  , TKYProfRoute (..)
+  , Route (..)
   , resourcesTKYProf
   , Handler
   , Widget
@@ -10,7 +10,7 @@
   , module StaticFiles
   , module Model
   , module Control.Monad.STM
-  , StaticRoute (..)
+  , StaticRoute
   , lift
   , liftIO
   ) where
@@ -24,8 +24,8 @@
 import StaticFiles
 import System.Directory
 import System.FilePath ((</>))
-import Yesod.Core
-import Yesod.Helpers.Static
+import Yesod.Core hiding (lift)
+import Yesod.Static
 import qualified Data.ByteString.Lazy as L
 import qualified Data.Text as T
 import qualified Settings
@@ -39,14 +39,6 @@
   , getReports :: Reports
   }
 
--- | A useful synonym; most of the handler functions in your application
--- will need to be of this type.
-type Handler = GHandler TKYProf TKYProf
-
--- | A useful synonym; most of the widgets functions in your application
--- will need to be of this type.
-type Widget = GWidget TKYProf TKYProf
-
 -- This is where we define all of the routes in our application. For a full
 -- explanation of the syntax, please see:
 -- http://docs.yesodweb.com/book/web-routes-quasi/
@@ -71,22 +63,16 @@
 -- Please see the documentation for the Yesod typeclass. There are a number
 -- of settings which can be configured by overriding methods here.
 instance Yesod TKYProf where
-  approot _ = Settings.approot
+  approot = ApprootRelative
 
   defaultLayout widget = do
     mmsg <- getMessage
     (title, bcs) <- breadcrumbs
     pc <- widgetToPageContent $ do
-      addWidget $(Settings.widgetFile "header")                     
+      $(Settings.widgetFile "header")
       widget
-      addLucius $(Settings.luciusFile "default-layout")
-    hamletToRepHtml $(Settings.hamletFile "default-layout")
-
-  -- This is done to provide an optimization for serving static files from
-  -- a separate domain. Please see the staticroot setting in Settings.hs
-  urlRenderOverride a (StaticR s) =
-    Just $ uncurry (joinPath a Settings.staticroot) $ renderRoute s
-  urlRenderOverride _ _ = Nothing
+      toWidget $(Settings.luciusFile "templates/default-layout.lucius")
+    hamletToRepHtml $(Settings.hamletFile "templates/default-layout.hamlet")
 
   -- This function creates static content files in the static folder
   -- and names them based on a hash of their content. This allows
@@ -100,6 +86,8 @@
     exists <- liftIO $ doesFileExist fn'
     unless exists $ liftIO $ L.writeFile fn' content
     return $ Just $ Right (StaticR $ StaticRoute ["tmp", T.pack fn] [], [])
+  
+  maximumContentLength _ _ = 20*1024*1024
 
 instance YesodBreadcrumbs TKYProf where
   breadcrumb HomeR                   = return ("Home", Nothing)
diff --git a/config/Settings.hs b/config/Settings.hs
--- a/config/Settings.hs
+++ b/config/Settings.hs
@@ -7,12 +7,10 @@
 -- by overriding methods in the Yesod typeclass. That instance is
 -- declared in the tkyprof.hs file.
 module Settings
-  ( hamletFile
-  , juliusFile
-  , luciusFile
+  ( H.hamletFile
+  , H.juliusFile
+  , H.luciusFile
   , widgetFile
-  , approot
-  , staticroot
   , staticdir
   ) where
 
@@ -20,46 +18,14 @@
 import qualified Text.Julius as H
 import qualified Text.Lucius as H
 import Language.Haskell.TH.Syntax
-import Yesod.Widget (addWidget, addJulius, addLucius)
-import Data.Monoid (mempty, mappend)
-import System.Directory (doesFileExist)
-import Data.Text (Text)
-
--- | The base URL for your application. This will usually be different for
--- development and production. Yesod automatically constructs URLs for you,
--- so this value must be accurate to create valid links.
-approot :: Text
-#ifdef PRODUCTION
--- You probably want to change this. If your domain name was "yesod.com",
--- you would probably want it to be:
--- > approot = "http://www.yesod.com"
--- Please note that there is no trailing slash.
-approot = "http://localhost:3000"
-#else
-approot = "http://localhost:3000"
-#endif
+import Yesod.Default.Util
+import Data.Default (def)
 
 -- | The location of static files on your system. This is a file system
 -- path. The default value works properly with your scaffolded site.
 staticdir :: FilePath
 staticdir = "static"
 
--- | The base URL for your static files. As you can see by the default
--- value, this can simply be "static" appended to your application root.
--- A powerful optimization can be serving static files from a separate
--- domain name. This allows you to use a web server optimized for static
--- files, more easily set expires and cache values, and avoid possibly
--- costly transference of cookies on static files. For more information,
--- please see:
---   http://code.google.com/speed/page-speed/docs/request.html#ServeFromCookielessDomain
---
--- If you change the resource pattern for StaticR in tkyprof.hs, you will
--- have to make a corresponding change here.
---
--- To see how this value is used, see urlRenderOverride in tkyprof.hs
-staticroot :: Text
-staticroot = approot `mappend` "/static"
-
 -- The rest of this file contains settings which rarely need changing by a
 -- user.
 
@@ -76,35 +42,5 @@
 -- used; to get the same auto-loading effect, it is recommended that you
 -- use the devel server.
 
-toHamletFile, toJuliusFile, toLuciusFile :: String -> FilePath
-toHamletFile x = "hamlet/" ++ x ++ ".hamlet"
-toJuliusFile x = "julius/" ++ x ++ ".julius"
-toLuciusFile x = "lucius/" ++ x ++ ".lucius"
-
-hamletFile :: FilePath -> Q Exp
-hamletFile = H.hamletFile . toHamletFile
-
-luciusFile :: FilePath -> Q Exp
-#ifdef PRODUCTION
-luciusFile = H.luciusFile . toLuciusFile
-#else
-luciusFile = H.luciusFileDebug . toLuciusFile
-#endif
-
-juliusFile :: FilePath -> Q Exp
-#ifdef PRODUCTION
-juliusFile = H.juliusFile . toJuliusFile
-#else
-juliusFile = H.juliusFileDebug . toJuliusFile
-#endif
-
 widgetFile :: FilePath -> Q Exp
-widgetFile x = do
-  let h = unlessExists toHamletFile hamletFile
-  let j = unlessExists toJuliusFile juliusFile
-  let l = unlessExists toLuciusFile luciusFile
-  [|addWidget $h >> addJulius $j >> addLucius $l|]
-  where
-    unlessExists tofn f = do
-      e <- qRunIO $ doesFileExist $ tofn x
-      if e then f x else [|mempty|]
+widgetFile = widgetFileNoReload def
diff --git a/config/StaticFiles.hs b/config/StaticFiles.hs
--- a/config/StaticFiles.hs
+++ b/config/StaticFiles.hs
@@ -1,7 +1,7 @@
-{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies #-}
+{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings #-}
 module StaticFiles where
 
-import Yesod.Helpers.Static
+import Yesod.Static
 
 -- | This generates easy references to files in the static directory at compile time.
 --   The upside to this is that you have compile-time verification that referenced files
diff --git a/hamlet/default-layout.hamlet b/hamlet/default-layout.hamlet
deleted file mode 100644
--- a/hamlet/default-layout.hamlet
+++ /dev/null
@@ -1,15 +0,0 @@
-!!!
-<html lang="en">
-  <head>
-    <meta charset="utf-8" />
-    <link rel="shortcut icon" type=image/png href=@{FaviconR}>
-    <link href="http://fonts.googleapis.com/css?family=Amaranth:400,700" rel="stylesheet" type="text/css">
-    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
-    <title>#{pageTitle pc}
-    ^{pageHead pc}
-  <body>
-    $maybe msg <- mmsg
-      <div #message>#{msg}
-    ^{pageBody pc}
-    <footer>
-      Copyright &copy;<time datetime="2011-08-02">2011</time>Mitsutoshi Aoe
diff --git a/hamlet/header.hamlet b/hamlet/header.hamlet
deleted file mode 100644
--- a/hamlet/header.hamlet
+++ /dev/null
@@ -1,13 +0,0 @@
-<div #header>
-  <nav #breadcrumbs>
-    <h1>
-      <a href=@{HomeR}>
-        <img #logo src=@{StaticR images_tkyprof_logo_orange_png} alt="Home">
-        TKYPr
-        <span #o>o
-        f
-    $forall bc <- bcs
-      <a href=@{fst bc}>#{snd bc}
-      <span .breadcrumbs-delimiter>>
-    #{title}
-
diff --git a/hamlet/home.hamlet b/hamlet/home.hamlet
deleted file mode 100644
--- a/hamlet/home.hamlet
+++ /dev/null
@@ -1,17 +0,0 @@
-<h2>1. Select your profiling reports
-<form #uploader action=@{ReportsR} method=post enctype=#{Multipart}>
-  <div #box-wrapper>
-    <div #uploader-dropbox .box>
-      <p>Drop files here!
-    <div #uploader-filedialog .box>
-      <p>Click to select files.
-      <input type=file>
-<h2>
-  <a href=@{ReportsR}>2. View reports
-$maybe _ <- listToMaybe reports
-  <ul>
-    $forall report <- reports
-      <li>
-        <a href=@{ReportsIdR (fst report)}>#{reportCommandLine (snd report)}
-$nothing
-  <p>There are currently no reports available. First of all, upload your profiling reports please.
diff --git a/hamlet/reports-id.hamlet b/hamlet/reports-id.hamlet
deleted file mode 100644
--- a/hamlet/reports-id.hamlet
+++ /dev/null
@@ -1,43 +0,0 @@
-<section #cost-centres>
-  <header>
-    <div .button-group>
-      <h2 #time .button>Time profiling
-      <h2 #alloc .button>Alloc profiling
-  <div #chart-container>
-    <figure #chart>
-    <div #sidebox>
-      <div #current-node>
-        <h2>Current node
-        <dl>
-          <dt>Module
-          <dd #current-node-module>
-          <dt>Name
-          <dd #current-node-name>
-          <dt>Number
-          <dd #current-node-number>
-          <dt>Entries
-          <dd #current-node-entries>
-          <dt>Individual %time
-          <dd #current-node-ind-time>
-          <dt>Individual %alloc
-          <dd #current-node-ind-alloc>
-          <dt>Inherited %time
-          <dd #current-node-inh-time>
-          <dt>Inherited %alloc
-          <dd #current-node-inh-alloc>
-      <div #children>
-        <h2>Children
-        <ol>
-<section #summary>
-  <h2>Summary
-  <div #report-summary .box>
-    <dl>
-      <dt>Timestamp
-      <dd>#{show reportTimestamp}
-      <dt>Command line
-      <dd>#{reportCommandLine}
-      <dt>Total time
-      <dd>#{totalSecs reportTotalTime} seconds
-      <dd>#{totalTicks reportTotalTime} ticks @ #{resolution reportTotalTime} ms
-      <dt>Total allocations
-      <dd>#{totalAllocBytes reportTotalAlloc} bytes
diff --git a/hamlet/reports.hamlet b/hamlet/reports.hamlet
deleted file mode 100644
--- a/hamlet/reports.hamlet
+++ /dev/null
@@ -1,8 +0,0 @@
-<h2>All reports
-$maybe _ <- listToMaybe reports
-  <ul>
-    $forall report <- reports
-      <li>
-        <a href=@{ReportsIdR (fst report)}>#{reportCommandLine (snd report)}
-$nothing
-  <p>There are currently no reports available. First of all, upload your profiling reports please.
diff --git a/julius/home.julius b/julius/home.julius
deleted file mode 100644
--- a/julius/home.julius
+++ /dev/null
@@ -1,13 +0,0 @@
-$(function() {
-  var uploader = $('#uploader');
-
-  uploader.bind('fileuploaddone', function(e, data) {
-    top.location.href = data.jqXHR.getResponseHeader('Location');
-  });
-
-  uploader.fileupload({
-    url:               "/reports",
-    paramName:         "reports",
-    singleFileUploads: false
-  });
-});
diff --git a/julius/reports-id.julius b/julius/reports-id.julius
deleted file mode 100644
--- a/julius/reports-id.julius
+++ /dev/null
@@ -1,287 +0,0 @@
-$(function() {
-  var data = #{json};
-  var parmalink = costCentreParmalink();
-  var chart = costCentreChart({
-    data: data,
-    parmalink: parmalink
-  });
-  var button = profilingModeButton({
-    chart: chart,
-    parmalink: parmalink
-  });
-
-  chart.transposeById(parmalink.id());
-  $(window).bind('popstate', function(event) {
-    if (!window.history.ready && !event.originalEvent.state) {
-      return; // workaround for popstate on load
-    }
-    parmalink.popstate(location.pathname);
-    button.mode(parmalink.mode());
-    chart.mode(parmalink.mode());
-    chart.transposeById(parmalink.id());
-  });
-});
-
-function costCentreParmalink(spec) {
-  var that = {};
-  var parsed = parse(location.pathname),
-      prefix = parsed[1],
-      mode   = parsed[2],
-      suffix = parsed[3];
-
-  function pathname() {
-    return prefix + mode + suffix;
-  };
-
-  function parse(path) {
-    var regex = /^(\/reports\/[0-9]+\/)(time|alloc)(.*)$/;
-    return regex.exec(path);
-  }
-
-  that.mode = function(newMode) {
-    if (!newMode)
-      return mode; // getter
-
-    mode = newMode;
-    window.history.ready = true; // workaround for popstate on load
-    history.pushState(null, null, pathname()); // HTML 5 History API
-    return mode;
-  };
-
-  that.transpose = function(node) {
-    var cursor = node, path = [];
-    for (cursor = node; cursor.parent; cursor = cursor.parent) {
-      path.unshift(cursor.no);
-    }
-    if (path.length > 0) {
-      suffix = "/" + path.join("/");
-    } else {
-      suffix = "";
-    }
-  };
-
-  that.popstate = function(url) {
-    var parsed = parse(url);
-    mode   = parsed[2];
-    suffix = parsed[3];
-  };
-
-  that.id = function() {
-    var regex = /^.*\/([0-9]*)$/;
-    var matched = regex.exec(suffix);
-    return matched ? matched[1] : null;
-  };
-
-  that.pathname = pathname;
-
-  return that;
-}
-
-function profilingModeButton(spec) {
-  var that = {};
-  var chart = spec.chart, parmalink = spec.parmalink;
-  var timeButton  = $("#time"),
-      allocButton = $("#alloc"),
-      _mode;
-
-  // methods
-  var mode = function(newMode) {
-    if (!newMode)
-      return _mode; // getter
-
-    _mode = newMode;
-    // buttons
-    if (_mode == "time") {
-      timeButton.addClass("active");
-      allocButton.removeClass("active");
-    } else {
-      timeButton.removeClass("active");
-      allocButton.addClass("active");
-    }
-    // chart
-    chart.mode(_mode);
-    return _mode;
-  };
-
-  // setup initial states and event handlers
-  mode(parmalink.mode());
-  timeButton.click(function(event) {
-    parmalink.mode("time");
-    mode(parmalink.mode());
-  });
-  allocButton.click(function(event) {
-    parmalink.mode("alloc");
-    mode(parmalink.mode());
-  });
-
-  // public slots
-  that.mode = mode;
-
-  return that;
-}
-
-function costCentreChart(spec) {
-  var that = {};
-
-  var cursor = spec.data,
-      selector = spec.selector,
-      parmalink = spec.parmalink;
-  var context = costCentreContext({cursor: cursor});
-
-  // chart
-  var chart = $("#chart"),
-      w = spec.w || chart.width(),
-      h = spec.h || chart.height(),
-      r = Math.min(w, h) / 2,
-      x = d3.scale.linear().range([0, 2*Math.PI]),
-      y = d3.scale.sqrt().range([0, r]),
-      color = spec.color || d3.scale.category20c();
-
-  var vis = d3.select("#chart")
-    .append("svg:svg")
-    .attr("width", w)
-    .attr("height", h)
-    .append("svg:g")
-    .attr("transform", "translate(" + w/2 + "," + h/2 + ")");
-
-  var partition = d3.layout.partition()
-    .children(function(d) { return d.subForest; })
-    .value(value(parmalink.mode()));
-
-  var arc = d3.svg.arc()
-    .startAngle(function(d) { return Math.max(0, Math.min(2*Math.PI, x(d.x))); })
-    .endAngle(function(d) { return Math.max(0, Math.min(2*Math.PI, x(d.x + d.dx))); })
-    .innerRadius(function(d) { return Math.max(0, y(d.y)); })
-    .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
-
-  var path = vis.data([cursor]).selectAll("path")
-    .data(partition.nodes)
-    .enter().append("svg:path")
-    .attr("d", arc)
-    .attr("id", function(d) { return "cc" + d.no + (d.isParent ? "p" : ""); })
-    .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
-    .on("click", click)
-    .on("mouseover", mouseover)
-    .each(function(d) { d.x0 = d.x; d.dx0 = d.dx; }); // stash the old values for transition
-
-  // event handlers
-  function click(d) {
-    transpose(d);
-    parmalink.transpose(d);
-    window.history.ready = true; // workaround for popstate on load
-    history.pushState(null, null, parmalink.pathname()); // HTML 5 History API
-  }
-
-  function mouseover(d) {
-    // XXX
-  }
-
-  // tweeners
-  function arcTween(a) {
-    var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
-    return function(t) {
-      var b = i(t);
-      a.x0  = b.x;
-      a.dx0 = b.dx;
-      return arc(b);
-    };
-  }
-
-  function zoomTween(d) {
-    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
-        yd = d3.interpolate(y.domain(), [d.y, 1]),
-        yr = d3.interpolate(y.range(), [d.y ? 20 : 0, r]);
-    return function(d, i) {
-      return i
-        ? function(t) { return arc(d); }
-        : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
-    };
-  }
-
-  // helper functions
-  function value(mode) {
-    if (mode === "time")
-      return function(d) { return d.individualTime; };
-    else
-      return function(d) { return d.individualAlloc; };
-  }
-
-  function nodeFromId(id) {
-    if (!id)
-      return null;
-    var elem = d3.select("#cc" + id);
-    return elem.node().__data__; // XXX: __data__ is not a public API
-  }
-
-  var mode = function(mode) {
-    path.data(partition.value(value(mode)))
-      .transition()
-      .duration(500)
-      .attrTween("d", arcTween);
-  };
-
-  var transpose = function(node) {
-    cursor = node;
-    context.transpose(cursor);
-    path.transition()
-      .duration(500)
-      .attrTween("d", zoomTween(node));
-  };
-
-  var transposeById = function(id) {
-    transpose(nodeFromId(id) || spec.data);
-  };
-
-  // public slots
-  that.mode = mode;
-  that.transpose = transpose;
-  that.transposeById = transposeById;
-
-  // setup initial states
-  mode(parmalink.mode());
-  transposeById(parmalink.id());
-
-  return that;
-}
-
-function costCentreContext(spec) {
-  var that = {};
-  var cursor = spec.cursor;
-
-  var showCostCentre = function(node) {
-    var currentNode = $("#current-node dl");
-    $("#current-node-module",    currentNode).text(node.module);
-    $("#current-node-name",      currentNode).text(node.name);
-    $("#current-node-number",    currentNode).text(node.no);
-    $("#current-node-entries",   currentNode).text(node.entries);
-    $("#current-node-ind-time",  currentNode).text(node.individualTime);
-    $("#current-node-ind-alloc", currentNode).text(node.individualAlloc);
-    $("#current-node-inh-time",  currentNode).text(node.inheritedTime);
-    $("#current-node-inh-alloc", currentNode).text(node.inheritedAlloc);
-  };
-
-  var showChildren = function(node) {
-    $("#children ol li").remove();
-    var children = $("#children ol");
-    var cs = node.children;
-    if (cs) {
-      var n = cs.length < 10 ? cs.length : 10;
-      for (var i = 0; i < n; i++) {
-        children.append("<li>" + cs[i].name + "</li>");
-      }
-    }
-  };
-
-  // setup
-  showCostCentre(cursor);
-  showChildren(cursor);
-
-  // public slots
-  that.transpose = function(node) {
-    cursor = node;
-    showCostCentre(cursor);
-    showChildren(cursor);
-  };
-
-  return that;
-}
diff --git a/julius/reports.julius b/julius/reports.julius
deleted file mode 100644
--- a/julius/reports.julius
+++ /dev/null
@@ -1,3 +0,0 @@
-$(function() {
-  console.log("reports");
-});
diff --git a/lucius/default-layout.lucius b/lucius/default-layout.lucius
deleted file mode 100644
--- a/lucius/default-layout.lucius
+++ /dev/null
@@ -1,38 +0,0 @@
-/* body */
-body {
-  color: #f3f3e3;
-  background: #212121;
-  font-family: sans-serif;
-}
-
-/* hx */
-h1, h2, h3, h4 {
-  font-family: 'Amaranth', sans-serif;
-  font-weight: 400;
-}
-
-h1 {
-  font-size: 2em;
-}
-
-h2 {
-  font-size: 1.5em;
-}
-
-/* a */
-a {
-  color: #f3f3e3;
-  text-decoration: none;
-}
-
-section a:hover {
-  color: #e6550d;
-  text-decoration: underline;
-}
-
-/* footer */
-footer {
-  text-align: right;
-  font-size: 0.75em;
-  visibility: hidden;
-}
diff --git a/lucius/header.lucius b/lucius/header.lucius
deleted file mode 100644
--- a/lucius/header.lucius
+++ /dev/null
@@ -1,32 +0,0 @@
-#header {
-  height: 38px;
-  width: 100%;
-}
-
-#header h1 {
-  font-family: 'Amaranth', sans-serif;
-  font-weight: 700;
-  font-size: 30px;
-  margin: 0px;
-  margin-right: 10px;
-  display: inline;
-}
-
-#header h1 #logo {
-  margin-right: 5px;
-}
-
-#header h1 #o {
-  color: #e6550d;
-}
-
-/* breadcrumbs */
-#breadcrumbs {
-  font-family: sans-serif;
-  font-size: 0.75em;
-}
-
-.breadcrumbs-delimiter {
-  margin-left: 0.5em;
-  margin-right: 0.5em;
-}
diff --git a/lucius/home.lucius b/lucius/home.lucius
deleted file mode 100644
--- a/lucius/home.lucius
+++ /dev/null
@@ -1,52 +0,0 @@
-#box-wrapper {
-  width: 100%;
-
-  display: -webkit-box;
-  display: -moz-box;
-  display: box;
-
-  -webkit-box-align: center;
-  -moz-box-align: center;
-  box-align: center;
-
-  -webkit-box-pack: center;
-  -moz-box-pack: center;
-  box-pack: center;
-}
-
-.box {
-  width: 50%;
-  text-align: center;
-  box-sizing: border-box;
-}
-
-/* dropbox */
-#uploader-dropbox {
-  height: 200px;
-  border: 2px dashed #fd8d38;
-
-  -webkit-border-radius: 10px;
-  -moz-border-radius: 10px;
-  border-radius: 10px;
-
-  display: -webkit-box;
-  display: -moz-box;
-  display: box;
-
-  -webkit-box-align: center;
-  -moz-box-align: center;
-  box-align: center;
-
-  -webkit-box-pack: center;
-  -moz-box-pack: center;
-  box-pack: center;
-}
-
-#uploader-dropbox:hover {
-  border: 2px solid #e6550d;
-}
-
-/* file dialog */
-#uploader-filedialog {
-  /* do nothing */
-}
diff --git a/lucius/reports-id.lucius b/lucius/reports-id.lucius
deleted file mode 100644
--- a/lucius/reports-id.lucius
+++ /dev/null
@@ -1,113 +0,0 @@
-/* title and buttons */
-#cost-centres > header {
-  margin: 1em;
-}
-#cost-centres h2 {
-  display: inline;
-  font-size: 1.5em;
-}
-
-#cost-centres .button {
-  border: 1.5px solid transparent;
-  padding-left: 4px;
-  padding-right: 4px;
-  cursor: pointer;
-}
-
-#cost-centres .button:hover {
-  /* border: 1.5px solid #fd8d38; */
-  border: 1.5px solid #f3f3e3;
-}
-
-#cost-centres .active {
-  /* border: 1.5px solid #fd8d38; */
-  /* background: #fd8d38; */
-  border: 1.5px solid #f3f3e3;
-  background: #f3f3e3;
-  color: #212121;
-}
-
-#cost-centres .button:first-child {
-  -webkit-border-top-left-radius: 0.5em;
-  -moz-border-top-left-radius: 0.5em;
-  border-top-left-radius: 0.5em;
-  -webkit-border-bottom-left-radius: 0.5em;
-  -moz-border-bottom-left-radius: 0.5em;
-  border-bottom-left-radius: 0.5em;
-}
-
-#cost-centres .button:last-child {
-  -webkit-border-top-right-radius: 0.5em;
-  -moz-border-top-right-radius: 0.5em;
-  border-top-right-radius: 0.5em;
-  -webkit-border-bottom-right-radius: 0.5em;
-  -moz-border-bottom-right-radius: 0.5em;
-  border-bottom-right-radius: 0.5em;
-}
-
-
-/* chart */
-#chart-container {
-  width: 100%;
-  font-size: 0.85em;
-
-  display: -webkit-box;
-  display: -moz-box;
-  display: box;
-}
-
-#chart {
-  -webkit-box-flex: 1;
-  -moz-box-flex: 1;
-  box-flex: 1;
-  min-height: 400px;
-  -webkit-box-ordinal-group: 1;
-  -moz-box-ordinal-group: 1;
-  box-ordinal-group: 1;
-}
-
-#chart path {
-  stroke: #212121;
-  stroke-width: 0.5;
-  fill-rule: evenodd;
-  opacity: 1;
-}
-
-/* sidebox */
-#sidebox {
-  background: #353535;
-  padding: 1em;
-  padding-top: 0.5em;
-  width: 18em;
-  min-height: 37em;
-  -webkit-box-ordinal-group: 2;
-  -moz-box-ordinal-group: 2;
-  box-ordinal-group: 2;
-  text-overflow: ellipsis;
-  overflow: hidden;
-
-  -webkit-border-radius: 10px;
-  -moz-border-radius: 10px;
-  border-radius: 10px;
-}
-
-#sidebox dt {
-  float: left;
-}
-
-#sidebox dd {
-  margin-left: 10em;
-}
-
-/* summary */
-#report-summary {
-  font-size: 0.85em;
-}
-
-#report-summary dt {
-  float: left;
-}
-
-#report-summary dd {
-  margin-left: 10em;
-}
diff --git a/lucius/reports.lucius b/lucius/reports.lucius
deleted file mode 100644
--- a/lucius/reports.lucius
+++ /dev/null
diff --git a/static/js/d3.layout.min.js b/static/js/d3.layout.min.js
--- a/static/js/d3.layout.min.js
+++ b/static/js/d3.layout.min.js
@@ -1,1 +1,1 @@
-(function(){function bj(a,b){var c=a.x+b[3],d=a.y+b[0],e=a.dx-b[1]-b[3],f=a.dy-b[0]-b[2];e<0&&(c+=e/2,e=0),f<0&&(d+=f/2,f=0);return{x:c,y:d,dx:e,dy:f}}function bi(a){return{x:a.x,y:a.y,dx:a.dx,dy:a.dy}}function bh(a,b,c){return a._tree.ancestor.parent==b.parent?a._tree.ancestor:c}function bg(a,b,c){a=a._tree,b=b._tree;var d=c/(b.number-a.number);a.change+=d,b.change-=d,b.shift+=c,b.prelim+=c,b.mod+=c}function bf(a){var b=0,c=0,d=a.children,e=d.length,f;while(--e>=0)f=d[e]._tree,f.prelim+=b,f.mod+=b,b+=f.shift+(c+=f.change)}function be(a,b){function c(a,d){var e=a.children;if(e){var f,g=null,h=-1,i=e.length;while(++h<i)f=e[h],c(f,g),g=f}b(a,d)}c(a,null)}function bd(a,b){return a.depth-b.depth}function bc(a,b){return b.x-a.x}function bb(a,b){return a.x-b.x}function ba(a,b){var c=a.children;if(c){var d,e=c.length,f=-1;while(++f<e)b(d=ba(c[f],b),a)>0&&(a=d)}return a}function _(a){return a.children?a.children[a.children.length-1]:a._tree.thread}function $(a){return a.children?a.children[0]:a._tree.thread}function Z(a,b){return a.parent==b.parent?1:2}function Y(a){var b=a.children;return b?Y(b[b.length-1]):a}function X(a){var b=a.children;return b?X(b[0]):a}function W(a){return a.reduce(function(a,b){return a+b.x},0)/a.length}function V(a){return 1+d3.max(a,function(a){return a.y})}function U(a,b,c){var d=b.r+c.r,e=a.r+c.r,f=b.x-a.x,g=b.y-a.y,h=Math.sqrt(f*f+g*g),i=(e*e+h*h-d*d)/(2*e*h),j=Math.acos(i),k=i*e,l=Math.sin(j)*e;f/=h,g/=h,c.x=a.x+k*f+l*g,c.y=a.y+k*g-l*f}function T(a,b,c,d){var e=a.children;a.x=b+=d*a.x,a.y=c+=d*a.y,a.r*=d;if(e){var f=-1,g=e.length;while(++f<g)T(e[f],b,c,d)}}function S(a){var b=a.children;b?(b.forEach(S),a.r=P(b)):a.r=Math.sqrt(a.value)}function R(a){delete a._pack_next,delete a._pack_prev}function Q(a){a._pack_next=a._pack_prev=a}function P(a){function l(a){b=Math.min(a.x-a.r,b),c=Math.max(a.x+a.r,c),d=Math.min(a.y-a.r,d),e=Math.max(a.y+a.r,e)}var b=Infinity,c=-Infinity,d=Infinity,e=-Infinity,f=a.length,g,h,i,j,k;a.forEach(Q),g=a[0],g.x=-g.r,g.y=0,l(g);if(f>1){h=a[1],h.x=h.r,h.y=0,l(h);if(f>2){i=a[2],U(g,h,i),l(i),M(g,i),g._pack_prev=i,M(i,h),h=g._pack_next;for(var m=3;m<f;m++){U(g,h,i=a[m]);var n=0,o=1,p=1;for(j=h._pack_next;j!==h;j=j._pack_next,o++)if(O(j,i)){n=1;break}if(n==1)for(k=g._pack_prev;k!==j._pack_prev;k=k._pack_prev,p++)if(O(k,i)){p<o&&(n=-1,j=k);break}n==0?(M(g,i),h=i,l(i)):n>0?(N(g,j),h=j,m--):(N(j,h),g=j,m--)}}}var q=(b+c)/2,r=(d+e)/2,s=0;for(var m=0;m<f;m++){var t=a[m];t.x-=q,t.y-=r,s=Math.max(s,t.r+Math.sqrt(t.x*t.x+t.y*t.y))}a.forEach(R);return s}function O(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r+b.r;return e*e-c*c-d*d>.001}function N(a,b){a._pack_next=b,b._pack_prev=a}function M(a,b){var c=a._pack_next;a._pack_next=b,b._pack_prev=a,b._pack_next=c,c._pack_prev=b}function L(a,b){return a.value-b.value}function J(a){return d3.merge(a.map(function(a){return(a.children||[]).map(function(b){return{source:a,target:b}})}))}function I(a,b){return b.value-a.value}function H(a){return a.value}function G(a){return a.children}function F(a,b){a.sort=d3.rebind(a,b.sort),a.children=d3.rebind(a,b.children),a.links=J,a.value=d3.rebind(a,b.value),a.nodes=function(b){K=!0;return(a.nodes=a)(b)};return a}function E(a){return[d3.min(a),d3.max(a)]}function D(a,b){var c=-1,d=+a[0],e=(a[1]-d)/b,f=[];while(++c<=b)f[c]=e*c+d;return f}function C(a,b){return D(a,Math.ceil(Math.log(b.length)/Math.LN2+1))}function B(a,b){return a+b[1]}function A(a){return a.reduce(B,0)}function z(a){var b=1,c=0,d=a[0][1],e,f=a.length;for(;b<f;++b)(e=a[b][1])>d&&(c=b,d=e);return c}function w(a,b,c){a.y0=b,a.y=c}function v(a){return a.y}function u(a){return a.x}function t(a){return 1}function s(a){return 20}function r(a){var b=0,c=0;a.count=0;if(!a.leaf){var d=a.nodes,e=d.length,f=-1,g;while(++f<e){g=d[f];if(g==null)continue;r(g),a.count+=g.count,b+=g.count*g.cx,c+=g.count*g.cy}}a.point&&(a.leaf||(a.point.x+=Math.random()-.5,a.point.y+=Math.random()-.5),a.count++,b+=a.point.x,c+=a.point.y),a.cx=b/a.count,a.cy=c/a.count}function q(){d3.event.stopPropagation(),d3.event.preventDefault()}function p(){i&&(q(),i=!1)}function o(){!f||(g&&(i=!0,q()),d3.event.type==="mouseup"&&n(),f.fixed=!1,e=h=f=j=null)}function n(){if(!!f){var a=j.parentNode;if(!a){f.fixed=!1,h=f=j=null;return}var b=m(a);g=!0,f.px=b[0]-h[0],f.py=b[1]-h[1],q(),e.resume()}}function m(a){return d3.event.touches?d3.svg.touches(a)[0]:d3.svg.mouse(a)}function l(a){a!==f&&(a.fixed=!1)}function k(a){a.fixed=!0}function c(a,c){if(a===c)return a;var d=b(a),e=b(c),f=d.pop(),g=e.pop(),h=null;while(f===g)h=f,f=d.pop(),g=e.pop();return h}function b(a){var b=[],c=a.parent;while(c!=null)b.push(a),a=c,c=c.parent;b.push(a);return b}function a(a){var b=a.source,d=a.target,e=c(b,d),f=[b];while(b!==e)b=b.parent,f.push(b);var g=f.length;while(d!==e)f.splice(g,0,d),d=d.parent;return f}d3.layout={},d3.layout.bundle=function(){return function(b){var c=[],d=-1,e=b.length;while(++d<e)c.push(a(b[d]));return c}},d3.layout.chord=function(){function k(){b.sort(function(a,b){return i(a.target.value,b.target.value)})}function j(){var a={},j=[],l=d3.range(e),m=[],n,o,p,q,r;b=[],c=[],n=0,q=-1;while(++q<e){o=0,r=-1;while(++r<e)o+=d[q][r];j.push(o),m.push(d3.range(e)),n+=o}g&&l.sort(function(a,b){return g(j[a],j[b])}),h&&m.forEach(function(a,b){a.sort(function(a,c){return h(d[b][a],d[b][c])})}),n=(2*Math.PI-f*e)/n,o=0,q=-1;while(++q<e){p=o,r=-1;while(++r<e){var s=l[q],t=m[q][r],u=d[s][t];a[s+"-"+t]={index:s,subindex:t,startAngle:o,endAngle:o+=u*n,value:u}}c.push({index:s,startAngle:p,endAngle:o,value:(o-p)/n}),o+=f}q=-1;while(++q<e){r=q-1;while(++r<e){var v=a[q+"-"+r],w=a[r+"-"+q];(v.value||w.value)&&b.push(v.value<w.value?{source:w,target:v}:{source:v,target:w})}}i&&k()}var a={},b,c,d,e,f=0,g,h,i;a.matrix=function(f){if(!arguments.length)return d;e=(d=f)&&d.length,b=c=null;return a},a.padding=function(d){if(!arguments.length)return f;f=d,b=c=null;return a},a.sortGroups=function(d){if(!arguments.length)return g;g=d,b=c=null;return a},a.sortSubgroups=function(c){if(!arguments.length)return h;h=c,b=null;return a},a.sortChords=function(c){if(!arguments.length)return i;i=c,b&&k();return a},a.chords=function(){b||j();return b},a.groups=function(){c||j();return c};return a},d3.layout.force=function(){function G(b,c){var d=m(this.parentNode);(f=b).fixed=!0,g=!1,j=this,e=a,h=[d[0]-b.x,d[1]-b.y],q()}function F(){var a=A.length,e=B.length,f=d3.geom.quadtree(A),g,h,j,k,l,m,n;for(g=0;g<e;++g){h=B[g],j=h.source,k=h.target,m=k.x-j.x,n=k.y-j.y;if(l=m*m+n*n)l=d*D[g]*((l=Math.sqrt(l))-C[g])/l,m*=l,n*=l,k.x-=m,k.y-=n,j.x+=m,j.y+=n}var o=d*x;m=c[0]/2,n=c[1]/2,g=-1;while(++g<a)h=A[g],h.x+=(m-h.x)*o,h.y+=(n-h.y)*o;r(f);var p=d*w;g=-1;while(++g<a)f.visit(E(A[g],p));g=-1;while(++g<a)h=A[g],h.fixed?(h.x=h.px,h.y=h.py):(h.x-=(h.px-(h.px=h.x))*i,h.y-=(h.py-(h.py=h.y))*i);b.tick.dispatch({type:"tick",alpha:d});return(d*=.99)<.005}function E(a,b){return function(c,d,e,f,g){if(c.point!==a){var h=c.cx-a.x,i=c.cy-a.y,j=1/Math.sqrt(h*h+i*i);if((f-d)*j<y){var k=b*c.count*j*j;a.x+=h*k,a.y+=i*k;return!0}if(c.point&&isFinite(j)){var k=b*j*j;a.x+=h*k,a.y+=i*k}}}}var a={},b=d3.dispatch("tick"),c=[1,1],d,i=.9,u=s,v=t,w=-30,x=.1,y=.8,z,A=[],B=[],C,D;a.on=function(c,d){b[c].add(d);return a},a.nodes=function(b){if(!arguments.length)return A;A=b;return a},a.links=function(b){if(!arguments.length)return B;B=b;return a},a.size=function(b){if(!arguments.length)return c;c=b;return a},a.linkDistance=function(b){if(!arguments.length)return u;u=d3.functor(b);return a},a.distance=a.linkDistance,a.linkStrength=function(b){if(!arguments.length)return v;v=d3.functor(b);return a},a.friction=function(b){if(!arguments.length)return i;i=b;return a},a.charge=function(b){if(!arguments.length)return w;w=b;return a},a.gravity=function(b){if(!arguments.length)return x;x=b;return a},a.theta=function(b){if(!arguments.length)return y;y=b;return a},a.start=function(){function l(){if(!i){i=[];for(d=0;d<e;++d)i[d]=[];for(d=0;d<f;++d){var a=B[d];i[a.source.index].push(a.target),i[a.target.index].push(a.source)}}return i[b]}function k(a,c){var d=l(b),e=-1,f=d.length,g;while(++e<f)if(!isNaN(g=d[e][a]))return g;return Math.random()*c}var b,d,e=A.length,f=B.length,g=c[0],h=c[1],i,j;for(b=0;b<e;++b)(j=A[b]).index=b;C=[],D=[];for(b=0;b<f;++b)j=B[b],typeof j.source=="number"&&(j.source=A[j.source]),typeof j.target=="number"&&(j.target=A[j.target]),C[b]=u.call(this,j,b),D[b]=v.call(this,j,b);for(b=0;b<e;++b)j=A[b],isNaN(j.x)&&(j.x=k("x",g)),isNaN(j.y)&&(j.y=k("y",h)),isNaN(j.px)&&(j.px=j.x),isNaN(j.py)&&(j.py=j.y);return a.resume()},a.resume=function(){d=.1,d3.timer(F);return a},a.stop=function(){d=0;return a},a.drag=function(){this.on("mouseover.force",k).on("mouseout.force",l).on("mousedown.force",G).on("touchstart.force",G),d3.select(window).on("mousemove.force",n).on("touchmove.force",n).on("mouseup.force",o,!0).on("touchend.force",o,!0).on("click.force",p,!0);return a};return a};var e,f,g,h,i,j;d3.layout.partition=function(){function e(e,f){var g=a.call(this,e,f);c(g[0],0,b[0],b[1]/d(g[0]));return g}function d(a){var b=a.children,c=0;if(b){var e=-1,f=b.length;while(++e<f)c=Math.max(c,d(b[e]))}return 1+c}function c(a,b,d,e){var f=a.children;a.x=b,a.y=a.depth*e,a.dx=d,a.dy=e;if(f){var g=-1,h=f.length,i,j;d=a.value===0?0:d/a.value;while(++g<h)c(i=f[g],b,j=i.value*d,e),b+=j}}var a=d3.layout.hierarchy(),b=[1,1];e.size=function(a){if(!arguments.length)return b;b=a;return e};return F(e,a)},d3.layout.pie=function(){function f(f,g){var h=+(typeof c=="function"?c.apply(this,arguments):c),i=(typeof e=="function"?e.apply(this,arguments):e)-c,j=d3.range(f.length);b!=null&&j.sort(function(a,c){return b(f[a],f[c])});var k=f.map(a);i/=k.reduce(function(a,b){return a+b},0);var l=j.map(function(a){return{data:f[a],value:d=k[a],startAngle:h,endAngle:h+=d*i}});return f.map(function(a,b){return l[j[b]]})}var a=Number,b=null,c=0,e=2*Math.PI;f.value=function(b){if(!arguments.length)return a;a=b;return f},f.sort=function(a){if(!arguments.length)return b;b=a;return f},f.startAngle=function(a){if(!arguments.length)return c;c=a;return f},f.endAngle=function(a){if(!arguments.length)return e;e=a;return f};return f},d3.layout.stack=function(){function g(h,i){var j=h.map(function(b,c){return a.call(g,b,c)}),k=j.map(function(a,b){return a.map(function(a,b){return[e.call(g,a,b),f.call(g,a,b)]})}),l=b.call(g,k,i);j=d3.permute(j,l),k=d3.permute(k,l);var m=c.call(g,k,i),n=j.length,o=j[0].length,p,q,r;for(q=0;q<o;++q){d.call(g,j[0][q],r=m[q],k[0][q][1]);for(p=1;p<n;++p)d.call(g,j[p][q],r+=k[p-1][q][1],k[p][q][1])}return h}var a=Object,b=x["default"],c=y.zero,d=w,e=u,f=v;g.values=function(b){if(!arguments.length)return a;a=b;return g},g.order=function(a){if(!arguments.length)return b;b=typeof a=="function"?a:x[a];return g},g.offset=function(a){if(!arguments.length)return c;c=typeof a=="function"?a:y[a];return g},g.x=function(a){if(!arguments.length)return e;e=a;return g},g.y=function(a){if(!arguments.length)return f;f=a;return g},g.out=function(a){if(!arguments.length)return d;d=a;return g};return g};var x={"inside-out":function(a){var b=a.length,c,d,e=a.map(z),f=a.map(A),g=d3.range(b).sort(function(a,b){return e[a]-e[b]}),h=0,i=0,j=[],k=[];for(c=0;c<b;++c)d=g[c],h<i?(h+=f[d],j.push(d)):(i+=f[d],k.push(d));return k.reverse().concat(j)},reverse:function(a){return d3.range(a.length).reverse()},"default":function(a){return d3.range(a.length)}},y={silhouette:function(a){var b=a.length,c=a[0].length,d=[],e=0,f,g,h,i=[];for(g=0;g<c;++g){for(f=0,h=0;f<b;f++)h+=a[f][g][1];h>e&&(e=h),d.push(h)}for(g=0;g<c;++g)i[g]=(e-d[g])/2;return i},wiggle:function(a){var b=a.length,c=a[0],d=c.length,e=0,f,g,h,i,j,k,l,m,n,o=[];o[0]=m=n=0;for(g=1;g<d;++g){for(f=0,i=0;f<b;++f)i+=a[f][g][1];for(f=0,j=0,l=c[g][0]-c[g-1][0];f<b;++f){for(h=0,k=(a[f][g][1]-a[f][g-1][1])/(2*l);h<f;++h)k+=(a[h][g][1]-a[h][g-1][1])/l;j+=k*a[f][g][1]}o[g]=m-=i?j/i*l:0,m<n&&(n=m)}for(g=0;g<d;++g)o[g]-=n;return o},expand:function(a){var b=a.length,c=a[0].length,d=1/b,e,f,g,h=[];for(f=0;f<c;++f){for(e=0,g=0;e<b;e++)g+=a[e][f][1];if(g)for(e=0;e<b;e++)a[e][f][1]/=g;else for(e=0;e<b;e++)a[e][f][1]=d}for(f=0;f<c;++f)h[f]=0;return h},zero:function(a){var b=-1,c=a[0].length,d=[];while(++b<c)d[b]=0;return d}};d3.layout.histogram=function(){function e(e,f){var g=[],h=e.map(b,this),i=c.call(this,h,f),j=d.call(this,i,h,f),k,f=-1,l=h.length,m=j.length-1,n=a?1:1/l,o;while(++f<m)k=g[f]=[],k.dx=j[f+1]-(k.x=j[f]),k.y=0;f=-1;while(++f<l)o=h[f],o>=i[0]&&o<=i[1]&&(k=g[d3.bisect(j,o,1,m)-1],k.y+=n,k.push(e[f]));return g}var a=!0,b=Number,c=E,d=C;e.value=function(a){if(!arguments.length)return b;b=a;return e},e.range=function(a){if(!arguments.length)return c;c=d3.functor(a);return e},e.bins=function(a){if(!arguments.length)return d;d=typeof a=="number"?function(b){return D(b,a)}:d3.functor(a);return e},e.frequency=function(b){if(!arguments.length)return a;a=!!b;return e};return e},d3.layout.hierarchy=function(){function g(a){var b=[];e(a,0,b);return b}function f(a,b){var d=a.children,e=0;if(d){var h=-1,i=d.length,j=b+1;while(++h<i)e+=f(d[h],j)}else c&&(e=c.call(g,K?a:a.data,b));c&&(a.value=e);return e}function e(f,h,i){var j=b.call(g,f,h),k=K?f:{data:f};k.depth=h,i.push(k);if(j){var l=-1,m=j.length,n=k.children=[],o=0,p=h+1;while(++l<m)d=e(j[l],p,i),d.parent=k,n.push(d),o+=d.value;a&&n.sort(a),c&&(k.value=o)}else c&&(k.value=c.call(g,f,h));return k}var a=I,b=G,c=H;g.sort=function(b){if(!arguments.length)return a;a=b;return g},g.children=function(a){if(!arguments.length)return b;b=a;return g},g.value=function(a){if(!arguments.length)return c;c=a;return g},g.revalue=function(a){f(a,0);return a};return g};var K=!1;d3.layout.pack=function(){function c(c,d){var e=a.call(this,c,d),f=e[0];f.x=0,f.y=0,S(f);var g=b[0],h=b[1],i=1/Math.max(2*f.r/g,2*f.r/h);T(f,g/2,h/2,i);return e}var a=d3.layout.hierarchy().sort(L),b=[1,1];c.size=function(a){if(!arguments.length)return b;b=a;return c};return F(c,a)},d3.layout.cluster=function(){function d(d,e){var f=a.call(this,d,e),g=f[0],h,i=0,j,k;be(g,function(a){a.children?(a.x=W(a.children),a.y=V(a.children)):(a.x=h?i+=b(a,h):0,a.y=0,h=a)});var l=X(g),m=Y(g),n=l.x-b(l,m)/2,o=m.x+b(m,l)/2;be(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=(1-a.y/g.y)*c[1]});return f}var a=d3.layout.hierarchy().sort(null).value(null),b=Z,c=[1,1];d.separation=function(a){if(!arguments.length)return b;b=a;return d},d.size=function(a){if(!arguments.length)return c;c=a;return d};return F(d,a)},d3.layout.tree=function(){function d(d,e){function j(a,c,d){if(c){var e=a,f=a,g=c,h=a.parent.children[0],i=e._tree.mod,j=f._tree.mod,k=g._tree.mod,l=h._tree.mod,m;while(g=_(g),e=$(e),g&&e)h=$(h),f=_(f),f._tree.ancestor=a,m=g._tree.prelim+k-e._tree.prelim-i+b(g,e),m>0&&(bg(bh(g,a,d),a,m),i+=m,j+=m),k+=g._tree.mod,i+=e._tree.mod,l+=h._tree.mod,j+=f._tree.mod;g&&!_(f)&&(f._tree.thread=g,f._tree.mod+=k-j),e&&!$(h)&&(h._tree.thread=e,h._tree.mod+=i-l,d=a)}return d}function i(a,b){a.x=a._tree.prelim+b;var c=a.children;if(c){var d=-1,e=c.length;b+=a._tree.mod;while(++d<e)i(c[d],b)}}function h(a,c){var d=a.children,e=a._tree;if(d){var f=d.length,g=d[0],i,k=g,l,m=-1;while(++m<f)l=d[m],h(l,i),k=j(l,i,k),i=l;bf(a);var n=.5*(g._tree.prelim+l._tree.prelim);c?(e.prelim=c._tree.prelim+b(a,c),e.mod=e.prelim-n):e.prelim=n}else c&&(e.prelim=c._tree.prelim+b(a,c))}var f=a.call(this,d,e),g=f[0];be(g,function(a,b){a._tree={ancestor:a,prelim:0,mod:0,change:0,shift:0,number:b?b._tree.number+1:0}}),h(g),i(g,-g._tree.prelim);var k=ba(g,bc),l=ba(g,bb),m=ba(g,bd),n=k.x-b(k,l)/2,o=l.x+b(l,k)/2,p=m.depth||1;be(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=a.depth/p*c[1],delete a._tree});return f}var a=d3.layout.hierarchy().sort(null).value(null),b=Z,c=[1,1];d.separation=function(a){if(!arguments.length)return b;b=a;return d},d.size=function(a){if(!arguments.length)return c;c=a;return d};return F(d,a)},d3.layout.treemap=function(){function n(b){var d=g||a(b),e=d[0];e.x=0,e.y=0,e.dx=c[0],e.dy=c[1],g&&a.revalue(e),i([e],e.dx*e.dy/e.value),(g?k:j)(e),f&&(g=d);return d}function m(a,c,d,e){var f=-1,g=a.length,h=d.x,i=d.y,j=c?b(a.area/c):0,k;if(c==d.dx){if(e||j>d.dy)j=d.dy;while(++f<g)k=a[f],k.x=h,k.y=i,k.dy=j,h+=k.dx=j?b(k.area/j):0;k.z=!0,k.dx+=d.x+d.dx-h,d.y+=j,d.dy-=j}else{if(e||j>d.dx)j=d.dx;while(++f<g)k=a[f],k.x=h,k.y=i,k.dx=j,i+=k.dy=j?b(k.area/j):0;k.z=!1,k.dy+=d.y+d.dy-i,d.x+=j,d.dx-=j}}function l(a,b){var c=a.area,d,e=0,f=Infinity,g=-1,i=a.length;while(++g<i){if(!(d=a[g].area))continue;d<f&&(f=d),d>e&&(e=d)}c*=c,b*=b;return c?Math.max(b*e*h/c,c/(b*f*h)):Infinity}function k(a){if(!!a.children){var b=e(a),c=a.children.slice(),d,f=[];i(c,b.dx*b.dy/a.value),f.area=0;while(d=c.pop())f.push(d),f.area+=d.area,d.z!=null&&(m(f,d.z?b.dx:b.dy,b,!c.length),f.length=f.area=0);a.children.forEach(k)}}function j(a){if(!!a.children){var b=e(a),c=[],d=a.children.slice(),f,g=Infinity,h,k=Math.min(b.dx,b.dy),n;i(d,b.dx*b.dy/a.value),c.area=0;while((n=d.length)>0)c.push(f=d[n-1]),c.area+=f.area,(h=l(c,k))<=g?(d.pop(),g=h):(c.area-=c.pop().area,m(c,k,b,!1),k=Math.min(b.dx,b.dy),c.length=c.area=0,g=Infinity);c.length&&(m(c,k,b,!0),c.length=c.area=0),a.children.forEach(j)}}function i(a,b){var c=-1,d=a.length,e,f;while(++c<d)f=(e=a[c]).value*(b<0?0:b),e.area=isNaN(f)||f<=0?0:f}var a=d3.layout.hierarchy(),b=Math.round,c=[1,1],d=null,e=bi,f=!1,g,h=.5*(1+Math.sqrt(5));n.size=function(a){if(!arguments.length)return c;c=a;return n},n.padding=function(a){function c(b){return bj(b,a)}function b(b){var c=a.call(n,b,b.depth);return c==null?bi(b):bj(b,typeof c=="number"?[c,c,c,c]:c)}if(!arguments.length)return d;var f;e=(d=a)==null?bi:(f=typeof a)==="function"?b:f==="number"?(a=[a,a,a,a],c):c;return n},n.round=function(a){if(!arguments.length)return b!=Number;b=a?Math.round:Number;return n},n.sticky=function(a){if(!arguments.length)return f;f=a,g=null;return n},n.ratio=function(a){if(!arguments.length)return h;h=a;return n};return F(n,a)}})()
+(function(){function bj(a,b){var c=a.x+b[3],d=a.y+b[0],e=a.dx-b[1]-b[3],f=a.dy-b[0]-b[2];e<0&&(c+=e/2,e=0),f<0&&(d+=f/2,f=0);return{x:c,y:d,dx:e,dy:f}}function bi(a){return{x:a.x,y:a.y,dx:a.dx,dy:a.dy}}function bh(a,b,c){return a._tree.ancestor.parent==b.parent?a._tree.ancestor:c}function bg(a,b,c){a=a._tree,b=b._tree;var d=c/(b.number-a.number);a.change+=d,b.change-=d,b.shift+=c,b.prelim+=c,b.mod+=c}function bf(a){var b=0,c=0,d=a.children,e=d.length,f;while(--e>=0)f=d[e]._tree,f.prelim+=b,f.mod+=b,b+=f.shift+(c+=f.change)}function be(a,b){function c(a,d){var e=a.children;if(e){var f,g=null,h=-1,i=e.length;while(++h<i)f=e[h],c(f,g),g=f}b(a,d)}c(a,null)}function bd(a,b){return a.depth-b.depth}function bc(a,b){return b.x-a.x}function bb(a,b){return a.x-b.x}function ba(a,b){var c=a.children;if(c){var d,e=c.length,f=-1;while(++f<e)b(d=ba(c[f],b),a)>0&&(a=d)}return a}function _(a){return a.children?a.children[a.children.length-1]:a._tree.thread}function $(a){return a.children?a.children[0]:a._tree.thread}function Z(a,b){return a.parent==b.parent?1:2}function Y(a){var b=a.children;return b?Y(b[b.length-1]):a}function X(a){var b=a.children;return b?X(b[0]):a}function W(a){return a.reduce(function(a,b){return a+b.x},0)/a.length}function V(a){return 1+d3.max(a,function(a){return a.y})}function U(a,b,c){var d=b.r+c.r,e=a.r+c.r,f=b.x-a.x,g=b.y-a.y,h=Math.sqrt(f*f+g*g),i=(e*e+h*h-d*d)/(2*e*h),j=Math.acos(i),k=i*e,l=Math.sin(j)*e;f/=h,g/=h,c.x=a.x+k*f+l*g,c.y=a.y+k*g-l*f}function T(a,b,c,d){var e=a.children;a.x=b+=d*a.x,a.y=c+=d*a.y,a.r*=d;if(e){var f=-1,g=e.length;while(++f<g)T(e[f],b,c,d)}}function S(a){var b=a.children;b?(b.forEach(S),a.r=P(b)):a.r=Math.sqrt(a.value)}function R(a){delete a._pack_next,delete a._pack_prev}function Q(a){a._pack_next=a._pack_prev=a}function P(a){function l(a){b=Math.min(a.x-a.r,b),c=Math.max(a.x+a.r,c),d=Math.min(a.y-a.r,d),e=Math.max(a.y+a.r,e)}var b=Infinity,c=-Infinity,d=Infinity,e=-Infinity,f=a.length,g,h,i,j,k;a.forEach(Q),g=a[0],g.x=-g.r,g.y=0,l(g);if(f>1){h=a[1],h.x=h.r,h.y=0,l(h);if(f>2){i=a[2],U(g,h,i),l(i),M(g,i),g._pack_prev=i,M(i,h),h=g._pack_next;for(var m=3;m<f;m++){U(g,h,i=a[m]);var n=0,o=1,p=1;for(j=h._pack_next;j!==h;j=j._pack_next,o++)if(O(j,i)){n=1;break}if(n==1)for(k=g._pack_prev;k!==j._pack_prev;k=k._pack_prev,p++)if(O(k,i)){p<o&&(n=-1,j=k);break}n==0?(M(g,i),h=i,l(i)):n>0?(N(g,j),h=j,m--):(N(j,h),g=j,m--)}}}var q=(b+c)/2,r=(d+e)/2,s=0;for(var m=0;m<f;m++){var t=a[m];t.x-=q,t.y-=r,s=Math.max(s,t.r+Math.sqrt(t.x*t.x+t.y*t.y))}a.forEach(R);return s}function O(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r+b.r;return e*e-c*c-d*d>.001}function N(a,b){a._pack_next=b,b._pack_prev=a}function M(a,b){var c=a._pack_next;a._pack_next=b,b._pack_prev=a,b._pack_next=c,c._pack_prev=b}function L(a,b){return a.value-b.value}function J(a){return d3.merge(a.map(function(a){return(a.children||[]).map(function(b){return{source:a,target:b}})}))}function I(a,b){return b.value-a.value}function H(a){return a.value}function G(a){return a.children}function F(a,b){a.sort=d3.rebind(a,b.sort),a.children=d3.rebind(a,b.children),a.links=J,a.value=d3.rebind(a,b.value),a.nodes=function(b){K=!0;return(a.nodes=a)(b)};return a}function E(a){return[d3.min(a),d3.max(a)]}function D(a,b){var c=-1,d=+a[0],e=(a[1]-d)/b,f=[];while(++c<=b)f[c]=e*c+d;return f}function C(a,b){return D(a,Math.ceil(Math.log(b.length)/Math.LN2+1))}function B(a,b){return a+b[1]}function A(a){return a.reduce(B,0)}function z(a){var b=1,c=0,d=a[0][1],e,f=a.length;for(;b<f;++b)(e=a[b][1])>d&&(c=b,d=e);return c}function w(a,b,c){a.y0=b,a.y=c}function v(a){return a.y}function u(a){return a.x}function t(a){return 1}function s(a){return 20}function r(a){var b=0,c=0;a.count=0;if(!a.leaf){var d=a.nodes,e=d.length,f=-1,g;while(++f<e){g=d[f];if(g==null)continue;r(g),a.count+=g.count,b+=g.count*g.cx,c+=g.count*g.cy}}a.point&&(a.leaf||(a.point.x+=Math.random()-.5,a.point.y+=Math.random()-.5),a.count++,b+=a.point.x,c+=a.point.y),a.cx=b/a.count,a.cy=c/a.count}function q(){d3.event.stopPropagation(),d3.event.preventDefault()}function p(){i&&(q(),i=!1)}function o(){!f||(g&&(i=!0,q()),d3.event.type==="mouseup"&&n(),f.fixed=!1,e=h=f=j=null)}function n(){if(!!f){var a=j.parentNode;if(!a){f.fixed=!1,h=f=j=null;return}var b=m(a);g=!0,f.px=b[0]-h[0],f.py=b[1]-h[1],q(),e.resume()}}function m(a){return d3.event.touches?d3.svg.touches(a)[0]:d3.svg.mouse(a)}function l(a){a!==f&&(a.fixed=!1)}function k(a){a.fixed=!0}function c(a,c){if(a===c)return a;var d=b(a),e=b(c),f=d.pop(),g=e.pop(),h=null;while(f===g)h=f,f=d.pop(),g=e.pop();return h}function b(a){var b=[],c=a.parent;while(c!=null)b.push(a),a=c,c=c.parent;b.push(a);return b}function a(a){var b=a.source,d=a.target,e=c(b,d),f=[b];while(b!==e)b=b.parent,f.push(b);var g=f.length;while(d!==e)f.splice(g,0,d),d=d.parent;return f}d3.layout={},d3.layout.bundle=function(){return function(b){var c=[],d=-1,e=b.length;while(++d<e)c.push(a(b[d]));return c}},d3.layout.chord=function(){function k(){b.sort(function(a,b){return i(a.target.value,b.target.value)})}function j(){var a={},j=[],l=d3.range(e),m=[],n,o,p,q,r;b=[],c=[],n=0,q=-1;while(++q<e){o=0,r=-1;while(++r<e)o+=d[q][r];j.push(o),m.push(d3.range(e)),n+=o}g&&l.sort(function(a,b){return g(j[a],j[b])}),h&&m.forEach(function(a,b){a.sort(function(a,c){return h(d[b][a],d[b][c])})}),n=(2*Math.PI-f*e)/n,o=0,q=-1;while(++q<e){p=o,r=-1;while(++r<e){var s=l[q],t=m[q][r],u=d[s][t];a[s+"-"+t]={index:s,subindex:t,startAngle:o,endAngle:o+=u*n,value:u}}c.push({index:s,startAngle:p,endAngle:o,value:(o-p)/n}),o+=f}q=-1;while(++q<e){r=q-1;while(++r<e){var v=a[q+"-"+r],w=a[r+"-"+q];(v.value||w.value)&&b.push(v.value<w.value?{source:w,target:v}:{source:v,target:w})}}i&&k()}var a={},b,c,d,e,f=0,g,h,i;a.matrix=function(f){if(!arguments.length)return d;e=(d=f)&&d.length,b=c=null;return a},a.padding=function(d){if(!arguments.length)return f;f=d,b=c=null;return a},a.sortGroups=function(d){if(!arguments.length)return g;g=d,b=c=null;return a},a.sortSubgroups=function(c){if(!arguments.length)return h;h=c,b=null;return a},a.sortChords=function(c){if(!arguments.length)return i;i=c,b&&k();return a},a.chords=function(){b||j();return b},a.groups=function(){c||j();return c};return a},d3.layout.force=function(){function G(b,c){var d=m(this.parentNode);(f=b).fixed=!0,g=!1,j=this,e=a,h=[d[0]-b.x,d[1]-b.y],q()}function F(){var a=A.length,e=B.length,f=d3.geom.quadtree(A),g,h,j,k,l,m,n;for(g=0;g<e;++g){h=B[g],j=h.source,k=h.target,m=k.x-j.x,n=k.y-j.y;if(l=m*m+n*n)l=d*D[g]*((l=Math.sqrt(l))-C[g])/l,m*=l,n*=l,k.x-=m,k.y-=n,j.x+=m,j.y+=n}var o=d*x;m=c[0]/2,n=c[1]/2,g=-1;while(++g<a)h=A[g],h.x+=(m-h.x)*o,h.y+=(n-h.y)*o;r(f);var p=d*w;g=-1;while(++g<a)f.visit(E(A[g],p));g=-1;while(++g<a)h=A[g],h.fixed?(h.x=h.px,h.y=h.py):(h.x-=(h.px-(h.px=h.x))*i,h.y-=(h.py-(h.py=h.y))*i);b.tick.dispatch({type:"tick",alpha:d});return(d*=.99)<.005}function E(a,b){return function(c,d,e,f,g){if(c.point!==a){var h=c.cx-a.x,i=c.cy-a.y,j=1/Math.sqrt(h*h+i*i);if((f-d)*j<y){var k=b*c.count*j*j;a.x+=h*k,a.y+=i*k;return!0}if(c.point&&isFinite(j)){var k=b*j*j;a.x+=h*k,a.y+=i*k}}}}var a={},b=d3.dispatch("tick"),c=[1,1],d,i=.9,u=s,v=t,w=-30,x=.1,y=.8,z,A=[],B=[],C,D;a.on=function(c,d){b[c].add(d);return a},a.nodes=function(b){if(!arguments.length)return A;A=b;return a},a.links=function(b){if(!arguments.length)return B;B=b;return a},a.size=function(b){if(!arguments.length)return c;c=b;return a},a.linkDistance=function(b){if(!arguments.length)return u;u=d3.functor(b);return a},a.distance=a.linkDistance,a.linkStrength=function(b){if(!arguments.length)return v;v=d3.functor(b);return a},a.friction=function(b){if(!arguments.length)return i;i=b;return a},a.charge=function(b){if(!arguments.length)return w;w=b;return a},a.gravity=function(b){if(!arguments.length)return x;x=b;return a},a.theta=function(b){if(!arguments.length)return y;y=b;return a},a.start=function(){function l(){if(!i){i=[];for(d=0;d<e;++d)i[d]=[];for(d=0;d<f;++d){var a=B[d];i[a.source.index].push(a.target),i[a.target.index].push(a.source)}}return i[b]}function k(a,c){var d=l(b),e=-1,f=d.length,g;while(++e<f)if(!isNaN(g=d[e][a]))return g;return Math.random()*c}var b,d,e=A.length,f=B.length,g=c[0],h=c[1],i,j;for(b=0;b<e;++b)(j=A[b]).index=b;C=[],D=[];for(b=0;b<f;++b)j=B[b],typeof j.source=="number"&&(j.source=A[j.source]),typeof j.target=="number"&&(j.target=A[j.target]),C[b]=u.call(this,j,b),D[b]=v.call(this,j,b);for(b=0;b<e;++b)j=A[b],isNaN(j.x)&&(j.x=k("x",g)),isNaN(j.y)&&(j.y=k("y",h)),isNaN(j.px)&&(j.px=j.x),isNaN(j.py)&&(j.py=j.y);return a.resume()},a.resume=function(){d=.1,d3.timer(F);return a},a.stop=function(){d=0;return a},a.drag=function(){this.on("mouseover.force",k).on("mouseout.force",l).on("mousedown.force",G).on("touchstart.force",G),d3.select(window).on("mousemove.force",n).on("touchmove.force",n).on("mouseup.force",o,!0).on("touchend.force",o,!0).on("click.force",p,!0);return a};return a};var e,f,g,h,i,j;d3.layout.partition=function(){function e(e,f){var g=a.call(this,e,f);c(g[0],0,b[0],b[1]/d(g[0]));return g}function d(a){var b=a.children,c=0;if(b){var e=-1,f=b.length;while(++e<f)c=Math.max(c,d(b[e]))}return 1+c}function c(a,b,d,e){var f=a.children;a.x=b,a.y=a.depth*e,a.dx=d,a.dy=e;if(f){var g=-1,h=f.length,i,j;d/=a.value;while(++g<h)c(i=f[g],b,j=i.value*d,e),b+=j}}var a=d3.layout.hierarchy(),b=[1,1];e.size=function(a){if(!arguments.length)return b;b=a;return e};return F(e,a)},d3.layout.pie=function(){function f(f,g){var h=+(typeof c=="function"?c.apply(this,arguments):c),i=(typeof e=="function"?e.apply(this,arguments):e)-c,j=d3.range(f.length);b!=null&&j.sort(function(a,c){return b(f[a],f[c])});var k=f.map(a);i/=k.reduce(function(a,b){return a+b},0);var l=j.map(function(a){return{data:f[a],value:d=k[a],startAngle:h,endAngle:h+=d*i}});return f.map(function(a,b){return l[j[b]]})}var a=Number,b=null,c=0,e=2*Math.PI;f.value=function(b){if(!arguments.length)return a;a=b;return f},f.sort=function(a){if(!arguments.length)return b;b=a;return f},f.startAngle=function(a){if(!arguments.length)return c;c=a;return f},f.endAngle=function(a){if(!arguments.length)return e;e=a;return f};return f},d3.layout.stack=function(){function g(h,i){var j=h.map(function(b,c){return a.call(g,b,c)}),k=j.map(function(a,b){return a.map(function(a,b){return[e.call(g,a,b),f.call(g,a,b)]})}),l=b.call(g,k,i);j=d3.permute(j,l),k=d3.permute(k,l);var m=c.call(g,k,i),n=j.length,o=j[0].length,p,q,r;for(q=0;q<o;++q){d.call(g,j[0][q],r=m[q],k[0][q][1]);for(p=1;p<n;++p)d.call(g,j[p][q],r+=k[p-1][q][1],k[p][q][1])}return h}var a=Object,b=x["default"],c=y.zero,d=w,e=u,f=v;g.values=function(b){if(!arguments.length)return a;a=b;return g},g.order=function(a){if(!arguments.length)return b;b=typeof a=="function"?a:x[a];return g},g.offset=function(a){if(!arguments.length)return c;c=typeof a=="function"?a:y[a];return g},g.x=function(a){if(!arguments.length)return e;e=a;return g},g.y=function(a){if(!arguments.length)return f;f=a;return g},g.out=function(a){if(!arguments.length)return d;d=a;return g};return g};var x={"inside-out":function(a){var b=a.length,c,d,e=a.map(z),f=a.map(A),g=d3.range(b).sort(function(a,b){return e[a]-e[b]}),h=0,i=0,j=[],k=[];for(c=0;c<b;++c)d=g[c],h<i?(h+=f[d],j.push(d)):(i+=f[d],k.push(d));return k.reverse().concat(j)},reverse:function(a){return d3.range(a.length).reverse()},"default":function(a){return d3.range(a.length)}},y={silhouette:function(a){var b=a.length,c=a[0].length,d=[],e=0,f,g,h,i=[];for(g=0;g<c;++g){for(f=0,h=0;f<b;f++)h+=a[f][g][1];h>e&&(e=h),d.push(h)}for(g=0;g<c;++g)i[g]=(e-d[g])/2;return i},wiggle:function(a){var b=a.length,c=a[0],d=c.length,e=0,f,g,h,i,j,k,l,m,n,o=[];o[0]=m=n=0;for(g=1;g<d;++g){for(f=0,i=0;f<b;++f)i+=a[f][g][1];for(f=0,j=0,l=c[g][0]-c[g-1][0];f<b;++f){for(h=0,k=(a[f][g][1]-a[f][g-1][1])/(2*l);h<f;++h)k+=(a[h][g][1]-a[h][g-1][1])/l;j+=k*a[f][g][1]}o[g]=m-=i?j/i*l:0,m<n&&(n=m)}for(g=0;g<d;++g)o[g]-=n;return o},expand:function(a){var b=a.length,c=a[0].length,d=1/b,e,f,g,h=[];for(f=0;f<c;++f){for(e=0,g=0;e<b;e++)g+=a[e][f][1];if(g)for(e=0;e<b;e++)a[e][f][1]/=g;else for(e=0;e<b;e++)a[e][f][1]=d}for(f=0;f<c;++f)h[f]=0;return h},zero:function(a){var b=-1,c=a[0].length,d=[];while(++b<c)d[b]=0;return d}};d3.layout.histogram=function(){function e(e,f){var g=[],h=e.map(b,this),i=c.call(this,h,f),j=d.call(this,i,h,f),k,f=-1,l=h.length,m=j.length-1,n=a?1:1/l,o;while(++f<m)k=g[f]=[],k.dx=j[f+1]-(k.x=j[f]),k.y=0;f=-1;while(++f<l)o=h[f],o>=i[0]&&o<=i[1]&&(k=g[d3.bisect(j,o,1,m)-1],k.y+=n,k.push(e[f]));return g}var a=!0,b=Number,c=E,d=C;e.value=function(a){if(!arguments.length)return b;b=a;return e},e.range=function(a){if(!arguments.length)return c;c=d3.functor(a);return e},e.bins=function(a){if(!arguments.length)return d;d=typeof a=="number"?function(b){return D(b,a)}:d3.functor(a);return e},e.frequency=function(b){if(!arguments.length)return a;a=!!b;return e};return e},d3.layout.hierarchy=function(){function g(a){var b=[];e(a,0,b);return b}function f(a,b){var d=a.children,e=0;if(d){var h=-1,i=d.length,j=b+1;while(++h<i)e+=f(d[h],j)}else c&&(e=c.call(g,K?a:a.data,b));c&&(a.value=e);return e}function e(f,h,i){var j=b.call(g,f,h),k=K?f:{data:f};k.depth=h,i.push(k);if(j){var l=-1,m=j.length,n=k.children=[],o=0,p=h+1;while(++l<m)d=e(j[l],p,i),d.parent=k,n.push(d),o+=d.value;a&&n.sort(a),c&&(k.value=o)}else c&&(k.value=c.call(g,f,h));return k}var a=I,b=G,c=H;g.sort=function(b){if(!arguments.length)return a;a=b;return g},g.children=function(a){if(!arguments.length)return b;b=a;return g},g.value=function(a){if(!arguments.length)return c;c=a;return g},g.revalue=function(a){f(a,0);return a};return g};var K=!1;d3.layout.pack=function(){function c(c,d){var e=a.call(this,c,d),f=e[0];f.x=0,f.y=0,S(f);var g=b[0],h=b[1],i=1/Math.max(2*f.r/g,2*f.r/h);T(f,g/2,h/2,i);return e}var a=d3.layout.hierarchy().sort(L),b=[1,1];c.size=function(a){if(!arguments.length)return b;b=a;return c};return F(c,a)},d3.layout.cluster=function(){function d(d,e){var f=a.call(this,d,e),g=f[0],h,i=0,j,k;be(g,function(a){a.children?(a.x=W(a.children),a.y=V(a.children)):(a.x=h?i+=b(a,h):0,a.y=0,h=a)});var l=X(g),m=Y(g),n=l.x-b(l,m)/2,o=m.x+b(m,l)/2;be(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=(1-a.y/g.y)*c[1]});return f}var a=d3.layout.hierarchy().sort(null).value(null),b=Z,c=[1,1];d.separation=function(a){if(!arguments.length)return b;b=a;return d},d.size=function(a){if(!arguments.length)return c;c=a;return d};return F(d,a)},d3.layout.tree=function(){function d(d,e){function j(a,c,d){if(c){var e=a,f=a,g=c,h=a.parent.children[0],i=e._tree.mod,j=f._tree.mod,k=g._tree.mod,l=h._tree.mod,m;while(g=_(g),e=$(e),g&&e)h=$(h),f=_(f),f._tree.ancestor=a,m=g._tree.prelim+k-e._tree.prelim-i+b(g,e),m>0&&(bg(bh(g,a,d),a,m),i+=m,j+=m),k+=g._tree.mod,i+=e._tree.mod,l+=h._tree.mod,j+=f._tree.mod;g&&!_(f)&&(f._tree.thread=g,f._tree.mod+=k-j),e&&!$(h)&&(h._tree.thread=e,h._tree.mod+=i-l,d=a)}return d}function i(a,b){a.x=a._tree.prelim+b;var c=a.children;if(c){var d=-1,e=c.length;b+=a._tree.mod;while(++d<e)i(c[d],b)}}function h(a,c){var d=a.children,e=a._tree;if(d){var f=d.length,g=d[0],i,k=g,l,m=-1;while(++m<f)l=d[m],h(l,i),k=j(l,i,k),i=l;bf(a);var n=.5*(g._tree.prelim+l._tree.prelim);c?(e.prelim=c._tree.prelim+b(a,c),e.mod=e.prelim-n):e.prelim=n}else c&&(e.prelim=c._tree.prelim+b(a,c))}var f=a.call(this,d,e),g=f[0];be(g,function(a,b){a._tree={ancestor:a,prelim:0,mod:0,change:0,shift:0,number:b?b._tree.number+1:0}}),h(g),i(g,-g._tree.prelim);var k=ba(g,bc),l=ba(g,bb),m=ba(g,bd),n=k.x-b(k,l)/2,o=l.x+b(l,k)/2,p=m.depth||1;be(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=a.depth/p*c[1],delete a._tree});return f}var a=d3.layout.hierarchy().sort(null).value(null),b=Z,c=[1,1];d.separation=function(a){if(!arguments.length)return b;b=a;return d},d.size=function(a){if(!arguments.length)return c;c=a;return d};return F(d,a)},d3.layout.treemap=function(){function n(b){var d=g||a(b),e=d[0];e.x=0,e.y=0,e.dx=c[0],e.dy=c[1],g&&a.revalue(e),i([e],e.dx*e.dy/e.value),(g?k:j)(e),f&&(g=d);return d}function m(a,c,d,e){var f=-1,g=a.length,h=d.x,i=d.y,j=c?b(a.area/c):0,k;if(c==d.dx){if(e||j>d.dy)j=d.dy;while(++f<g)k=a[f],k.x=h,k.y=i,k.dy=j,h+=k.dx=j?b(k.area/j):0;k.z=!0,k.dx+=d.x+d.dx-h,d.y+=j,d.dy-=j}else{if(e||j>d.dx)j=d.dx;while(++f<g)k=a[f],k.x=h,k.y=i,k.dx=j,i+=k.dy=j?b(k.area/j):0;k.z=!1,k.dy+=d.y+d.dy-i,d.x+=j,d.dx-=j}}function l(a,b){var c=a.area,d,e=0,f=Infinity,g=-1,i=a.length;while(++g<i){if(!(d=a[g].area))continue;d<f&&(f=d),d>e&&(e=d)}c*=c,b*=b;return c?Math.max(b*e*h/c,c/(b*f*h)):Infinity}function k(a){if(!!a.children){var b=e(a),c=a.children.slice(),d,f=[];i(c,b.dx*b.dy/a.value),f.area=0;while(d=c.pop())f.push(d),f.area+=d.area,d.z!=null&&(m(f,d.z?b.dx:b.dy,b,!c.length),f.length=f.area=0);a.children.forEach(k)}}function j(a){if(!!a.children){var b=e(a),c=[],d=a.children.slice(),f,g=Infinity,h,k=Math.min(b.dx,b.dy),n;i(d,b.dx*b.dy/a.value),c.area=0;while((n=d.length)>0)c.push(f=d[n-1]),c.area+=f.area,(h=l(c,k))<=g?(d.pop(),g=h):(c.area-=c.pop().area,m(c,k,b,!1),k=Math.min(b.dx,b.dy),c.length=c.area=0,g=Infinity);c.length&&(m(c,k,b,!0),c.length=c.area=0),a.children.forEach(j)}}function i(a,b){var c=-1,d=a.length,e,f;while(++c<d)f=(e=a[c]).value*(b<0?0:b),e.area=isNaN(f)||f<=0?0:f}var a=d3.layout.hierarchy(),b=Math.round,c=[1,1],d=null,e=bi,f=!1,g,h=.5*(1+Math.sqrt(5));n.size=function(a){if(!arguments.length)return c;c=a;return n},n.padding=function(a){function c(b){return bj(b,a)}function b(b){var c=a.call(n,b,b.depth);return c==null?bi(b):bj(b,typeof c=="number"?[c,c,c,c]:c)}if(!arguments.length)return d;var f;e=(d=a)==null?bi:(f=typeof a)==="function"?b:f==="number"?(a=[a,a,a,a],c):c;return n},n.round=function(a){if(!arguments.length)return b!=Number;b=a?Math.round:Number;return n},n.sticky=function(a){if(!arguments.length)return f;f=a,g=null;return n},n.ratio=function(a){if(!arguments.length)return h;h=a;return n};return F(n,a)}})()
diff --git a/templates/default-layout.hamlet b/templates/default-layout.hamlet
new file mode 100644
--- /dev/null
+++ b/templates/default-layout.hamlet
@@ -0,0 +1,15 @@
+!!!
+<html lang="en">
+  <head>
+    <meta charset="utf-8" />
+    <link rel="shortcut icon" type=image/png href=@{FaviconR}>
+    <link href="http://fonts.googleapis.com/css?family=Amaranth:400,700" rel="stylesheet" type="text/css">
+    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js">
+    <title>#{pageTitle pc}
+    ^{pageHead pc}
+  <body>
+    $maybe msg <- mmsg
+      <div #message>#{msg}
+    ^{pageBody pc}
+    <footer>
+      Copyright &copy;<time datetime="2011-08-02">2011</time>Mitsutoshi Aoe
diff --git a/templates/default-layout.lucius b/templates/default-layout.lucius
new file mode 100644
--- /dev/null
+++ b/templates/default-layout.lucius
@@ -0,0 +1,38 @@
+/* body */
+body {
+  color: #f3f3e3;
+  background: #212121;
+  font-family: sans-serif;
+}
+
+/* hx */
+h1, h2, h3, h4 {
+  font-family: 'Amaranth', sans-serif;
+  font-weight: 400;
+}
+
+h1 {
+  font-size: 2em;
+}
+
+h2 {
+  font-size: 1.5em;
+}
+
+/* a */
+a {
+  color: #f3f3e3;
+  text-decoration: none;
+}
+
+section a:hover {
+  color: #e6550d;
+  text-decoration: underline;
+}
+
+/* footer */
+footer {
+  text-align: right;
+  font-size: 0.75em;
+  visibility: hidden;
+}
diff --git a/templates/header.hamlet b/templates/header.hamlet
new file mode 100644
--- /dev/null
+++ b/templates/header.hamlet
@@ -0,0 +1,13 @@
+<div #header>
+  <nav #breadcrumbs>
+    <h1>
+      <a href=@{HomeR}>
+        <img #logo src=@{StaticR images_tkyprof_logo_orange_png} alt="Home">
+        TKYPr
+        <span #o>o
+        f
+    $forall bc <- bcs
+      <a href=@{fst bc}>#{snd bc}
+      <span .breadcrumbs-delimiter>>
+    #{title}
+
diff --git a/templates/header.lucius b/templates/header.lucius
new file mode 100644
--- /dev/null
+++ b/templates/header.lucius
@@ -0,0 +1,32 @@
+#header {
+  height: 38px;
+  width: 100%;
+}
+
+#header h1 {
+  font-family: 'Amaranth', sans-serif;
+  font-weight: 700;
+  font-size: 30px;
+  margin: 0px;
+  margin-right: 10px;
+  display: inline;
+}
+
+#header h1 #logo {
+  margin-right: 5px;
+}
+
+#header h1 #o {
+  color: #e6550d;
+}
+
+/* breadcrumbs */
+#breadcrumbs {
+  font-family: sans-serif;
+  font-size: 0.75em;
+}
+
+.breadcrumbs-delimiter {
+  margin-left: 0.5em;
+  margin-right: 0.5em;
+}
diff --git a/templates/home.hamlet b/templates/home.hamlet
new file mode 100644
--- /dev/null
+++ b/templates/home.hamlet
@@ -0,0 +1,17 @@
+<h2>1. Select your profiling reports
+<form #uploader action=@{ReportsR} method=post enctype=#{Multipart}>
+  <div #box-wrapper>
+    <div #uploader-dropbox .box>
+      <p>Drop files here!
+    <div #uploader-filedialog .box>
+      <p>Click to select files.
+      <input type=file>
+<h2>
+  <a href=@{ReportsR}>2. View reports
+$maybe _ <- listToMaybe reports
+  <ul>
+    $forall report <- reports
+      <li>
+        <a href=@{ReportsIdR (fst report)}>#{reportCommandLine (snd report)}
+$nothing
+  <p>There are currently no reports available. First of all, upload your profiling reports please.
diff --git a/templates/home.julius b/templates/home.julius
new file mode 100644
--- /dev/null
+++ b/templates/home.julius
@@ -0,0 +1,13 @@
+$(function() {
+  var uploader = $('#uploader');
+
+  uploader.bind('fileuploaddone', function(e, data) {
+    top.location.href = data.jqXHR.getResponseHeader('Location');
+  });
+
+  uploader.fileupload({
+    url:               "/reports",
+    paramName:         "reports",
+    singleFileUploads: false
+  });
+});
diff --git a/templates/home.lucius b/templates/home.lucius
new file mode 100644
--- /dev/null
+++ b/templates/home.lucius
@@ -0,0 +1,52 @@
+#box-wrapper {
+  width: 100%;
+
+  display: -webkit-box;
+  display: -moz-box;
+  display: box;
+
+  -webkit-box-align: center;
+  -moz-box-align: center;
+  box-align: center;
+
+  -webkit-box-pack: center;
+  -moz-box-pack: center;
+  box-pack: center;
+}
+
+.box {
+  width: 50%;
+  text-align: center;
+  box-sizing: border-box;
+}
+
+/* dropbox */
+#uploader-dropbox {
+  height: 200px;
+  border: 2px dashed #fd8d38;
+
+  -webkit-border-radius: 10px;
+  -moz-border-radius: 10px;
+  border-radius: 10px;
+
+  display: -webkit-box;
+  display: -moz-box;
+  display: box;
+
+  -webkit-box-align: center;
+  -moz-box-align: center;
+  box-align: center;
+
+  -webkit-box-pack: center;
+  -moz-box-pack: center;
+  box-pack: center;
+}
+
+#uploader-dropbox:hover {
+  border: 2px solid #e6550d;
+}
+
+/* file dialog */
+#uploader-filedialog {
+  /* do nothing */
+}
diff --git a/templates/reports-id.hamlet b/templates/reports-id.hamlet
new file mode 100644
--- /dev/null
+++ b/templates/reports-id.hamlet
@@ -0,0 +1,43 @@
+<section #cost-centres>
+  <header>
+    <div .button-group>
+      <h2 #time .button>Time profiling
+      <h2 #alloc .button>Alloc profiling
+  <div #chart-container>
+    <figure #chart>
+    <div #sidebox>
+      <div #current-node>
+        <h2>Current node
+        <dl>
+          <dt>Module
+          <dd #current-node-module>
+          <dt>Name
+          <dd #current-node-name>
+          <dt>Number
+          <dd #current-node-number>
+          <dt>Entries
+          <dd #current-node-entries>
+          <dt>Individual %time
+          <dd #current-node-ind-time>
+          <dt>Individual %alloc
+          <dd #current-node-ind-alloc>
+          <dt>Inherited %time
+          <dd #current-node-inh-time>
+          <dt>Inherited %alloc
+          <dd #current-node-inh-alloc>
+      <div #children>
+        <h2>Children
+        <ol>
+<section #summary>
+  <h2>Summary
+  <div #report-summary .box>
+    <dl>
+      <dt>Timestamp
+      <dd>#{show reportTimestamp}
+      <dt>Command line
+      <dd>#{reportCommandLine}
+      <dt>Total time
+      <dd>#{totalSecs reportTotalTime} seconds
+      <dd>#{totalTicks reportTotalTime} ticks @ #{resolution reportTotalTime} ms
+      <dt>Total allocations
+      <dd>#{totalAllocBytes reportTotalAlloc} bytes
diff --git a/templates/reports-id.julius b/templates/reports-id.julius
new file mode 100644
--- /dev/null
+++ b/templates/reports-id.julius
@@ -0,0 +1,287 @@
+$(function() {
+  var data = #{json};
+  var parmalink = costCentreParmalink();
+  var chart = costCentreChart({
+    data: data,
+    parmalink: parmalink
+  });
+  var button = profilingModeButton({
+    chart: chart,
+    parmalink: parmalink
+  });
+
+  chart.transposeById(parmalink.id());
+  $(window).bind('popstate', function(event) {
+    if (!window.history.ready && !event.originalEvent.state) {
+      return; // workaround for popstate on load
+    }
+    parmalink.popstate(location.pathname);
+    button.mode(parmalink.mode());
+    chart.mode(parmalink.mode());
+    chart.transposeById(parmalink.id());
+  });
+});
+
+function costCentreParmalink(spec) {
+  var that = {};
+  var parsed = parse(location.pathname),
+      prefix = parsed[1],
+      mode   = parsed[2],
+      suffix = parsed[3];
+
+  function pathname() {
+    return prefix + mode + suffix;
+  };
+
+  function parse(path) {
+    var regex = /^(\/reports\/[0-9]+\/)(time|alloc)(.*)$/;
+    return regex.exec(path);
+  }
+
+  that.mode = function(newMode) {
+    if (!newMode)
+      return mode; // getter
+
+    mode = newMode;
+    window.history.ready = true; // workaround for popstate on load
+    history.pushState(null, null, pathname()); // HTML 5 History API
+    return mode;
+  };
+
+  that.transpose = function(node) {
+    var cursor = node, path = [];
+    for (cursor = node; cursor.parent; cursor = cursor.parent) {
+      path.unshift(cursor.no);
+    }
+    if (path.length > 0) {
+      suffix = "/" + path.join("/");
+    } else {
+      suffix = "";
+    }
+  };
+
+  that.popstate = function(url) {
+    var parsed = parse(url);
+    mode   = parsed[2];
+    suffix = parsed[3];
+  };
+
+  that.id = function() {
+    var regex = /^.*\/([0-9]*)$/;
+    var matched = regex.exec(suffix);
+    return matched ? matched[1] : null;
+  };
+
+  that.pathname = pathname;
+
+  return that;
+}
+
+function profilingModeButton(spec) {
+  var that = {};
+  var chart = spec.chart, parmalink = spec.parmalink;
+  var timeButton  = $("#time"),
+      allocButton = $("#alloc"),
+      _mode;
+
+  // methods
+  var mode = function(newMode) {
+    if (!newMode)
+      return _mode; // getter
+
+    _mode = newMode;
+    // buttons
+    if (_mode == "time") {
+      timeButton.addClass("active");
+      allocButton.removeClass("active");
+    } else {
+      timeButton.removeClass("active");
+      allocButton.addClass("active");
+    }
+    // chart
+    chart.mode(_mode);
+    return _mode;
+  };
+
+  // setup initial states and event handlers
+  mode(parmalink.mode());
+  timeButton.click(function(event) {
+    parmalink.mode("time");
+    mode(parmalink.mode());
+  });
+  allocButton.click(function(event) {
+    parmalink.mode("alloc");
+    mode(parmalink.mode());
+  });
+
+  // public slots
+  that.mode = mode;
+
+  return that;
+}
+
+function costCentreChart(spec) {
+  var that = {};
+
+  var cursor = spec.data,
+      selector = spec.selector,
+      parmalink = spec.parmalink;
+  var context = costCentreContext({cursor: cursor});
+
+  // chart
+  var chart = $("#chart"),
+      w = spec.w || chart.width(),
+      h = spec.h || chart.height(),
+      r = Math.min(w, h) / 2,
+      x = d3.scale.linear().range([0, 2*Math.PI]),
+      y = d3.scale.sqrt().range([0, r]),
+      color = spec.color || d3.scale.category20c();
+
+  var vis = d3.select("#chart")
+    .append("svg:svg")
+    .attr("width", w)
+    .attr("height", h)
+    .append("svg:g")
+    .attr("transform", "translate(" + w/2 + "," + h/2 + ")");
+
+  var partition = d3.layout.partition()
+    .children(function(d) { return d.subForest; })
+    .value(value(parmalink.mode()));
+
+  var arc = d3.svg.arc()
+    .startAngle(function(d) { return Math.max(0, Math.min(2*Math.PI, x(d.x))); })
+    .endAngle(function(d) { return Math.max(0, Math.min(2*Math.PI, x(d.x + d.dx))); })
+    .innerRadius(function(d) { return Math.max(0, y(d.y)); })
+    .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
+
+  var path = vis.data([cursor]).selectAll("path")
+    .data(partition.nodes)
+    .enter().append("svg:path")
+    .attr("d", arc)
+    .attr("id", function(d) { return "cc" + d.no + (d.isParent ? "p" : ""); })
+    .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
+    .on("click", click)
+    .on("mouseover", mouseover)
+    .each(function(d) { d.x0 = d.x; d.dx0 = d.dx; }); // stash the old values for transition
+
+  // event handlers
+  function click(d) {
+    transpose(d);
+    parmalink.transpose(d);
+    window.history.ready = true; // workaround for popstate on load
+    history.pushState(null, null, parmalink.pathname()); // HTML 5 History API
+  }
+
+  function mouseover(d) {
+    // XXX
+  }
+
+  // tweeners
+  function arcTween(a) {
+    var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
+    return function(t) {
+      var b = i(t);
+      a.x0  = b.x;
+      a.dx0 = b.dx;
+      return arc(b);
+    };
+  }
+
+  function zoomTween(d) {
+    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
+        yd = d3.interpolate(y.domain(), [d.y, 1]),
+        yr = d3.interpolate(y.range(), [d.y ? 20 : 0, r]);
+    return function(d, i) {
+      return i
+        ? function(t) { return arc(d); }
+        : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
+    };
+  }
+
+  // helper functions
+  function value(mode) {
+    if (mode === "time")
+      return function(d) { return d.individualTime; };
+    else
+      return function(d) { return d.individualAlloc; };
+  }
+
+  function nodeFromId(id) {
+    if (!id)
+      return null;
+    var elem = d3.select("#cc" + id);
+    return elem.node().__data__; // XXX: __data__ is not a public API
+  }
+
+  var mode = function(mode) {
+    path.data(partition.value(value(mode)))
+      .transition()
+      .duration(500)
+      .attrTween("d", arcTween);
+  };
+
+  var transpose = function(node) {
+    cursor = node;
+    context.transpose(cursor);
+    path.transition()
+      .duration(500)
+      .attrTween("d", zoomTween(node));
+  };
+
+  var transposeById = function(id) {
+    transpose(nodeFromId(id) || spec.data);
+  };
+
+  // public slots
+  that.mode = mode;
+  that.transpose = transpose;
+  that.transposeById = transposeById;
+
+  // setup initial states
+  mode(parmalink.mode());
+  transposeById(parmalink.id());
+
+  return that;
+}
+
+function costCentreContext(spec) {
+  var that = {};
+  var cursor = spec.cursor;
+
+  var showCostCentre = function(node) {
+    var currentNode = $("#current-node dl");
+    $("#current-node-module",    currentNode).text(node.module);
+    $("#current-node-name",      currentNode).text(node.name);
+    $("#current-node-number",    currentNode).text(node.no);
+    $("#current-node-entries",   currentNode).text(node.entries);
+    $("#current-node-ind-time",  currentNode).text(node.individualTime);
+    $("#current-node-ind-alloc", currentNode).text(node.individualAlloc);
+    $("#current-node-inh-time",  currentNode).text(node.inheritedTime);
+    $("#current-node-inh-alloc", currentNode).text(node.inheritedAlloc);
+  };
+
+  var showChildren = function(node) {
+    $("#children ol li").remove();
+    var children = $("#children ol");
+    var cs = node.children;
+    if (cs) {
+      var n = cs.length < 10 ? cs.length : 10;
+      for (var i = 0; i < n; i++) {
+        children.append("<li>" + cs[i].name + "</li>");
+      }
+    }
+  };
+
+  // setup
+  showCostCentre(cursor);
+  showChildren(cursor);
+
+  // public slots
+  that.transpose = function(node) {
+    cursor = node;
+    showCostCentre(cursor);
+    showChildren(cursor);
+  };
+
+  return that;
+}
diff --git a/templates/reports-id.lucius b/templates/reports-id.lucius
new file mode 100644
--- /dev/null
+++ b/templates/reports-id.lucius
@@ -0,0 +1,113 @@
+/* title and buttons */
+#cost-centres > header {
+  margin: 1em;
+}
+#cost-centres h2 {
+  display: inline;
+  font-size: 1.5em;
+}
+
+#cost-centres .button {
+  border: 1.5px solid transparent;
+  padding-left: 4px;
+  padding-right: 4px;
+  cursor: pointer;
+}
+
+#cost-centres .button:hover {
+  /* border: 1.5px solid #fd8d38; */
+  border: 1.5px solid #f3f3e3;
+}
+
+#cost-centres .active {
+  /* border: 1.5px solid #fd8d38; */
+  /* background: #fd8d38; */
+  border: 1.5px solid #f3f3e3;
+  background: #f3f3e3;
+  color: #212121;
+}
+
+#cost-centres .button:first-child {
+  -webkit-border-top-left-radius: 0.5em;
+  -moz-border-top-left-radius: 0.5em;
+  border-top-left-radius: 0.5em;
+  -webkit-border-bottom-left-radius: 0.5em;
+  -moz-border-bottom-left-radius: 0.5em;
+  border-bottom-left-radius: 0.5em;
+}
+
+#cost-centres .button:last-child {
+  -webkit-border-top-right-radius: 0.5em;
+  -moz-border-top-right-radius: 0.5em;
+  border-top-right-radius: 0.5em;
+  -webkit-border-bottom-right-radius: 0.5em;
+  -moz-border-bottom-right-radius: 0.5em;
+  border-bottom-right-radius: 0.5em;
+}
+
+
+/* chart */
+#chart-container {
+  width: 100%;
+  font-size: 0.85em;
+
+  display: -webkit-box;
+  display: -moz-box;
+  display: box;
+}
+
+#chart {
+  -webkit-box-flex: 1;
+  -moz-box-flex: 1;
+  box-flex: 1;
+  min-height: 400px;
+  -webkit-box-ordinal-group: 1;
+  -moz-box-ordinal-group: 1;
+  box-ordinal-group: 1;
+}
+
+#chart path {
+  stroke: #212121;
+  stroke-width: 0.5;
+  fill-rule: evenodd;
+  opacity: 1;
+}
+
+/* sidebox */
+#sidebox {
+  background: #353535;
+  padding: 1em;
+  padding-top: 0.5em;
+  width: 18em;
+  min-height: 37em;
+  -webkit-box-ordinal-group: 2;
+  -moz-box-ordinal-group: 2;
+  box-ordinal-group: 2;
+  text-overflow: ellipsis;
+  overflow: hidden;
+
+  -webkit-border-radius: 10px;
+  -moz-border-radius: 10px;
+  border-radius: 10px;
+}
+
+#sidebox dt {
+  float: left;
+}
+
+#sidebox dd {
+  margin-left: 10em;
+}
+
+/* summary */
+#report-summary {
+  font-size: 0.85em;
+}
+
+#report-summary dt {
+  float: left;
+}
+
+#report-summary dd {
+  margin-left: 10em;
+}
diff --git a/templates/reports.hamlet b/templates/reports.hamlet
new file mode 100644
--- /dev/null
+++ b/templates/reports.hamlet
@@ -0,0 +1,8 @@
+<h2>All reports
+$maybe _ <- listToMaybe reports
+  <ul>
+    $forall report <- reports
+      <li>
+        <a href=@{ReportsIdR (fst report)}>#{reportCommandLine (snd report)}
+$nothing
+  <p>There are currently no reports available. First of all, upload your profiling reports please.
diff --git a/templates/reports.julius b/templates/reports.julius
new file mode 100644
--- /dev/null
+++ b/templates/reports.julius
@@ -0,0 +1,3 @@
+$(function() {
+  console.log("reports");
+});
diff --git a/templates/reports.lucius b/templates/reports.lucius
new file mode 100644
--- /dev/null
+++ b/templates/reports.lucius
diff --git a/tkyprof.cabal b/tkyprof.cabal
--- a/tkyprof.cabal
+++ b/tkyprof.cabal
@@ -1,5 +1,5 @@
 name:                 tkyprof
-version:              0.0.6.3
+version:              0.1.0.1
 license:              BSD3
 license-file:         LICENSE
 author:               Mitsutoshi Aoe
@@ -13,7 +13,7 @@
 build-type:           Simple
 homepage:             https://github.com/maoe/tkyprof
 bug-reports:          https://github.com/maoe/tkyprof/issues
-tested-with:          GHC == 7.0.2
+tested-with:          GHC == 7.6.1
 
 data-files:           static/js/d3.layout.min.js
                       static/js/d3.min.js
@@ -28,9 +28,9 @@
                       README.markdown
 
 extra-source-files:   config/routes
-                      hamlet/*.hamlet
-                      julius/*.julius
-                      lucius/*.lucius
+                      templates/*.hamlet
+                      templates/*.julius
+                      templates/*.lucius
 
 flag production
   description:        Build the production executable.
@@ -57,32 +57,38 @@
   other-modules:      Paths_tkyprof
   ghc-options:        -Wall -threaded
   build-depends:      base >= 4 && < 5
-                    , aeson >= 0.3 && < 0.4
-                    , attoparsec >= 0.9 && < 0.10
-                    , attoparsec-enumerator >= 0.2 && < 0.3
-                    , bytestring >= 0.9 && < 0.10
-                    , cmdargs >= 0.7 && < 0.8
-                    , containers < 0.5
+                    , aeson >= 0.3 && < 0.7
+                    , attoparsec >= 0.9 && < 0.11
+                    , attoparsec-conduit >= 0.5 && < 0.6
+                    , bytestring >= 0.9 && < 0.11
+                    , cmdargs >= 0.7 && < 0.11
+                    , containers < 0.6
+                    , unordered-containers >= 0.2 && < 0.3
                     , directory < 2
-                    , enumerator >= 0.4 && < 0.5
+                    , data-default < 0.6
                     , filepath >= 1.1 && < 2
-                    , hamlet >= 0.8 && < 0.10
+                    , hamlet >= 0.8 && < 1.2
                     , mtl >= 1.1 && < 3
                     , rosezipper >= 0.2 && < 0.3
                     , stm < 3
                     , template-haskell < 3
                     , text >= 0.11 && < 0.12
-                    , time >= 1.2 && < 1.3
-                    , transformers >= 0.2 && < 0.3
+                    , time >= 1.2 && < 1.5
+                    , transformers >= 0.2 && < 0.4
                     , vector >= 0.6 && < 1
-                    , wai >= 0.4 && < 0.5
-                    , wai-extra >= 0.4 && < 0.5
-                    , warp >= 0.4 && < 0.5
-                    , web-routes >= 0.23 && < 0.26
-                    , yesod-core >= 0.8 && < 0.9
-                    , yesod-form >= 0.1 && < 0.2
-                    , yesod-json >= 0.1 && < 0.2
-                    , yesod-static >= 0.1 && < 0.2
+                    , wai >= 0.4 && < 1.4
+                    , wai-extra >= 0.4 && < 1.4
+                    , warp >= 0.4 && < 1.4
+                    , web-routes >= 0.23 && < 0.28
+                    , yesod-core >= 1.1 && < 1.7
+                    , yesod-default >= 1.1 && < 1.2
+                    , yesod-form >= 0.1 && < 1.3
+                    , yesod-json >= 0.1 && < 1.2
+                    , yesod-static >= 0.1 && < 1.2
+                    , shakespeare-css >= 1.0 && < 1.1
+                    , shakespeare-js >= 1.0 && < 1.2
+                    , http-types >= 0.7 && < 1.0
+                    , conduit >= 0.5 && < 0.6
 
 library
   if flag(devel)
