diff --git a/Handler/Home.hs b/Handler/Home.hs
--- a/Handler/Home.hs
+++ b/Handler/Home.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE TemplateHaskell, QuasiQuotes, OverloadedStrings #-}
 module Handler.Home where
-import TKYProf
+import TKYProf hiding (reports)
 import Yesod.Form (Enctype(Multipart))
 import Data.Maybe (listToMaybe)
 import Handler.Reports.Helpers (getAllReports)
diff --git a/Handler/Reports.hs b/Handler/Reports.hs
--- a/Handler/Reports.hs
+++ b/Handler/Reports.hs
@@ -3,18 +3,20 @@
   ( getReportsR
   , postReportsR
   , getReportsIdR
+  , getReportsIdTimeR
+  , getReportsIdAllocR
   ) where
 
-import TKYProf
-import ProfilingReport
-import Control.Applicative
-import Yesod.Request
 import Data.Maybe (listToMaybe)
+import Data.Text (Text)
 import Handler.Reports.Helpers (getAllReports, getProfilingReport, postProfilingReport)
+import ProfilingReport
+import TKYProf
+import Yesod.Request
+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.Aeson as A (encode)
 import qualified Data.Text.Lazy.Encoding as T (decodeUtf8)
 
 getReportsR :: Handler RepHtml
@@ -26,30 +28,48 @@
 
 postReportsR :: Handler ()
 postReportsR = do
-  FileInfo {fileContent} <- getPostedReport
-  prof <- parseFileContent fileContent
-  postProfilingReport prof
+  files <- getPostedReports
+  case files of
+    [fileInfo] -> do reportId <- postFileInfo fileInfo
+                     sendResponseCreated $ ReportsIdR reportId
+    _          -> do mapM_ postFileInfo files
+                     sendResponseCreated ReportsR
 
 getReportsIdR :: ReportID -> Handler RepHtml
-getReportsIdR reportId = do
-  report@ProfilingReport {..} <- getProfilingReport reportId
-  let json = T.decodeUtf8 $ A.encode reportCostCentres
-  defaultLayout $ do
-    setTitle $ "TKYProf Reports"
-    addScript $ StaticR js_d3_min_js
-    addScript $ StaticR js_d3_layout_min_js
-    addWidget $(widgetFile "reports-id")
+getReportsIdR reportId = redirect RedirectSeeOther (ReportsIdTimeR reportId [])
 
+getReportsIdTimeR :: ReportID -> [a] -> Handler RepHtml
+getReportsIdTimeR reportId _ = getReportsIdCommon reportId "time"
+
+getReportsIdAllocR :: ReportID -> [a] -> Handler RepHtml
+getReportsIdAllocR reportId _ = getReportsIdCommon reportId "alloc"
+
 -- Helper functions
-getPostedReport :: Handler FileInfo
-getPostedReport = do
+getPostedReports :: Handler [FileInfo]
+getPostedReports = do
   (_, files) <- runRequestBody
-  case lookup "reports" files of
-    Nothing   -> invalidArgs ["Missing files"]
-    Just file -> return file
+  case [ file | (header, file) <- files, header == "reports" ] of
+    []    -> invalidArgs ["Missing files"]
+    found -> return found
 
+postFileInfo :: FileInfo -> Handler ReportID
+postFileInfo FileInfo {fileContent} = do
+  prof <- parseFileContent fileContent
+  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
+  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")
diff --git a/Handler/Reports/Helpers.hs b/Handler/Reports/Helpers.hs
--- a/Handler/Reports/Helpers.hs
+++ b/Handler/Reports/Helpers.hs
@@ -12,8 +12,8 @@
 import Control.Monad.Trans (liftIO)
 import Model (Reports(..), ReportID, allReports, lookupReport, insertReport)
 import ProfilingReport (ProfilingReport)
-import TKYProf (Handler, TKYProf(getReports), TKYProfRoute(..))
-import Yesod.Core (getYesod, sendResponseCreated)
+import TKYProf (Handler, TKYProf(getReports))
+import Yesod.Core (getYesod)
 import Yesod.Handler (notFound)
 
 runReports :: STM a -> Handler a
@@ -38,10 +38,7 @@
     Just r  -> return r
     Nothing -> notFound
 
-postProfilingReport :: ProfilingReport -> Handler ()
+postProfilingReport :: ProfilingReport -> Handler ReportID
 postProfilingReport prof = do
   rs <- getReports'
