diff --git a/client/catalog/js/catalog.js b/client/catalog/js/catalog.js
new file mode 100644
index 0000000..d5234f3
--- /dev/null
+++ b/client/catalog/js/catalog.js
@@ -0,0 +1,377 @@
+//Run when the document loads AND we have the config loaded.
+(function(){
+  var catalog = null;
+  var config = null;
+  Promise.all([
+    new Promise(function(resolve, reject){
+      $.ajax('config.json').done(function(data){
+        catalog = data.catalogPrefix;
+        config = data.faceConfig;
+        resolve();
+      }).fail(function(){
+        console.error("Failed to get config.");
+        reject()
+      });
+    }),
+    new Promise(function(resolve, reject){
+      var timeout = setTimeout(function(){
+        console.error("Document never loaded? Something bad has happened!");
+        reject();
+      }, 10000);
+      $(function () {
+        clearTimeout(timeout);
+        resolve();
+      });
+    })
+  ]).then(function(){
+    new Atmos(catalog, config);
+  }, function(){
+    console.error("Failed to initialize!");
+  })
+})();
+
+var Atmos = (function(){
+  "use strict";
+  /**
+   * Atmos
+   * @version 2.0
+   *
+   * Configures an Atmos object. This manages the atmos interface.
+   *
+   * @constructor
+   * @param {string} catalog - NDN path
+   * @param {Object} config - Object of configuration options for a Face.
+   */
+  function Atmos(catalog, config){
+
+    //Internal variables.
+    this.results = [];
+    this.resultCount = 0;
+    this.name = null;
+    this.page = 0;
+    this.lastPage = -1;
+    //this.itemsPerPage = 25; //TODO
+
+    this.catalog = catalog;
+
+    this.face = new Face(config);
+
+    this.categories = $('#side-menu');
+    this.resultTable = $('#resultTable');
+    this.filters = $('#filters');
+    this.searchInput = $('#search');
+    this.searchBar = $('#searchBar');
+    this.searchButton = $('#searchButton');
+    this.pagers = $('.pager');
+    this.alerts = $('#alerts');
+
+    var scope = this;
+
+    this.resultTable.on('click', '.interest-button', function(){
+      var button = $(this);
+
+      if (button.is(':disabled')){
+        console.warn("Attempt to request again!");
+      }
+
+      var name = button.parent().prev().text();
+      var interest = new Interest(new Name('/retrieve' + name));
+      scope.face.expressInterest(interest, function(){}, function(){});
+
+      button.text("Requested!")
+        .removeClass('btn-primary')
+        .addClass('btn-success')
+        .addClass('disabled')
+        .prop('disabled', true);
+    });
+
+    //Filter setup
+    $.getJSON("search_catagories.json").done(function (data) {
+      $.each(data, function (pageSection, contents) {
+        if (pageSection == "SearchCatagories") {
+          $.each(contents, function (category, searchOptions) {
+            //Create the category
+            var e = $('<li><a href="#">' + category.replace(/\_/g, " ") + '</a><ul class="subnav nav nav-pills nav-stacked"></ul></li>');
+
+            var sub = e.find('ul.subnav');
+            $.each(searchOptions, function(index, name){
+              //Create the filter list inside the category
+              var item = $('<li><a href="#">' + name + '</a></li>');
+              sub.append(item);
+              item.click(function(){ //Click on the side menu filters
+                if (item.hasClass('active')){ //Does the filter already exist?
+                  item.removeClass('active');
+                  scope.filters.find(':contains(' + category + ':' + name + ')').remove();
+                } else { //Add a filter
+                  item.addClass('active');
+                  var filter = $('<span class="label label-default"></span>');
+                  filter.text(category + ':' + name);
+
+                  scope.filters.append(filter);
+
+                  filter.click(function(){ //Click on a filter
+                    filter.remove();
+                    item.removeClass('active');
+                  });
+                }
+
+              });
+            });
+
+            //Toggle the menus. (Only respond when the immediate tab is clicked.)
+            e.find('> a').click(function(){
+              scope.categories.find('.subnav').slideUp();
+              var t = $(this).siblings('.subnav');
+              if ( !t.is(':visible') ){ //If the sub menu is not visible
+                t.slideDown(function(){
+                  t.triggerHandler('focus');
+                }); //Make it visible and look at it.
+              }
+            });
+
+            scope.categories.append(e);
+
+          });
+        }
+      });
+    });
+
+    this.searchInput.autoComplete(function(field, callback){
+      scope.autoComplete(field, callback);
+    });
+
+    this.searchBar.submit(function(e){
+      e.preventDefault();
+      console.warn("This feature is incomplete.");
+    });
+
+    this.searchButton.click(function(){
+      console.log("Search Button Pressed");
+      scope.search();
+    });
+
+    this.pagers.find('.next').click(function(){
+      if (!$(this).hasClass('disabled')){
+        scope.getResults(scope.page + 1);
+      }
+    });
+    this.pagers.find('.previous').click(function(){
+      if (!$(this).hasClass('disabled')){
+        scope.getResults(scope.page - 1);
+      }
+    });
+
+  }
+
+  Atmos.prototype.search = function(){
+
+    var filters = this.getFilters();
+
+    console.log("Search started!", this.searchInput.val(), filters);
+
+    console.log("Initiating query");
+
+    this.results = []; //Drop any old results.
+    this.resultTable.empty();
+
+    var scope = this;
+
+    this.query(this.catalog, filters,
+    function(interest, data){ //Response function
+      console.log("Query Response:", interest, data);
+
+      var parameters = JSON.stringify(filters);
+
+      var ack = data.getName();
+
+      scope.name = new Name(scope.catalog).append("query-results").append(parameters).append(ack.get(-3)).append(ack.get(-2));
+
+      scope.getResults(0);
+
+    }, function(interest){ //Timeout function
+      console.warn("Request failed! Timeout");
+      scope.createAlert("Request timed out. \"" + interest.getName().toUri() + "\" See console for details.");
+    });
+
+  }
+
+  Atmos.prototype.autoComplete = function(field, callback){
+
+    if (this.searchInput.val().length === 0 && !filters.hasOwnProperty()){
+      if (!this.searchBar.hasClass('has-error')){
+        this.searchBar.addClass('has-error').append('<span class="help-block">A filter or search value is required!</span>');
+      }
+      return;
+    } else {
+      this.searchBar.removeClass('has-error').find('.help-block').fadeOut(function(){$(this).remove()});
+    }
+
+    var scope = this;
+
+    this.query(this.catalog, {"?": field},
+    function(interest, data){
+
+      var ack = data.getName();
+
+      var name = new Name(scope.catalog).append('query-results').append(JSON.stringify({"?": field})).append(ack.get(-3)).append(ack.get(-2));
+
+      scope.face.expressInterest(new Interest(name).setInterestLifetimeMilliseconds(5000),
+      function(interest, data){
+
+        if (data.getContent().length !== 0){
+          var options = JSON.parse(data.getContent().toString().replace(/[\n\0]/g, "")).next.map(function(element){
+            return field + element;
+          });
+          callback(options);
+        }
+
+      }, function(interest){
+        console.warn("Interest timed out!", interest);
+        scope.createAlert("Request timed out. \"" + interest.getName().toUri() + "\" See console for details.");
+      });
+
+    }, function(interest){
+      console.error("Request failed! Timeout", interest);
+      scope.createAlert("Request timed out. \"" + interest.getName().toUri() + "\" See console for details.");
+    });
+
+  }
+
+  Atmos.prototype.showResults = function(resultIndex) {
+
+    var results = $(this.results[resultIndex].reduce(function(prev, current){
+      prev.push('<tr><td><input type="checkbox"></td><td>');
+      prev.push(current);
+      prev.push('</td><td><button class="interest-button btn btn-primary btn-sm">Retrieve</button></td></tr>');
+      return prev;
+    }, []).join(''));
+
+    this.resultTable.empty().append(results);
+
+    this.pagers.find('.totalResults').text('(Page' + (resultIndex + 1) + ') Showing ' + this.results[resultIndex].length + ' of ' + this.resultCount + ' results');
+
+    if (resultIndex === this.lastPage) {
+      this.pagers.find('.next').addClass('disabled');
+    }
+
+    if (resultIndex === 0){
+      this.pagers.find('.next').removeClass('disabled');
+      this.pagers.find('.previous').addClass('disabled');
+    } else if (resultIndex === 1) {
+      this.pagers.find('.previous').removeClass('disabled');
+    }
+
+  }
+
+  Atmos.prototype.getResults = function(index){
+
+    if (this.results[index]){
+      //console.log("We already have index", index);
+      this.page = index;
+      this.showResults(index);
+      return;
+    }
+
+    if (this.name === null) {
+      console.error("This shouldn't be reached! We are getting results before a search has occured!");
+      throw new Error("Illegal State");
+    }
+
+    var first = new Name(this.name).appendSegment(index);
+
+    console.log("Requesting data index: (", index, ") at ", first.toUri());
+
+    var scope = this;
+
+    this.face.expressInterest(new Interest(first).setInterestLifetimeMilliseconds(5000),
+      function(interest, data){ //Response
+
+        if (data.getContent().length === 0){
+          console.log("Empty response.");
+          return;
+        }
+
+        if (data.getName().get(-1).equals(data.getMetaInfo().getFinalBlockId())) { //Final page.
+          scope.lastPage = index;
+          //The next buttons will be disabled by showResults.
+        }
+
+        var content = JSON.parse(data.getContent().toString().replace(/[\n\0]/g,""));
+
+        var results = scope.results[index] = content.results;
+
+        scope.resultCount = content.resultCount;
+
+        scope.pagers.find('.totalResults').text(scope.resultCount + " Results");
+
+        //console.log("Got results:", results);
+
+        scope.page = index;
+
+        if (!results){
+          console.log("No results were found!");
+          return;
+        }
+
+        scope.showResults(index);
+
+      },
+      function(interest){ //Timeout
+        console.error("Failed to retrieve results: timeout", interest);
+        scope.createAlert("Request timed out. \"" + interest.getName().toUri() + "\" See console for details.");
+      }
+    );
+
+  }
+
+  Atmos.prototype.query = function(prefix, parameters, callback, timeout) {
+
+    var queryPrefix = new Name(prefix);
+    queryPrefix.append("query");
+
+    var jsonString = JSON.stringify(parameters);
+    queryPrefix.append(jsonString);
+
+    var queryInterest = new Interest(queryPrefix);
+    queryInterest.setInterestLifetimeMilliseconds(4000);
+
+    this.face.expressInterest(queryInterest, callback, timeout);
+
+  }
+
+  /**
+   * This function returns a map of all the categories active filters.
+   * @return {Object<string, string>}
+   */
+  Atmos.prototype.getFilters = function(){
+    var filters = this.filters.children().toArray().reduce(function(prev, current){
+      var data = $(current).text().split(/:/);
+      prev[data[0]] = data[1];
+      return prev;
+    }, {}); //Collect a map<category, filter>.
+    //TODO Make the return value map<category, Array<filter>>
+    return filters;
+  }
+
+  /**
+   * Creates a closable alert for the user.
+   *
+   * @param {string} message
+   * @param {string} type - Override the alert type.
+   */
+  Atmos.prototype.createAlert = function(message, type) {
+
+    var alert = $('<div class="alert"><div>');
+    alert.addClass(type?type:'alert-info');
+    alert.text(message);
+    alert.append(Atmos.closeButton);
+
+    this.alerts.append(alert);
+  }
+  Atmos.closeButton = '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
+
+  return Atmos;
+
+})();
+
+
