Update to API v0.1
diff --git a/lib/Korap.pm b/lib/Korap.pm
index 04f0014..f0115ae 100644
--- a/lib/Korap.pm
+++ b/lib/Korap.pm
@@ -1,12 +1,17 @@
 package Korap;
 use Mojo::Base 'Mojolicious';
 
-our $VERSION = '0.03';
+our $VERSION = '0.04';
+
+# Start dev with
+# morbo -w lib -w templates -w public/sass -w public/js script/korap
 
 # Start the application and register all routes and plugins
 sub startup {
   my $self = shift;
 
+  $self->defaults(layout => 'default');
+
   # Set secret for signed cookies
   $self->secrets(['fmhsfjgfchgsdbfgshfxztsbt32477eb45veu4vubrghfgghbtv']);
 
@@ -21,20 +26,41 @@
 	      Number::Commify
 	      KorapSearch
 	      KorapInfo
-	      KorapTagHelpers/) {
-    # AssetPack
+	      KorapTagHelpers
+              /) {
     $self->plugin($_);
   };
 
-#  $self->asset(
-#    'korap.css' => (
-#      'style.css',
-#      'sass/hint.scss',
-#      'table.css',
-#      'sass/kwic-4.0.scss',
-#      'fontawesome/font-awesome.min.css'
-#    )
-#  );
+  $self->plugin(AssetPack => {
+    minify => 1
+  });
+
+  $self->plugin('AssetPack::LibSass');
+
+  $self->asset(
+    'korap.css' => (
+      '/sass/style.scss',
+      '/sass/sidebar.scss',
+      '/sass/tutorial.scss',
+      '/sass/hint.scss',
+      '/sass/query.scss',
+      '/sass/table.scss',
+      '/sass/pagination.scss',
+      '/sass/kwic-4.0.scss',
+      '/css/media.css',
+      '/css/font-awesome.min.css',
+      '/css/highlight.css'
+    )
+  );
+
+  $self->asset(
+    'korap.js' => (
+      '/js/jquery-2.0.0.min.js',
+      '/js/translateTable.js',
+      '/js/hint.js',
+      '/js/highlight.pack.js'
+    )
+  );
 
   $self->helper(
     date_format => sub {
@@ -54,20 +80,30 @@
     ->to('tutorial#page')->name('tutorial');
 
   # Collection data
-  my $collection = $r->route('/collection');
-  $collection->to('search#info');
-  $collection->search;
+  my $collection = $r->bridge('/collection');
+  $collection->to('info#about_collection');
+  my $collection_id = $collection->bridge('/:collection_id');
+  # stats
+  # $collection_id->;
+  $collection_id->search;
 
   # Corpus data
-  my $corpus = $r->route('/corpus');
-  $corpus->search;
-  $corpus->route('/:corpus_id')->search;
-  $corpus->route('/:corpus_id/#doc_id')->search;
-  $corpus->route('/:corpus_id/#doc_id/:match_id')
-         ->to('info#about_match')->name('match');
+  my $corpus_res = $r->route('/corpus');
+  my $corpus = $corpus_res->route('/:corpus_id');
+  # Todo: Stats
+  $corpus->search->name('search_corpus');
+  my $doc = $corpus->route('/#doc_id');
+  $doc->search->name('search_document');
+
+  # Match data
+  my $match = $doc->route('/:match_id');
+  $match->route->to('info#about_match')->name('match');
+  my $match_layer = $match->route('/:layer');
+  $match_layer->route->to('info#about_match');
+  $match_layer->route('/:foundry')->to('info#about_match');
 
   # Utilities
-  $r->get('/util/query')->to('search#query');
+  # $r->get('/util/query')->to('search#query');
 };
 
 
diff --git a/lib/Korap/Info.pm b/lib/Korap/Info.pm
index 50396bf..b4c5d91 100644
--- a/lib/Korap/Info.pm
+++ b/lib/Korap/Info.pm
@@ -8,20 +8,49 @@
   my $doc_id    = $c->stash('doc_id');
   my $match_id  = $c->stash('match_id');
 
+  my $foundry = '*';
+  my %query = (foundry => '*');
+  if ($c->stash('foundry')) {
+    $query{foundry} = $c->stash('foundry');
+    if ($c->stash('layer')) {
+      $query{layer} = $c->stash('layer');
+    };
+  };
+
   return $c->respond_to(
     json => sub {
-      $c->render(json => $c->notifications(json => $c->match_info($corpus_id, $doc_id, $match_id)))
+      $c->render(json => $c->notifications(json => $c->match_info($corpus_id, $doc_id, $match_id, %query)))
     },
     html => sub {
+      my $match = $c->match_info($corpus_id, $doc_id, $match_id);
+      if ($match->{error}) {
+	$c->notify(error => $match->{error});
+	return $c->render_exception('error');
+      };
+
       $c->render(
 	layout => 'default',
 	template => 'match_info',
-	match => $c->match_info($corpus_id, $doc_id, $match_id, foundry => '')
+	match => $match
       )
     }
   );
 };
 