-  reportId <- runReports $ insertReport prof rs
-  sendResponseCreated (ReportsIdR reportId)
-
-
+  runReports $ insertReport prof rs
diff --git a/TKYProf.hs b/TKYProf.hs
--- a/TKYProf.hs
+++ b/TKYProf.hs
@@ -102,7 +102,8 @@
     return $ Just $ Right (StaticR $ StaticRoute ["tmp", T.pack fn] [], [])
 
 instance YesodBreadcrumbs TKYProf where
-  breadcrumb HomeR            = return ("Home", Nothing)
-  breadcrumb ReportsR         = return ("Reports", Just HomeR)
-  breadcrumb (ReportsIdR rid) = return ("Report #" `T.append` T.pack (show rid), Just ReportsR)
-  breadcrumb _                = return ("Not found", Just HomeR)
+  breadcrumb HomeR                   = return ("Home", Nothing)
+  breadcrumb ReportsR                = return ("Reports", Just HomeR)
+  breadcrumb (ReportsIdTimeR rid _)  = return ("Report #" `T.append` T.pack (show rid), Just ReportsR)
+  breadcrumb (ReportsIdAllocR rid _) = return ("Report #" `T.append` T.pack (show rid), Just ReportsR)
+  breadcrumb _                       = return ("Not found", Just HomeR)
diff --git a/config/routes b/config/routes
--- a/config/routes
+++ b/config/routes
@@ -1,6 +1,8 @@
-/                          HomeR              GET
-/reports                   ReportsR           GET POST
-/reports/#Integer          ReportsIdR         GET
-/static                    StaticR            Static getStatic
-/favicon.png               FaviconR           GET
-/robots.txt                RobotsR            GET
+/                              HomeR           GET
+/reports                       ReportsR        GET POST
+/reports/#Integer              ReportsIdR      GET
+/reports/#Integer/time/*Texts  ReportsIdTimeR  GET
+/reports/#Integer/alloc/*Texts ReportsIdAllocR GET
+/static                        StaticR         Static getStatic
+/favicon.png                   FaviconR        GET
+/robots.txt                    RobotsR         GET
diff --git a/hamlet/home.hamlet b/hamlet/home.hamlet
--- a/hamlet/home.hamlet
+++ b/hamlet/home.hamlet
@@ -1,19 +1,17 @@
-<section>
-  <h1>Instructions
-  <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.
+<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
--- a/hamlet/reports-id.hamlet
+++ b/hamlet/reports-id.hamlet
@@ -1,10 +1,8 @@
-<h1>Time and Allocation Profiling Report ##{reportId}
 <section #cost-centres>
   <header>
-    <h1>Cost centres:
     <div .button-group>
-      <div #time .button .active>Time profiling
-      <div #alloc .button>Alloc profiling
+      <h2 #time .button>Time profiling
+      <h2 #alloc .button>Alloc profiling
   <div #chart-container>
     <figure #chart>
     <div #sidebox>
@@ -31,7 +29,7 @@
         <h2>Children
         <ol>
 <section #summary>
-  <h1>Summary
+  <h2>Summary
   <div #report-summary .box>
     <dl>
       <dt>Timestamp
diff --git a/hamlet/reports.hamlet b/hamlet/reports.hamlet
--- a/hamlet/reports.hamlet
+++ b/hamlet/reports.hamlet
@@ -1,9 +1,8 @@
-<section>
-  <h1>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.
+<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
--- a/julius/home.julius
+++ b/julius/home.julius
@@ -6,7 +6,8 @@
   });
 
   uploader.fileupload({
-    url: '/reports',
-    paramName: "reports"
+    url:               "/reports",
+    paramName:         "reports",
+    singleFileUploads: false
   });
 });