+# Todo: Return info for all collections
+sub about_collection {
+  my $c = shift;
+  my $api = $c->config('KorAP')->{'api0.1'};
+  my $src = $c->stash('collection_id');
+  if ($src) {
+    $c->render(
+      json => $c->notifications(
+	json => $c->info_on($src)
+      )
+    );
+  };
+};
+
 1;
 
 __END__
diff --git a/lib/Korap/Plugin/KorapInfo.pm b/lib/Korap/Plugin/KorapInfo.pm
index 4ee8612..946c997 100644
--- a/lib/Korap/Plugin/KorapInfo.pm
+++ b/lib/Korap/Plugin/KorapInfo.pm
@@ -68,23 +68,29 @@
     match_info => sub {
       my $c = shift;
 
-      return map_match($json->{matchInfo2}) if $c->app->mode eq 'test';
-
       my $corpus = shift;
       my $doc = shift;
       my $match = shift;
+      my %param = @_;
+
+      if ($c->app->mode eq 'test') {
+	return map_match($json->{treeInfo}) if $param{spans};
+	return map_match($json->{matchInfo2});
+      };
 
       # Build url
-      my $temp_api = 'http://10.0.10.13:8070/api/v0.1/';
-      my $url = Mojo::URL->new($temp_api)->path('matchInfo');
+      my $temp_api = $c->config('KorAP')->{'api-0.1'};
+      my $url = Mojo::URL->new($temp_api)->path(
+	join('/', 'corpus', $corpus, $doc, $match, 'matchInfo')
+      );
 
       # Build match id
-      $match = 'match-' . $corpus . '!' . $corpus . '_' . $doc . '-' . $match;
+      # $match = 'match-' . $corpus . '!' . $corpus . '_' . $doc . '-' . $match;
 
-      my %param = @_;
-      my %query = ( id => $match );
-      $query{foundry} = $param{foundry} // '*';
-      $query{layer} = $param{layer} if defined $param{layer};
+      my %query;
+      $query{foundry} = $param{foundry} if defined $param{foundry};
+      $query{layer}   = $param{layer}   if defined $param{layer};
+      $query{spans}   = $param{spans} ? 'true' : 'false';
 
       # Add query
       $url->query(\%query);
@@ -94,6 +100,7 @@
       if (my $response = $c->ua->get($url)->success) {
 	return map_match($response->json);
       };
+
       $c->notify(error => 'Unable to retrieve resource');
       return {};
     }
@@ -105,6 +112,25 @@
 
 __DATA__
 {
+  "treeInfo": {
+    "author":"Filzstift,Alexander Sommer,TheK",
+    "textClass":"freizeit-unterhaltung reisen",
+    "corpusID":"WPD",
+    "title":"Neuseeland",
+    "foundries":"xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency connexor connexor/morpho connexor/syntax connexor/phrase treetagger treetagger/morpho base base/sentences base/paragraphs opennlp opennlp/morpho",
+    "tokenization":"opennlp#tokens",
+    "field":"tokens",
+    "startMore":false,
+    "endMore":false,
+    "docID":"WPD_NNN.02848",
+    "snippet" : "<span class=\"context-left\"><span class=\"more\"></span></span><span class=\"match\"><span title=\"xip/c:VERB\">enthält</span>, <span title=\"xip/c:CONJ\">aber</span> <span title=\"xip/c:PTCL\">an</span> <span title=\"xip/c:CONJ\">und</span> <span title=\"xip/c:PP\"><span title=\"xip/c:PREP\">für</span> <span title=\"xip/c:NP\"><span title=\"xip/c:PRON\">sich</span></span></span> <span title=\"xip/c:NP\"><span title=\"xip/c:DET\">keinen</span> <span title=\"xip/c:NPA\"><span title=\"xip/c:AP\"><span title=\"xip/c:ADJ\">weiteren</span></span> <span title=\"xip/c:NOUN\">Sinn</span></span></span> <span title=\"xip/c:VERB\">enthält</span></span><span class=\"context-right\"><span class=\"more\"></span></span>",
+    "ID":"match-WPD!WPD_NNN.02848-p1213-1224",
+    "pubDate":"2005-03-28",
+    "context":{
+      "left":["token",0],
+      "right":["token",0]
+    }
+  },
   "matchInfo": {
     "author":"Filzstift,Alexander Sommer,TheK",
     "textClass":"freizeit-unterhaltung reisen",
diff --git a/lib/Korap/Plugin/KorapSearch.pm b/lib/Korap/Plugin/KorapSearch.pm
index 0940cf0..a2c22bd 100644
--- a/lib/Korap/Plugin/KorapSearch.pm
+++ b/lib/Korap/Plugin/KorapSearch.pm
@@ -8,13 +8,12 @@
 # TODO: Write search snippet
 
 sub map_matches {
-  my $matches = shift;
   [
     map {
       $_->{ID} =~ s/^match\-[^!]+![^-]+-//;
       $_->{docID} =~ s/^[^_]+_//;
       $_;
-    } @$matches
+    } @{ shift() }
   ];
 };
 
@@ -27,12 +26,13 @@
     $param = { %$param, %$config_param };
   };
 
-  my $api = $param->{api};
+  my $api = $param->{'api-0.1'};
 
   # Create search endpoint
   $mojo->routes->add_shortcut(
     search => sub {
-      shift->route('/search')->to('search#remote')
+      # Todo: Support TRACE
+      return shift->route('/search')->to('search#remote')
     }
   );
 
@@ -55,7 +55,7 @@
 	$c->stash('search.bm.hit' => 20);
 	$c->stash('search.bm.result' => 10);
 	$c->stash('search.query' => $json->{request}->{query});
-	$c->stash('search.hits' => $json->{matches});
+	$c->stash('search.hits' => map_matches $json->{matches});
 	return $cb->();
       };
 
@@ -85,7 +85,17 @@
       };
 
       my $url = Mojo::URL->new($api);
-      $url->path('resource/search');
+
+      if ($c->stash('corpus_id')) {
+	$url->path('corpus/' . $c->stash('corpus_id') . '/search');
+      }
+      elsif ($c->stash('collection_id')) {
+	$url->path('virtualcollection/' . $c->stash('collection_id') . '/search');
+      }
+      else {
+	$url->path('search');
+      };
+
       #if ($c->stash('resource')) {
       #$url->path($c->stash('resource'));
       #if ($c->stash('cid')) {
@@ -100,7 +110,7 @@
       $url->query(\%query);
       my $cache_url = $url->to_string;
 
-      $url->query({ctx => 'paragraph'});
+      $url->query({context => 'paragraph'});
 
       # Check cache for total results
       my $total_results = $c->chi->get('total-' . $cache_url);
@@ -108,7 +118,6 @@
 	$c->stash('search.totalResults' => $total_results);
 	$c->app->log->warn('Get total result from cache');
 	$url->query({cutoff => 'true'});