diff --git a/julius/reports-id.julius b/julius/reports-id.julius
--- a/julius/reports-id.julius
+++ b/julius/reports-id.julius
@@ -1,22 +1,157 @@
 $(function() {
-  var report = #{json};
+  var data = #{json};
+  var parmalink = costCentreParmalink();
+  var chart = costCentreChart({
+    data: data,
+    parmalink: parmalink
+  });
+  var button = profilingModeButton({
+    chart: chart,
+    parmalink: parmalink
+  });
 
-  var w = $("#chart").width(),
-      h = $("#chart").height(),
+  $(window).bind('popstate', function(event) {
+    console.log('popstate');
+    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;
+
+  console.log(timeButton);
+  console.log(allocButton);
+
+  // methods
+  var mode = function(newMode) {
+    if (!newMode)
+      return _mode; // getter
+
+    console.log("button.mode: " + newMode);
+
+    _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 = d3.scale.category20c();
+      color = spec.color || d3.scale.category20c();
 
-  var vis = d3.select("#chart").append("svg:svg")
+  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()
-    .value(function(d) { return d.individualTime; })
-    .children(function(d) { return d.subForest; });
+    .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))); })
@@ -24,67 +159,41 @@
     .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([report]).selectAll("path")
+  var path = vis.data([cursor]).selectAll("path")
     .data(partition.nodes)
     .enter().append("svg:path")
-    .attr("id", function(d) { return "cc" + d.no + (d.isParent ? "p" : ""); })
-    .attr("class", function(d) { return d.children || d.isParent ? "branch" : "leaf"; })
     .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(stash);
-
-  d3.select("#time").on("click", function() {
-    path.data(partition.value(function(d) { return d.individualTime; }))
-      .transition()
-      .duration(500)
-      .attrTween("d", arcTween);
-
-    d3.select("#time").classed("active", true);
-    d3.select("#alloc").classed("active", false);
-  });
-
-  d3.select("#alloc").on("click", function() {
-    path.data(partition.value(function(d) { return d.individualAlloc; }))
-      .transition()
-      .duration(500)
-      .attrTween("d", arcTween);
-
-    d3.select("#time").classed("active", false);
-    d3.select("#alloc").classed("active", true);
-  });
+    .each(function(d) { d.x0 = d.x; d.dx0 = d.dx; }); // stash the old values for transition
 
+  // event handlers
   function click(d) {
-    showCostCentre(d);
-    showChildren(d);
-    path.transition()
-      .duration(500)
-      .attrTween("d", arcTweenZoom(d));
+    transpose(d);
+    parmalink.transpose(d);
+    console.log(parmalink.pathname());
+    window.history.ready = true; // workaround for popstate on load
+    history.pushState(null, null, parmalink.pathname()); // HTML 5 History API
   }
 
   function mouseover(d) {
-
-  }
-
-  // Stash the old values for transition.
-  function stash(d) {
-    d.x0 = d.x;
-    d.dx0 = d.dx;
+    // XXX
   }
 
-  // Interpolate the arcs in data space.
+  // 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.x0  = b.x;
       a.dx0 = b.dx;
       return arc(b);
     };
   }
 
-  function arcTweenZoom(d) {
+  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]);
@@ -95,27 +204,90 @@
     };
   }
 
-  function showCostCentre(node) {
+  // 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;
+    console.log(id);
+    var elem = d3.select("#cc" + id);
+    console.log(elem);
+    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(cursor));
+  };
+
+  // setup initial states
+  mode(parmalink.mode());
+  transpose(nodeFromId(parmalink.id()) || spec.data);
+
+  // public slots
+  that.mode = mode;
+  that.transpose = transpose;
+  that.transposeById = function(id) {
+    transpose(nodeFromId(id) || spec.data);
+  };
+
+  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-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-time",  currentNode).text(node.inheritedTime);
     $("#current-node-inh-alloc", currentNode).text(node.inheritedAlloc);
-  }
+  };
 
-  function showChildren(node) {
+  var showChildren = function(node) {
     $("#children ol li").remove();
     var children = $("#children ol");
     var cs = node.children;
-        n  = cs.length < 10 ? cs.length : 10;
-    for (var i = 0; i < n; i++) {
-      children.append("<li>" + cs[i].name + "</li>");
+    if (cs) {
+      var n = cs.length < 10 ? cs.length : 10;
+      for (var i = 0; i < n; i++) {
+        children.append("<li>" + cs[i].name + "</li>");
+      }
     }
-  }
-  showCostCentre(report);
-  showChildren(report);
-});
+  };
+
+  // setup
+  showCostCentre(cursor);
+  showChildren(cursor);
+
+  // public slots
+  that.transpose = function(node) {
+    cursor = node;
+    showCostCentre(cursor);
+    showChildren(cursor);
+  };
+
+  return that;
+}
diff --git a/lucius/reports-id.lucius b/lucius/reports-id.lucius
--- a/lucius/reports-id.lucius
+++ b/lucius/reports-id.lucius
@@ -1,16 +1,10 @@
 /* title and buttons */