-	$url->query({cutOff => 'true'});
       }
       else {
 	$c->stash('search.totalResults' => 0);
@@ -118,10 +127,9 @@
 
       $c->stash('search.itemsPerPage' => $count);
 
-      my $ua = Mojo::UserAgent->new($url);
       $c->app->log->debug($url->to_string);
 
-      $c->app->log->debug("Start tx");
+      my $ua = Mojo::UserAgent->new($url);
 
       # Blocking request
       # TODO: Make non-blocking
@@ -139,10 +147,10 @@
 	# Reformat benchmark counter
 	my $b_hit    = $json->{benchmarkHitCounter};
 	my $b_search = $json->{benchmarkSearchResults};
-	if ($b_hit =~ s/\s+(m)?s$//) {
+	if ($b_hit & $b_hit =~ s/\s+(m)?s$//) {
 	  $b_hit = sprintf("%.2f", $b_hit) . ($1 ? $1 : '') . 's';
 	};
-	if ($b_search =~ s/\s+(m)?s$//) {
+	if ($b_search && $b_search =~ s/\s+(m)?s$//) {
 	  $b_search = sprintf("%.2f", $b_search) . ($1 ? $1 : '') . 's';
 	};
 
diff --git a/lib/Korap/Plugin/KorapTagHelpers.pm b/lib/Korap/Plugin/KorapTagHelpers.pm
index b54161c..b2b9a4e 100644
--- a/lib/Korap/Plugin/KorapTagHelpers.pm
+++ b/lib/Korap/Plugin/KorapTagHelpers.pm
@@ -10,9 +10,9 @@
     korap_tut_query => sub {
       my ($c, $ql, $q) = @_;
       $q = xml_escape $q;
-      b('<code class="query tutorial" onclick="top.useQuery(this)" ' .
-	  qq!data-query="$q" data-query-language="$ql"><pre>! .
-	    $q . '</pre></code>');
+      b('<pre class="query tutorial" onclick="top.useQuery(this)" ' .
+	  qq!data-query="$q" data-query-language="$ql"><code>! .
+	    $q . '</code></pre>');
     }
   );
 };
diff --git a/lib/Korap/Search.pm b/lib/Korap/Search.pm
index 9166130..a656635 100644
--- a/lib/Korap/Search.pm
+++ b/lib/Korap/Search.pm
@@ -7,24 +7,28 @@
   $c->layout('default');
   $c->title('KorAP');
 
+  my $api = $c->config('KorAP')->{'api-0.1'};
+
+  # Todo: Support query building directly
+
   $c->stash(test_port => (
     $c->req->url->to_abs->port == 6666 ||
-      $c->app->mode eq 'development') ? 1 : 0);
+      $c->app->mode =~ m/^development|test$/) ? 1 : 0);
 
   if ((scalar $c->param('action') // '') eq 'inspect') {
-    my $api = $c->config('KorAP')->{api};
-    my $url = Mojo::URL->new($api)->path('resource/query');
+    my $url = Mojo::URL->new($api)->path('search');
 
     $url->query({
       q => scalar $c->param('q') // '',
       ql => scalar $c->param('ql') // 'poliqarp'
     });
 
-    if (my $response = $c->ua->get($url)->success) {
+    my $tx = $c->ua->build_tx(TRACE => $url);
+    if (my $response = $c->ua->start($tx)->success) {
       $c->stash('search.query' => $response->json);
     }
     else {
-      $c->notify(error => 'Unable to retrieve serialized query');
+      $c->notify(error => 'Unable to trace query');
     };
 
     $c->param(cutoff => 1);
@@ -38,13 +42,6 @@
   $c->render(template => 'search');
 };
 
-sub info {
-  my $c = shift;
-  my $api = $c->config('KorAP')->{api};
-  my $src = $c->stash('resource');
-  $c->render(json => $c->notifications(json => $c->info_on($src)));
-};
-
 
 1;
 
@@ -54,9 +51,6 @@
 [{"shared":false,"id":1,"managed":true,"created":1401193381119,"stats":{"documents":196510,"tokens":51545081,"sentences":4116282,"paragraphs":2034752},"query":[{"@type":"korap:meta-filter","@value":{"@type":"korap:term","@field":"korap:field#corpusID","@value":"WPD"}}],"description":"Die freie Enzyklopädie","name":"Wikipedia","foundries":"base;corenlp;mate;mpt;opennlp;tt;xip"}]
 
 
-
-
-
 http://10.0.10.13:8070/api/v1/resource/matchInfo?id=match-WPD!WPD_NNN.02848-p1223-1224&f=mate&l=
 
 {"author":"Filzstift,Alexander Sommer,TheK","textClass":"freizeit-unterhaltung reisen","corpusID":"WPD","title":"Neuseeland","foundries":"xip xip/morpho xip/constituency xip/dependency corenlp corenlp/namedentities corenlp/namedentities/ne_dewac_175m_600 corenlp/namedentities corenlp/namedentities/ne_hgc_175m_600 mate mate/morpho mate/dependency connexor connexor/morpho connexor/syntax connexor/phrase treetagger treetagger/morpho base base/sentences base/paragraphs opennlp opennlp/morpho","tokenization":"opennlp#tokens","field":"tokens","startMore":false,"endMore":false,"docID":"WPD_NNN.02848","snippet":"<span class=\"context-left\"></span><span class=\"match\"><span title=\"mate/l:besonders\"><span title=\"mate/p:ADV\">Besonders</span></span> <span title=\"mate/l:auffällig\"><span title=\"mate/m:degree:pos\"><span title=\"mate/p:ADJD\">auffällig</span></span></span> <span title=\"mate/l:sein\"><span title=\"mate/m:mood:ind\"><span title=\"mate/m:number:pl\"><span title=\"mate/m:person:3\"><span title=\"mate/m:tense:pres\"><span title=\"mate/p:VAFIN\">sind</span></span></span></span></span></span> <span title=\"mate/l:schließlich\"><span title=\"mate/p:ADV\">schließlich</span></span> <span title=\"mate/l:noch\"><span title=\"mate/p:ADV\">noch</span></span> <span title=\"mate/l:der\"><span title=\"mate/m:case:nom\"><span title=\"mate/m:gender:masc\"><span title=\"mate/m:number:sg\"><span title=\"mate/p:ART\">der</span></span></span></span></span> <span title=\"mate/l:pohutukawa\"><span title=\"mate/m:case:nom\"><span title=\"mate/m:gender:masc\"><span title=\"mate/m:number:sg\"><span title=\"mate/p:NE\">Pohutukawa</span></span></span></span></span> <span title=\"mate/l:und\"><span title=\"mate/p:KON\">und</span></span> <span title=\"mate/l:der\"><span title=\"mate/m:case:nom\"><span title=\"mate/m:gender:masc\"><span title=\"mate/m:number:sg\"><span title=\"mate/p:ART\">der</span></span></span></span></span> <span title=\"mate/l:cabbage\"><span title=\"mate/m:case:nom\"><span title=\"mate/m:gender:masc\"><span title=\"mate/m:number:sg\"><span title=\"mate/p:NE\">Cabbage</span></span></span></span></span> <span title=\"mate/l:tree\"><span title=\"mate/m:gender:masc\"><span title=\"mate/m:number:sg\"><span title=\"mate/p:NE\"><span title=\"mate/m:case:nom\">Tree</span></span></span></span></span></span><span class=\"context-right\"></span>","ID":"match-WPD!WPD_NNN.02848-p1213-1224","pubDate":"2005-03-28","context":{"left":["token",0],"right":["token",0]}}
diff --git a/lib/Mojolicious/Plugin/AssetPack/LibSass.pm b/lib/Mojolicious/Plugin/AssetPack/LibSass.pm
new file mode 100644
index 0000000..6a082a4
--- /dev/null
+++ b/lib/Mojolicious/Plugin/AssetPack/LibSass.pm
@@ -0,0 +1,27 @@
+package Mojolicious::Plugin::AssetPack::LibSass;
+use Mojo::Base 'Mojolicious::Plugin';
+use CSS::Sass;
+use CSS::Minifier::XS;
+
+sub register {
+  my ($plugin, $mojo) = @_;
+
+  my $sass = CSS::Sass->new;
+
+  # Todo: Check if AssetPack is loaded
+  # Todo: Only minify if necessary
+
+  my $proc = $mojo->asset->preprocessors;
+
+  $proc->remove('scss');
+  $proc->add(
+    scss => sub {
+      my ($as, $text, $file) = @_;
+      $$text = CSS::Minifier::XS::minify($sass->compile($$text));
+    });
+  $proc->map_type(scss => 'css');
+};
+
+1;
+
+__END__