-#cost-centres h1 {
-  display: inline;
-  margin-right: 15px;
-  font-size: 1.5em;
+#cost-centres > header {
+  margin: 1em;
 }
-
-#cost-centres .button-group,
-#cost-centres .button-group div {
+#cost-centres h2 {
   display: inline;
-  font-family: 'Amaranth', sans-serif;
-  font-weight: 700;
-  font-size: 1.0em;
+  font-size: 1.5em;
 }
 
 #cost-centres .button {
diff --git a/static/js/tkyprof.js b/static/js/tkyprof.js
new file mode 100644
--- /dev/null
+++ b/static/js/tkyprof.js
@@ -0,0 +1,87 @@
+// Quoted by "JavsScrpt: The Good Parts"
+
+Function.prototype.method = function(name, func) {
+  if (!this.prototype[name]) {
+    this.prototype[name] = func;
+    return this;
+  }
+}
+
+Function.method('curry', function() {
+  var slice = Array.prototype.slice,
+      args = slice.apply(arguments),
+      that = this;
+  return function() {
+    return that.apply(null, args.concat(slice.apply(arguments)));
+  };
+});
+
+Array.method('shift', function() {
+  return this.splice(0, 1)[0];
+});
+
+Array.method('splice', function(start, deleteCount) {
+  var max = Math.max,
+      min = Math.min,
+      delta,
+      element,
+      insertCount = max(arguments.length - 2, 0),
+      k = 0,
+      len = this.length,
+      newLen,
+      result = [],
+      shiftCount;
+
+  start = start || 0;
+  if (start < 0) {
+    start += len;
+  }
+  start = max(min(start, len), 0);
+  deleteCount = max(
+    min(
+      typeof deleteCount === 'number'
+        ? deleteCount
+        : len,
+      len - start
+    ),
+    0
+  );
+  delta = insertCount - deleteCount;
+  newLen = len + delta;
+  while (k < deleteCount) {
+    element = this[start + k];
+    if (element !== undefined) {
+      result[k] = element;
+    }
+    k += 1;
+  }
+  shiftCount = len - start - deleteCount;
+  if (delta < 0) {
+    k = start + insertCount;
+    while (shiftCount) {
+      this[k] = this[k - delta];
+      k += 1;
+      shiftCount -= 1;
+    }
+    this.length = newLen;
+  } else if (delta > 0) {
+    k = 1;
+    while (shiftCount) {
+      this[newLen - k] = this[len - k];
+      k += 1;
+      shiftCount -= 1;
+    }
+  }
+  for (k = 0; k < insertCount; k += 1) {
+    this[start + k] = arguments[k + 2];
+  }
+  return result;
+});
+
+Array.method('unshift', function() {
+  this.splice.apply(
+    this,
+    [0, 0].concat(Array.prototype.slice.apply(arguments))
+  );
+  return this.length;
+});
diff --git a/tkyprof.cabal b/tkyprof.cabal
--- a/tkyprof.cabal
+++ b/tkyprof.cabal
@@ -1,17 +1,19 @@
 name:                 tkyprof
-version:              0.0.5.2
+version:              0.0.6
 license:              BSD3
 license-file:         LICENSE
 author:               Mitsutoshi Aoe
 maintainer:           Mitsutoshi Aoe <maoe@foldr.in>
-synopsis:             A visualizer for GHC Profiling Reports
-description:          A visualizer for GHC Profiling Reports
+copyright:            Copyright (C) 2011 Mitsutoshi Aoe
+synopsis:             A web-based visualizer for GHC Profiling Reports
+description:          A web-based visualizer for GHC Profiling Reports
 category:             Development
 stability:            Experimental
 cabal-version:        >= 1.6
 build-type:           Simple
 homepage:             https://github.com/maoe/tkyprof
 bug-reports:          https://github.com/maoe/tkyprof/issues
+tested-with:          GHC == 7.0.2
 
 data-files:           static/js/d3.layout.min.js
                       static/js/d3.min.js
@@ -19,6 +21,7 @@
                       static/js/jquery.iframe-transport.js
                       static/js/jquery.pjax.js
                       static/js/jquery.ui.widget.js
+                      static/js/tkyprof.js
                       static/images/*.png
                       config/favicon.png
 
